@dexlyai/dexly 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/dist/cli.js +611 -300
- package/dist/host.js +332 -111
- package/package.json +1 -1
package/dist/host.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
#!/usr/bin/env node
|
|
3
2
|
"use strict";
|
|
4
3
|
var __create = Object.create;
|
|
5
4
|
var __defProp = Object.defineProperty;
|
|
@@ -118,33 +117,22 @@ var require_companion = __commonJS({
|
|
|
118
117
|
});
|
|
119
118
|
|
|
120
119
|
// src/host.ts
|
|
121
|
-
var
|
|
120
|
+
var import_node_process5 = __toESM(require("node:process"));
|
|
122
121
|
|
|
123
122
|
// src/host-runtime.ts
|
|
124
|
-
var
|
|
123
|
+
var import_node_process4 = __toESM(require("node:process"));
|
|
125
124
|
|
|
126
125
|
// src/codex-host.ts
|
|
127
|
-
var
|
|
128
|
-
var import_node_child_process2 = require("node:child_process");
|
|
126
|
+
var import_node_process3 = __toESM(require("node:process"));
|
|
129
127
|
var import_node_readline = __toESM(require("node:readline"));
|
|
130
|
-
var
|
|
128
|
+
var import_companion5 = __toESM(require_companion());
|
|
131
129
|
|
|
132
130
|
// src/constants.ts
|
|
133
|
-
var import_node_os = __toESM(require("node:os"));
|
|
134
131
|
var import_node_path = __toESM(require("node:path"));
|
|
135
132
|
var import_companion = __toESM(require_companion());
|
|
136
|
-
var DEXLY_COMPANION_VERSION = true ? "0.1.
|
|
133
|
+
var DEXLY_COMPANION_VERSION = true ? "0.1.3" : packageJson.version;
|
|
137
134
|
var DEXLY_COMPANION_DESCRIPTION = "Dexly native bridge for Codex";
|
|
138
135
|
var DEXLY_COMPANION_METADATA_FILE_NAME = "install-metadata.json";
|
|
139
|
-
function defaultInstallRoot(homeDir = import_node_os.default.homedir()) {
|
|
140
|
-
return import_node_path.default.join(homeDir, "Library", "Application Support", "Dexly", "companion");
|
|
141
|
-
}
|
|
142
|
-
function defaultChromeHostManifestDir(homeDir = import_node_os.default.homedir()) {
|
|
143
|
-
return import_node_path.default.join(homeDir, "Library", "Application Support", "Google", "Chrome", "NativeMessagingHosts");
|
|
144
|
-
}
|
|
145
|
-
function defaultChromeAllowedOrigins() {
|
|
146
|
-
return [...import_companion.DEXLY_FIXED_ALLOWED_ORIGINS];
|
|
147
|
-
}
|
|
148
136
|
function currentInstallPath(installRoot) {
|
|
149
137
|
return import_node_path.default.join(installRoot, "current");
|
|
150
138
|
}
|
|
@@ -154,11 +142,8 @@ function installMetadataPath(installRoot) {
|
|
|
154
142
|
function installedHostScriptPath(installRoot) {
|
|
155
143
|
return import_node_path.default.join(currentInstallPath(installRoot), "dist", "host.js");
|
|
156
144
|
}
|
|
157
|
-
function installedHostLauncherPath(installRoot) {
|
|
158
|
-
return import_node_path.default.join(currentInstallPath(installRoot), "bin",
|
|
159
|
-
}
|
|
160
|
-
function installedHostManifestPath(manifestDir) {
|
|
161
|
-
return import_node_path.default.join(manifestDir, `${import_companion.DEXLY_COMPANION_HOST_NAME}.json`);
|
|
145
|
+
function installedHostLauncherPath(installRoot, platform = process.platform) {
|
|
146
|
+
return import_node_path.default.join(currentInstallPath(installRoot), "bin", resolveLauncherFileName(platform));
|
|
162
147
|
}
|
|
163
148
|
function buildChromeHostManifest(hostPath, allowedOrigins) {
|
|
164
149
|
return {
|
|
@@ -169,9 +154,12 @@ function buildChromeHostManifest(hostPath, allowedOrigins) {
|
|
|
169
154
|
allowed_origins: allowedOrigins
|
|
170
155
|
};
|
|
171
156
|
}
|
|
157
|
+
function resolveLauncherFileName(platform) {
|
|
158
|
+
return platform === "win32" ? "dexly-companion-host.cmd" : "dexly-companion-host";
|
|
159
|
+
}
|
|
172
160
|
|
|
173
161
|
// src/management.ts
|
|
174
|
-
var
|
|
162
|
+
var import_companion4 = __toESM(require_companion());
|
|
175
163
|
|
|
176
164
|
// src/install-metadata.ts
|
|
177
165
|
var import_promises = require("node:fs/promises");
|
|
@@ -234,14 +222,171 @@ async function saveInstallMetadata(installRoot, metadata) {
|
|
|
234
222
|
|
|
235
223
|
// src/install.ts
|
|
236
224
|
var import_promises2 = require("node:fs/promises");
|
|
237
|
-
var
|
|
225
|
+
var import_node_path4 = __toESM(require("node:path"));
|
|
238
226
|
|
|
239
|
-
// src/
|
|
227
|
+
// src/platform.ts
|
|
228
|
+
var import_node_os = __toESM(require("node:os"));
|
|
240
229
|
var import_node_path2 = __toESM(require("node:path"));
|
|
241
230
|
var import_node_process = __toESM(require("node:process"));
|
|
231
|
+
var import_companion3 = __toESM(require_companion());
|
|
232
|
+
function assertSupportedPlatform(platform = import_node_process.default.platform) {
|
|
233
|
+
switch (platform) {
|
|
234
|
+
case "darwin":
|
|
235
|
+
case "linux":
|
|
236
|
+
case "win32":
|
|
237
|
+
return platform;
|
|
238
|
+
default:
|
|
239
|
+
throw new Error(
|
|
240
|
+
`Dexly Companion currently supports macOS, Windows, and Linux only. Unsupported platform: ${platform}.`
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
function defaultChromeAllowedOrigins() {
|
|
245
|
+
return [...import_companion3.DEXLY_FIXED_ALLOWED_ORIGINS];
|
|
246
|
+
}
|
|
247
|
+
function defaultInstallRoot(options = {}) {
|
|
248
|
+
const platform = assertSupportedPlatform(options.platform);
|
|
249
|
+
const homeDir = options.homeDir ?? import_node_os.default.homedir();
|
|
250
|
+
const env = options.env ?? import_node_process.default.env;
|
|
251
|
+
switch (platform) {
|
|
252
|
+
case "darwin":
|
|
253
|
+
return import_node_path2.default.join(homeDir, "Library", "Application Support", "Dexly", "companion");
|
|
254
|
+
case "linux": {
|
|
255
|
+
const dataHome = env.XDG_DATA_HOME?.trim() || import_node_path2.default.join(homeDir, ".local", "share");
|
|
256
|
+
return import_node_path2.default.join(dataHome, "Dexly", "companion");
|
|
257
|
+
}
|
|
258
|
+
case "win32": {
|
|
259
|
+
const localAppData = env.LOCALAPPDATA?.trim() || import_node_path2.default.join(homeDir, "AppData", "Local");
|
|
260
|
+
return import_node_path2.default.join(localAppData, "Dexly", "companion");
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
function resolveChromeHostRegistration(options = {}) {
|
|
265
|
+
const platform = assertSupportedPlatform(options.platform);
|
|
266
|
+
const homeDir = options.homeDir ?? import_node_os.default.homedir();
|
|
267
|
+
const env = options.env ?? import_node_process.default.env;
|
|
268
|
+
const installRoot = options.installRoot ?? defaultInstallRoot({
|
|
269
|
+
platform,
|
|
270
|
+
homeDir,
|
|
271
|
+
env
|
|
272
|
+
});
|
|
273
|
+
const manifestPath = options.manifestDir ? import_node_path2.default.join(options.manifestDir, `${import_companion3.DEXLY_COMPANION_HOST_NAME}.json`) : defaultChromeManifestPath({
|
|
274
|
+
platform,
|
|
275
|
+
homeDir,
|
|
276
|
+
env,
|
|
277
|
+
installRoot
|
|
278
|
+
});
|
|
279
|
+
if (platform === "win32") {
|
|
280
|
+
return {
|
|
281
|
+
kind: "windows-registry",
|
|
282
|
+
manifestPath,
|
|
283
|
+
allowedOrigins: defaultChromeAllowedOrigins(),
|
|
284
|
+
registryKey: options.windowsRegistryKey ?? `HKCU\\Software\\Google\\Chrome\\NativeMessagingHosts\\${import_companion3.DEXLY_COMPANION_HOST_NAME}`
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
return {
|
|
288
|
+
kind: "manifest-file",
|
|
289
|
+
manifestPath,
|
|
290
|
+
allowedOrigins: defaultChromeAllowedOrigins(),
|
|
291
|
+
registryKey: null
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
function resolvePlatformLayout(options = {}) {
|
|
295
|
+
const platform = assertSupportedPlatform(options.platform);
|
|
296
|
+
const installRoot = options.installRoot ?? defaultInstallRoot(options);
|
|
297
|
+
return {
|
|
298
|
+
platform,
|
|
299
|
+
installRoot,
|
|
300
|
+
activationStrategy: platform === "win32" ? "copy" : "symlink",
|
|
301
|
+
launcherKind: platform === "win32" ? "windows-cmd" : "posix",
|
|
302
|
+
launcherFileName: platform === "win32" ? "dexly-companion-host.cmd" : "dexly-companion-host",
|
|
303
|
+
hostRegistration: resolveChromeHostRegistration({
|
|
304
|
+
...options,
|
|
305
|
+
platform,
|
|
306
|
+
installRoot
|
|
307
|
+
})
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
function defaultLauncherPathEntries(platform = import_node_process.default.platform, env = import_node_process.default.env) {
|
|
311
|
+
switch (assertSupportedPlatform(platform)) {
|
|
312
|
+
case "darwin":
|
|
313
|
+
return ["/usr/local/bin", "/opt/homebrew/bin", "/usr/bin", "/bin", "/usr/sbin", "/sbin"];
|
|
314
|
+
case "linux":
|
|
315
|
+
return ["/usr/local/bin", "/usr/bin", "/bin", "/usr/sbin", "/sbin"];
|
|
316
|
+
case "win32": {
|
|
317
|
+
const systemRoot = env.SystemRoot?.trim() || "C:\\Windows";
|
|
318
|
+
return [import_node_path2.default.join(systemRoot, "System32"), systemRoot];
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
function renderHostLauncher(options) {
|
|
323
|
+
const platform = assertSupportedPlatform(options.platform);
|
|
324
|
+
const pathEntries = [
|
|
325
|
+
import_node_path2.default.dirname(options.nodePath),
|
|
326
|
+
options.codexPath ? import_node_path2.default.dirname(options.codexPath) : null,
|
|
327
|
+
...defaultLauncherPathEntries(platform, options.env ?? import_node_process.default.env)
|
|
328
|
+
].filter((entry, index, entries) => typeof entry === "string" && entries.indexOf(entry) === index);
|
|
329
|
+
if (platform === "win32") {
|
|
330
|
+
const lines2 = [
|
|
331
|
+
"@echo off",
|
|
332
|
+
"setlocal",
|
|
333
|
+
`set "PATH=${toBatchLiteral(pathEntries.join(import_node_path2.default.delimiter))};%PATH%"`,
|
|
334
|
+
options.codexPath ? `set "DEXLY_COMPANION_CODEX_PATH=${toBatchLiteral(options.codexPath)}"` : null,
|
|
335
|
+
`set "DEXLY_COMPANION_NODE_PATH=${toBatchLiteral(options.nodePath)}"`,
|
|
336
|
+
`set "DEXLY_COMPANION_HOST_SCRIPT=${toBatchLiteral(options.hostScriptPath)}"`,
|
|
337
|
+
'"%DEXLY_COMPANION_NODE_PATH%" "%DEXLY_COMPANION_HOST_SCRIPT%" %*'
|
|
338
|
+
].filter((line) => typeof line === "string");
|
|
339
|
+
return `${lines2.join("\r\n")}\r
|
|
340
|
+
`;
|
|
341
|
+
}
|
|
342
|
+
const lines = [
|
|
343
|
+
"#!/bin/sh",
|
|
344
|
+
"set -eu",
|
|
345
|
+
`export PATH=${toShellLiteral(pathEntries.join(import_node_path2.default.delimiter))}`,
|
|
346
|
+
options.codexPath ? `export DEXLY_COMPANION_CODEX_PATH=${toShellLiteral(options.codexPath)}` : null,
|
|
347
|
+
`exec ${toShellLiteral(options.nodePath)} ${toShellLiteral(options.hostScriptPath)} "$@"`
|
|
348
|
+
].filter((line) => typeof line === "string");
|
|
349
|
+
return `${lines.join("\n")}
|
|
350
|
+
`;
|
|
351
|
+
}
|
|
352
|
+
function defaultChromeManifestPath(options) {
|
|
353
|
+
switch (options.platform) {
|
|
354
|
+
case "darwin":
|
|
355
|
+
return import_node_path2.default.join(
|
|
356
|
+
options.homeDir,
|
|
357
|
+
"Library",
|
|
358
|
+
"Application Support",
|
|
359
|
+
"Google",
|
|
360
|
+
"Chrome",
|
|
361
|
+
"NativeMessagingHosts",
|
|
362
|
+
`${import_companion3.DEXLY_COMPANION_HOST_NAME}.json`
|
|
363
|
+
);
|
|
364
|
+
case "linux": {
|
|
365
|
+
const configHome = options.env.XDG_CONFIG_HOME?.trim() || import_node_path2.default.join(options.homeDir, ".config");
|
|
366
|
+
return import_node_path2.default.join(
|
|
367
|
+
configHome,
|
|
368
|
+
"google-chrome",
|
|
369
|
+
"NativeMessagingHosts",
|
|
370
|
+
`${import_companion3.DEXLY_COMPANION_HOST_NAME}.json`
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
case "win32":
|
|
374
|
+
return import_node_path2.default.join(options.installRoot, "native-host", `${import_companion3.DEXLY_COMPANION_HOST_NAME}.json`);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
function toShellLiteral(value) {
|
|
378
|
+
return `'${value.replace(/'/g, `'"'"'`)}'`;
|
|
379
|
+
}
|
|
380
|
+
function toBatchLiteral(value) {
|
|
381
|
+
return value.replace(/%/g, "%%").replace(/"/g, '""');
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// src/tooling.ts
|
|
385
|
+
var import_node_path3 = __toESM(require("node:path"));
|
|
386
|
+
var import_node_process2 = __toESM(require("node:process"));
|
|
242
387
|
var import_node_child_process = require("node:child_process");
|
|
243
388
|
function detectToolPaths() {
|
|
244
|
-
const nodePath =
|
|
389
|
+
const nodePath = import_node_process2.default.execPath;
|
|
245
390
|
const npmPath = resolveExecutablePath("npm") ?? "npm";
|
|
246
391
|
const codexPath = resolveExecutablePath("codex");
|
|
247
392
|
return {
|
|
@@ -250,40 +395,38 @@ function detectToolPaths() {
|
|
|
250
395
|
codexPath
|
|
251
396
|
};
|
|
252
397
|
}
|
|
253
|
-
function resolveExecutablePath(command, env =
|
|
254
|
-
const
|
|
398
|
+
function resolveExecutablePath(command, env = import_node_process2.default.env, platform = import_node_process2.default.platform) {
|
|
399
|
+
const lookupCommand = platform === "win32" ? "where" : "which";
|
|
400
|
+
const result = (0, import_node_child_process.spawnSync)(lookupCommand, [command], {
|
|
255
401
|
encoding: "utf8",
|
|
256
402
|
env
|
|
257
403
|
});
|
|
258
|
-
if (result.status !== 0) {
|
|
404
|
+
if (result.error || result.status !== 0) {
|
|
259
405
|
return null;
|
|
260
406
|
}
|
|
261
|
-
const executablePath = result.stdout.trim();
|
|
262
|
-
return executablePath
|
|
407
|
+
const executablePath = result.stdout.split(/\r?\n/).map((value) => value.trim()).find((value) => value.length > 0);
|
|
408
|
+
return executablePath ?? null;
|
|
263
409
|
}
|
|
264
|
-
function buildToolEnv(toolPaths, extraPaths = []) {
|
|
410
|
+
function buildToolEnv(toolPaths, extraPaths = [], platform = import_node_process2.default.platform) {
|
|
411
|
+
const supportedPlatform = assertSupportedPlatform(platform);
|
|
412
|
+
const pathSeparator = supportedPlatform === "win32" ? ";" : ":";
|
|
265
413
|
const pathEntries = [
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
toolPaths.codexPath ?
|
|
414
|
+
import_node_path3.default.dirname(toolPaths.nodePath),
|
|
415
|
+
import_node_path3.default.dirname(toolPaths.npmPath),
|
|
416
|
+
toolPaths.codexPath ? import_node_path3.default.dirname(toolPaths.codexPath) : null,
|
|
269
417
|
...extraPaths,
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
"/usr/bin",
|
|
273
|
-
"/bin",
|
|
274
|
-
"/usr/sbin",
|
|
275
|
-
"/sbin",
|
|
276
|
-
import_node_process.default.env.PATH ?? null
|
|
418
|
+
...defaultLauncherPathEntries(supportedPlatform, import_node_process2.default.env),
|
|
419
|
+
import_node_process2.default.env.PATH ?? null
|
|
277
420
|
].filter((entry, index, entries) => typeof entry === "string" && entries.indexOf(entry) === index);
|
|
278
421
|
return {
|
|
279
|
-
...
|
|
280
|
-
PATH: pathEntries.join(
|
|
422
|
+
...import_node_process2.default.env,
|
|
423
|
+
PATH: pathEntries.join(pathSeparator),
|
|
281
424
|
...toolPaths.codexPath ? { DEXLY_COMPANION_CODEX_PATH: toolPaths.codexPath } : {}
|
|
282
425
|
};
|
|
283
426
|
}
|
|
284
427
|
async function runCommand(command, args, options = {}) {
|
|
285
428
|
return await new Promise((resolve, reject) => {
|
|
286
|
-
const child = (
|
|
429
|
+
const child = spawnManaged(command, args, {
|
|
287
430
|
cwd: options.cwd,
|
|
288
431
|
env: options.env,
|
|
289
432
|
stdio: "pipe"
|
|
@@ -311,8 +454,8 @@ async function runCommand(command, args, options = {}) {
|
|
|
311
454
|
});
|
|
312
455
|
});
|
|
313
456
|
}
|
|
314
|
-
function resolveCodexVersion(codexCommand =
|
|
315
|
-
const result = (
|
|
457
|
+
function resolveCodexVersion(codexCommand = import_node_process2.default.env.DEXLY_COMPANION_CODEX_PATH ?? "codex", env = import_node_process2.default.env) {
|
|
458
|
+
const result = spawnManagedSync(codexCommand, ["--version"], {
|
|
316
459
|
encoding: "utf8",
|
|
317
460
|
env
|
|
318
461
|
});
|
|
@@ -321,8 +464,8 @@ function resolveCodexVersion(codexCommand = import_node_process.default.env.DEXL
|
|
|
321
464
|
}
|
|
322
465
|
return result.stdout.trim() || null;
|
|
323
466
|
}
|
|
324
|
-
function resolveNpmGlobalBinDir(npmPath, env =
|
|
325
|
-
const result = (
|
|
467
|
+
function resolveNpmGlobalBinDir(npmPath, env = import_node_process2.default.env, platform = import_node_process2.default.platform) {
|
|
468
|
+
const result = spawnManagedSync(npmPath, ["config", "get", "prefix"], {
|
|
326
469
|
encoding: "utf8",
|
|
327
470
|
env
|
|
328
471
|
});
|
|
@@ -330,76 +473,151 @@ function resolveNpmGlobalBinDir(npmPath, env = import_node_process.default.env)
|
|
|
330
473
|
return null;
|
|
331
474
|
}
|
|
332
475
|
const prefix = result.stdout.trim();
|
|
333
|
-
|
|
476
|
+
if (prefix.length === 0) {
|
|
477
|
+
return null;
|
|
478
|
+
}
|
|
479
|
+
return npmGlobalBinDirFromPrefix(prefix, platform);
|
|
480
|
+
}
|
|
481
|
+
function spawnManaged(command, args, options = {}) {
|
|
482
|
+
const invocation = buildSpawnInvocation(command, args, options.env);
|
|
483
|
+
return (0, import_node_child_process.spawn)(invocation.command, invocation.args, {
|
|
484
|
+
...options,
|
|
485
|
+
windowsVerbatimArguments: invocation.windowsVerbatimArguments
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
function spawnManagedSync(command, args, options = {}) {
|
|
489
|
+
const invocation = buildSpawnInvocation(command, args, options.env);
|
|
490
|
+
return (0, import_node_child_process.spawnSync)(invocation.command, invocation.args, {
|
|
491
|
+
...options,
|
|
492
|
+
windowsVerbatimArguments: invocation.windowsVerbatimArguments
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
function buildSpawnInvocation(command, args, env = import_node_process2.default.env, platform = import_node_process2.default.platform) {
|
|
496
|
+
if (platform !== "win32" || !isWindowsCommandScript(command, platform)) {
|
|
497
|
+
return {
|
|
498
|
+
command,
|
|
499
|
+
args
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
return {
|
|
503
|
+
command: resolveWindowsCommandShell(env),
|
|
504
|
+
args: ["/d", "/s", "/c", quoteWindowsCommand([command, ...args])],
|
|
505
|
+
windowsVerbatimArguments: false
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
function isWindowsCommandScript(command, platform = import_node_process2.default.platform) {
|
|
509
|
+
if (platform !== "win32") {
|
|
510
|
+
return false;
|
|
511
|
+
}
|
|
512
|
+
const normalized = command.trim().toLowerCase();
|
|
513
|
+
return normalized.endsWith(".cmd") || normalized.endsWith(".bat");
|
|
514
|
+
}
|
|
515
|
+
function resolveWindowsCommandShell(env = import_node_process2.default.env) {
|
|
516
|
+
const comSpec = env.ComSpec?.trim();
|
|
517
|
+
if (comSpec) {
|
|
518
|
+
return comSpec;
|
|
519
|
+
}
|
|
520
|
+
const systemRoot = env.SystemRoot?.trim() || "C:\\Windows";
|
|
521
|
+
return import_node_path3.default.join(systemRoot, "System32", "cmd.exe");
|
|
522
|
+
}
|
|
523
|
+
function quoteWindowsCommand(parts) {
|
|
524
|
+
return parts.map(quoteWindowsArgument).join(" ");
|
|
525
|
+
}
|
|
526
|
+
function quoteWindowsArgument(value) {
|
|
527
|
+
if (value.length === 0) {
|
|
528
|
+
return '""';
|
|
529
|
+
}
|
|
530
|
+
if (!/[ \t"&()^<>|]/.test(value)) {
|
|
531
|
+
return value;
|
|
532
|
+
}
|
|
533
|
+
return `"${value.replace(/"/g, '""')}"`;
|
|
534
|
+
}
|
|
535
|
+
function npmGlobalBinDirFromPrefix(prefix, platform = import_node_process2.default.platform) {
|
|
536
|
+
return platform === "win32" ? prefix : import_node_path3.default.join(prefix, "bin");
|
|
334
537
|
}
|
|
335
538
|
|
|
336
539
|
// src/install.ts
|
|
337
|
-
async function rewriteCurrentLauncher(installRoot, toolPaths) {
|
|
338
|
-
const
|
|
339
|
-
|
|
540
|
+
async function rewriteCurrentLauncher(installRoot, toolPaths, options = {}) {
|
|
541
|
+
const layout = resolvePlatformLayout({
|
|
542
|
+
installRoot,
|
|
543
|
+
platform: options.platform
|
|
544
|
+
});
|
|
545
|
+
const launcherPath = installedHostLauncherPath(installRoot, layout.platform);
|
|
546
|
+
await (0, import_promises2.mkdir)(import_node_path4.default.dirname(launcherPath), { recursive: true });
|
|
340
547
|
await (0, import_promises2.writeFile)(
|
|
341
548
|
launcherPath,
|
|
342
549
|
renderHostLauncher({
|
|
550
|
+
platform: layout.platform,
|
|
343
551
|
nodePath: toolPaths.nodePath,
|
|
344
552
|
hostScriptPath: installedHostScriptPath(installRoot),
|
|
345
553
|
codexPath: toolPaths.codexPath
|
|
346
554
|
}),
|
|
347
555
|
"utf8"
|
|
348
556
|
);
|
|
349
|
-
await (
|
|
557
|
+
await chmodIfSupported(layout.platform, launcherPath);
|
|
350
558
|
return launcherPath;
|
|
351
559
|
}
|
|
352
|
-
async function
|
|
353
|
-
const
|
|
354
|
-
|
|
560
|
+
async function ensureChromeHostRegistration(installRoot, options = {}) {
|
|
561
|
+
const layout = resolvePlatformLayout({
|
|
562
|
+
installRoot,
|
|
563
|
+
platform: options.platform,
|
|
564
|
+
manifestDir: options.manifestDir,
|
|
565
|
+
windowsRegistryKey: options.windowsRegistryKey
|
|
566
|
+
});
|
|
567
|
+
const manifestPath = layout.hostRegistration.manifestPath;
|
|
568
|
+
await (0, import_promises2.mkdir)(import_node_path4.default.dirname(manifestPath), { recursive: true });
|
|
355
569
|
await (0, import_promises2.writeFile)(
|
|
356
570
|
manifestPath,
|
|
357
|
-
`${JSON.stringify(
|
|
571
|
+
`${JSON.stringify(
|
|
572
|
+
buildChromeHostManifest(installedHostLauncherPath(installRoot, layout.platform), layout.hostRegistration.allowedOrigins),
|
|
573
|
+
null,
|
|
574
|
+
2
|
|
575
|
+
)}
|
|
358
576
|
`,
|
|
359
577
|
"utf8"
|
|
360
578
|
);
|
|
579
|
+
if (layout.hostRegistration.kind === "windows-registry" && layout.hostRegistration.registryKey) {
|
|
580
|
+
await (options.registryWriter ?? writeWindowsRegistryManifestPath)(
|
|
581
|
+
layout.hostRegistration.registryKey,
|
|
582
|
+
manifestPath
|
|
583
|
+
);
|
|
584
|
+
}
|
|
361
585
|
return manifestPath;
|
|
362
586
|
}
|
|
363
|
-
function
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
"/opt/homebrew/bin",
|
|
369
|
-
"/usr/bin",
|
|
370
|
-
"/bin",
|
|
371
|
-
"/usr/sbin",
|
|
372
|
-
"/sbin"
|
|
373
|
-
].filter((entry, index, entries) => typeof entry === "string" && entries.indexOf(entry) === index);
|
|
374
|
-
const lines = [
|
|
375
|
-
"#!/bin/sh",
|
|
376
|
-
"set -eu",
|
|
377
|
-
`export PATH=${toShellLiteral(pathEntries.join(":"))}`,
|
|
378
|
-
options.codexPath ? `export DEXLY_COMPANION_CODEX_PATH=${toShellLiteral(options.codexPath)}` : null,
|
|
379
|
-
`exec ${toShellLiteral(options.nodePath)} ${toShellLiteral(options.hostScriptPath)} "$@"`
|
|
380
|
-
].filter((line) => typeof line === "string");
|
|
381
|
-
return `${lines.join("\n")}
|
|
382
|
-
`;
|
|
587
|
+
async function chmodIfSupported(platform, targetPath) {
|
|
588
|
+
if (platform === "win32") {
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
await (0, import_promises2.chmod)(targetPath, 493);
|
|
383
592
|
}
|
|
384
|
-
function
|
|
385
|
-
|
|
593
|
+
async function writeWindowsRegistryManifestPath(registryKey, manifestPath) {
|
|
594
|
+
await runCommand("reg.exe", [
|
|
595
|
+
"add",
|
|
596
|
+
registryKey,
|
|
597
|
+
"/ve",
|
|
598
|
+
"/t",
|
|
599
|
+
"REG_SZ",
|
|
600
|
+
"/d",
|
|
601
|
+
manifestPath,
|
|
602
|
+
"/f"
|
|
603
|
+
]);
|
|
386
604
|
}
|
|
387
605
|
|
|
388
606
|
// src/management.ts
|
|
389
607
|
async function upgradeInstalledCompanion(options) {
|
|
390
|
-
const installRoot = options.installRoot ?? defaultInstallRoot();
|
|
608
|
+
const installRoot = options.installRoot ?? defaultInstallRoot({ platform: options.platform });
|
|
391
609
|
const metadata = await loadInstallMetadata(installRoot);
|
|
392
610
|
if (!metadata) {
|
|
393
611
|
throw new Error("Dexly Companion install metadata is missing. Reinstall Dexly Companion first.");
|
|
394
612
|
}
|
|
395
613
|
const specifier = options.version?.trim() ? options.version.trim() : options.distTag.trim();
|
|
396
|
-
const targetSpecifier = `${
|
|
397
|
-
const env = buildToolEnv(metadata.tools);
|
|
614
|
+
const targetSpecifier = `${import_companion4.DEXLY_COMPANION_PACKAGE_NAME}@${specifier}`;
|
|
615
|
+
const env = buildToolEnv(metadata.tools, [], options.platform);
|
|
398
616
|
await runCommand(metadata.tools.npmPath, [
|
|
399
617
|
"exec",
|
|
400
618
|
"--yes",
|
|
401
619
|
`--package=${targetSpecifier}`,
|
|
402
|
-
|
|
620
|
+
import_companion4.DEXLY_COMPANION_EXECUTABLE_NAME,
|
|
403
621
|
"install",
|
|
404
622
|
"--channel",
|
|
405
623
|
options.distTag
|
|
@@ -415,15 +633,14 @@ async function upgradeInstalledCompanion(options) {
|
|
|
415
633
|
};
|
|
416
634
|
}
|
|
417
635
|
async function installCodexWithCompanion(options) {
|
|
418
|
-
const installRoot = options?.installRoot ?? defaultInstallRoot();
|
|
419
|
-
const manifestDir = options?.manifestDir ?? defaultChromeHostManifestDir();
|
|
636
|
+
const installRoot = options?.installRoot ?? defaultInstallRoot({ platform: options?.platform });
|
|
420
637
|
const existingMetadata = await loadInstallMetadata(installRoot);
|
|
421
638
|
const toolPaths = existingMetadata?.tools ?? detectToolPaths();
|
|
422
|
-
const env = buildToolEnv(toolPaths);
|
|
639
|
+
const env = buildToolEnv(toolPaths, [], options?.platform);
|
|
423
640
|
await runCommand(toolPaths.npmPath, ["install", "-g", "@openai/codex"], { env });
|
|
424
|
-
const globalBinDir = resolveNpmGlobalBinDir(toolPaths.npmPath, env);
|
|
425
|
-
const nextEnv = buildToolEnv(toolPaths, globalBinDir ? [globalBinDir] : []);
|
|
426
|
-
const codexPath = resolveExecutablePath("codex", nextEnv);
|
|
641
|
+
const globalBinDir = resolveNpmGlobalBinDir(toolPaths.npmPath, env, options?.platform);
|
|
642
|
+
const nextEnv = buildToolEnv(toolPaths, globalBinDir ? [globalBinDir] : [], options?.platform);
|
|
643
|
+
const codexPath = resolveExecutablePath("codex", nextEnv, options?.platform);
|
|
427
644
|
const codexVersion = resolveCodexVersion(codexPath ?? void 0, nextEnv);
|
|
428
645
|
if (!codexPath || !codexVersion) {
|
|
429
646
|
throw new Error("Codex install completed, but Dexly Companion could not resolve the installed codex binary.");
|
|
@@ -432,8 +649,12 @@ async function installCodexWithCompanion(options) {
|
|
|
432
649
|
...toolPaths,
|
|
433
650
|
codexPath
|
|
434
651
|
};
|
|
435
|
-
await rewriteCurrentLauncher(installRoot, nextToolPaths);
|
|
436
|
-
await
|
|
652
|
+
await rewriteCurrentLauncher(installRoot, nextToolPaths, { platform: options?.platform });
|
|
653
|
+
await ensureChromeHostRegistration(installRoot, {
|
|
654
|
+
platform: options?.platform,
|
|
655
|
+
manifestDir: options?.manifestDir,
|
|
656
|
+
windowsRegistryKey: options?.windowsRegistryKey
|
|
657
|
+
});
|
|
437
658
|
if (existingMetadata) {
|
|
438
659
|
await saveInstallMetadata(installRoot, {
|
|
439
660
|
...existingMetadata,
|
|
@@ -444,7 +665,7 @@ async function installCodexWithCompanion(options) {
|
|
|
444
665
|
return {
|
|
445
666
|
codexPath,
|
|
446
667
|
codexVersion,
|
|
447
|
-
installCommand:
|
|
668
|
+
installCommand: import_companion4.DEXLY_CODEX_INSTALL_COMMAND
|
|
448
669
|
};
|
|
449
670
|
}
|
|
450
671
|
|
|
@@ -462,9 +683,9 @@ var DexlyNativeHost = class {
|
|
|
462
683
|
stderrLines = [];
|
|
463
684
|
constructor(options) {
|
|
464
685
|
this.send = options.send;
|
|
465
|
-
this.spawnProcess = options.spawnProcess ??
|
|
466
|
-
this.spawnProcessSync = options.spawnProcessSync ??
|
|
467
|
-
this.codexCommand = options.codexCommand ??
|
|
686
|
+
this.spawnProcess = options.spawnProcess ?? ((command, args, spawnOptions) => spawnManaged(command, [...args], spawnOptions));
|
|
687
|
+
this.spawnProcessSync = options.spawnProcessSync ?? ((command, args, spawnOptions) => spawnManagedSync(command, [...args], spawnOptions));
|
|
688
|
+
this.codexCommand = options.codexCommand ?? import_node_process3.default.env.DEXLY_COMPANION_CODEX_PATH ?? "codex";
|
|
468
689
|
this.requestProcessExit = options.requestProcessExit ?? null;
|
|
469
690
|
}
|
|
470
691
|
async handleMessage(message) {
|
|
@@ -724,7 +945,7 @@ var DexlyNativeHost = class {
|
|
|
724
945
|
null,
|
|
725
946
|
null,
|
|
726
947
|
"codex_not_connected",
|
|
727
|
-
`${
|
|
948
|
+
`${import_companion5.DEXLY_COMPANION_DISPLAY_NAME} is not connected to Codex app-server.`
|
|
728
949
|
));
|
|
729
950
|
return;
|
|
730
951
|
}
|
|
@@ -814,19 +1035,19 @@ function writeNativeMessage(output, message) {
|
|
|
814
1035
|
// src/host-runtime.ts
|
|
815
1036
|
async function runNativeHost() {
|
|
816
1037
|
const host = new DexlyNativeHost({
|
|
817
|
-
send: (message) => writeNativeMessage(
|
|
1038
|
+
send: (message) => writeNativeMessage(import_node_process4.default.stdout, message),
|
|
818
1039
|
requestProcessExit: () => {
|
|
819
|
-
setTimeout(() =>
|
|
1040
|
+
setTimeout(() => import_node_process4.default.exit(0), 25);
|
|
820
1041
|
}
|
|
821
1042
|
});
|
|
822
|
-
|
|
1043
|
+
import_node_process4.default.stdout.on("error", (error) => {
|
|
823
1044
|
if ("code" in error && error.code === "EPIPE") {
|
|
824
|
-
void host.close().finally(() =>
|
|
1045
|
+
void host.close().finally(() => import_node_process4.default.exit(0));
|
|
825
1046
|
}
|
|
826
1047
|
});
|
|
827
|
-
const detachReader = createNativeMessageReader(
|
|
1048
|
+
const detachReader = createNativeMessageReader(import_node_process4.default.stdin, (message) => {
|
|
828
1049
|
void host.handleMessage(message).catch((error) => {
|
|
829
|
-
writeNativeMessage(
|
|
1050
|
+
writeNativeMessage(import_node_process4.default.stdout, {
|
|
830
1051
|
kind: "host/error",
|
|
831
1052
|
action: null,
|
|
832
1053
|
requestId: null,
|
|
@@ -839,21 +1060,21 @@ async function runNativeHost() {
|
|
|
839
1060
|
detachReader();
|
|
840
1061
|
await host.close();
|
|
841
1062
|
};
|
|
842
|
-
|
|
843
|
-
void shutdown().finally(() =>
|
|
1063
|
+
import_node_process4.default.stdin.on("end", () => {
|
|
1064
|
+
void shutdown().finally(() => import_node_process4.default.exit(0));
|
|
844
1065
|
});
|
|
845
|
-
|
|
846
|
-
void shutdown().finally(() =>
|
|
1066
|
+
import_node_process4.default.on("SIGINT", () => {
|
|
1067
|
+
void shutdown().finally(() => import_node_process4.default.exit(0));
|
|
847
1068
|
});
|
|
848
|
-
|
|
849
|
-
void shutdown().finally(() =>
|
|
1069
|
+
import_node_process4.default.on("SIGTERM", () => {
|
|
1070
|
+
void shutdown().finally(() => import_node_process4.default.exit(0));
|
|
850
1071
|
});
|
|
851
1072
|
}
|
|
852
1073
|
|
|
853
1074
|
// src/host.ts
|
|
854
1075
|
void runNativeHost().catch((error) => {
|
|
855
1076
|
const message = error instanceof Error ? error.message : "Dexly Companion host failed.";
|
|
856
|
-
|
|
1077
|
+
import_node_process5.default.stderr.write(`${message}
|
|
857
1078
|
`);
|
|
858
|
-
|
|
1079
|
+
import_node_process5.default.exit(1);
|
|
859
1080
|
});
|