@agent-vm/openclaw-agent-vm-plugin 0.0.71 → 0.0.73

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/dist/index.d.ts CHANGED
@@ -1,31 +1,6 @@
1
+ import { EndToolVmActiveUseRequest, HeartbeatToolVmActiveUseResponse, StartToolVmActiveUseRequest, StartToolVmActiveUseResponse, ToolVmLeasePeek, ToolVmSshLease } from "@agent-vm/gateway-interface";
2
+
1
3
  //#region src/controller-lease-client.d.ts
2
- interface GondolinLeaseResponse {
3
- readonly idleTtlMs?: number;
4
- readonly leaseId: string;
5
- readonly ssh: {
6
- readonly host: string;
7
- readonly identityPem: string;
8
- readonly knownHostsLine: string;
9
- readonly port: number;
10
- readonly user: string;
11
- };
12
- readonly tcpSlot: number;
13
- readonly workdir: string;
14
- }
15
- interface LeasePeekResponse {
16
- readonly createdAt: number;
17
- readonly lastUsedAt: number;
18
- readonly leaseId: string;
19
- readonly profileId: string;
20
- readonly scopeKey: string;
21
- readonly ssh: {
22
- readonly host: string;
23
- readonly port: number;
24
- readonly user: string;
25
- };
26
- readonly tcpSlot: number;
27
- readonly zoneId: string;
28
- }
29
4
  interface OpenClawRuntimeStatusReport {
30
5
  readonly findings: readonly {
31
6
  readonly hint: string;
@@ -36,17 +11,22 @@ interface OpenClawRuntimeStatusReport {
36
11
  readonly zoneId: string;
37
12
  }
38
13
  interface LeaseClient {
39
- keepLeaseAlive(leaseId: string): Promise<GondolinLeaseResponse>;
40
- peekLease(leaseId: string): Promise<LeasePeekResponse>;
14
+ endActiveUse(leaseId: string, useId: string, request: EndToolVmActiveUseRequest): Promise<void>;
15
+ heartbeatActiveUse(leaseId: string, useId: string): Promise<HeartbeatToolVmActiveUseResponse>;
16
+ peekLease(leaseId: string): Promise<ToolVmLeasePeek>;
41
17
  publishOpenClawRuntimeStatus?(report: OpenClawRuntimeStatusReport): Promise<void>;
42
- releaseLease(leaseId: string): Promise<void>;
18
+ releaseLease(leaseId: string, options?: {
19
+ readonly force?: boolean;
20
+ }): Promise<void>;
21
+ renewLease(leaseId: string): Promise<ToolVmSshLease>;
43
22
  requestLease(request: {
44
23
  readonly agentWorkspaceDir: string;
45
24
  readonly profileId: string;
46
25
  readonly scopeKey: string;
47
26
  readonly workMountDir: string;
48
27
  readonly zoneId: string;
49
- }): Promise<GondolinLeaseResponse>;
28
+ }): Promise<ToolVmSshLease>;
29
+ startActiveUse(leaseId: string, request: StartToolVmActiveUseRequest): Promise<StartToolVmActiveUseResponse>;
50
30
  }
51
31
  type ControllerLeaseRequestErrorKind = 'client-error' | 'server-error';
