@kodelyth/acpx 2026.5.42 → 2026.6.2

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/src/config.ts DELETED
@@ -1,281 +0,0 @@
1
- import fs from "node:fs";
2
- import { createRequire } from "node:module";
3
- import path from "node:path";
4
- import { fileURLToPath } from "node:url";
5
- import { formatPluginConfigIssue } from "klaw/plugin-sdk/extension-shared";
6
- import { normalizeLowercaseStringOrEmpty } from "klaw/plugin-sdk/string-coerce-runtime";
7
- import { AcpxPluginConfigSchema, DEFAULT_ACPX_TIMEOUT_SECONDS } from "./config-schema.js";
8
- import type {
9
- AcpxPluginConfig,
10
- AcpxPermissionMode,
11
- AcpxNonInteractivePermissionPolicy,
12
- McpServerConfig,
13
- AcpxMcpServer,
14
- ResolvedAcpxPluginConfig,
15
- } from "./config-schema.js";
16
- export { type ResolvedAcpxPluginConfig } from "./config-schema.js";
17
-
18
- const ACPX_PLUGIN_TOOLS_MCP_SERVER_NAME = "klaw-plugin-tools";
19
- const ACPX_KLAW_TOOLS_MCP_SERVER_NAME = "klaw-tools";
20
- const requireFromHere = createRequire(import.meta.url);
21
-
22
- function isAcpxPluginRoot(dir: string): boolean {
23
- return (
24
- fs.existsSync(path.join(dir, "klaw.plugin.json")) &&
25
- fs.existsSync(path.join(dir, "package.json"))
26
- );
27
- }
28
-
29
- function resolveNearestAcpxPluginRoot(moduleUrl: string): string {
30
- let cursor = path.dirname(fileURLToPath(moduleUrl));
31
- for (let i = 0; i < 3; i += 1) {
32
- // Bundled entries live at the plugin root while source files still live under src/.
33
- if (isAcpxPluginRoot(cursor)) {
34
- return cursor;
35
- }
36
- const parent = path.dirname(cursor);
37
- if (parent === cursor) {
38
- break;
39
- }
40
- cursor = parent;
41
- }
42
- return path.resolve(path.dirname(fileURLToPath(moduleUrl)), "..");
43
- }
44
-
45
- function resolveWorkspaceAcpxPluginRoot(currentRoot: string): string | null {
46
- if (
47
- path.basename(currentRoot) !== "acpx" ||
48
- path.basename(path.dirname(currentRoot)) !== "extensions" ||
49
- path.basename(path.dirname(path.dirname(currentRoot))) !== "dist"
50
- ) {
51
- return null;
52
- }
53
- const workspaceRoot = path.resolve(currentRoot, "..", "..", "..", "extensions", "acpx");
54
- return isAcpxPluginRoot(workspaceRoot) ? workspaceRoot : null;
55
- }
56
-
57
- function resolveRepoAcpxPluginRoot(currentRoot: string): string | null {
58
- const workspaceRoot = path.join(currentRoot, "extensions", "acpx");
59
- return isAcpxPluginRoot(workspaceRoot) ? workspaceRoot : null;
60
- }
61
-
62
- function resolveAcpxPluginRootFromKlawLayout(moduleUrl: string): string | null {
63
- let cursor = path.dirname(fileURLToPath(moduleUrl));
64
- for (let i = 0; i < 5; i += 1) {
65
- const candidates = [
66
- path.join(cursor, "extensions", "acpx"),
67
- path.join(cursor, "dist", "extensions", "acpx"),
68
- path.join(cursor, "dist-runtime", "extensions", "acpx"),
69
- ];
70
- for (const candidate of candidates) {
71
- if (isAcpxPluginRoot(candidate)) {
72
- return candidate;
73
- }
74
- }
75
- const parent = path.dirname(cursor);
76
- if (parent === cursor) {
77
- break;
78
- }
79
- cursor = parent;
80
- }
81
- return null;
82
- }
83
- export function resolveAcpxPluginRoot(moduleUrl: string = import.meta.url): string {
84
- const resolvedRoot = resolveNearestAcpxPluginRoot(moduleUrl);
85
- // In a live repo checkout, dist/ can be rebuilt out from under the running gateway.
86
- // Prefer the stable source plugin root when a built extension is running beside it.
87
- return (
88
- resolveWorkspaceAcpxPluginRoot(resolvedRoot) ??
89
- resolveRepoAcpxPluginRoot(resolvedRoot) ??
90
- // Shared dist/dist-runtime chunks can load this module outside the plugin tree.
91
- // Scan common Klaw layouts before falling back to the nearest path guess.
92
- resolveAcpxPluginRootFromKlawLayout(moduleUrl) ??
93
- resolvedRoot
94
- );
95
- }
96
-
97
- const DEFAULT_PERMISSION_MODE: AcpxPermissionMode = "approve-reads";
98
- const DEFAULT_NON_INTERACTIVE_POLICY: AcpxNonInteractivePermissionPolicy = "fail";
99
- const DEFAULT_QUEUE_OWNER_TTL_SECONDS = 0.1;
100
- const DEFAULT_STRICT_WINDOWS_CMD_WRAPPER = true;
101
-
102
- type ParseResult =
103
- | { ok: true; value: AcpxPluginConfig | undefined }
104
- | { ok: false; message: string };
105
-
106
- function parseAcpxPluginConfig(value: unknown): ParseResult {
107
- if (value === undefined) {
108
- return { ok: true, value: undefined };
109
- }
110
- const parsed = AcpxPluginConfigSchema.safeParse(value);
111
- if (!parsed.success) {
112
- return { ok: false, message: formatPluginConfigIssue(parsed.error.issues[0]) };
113
- }
114
- return {
115
- ok: true,
116
- value: parsed.data as AcpxPluginConfig,
117
- };
118
- }
119
-
120
- function resolveKlawRoot(currentRoot: string): string {
121
- if (
122
- path.basename(currentRoot) === "acpx" &&
123
- path.basename(path.dirname(currentRoot)) === "extensions"
124
- ) {
125
- const parent = path.dirname(path.dirname(currentRoot));
126
- if (path.basename(parent) === "dist") {
127
- return path.dirname(parent);
128
- }
129
- return parent;
130
- }
131
- return path.resolve(currentRoot, "..");
132
- }
133
-
134
- function resolveTsxImportSpecifier(): string {
135
- try {
136
- return requireFromHere.resolve("tsx");
137
- } catch {
138
- return "tsx";
139
- }
140
- }
141
-
142
- function shellQuoteCommandArg(arg: string): string {
143
- if (!/[\s'"\\$|&;<>{}()*?[\]~`]/.test(arg)) {
144
- return arg;
145
- }
146
- return `'${arg.replace(/'/g, "'\"'\"'")}'`;
147
- }
148
-
149
- function resolvePluginToolsMcpServerConfig(moduleUrl: string = import.meta.url): McpServerConfig {
150
- const pluginRoot = resolveAcpxPluginRoot(moduleUrl);
151
- const openClawRoot = resolveKlawRoot(pluginRoot);
152
- const distEntry = path.join(openClawRoot, "dist", "mcp", "plugin-tools-serve.js");
153
- if (fs.existsSync(distEntry)) {
154
- return {
155
- command: process.execPath,
156
- args: [distEntry],
157
- };
158
- }
159
- const sourceEntry = path.join(openClawRoot, "src", "mcp", "plugin-tools-serve.ts");
160
- return {
161
- command: process.execPath,
162
- args: ["--import", resolveTsxImportSpecifier(), sourceEntry],
163
- };
164
- }
165
-
166
- function resolveKlawToolsMcpServerConfig(moduleUrl: string = import.meta.url): McpServerConfig {
167
- const pluginRoot = resolveAcpxPluginRoot(moduleUrl);
168
- const openClawRoot = resolveKlawRoot(pluginRoot);
169
- const distEntry = path.join(openClawRoot, "dist", "mcp", "klaw-tools-serve.js");
170
- if (fs.existsSync(distEntry)) {
171
- return {
172
- command: process.execPath,
173
- args: [distEntry],
174
- };
175
- }
176
- const sourceEntry = path.join(openClawRoot, "src", "mcp", "klaw-tools-serve.ts");
177
- return {
178
- command: process.execPath,
179
- args: ["--import", resolveTsxImportSpecifier(), sourceEntry],
180
- };
181
- }
182
-
183
- function resolveConfiguredMcpServers(params: {
184
- mcpServers?: Record<string, McpServerConfig>;
185
- pluginToolsMcpBridge: boolean;
186
- openClawToolsMcpBridge: boolean;
187
- moduleUrl?: string;
188
- }): Record<string, McpServerConfig> {
189
- const resolved = { ...params.mcpServers };
190
- if (params.pluginToolsMcpBridge && resolved[ACPX_PLUGIN_TOOLS_MCP_SERVER_NAME]) {
191
- throw new Error(
192
- `mcpServers.${ACPX_PLUGIN_TOOLS_MCP_SERVER_NAME} is reserved when pluginToolsMcpBridge=true`,
193
- );
194
- }
195
- if (params.openClawToolsMcpBridge && resolved[ACPX_KLAW_TOOLS_MCP_SERVER_NAME]) {
196
- throw new Error(
197
- `mcpServers.${ACPX_KLAW_TOOLS_MCP_SERVER_NAME} is reserved when openClawToolsMcpBridge=true`,
198
- );
199
- }
200
- if (params.pluginToolsMcpBridge) {
201
- resolved[ACPX_PLUGIN_TOOLS_MCP_SERVER_NAME] = resolvePluginToolsMcpServerConfig(
202
- params.moduleUrl,
203
- );
204
- }
205
- if (params.openClawToolsMcpBridge) {
206
- resolved[ACPX_KLAW_TOOLS_MCP_SERVER_NAME] = resolveKlawToolsMcpServerConfig(params.moduleUrl);
207
- }
208
- return resolved;
209
- }
210
-
211
- export function toAcpMcpServers(mcpServers: Record<string, McpServerConfig>): AcpxMcpServer[] {
212
- return Object.entries(mcpServers).map(([name, server]) => ({
213
- name,
214
- command: server.command,
215
- args: [...(server.args ?? [])],
216
- env: Object.entries(server.env ?? {}).map(([envName, value]) => ({
217
- name: envName,
218
- value,
219
- })),
220
- }));
221
- }
222
-
223
- export function resolveAcpxPluginConfig(params: {
224
- rawConfig: unknown;
225
- workspaceDir?: string;
226
- moduleUrl?: string;
227
- }): ResolvedAcpxPluginConfig {
228
- const parsed = parseAcpxPluginConfig(params.rawConfig);
229
- if (!parsed.ok) {
230
- throw new Error(parsed.message);
231
- }
232
- const normalized = parsed.value ?? {};
233
- const workspaceDir = params.workspaceDir?.trim() || process.cwd();
234
- const fallbackCwd = workspaceDir;
235
- const cwd = path.resolve(normalized.cwd?.trim() || fallbackCwd);
236
- const stateDir = path.resolve(normalized.stateDir?.trim() || path.join(workspaceDir, "state"));
237
- const pluginToolsMcpBridge = normalized.pluginToolsMcpBridge === true;
238
- const openClawToolsMcpBridge = normalized.openClawToolsMcpBridge === true;
239
- const mcpServers = resolveConfiguredMcpServers({
240
- mcpServers: normalized.mcpServers,
241
- pluginToolsMcpBridge,
242
- openClawToolsMcpBridge,
243
- moduleUrl: params.moduleUrl,
244
- });
245
- const agents = Object.fromEntries(
246
- Object.entries(normalized.agents ?? {}).map(([name, entry]) => {
247
- const cmd = entry.command.trim();
248
- const cmdArgs = entry.args ?? [];
249
- const fullCommand =
250
- cmdArgs.length > 0 ? `${cmd} ${cmdArgs.map(shellQuoteCommandArg).join(" ")}` : cmd;
251
- return [normalizeLowercaseStringOrEmpty(name), fullCommand];
252
- }),
253
- );
254
-
255
- // Lowercase probeAgent so lookups match the registry keys built above, which
256
- // also go through normalizeLowercaseStringOrEmpty. Without this, a user who
257
- // writes `probeAgent: "OpenCode"` would silently miss the stored "opencode"
258
- // key.
259
- const probeAgent = normalizeLowercaseStringOrEmpty(normalized.probeAgent) || undefined;
260
-
261
- return {
262
- cwd,
263
- stateDir,
264
- probeAgent,
265
- permissionMode: normalized.permissionMode ?? DEFAULT_PERMISSION_MODE,
266
- nonInteractivePermissions:
267
- normalized.nonInteractivePermissions ?? DEFAULT_NON_INTERACTIVE_POLICY,
268
- pluginToolsMcpBridge,
269
- openClawToolsMcpBridge,
270
- strictWindowsCmdWrapper:
271
- normalized.strictWindowsCmdWrapper ?? DEFAULT_STRICT_WINDOWS_CMD_WRAPPER,
272
- timeoutSeconds: normalized.timeoutSeconds ?? DEFAULT_ACPX_TIMEOUT_SECONDS,
273
- queueOwnerTtlSeconds: normalized.queueOwnerTtlSeconds ?? DEFAULT_QUEUE_OWNER_TTL_SECONDS,
274
- legacyCompatibilityConfig: {
275
- strictWindowsCmdWrapper: normalized.strictWindowsCmdWrapper,
276
- queueOwnerTtlSeconds: normalized.queueOwnerTtlSeconds,
277
- },
278
- mcpServers,
279
- agents,
280
- };
281
- }
@@ -1,21 +0,0 @@
1
- import fs from "node:fs";
2
- import { describe, expect, it } from "vitest";
3
-
4
- type AcpxPackageManifest = {
5
- dependencies?: Record<string, string>;
6
- devDependencies?: Record<string, string>;
7
- };
8
-
9
- describe("acpx package manifest", () => {
10
- it("keeps runtime dependencies in the package manifest", () => {
11
- const packageJson = JSON.parse(
12
- fs.readFileSync(new URL("../package.json", import.meta.url), "utf8"),
13
- ) as AcpxPackageManifest;
14
-
15
- expect(packageJson.dependencies?.acpx).toBeTypeOf("string");
16
- expect(packageJson.dependencies?.acpx).not.toBe("");
17
- expect(packageJson.dependencies?.["@zed-industries/codex-acp"]).toBe("0.14.0");
18
- expect(packageJson.dependencies?.["@agentclientprotocol/claude-agent-acp"]).toBe("0.33.1");
19
- expect(packageJson.devDependencies?.["@agentclientprotocol/claude-agent-acp"]).toBeUndefined();
20
- });
21
- });
@@ -1,89 +0,0 @@
1
- import { mkdtemp, rm } from "node:fs/promises";
2
- import { tmpdir } from "node:os";
3
- import path from "node:path";
4
- import { describe, expect, it } from "vitest";
5
- import {
6
- createAcpxProcessLeaseStore,
7
- KLAW_ACPX_LEASE_ID_ARG,
8
- KLAW_ACPX_LEASE_ID_ENV,
9
- KLAW_GATEWAY_INSTANCE_ID_ARG,
10
- KLAW_GATEWAY_INSTANCE_ID_ENV,
11
- withAcpxLeaseEnvironment,
12
- type AcpxProcessLease,
13
- } from "./process-lease.js";
14
-
15
- function makeLease(index: number): AcpxProcessLease {
16
- return {
17
- leaseId: `lease-${index}`,
18
- gatewayInstanceId: "gateway-test",
19
- sessionKey: `agent:codex:acp:${index}`,
20
- wrapperRoot: "/tmp/klaw/acpx",
21
- wrapperPath: "/tmp/klaw/acpx/codex-acp-wrapper.mjs",
22
- rootPid: 1000 + index,
23
- commandHash: `hash-${index}`,
24
- startedAt: index,
25
- state: "open",
26
- };
27
- }
28
-
29
- describe("createAcpxProcessLeaseStore", () => {
30
- it("serializes concurrent lease saves without dropping records", async () => {
31
- const stateDir = await mkdtemp(path.join(tmpdir(), "klaw-acpx-leases-"));
32
- try {
33
- const store = createAcpxProcessLeaseStore({ stateDir });
34
- await Promise.all(Array.from({ length: 25 }, (_, index) => store.save(makeLease(index))));
35
-
36
- const leases = await store.listOpen("gateway-test");
37
- expect(leases.map((lease) => lease.leaseId).toSorted()).toEqual(
38
- Array.from({ length: 25 }, (_, index) => `lease-${index}`).toSorted(),
39
- );
40
- } finally {
41
- await rm(stateDir, { recursive: true, force: true });
42
- }
43
- });
44
- });
45
-
46
- describe("withAcpxLeaseEnvironment", () => {
47
- it("adds lease environment and wrapper args on POSIX", () => {
48
- const command = withAcpxLeaseEnvironment({
49
- command: "node /tmp/klaw/acpx/codex-acp-wrapper.mjs",
50
- leaseId: "lease-test",
51
- gatewayInstanceId: "gateway-test",
52
- platform: "darwin",
53
- });
54
-
55
- expect(command).toBe(
56
- [
57
- "env",
58
- `${KLAW_ACPX_LEASE_ID_ENV}=lease-test`,
59
- `${KLAW_GATEWAY_INSTANCE_ID_ENV}=gateway-test`,
60
- "node /tmp/klaw/acpx/codex-acp-wrapper.mjs",
61
- KLAW_ACPX_LEASE_ID_ARG,
62
- "lease-test",
63
- KLAW_GATEWAY_INSTANCE_ID_ARG,
64
- "gateway-test",
65
- ].join(" "),
66
- );
67
- });
68
-
69
- it("keeps Windows logs keyed by lease id with wrapper args", () => {
70
- const command = withAcpxLeaseEnvironment({
71
- command: "node C:/klaw/acpx/codex-acp-wrapper.mjs",
72
- leaseId: "lease-test",
73
- gatewayInstanceId: "gateway-test",
74
- platform: "win32",
75
- });
76
-
77
- expect(command).toBe(
78
- [
79
- "node C:/klaw/acpx/codex-acp-wrapper.mjs",
80
- KLAW_ACPX_LEASE_ID_ARG,
81
- "lease-test",
82
- KLAW_GATEWAY_INSTANCE_ID_ARG,
83
- "gateway-test",
84
- ].join(" "),
85
- );
86
- expect(command).not.toContain(`${KLAW_ACPX_LEASE_ID_ENV}=`);
87
- expect(command).not.toContain(`${KLAW_GATEWAY_INSTANCE_ID_ENV}=`);
88
- });
89
- });
@@ -1,179 +0,0 @@
1
- import { randomUUID, createHash } from "node:crypto";
2
- import fs from "node:fs/promises";
3
- import path from "node:path";
4
- import { readJsonFileWithFallback, writeJsonFileAtomically } from "klaw/plugin-sdk/json-store";
5
-
6
- export const KLAW_ACPX_LEASE_ID_ENV = "KLAW_ACPX_LEASE_ID";
7
- export const KLAW_GATEWAY_INSTANCE_ID_ENV = "KLAW_GATEWAY_INSTANCE_ID";
8
- export const KLAW_ACPX_LEASE_ID_ARG = "--klaw-acpx-lease-id";
9
- export const KLAW_GATEWAY_INSTANCE_ID_ARG = "--klaw-gateway-instance-id";
10
-
11
- export type AcpxProcessLeaseState = "open" | "closing" | "closed" | "lost";
12
-
13
- export type AcpxProcessLease = {
14
- leaseId: string;
15
- gatewayInstanceId: string;
16
- sessionKey: string;
17
- wrapperRoot: string;
18
- wrapperPath: string;
19
- rootPid: number;
20
- processGroupId?: number;
21
- commandHash: string;
22
- startedAt: number;
23
- state: AcpxProcessLeaseState;
24
- };
25
-
26
- export type AcpxProcessLeaseStore = {
27
- load(leaseId: string): Promise<AcpxProcessLease | undefined>;
28
- listOpen(gatewayInstanceId?: string): Promise<AcpxProcessLease[]>;
29
- save(lease: AcpxProcessLease): Promise<void>;
30
- markState(leaseId: string, state: AcpxProcessLeaseState): Promise<void>;
31
- };
32
-
33
- type LeaseFile = {
34
- version: 1;
35
- leases: AcpxProcessLease[];
36
- };
37
-
38
- const LEASE_FILE = "process-leases.json";
39
-
40
- function normalizeLease(value: unknown): AcpxProcessLease | undefined {
41
- if (typeof value !== "object" || value === null) {
42
- return undefined;
43
- }
44
- const record = value as Record<string, unknown>;
45
- if (
46
- typeof record.leaseId !== "string" ||
47
- typeof record.gatewayInstanceId !== "string" ||
48
- typeof record.sessionKey !== "string" ||
49
- typeof record.wrapperRoot !== "string" ||
50
- typeof record.wrapperPath !== "string" ||
51
- typeof record.rootPid !== "number" ||
52
- typeof record.commandHash !== "string" ||
53
- typeof record.startedAt !== "number" ||
54
- !["open", "closing", "closed", "lost"].includes(String(record.state))
55
- ) {
56
- return undefined;
57
- }
58
- return {
59
- leaseId: record.leaseId,
60
- gatewayInstanceId: record.gatewayInstanceId,
61
- sessionKey: record.sessionKey,
62
- wrapperRoot: record.wrapperRoot,
63
- wrapperPath: record.wrapperPath,
64
- rootPid: record.rootPid,
65
- ...(typeof record.processGroupId === "number" ? { processGroupId: record.processGroupId } : {}),
66
- commandHash: record.commandHash,
67
- startedAt: record.startedAt,
68
- state: record.state as AcpxProcessLeaseState,
69
- };
70
- }
71
-
72
- async function readLeaseFile(filePath: string): Promise<LeaseFile> {
73
- const { value } = await readJsonFileWithFallback<Partial<LeaseFile>>(filePath, {
74
- version: 1,
75
- leases: [],
76
- });
77
- const leases = Array.isArray(value.leases)
78
- ? value.leases.map(normalizeLease).filter((lease): lease is AcpxProcessLease => !!lease)
79
- : [];
80
- return { version: 1, leases };
81
- }
82
-
83
- function writeLeaseFile(filePath: string, value: LeaseFile): Promise<void> {
84
- return writeJsonFileAtomically(filePath, value);
85
- }
86
-
87
- export function createAcpxProcessLeaseStore(params: { stateDir: string }): AcpxProcessLeaseStore {
88
- const filePath = path.join(params.stateDir, LEASE_FILE);
89
- let updateQueue: Promise<void> = Promise.resolve();
90
-
91
- async function update(
92
- mutator: (leases: AcpxProcessLease[]) => AcpxProcessLease[],
93
- ): Promise<void> {
94
- const run = updateQueue.then(async () => {
95
- await fs.mkdir(params.stateDir, { recursive: true });
96
- const current = await readLeaseFile(filePath);
97
- await writeLeaseFile(filePath, {
98
- version: 1,
99
- leases: mutator(current.leases),
100
- });
101
- });
102
- updateQueue = run.catch(() => {});
103
- await run;
104
- }
105
-
106
- async function readCurrent(): Promise<LeaseFile> {
107
- await updateQueue;
108
- return await readLeaseFile(filePath);
109
- }
110
-
111
- return {
112
- async load(leaseId) {
113
- const current = await readCurrent();
114
- return current.leases.find((lease) => lease.leaseId === leaseId);
115
- },
116
- async listOpen(gatewayInstanceId) {
117
- const current = await readCurrent();
118
- return current.leases.filter(
119
- (lease) =>
120
- (lease.state === "open" || lease.state === "closing") &&
121
- (!gatewayInstanceId || lease.gatewayInstanceId === gatewayInstanceId),
122
- );
123
- },
124
- async save(lease) {
125
- await update((leases) => [
126
- ...leases.filter((entry) => entry.leaseId !== lease.leaseId),
127
- lease,
128
- ]);
129
- },
130
- async markState(leaseId, state) {
131
- await update((leases) =>
132
- leases.map((lease) => (lease.leaseId === leaseId ? { ...lease, state } : lease)),
133
- );
134
- },
135
- };
136
- }
137
-
138
- export function createAcpxProcessLeaseId(): string {
139
- return randomUUID();
140
- }
141
-
142
- export function hashAcpxProcessCommand(command: string): string {
143
- return createHash("sha256").update(command).digest("hex");
144
- }
145
-
146
- function quoteEnvValue(value: string): string {
147
- return /^[A-Za-z0-9_./:=@+-]+$/.test(value) ? value : `'${value.replace(/'/g, "'\\''")}'`;
148
- }
149
-
150
- function appendAcpxLeaseArgs(params: {
151
- command: string;
152
- leaseId: string;
153
- gatewayInstanceId: string;
154
- }): string {
155
- return [
156
- params.command,
157
- KLAW_ACPX_LEASE_ID_ARG,
158
- quoteEnvValue(params.leaseId),
159
- KLAW_GATEWAY_INSTANCE_ID_ARG,
160
- quoteEnvValue(params.gatewayInstanceId),
161
- ].join(" ");
162
- }
163
-
164
- export function withAcpxLeaseEnvironment(params: {
165
- command: string;
166
- leaseId: string;
167
- gatewayInstanceId: string;
168
- platform?: NodeJS.Platform;
169
- }): string {
170
- if ((params.platform ?? process.platform) === "win32") {
171
- return appendAcpxLeaseArgs(params);
172
- }
173
- return [
174
- "env",
175
- `${KLAW_ACPX_LEASE_ID_ENV}=${quoteEnvValue(params.leaseId)}`,
176
- `${KLAW_GATEWAY_INSTANCE_ID_ENV}=${quoteEnvValue(params.gatewayInstanceId)}`,
177
- appendAcpxLeaseArgs(params),
178
- ].join(" ");
179
- }