52
32
  declare class ControllerLeaseRequestError extends Error {
@@ -67,7 +47,7 @@ declare function createLeaseClient(options: {
67
47
  }): LeaseClient;
68
48
  //#endregion
69
49
  //#region src/sandbox-backend/sandbox-backend-contract.d.ts
70
- interface FsBridgeLeaseContext {
50
+ interface OpenClawFsBridgeLeaseContext {
71
51
  readonly remoteAgentWorkspaceDir: string;
72
52
  readonly remoteWorkspaceDir: string;
73
53
  readonly runRemoteShellScript: (params: {
@@ -82,7 +62,7 @@ interface FsBridgeLeaseContext {
82
62
  readonly stdout: Buffer;
83
63
  }>;
84
64
  }
85
- interface GondolinFsBridge {
65
+ interface OpenClawSandboxFsBridge {
86
66
  mkdirp(params: {
87
67
  readonly cwd?: string;
88
68
  readonly filePath: string;
@@ -135,7 +115,7 @@ interface CreateBackendDependencies {
135
115
  readonly buildExecSpec: (params: {
136
116
  readonly command: string;
137
117
  readonly env: Record<string, string>;
138
- readonly ssh: GondolinLeaseResponse['ssh'];
118
+ readonly ssh: ToolVmSshLease['ssh'];
139
119
  readonly usePty: boolean;
140
120
  readonly workdir: string;
141
121
  }) => Promise<{
@@ -144,9 +124,9 @@ interface CreateBackendDependencies {
144
124
  readonly finalizeToken?: unknown;
145
125
  readonly stdinMode: 'pipe-open' | 'pipe-closed';
146
126
  }>;
147
- readonly createFsBridgeBuilder?: (leaseContext: FsBridgeLeaseContext) => (params: {
127
+ readonly createFsBridgeBuilder?: (leaseContext: OpenClawFsBridgeLeaseContext) => (params: {
148
128
  readonly sandbox: unknown;
149
- }) => GondolinFsBridge;
129
+ }) => OpenClawSandboxFsBridge;
150
130
  readonly createLeaseClient?: (options: {
151
131
  readonly controllerUrl: string;
152
132
  }) => LeaseClient;
@@ -154,7 +134,7 @@ interface CreateBackendDependencies {
154
134
  readonly allowFailure?: boolean;
155
135
  readonly script: string;
156
136
  readonly signal?: AbortSignal;
157
- readonly ssh: GondolinLeaseResponse['ssh'];
137
+ readonly ssh: ToolVmSshLease['ssh'];
158
138
  readonly stdin?: Buffer | string;
159
139
  }) => Promise<{
160
140
  readonly code: number;
@@ -162,13 +142,13 @@ interface CreateBackendDependencies {
162
142
  readonly stdout: Buffer;
163
143
  }>;
164
144
  }
165
- interface GondolinSandboxBackendHandle {
145
+ interface OpenClawSandboxBackendHandle {
166
146
  readonly configLabel?: string;
167
147
  readonly configLabelKind?: string;
168
- createFsBridge?: (params: {
148
+ readonly createFsBridge?: (params: {
169
149
  readonly sandbox: unknown;
170
- }) => GondolinFsBridge;
171
- env?: Record<string, string>;
150
+ }) => OpenClawSandboxFsBridge;
151
+ readonly env?: Record<string, string>;
172
152
  readonly id: string;
173
153
  readonly runtimeId: string;
174
154
  readonly runtimeLabel: string;
@@ -184,7 +164,7 @@ interface GondolinSandboxBackendHandle {
184
164
  readonly finalizeToken?: unknown;
185
165
  readonly stdinMode: 'pipe-open' | 'pipe-closed';
186
166
  }>;
187
- finalizeExec?: (params: {
167
+ readonly finalizeExec?: (params: {
188
168
  readonly exitCode: number | null;
189
169
  readonly status: 'completed' | 'failed';
190
170
  readonly timedOut: boolean;
@@ -215,7 +195,7 @@ declare function createGondolinSandboxBackendFactory(options: {
215
195
  readonly scopeKey: string;
216
196
  readonly sessionKey: string;
217
197
  readonly workspaceDir: string;
218
- }) => Promise<GondolinSandboxBackendHandle>;
198
+ }) => Promise<OpenClawSandboxBackendHandle>;
219
199
  //#endregion
220
200
  //#region src/sandbox-backend/sandbox-backend-manager.d.ts
221
201
  declare function createGondolinSandboxBackendManager(options: {
@@ -282,7 +262,7 @@ interface SshHelpers {
282
262
  }>;
283
263
  };
284
264
  readonly sandbox: unknown;
285
- }) => GondolinFsBridge;
265
+ }) => OpenClawSandboxFsBridge;
286
266
  readonly createSshSandboxSessionFromSettings: (settings: {
287
267
  readonly command: string;
288
268
  readonly identityData?: string;
@@ -329,9 +309,9 @@ interface OpenClawToolRegistrationApi {
329
309
  //#region src/openclaw-backend-dependencies.d.ts
330
310
  declare function createBackendDeps(ssh: SshHelpers): {
331
311
  readonly buildExecSpec: CreateBackendDependencies['buildExecSpec'];
332
- readonly createFsBridgeBuilder: (leaseContext: FsBridgeLeaseContext) => (params: {
312
+ readonly createFsBridgeBuilder: (leaseContext: OpenClawFsBridgeLeaseContext) => (params: {
333
313
  readonly sandbox: unknown;
334
- }) => GondolinFsBridge;
314
+ }) => OpenClawSandboxFsBridge;
335
315
  readonly runRemoteShellScript: CreateBackendDependencies['runRemoteShellScript'];
336
316
  };
337
317
  //#endregion
@@ -356,5 +336,5 @@ declare const plugin: {
356
336
  //#region src/index.d.ts
357
337
  declare const OPENCLAW_GONDOLIN_PLUGIN_PACKAGE_NAME = "@agent-vm/openclaw-agent-vm-plugin";
358
338
  //#endregion
359
- export { ControllerLeaseRequestError, ControllerLeaseRequestErrorKind, CreateBackendDependencies, FsBridgeLeaseContext, GondolinFsBridge, GondolinLeaseResponse, GondolinSandboxBackendHandle, LeaseClient, LeasePeekResponse, OPENCLAW_GONDOLIN_PLUGIN_PACKAGE_NAME, OpenClawRuntimeStatusReport, ResolvedGondolinPluginConfig, type SshHelpers, createBackendDeps, createGondolinSandboxBackendFactory, createGondolinSandboxBackendManager, createLeaseClient, plugin as default, resolveGondolinPluginConfig };
339
+ export { ControllerLeaseRequestError, ControllerLeaseRequestErrorKind, type CreateBackendDependencies, LeaseClient, OPENCLAW_GONDOLIN_PLUGIN_PACKAGE_NAME, type OpenClawFsBridgeLeaseContext, OpenClawRuntimeStatusReport, type OpenClawSandboxBackendHandle, type OpenClawSandboxFsBridge, ResolvedGondolinPluginConfig, type SshHelpers, createBackendDeps, createGondolinSandboxBackendFactory, createGondolinSandboxBackendManager, createLeaseClient, plugin as default, resolveGondolinPluginConfig };
360
340
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/controller-lease-client.ts","../src/sandbox-backend/sandbox-backend-contract.ts","../src/sandbox-backend/sandbox-backend-handle-factory.ts","../src/sandbox-backend/sandbox-backend-manager.ts","../src/gondolin-plugin-config.ts","../src/openclaw-sandbox-sdk-contract.ts","../src/openclaw-backend-dependencies.ts","../src/openclaw-plugin-registration.ts","../src/index.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/controller-lease-client.ts","../src/sandbox-backend/sandbox-backend-contract.ts","../src/sandbox-backend/sandbox-backend-handle-factory.ts","../src/sandbox-backend/sandbox-backend-manager.ts","../src/gondolin-plugin-config.ts","../src/openclaw-sandbox-sdk-contract.ts","../src/openclaw-backend-dependencies.ts","../src/openclaw-plugin-registration.ts","../src/index.ts"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { createToolVmActiveUseHandle, isToolVmLeasePeek, isToolVmSshLease } from "@agent-vm/gateway-interface";
1
2
  //#region src/controller-lease-client.ts
2
3
  var ControllerLeaseRequestError = class extends Error {
3
4
  bodyText;
@@ -16,21 +17,13 @@ var ControllerLeaseRequestError = class extends Error {
16
17
  function objectValue(value) {
17
18
  return typeof value === "object" && value !== null ? value : void 0;
18
19
  }
19
- function isSshResponse(value) {
20
+ function isStartActiveUseResponse(value) {
20
21
  const record = objectValue(value);
21
- return record !== void 0 && typeof Reflect.get(record, "host") === "string" && typeof Reflect.get(record, "identityPem") === "string" && typeof Reflect.get(record, "knownHostsLine") === "string" && typeof Reflect.get(record, "port") === "number" && typeof Reflect.get(record, "user") === "string";
22
+ return record !== void 0 && typeof Reflect.get(record, "expiresAt") === "number" && typeof Reflect.get(record, "heartbeatAfterMs") === "number" && typeof Reflect.get(record, "useId") === "string";
22
23
  }
23
- function isLeasePeekSshResponse(value) {
24
+ function isHeartbeatActiveUseResponse(value) {
24
25
  const record = objectValue(value);
25
- return record !== void 0 && typeof Reflect.get(record, "host") === "string" && typeof Reflect.get(record, "port") === "number" && typeof Reflect.get(record, "user") === "string";
26
- }
27
- function isGondolinLeaseResponse$1(value) {
28
- const record = objectValue(value);
29
- return record !== void 0 && (Reflect.get(record, "idleTtlMs") === void 0 || typeof Reflect.get(record, "idleTtlMs") === "number") && typeof Reflect.get(record, "leaseId") === "string" && isSshResponse(Reflect.get(record, "ssh")) && typeof Reflect.get(record, "tcpSlot") === "number" && typeof Reflect.get(record, "workdir") === "string";
30
- }
31
- function isLeasePeekResponse(value) {
32
- const record = objectValue(value);
33
- return record !== void 0 && typeof Reflect.get(record, "createdAt") === "number" && typeof Reflect.get(record, "lastUsedAt") === "number" && typeof Reflect.get(record, "leaseId") === "string" && typeof Reflect.get(record, "profileId") === "string" && typeof Reflect.get(record, "scopeKey") === "string" && isLeasePeekSshResponse(Reflect.get(record, "ssh")) && typeof Reflect.get(record, "tcpSlot") === "number" && typeof Reflect.get(record, "zoneId") === "string";
26
+ return record !== void 0 && typeof Reflect.get(record, "expiresAt") === "number" && typeof Reflect.get(record, "heartbeatAfterMs") === "number";
34
27
  }
35
28
  function formatUnknownError$1(error) {
36
29
  return error instanceof Error ? error.message : String(error);
@@ -70,12 +63,32 @@ async function readJsonResponse(response, context, isExpectedResponse) {
70
63
  function createLeaseClient(options) {
71
64
  const fetchImpl = options.fetchImpl ?? fetch;
72
65
  const baseUrl = options.controllerUrl.replace(/\/$/u, "");
66
+ const renewLease = async (leaseId) => {
67
+ return await readJsonResponse(await fetchImpl(`${baseUrl}/lease/${encodeURIComponent(leaseId)}/renew`, { method: "POST" }), "Controller lease renew API", isToolVmSshLease);
68
+ };
73
69
  return {
74
- keepLeaseAlive: async (leaseId) => {
75
- return await readJsonResponse(await fetchImpl(`${baseUrl}/lease/${leaseId}`), "Controller lease keepalive API", isGondolinLeaseResponse$1);
70
+ endActiveUse: async (leaseId, useId, request) => {
71
+ const response = await fetchImpl(`${baseUrl}/lease/${encodeURIComponent(leaseId)}/uses/${encodeURIComponent(useId)}`, {
72
+ body: JSON.stringify(request),
73
+ headers: { "content-type": "application/json" },
74
+ method: "DELETE"
75
+ });
76
+ if (!response.ok) {
77
+ const errorBody = await readErrorBody(response, "Controller active-use end API");
78
+ throw new ControllerLeaseRequestError({
79
+ bodyText: errorBody.bodyText,
80
+ context: "Controller active-use end API",
81
+ responseBody: errorBody.responseBody,
82
+ status: response.status
83
+ });
84
+ }
85
+ },
86
+ heartbeatActiveUse: async (leaseId, useId) => {
87
+ return await readJsonResponse(await fetchImpl(`${baseUrl}/lease/${encodeURIComponent(leaseId)}/uses/${encodeURIComponent(useId)}/heartbeat`, { method: "POST" }), "Controller active-use heartbeat API", isHeartbeatActiveUseResponse);
76
88
  },
89
+ renewLease,
77
90
  peekLease: async (leaseId) => {
78
- return await readJsonResponse(await fetchImpl(`${baseUrl}/lease/${leaseId}/peek`), "Controller lease peek API", isLeasePeekResponse);
91
+ return await readJsonResponse(await fetchImpl(`${baseUrl}/lease/${encodeURIComponent(leaseId)}/peek`), "Controller lease peek API", isToolVmLeasePeek);
79
92
  },
80
93
  publishOpenClawRuntimeStatus: async (report) => {
81
94
  const response = await fetchImpl(`${baseUrl}/zones/${encodeURIComponent(report.zoneId)}/openclaw-runtime-status`, {
@@ -93,8 +106,10 @@ function createLeaseClient(options) {
93
106
  });
94
107
  }
95
108
  },
96
- releaseLease: async (leaseId) => {
97
- const response = await fetchImpl(`${baseUrl}/lease/${leaseId}`, { method: "DELETE" });
109
+ releaseLease: async (leaseId, releaseOptions = {}) => {
110
+ const releaseUrl = new URL(`${baseUrl}/lease/${encodeURIComponent(leaseId)}`);
111
+ if (releaseOptions.force === true) releaseUrl.searchParams.set("force", "true");
112
+ const response = await fetchImpl(releaseUrl.toString(), { method: "DELETE" });
98
113
  if (!response.ok) {
99
114
  const errorBody = await readErrorBody(response, "Controller lease release API");
100
115
  throw new ControllerLeaseRequestError({
@@ -116,16 +131,18 @@ function createLeaseClient(options) {
116
131
  }),
117
132
  headers: { "content-type": "application/json" },
118
133
  method: "POST"
119
- }), "Controller lease API", isGondolinLeaseResponse$1);
134
+ }), "Controller lease API", isToolVmSshLease);
135
+ },
136
+ startActiveUse: async (leaseId, request) => {
137
+ return await readJsonResponse(await fetchImpl(`${baseUrl}/lease/${encodeURIComponent(leaseId)}/uses`, {
138
+ body: JSON.stringify(request),
139
+ headers: { "content-type": "application/json" },
140
+ method: "POST"
141
+ }), "Controller active-use start API", isStartActiveUseResponse);
120
142
  }
121
143
  };
122
144
  }
123
145
  //#endregion
124
- //#region src/sandbox-backend/sandbox-backend-contract.ts
125
- function isGondolinLeaseResponse(value) {
126
- return typeof value === "object" && value !== null && typeof value.leaseId === "string" && typeof value.tcpSlot === "number" && typeof value.workdir === "string" && typeof value.ssh === "object" && value.ssh !== null;
127
- }
128
- //#endregion
129
146
  //#region src/sandbox-backend/sandbox-shell-script.ts
130
147
  function buildShellScriptWithArgs(script, args) {
131
148
  if (!args || args.length === 0) return script;
@@ -151,14 +168,17 @@ function writeSandboxBackendLog(message) {
151
168
  function shouldRefreshCachedLease(error) {
152
169
  return error instanceof ControllerLeaseRequestError && error.status === 404;
153
170
  }
154
- function hasDisposeFunction(value) {
155
- return typeof value === "object" && value !== null && "dispose" in value && typeof value.dispose === "function";
171
+ function isCleanupNotFound(error) {
172
+ return error instanceof ControllerLeaseRequestError && error.status === 404;
173
+ }
174
+ function isDisposableFinalizeToken(value) {
175
+ return typeof value === "object" && value !== null && "dispose" in value && typeof Reflect.get(value, "dispose") === "function";
156
176
  }
157
- function renewalIntervalMsForLease(lease) {
158
- const fallbackRenewalIntervalMs = 6e4;
159
- const minimumRenewalIntervalMs = 1e3;
160
- if (lease.idleTtlMs === void 0) return fallbackRenewalIntervalMs;
161
- return Math.max(minimumRenewalIntervalMs, Math.min(fallbackRenewalIntervalMs, Math.floor(lease.idleTtlMs / 3)));
177
+ function isActiveUseFinalizeToken(value) {
178
+ return typeof value === "object" && value !== null && "activeUseHandle" in value && typeof Reflect.get(value, "activeUseHandle") === "object";
179
+ }
180
+ function activeUseOutcomeForFinalizeParams(finalizeParams) {
181
+ return finalizeParams.timedOut ? "timed-out" : finalizeParams.status === "completed" ? "completed" : "failed";
162
182
  }
163
183
  function createGondolinSandboxBackendFactory(options, dependencies) {
164
184
  const scopeCache = /* @__PURE__ */ new Map();
@@ -174,10 +194,10 @@ function createGondolinSandboxBackendFactory(options, dependencies) {
174
194
  const leaseClient = dependencies.createLeaseClient?.({ controllerUrl: options.controllerUrl }) ?? createLeaseClient({ controllerUrl: options.controllerUrl });
175
195
  const cachedEntry = scopeCache.get(cacheKey);
176
196
  if (cachedEntry) try {
177
- await leaseClient.keepLeaseAlive(cachedEntry.lease.leaseId);
197
+ await leaseClient.renewLease(cachedEntry.lease.leaseId);
178
198
  return cachedEntry.handle;
179
199
  } catch (error) {
180
- writeSandboxBackendLog(`lease keepalive failed for zone '${options.zoneId}' scope '${params.scopeKey}' lease '${cachedEntry.lease.leaseId}': ${formatUnknownError(error)}`);
200
+ writeSandboxBackendLog(`lease renew failed for zone '${options.zoneId}' scope '${params.scopeKey}' lease '${cachedEntry.lease.leaseId}': ${formatUnknownError(error)}`);
181
201
  if (!shouldRefreshCachedLease(error)) throw error;
182
202
  scopeCache.delete(cacheKey);
183
203
  }
@@ -190,27 +210,18 @@ function createGondolinSandboxBackendFactory(options, dependencies) {
190
210
  workMountDir: params.workspaceDir,
191
211
  zoneId: options.zoneId
192
212
  });
193
- if (!isGondolinLeaseResponse(leaseResponse)) throw new TypeError("Controller lease API returned an unexpected response.");
213
+ if (!isToolVmSshLease(leaseResponse)) throw new TypeError("Controller lease API returned an unexpected response.");
194
214
  const lease = leaseResponse;
195
215
  const handle = createSandboxBackendHandle({
196
216
  cfg: params.cfg,
197
217
  controllerUrl: options.controllerUrl,
198
218
  createFsBridgeBuilder: dependencies.createFsBridgeBuilder,
199
- keepLeaseAlive: async (operation) => {
200
- try {
201
- await leaseClient.keepLeaseAlive(lease.leaseId);
202
- } catch (error) {
203
- writeSandboxBackendLog(`lease command keepalive failed during ${operation} for zone '${options.zoneId}' scope '${params.scopeKey}' lease '${lease.leaseId}': ${formatUnknownError(error)}`);
204
- if (shouldRefreshCachedLease(error)) {
205
- if (scopeCache.get(cacheKey)?.lease.leaseId === lease.leaseId) scopeCache.delete(cacheKey);
206
- }
207
- throw error;
208
- }
209
- },
210
219
  lease,
220
+ leaseClient,
211
221
  runRemoteShellScript: dependencies.runRemoteShellScript,
212
222
  buildExecSpec: dependencies.buildExecSpec,
213
223
  scopeKey: params.scopeKey,
224
+ sessionKey: params.sessionKey,
214
225
  zoneId: options.zoneId
215
226
  });
216
227
  scopeCache.set(cacheKey, {
@@ -221,45 +232,63 @@ function createGondolinSandboxBackendFactory(options, dependencies) {
221
232
  };
222
233
  }
223
234
  function createSandboxBackendHandle(options) {
224
- const renewalIntervalMs = renewalIntervalMsForLease(options.lease);
225
- function beginLeaseRenewalTimer(operation) {
226
- const interval = setInterval(() => {
227
- options.keepLeaseAlive(`${operation} active`).catch((error) => {
228
- writeSandboxBackendLog(`lease command keepalive failed while ${operation} was active for zone '${options.zoneId}' scope '${options.scopeKey}' lease '${options.lease.leaseId}': ${formatUnknownError(error)}`);
229
- });
230
- }, renewalIntervalMs);
231
- if ("unref" in interval && typeof interval.unref === "function") interval.unref();
232
- return { dispose: () => clearInterval(interval) };
233
- }
234
- async function renewLeaseAfterOperation(operation, optionsForRenewal) {
235
- try {
236
- await options.keepLeaseAlive(operation);
237
- } catch (error) {
238
- if (!optionsForRenewal.hadPrimaryError) throw error;
239
- writeSandboxBackendLog(`lease command keepalive failed after ${operation} for zone '${options.zoneId}' scope '${options.scopeKey}' lease '${options.lease.leaseId}': ${formatUnknownError(error)}`);
240
- }
241
- }
242
- async function runWithLeaseRenewal(operation, runOperation) {
243
- await options.keepLeaseAlive(`${operation} start`);
244
- const renewalTimer = beginLeaseRenewalTimer(operation);
235
+ const createActiveUseHandle = async (correlation) => await createToolVmActiveUseHandle({
236
+ correlation,
237
+ endActiveUse: async (useId, request) => {
238
+ await options.leaseClient.endActiveUse(options.lease.leaseId, useId, request);
239
+ },
240
+ heartbeatActiveUse: async (useId) => await options.leaseClient.heartbeatActiveUse(options.lease.leaseId, useId),
241
+ isEndErrorTolerable: isCleanupNotFound,
242
+ logEndFailure: (error) => {
243
+ writeSandboxBackendLog(`active-use cleanup ignored for zone '${options.zoneId}' lease '${options.lease.leaseId}': ${formatUnknownError(error)}`);
244
+ },
245
+ logHeartbeatFailure: (error) => {
246
+ writeSandboxBackendLog(`active-use heartbeat failed for zone '${options.zoneId}' lease '${options.lease.leaseId}': ${formatUnknownError(error)}`);
247
+ },
248
+ startActiveUse: async (request) => await options.leaseClient.startActiveUse(options.lease.leaseId, request)
249
+ });
250
+ const runWithActiveUse = async (correlation, fn) => {
251
+ const activeUseHandle = await createActiveUseHandle(correlation);
245
252
  try {
246
- const result = await runOperation();
247
- renewalTimer.dispose();
248
- await renewLeaseAfterOperation(`${operation} end`, { hadPrimaryError: false });
253
+ const result = await fn();
254
+ await activeUseHandle.dispose("completed");
249
255
  return result;
250
256
  } catch (error) {
251
- renewalTimer.dispose();
252
- await renewLeaseAfterOperation(`${operation} end`, { hadPrimaryError: true });
257
+ await activeUseHandle.dispose("failed").catch((cleanupError) => {
258
+ writeSandboxBackendLog(`failed to end active use after operation failure for zone '${options.zoneId}' lease '${options.lease.leaseId}': ${formatUnknownError(cleanupError)}`);
259
+ });
253
260
  throw error;
254
261
  }
255
- }
256
- const boundRunRemoteShellScript = async (shellParams) => await runWithLeaseRenewal("fs bridge shell command", async () => await options.runRemoteShellScript({
262
+ };
263
+ const boundRunRemoteShellScript = async (shellParams) => await runWithActiveUse({
264
+ sessionKey: options.sessionKey,
265
+ toolName: "fs-bridge"
266
+ }, async () => await options.runRemoteShellScript({
257
267
  ...shellParams.allowFailure !== void 0 ? { allowFailure: shellParams.allowFailure } : {},
258
268
  script: buildShellScriptWithArgs(shellParams.script, shellParams.args),
259
269
  ...shellParams.signal !== void 0 ? { signal: shellParams.signal } : {},
260
270
  ssh: options.lease.ssh,
261
271
  ...shellParams.stdin !== void 0 ? { stdin: shellParams.stdin } : {}
262
272
  }));
273
+ const disposeInnerFinalizeToken = async (token) => {
274
+ if (isDisposableFinalizeToken(token)) await token.dispose();
275
+ };
276
+ const endActiveUseFinalizeToken = async (token, outcome) => {
277
+ let innerError;
278
+ try {
279
+ await disposeInnerFinalizeToken(token.innerToken);
280
+ } catch (error) {
281
+ innerError = error;
282
+ }
283
+ let activeUseError;
284
+ try {
285
+ await token.activeUseHandle.dispose(outcome);
286
+ } catch (error) {
287
+ activeUseError = error;
288
+ }
289
+ if (innerError) throw innerError;
290
+ if (activeUseError) throw activeUseError;
291
+ };
263
292
  const createFsBridge = options.createFsBridgeBuilder?.({
264
293
  remoteAgentWorkspaceDir: options.lease.workdir,
265
294
  remoteWorkspaceDir: options.lease.workdir,
@@ -275,47 +304,43 @@ function createSandboxBackendHandle(options) {
275
304
  runtimeLabel: options.lease.leaseId,
276
305
  workdir: options.lease.workdir,
277
306
  buildExecSpec: async (execParams) => {
278
- await options.keepLeaseAlive("exec spec build start");
279
- const execRenewalTimer = beginLeaseRenewalTimer("exec command");
280
- let execSpec;
307
+ const activeUseHandle = await createActiveUseHandle({
308
+ sessionKey: options.sessionKey,
309
+ toolName: "shell"
310
+ });
281
311
  try {
282
- execSpec = await options.buildExecSpec({
312
+ const execSpec = await options.buildExecSpec({
283
313
  command: execParams.command,
284
314
  env: execParams.env,
285
315
  ssh: options.lease.ssh,
286
316
  usePty: execParams.usePty,
287
317
  workdir: execParams.workdir ?? options.lease.workdir
288
318
  });
319
+ return {
320
+ ...execSpec,
321
+ finalizeToken: {
322
+ activeUseHandle,
323
+ ...execSpec.finalizeToken !== void 0 ? { innerToken: execSpec.finalizeToken } : {}
324
+ }
325
+ };
289
326
  } catch (error) {
290
- execRenewalTimer.dispose();
327
+ await activeUseHandle.dispose("failed").catch((cleanupError) => {
328
+ writeSandboxBackendLog(`failed to end active use after buildExecSpec failure for zone '${options.zoneId}' lease '${options.lease.leaseId}': ${formatUnknownError(cleanupError)}`);
329
+ });
291
330
  throw error;
292
331
  }
293
- return {
294
- ...execSpec,
295
- finalizeToken: {
296
- innerToken: execSpec.finalizeToken,
297
- leaseRenewalTimer: execRenewalTimer
298
- }
299
- };
300
332
  },
301
333
  finalizeExec: async (finalizeParams) => {
302
- const token = finalizeParams.token;
303
- const leaseRenewalTimer = typeof token === "object" && token !== null && "leaseRenewalTimer" in token && hasDisposeFunction(token.leaseRenewalTimer) ? token.leaseRenewalTimer : void 0;
304
- const innerToken = typeof token === "object" && token !== null && "innerToken" in token ? token.innerToken : token;
305
- let hadPrimaryError = false;
306
- let primaryError;
307
- try {
308
- if (hasDisposeFunction(innerToken)) await innerToken.dispose();
309
- } catch (error) {
310
- hadPrimaryError = true;
311
- primaryError = error;
312
- } finally {
313
- await leaseRenewalTimer?.dispose();
334
+ if (isActiveUseFinalizeToken(finalizeParams.token)) {
335
+ await endActiveUseFinalizeToken(finalizeParams.token, activeUseOutcomeForFinalizeParams(finalizeParams));
336
+ return;
314
337
  }
315
- await renewLeaseAfterOperation("exec finalize", { hadPrimaryError });
316
- if (hadPrimaryError) throw primaryError;
338
+ await disposeInnerFinalizeToken(finalizeParams.token);
317
339
  },
318
- runShellCommand: async (commandParams) => await runWithLeaseRenewal("shell command", async () => await options.runRemoteShellScript({
340
+ runShellCommand: async (commandParams) => await runWithActiveUse({
341
+ sessionKey: options.sessionKey,
342
+ toolName: "runShellCommand"
343
+ }, async () => await options.runRemoteShellScript({
319
344
  script: commandParams.script,
320
345
  ssh: options.lease.ssh
321
346
  }))
@@ -332,7 +357,8 @@ function createGondolinSandboxBackendManager(options, dependencies) {
332
357
  configLabelMatch: true,
333
358
  running: await leaseClient.peekLease(params.entry.containerName) !== null
334
359
  };
335
- } catch {
360
+ } catch (error) {
361
+ if (!(error instanceof ControllerLeaseRequestError) || error.status !== 404) throw error;
336
362
  return {
337
363
  configLabelMatch: false,
338
364
  running: false
@@ -340,7 +366,7 @@ function createGondolinSandboxBackendManager(options, dependencies) {
340
366
  }
341
367
  },
342
368
  removeRuntime: async (params) => {
343
- await (dependencies.createLeaseClient?.({ controllerUrl: options.controllerUrl }) ?? createLeaseClient({ controllerUrl: options.controllerUrl })).releaseLease(params.entry.containerName);
369
+ await (dependencies.createLeaseClient?.({ controllerUrl: options.controllerUrl }) ?? createLeaseClient({ controllerUrl: options.controllerUrl })).releaseLease(params.entry.containerName, { force: true });
344
370
  }
345
371
  };
346
372
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["isGondolinLeaseResponse","formatUnknownError"],"sources":["../src/controller-lease-client.ts","../src/sandbox-backend/sandbox-backend-contract.ts","../src/sandbox-backend/sandbox-shell-script.ts","../src/sandbox-backend/sandbox-backend-handle-factory.ts","../src/sandbox-backend/sandbox-backend-manager.ts","../src/gondolin-plugin-config.ts","../src/openclaw-backend-dependencies.ts","../src/openclaw-runtime-status.ts","../src/openclaw-sandbox-sdk-contract.ts","../src/zone-git-tool.ts","../src/openclaw-plugin-registration.ts","../src/index.ts"],"sourcesContent":["export interface GondolinLeaseResponse {\n\treadonly idleTtlMs?: number;\n\treadonly leaseId: string;\n\treadonly ssh: {\n\t\treadonly host: string;\n\t\treadonly identityPem: string;\n\t\treadonly knownHostsLine: string;\n\t\treadonly port: number;\n\t\treadonly user: string;\n\t};\n\treadonly tcpSlot: number;\n\treadonly workdir: string;\n}\n\nexport interface LeasePeekResponse {\n\treadonly createdAt: number;\n\treadonly lastUsedAt: number;\n\treadonly leaseId: string;\n\treadonly profileId: string;\n\treadonly scopeKey: string;\n\treadonly ssh: {\n\t\treadonly host: string;\n\t\treadonly port: number;\n\t\treadonly user: string;\n\t};\n\treadonly tcpSlot: number;\n\treadonly zoneId: string;\n}\n\nexport interface OpenClawRuntimeStatusReport {\n\treadonly findings: readonly {\n\t\treadonly hint: string;\n\t\treadonly id: string;\n\t\treadonly ok: boolean;\n\t}[];\n\treadonly pluginId: 'gondolin';\n\treadonly zoneId: string;\n}\n\nexport interface LeaseClient {\n\t// Cached handles use keepalive; read-only runtime probes use peekLease.\n\tkeepLeaseAlive(leaseId: string): Promise<GondolinLeaseResponse>;\n\tpeekLease(leaseId: string): Promise<LeasePeekResponse>;\n\tpublishOpenClawRuntimeStatus?(report: OpenClawRuntimeStatusReport): Promise<void>;\n\treleaseLease(leaseId: string): Promise<void>;\n\trequestLease(request: {\n\t\treadonly agentWorkspaceDir: string;\n\t\treadonly profileId: string;\n\t\treadonly scopeKey: string;\n\t\treadonly workMountDir: string;\n\t\treadonly zoneId: string;\n\t}): Promise<GondolinLeaseResponse>;\n}\n\nexport type ControllerLeaseRequestErrorKind = 'client-error' | 'server-error';\n\nexport class ControllerLeaseRequestError extends Error {\n\treadonly bodyText: string;\n\treadonly kind: ControllerLeaseRequestErrorKind;\n\treadonly responseBody: unknown;\n\treadonly status: number;\n\n\tconstructor(options: {\n\t\treadonly bodyText: string;\n\t\treadonly context: string;\n\t\treadonly responseBody: unknown;\n\t\treadonly status: number;\n\t}) {\n\t\tconst kind: ControllerLeaseRequestErrorKind =\n\t\t\toptions.status >= 400 && options.status < 500 ? 'client-error' : 'server-error';\n\t\tsuper(`${options.context} returned HTTP ${String(options.status)} (${kind})`);\n\t\tthis.bodyText = options.bodyText;\n\t\tthis.kind = kind;\n\t\tthis.responseBody = options.responseBody;\n\t\tthis.status = options.status;\n\t}\n}\n\nfunction objectValue(value: unknown): object | undefined {\n\treturn typeof value === 'object' && value !== null ? value : undefined;\n}\n\nfunction isSshResponse(value: unknown): value is GondolinLeaseResponse['ssh'] {\n\tconst record = objectValue(value);\n\treturn (\n\t\trecord !== undefined &&\n\t\ttypeof Reflect.get(record, 'host') === 'string' &&\n\t\ttypeof Reflect.get(record, 'identityPem') === 'string' &&\n\t\ttypeof Reflect.get(record, 'knownHostsLine') === 'string' &&\n\t\ttypeof Reflect.get(record, 'port') === 'number' &&\n\t\ttypeof Reflect.get(record, 'user') === 'string'\n\t);\n}\n\nfunction isLeasePeekSshResponse(value: unknown): value is LeasePeekResponse['ssh'] {\n\tconst record = objectValue(value);\n\treturn (\n\t\trecord !== undefined &&\n\t\ttypeof Reflect.get(record, 'host') === 'string' &&\n\t\ttypeof Reflect.get(record, 'port') === 'number' &&\n\t\ttypeof Reflect.get(record, 'user') === 'string'\n\t);\n}\n\nfunction isGondolinLeaseResponse(value: unknown): value is GondolinLeaseResponse {\n\tconst record = objectValue(value);\n\treturn (\n\t\trecord !== undefined &&\n\t\t(Reflect.get(record, 'idleTtlMs') === undefined ||\n\t\t\ttypeof Reflect.get(record, 'idleTtlMs') === 'number') &&\n\t\ttypeof Reflect.get(record, 'leaseId') === 'string' &&\n\t\tisSshResponse(Reflect.get(record, 'ssh')) &&\n\t\ttypeof Reflect.get(record, 'tcpSlot') === 'number' &&\n\t\ttypeof Reflect.get(record, 'workdir') === 'string'\n\t);\n}\n\nfunction isLeasePeekResponse(value: unknown): value is LeasePeekResponse {\n\tconst record = objectValue(value);\n\treturn (\n\t\trecord !== undefined &&\n\t\ttypeof Reflect.get(record, 'createdAt') === 'number' &&\n\t\ttypeof Reflect.get(record, 'lastUsedAt') === 'number' &&\n\t\ttypeof Reflect.get(record, 'leaseId') === 'string' &&\n\t\ttypeof Reflect.get(record, 'profileId') === 'string' &&\n\t\ttypeof Reflect.get(record, 'scopeKey') === 'string' &&\n\t\tisLeasePeekSshResponse(Reflect.get(record, 'ssh')) &&\n\t\ttypeof Reflect.get(record, 'tcpSlot') === 'number' &&\n\t\ttypeof Reflect.get(record, 'zoneId') === 'string'\n\t);\n}\n\nfunction formatUnknownError(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction writeLeaseClientLog(message: string): void {\n\tprocess.stderr.write(`[openclaw-agent-vm-plugin] ${message}\\n`);\n}\n\nfunction parseJsonBody(bodyText: string, context: string): unknown {\n\ttry {\n\t\treturn JSON.parse(bodyText);\n\t} catch (error) {\n\t\twriteLeaseClientLog(`${context} returned a non-JSON error body: ${formatUnknownError(error)}`);\n\t\treturn undefined;\n\t}\n}\n\nasync function readErrorBody(\n\tresponse: Response,\n\tcontext: string,\n): Promise<{\n\treadonly bodyText: string;\n\treadonly responseBody: unknown;\n}> {\n\tconst bodyText = await response.text().catch(() => '(unreadable)');\n\treturn {\n\t\tbodyText,\n\t\tresponseBody: bodyText === '(unreadable)' ? undefined : parseJsonBody(bodyText, context),\n\t};\n}\n\nasync function readJsonResponse<TValue>(\n\tresponse: Response,\n\tcontext: string,\n\tisExpectedResponse: (value: unknown) => value is TValue,\n): Promise<TValue> {\n\tif (!response.ok) {\n\t\tconst errorBody = await readErrorBody(response, context);\n\t\tthrow new ControllerLeaseRequestError({\n\t\t\tbodyText: errorBody.bodyText,\n\t\t\tcontext,\n\t\t\tresponseBody: errorBody.responseBody,\n\t\t\tstatus: response.status,\n\t\t});\n\t}\n\tconst payload = await response.json();\n\tif (!isExpectedResponse(payload)) {\n\t\tthrow new TypeError(\n\t\t\t`${context} returned an invalid response: ${JSON.stringify(payload).slice(0, 200)}`,\n\t\t);\n\t}\n\treturn payload;\n}\n\nexport function createLeaseClient(options: {\n\treadonly controllerUrl: string;\n\treadonly fetchImpl?: (input: string | URL | Request, init?: RequestInit) => Promise<Response>;\n}): LeaseClient {\n\tconst fetchImpl = options.fetchImpl ?? fetch;\n\tconst baseUrl = options.controllerUrl.replace(/\\/$/u, '');\n\n\treturn {\n\t\tkeepLeaseAlive: async (leaseId: string): Promise<GondolinLeaseResponse> => {\n\t\t\tconst response = await fetchImpl(`${baseUrl}/lease/${leaseId}`);\n\t\t\treturn await readJsonResponse(\n\t\t\t\tresponse,\n\t\t\t\t'Controller lease keepalive API',\n\t\t\t\tisGondolinLeaseResponse,\n\t\t\t);\n\t\t},\n\t\tpeekLease: async (leaseId: string): Promise<LeasePeekResponse> => {\n\t\t\tconst response = await fetchImpl(`${baseUrl}/lease/${leaseId}/peek`);\n\t\t\treturn await readJsonResponse(response, 'Controller lease peek API', isLeasePeekResponse);\n\t\t},\n\t\tpublishOpenClawRuntimeStatus: async (report): Promise<void> => {\n\t\t\tconst response = await fetchImpl(\n\t\t\t\t`${baseUrl}/zones/${encodeURIComponent(report.zoneId)}/openclaw-runtime-status`,\n\t\t\t\t{\n\t\t\t\t\tbody: JSON.stringify(report),\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'content-type': 'application/json',\n\t\t\t\t\t},\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t},\n\t\t\t);\n\t\t\tif (!response.ok) {\n\t\t\t\tconst errorBody = await readErrorBody(response, 'Controller OpenClaw runtime status API');\n\t\t\t\tthrow new ControllerLeaseRequestError({\n\t\t\t\t\tbodyText: errorBody.bodyText,\n\t\t\t\t\tcontext: 'Controller OpenClaw runtime status API',\n\t\t\t\t\tresponseBody: errorBody.responseBody,\n\t\t\t\t\tstatus: response.status,\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\treleaseLease: async (leaseId: string): Promise<void> => {\n\t\t\tconst response = await fetchImpl(`${baseUrl}/lease/${leaseId}`, {\n\t\t\t\tmethod: 'DELETE',\n\t\t\t});\n\t\t\tif (!response.ok) {\n\t\t\t\tconst errorBody = await readErrorBody(response, 'Controller lease release API');\n\t\t\t\tthrow new ControllerLeaseRequestError({\n\t\t\t\t\tbodyText: errorBody.bodyText,\n\t\t\t\t\tcontext: 'Controller lease release API',\n\t\t\t\t\tresponseBody: errorBody.responseBody,\n\t\t\t\t\tstatus: response.status,\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\trequestLease: async (request): Promise<GondolinLeaseResponse> => {\n\t\t\tconst response = await fetchImpl(`${baseUrl}/lease`, {\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tagentWorkspaceDir: request.agentWorkspaceDir,\n\t\t\t\t\tprofileId: request.profileId,\n\t\t\t\t\tscopeKey: request.scopeKey,\n\t\t\t\t\tworkMountDir: request.workMountDir,\n\t\t\t\t\tzoneId: request.zoneId,\n\t\t\t\t}),\n\t\t\t\theaders: {\n\t\t\t\t\t'content-type': 'application/json',\n\t\t\t\t},\n\t\t\t\tmethod: 'POST',\n\t\t\t});\n\t\t\treturn await readJsonResponse(response, 'Controller lease API', isGondolinLeaseResponse);\n\t\t},\n\t};\n}\n","import type { GondolinLeaseResponse, LeaseClient } from '../controller-lease-client.js';\n\nexport function isGondolinLeaseResponse(value: unknown): value is GondolinLeaseResponse {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\ttypeof (value as { leaseId?: unknown }).leaseId === 'string' &&\n\t\ttypeof (value as { tcpSlot?: unknown }).tcpSlot === 'number' &&\n\t\ttypeof (value as { workdir?: unknown }).workdir === 'string' &&\n\t\ttypeof (value as { ssh?: unknown }).ssh === 'object' &&\n\t\t(value as { ssh?: unknown }).ssh !== null\n\t);\n}\n\nexport interface FsBridgeLeaseContext {\n\treadonly remoteAgentWorkspaceDir: string;\n\treadonly remoteWorkspaceDir: string;\n\treadonly runRemoteShellScript: (params: {\n\t\treadonly allowFailure?: boolean;\n\t\treadonly args?: string[];\n\t\treadonly script: string;\n\t\treadonly signal?: AbortSignal;\n\t\treadonly stdin?: Buffer | string;\n\t}) => Promise<{\n\t\treadonly code: number;\n\t\treadonly stderr: Buffer;\n\t\treadonly stdout: Buffer;\n\t}>;\n}\n\nexport interface GondolinFsBridge {\n\tmkdirp(params: {\n\t\treadonly cwd?: string;\n\t\treadonly filePath: string;\n\t\treadonly signal?: AbortSignal;\n\t}): Promise<void>;\n\treadFile(params: {\n\t\treadonly cwd?: string;\n\t\treadonly filePath: string;\n\t\treadonly signal?: AbortSignal;\n\t}): Promise<Buffer>;\n\tremove(params: {\n\t\treadonly cwd?: string;\n\t\treadonly filePath: string;\n\t\treadonly force?: boolean;\n\t\treadonly recursive?: boolean;\n\t\treadonly signal?: AbortSignal;\n\t}): Promise<void>;\n\trename(params: {\n\t\treadonly cwd?: string;\n\t\treadonly from: string;\n\t\treadonly signal?: AbortSignal;\n\t\treadonly to: string;\n\t}): Promise<void>;\n\tresolvePath(params: { readonly cwd?: string; readonly filePath: string }): {\n\t\treadonly containerPath: string;\n\t\treadonly relativePath: string;\n\t};\n\tstat(params: {\n\t\treadonly cwd?: string;\n\t\treadonly filePath: string;\n\t\treadonly signal?: AbortSignal;\n\t}): Promise<{\n\t\treadonly mtimeMs: number;\n\t\treadonly size: number;\n\t\treadonly type: 'directory' | 'file' | 'other';\n\t} | null>;\n\twriteFile(params: {\n\t\treadonly cwd?: string;\n\t\treadonly data: Buffer | string;\n\t\treadonly encoding?: BufferEncoding;\n\t\treadonly filePath: string;\n\t\treadonly mkdir?: boolean;\n\t\treadonly signal?: AbortSignal;\n\t}): Promise<void>;\n}\n\nexport interface CreateBackendDependencies {\n\treadonly buildExecSpec: (params: {\n\t\treadonly command: string;\n\t\treadonly env: Record<string, string>;\n\t\treadonly ssh: GondolinLeaseResponse['ssh'];\n\t\treadonly usePty: boolean;\n\t\treadonly workdir: string;\n\t}) => Promise<{\n\t\treadonly argv: string[];\n\t\treadonly env: Record<string, string>;\n\t\treadonly finalizeToken?: unknown;\n\t\treadonly stdinMode: 'pipe-open' | 'pipe-closed';\n\t}>;\n\treadonly createFsBridgeBuilder?: (\n\t\tleaseContext: FsBridgeLeaseContext,\n\t) => (params: { readonly sandbox: unknown }) => GondolinFsBridge;\n\treadonly createLeaseClient?: (options: { readonly controllerUrl: string }) => LeaseClient;\n\treadonly runRemoteShellScript: (params: {\n\t\treadonly allowFailure?: boolean;\n\t\treadonly script: string;\n\t\treadonly signal?: AbortSignal;\n\t\treadonly ssh: GondolinLeaseResponse['ssh'];\n\t\treadonly stdin?: Buffer | string;\n\t}) => Promise<{\n\t\treadonly code: number;\n\t\treadonly stderr: Buffer;\n\t\treadonly stdout: Buffer;\n\t}>;\n}\n\nexport interface GondolinSandboxBackendHandle {\n\treadonly configLabel?: string;\n\treadonly configLabelKind?: string;\n\tcreateFsBridge?: (params: { readonly sandbox: unknown }) => GondolinFsBridge;\n\tenv?: Record<string, string>;\n\treadonly id: string;\n\treadonly runtimeId: string;\n\treadonly runtimeLabel: string;\n\treadonly workdir: string;\n\tbuildExecSpec(params: {\n\t\treadonly command: string;\n\t\treadonly env: Record<string, string>;\n\t\treadonly usePty: boolean;\n\t\treadonly workdir?: string;\n\t}): Promise<{\n\t\treadonly argv: string[];\n\t\treadonly env: Record<string, string>;\n\t\treadonly finalizeToken?: unknown;\n\t\treadonly stdinMode: 'pipe-open' | 'pipe-closed';\n\t}>;\n\tfinalizeExec?: (params: {\n\t\treadonly exitCode: number | null;\n\t\treadonly status: 'completed' | 'failed';\n\t\treadonly timedOut: boolean;\n\t\treadonly token?: unknown;\n\t}) => Promise<void>;\n\trunShellCommand(params: { readonly script: string }): Promise<{\n\t\treadonly code: number;\n\t\treadonly stderr: Buffer;\n\t\treadonly stdout: Buffer;\n\t}>;\n}\n\nexport interface CachedScopeEntry {\n\treadonly handle: GondolinSandboxBackendHandle;\n\treadonly lease: GondolinLeaseResponse;\n}\n","export function buildShellScriptWithArgs(script: string, args?: readonly string[]): string {\n\tif (!args || args.length === 0) {\n\t\treturn script;\n\t}\n\n\tconst escapedArgs = args.map((arg) => `'${arg.replace(/'/g, \"'\\\\''\")}'`).join(' ');\n\treturn `set -- ${escapedArgs}; ${script}`;\n}\n","import {\n\tControllerLeaseRequestError,\n\tcreateLeaseClient,\n\ttype GondolinLeaseResponse,\n\ttype OpenClawRuntimeStatusReport,\n} from '../controller-lease-client.js';\nimport {\n\ttype CachedScopeEntry,\n\ttype CreateBackendDependencies,\n\ttype FsBridgeLeaseContext,\n\ttype GondolinSandboxBackendHandle,\n\tisGondolinLeaseResponse,\n} from './sandbox-backend-contract.js';\nimport { buildShellScriptWithArgs } from './sandbox-shell-script.js';\n\nfunction scopeCacheKey(params: {\n\treadonly agentWorkspaceDir: string;\n\treadonly profileId: string;\n\treadonly scopeKey: string;\n\treadonly workspaceDir: string;\n\treadonly zoneId: string;\n}): string {\n\treturn [\n\t\tparams.zoneId,\n\t\tparams.scopeKey,\n\t\tparams.profileId,\n\t\tparams.agentWorkspaceDir,\n\t\tparams.workspaceDir,\n\t].join('\\0');\n}\n\nfunction formatUnknownError(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction writeSandboxBackendLog(message: string): void {\n\tprocess.stderr.write(`[openclaw-agent-vm-plugin] ${message}\\n`);\n}\n\nfunction shouldRefreshCachedLease(error: unknown): boolean {\n\treturn error instanceof ControllerLeaseRequestError && error.status === 404;\n}\n\nfunction hasDisposeFunction(\n\tvalue: unknown,\n): value is { readonly dispose: () => void | Promise<void> } {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\t'dispose' in value &&\n\t\ttypeof value.dispose === 'function'\n\t);\n}\n\nfunction renewalIntervalMsForLease(lease: GondolinLeaseResponse): number {\n\tconst fallbackRenewalIntervalMs = 60_000;\n\tconst minimumRenewalIntervalMs = 1_000;\n\tif (lease.idleTtlMs === undefined) {\n\t\treturn fallbackRenewalIntervalMs;\n\t}\n\treturn Math.max(\n\t\tminimumRenewalIntervalMs,\n\t\tMath.min(fallbackRenewalIntervalMs, Math.floor(lease.idleTtlMs / 3)),\n\t);\n}\n\nexport function createGondolinSandboxBackendFactory(\n\toptions: {\n\t\treadonly controllerUrl: string;\n\t\treadonly openClawRuntimeStatusProvider?: () => OpenClawRuntimeStatusReport | undefined;\n\t\treadonly profileId?: string;\n\t\treadonly zoneId: string;\n\t},\n\tdependencies: CreateBackendDependencies,\n): (params: {\n\treadonly agentWorkspaceDir: string;\n\treadonly cfg: {\n\t\treadonly docker?: {\n\t\t\treadonly env?: Record<string, string>;\n\t\t};\n\t};\n\treadonly scopeKey: string;\n\treadonly sessionKey: string;\n\treadonly workspaceDir: string;\n}) => Promise<GondolinSandboxBackendHandle> {\n\tconst scopeCache = new Map<string, CachedScopeEntry>();\n\n\treturn async (params) => {\n\t\tconst profileId = options.profileId ?? 'standard';\n\t\tconst cacheKey = scopeCacheKey({\n\t\t\tagentWorkspaceDir: params.agentWorkspaceDir,\n\t\t\tprofileId,\n\t\t\tscopeKey: params.scopeKey,\n\t\t\tworkspaceDir: params.workspaceDir,\n\t\t\tzoneId: options.zoneId,\n\t\t});\n\t\tconst leaseClient =\n\t\t\tdependencies.createLeaseClient?.({\n\t\t\t\tcontrollerUrl: options.controllerUrl,\n\t\t\t}) ?? createLeaseClient({ controllerUrl: options.controllerUrl });\n\t\tconst cachedEntry = scopeCache.get(cacheKey);\n\t\tif (cachedEntry) {\n\t\t\ttry {\n\t\t\t\tawait leaseClient.keepLeaseAlive(cachedEntry.lease.leaseId);\n\t\t\t\treturn cachedEntry.handle;\n\t\t\t} catch (error) {\n\t\t\t\twriteSandboxBackendLog(\n\t\t\t\t\t`lease keepalive failed for zone '${options.zoneId}' scope '${params.scopeKey}' lease '${cachedEntry.lease.leaseId}': ${formatUnknownError(error)}`,\n\t\t\t\t);\n\t\t\t\tif (!shouldRefreshCachedLease(error)) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tscopeCache.delete(cacheKey);\n\t\t\t}\n\t\t}\n\t\t// OpenClaw SDK still names the selected sandbox path `workspaceDir`.\n\t\t// agent-vm's controller calls the same value `workMountDir` because it\n\t\t// backs the Tool VM /work mount.\n\t\tconst runtimeStatus = options.openClawRuntimeStatusProvider?.();\n\t\tif (runtimeStatus && leaseClient.publishOpenClawRuntimeStatus) {\n\t\t\tawait leaseClient.publishOpenClawRuntimeStatus(runtimeStatus);\n\t\t}\n\t\tconst leaseResponse = await leaseClient.requestLease({\n\t\t\tagentWorkspaceDir: params.agentWorkspaceDir,\n\t\t\tprofileId,\n\t\t\tscopeKey: params.scopeKey,\n\t\t\tworkMountDir: params.workspaceDir,\n\t\t\tzoneId: options.zoneId,\n\t\t});\n\t\tif (!isGondolinLeaseResponse(leaseResponse)) {\n\t\t\tthrow new TypeError('Controller lease API returned an unexpected response.');\n\t\t}\n\n\t\tconst lease = leaseResponse;\n\t\tconst handle = createSandboxBackendHandle({\n\t\t\tcfg: params.cfg,\n\t\t\tcontrollerUrl: options.controllerUrl,\n\t\t\tcreateFsBridgeBuilder: dependencies.createFsBridgeBuilder,\n\t\t\tkeepLeaseAlive: async (operation) => {\n\t\t\t\ttry {\n\t\t\t\t\tawait leaseClient.keepLeaseAlive(lease.leaseId);\n\t\t\t\t} catch (error) {\n\t\t\t\t\twriteSandboxBackendLog(\n\t\t\t\t\t\t`lease command keepalive failed during ${operation} for zone '${options.zoneId}' scope '${params.scopeKey}' lease '${lease.leaseId}': ${formatUnknownError(error)}`,\n\t\t\t\t\t);\n\t\t\t\t\tif (shouldRefreshCachedLease(error)) {\n\t\t\t\t\t\tconst cachedEntryForLease = scopeCache.get(cacheKey);\n\t\t\t\t\t\tif (cachedEntryForLease?.lease.leaseId === lease.leaseId) {\n\t\t\t\t\t\t\tscopeCache.delete(cacheKey);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t},\n\t\t\tlease,\n\t\t\trunRemoteShellScript: dependencies.runRemoteShellScript,\n\t\t\tbuildExecSpec: dependencies.buildExecSpec,\n\t\t\tscopeKey: params.scopeKey,\n\t\t\tzoneId: options.zoneId,\n\t\t});\n\t\tscopeCache.set(cacheKey, { handle, lease });\n\t\treturn handle;\n\t};\n}\n\nfunction createSandboxBackendHandle(options: {\n\treadonly buildExecSpec: CreateBackendDependencies['buildExecSpec'];\n\treadonly cfg: {\n\t\treadonly docker?: {\n\t\t\treadonly env?: Record<string, string>;\n\t\t};\n\t};\n\treadonly controllerUrl: string;\n\treadonly createFsBridgeBuilder?: CreateBackendDependencies['createFsBridgeBuilder'];\n\treadonly keepLeaseAlive: (operation: string) => Promise<void>;\n\treadonly lease: GondolinLeaseResponse;\n\treadonly runRemoteShellScript: CreateBackendDependencies['runRemoteShellScript'];\n\treadonly scopeKey: string;\n\treadonly zoneId: string;\n}): GondolinSandboxBackendHandle {\n\tconst renewalIntervalMs = renewalIntervalMsForLease(options.lease);\n\n\tfunction beginLeaseRenewalTimer(operation: string): { readonly dispose: () => void } {\n\t\tconst interval = setInterval(() => {\n\t\t\tvoid options.keepLeaseAlive(`${operation} active`).catch((error: unknown) => {\n\t\t\t\twriteSandboxBackendLog(\n\t\t\t\t\t`lease command keepalive failed while ${operation} was active for zone '${options.zoneId}' scope '${options.scopeKey}' lease '${options.lease.leaseId}': ${formatUnknownError(error)}`,\n\t\t\t\t);\n\t\t\t});\n\t\t}, renewalIntervalMs);\n\t\tif ('unref' in interval && typeof interval.unref === 'function') {\n\t\t\tinterval.unref();\n\t\t}\n\t\treturn {\n\t\t\tdispose: () => clearInterval(interval),\n\t\t};\n\t}\n\n\tasync function renewLeaseAfterOperation(\n\t\toperation: string,\n\t\toptionsForRenewal: { readonly hadPrimaryError: boolean },\n\t): Promise<void> {\n\t\ttry {\n\t\t\tawait options.keepLeaseAlive(operation);\n\t\t} catch (error) {\n\t\t\tif (!optionsForRenewal.hadPrimaryError) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\twriteSandboxBackendLog(\n\t\t\t\t`lease command keepalive failed after ${operation} for zone '${options.zoneId}' scope '${options.scopeKey}' lease '${options.lease.leaseId}': ${formatUnknownError(error)}`,\n\t\t\t);\n\t\t}\n\t}\n\n\tasync function runWithLeaseRenewal<TValue>(\n\t\toperation: string,\n\t\trunOperation: () => Promise<TValue>,\n\t): Promise<TValue> {\n\t\tawait options.keepLeaseAlive(`${operation} start`);\n\t\tconst renewalTimer = beginLeaseRenewalTimer(operation);\n\t\ttry {\n\t\t\tconst result = await runOperation();\n\t\t\trenewalTimer.dispose();\n\t\t\tawait renewLeaseAfterOperation(`${operation} end`, { hadPrimaryError: false });\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\trenewalTimer.dispose();\n\t\t\tawait renewLeaseAfterOperation(`${operation} end`, { hadPrimaryError: true });\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tconst boundRunRemoteShellScript: FsBridgeLeaseContext['runRemoteShellScript'] = async (\n\t\tshellParams,\n\t) =>\n\t\tawait runWithLeaseRenewal(\n\t\t\t'fs bridge shell command',\n\t\t\tasync () =>\n\t\t\t\tawait options.runRemoteShellScript({\n\t\t\t\t\t...(shellParams.allowFailure !== undefined\n\t\t\t\t\t\t? { allowFailure: shellParams.allowFailure }\n\t\t\t\t\t\t: {}),\n\t\t\t\t\tscript: buildShellScriptWithArgs(shellParams.script, shellParams.args),\n\t\t\t\t\t...(shellParams.signal !== undefined ? { signal: shellParams.signal } : {}),\n\t\t\t\t\tssh: options.lease.ssh,\n\t\t\t\t\t...(shellParams.stdin !== undefined ? { stdin: shellParams.stdin } : {}),\n\t\t\t\t}),\n\t\t);\n\n\tconst createFsBridge = options.createFsBridgeBuilder?.({\n\t\tremoteAgentWorkspaceDir: options.lease.workdir,\n\t\tremoteWorkspaceDir: options.lease.workdir,\n\t\trunRemoteShellScript: boundRunRemoteShellScript,\n\t});\n\n\treturn {\n\t\t...(createFsBridge ? { createFsBridge } : {}),\n\t\t...(options.cfg.docker?.env ? { env: options.cfg.docker.env } : {}),\n\t\tconfigLabel: `${options.controllerUrl} (${options.zoneId})`,\n\t\tconfigLabelKind: 'VM',\n\t\tid: 'gondolin',\n\t\truntimeId: options.lease.leaseId,\n\t\truntimeLabel: options.lease.leaseId,\n\t\tworkdir: options.lease.workdir,\n\t\tbuildExecSpec: async (execParams) => {\n\t\t\tawait options.keepLeaseAlive('exec spec build start');\n\t\t\tconst execRenewalTimer = beginLeaseRenewalTimer('exec command');\n\t\t\tlet execSpec: Awaited<ReturnType<CreateBackendDependencies['buildExecSpec']>>;\n\t\t\ttry {\n\t\t\t\texecSpec = await options.buildExecSpec({\n\t\t\t\t\tcommand: execParams.command,\n\t\t\t\t\tenv: execParams.env,\n\t\t\t\t\tssh: options.lease.ssh,\n\t\t\t\t\tusePty: execParams.usePty,\n\t\t\t\t\tworkdir: execParams.workdir ?? options.lease.workdir,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\texecRenewalTimer.dispose();\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\t...execSpec,\n\t\t\t\tfinalizeToken: {\n\t\t\t\t\tinnerToken: execSpec.finalizeToken,\n\t\t\t\t\tleaseRenewalTimer: execRenewalTimer,\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\tfinalizeExec: async (finalizeParams) => {\n\t\t\tconst token = finalizeParams.token;\n\t\t\tconst leaseRenewalTimer =\n\t\t\t\ttypeof token === 'object' &&\n\t\t\t\ttoken !== null &&\n\t\t\t\t'leaseRenewalTimer' in token &&\n\t\t\t\thasDisposeFunction(token.leaseRenewalTimer)\n\t\t\t\t\t? token.leaseRenewalTimer\n\t\t\t\t\t: undefined;\n\t\t\tconst innerToken =\n\t\t\t\ttypeof token === 'object' && token !== null && 'innerToken' in token\n\t\t\t\t\t? token.innerToken\n\t\t\t\t\t: token;\n\t\t\tlet hadPrimaryError = false;\n\t\t\tlet primaryError: unknown;\n\t\t\ttry {\n\t\t\t\tif (hasDisposeFunction(innerToken)) {\n\t\t\t\t\tawait innerToken.dispose();\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\thadPrimaryError = true;\n\t\t\t\tprimaryError = error;\n\t\t\t} finally {\n\t\t\t\tawait leaseRenewalTimer?.dispose();\n\t\t\t}\n\t\t\tawait renewLeaseAfterOperation('exec finalize', {\n\t\t\t\thadPrimaryError,\n\t\t\t});\n\t\t\tif (hadPrimaryError) {\n\t\t\t\tthrow primaryError;\n\t\t\t}\n\t\t},\n\t\trunShellCommand: async (commandParams) =>\n\t\t\tawait runWithLeaseRenewal(\n\t\t\t\t'shell command',\n\t\t\t\tasync () =>\n\t\t\t\t\tawait options.runRemoteShellScript({\n\t\t\t\t\t\tscript: commandParams.script,\n\t\t\t\t\t\tssh: options.lease.ssh,\n\t\t\t\t\t}),\n\t\t\t),\n\t} satisfies GondolinSandboxBackendHandle;\n}\n","import { createLeaseClient } from '../controller-lease-client.js';\nimport type { CreateBackendDependencies } from './sandbox-backend-contract.js';\n\nexport function createGondolinSandboxBackendManager(\n\toptions: {\n\t\treadonly controllerUrl: string;\n\t\treadonly zoneId: string;\n\t},\n\tdependencies: CreateBackendDependencies,\n): {\n\tdescribeRuntime: (params: {\n\t\treadonly entry: { readonly containerName: string };\n\t}) => Promise<{ readonly configLabelMatch: boolean; readonly running: boolean }>;\n\tremoveRuntime: (params: { readonly entry: { readonly containerName: string } }) => Promise<void>;\n} {\n\treturn {\n\t\tdescribeRuntime: async (params) => {\n\t\t\tconst leaseClient =\n\t\t\t\tdependencies.createLeaseClient?.({\n\t\t\t\t\tcontrollerUrl: options.controllerUrl,\n\t\t\t\t}) ?? createLeaseClient({ controllerUrl: options.controllerUrl });\n\t\t\ttry {\n\t\t\t\tconst leaseStatus = await leaseClient.peekLease(params.entry.containerName);\n\t\t\t\treturn { configLabelMatch: true, running: leaseStatus !== null };\n\t\t\t} catch {\n\t\t\t\treturn { configLabelMatch: false, running: false };\n\t\t\t}\n\t\t},\n\t\tremoveRuntime: async (params) => {\n\t\t\tconst leaseClient =\n\t\t\t\tdependencies.createLeaseClient?.({\n\t\t\t\t\tcontrollerUrl: options.controllerUrl,\n\t\t\t\t}) ?? createLeaseClient({ controllerUrl: options.controllerUrl });\n\t\t\tawait leaseClient.releaseLease(params.entry.containerName);\n\t\t},\n\t};\n}\n","export interface ResolvedGondolinPluginConfig {\n\treadonly controllerUrl: string;\n\treadonly profileId?: string;\n\treadonly zoneGitToken?: string;\n\treadonly zoneGitTokenEnv?: string;\n\treadonly zoneId: string;\n}\n\nexport function resolveGondolinPluginConfig(\n\tconfig: Record<string, unknown>,\n): ResolvedGondolinPluginConfig {\n\tif (typeof config.controllerUrl !== 'string' || typeof config.zoneId !== 'string') {\n\t\tthrow new Error('Gondolin plugin config requires controllerUrl and zoneId.');\n\t}\n\n\treturn {\n\t\tcontrollerUrl: config.controllerUrl,\n\t\t...(typeof config.profileId === 'string' ? { profileId: config.profileId } : {}),\n\t\t...(typeof config.zoneGitToken === 'string' ? { zoneGitToken: config.zoneGitToken } : {}),\n\t\t...(typeof config.zoneGitTokenEnv === 'string'\n\t\t\t? { zoneGitTokenEnv: config.zoneGitTokenEnv }\n\t\t\t: {}),\n\t\tzoneId: config.zoneId,\n\t};\n}\n","import type { SshHelpers, SshSandboxSession } from './openclaw-sandbox-sdk-contract.js';\nimport type {\n\tCreateBackendDependencies,\n\tFsBridgeLeaseContext,\n\tGondolinFsBridge,\n} from './sandbox-backend-factory.js';\n\nexport function createBackendDeps(ssh: SshHelpers): {\n\treadonly buildExecSpec: CreateBackendDependencies['buildExecSpec'];\n\treadonly createFsBridgeBuilder: (\n\t\tleaseContext: FsBridgeLeaseContext,\n\t) => (params: { readonly sandbox: unknown }) => GondolinFsBridge;\n\treadonly runRemoteShellScript: CreateBackendDependencies['runRemoteShellScript'];\n} {\n\treturn {\n\t\tbuildExecSpec: async ({ command, env, ssh: sshCreds, usePty, workdir }) => {\n\t\t\tconst session = await ssh.createSshSandboxSessionFromSettings({\n\t\t\t\tcommand: 'ssh',\n\t\t\t\tidentityData: sshCreds.identityPem,\n\t\t\t\tstrictHostKeyChecking: false,\n\t\t\t\ttarget: `${sshCreds.user}@${sshCreds.host}:${sshCreds.port}`,\n\t\t\t\tupdateHostKeys: false,\n\t\t\t\tworkspaceRoot: workdir,\n\t\t\t});\n\t\t\tconst disposeSshSandboxSession = ssh.disposeSshSandboxSession;\n\t\t\treturn {\n\t\t\t\targv: ssh.buildSshSandboxArgv({\n\t\t\t\t\tremoteCommand: ssh.buildExecRemoteCommand({\n\t\t\t\t\t\tcommand,\n\t\t\t\t\t\tenv,\n\t\t\t\t\t\tworkdir,\n\t\t\t\t\t}),\n\t\t\t\t\tsession,\n\t\t\t\t\ttty: usePty,\n\t\t\t\t}),\n\t\t\t\tenv: ssh.sanitizeEnvVars(process.env).allowed,\n\t\t\t\tfinalizeToken: {\n\t\t\t\t\tdispose: async (): Promise<void> => {\n\t\t\t\t\t\tif (disposeSshSandboxSession) {\n\t\t\t\t\t\t\tawait disposeSshSandboxSession(session);\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tsession,\n\t\t\t\t},\n\t\t\t\tstdinMode: 'pipe-open' as const,\n\t\t\t};\n\t\t},\n\t\tcreateFsBridgeBuilder:\n\t\t\t(leaseContext: FsBridgeLeaseContext) =>\n\t\t\t(params: { readonly sandbox: unknown }): GondolinFsBridge =>\n\t\t\t\tssh.createRemoteShellSandboxFsBridge({\n\t\t\t\t\tsandbox: params.sandbox,\n\t\t\t\t\truntime: {\n\t\t\t\t\t\tremoteAgentWorkspaceDir: leaseContext.remoteAgentWorkspaceDir,\n\t\t\t\t\t\tremoteWorkspaceDir: leaseContext.remoteWorkspaceDir,\n\t\t\t\t\t\trunRemoteShellScript: leaseContext.runRemoteShellScript,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\trunRemoteShellScript: async ({ allowFailure, script, signal, ssh: sshCreds, stdin }) => {\n\t\t\tconst session = await ssh.createSshSandboxSessionFromSettings({\n\t\t\t\tcommand: 'ssh',\n\t\t\t\tidentityData: sshCreds.identityPem,\n\t\t\t\tstrictHostKeyChecking: false,\n\t\t\t\ttarget: `${sshCreds.user}@${sshCreds.host}:${sshCreds.port}`,\n\t\t\t\tupdateHostKeys: false,\n\t\t\t\tworkspaceRoot: '/work',\n\t\t\t});\n\t\t\treturn await ssh.runSshSandboxCommand({\n\t\t\t\t...(allowFailure !== undefined ? { allowFailure } : {}),\n\t\t\t\tremoteCommand: ssh.buildRemoteCommand(['/bin/sh', '-c', script, 'gondolin-sandbox-fs']),\n\t\t\t\tsession,\n\t\t\t\t...(signal !== undefined ? { signal } : {}),\n\t\t\t\t...(stdin !== undefined ? { stdin } : {}),\n\t\t\t});\n\t\t},\n\t};\n}\n\nexport type { SshHelpers, SshSandboxSession };\n","interface OpenClawAgentConfig {\n\treadonly [key: string]: unknown;\n\treadonly id?: unknown;\n\treadonly sandbox?: {\n\t\treadonly [key: string]: unknown;\n\t\treadonly backend?: unknown;\n\t\treadonly mode?: unknown;\n\t\treadonly scope?: unknown;\n\t\treadonly workspaceAccess?: unknown;\n\t};\n\treadonly workspace?: unknown;\n}\n\ninterface OpenClawRuntimeConfig {\n\treadonly [key: string]: unknown;\n\treadonly agents?: {\n\t\treadonly defaults?: OpenClawAgentConfig;\n\t\treadonly list?: readonly unknown[];\n\t};\n}\n\nexport interface OpenClawRuntimeRequirementFinding {\n\treadonly hint: string;\n\treadonly id: string;\n\treadonly ok: boolean;\n}\n\nexport interface OpenClawRuntimeStatusReport {\n\treadonly findings: readonly OpenClawRuntimeRequirementFinding[];\n\treadonly pluginId: 'gondolin';\n\treadonly zoneId: string;\n}\n\nfunction isObjectRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction readAgentConfigEntries(config: OpenClawRuntimeConfig): readonly {\n\treadonly config: OpenClawAgentConfig;\n\treadonly label: string;\n}[] {\n\tconst defaultConfig = config.agents?.defaults ?? {};\n\tconst agentConfigs = (config.agents?.list ?? [])\n\t\t.filter(isObjectRecord)\n\t\t.map((agentConfig, agentIndex) => ({\n\t\t\tconfig: agentConfig,\n\t\t\tlabel:\n\t\t\t\ttypeof agentConfig.id === 'string'\n\t\t\t\t\t? `agent-${agentConfig.id}`\n\t\t\t\t\t: `agent-${String(agentIndex)}`,\n\t\t}));\n\treturn [{ config: defaultConfig, label: 'defaults' }, ...agentConfigs];\n}\n\nfunction effectiveSandboxValue(\n\tdefaults: OpenClawAgentConfig,\n\tagentConfig: OpenClawAgentConfig,\n\tkey: 'backend' | 'mode' | 'scope' | 'workspaceAccess',\n): unknown {\n\treturn agentConfig.sandbox?.[key] ?? defaults.sandbox?.[key];\n}\n\nfunction effectiveWorkspace(\n\tdefaults: OpenClawAgentConfig,\n\tagentConfig: OpenClawAgentConfig,\n): unknown {\n\treturn agentConfig.workspace ?? defaults.workspace;\n}\n\nfunction requirementFinding(options: {\n\treadonly actualValue: unknown;\n\treadonly expectedValue: string;\n\treadonly fieldPath: string;\n\treadonly label: string;\n\treadonly zoneId: string;\n}): OpenClawRuntimeRequirementFinding {\n\tconst ok = options.actualValue === options.expectedValue;\n\treturn {\n\t\tid: `openclaw-tool-vm-${options.fieldPath.replace(/[.[\\]]/gu, '-')}-${options.zoneId}-${options.label}`,\n\t\tok,\n\t\thint: ok\n\t\t\t? `${options.fieldPath}=${options.expectedValue}`\n\t\t\t: `Set ${options.fieldPath} to \"${options.expectedValue}\" for OpenClaw Tool VM mediation.`,\n\t};\n}\n\nexport function buildOpenClawRuntimeStatusReport(options: {\n\treadonly config: Record<string, unknown>;\n\treadonly zoneId: string;\n}): OpenClawRuntimeStatusReport {\n\tconst config: OpenClawRuntimeConfig = options.config;\n\tconst defaults = config.agents?.defaults ?? {};\n\treturn {\n\t\tpluginId: 'gondolin',\n\t\tzoneId: options.zoneId,\n\t\tfindings: readAgentConfigEntries(config).flatMap(({ config: agentConfig, label }) => {\n\t\t\tconst workspace = effectiveWorkspace(defaults, agentConfig);\n\t\t\treturn [\n\t\t\t\trequirementFinding({\n\t\t\t\t\tactualValue: effectiveSandboxValue(defaults, agentConfig, 'backend'),\n\t\t\t\t\texpectedValue: 'gondolin',\n\t\t\t\t\tfieldPath: `agents.${label}.sandbox.backend`,\n\t\t\t\t\tlabel,\n\t\t\t\t\tzoneId: options.zoneId,\n\t\t\t\t}),\n\t\t\t\trequirementFinding({\n\t\t\t\t\tactualValue: effectiveSandboxValue(defaults, agentConfig, 'mode'),\n\t\t\t\t\texpectedValue: 'all',\n\t\t\t\t\tfieldPath: `agents.${label}.sandbox.mode`,\n\t\t\t\t\tlabel,\n\t\t\t\t\tzoneId: options.zoneId,\n\t\t\t\t}),\n\t\t\t\trequirementFinding({\n\t\t\t\t\tactualValue: effectiveSandboxValue(defaults, agentConfig, 'scope'),\n\t\t\t\t\texpectedValue: 'agent',\n\t\t\t\t\tfieldPath: `agents.${label}.sandbox.scope`,\n\t\t\t\t\tlabel,\n\t\t\t\t\tzoneId: options.zoneId,\n\t\t\t\t}),\n\t\t\t\trequirementFinding({\n\t\t\t\t\tactualValue: effectiveSandboxValue(defaults, agentConfig, 'workspaceAccess'),\n\t\t\t\t\texpectedValue: 'rw',\n\t\t\t\t\tfieldPath: `agents.${label}.sandbox.workspaceAccess`,\n\t\t\t\t\tlabel,\n\t\t\t\t\tzoneId: options.zoneId,\n\t\t\t\t}),\n\t\t\t\t{\n\t\t\t\t\tid: `openclaw-tool-vm-workspace-${options.zoneId}-${label}`,\n\t\t\t\t\tok: workspace !== '/zone',\n\t\t\t\t\thint:\n\t\t\t\t\t\tworkspace === '/zone'\n\t\t\t\t\t\t\t? 'Use /zone/agents/default or per-agent workspaces; keep /zone for shared zone files.'\n\t\t\t\t\t\t\t: typeof workspace === 'string'\n\t\t\t\t\t\t\t\t? workspace\n\t\t\t\t\t\t\t\t: 'agents workspace is unset',\n\t\t\t\t},\n\t\t\t] as const satisfies readonly OpenClawRuntimeRequirementFinding[];\n\t\t}),\n\t};\n}\n","export interface SshSandboxSession {\n\treadonly command: string;\n\treadonly configPath: string;\n\treadonly host: string;\n}\n\nexport interface SshHelpers {\n\treadonly buildExecRemoteCommand: (params: {\n\t\treadonly command: string;\n\t\treadonly env: Record<string, string>;\n\t\treadonly workdir?: string;\n\t}) => string;\n\treadonly buildRemoteCommand: (argv: readonly string[]) => string;\n\treadonly buildSshSandboxArgv: (params: {\n\t\treadonly remoteCommand: string;\n\t\treadonly session: SshSandboxSession;\n\t\treadonly tty?: boolean;\n\t}) => string[];\n\treadonly createRemoteShellSandboxFsBridge: (params: {\n\t\treadonly runtime: {\n\t\t\treadonly remoteAgentWorkspaceDir: string;\n\t\t\treadonly remoteWorkspaceDir: string;\n\t\t\treadonly runRemoteShellScript: (shellParams: {\n\t\t\t\treadonly allowFailure?: boolean;\n\t\t\t\treadonly args?: string[];\n\t\t\t\treadonly script: string;\n\t\t\t\treadonly signal?: AbortSignal;\n\t\t\t\treadonly stdin?: Buffer | string;\n\t\t\t}) => Promise<{\n\t\t\t\treadonly code: number;\n\t\t\t\treadonly stderr: Buffer;\n\t\t\t\treadonly stdout: Buffer;\n\t\t\t}>;\n\t\t};\n\t\treadonly sandbox: unknown;\n\t}) => import('./sandbox-backend-factory.js').GondolinFsBridge;\n\treadonly createSshSandboxSessionFromSettings: (settings: {\n\t\treadonly command: string;\n\t\treadonly identityData?: string;\n\t\treadonly strictHostKeyChecking: boolean;\n\t\treadonly target: string;\n\t\treadonly updateHostKeys: boolean;\n\t\treadonly workspaceRoot: string;\n\t}) => Promise<SshSandboxSession>;\n\treadonly disposeSshSandboxSession?: (session: SshSandboxSession) => Promise<void>;\n\treadonly runSshSandboxCommand: (params: {\n\t\treadonly allowFailure?: boolean;\n\t\treadonly remoteCommand: string;\n\t\treadonly session: SshSandboxSession;\n\t\treadonly signal?: AbortSignal;\n\t\treadonly stdin?: Buffer | string;\n\t}) => Promise<{\n\t\treadonly code: number;\n\t\treadonly stderr: Buffer;\n\t\treadonly stdout: Buffer;\n\t}>;\n\treadonly sanitizeEnvVars: (env: NodeJS.ProcessEnv) => {\n\t\treadonly allowed: Record<string, string>;\n\t};\n}\n\nexport interface OpenClawToolRegistration {\n\treadonly description: string;\n\treadonly execute: (toolCallId: string, params: unknown) => Promise<OpenClawToolResult>;\n\treadonly name: string;\n\treadonly parameters: Record<string, unknown>;\n}\n\nexport interface OpenClawToolRegistrationOptions {\n\treadonly name?: string;\n\treadonly names?: readonly string[];\n\treadonly optional?: boolean;\n}\n\nexport interface OpenClawToolResult {\n\treadonly content: string;\n\treadonly details?: unknown;\n}\n\nexport interface OpenClawToolRegistrationApi {\n\treadonly registerTool?: (\n\t\ttool: OpenClawToolRegistration,\n\t\toptions?: OpenClawToolRegistrationOptions,\n\t) => void;\n}\n\nexport function assertSdkShape(value: unknown): asserts value is SshHelpers & {\n\tregisterSandboxBackend: (\n\t\tid: string,\n\t\tregistration: {\n\t\t\tfactory: ReturnType<\n\t\t\t\ttypeof import('./sandbox-backend-factory.js').createGondolinSandboxBackendFactory\n\t\t\t>;\n\t\t\tmanager?: ReturnType<\n\t\t\t\ttypeof import('./sandbox-backend-factory.js').createGondolinSandboxBackendManager\n\t\t\t>;\n\t\t},\n\t) => void;\n} {\n\tif (typeof value !== 'object' || value === null) {\n\t\tthrow new TypeError('OpenClaw SDK module is not an object');\n\t}\n\n\tfor (const exportName of [\n\t\t'buildExecRemoteCommand',\n\t\t'buildRemoteCommand',\n\t\t'buildSshSandboxArgv',\n\t\t'createRemoteShellSandboxFsBridge',\n\t\t'createSshSandboxSessionFromSettings',\n\t\t'runSshSandboxCommand',\n\t\t'sanitizeEnvVars',\n\t\t'registerSandboxBackend',\n\t] as const) {\n\t\tif (typeof (value as Record<string, unknown>)[exportName] !== 'function') {\n\t\t\tthrow new TypeError(`OpenClaw SDK missing required export: ${exportName}`);\n\t\t}\n\t}\n}\n","import type { OpenClawToolRegistrationApi } from './openclaw-sandbox-sdk-contract.js';\n\ntype RequiredOpenClawToolRegistrationApi = OpenClawToolRegistrationApi & {\n\treadonly registerTool: NonNullable<OpenClawToolRegistrationApi['registerTool']>;\n};\n\nexport interface RegisterZoneGitToolOptions {\n\treadonly api: RequiredOpenClawToolRegistrationApi;\n\treadonly controllerUrl: string;\n\treadonly fetchImpl?: typeof fetch;\n\treadonly zoneGitToken?: string;\n\treadonly zoneId: string;\n}\n\nconst zoneGitCapabilityHeader = 'x-agent-vm-zone-git-token';\n\nfunction readExpectedHead(input: unknown): string {\n\tif (typeof input !== 'object' || input === null || !('expectedHead' in input)) {\n\t\tthrow new Error('zone_git_push requires expectedHead.');\n\t}\n\tconst expectedHead = input.expectedHead;\n\tif (typeof expectedHead !== 'string' || expectedHead.length === 0) {\n\t\tthrow new Error('zone_git_push requires expectedHead.');\n\t}\n\treturn expectedHead;\n}\n\nfunction buildControllerUrl(controllerUrl: string, zoneId: string): string {\n\treturn `${controllerUrl.replace(/\\/$/u, '')}/zones/${encodeURIComponent(zoneId)}/zone-git/push`;\n}\n\nasync function readResponseText(response: Response): Promise<string> {\n\ttry {\n\t\treturn await response.text();\n\t} catch (error) {\n\t\treturn error instanceof Error ? error.message : String(error);\n\t}\n}\n\nfunction parseJsonPayload(responseText: string): unknown {\n\ttry {\n\t\treturn JSON.parse(responseText);\n\t} catch (error) {\n\t\tthrow new Error(`zone_git_push returned non-JSON response: ${responseText.slice(0, 500)}`, {\n\t\t\tcause: error,\n\t\t});\n\t}\n}\n\nexport function registerZoneGitTool(options: RegisterZoneGitToolOptions): void {\n\toptions.api.registerTool(\n\t\t{\n\t\t\tname: 'zone_git_push',\n\t\t\tdescription:\n\t\t\t\t'Push committed OpenClaw zone workspace changes through the agent-vm controller. Use after git commit; do not run raw git push.',\n\t\t\tparameters: {\n\t\t\t\ttype: 'object',\n\t\t\t\tadditionalProperties: false,\n\t\t\t\tproperties: {\n\t\t\t\t\texpectedHead: { type: 'string' },\n\t\t\t\t},\n\t\t\t\trequired: ['expectedHead'],\n\t\t\t},\n\t\t\texecute: async (_toolCallId: string, input: unknown) => {\n\t\t\t\tconst expectedHead = readExpectedHead(input);\n\t\t\t\tconst response = await (options.fetchImpl ?? fetch)(\n\t\t\t\t\tbuildControllerUrl(options.controllerUrl, options.zoneId),\n\t\t\t\t\t{\n\t\t\t\t\t\tbody: JSON.stringify({ expectedHead }),\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t'content-type': 'application/json',\n\t\t\t\t\t\t\t...(options.zoneGitToken ? { [zoneGitCapabilityHeader]: options.zoneGitToken } : {}),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tconst responseText = await readResponseText(response);\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tthrow new Error(`zone_git_push failed: ${response.status} ${responseText.slice(0, 500)}`);\n\t\t\t\t}\n\t\t\t\tconst payload = parseJsonPayload(responseText);\n\t\t\t\treturn {\n\t\t\t\t\tcontent: JSON.stringify(payload),\n\t\t\t\t\tdetails: payload,\n\t\t\t\t};\n\t\t\t},\n\t\t},\n\t\t{ name: 'zone_git_push', optional: true },\n\t);\n}\n","import { createLeaseClient } from './controller-lease-client.js';\nimport { resolveGondolinPluginConfig } from './gondolin-plugin-config.js';\nimport { createBackendDeps } from './openclaw-backend-dependencies.js';\nimport { buildOpenClawRuntimeStatusReport } from './openclaw-runtime-status.js';\nimport {\n\tassertSdkShape,\n\ttype OpenClawToolRegistrationApi,\n\ttype SshHelpers,\n\ttype SshSandboxSession,\n} from './openclaw-sandbox-sdk-contract.js';\nimport {\n\tcreateGondolinSandboxBackendFactory,\n\tcreateGondolinSandboxBackendManager,\n} from './sandbox-backend-factory.js';\nimport { registerZoneGitTool } from './zone-git-tool.js';\n\nconst plugin = {\n\tid: 'gondolin',\n\tname: 'Gondolin VM Sandbox',\n\tdescription: 'Sandbox backend powered by Gondolin micro-VMs.',\n\n\tregister(api: {\n\t\treadonly config?: Record<string, unknown>;\n\t\treadonly pluginConfig: Record<string, unknown>;\n\t\treadonly registerTool?: OpenClawToolRegistrationApi['registerTool'];\n\t\treadonly registrationMode: string;\n\t\treadonly runtime?: {\n\t\t\treadonly config?: {\n\t\t\t\treadonly current?: () => Record<string, unknown>;\n\t\t\t};\n\t\t};\n\t}): void {\n\t\tconst registerTool = api.registerTool;\n\t\tif (typeof registerTool !== 'function') {\n\t\t\tif (api.registrationMode === 'full') {\n\t\t\t\tthrow new Error('Gondolin full registration requires OpenClaw registerTool.');\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tconst pluginConfig = resolveGondolinPluginConfig(api.pluginConfig);\n\t\tconst zoneGitToken =\n\t\t\tpluginConfig.zoneGitToken ??\n\t\t\t(pluginConfig.zoneGitTokenEnv ? process.env[pluginConfig.zoneGitTokenEnv] : undefined);\n\t\tregisterZoneGitTool({\n\t\t\tapi: { registerTool },\n\t\t\tcontrollerUrl: pluginConfig.controllerUrl,\n\t\t\t...(zoneGitToken ? { zoneGitToken } : {}),\n\t\t\tzoneId: pluginConfig.zoneId,\n\t\t});\n\t\tif (api.registrationMode !== 'full') {\n\t\t\treturn;\n\t\t}\n\t\tconst buildRuntimeStatus = ():\n\t\t\t| ReturnType<typeof buildOpenClawRuntimeStatusReport>\n\t\t\t| undefined => {\n\t\t\tconst runtimeConfig = api.runtime?.config?.current?.() ?? api.config;\n\t\t\treturn runtimeConfig\n\t\t\t\t? buildOpenClawRuntimeStatusReport({\n\t\t\t\t\t\tconfig: runtimeConfig,\n\t\t\t\t\t\tzoneId: pluginConfig.zoneId,\n\t\t\t\t\t})\n\t\t\t\t: undefined;\n\t\t};\n\t\tconst initialRuntimeStatus = buildRuntimeStatus();\n\t\tif (initialRuntimeStatus) {\n\t\t\tconst leaseClient = createLeaseClient({ controllerUrl: pluginConfig.controllerUrl });\n\t\t\tvoid leaseClient\n\t\t\t\t.publishOpenClawRuntimeStatus?.(initialRuntimeStatus)\n\t\t\t\t?.catch((error: unknown) => {\n\t\t\t\t\tconst message = error instanceof Error ? error.message : JSON.stringify(error);\n\t\t\t\t\tprocess.stderr.write(\n\t\t\t\t\t\t`[gondolin] failed to publish OpenClaw runtime status: ${message}\\n`,\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t}\n\n\t\tconst sdkPath = '/opt/openclaw-sdk/sandbox.js';\n\t\tconst sdkPromise = import(sdkPath).then((sdkRaw: Record<string, unknown>) => {\n\t\t\tassertSdkShape(sdkRaw);\n\n\t\t\tconst sshHelpers: SshHelpers = {\n\t\t\t\tbuildExecRemoteCommand: sdkRaw.buildExecRemoteCommand,\n\t\t\t\tbuildRemoteCommand: sdkRaw.buildRemoteCommand,\n\t\t\t\tbuildSshSandboxArgv: sdkRaw.buildSshSandboxArgv,\n\t\t\t\tcreateRemoteShellSandboxFsBridge: sdkRaw.createRemoteShellSandboxFsBridge,\n\t\t\t\tcreateSshSandboxSessionFromSettings: sdkRaw.createSshSandboxSessionFromSettings,\n\t\t\t\t...(typeof sdkRaw.disposeSshSandboxSession === 'function'\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tdisposeSshSandboxSession: sdkRaw.disposeSshSandboxSession as (\n\t\t\t\t\t\t\t\tsession: SshSandboxSession,\n\t\t\t\t\t\t\t) => Promise<void>,\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t\trunSshSandboxCommand: sdkRaw.runSshSandboxCommand,\n\t\t\t\tsanitizeEnvVars: sdkRaw.sanitizeEnvVars,\n\t\t\t};\n\n\t\t\tconst backendDependencies = createBackendDeps(sshHelpers);\n\t\t\tsdkRaw.registerSandboxBackend('gondolin', {\n\t\t\t\tfactory: createGondolinSandboxBackendFactory(\n\t\t\t\t\t{\n\t\t\t\t\t\t...pluginConfig,\n\t\t\t\t\t\topenClawRuntimeStatusProvider: buildRuntimeStatus,\n\t\t\t\t\t},\n\t\t\t\t\tbackendDependencies,\n\t\t\t\t),\n\t\t\t\tmanager: createGondolinSandboxBackendManager(pluginConfig, backendDependencies),\n\t\t\t});\n\t\t});\n\n\t\tsdkPromise.catch((error: unknown) => {\n\t\t\tconst message = error instanceof Error ? error.message : JSON.stringify(error);\n\t\t\tprocess.stderr.write(`[gondolin] failed to load OpenClaw SDK: ${message}\\n`);\n\t\t});\n\t},\n};\n\nexport default plugin;\n\nexport { createBackendDeps };\nexport type { SshHelpers };\n","export * from './sandbox-backend-factory.js';\nexport * from './gondolin-plugin-config.js';\nexport * from './controller-lease-client.js';\nexport * from './openclaw-plugin-registration.js';\nexport { default } from './openclaw-plugin-registration.js';\n\nexport const OPENCLAW_GONDOLIN_PLUGIN_PACKAGE_NAME = '@agent-vm/openclaw-agent-vm-plugin';\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["formatUnknownError"],"sources":["../src/controller-lease-client.ts","../src/sandbox-backend/sandbox-shell-script.ts","../src/sandbox-backend/sandbox-backend-handle-factory.ts","../src/sandbox-backend/sandbox-backend-manager.ts","../src/gondolin-plugin-config.ts","../src/openclaw-backend-dependencies.ts","../src/openclaw-runtime-status.ts","../src/openclaw-sandbox-sdk-contract.ts","../src/zone-git-tool.ts","../src/openclaw-plugin-registration.ts","../src/index.ts"],"sourcesContent":["import {\n\tisToolVmLeasePeek,\n\tisToolVmSshLease,\n\ttype ToolVmLeasePeek,\n\ttype ToolVmSshLease,\n} from '@agent-vm/gateway-interface';\nimport type {\n\tEndToolVmActiveUseRequest,\n\tHeartbeatToolVmActiveUseResponse,\n\tStartToolVmActiveUseRequest,\n\tStartToolVmActiveUseResponse,\n} from '@agent-vm/gateway-interface';\n\nexport interface OpenClawRuntimeStatusReport {\n\treadonly findings: readonly {\n\t\treadonly hint: string;\n\t\treadonly id: string;\n\t\treadonly ok: boolean;\n\t}[];\n\treadonly pluginId: 'gondolin';\n\treadonly zoneId: string;\n}\n\nexport interface LeaseClient {\n\t// Cached handles use renewLease; read-only runtime probes use peekLease.\n\tendActiveUse(leaseId: string, useId: string, request: EndToolVmActiveUseRequest): Promise<void>;\n\theartbeatActiveUse(leaseId: string, useId: string): Promise<HeartbeatToolVmActiveUseResponse>;\n\tpeekLease(leaseId: string): Promise<ToolVmLeasePeek>;\n\tpublishOpenClawRuntimeStatus?(report: OpenClawRuntimeStatusReport): Promise<void>;\n\treleaseLease(leaseId: string, options?: { readonly force?: boolean }): Promise<void>;\n\trenewLease(leaseId: string): Promise<ToolVmSshLease>;\n\trequestLease(request: {\n\t\treadonly agentWorkspaceDir: string;\n\t\treadonly profileId: string;\n\t\treadonly scopeKey: string;\n\t\treadonly workMountDir: string;\n\t\treadonly zoneId: string;\n\t}): Promise<ToolVmSshLease>;\n\tstartActiveUse(\n\t\tleaseId: string,\n\t\trequest: StartToolVmActiveUseRequest,\n\t): Promise<StartToolVmActiveUseResponse>;\n}\n\nexport type ControllerLeaseRequestErrorKind = 'client-error' | 'server-error';\n\nexport class ControllerLeaseRequestError extends Error {\n\treadonly bodyText: string;\n\treadonly kind: ControllerLeaseRequestErrorKind;\n\treadonly responseBody: unknown;\n\treadonly status: number;\n\n\tconstructor(options: {\n\t\treadonly bodyText: string;\n\t\treadonly context: string;\n\t\treadonly responseBody: unknown;\n\t\treadonly status: number;\n\t}) {\n\t\tconst kind: ControllerLeaseRequestErrorKind =\n\t\t\toptions.status >= 400 && options.status < 500 ? 'client-error' : 'server-error';\n\t\tsuper(`${options.context} returned HTTP ${String(options.status)} (${kind})`);\n\t\tthis.bodyText = options.bodyText;\n\t\tthis.kind = kind;\n\t\tthis.responseBody = options.responseBody;\n\t\tthis.status = options.status;\n\t}\n}\n\nfunction objectValue(value: unknown): object | undefined {\n\treturn typeof value === 'object' && value !== null ? value : undefined;\n}\n\nfunction isStartActiveUseResponse(value: unknown): value is StartToolVmActiveUseResponse {\n\tconst record = objectValue(value);\n\treturn (\n\t\trecord !== undefined &&\n\t\ttypeof Reflect.get(record, 'expiresAt') === 'number' &&\n\t\ttypeof Reflect.get(record, 'heartbeatAfterMs') === 'number' &&\n\t\ttypeof Reflect.get(record, 'useId') === 'string'\n\t);\n}\n\nfunction isHeartbeatActiveUseResponse(value: unknown): value is HeartbeatToolVmActiveUseResponse {\n\tconst record = objectValue(value);\n\treturn (\n\t\trecord !== undefined &&\n\t\ttypeof Reflect.get(record, 'expiresAt') === 'number' &&\n\t\ttypeof Reflect.get(record, 'heartbeatAfterMs') === 'number'\n\t);\n}\n\nfunction formatUnknownError(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction writeLeaseClientLog(message: string): void {\n\tprocess.stderr.write(`[openclaw-agent-vm-plugin] ${message}\\n`);\n}\n\nfunction parseJsonBody(bodyText: string, context: string): unknown {\n\ttry {\n\t\treturn JSON.parse(bodyText);\n\t} catch (error) {\n\t\twriteLeaseClientLog(`${context} returned a non-JSON error body: ${formatUnknownError(error)}`);\n\t\treturn undefined;\n\t}\n}\n\nasync function readErrorBody(\n\tresponse: Response,\n\tcontext: string,\n): Promise<{\n\treadonly bodyText: string;\n\treadonly responseBody: unknown;\n}> {\n\tconst bodyText = await response.text().catch(() => '(unreadable)');\n\treturn {\n\t\tbodyText,\n\t\tresponseBody: bodyText === '(unreadable)' ? undefined : parseJsonBody(bodyText, context),\n\t};\n}\n\nasync function readJsonResponse<TValue>(\n\tresponse: Response,\n\tcontext: string,\n\tisExpectedResponse: (value: unknown) => value is TValue,\n): Promise<TValue> {\n\tif (!response.ok) {\n\t\tconst errorBody = await readErrorBody(response, context);\n\t\tthrow new ControllerLeaseRequestError({\n\t\t\tbodyText: errorBody.bodyText,\n\t\t\tcontext,\n\t\t\tresponseBody: errorBody.responseBody,\n\t\t\tstatus: response.status,\n\t\t});\n\t}\n\tconst payload = await response.json();\n\tif (!isExpectedResponse(payload)) {\n\t\tthrow new TypeError(\n\t\t\t`${context} returned an invalid response: ${JSON.stringify(payload).slice(0, 200)}`,\n\t\t);\n\t}\n\treturn payload;\n}\n\nexport function createLeaseClient(options: {\n\treadonly controllerUrl: string;\n\treadonly fetchImpl?: (input: string | URL | Request, init?: RequestInit) => Promise<Response>;\n}): LeaseClient {\n\tconst fetchImpl = options.fetchImpl ?? fetch;\n\tconst baseUrl = options.controllerUrl.replace(/\\/$/u, '');\n\tconst renewLease = async (leaseId: string): Promise<ToolVmSshLease> => {\n\t\tconst response = await fetchImpl(`${baseUrl}/lease/${encodeURIComponent(leaseId)}/renew`, {\n\t\t\tmethod: 'POST',\n\t\t});\n\t\treturn await readJsonResponse(response, 'Controller lease renew API', isToolVmSshLease);\n\t};\n\n\treturn {\n\t\tendActiveUse: async (\n\t\t\tleaseId: string,\n\t\t\tuseId: string,\n\t\t\trequest: EndToolVmActiveUseRequest,\n\t\t): Promise<void> => {\n\t\t\tconst response = await fetchImpl(\n\t\t\t\t`${baseUrl}/lease/${encodeURIComponent(leaseId)}/uses/${encodeURIComponent(useId)}`,\n\t\t\t\t{\n\t\t\t\t\tbody: JSON.stringify(request),\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'content-type': 'application/json',\n\t\t\t\t\t},\n\t\t\t\t\tmethod: 'DELETE',\n\t\t\t\t},\n\t\t\t);\n\t\t\tif (!response.ok) {\n\t\t\t\tconst errorBody = await readErrorBody(response, 'Controller active-use end API');\n\t\t\t\tthrow new ControllerLeaseRequestError({\n\t\t\t\t\tbodyText: errorBody.bodyText,\n\t\t\t\t\tcontext: 'Controller active-use end API',\n\t\t\t\t\tresponseBody: errorBody.responseBody,\n\t\t\t\t\tstatus: response.status,\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\theartbeatActiveUse: async (\n\t\t\tleaseId: string,\n\t\t\tuseId: string,\n\t\t): Promise<HeartbeatToolVmActiveUseResponse> => {\n\t\t\tconst response = await fetchImpl(\n\t\t\t\t`${baseUrl}/lease/${encodeURIComponent(leaseId)}/uses/${encodeURIComponent(useId)}/heartbeat`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t},\n\t\t\t);\n\t\t\treturn await readJsonResponse(\n\t\t\t\tresponse,\n\t\t\t\t'Controller active-use heartbeat API',\n\t\t\t\tisHeartbeatActiveUseResponse,\n\t\t\t);\n\t\t},\n\t\trenewLease,\n\t\tpeekLease: async (leaseId: string): Promise<ToolVmLeasePeek> => {\n\t\t\tconst response = await fetchImpl(`${baseUrl}/lease/${encodeURIComponent(leaseId)}/peek`);\n\t\t\treturn await readJsonResponse(response, 'Controller lease peek API', isToolVmLeasePeek);\n\t\t},\n\t\tpublishOpenClawRuntimeStatus: async (report): Promise<void> => {\n\t\t\tconst response = await fetchImpl(\n\t\t\t\t`${baseUrl}/zones/${encodeURIComponent(report.zoneId)}/openclaw-runtime-status`,\n\t\t\t\t{\n\t\t\t\t\tbody: JSON.stringify(report),\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'content-type': 'application/json',\n\t\t\t\t\t},\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t},\n\t\t\t);\n\t\t\tif (!response.ok) {\n\t\t\t\tconst errorBody = await readErrorBody(response, 'Controller OpenClaw runtime status API');\n\t\t\t\tthrow new ControllerLeaseRequestError({\n\t\t\t\t\tbodyText: errorBody.bodyText,\n\t\t\t\t\tcontext: 'Controller OpenClaw runtime status API',\n\t\t\t\t\tresponseBody: errorBody.responseBody,\n\t\t\t\t\tstatus: response.status,\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\treleaseLease: async (\n\t\t\tleaseId: string,\n\t\t\treleaseOptions: { readonly force?: boolean } = {},\n\t\t): Promise<void> => {\n\t\t\tconst releaseUrl = new URL(`${baseUrl}/lease/${encodeURIComponent(leaseId)}`);\n\t\t\tif (releaseOptions.force === true) {\n\t\t\t\treleaseUrl.searchParams.set('force', 'true');\n\t\t\t}\n\t\t\tconst response = await fetchImpl(releaseUrl.toString(), {\n\t\t\t\tmethod: 'DELETE',\n\t\t\t});\n\t\t\tif (!response.ok) {\n\t\t\t\tconst errorBody = await readErrorBody(response, 'Controller lease release API');\n\t\t\t\tthrow new ControllerLeaseRequestError({\n\t\t\t\t\tbodyText: errorBody.bodyText,\n\t\t\t\t\tcontext: 'Controller lease release API',\n\t\t\t\t\tresponseBody: errorBody.responseBody,\n\t\t\t\t\tstatus: response.status,\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\trequestLease: async (request): Promise<ToolVmSshLease> => {\n\t\t\tconst response = await fetchImpl(`${baseUrl}/lease`, {\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tagentWorkspaceDir: request.agentWorkspaceDir,\n\t\t\t\t\tprofileId: request.profileId,\n\t\t\t\t\tscopeKey: request.scopeKey,\n\t\t\t\t\tworkMountDir: request.workMountDir,\n\t\t\t\t\tzoneId: request.zoneId,\n\t\t\t\t}),\n\t\t\t\theaders: {\n\t\t\t\t\t'content-type': 'application/json',\n\t\t\t\t},\n\t\t\t\tmethod: 'POST',\n\t\t\t});\n\t\t\treturn await readJsonResponse(response, 'Controller lease API', isToolVmSshLease);\n\t\t},\n\t\tstartActiveUse: async (\n\t\t\tleaseId: string,\n\t\t\trequest: StartToolVmActiveUseRequest,\n\t\t): Promise<StartToolVmActiveUseResponse> => {\n\t\t\tconst response = await fetchImpl(`${baseUrl}/lease/${encodeURIComponent(leaseId)}/uses`, {\n\t\t\t\tbody: JSON.stringify(request),\n\t\t\t\theaders: {\n\t\t\t\t\t'content-type': 'application/json',\n\t\t\t\t},\n\t\t\t\tmethod: 'POST',\n\t\t\t});\n\t\t\treturn await readJsonResponse(\n\t\t\t\tresponse,\n\t\t\t\t'Controller active-use start API',\n\t\t\t\tisStartActiveUseResponse,\n\t\t\t);\n\t\t},\n\t};\n}\n","export function buildShellScriptWithArgs(script: string, args?: readonly string[]): string {\n\tif (!args || args.length === 0) {\n\t\treturn script;\n\t}\n\n\tconst escapedArgs = args.map((arg) => `'${arg.replace(/'/g, \"'\\\\''\")}'`).join(' ');\n\treturn `set -- ${escapedArgs}; ${script}`;\n}\n","import {\n\tcreateToolVmActiveUseHandle,\n\ttype ToolVmActiveUseHandle,\n\ttype ToolVmActiveUseOutcome,\n\ttype ToolVmActiveUseCorrelation,\n\ttype StartToolVmActiveUseRequest,\n\ttype StartToolVmActiveUseResponse,\n\ttype HeartbeatToolVmActiveUseResponse,\n\ttype EndToolVmActiveUseRequest,\n\tisToolVmSshLease,\n} from '@agent-vm/gateway-interface';\n\nimport {\n\tControllerLeaseRequestError,\n\tcreateLeaseClient,\n\ttype LeaseClient,\n\ttype OpenClawRuntimeStatusReport,\n} from '../controller-lease-client.js';\nimport {\n\ttype CachedScopeEntry,\n\ttype CreateBackendDependencies,\n\ttype OpenClawFsBridgeLeaseContext,\n\ttype OpenClawSandboxBackendHandle,\n} from './sandbox-backend-contract.js';\nimport { buildShellScriptWithArgs } from './sandbox-shell-script.js';\n\nfunction scopeCacheKey(params: {\n\treadonly agentWorkspaceDir: string;\n\treadonly profileId: string;\n\treadonly scopeKey: string;\n\treadonly workspaceDir: string;\n\treadonly zoneId: string;\n}): string {\n\treturn [\n\t\tparams.zoneId,\n\t\tparams.scopeKey,\n\t\tparams.profileId,\n\t\tparams.agentWorkspaceDir,\n\t\tparams.workspaceDir,\n\t].join('\\0');\n}\n\nfunction formatUnknownError(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction writeSandboxBackendLog(message: string): void {\n\tprocess.stderr.write(`[openclaw-agent-vm-plugin] ${message}\\n`);\n}\n\nfunction shouldRefreshCachedLease(error: unknown): boolean {\n\treturn error instanceof ControllerLeaseRequestError && error.status === 404;\n}\n\nfunction isCleanupNotFound(error: unknown): boolean {\n\treturn error instanceof ControllerLeaseRequestError && error.status === 404;\n}\n\ninterface DisposableFinalizeToken {\n\tdispose(): Promise<void>;\n}\n\ninterface ActiveUseFinalizeToken {\n\treadonly activeUseHandle: ToolVmActiveUseHandle;\n\treadonly innerToken?: unknown;\n}\n\nfunction isDisposableFinalizeToken(value: unknown): value is DisposableFinalizeToken {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\t'dispose' in value &&\n\t\ttypeof Reflect.get(value, 'dispose') === 'function'\n\t);\n}\n\nfunction isActiveUseFinalizeToken(value: unknown): value is ActiveUseFinalizeToken {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\t'activeUseHandle' in value &&\n\t\ttypeof Reflect.get(value, 'activeUseHandle') === 'object'\n\t);\n}\n\nfunction activeUseOutcomeForFinalizeParams(finalizeParams: {\n\treadonly status: 'completed' | 'failed';\n\treadonly timedOut: boolean;\n}): ToolVmActiveUseOutcome {\n\treturn finalizeParams.timedOut\n\t\t? 'timed-out'\n\t\t: finalizeParams.status === 'completed'\n\t\t\t? 'completed'\n\t\t\t: 'failed';\n}\n\nexport function createGondolinSandboxBackendFactory(\n\toptions: {\n\t\treadonly controllerUrl: string;\n\t\treadonly openClawRuntimeStatusProvider?: () => OpenClawRuntimeStatusReport | undefined;\n\t\treadonly profileId?: string;\n\t\treadonly zoneId: string;\n\t},\n\tdependencies: CreateBackendDependencies,\n): (params: {\n\treadonly agentWorkspaceDir: string;\n\treadonly cfg: {\n\t\treadonly docker?: {\n\t\t\treadonly env?: Record<string, string>;\n\t\t};\n\t};\n\treadonly scopeKey: string;\n\treadonly sessionKey: string;\n\treadonly workspaceDir: string;\n}) => Promise<OpenClawSandboxBackendHandle> {\n\tconst scopeCache = new Map<string, CachedScopeEntry>();\n\n\treturn async (params) => {\n\t\tconst profileId = options.profileId ?? 'standard';\n\t\tconst cacheKey = scopeCacheKey({\n\t\t\tagentWorkspaceDir: params.agentWorkspaceDir,\n\t\t\tprofileId,\n\t\t\tscopeKey: params.scopeKey,\n\t\t\tworkspaceDir: params.workspaceDir,\n\t\t\tzoneId: options.zoneId,\n\t\t});\n\t\tconst leaseClient =\n\t\t\tdependencies.createLeaseClient?.({\n\t\t\t\tcontrollerUrl: options.controllerUrl,\n\t\t\t}) ?? createLeaseClient({ controllerUrl: options.controllerUrl });\n\t\tconst cachedEntry = scopeCache.get(cacheKey);\n\t\tif (cachedEntry) {\n\t\t\ttry {\n\t\t\t\tawait leaseClient.renewLease(cachedEntry.lease.leaseId);\n\t\t\t\treturn cachedEntry.handle;\n\t\t\t} catch (error) {\n\t\t\t\twriteSandboxBackendLog(\n\t\t\t\t\t`lease renew failed for zone '${options.zoneId}' scope '${params.scopeKey}' lease '${cachedEntry.lease.leaseId}': ${formatUnknownError(error)}`,\n\t\t\t\t);\n\t\t\t\tif (!shouldRefreshCachedLease(error)) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tscopeCache.delete(cacheKey);\n\t\t\t}\n\t\t}\n\t\t// OpenClaw SDK still names the selected sandbox path `workspaceDir`.\n\t\t// agent-vm's controller calls the same value `workMountDir` because it\n\t\t// backs the Tool VM /work mount.\n\t\tconst runtimeStatus = options.openClawRuntimeStatusProvider?.();\n\t\tif (runtimeStatus && leaseClient.publishOpenClawRuntimeStatus) {\n\t\t\tawait leaseClient.publishOpenClawRuntimeStatus(runtimeStatus);\n\t\t}\n\t\tconst leaseResponse = await leaseClient.requestLease({\n\t\t\tagentWorkspaceDir: params.agentWorkspaceDir,\n\t\t\tprofileId,\n\t\t\tscopeKey: params.scopeKey,\n\t\t\tworkMountDir: params.workspaceDir,\n\t\t\tzoneId: options.zoneId,\n\t\t});\n\t\tif (!isToolVmSshLease(leaseResponse)) {\n\t\t\tthrow new TypeError('Controller lease API returned an unexpected response.');\n\t\t}\n\n\t\tconst lease = leaseResponse;\n\t\tconst handle = createSandboxBackendHandle({\n\t\t\tcfg: params.cfg,\n\t\t\tcontrollerUrl: options.controllerUrl,\n\t\t\tcreateFsBridgeBuilder: dependencies.createFsBridgeBuilder,\n\t\t\tlease,\n\t\t\tleaseClient,\n\t\t\trunRemoteShellScript: dependencies.runRemoteShellScript,\n\t\t\tbuildExecSpec: dependencies.buildExecSpec,\n\t\t\tscopeKey: params.scopeKey,\n\t\t\tsessionKey: params.sessionKey,\n\t\t\tzoneId: options.zoneId,\n\t\t});\n\t\tscopeCache.set(cacheKey, { handle, lease });\n\t\treturn handle;\n\t};\n}\n\nfunction createSandboxBackendHandle(options: {\n\treadonly buildExecSpec: CreateBackendDependencies['buildExecSpec'];\n\treadonly cfg: {\n\t\treadonly docker?: {\n\t\t\treadonly env?: Record<string, string>;\n\t\t};\n\t};\n\treadonly controllerUrl: string;\n\treadonly createFsBridgeBuilder?: CreateBackendDependencies['createFsBridgeBuilder'];\n\treadonly lease: CachedScopeEntry['lease'];\n\treadonly leaseClient: LeaseClient;\n\treadonly runRemoteShellScript: CreateBackendDependencies['runRemoteShellScript'];\n\treadonly scopeKey: string;\n\treadonly sessionKey: string;\n\treadonly zoneId: string;\n}): OpenClawSandboxBackendHandle {\n\tconst createActiveUseHandle = async (\n\t\tcorrelation: ToolVmActiveUseCorrelation,\n\t): Promise<ToolVmActiveUseHandle> =>\n\t\tawait createToolVmActiveUseHandle({\n\t\t\tcorrelation,\n\t\t\tendActiveUse: async (useId: string, request: EndToolVmActiveUseRequest): Promise<void> => {\n\t\t\t\tawait options.leaseClient.endActiveUse(options.lease.leaseId, useId, request);\n\t\t\t},\n\t\t\theartbeatActiveUse: async (useId: string): Promise<HeartbeatToolVmActiveUseResponse> =>\n\t\t\t\tawait options.leaseClient.heartbeatActiveUse(options.lease.leaseId, useId),\n\t\t\tisEndErrorTolerable: isCleanupNotFound,\n\t\t\tlogEndFailure: (error: unknown): void => {\n\t\t\t\twriteSandboxBackendLog(\n\t\t\t\t\t`active-use cleanup ignored for zone '${options.zoneId}' lease '${options.lease.leaseId}': ${formatUnknownError(error)}`,\n\t\t\t\t);\n\t\t\t},\n\t\t\tlogHeartbeatFailure: (error: unknown): void => {\n\t\t\t\twriteSandboxBackendLog(\n\t\t\t\t\t`active-use heartbeat failed for zone '${options.zoneId}' lease '${options.lease.leaseId}': ${formatUnknownError(error)}`,\n\t\t\t\t);\n\t\t\t},\n\t\t\tstartActiveUse: async (\n\t\t\t\trequest: StartToolVmActiveUseRequest,\n\t\t\t): Promise<StartToolVmActiveUseResponse> =>\n\t\t\t\tawait options.leaseClient.startActiveUse(options.lease.leaseId, request),\n\t\t});\n\n\tconst runWithActiveUse = async <TResult>(\n\t\tcorrelation: ToolVmActiveUseCorrelation,\n\t\tfn: () => Promise<TResult>,\n\t): Promise<TResult> => {\n\t\tconst activeUseHandle = await createActiveUseHandle(correlation);\n\t\ttry {\n\t\t\tconst result = await fn();\n\t\t\tawait activeUseHandle.dispose('completed');\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tawait activeUseHandle.dispose('failed').catch((cleanupError: unknown) => {\n\t\t\t\twriteSandboxBackendLog(\n\t\t\t\t\t`failed to end active use after operation failure for zone '${options.zoneId}' lease '${options.lease.leaseId}': ${formatUnknownError(cleanupError)}`,\n\t\t\t\t);\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t};\n\n\tconst boundRunRemoteShellScript: OpenClawFsBridgeLeaseContext['runRemoteShellScript'] = async (\n\t\tshellParams,\n\t) =>\n\t\tawait runWithActiveUse(\n\t\t\t{\n\t\t\t\tsessionKey: options.sessionKey,\n\t\t\t\ttoolName: 'fs-bridge',\n\t\t\t},\n\t\t\tasync () =>\n\t\t\t\tawait options.runRemoteShellScript({\n\t\t\t\t\t...(shellParams.allowFailure !== undefined\n\t\t\t\t\t\t? { allowFailure: shellParams.allowFailure }\n\t\t\t\t\t\t: {}),\n\t\t\t\t\tscript: buildShellScriptWithArgs(shellParams.script, shellParams.args),\n\t\t\t\t\t...(shellParams.signal !== undefined ? { signal: shellParams.signal } : {}),\n\t\t\t\t\tssh: options.lease.ssh,\n\t\t\t\t\t...(shellParams.stdin !== undefined ? { stdin: shellParams.stdin } : {}),\n\t\t\t\t}),\n\t\t);\n\n\tconst disposeInnerFinalizeToken = async (token: unknown): Promise<void> => {\n\t\tif (isDisposableFinalizeToken(token)) {\n\t\t\tawait token.dispose();\n\t\t}\n\t};\n\n\tconst endActiveUseFinalizeToken = async (\n\t\ttoken: ActiveUseFinalizeToken,\n\t\toutcome: ToolVmActiveUseOutcome,\n\t): Promise<void> => {\n\t\tlet innerError: unknown;\n\t\ttry {\n\t\t\tawait disposeInnerFinalizeToken(token.innerToken);\n\t\t} catch (error) {\n\t\t\tinnerError = error;\n\t\t}\n\t\tlet activeUseError: unknown;\n\t\ttry {\n\t\t\tawait token.activeUseHandle.dispose(outcome);\n\t\t} catch (error) {\n\t\t\tactiveUseError = error;\n\t\t}\n\t\tif (innerError) {\n\t\t\tthrow innerError;\n\t\t}\n\t\tif (activeUseError) {\n\t\t\tthrow activeUseError;\n\t\t}\n\t};\n\n\tconst createFsBridge = options.createFsBridgeBuilder?.({\n\t\tremoteAgentWorkspaceDir: options.lease.workdir,\n\t\tremoteWorkspaceDir: options.lease.workdir,\n\t\trunRemoteShellScript: boundRunRemoteShellScript,\n\t});\n\n\treturn {\n\t\t...(createFsBridge ? { createFsBridge } : {}),\n\t\t...(options.cfg.docker?.env ? { env: options.cfg.docker.env } : {}),\n\t\tconfigLabel: `${options.controllerUrl} (${options.zoneId})`,\n\t\tconfigLabelKind: 'VM',\n\t\tid: 'gondolin',\n\t\truntimeId: options.lease.leaseId,\n\t\truntimeLabel: options.lease.leaseId,\n\t\tworkdir: options.lease.workdir,\n\t\tbuildExecSpec: async (execParams) => {\n\t\t\tconst activeUseHandle = await createActiveUseHandle({\n\t\t\t\tsessionKey: options.sessionKey,\n\t\t\t\ttoolName: 'shell',\n\t\t\t});\n\t\t\ttry {\n\t\t\t\tconst execSpec = await options.buildExecSpec({\n\t\t\t\t\tcommand: execParams.command,\n\t\t\t\t\tenv: execParams.env,\n\t\t\t\t\tssh: options.lease.ssh,\n\t\t\t\t\tusePty: execParams.usePty,\n\t\t\t\t\tworkdir: execParams.workdir ?? options.lease.workdir,\n\t\t\t\t});\n\t\t\t\treturn {\n\t\t\t\t\t...execSpec,\n\t\t\t\t\tfinalizeToken: {\n\t\t\t\t\t\tactiveUseHandle,\n\t\t\t\t\t\t...(execSpec.finalizeToken !== undefined ? { innerToken: execSpec.finalizeToken } : {}),\n\t\t\t\t\t} satisfies ActiveUseFinalizeToken,\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tawait activeUseHandle.dispose('failed').catch((cleanupError: unknown) => {\n\t\t\t\t\twriteSandboxBackendLog(\n\t\t\t\t\t\t`failed to end active use after buildExecSpec failure for zone '${options.zoneId}' lease '${options.lease.leaseId}': ${formatUnknownError(cleanupError)}`,\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\t\tfinalizeExec: async (finalizeParams) => {\n\t\t\tif (isActiveUseFinalizeToken(finalizeParams.token)) {\n\t\t\t\tawait endActiveUseFinalizeToken(\n\t\t\t\t\tfinalizeParams.token,\n\t\t\t\t\tactiveUseOutcomeForFinalizeParams(finalizeParams),\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait disposeInnerFinalizeToken(finalizeParams.token);\n\t\t},\n\t\trunShellCommand: async (commandParams) =>\n\t\t\tawait runWithActiveUse(\n\t\t\t\t{\n\t\t\t\t\tsessionKey: options.sessionKey,\n\t\t\t\t\ttoolName: 'runShellCommand',\n\t\t\t\t},\n\t\t\t\tasync () =>\n\t\t\t\t\tawait options.runRemoteShellScript({\n\t\t\t\t\t\tscript: commandParams.script,\n\t\t\t\t\t\tssh: options.lease.ssh,\n\t\t\t\t\t}),\n\t\t\t),\n\t} satisfies OpenClawSandboxBackendHandle;\n}\n","import { ControllerLeaseRequestError, createLeaseClient } from '../controller-lease-client.js';\nimport type { CreateBackendDependencies } from './sandbox-backend-contract.js';\n\nexport function createGondolinSandboxBackendManager(\n\toptions: {\n\t\treadonly controllerUrl: string;\n\t\treadonly zoneId: string;\n\t},\n\tdependencies: CreateBackendDependencies,\n): {\n\tdescribeRuntime: (params: {\n\t\treadonly entry: { readonly containerName: string };\n\t}) => Promise<{ readonly configLabelMatch: boolean; readonly running: boolean }>;\n\tremoveRuntime: (params: { readonly entry: { readonly containerName: string } }) => Promise<void>;\n} {\n\treturn {\n\t\tdescribeRuntime: async (params) => {\n\t\t\tconst leaseClient =\n\t\t\t\tdependencies.createLeaseClient?.({\n\t\t\t\t\tcontrollerUrl: options.controllerUrl,\n\t\t\t\t}) ?? createLeaseClient({ controllerUrl: options.controllerUrl });\n\t\t\ttry {\n\t\t\t\tconst leaseStatus = await leaseClient.peekLease(params.entry.containerName);\n\t\t\t\treturn { configLabelMatch: true, running: leaseStatus !== null };\n\t\t\t} catch (error) {\n\t\t\t\tif (!(error instanceof ControllerLeaseRequestError) || error.status !== 404) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\treturn { configLabelMatch: false, running: false };\n\t\t\t}\n\t\t},\n\t\tremoveRuntime: async (params) => {\n\t\t\tconst leaseClient =\n\t\t\t\tdependencies.createLeaseClient?.({\n\t\t\t\t\tcontrollerUrl: options.controllerUrl,\n\t\t\t\t}) ?? createLeaseClient({ controllerUrl: options.controllerUrl });\n\t\t\tawait leaseClient.releaseLease(params.entry.containerName, { force: true });\n\t\t},\n\t};\n}\n","export interface ResolvedGondolinPluginConfig {\n\treadonly controllerUrl: string;\n\treadonly profileId?: string;\n\treadonly zoneGitToken?: string;\n\treadonly zoneGitTokenEnv?: string;\n\treadonly zoneId: string;\n}\n\nexport function resolveGondolinPluginConfig(\n\tconfig: Record<string, unknown>,\n): ResolvedGondolinPluginConfig {\n\tif (typeof config.controllerUrl !== 'string' || typeof config.zoneId !== 'string') {\n\t\tthrow new Error('Gondolin plugin config requires controllerUrl and zoneId.');\n\t}\n\n\treturn {\n\t\tcontrollerUrl: config.controllerUrl,\n\t\t...(typeof config.profileId === 'string' ? { profileId: config.profileId } : {}),\n\t\t...(typeof config.zoneGitToken === 'string' ? { zoneGitToken: config.zoneGitToken } : {}),\n\t\t...(typeof config.zoneGitTokenEnv === 'string'\n\t\t\t? { zoneGitTokenEnv: config.zoneGitTokenEnv }\n\t\t\t: {}),\n\t\tzoneId: config.zoneId,\n\t};\n}\n","import type { SshHelpers, SshSandboxSession } from './openclaw-sandbox-sdk-contract.js';\nimport type {\n\tCreateBackendDependencies,\n\tOpenClawFsBridgeLeaseContext,\n\tOpenClawSandboxFsBridge,\n} from './sandbox-backend-factory.js';\n\nexport function createBackendDeps(ssh: SshHelpers): {\n\treadonly buildExecSpec: CreateBackendDependencies['buildExecSpec'];\n\treadonly createFsBridgeBuilder: (\n\t\tleaseContext: OpenClawFsBridgeLeaseContext,\n\t) => (params: { readonly sandbox: unknown }) => OpenClawSandboxFsBridge;\n\treadonly runRemoteShellScript: CreateBackendDependencies['runRemoteShellScript'];\n} {\n\treturn {\n\t\tbuildExecSpec: async ({ command, env, ssh: sshCreds, usePty, workdir }) => {\n\t\t\tconst session = await ssh.createSshSandboxSessionFromSettings({\n\t\t\t\tcommand: 'ssh',\n\t\t\t\tidentityData: sshCreds.identityPem,\n\t\t\t\tstrictHostKeyChecking: false,\n\t\t\t\ttarget: `${sshCreds.user}@${sshCreds.host}:${sshCreds.port}`,\n\t\t\t\tupdateHostKeys: false,\n\t\t\t\tworkspaceRoot: workdir,\n\t\t\t});\n\t\t\tconst disposeSshSandboxSession = ssh.disposeSshSandboxSession;\n\t\t\treturn {\n\t\t\t\targv: ssh.buildSshSandboxArgv({\n\t\t\t\t\tremoteCommand: ssh.buildExecRemoteCommand({\n\t\t\t\t\t\tcommand,\n\t\t\t\t\t\tenv,\n\t\t\t\t\t\tworkdir,\n\t\t\t\t\t}),\n\t\t\t\t\tsession,\n\t\t\t\t\ttty: usePty,\n\t\t\t\t}),\n\t\t\t\tenv: ssh.sanitizeEnvVars(process.env).allowed,\n\t\t\t\tfinalizeToken: {\n\t\t\t\t\tdispose: async (): Promise<void> => {\n\t\t\t\t\t\tif (disposeSshSandboxSession) {\n\t\t\t\t\t\t\tawait disposeSshSandboxSession(session);\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tsession,\n\t\t\t\t},\n\t\t\t\tstdinMode: 'pipe-open' as const,\n\t\t\t};\n\t\t},\n\t\tcreateFsBridgeBuilder:\n\t\t\t(leaseContext: OpenClawFsBridgeLeaseContext) =>\n\t\t\t(params: { readonly sandbox: unknown }): OpenClawSandboxFsBridge =>\n\t\t\t\tssh.createRemoteShellSandboxFsBridge({\n\t\t\t\t\tsandbox: params.sandbox,\n\t\t\t\t\truntime: {\n\t\t\t\t\t\tremoteAgentWorkspaceDir: leaseContext.remoteAgentWorkspaceDir,\n\t\t\t\t\t\tremoteWorkspaceDir: leaseContext.remoteWorkspaceDir,\n\t\t\t\t\t\trunRemoteShellScript: leaseContext.runRemoteShellScript,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\trunRemoteShellScript: async ({ allowFailure, script, signal, ssh: sshCreds, stdin }) => {\n\t\t\tconst session = await ssh.createSshSandboxSessionFromSettings({\n\t\t\t\tcommand: 'ssh',\n\t\t\t\tidentityData: sshCreds.identityPem,\n\t\t\t\tstrictHostKeyChecking: false,\n\t\t\t\ttarget: `${sshCreds.user}@${sshCreds.host}:${sshCreds.port}`,\n\t\t\t\tupdateHostKeys: false,\n\t\t\t\tworkspaceRoot: '/work',\n\t\t\t});\n\t\t\treturn await ssh.runSshSandboxCommand({\n\t\t\t\t...(allowFailure !== undefined ? { allowFailure } : {}),\n\t\t\t\tremoteCommand: ssh.buildRemoteCommand(['/bin/sh', '-c', script, 'gondolin-sandbox-fs']),\n\t\t\t\tsession,\n\t\t\t\t...(signal !== undefined ? { signal } : {}),\n\t\t\t\t...(stdin !== undefined ? { stdin } : {}),\n\t\t\t});\n\t\t},\n\t};\n}\n\nexport type { SshHelpers, SshSandboxSession };\n","interface OpenClawAgentConfig {\n\treadonly [key: string]: unknown;\n\treadonly id?: unknown;\n\treadonly sandbox?: {\n\t\treadonly [key: string]: unknown;\n\t\treadonly backend?: unknown;\n\t\treadonly mode?: unknown;\n\t\treadonly scope?: unknown;\n\t\treadonly workspaceAccess?: unknown;\n\t};\n\treadonly workspace?: unknown;\n}\n\ninterface OpenClawRuntimeConfig {\n\treadonly [key: string]: unknown;\n\treadonly agents?: {\n\t\treadonly defaults?: OpenClawAgentConfig;\n\t\treadonly list?: readonly unknown[];\n\t};\n}\n\nexport interface OpenClawRuntimeRequirementFinding {\n\treadonly hint: string;\n\treadonly id: string;\n\treadonly ok: boolean;\n}\n\nexport interface OpenClawRuntimeStatusReport {\n\treadonly findings: readonly OpenClawRuntimeRequirementFinding[];\n\treadonly pluginId: 'gondolin';\n\treadonly zoneId: string;\n}\n\nfunction isObjectRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction readAgentConfigEntries(config: OpenClawRuntimeConfig): readonly {\n\treadonly config: OpenClawAgentConfig;\n\treadonly label: string;\n}[] {\n\tconst defaultConfig = config.agents?.defaults ?? {};\n\tconst agentConfigs = (config.agents?.list ?? [])\n\t\t.filter(isObjectRecord)\n\t\t.map((agentConfig, agentIndex) => ({\n\t\t\tconfig: agentConfig,\n\t\t\tlabel:\n\t\t\t\ttypeof agentConfig.id === 'string'\n\t\t\t\t\t? `agent-${agentConfig.id}`\n\t\t\t\t\t: `agent-${String(agentIndex)}`,\n\t\t}));\n\treturn [{ config: defaultConfig, label: 'defaults' }, ...agentConfigs];\n}\n\nfunction effectiveSandboxValue(\n\tdefaults: OpenClawAgentConfig,\n\tagentConfig: OpenClawAgentConfig,\n\tkey: 'backend' | 'mode' | 'scope' | 'workspaceAccess',\n): unknown {\n\treturn agentConfig.sandbox?.[key] ?? defaults.sandbox?.[key];\n}\n\nfunction effectiveWorkspace(\n\tdefaults: OpenClawAgentConfig,\n\tagentConfig: OpenClawAgentConfig,\n): unknown {\n\treturn agentConfig.workspace ?? defaults.workspace;\n}\n\nfunction requirementFinding(options: {\n\treadonly actualValue: unknown;\n\treadonly expectedValue: string;\n\treadonly fieldPath: string;\n\treadonly label: string;\n\treadonly zoneId: string;\n}): OpenClawRuntimeRequirementFinding {\n\tconst ok = options.actualValue === options.expectedValue;\n\treturn {\n\t\tid: `openclaw-tool-vm-${options.fieldPath.replace(/[.[\\]]/gu, '-')}-${options.zoneId}-${options.label}`,\n\t\tok,\n\t\thint: ok\n\t\t\t? `${options.fieldPath}=${options.expectedValue}`\n\t\t\t: `Set ${options.fieldPath} to \"${options.expectedValue}\" for OpenClaw Tool VM mediation.`,\n\t};\n}\n\nexport function buildOpenClawRuntimeStatusReport(options: {\n\treadonly config: Record<string, unknown>;\n\treadonly zoneId: string;\n}): OpenClawRuntimeStatusReport {\n\tconst config: OpenClawRuntimeConfig = options.config;\n\tconst defaults = config.agents?.defaults ?? {};\n\treturn {\n\t\tpluginId: 'gondolin',\n\t\tzoneId: options.zoneId,\n\t\tfindings: readAgentConfigEntries(config).flatMap(({ config: agentConfig, label }) => {\n\t\t\tconst workspace = effectiveWorkspace(defaults, agentConfig);\n\t\t\treturn [\n\t\t\t\trequirementFinding({\n\t\t\t\t\tactualValue: effectiveSandboxValue(defaults, agentConfig, 'backend'),\n\t\t\t\t\texpectedValue: 'gondolin',\n\t\t\t\t\tfieldPath: `agents.${label}.sandbox.backend`,\n\t\t\t\t\tlabel,\n\t\t\t\t\tzoneId: options.zoneId,\n\t\t\t\t}),\n\t\t\t\trequirementFinding({\n\t\t\t\t\tactualValue: effectiveSandboxValue(defaults, agentConfig, 'mode'),\n\t\t\t\t\texpectedValue: 'all',\n\t\t\t\t\tfieldPath: `agents.${label}.sandbox.mode`,\n\t\t\t\t\tlabel,\n\t\t\t\t\tzoneId: options.zoneId,\n\t\t\t\t}),\n\t\t\t\trequirementFinding({\n\t\t\t\t\tactualValue: effectiveSandboxValue(defaults, agentConfig, 'scope'),\n\t\t\t\t\texpectedValue: 'agent',\n\t\t\t\t\tfieldPath: `agents.${label}.sandbox.scope`,\n\t\t\t\t\tlabel,\n\t\t\t\t\tzoneId: options.zoneId,\n\t\t\t\t}),\n\t\t\t\trequirementFinding({\n\t\t\t\t\tactualValue: effectiveSandboxValue(defaults, agentConfig, 'workspaceAccess'),\n\t\t\t\t\texpectedValue: 'rw',\n\t\t\t\t\tfieldPath: `agents.${label}.sandbox.workspaceAccess`,\n\t\t\t\t\tlabel,\n\t\t\t\t\tzoneId: options.zoneId,\n\t\t\t\t}),\n\t\t\t\t{\n\t\t\t\t\tid: `openclaw-tool-vm-workspace-${options.zoneId}-${label}`,\n\t\t\t\t\tok: workspace !== '/zone',\n\t\t\t\t\thint:\n\t\t\t\t\t\tworkspace === '/zone'\n\t\t\t\t\t\t\t? 'Use /zone/agents/default or per-agent workspaces; keep /zone for shared zone files.'\n\t\t\t\t\t\t\t: typeof workspace === 'string'\n\t\t\t\t\t\t\t\t? workspace\n\t\t\t\t\t\t\t\t: 'agents workspace is unset',\n\t\t\t\t},\n\t\t\t] as const satisfies readonly OpenClawRuntimeRequirementFinding[];\n\t\t}),\n\t};\n}\n","export interface SshSandboxSession {\n\treadonly command: string;\n\treadonly configPath: string;\n\treadonly host: string;\n}\n\nexport interface SshHelpers {\n\treadonly buildExecRemoteCommand: (params: {\n\t\treadonly command: string;\n\t\treadonly env: Record<string, string>;\n\t\treadonly workdir?: string;\n\t}) => string;\n\treadonly buildRemoteCommand: (argv: readonly string[]) => string;\n\treadonly buildSshSandboxArgv: (params: {\n\t\treadonly remoteCommand: string;\n\t\treadonly session: SshSandboxSession;\n\t\treadonly tty?: boolean;\n\t}) => string[];\n\treadonly createRemoteShellSandboxFsBridge: (params: {\n\t\treadonly runtime: {\n\t\t\treadonly remoteAgentWorkspaceDir: string;\n\t\t\treadonly remoteWorkspaceDir: string;\n\t\t\treadonly runRemoteShellScript: (shellParams: {\n\t\t\t\treadonly allowFailure?: boolean;\n\t\t\t\treadonly args?: string[];\n\t\t\t\treadonly script: string;\n\t\t\t\treadonly signal?: AbortSignal;\n\t\t\t\treadonly stdin?: Buffer | string;\n\t\t\t}) => Promise<{\n\t\t\t\treadonly code: number;\n\t\t\t\treadonly stderr: Buffer;\n\t\t\t\treadonly stdout: Buffer;\n\t\t\t}>;\n\t\t};\n\t\treadonly sandbox: unknown;\n\t}) => import('./sandbox-backend-factory.js').OpenClawSandboxFsBridge;\n\treadonly createSshSandboxSessionFromSettings: (settings: {\n\t\treadonly command: string;\n\t\treadonly identityData?: string;\n\t\treadonly strictHostKeyChecking: boolean;\n\t\treadonly target: string;\n\t\treadonly updateHostKeys: boolean;\n\t\treadonly workspaceRoot: string;\n\t}) => Promise<SshSandboxSession>;\n\treadonly disposeSshSandboxSession?: (session: SshSandboxSession) => Promise<void>;\n\treadonly runSshSandboxCommand: (params: {\n\t\treadonly allowFailure?: boolean;\n\t\treadonly remoteCommand: string;\n\t\treadonly session: SshSandboxSession;\n\t\treadonly signal?: AbortSignal;\n\t\treadonly stdin?: Buffer | string;\n\t}) => Promise<{\n\t\treadonly code: number;\n\t\treadonly stderr: Buffer;\n\t\treadonly stdout: Buffer;\n\t}>;\n\treadonly sanitizeEnvVars: (env: NodeJS.ProcessEnv) => {\n\t\treadonly allowed: Record<string, string>;\n\t};\n}\n\nexport interface OpenClawToolRegistration {\n\treadonly description: string;\n\treadonly execute: (toolCallId: string, params: unknown) => Promise<OpenClawToolResult>;\n\treadonly name: string;\n\treadonly parameters: Record<string, unknown>;\n}\n\nexport interface OpenClawToolRegistrationOptions {\n\treadonly name?: string;\n\treadonly names?: readonly string[];\n\treadonly optional?: boolean;\n}\n\nexport interface OpenClawToolResult {\n\treadonly content: string;\n\treadonly details?: unknown;\n}\n\nexport interface OpenClawToolRegistrationApi {\n\treadonly registerTool?: (\n\t\ttool: OpenClawToolRegistration,\n\t\toptions?: OpenClawToolRegistrationOptions,\n\t) => void;\n}\n\nexport function assertSdkShape(value: unknown): asserts value is SshHelpers & {\n\tregisterSandboxBackend: (\n\t\tid: string,\n\t\tregistration: {\n\t\t\tfactory: ReturnType<\n\t\t\t\ttypeof import('./sandbox-backend-factory.js').createGondolinSandboxBackendFactory\n\t\t\t>;\n\t\t\tmanager?: ReturnType<\n\t\t\t\ttypeof import('./sandbox-backend-factory.js').createGondolinSandboxBackendManager\n\t\t\t>;\n\t\t},\n\t) => void;\n} {\n\tif (typeof value !== 'object' || value === null) {\n\t\tthrow new TypeError('OpenClaw SDK module is not an object');\n\t}\n\n\tfor (const exportName of [\n\t\t'buildExecRemoteCommand',\n\t\t'buildRemoteCommand',\n\t\t'buildSshSandboxArgv',\n\t\t'createRemoteShellSandboxFsBridge',\n\t\t'createSshSandboxSessionFromSettings',\n\t\t'runSshSandboxCommand',\n\t\t'sanitizeEnvVars',\n\t\t'registerSandboxBackend',\n\t] as const) {\n\t\tif (typeof (value as Record<string, unknown>)[exportName] !== 'function') {\n\t\t\tthrow new TypeError(`OpenClaw SDK missing required export: ${exportName}`);\n\t\t}\n\t}\n}\n","import type { OpenClawToolRegistrationApi } from './openclaw-sandbox-sdk-contract.js';\n\ntype RequiredOpenClawToolRegistrationApi = OpenClawToolRegistrationApi & {\n\treadonly registerTool: NonNullable<OpenClawToolRegistrationApi['registerTool']>;\n};\n\nexport interface RegisterZoneGitToolOptions {\n\treadonly api: RequiredOpenClawToolRegistrationApi;\n\treadonly controllerUrl: string;\n\treadonly fetchImpl?: typeof fetch;\n\treadonly zoneGitToken?: string;\n\treadonly zoneId: string;\n}\n\nconst zoneGitCapabilityHeader = 'x-agent-vm-zone-git-token';\n\nfunction readExpectedHead(input: unknown): string {\n\tif (typeof input !== 'object' || input === null || !('expectedHead' in input)) {\n\t\tthrow new Error('zone_git_push requires expectedHead.');\n\t}\n\tconst expectedHead = input.expectedHead;\n\tif (typeof expectedHead !== 'string' || expectedHead.length === 0) {\n\t\tthrow new Error('zone_git_push requires expectedHead.');\n\t}\n\treturn expectedHead;\n}\n\nfunction buildControllerUrl(controllerUrl: string, zoneId: string): string {\n\treturn `${controllerUrl.replace(/\\/$/u, '')}/zones/${encodeURIComponent(zoneId)}/zone-git/push`;\n}\n\nasync function readResponseText(response: Response): Promise<string> {\n\ttry {\n\t\treturn await response.text();\n\t} catch (error) {\n\t\treturn error instanceof Error ? error.message : String(error);\n\t}\n}\n\nfunction parseJsonPayload(responseText: string): unknown {\n\ttry {\n\t\treturn JSON.parse(responseText);\n\t} catch (error) {\n\t\tthrow new Error(`zone_git_push returned non-JSON response: ${responseText.slice(0, 500)}`, {\n\t\t\tcause: error,\n\t\t});\n\t}\n}\n\nexport function registerZoneGitTool(options: RegisterZoneGitToolOptions): void {\n\toptions.api.registerTool(\n\t\t{\n\t\t\tname: 'zone_git_push',\n\t\t\tdescription:\n\t\t\t\t'Push committed OpenClaw zone workspace changes through the agent-vm controller. Use after git commit; do not run raw git push.',\n\t\t\tparameters: {\n\t\t\t\ttype: 'object',\n\t\t\t\tadditionalProperties: false,\n\t\t\t\tproperties: {\n\t\t\t\t\texpectedHead: { type: 'string' },\n\t\t\t\t},\n\t\t\t\trequired: ['expectedHead'],\n\t\t\t},\n\t\t\texecute: async (_toolCallId: string, input: unknown) => {\n\t\t\t\tconst expectedHead = readExpectedHead(input);\n\t\t\t\tconst response = await (options.fetchImpl ?? fetch)(\n\t\t\t\t\tbuildControllerUrl(options.controllerUrl, options.zoneId),\n\t\t\t\t\t{\n\t\t\t\t\t\tbody: JSON.stringify({ expectedHead }),\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t'content-type': 'application/json',\n\t\t\t\t\t\t\t...(options.zoneGitToken ? { [zoneGitCapabilityHeader]: options.zoneGitToken } : {}),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tconst responseText = await readResponseText(response);\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tthrow new Error(`zone_git_push failed: ${response.status} ${responseText.slice(0, 500)}`);\n\t\t\t\t}\n\t\t\t\tconst payload = parseJsonPayload(responseText);\n\t\t\t\treturn {\n\t\t\t\t\tcontent: JSON.stringify(payload),\n\t\t\t\t\tdetails: payload,\n\t\t\t\t};\n\t\t\t},\n\t\t},\n\t\t{ name: 'zone_git_push', optional: true },\n\t);\n}\n","import { createLeaseClient } from './controller-lease-client.js';\nimport { resolveGondolinPluginConfig } from './gondolin-plugin-config.js';\nimport { createBackendDeps } from './openclaw-backend-dependencies.js';\nimport { buildOpenClawRuntimeStatusReport } from './openclaw-runtime-status.js';\nimport {\n\tassertSdkShape,\n\ttype OpenClawToolRegistrationApi,\n\ttype SshHelpers,\n\ttype SshSandboxSession,\n} from './openclaw-sandbox-sdk-contract.js';\nimport {\n\tcreateGondolinSandboxBackendFactory,\n\tcreateGondolinSandboxBackendManager,\n} from './sandbox-backend-factory.js';\nimport { registerZoneGitTool } from './zone-git-tool.js';\n\nconst plugin = {\n\tid: 'gondolin',\n\tname: 'Gondolin VM Sandbox',\n\tdescription: 'Sandbox backend powered by Gondolin micro-VMs.',\n\n\tregister(api: {\n\t\treadonly config?: Record<string, unknown>;\n\t\treadonly pluginConfig: Record<string, unknown>;\n\t\treadonly registerTool?: OpenClawToolRegistrationApi['registerTool'];\n\t\treadonly registrationMode: string;\n\t\treadonly runtime?: {\n\t\t\treadonly config?: {\n\t\t\t\treadonly current?: () => Record<string, unknown>;\n\t\t\t};\n\t\t};\n\t}): void {\n\t\tconst registerTool = api.registerTool;\n\t\tif (typeof registerTool !== 'function') {\n\t\t\tif (api.registrationMode === 'full') {\n\t\t\t\tthrow new Error('Gondolin full registration requires OpenClaw registerTool.');\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tconst pluginConfig = resolveGondolinPluginConfig(api.pluginConfig);\n\t\tconst zoneGitToken =\n\t\t\tpluginConfig.zoneGitToken ??\n\t\t\t(pluginConfig.zoneGitTokenEnv ? process.env[pluginConfig.zoneGitTokenEnv] : undefined);\n\t\tregisterZoneGitTool({\n\t\t\tapi: { registerTool },\n\t\t\tcontrollerUrl: pluginConfig.controllerUrl,\n\t\t\t...(zoneGitToken ? { zoneGitToken } : {}),\n\t\t\tzoneId: pluginConfig.zoneId,\n\t\t});\n\t\tif (api.registrationMode !== 'full') {\n\t\t\treturn;\n\t\t}\n\t\tconst buildRuntimeStatus = ():\n\t\t\t| ReturnType<typeof buildOpenClawRuntimeStatusReport>\n\t\t\t| undefined => {\n\t\t\tconst runtimeConfig = api.runtime?.config?.current?.() ?? api.config;\n\t\t\treturn runtimeConfig\n\t\t\t\t? buildOpenClawRuntimeStatusReport({\n\t\t\t\t\t\tconfig: runtimeConfig,\n\t\t\t\t\t\tzoneId: pluginConfig.zoneId,\n\t\t\t\t\t})\n\t\t\t\t: undefined;\n\t\t};\n\t\tconst initialRuntimeStatus = buildRuntimeStatus();\n\t\tif (initialRuntimeStatus) {\n\t\t\tconst leaseClient = createLeaseClient({ controllerUrl: pluginConfig.controllerUrl });\n\t\t\tvoid leaseClient\n\t\t\t\t.publishOpenClawRuntimeStatus?.(initialRuntimeStatus)\n\t\t\t\t?.catch((error: unknown) => {\n\t\t\t\t\tconst message = error instanceof Error ? error.message : JSON.stringify(error);\n\t\t\t\t\tprocess.stderr.write(\n\t\t\t\t\t\t`[gondolin] failed to publish OpenClaw runtime status: ${message}\\n`,\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t}\n\n\t\tconst sdkPath = '/opt/openclaw-sdk/sandbox.js';\n\t\tconst sdkPromise = import(sdkPath).then((sdkRaw: Record<string, unknown>) => {\n\t\t\tassertSdkShape(sdkRaw);\n\n\t\t\tconst sshHelpers: SshHelpers = {\n\t\t\t\tbuildExecRemoteCommand: sdkRaw.buildExecRemoteCommand,\n\t\t\t\tbuildRemoteCommand: sdkRaw.buildRemoteCommand,\n\t\t\t\tbuildSshSandboxArgv: sdkRaw.buildSshSandboxArgv,\n\t\t\t\tcreateRemoteShellSandboxFsBridge: sdkRaw.createRemoteShellSandboxFsBridge,\n\t\t\t\tcreateSshSandboxSessionFromSettings: sdkRaw.createSshSandboxSessionFromSettings,\n\t\t\t\t...(typeof sdkRaw.disposeSshSandboxSession === 'function'\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tdisposeSshSandboxSession: sdkRaw.disposeSshSandboxSession as (\n\t\t\t\t\t\t\t\tsession: SshSandboxSession,\n\t\t\t\t\t\t\t) => Promise<void>,\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t\trunSshSandboxCommand: sdkRaw.runSshSandboxCommand,\n\t\t\t\tsanitizeEnvVars: sdkRaw.sanitizeEnvVars,\n\t\t\t};\n\n\t\t\tconst backendDependencies = createBackendDeps(sshHelpers);\n\t\t\tsdkRaw.registerSandboxBackend('gondolin', {\n\t\t\t\tfactory: createGondolinSandboxBackendFactory(\n\t\t\t\t\t{\n\t\t\t\t\t\t...pluginConfig,\n\t\t\t\t\t\topenClawRuntimeStatusProvider: buildRuntimeStatus,\n\t\t\t\t\t},\n\t\t\t\t\tbackendDependencies,\n\t\t\t\t),\n\t\t\t\tmanager: createGondolinSandboxBackendManager(pluginConfig, backendDependencies),\n\t\t\t});\n\t\t});\n\n\t\tsdkPromise.catch((error: unknown) => {\n\t\t\tconst message = error instanceof Error ? error.message : JSON.stringify(error);\n\t\t\tprocess.stderr.write(`[gondolin] failed to load OpenClaw SDK: ${message}\\n`);\n\t\t});\n\t},\n};\n\nexport default plugin;\n\nexport { createBackendDeps };\nexport type { SshHelpers };\n","export * from './sandbox-backend-factory.js';\nexport * from './gondolin-plugin-config.js';\nexport * from './controller-lease-client.js';\nexport * from './openclaw-plugin-registration.js';\nexport { default } from './openclaw-plugin-registration.js';\n\nexport const OPENCLAW_GONDOLIN_PLUGIN_PACKAGE_NAME = '@agent-vm/openclaw-agent-vm-plugin';\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-vm/openclaw-agent-vm-plugin",
3
- "version": "0.0.71",
3
+ "version": "0.0.73",
4
4
  "description": "OpenClaw sandbox-backend plugin that delegates execution to a Gondolin-managed VM.",
5
5
  "homepage": "https://github.com/ShravanSunder/agent-vm#readme",
6
6
  "bugs": {
@@ -29,7 +29,8 @@
29
29
  "access": "public"
30
30
  },
31
31
  "dependencies": {
32
- "@agent-vm/gondolin-adapter": "0.0.71"
32
+ "@agent-vm/gateway-interface": "0.0.73",
33
+ "@agent-vm/gondolin-adapter": "0.0.73"
33
34
  },
34
35
  "scripts": {
35
36
  "build": "tsdown && cp openclaw.plugin.json sdk-validate.mjs dist/",