@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/cli.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,29 +117,21 @@ var require_companion = __commonJS({
|
|
|
118
117
|
});
|
|
119
118
|
|
|
120
119
|
// src/cli.ts
|
|
121
|
-
var
|
|
120
|
+
var import_node_path5 = __toESM(require("node:path"));
|
|
122
121
|
var import_node_process5 = __toESM(require("node:process"));
|
|
123
|
-
var
|
|
122
|
+
var import_companion7 = __toESM(require_companion());
|
|
124
123
|
|
|
125
124
|
// src/doctor.ts
|
|
126
|
-
var
|
|
127
|
-
var import_node_child_process = require("node:child_process");
|
|
125
|
+
var import_promises2 = require("node:fs/promises");
|
|
128
126
|
var import_node_events = require("node:events");
|
|
129
|
-
var
|
|
127
|
+
var import_companion4 = __toESM(require_companion());
|
|
130
128
|
|
|
131
129
|
// src/constants.ts
|
|
132
|
-
var import_node_os = __toESM(require("node:os"));
|
|
133
130
|
var import_node_path = __toESM(require("node:path"));
|
|
134
131
|
var import_companion = __toESM(require_companion());
|
|
135
|
-
var DEXLY_COMPANION_VERSION = true ? "0.1.
|
|
132
|
+
var DEXLY_COMPANION_VERSION = true ? "0.1.3" : packageJson.version;
|
|
136
133
|
var DEXLY_COMPANION_DESCRIPTION = "Dexly native bridge for Codex";
|
|
137
134
|
var DEXLY_COMPANION_METADATA_FILE_NAME = "install-metadata.json";
|
|
138
|
-
function defaultInstallRoot(homeDir = import_node_os.default.homedir()) {
|
|
139
|
-
return import_node_path.default.join(homeDir, "Library", "Application Support", "Dexly", "companion");
|
|
140
|
-
}
|
|
141
|
-
function defaultChromeHostManifestDir(homeDir = import_node_os.default.homedir()) {
|
|
142
|
-
return import_node_path.default.join(homeDir, "Library", "Application Support", "Google", "Chrome", "NativeMessagingHosts");
|
|
143
|
-
}
|
|
144
135
|
function defaultChromeAllowedOrigins() {
|
|
145
136
|
return [...import_companion.DEXLY_FIXED_ALLOWED_ORIGINS];
|
|
146
137
|
}
|
|
@@ -159,8 +150,8 @@ function versionInstallPath(installRoot, version) {
|
|
|
159
150
|
function installedHostScriptPath(installRoot) {
|
|
160
151
|
return import_node_path.default.join(currentInstallPath(installRoot), "dist", "host.js");
|
|
161
152
|
}
|
|
162
|
-
function installedHostLauncherPath(installRoot) {
|
|
163
|
-
return import_node_path.default.join(currentInstallPath(installRoot), "bin",
|
|
153
|
+
function installedHostLauncherPath(installRoot, platform = process.platform) {
|
|
154
|
+
return import_node_path.default.join(currentInstallPath(installRoot), "bin", resolveLauncherFileName(platform));
|
|
164
155
|
}
|
|
165
156
|
function versionedCliPath(versionRoot) {
|
|
166
157
|
return import_node_path.default.join(versionRoot, "dist", "cli.js");
|
|
@@ -168,15 +159,12 @@ function versionedCliPath(versionRoot) {
|
|
|
168
159
|
function versionedHostScriptPath(versionRoot) {
|
|
169
160
|
return import_node_path.default.join(versionRoot, "dist", "host.js");
|
|
170
161
|
}
|
|
171
|
-
function versionedHostLauncherPath(versionRoot) {
|
|
172
|
-
return import_node_path.default.join(versionRoot, "bin",
|
|
162
|
+
function versionedHostLauncherPath(versionRoot, platform = process.platform) {
|
|
163
|
+
return import_node_path.default.join(versionRoot, "bin", resolveLauncherFileName(platform));
|
|
173
164
|
}
|
|
174
165
|
function versionedPackageJsonPath(versionRoot) {
|
|
175
166
|
return import_node_path.default.join(versionRoot, "package.json");
|
|
176
167
|
}
|
|
177
|
-
function installedHostManifestPath(manifestDir) {
|
|
178
|
-
return import_node_path.default.join(manifestDir, `${import_companion.DEXLY_COMPANION_HOST_NAME}.json`);
|
|
179
|
-
}
|
|
180
168
|
function buildChromeHostManifest(hostPath, allowedOrigins) {
|
|
181
169
|
return {
|
|
182
170
|
name: import_companion.DEXLY_COMPANION_HOST_NAME,
|
|
@@ -186,6 +174,68 @@ function buildChromeHostManifest(hostPath, allowedOrigins) {
|
|
|
186
174
|
allowed_origins: allowedOrigins
|
|
187
175
|
};
|
|
188
176
|
}
|
|
177
|
+
function resolveLauncherFileName(platform) {
|
|
178
|
+
return platform === "win32" ? "dexly-companion-host.cmd" : "dexly-companion-host";
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// src/install-metadata.ts
|
|
182
|
+
var import_promises = require("node:fs/promises");
|
|
183
|
+
var import_companion2 = __toESM(require_companion());
|
|
184
|
+
function normalizeString(value) {
|
|
185
|
+
return typeof value === "string" && value.trim().length > 0 ? value : null;
|
|
186
|
+
}
|
|
187
|
+
function normalizeToolPaths(value) {
|
|
188
|
+
if (!value || typeof value !== "object") {
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
const candidate = value;
|
|
192
|
+
const nodePath = normalizeString(candidate.nodePath);
|
|
193
|
+
const npmPath = normalizeString(candidate.npmPath);
|
|
194
|
+
if (!nodePath || !npmPath) {
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
return {
|
|
198
|
+
nodePath,
|
|
199
|
+
npmPath,
|
|
200
|
+
codexPath: normalizeString(candidate.codexPath)
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
async function loadInstallMetadata(installRoot) {
|
|
204
|
+
try {
|
|
205
|
+
const raw = await (0, import_promises.readFile)(installMetadataPath(installRoot), "utf8");
|
|
206
|
+
const parsed = JSON.parse(raw);
|
|
207
|
+
const tools = normalizeToolPaths(parsed.tools);
|
|
208
|
+
const currentVersion = normalizeString(parsed.currentVersion);
|
|
209
|
+
const installedAt = normalizeString(parsed.installedAt);
|
|
210
|
+
const updatedAt = normalizeString(parsed.updatedAt);
|
|
211
|
+
if (!tools || !currentVersion || !installedAt || !updatedAt) {
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
const knownGoodVersions = Array.isArray(parsed.knownGoodVersions) ? parsed.knownGoodVersions.filter((value) => typeof value === "string" && value.trim().length > 0) : [currentVersion];
|
|
215
|
+
return {
|
|
216
|
+
schemaVersion: 1,
|
|
217
|
+
packageName: import_companion2.DEXLY_COMPANION_PACKAGE_NAME,
|
|
218
|
+
executableName: import_companion2.DEXLY_COMPANION_EXECUTABLE_NAME,
|
|
219
|
+
currentVersion,
|
|
220
|
+
previousVersion: normalizeString(parsed.previousVersion),
|
|
221
|
+
knownGoodVersions: knownGoodVersions.length > 0 ? knownGoodVersions : [currentVersion],
|
|
222
|
+
currentChannel: normalizeString(parsed.currentChannel),
|
|
223
|
+
installedAt,
|
|
224
|
+
updatedAt,
|
|
225
|
+
tools
|
|
226
|
+
};
|
|
227
|
+
} catch {
|
|
228
|
+
return null;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
async function saveInstallMetadata(installRoot, metadata) {
|
|
232
|
+
await (0, import_promises.writeFile)(
|
|
233
|
+
installMetadataPath(installRoot),
|
|
234
|
+
`${JSON.stringify(metadata, null, 2)}
|
|
235
|
+
`,
|
|
236
|
+
"utf8"
|
|
237
|
+
);
|
|
238
|
+
}
|
|
189
239
|
|
|
190
240
|
// src/native-protocol.ts
|
|
191
241
|
var import_node_buffer = require("node:buffer");
|
|
@@ -224,33 +274,352 @@ function writeNativeMessage(output, message) {
|
|
|
224
274
|
output.write(encodeNativeMessage(message));
|
|
225
275
|
}
|
|
226
276
|
|
|
277
|
+
// src/platform.ts
|
|
278
|
+
var import_node_os = __toESM(require("node:os"));
|
|
279
|
+
var import_node_path2 = __toESM(require("node:path"));
|
|
280
|
+
var import_node_process = __toESM(require("node:process"));
|
|
281
|
+
var import_companion3 = __toESM(require_companion());
|
|
282
|
+
function assertSupportedPlatform(platform = import_node_process.default.platform) {
|
|
283
|
+
switch (platform) {
|
|
284
|
+
case "darwin":
|
|
285
|
+
case "linux":
|
|
286
|
+
case "win32":
|
|
287
|
+
return platform;
|
|
288
|
+
default:
|
|
289
|
+
throw new Error(
|
|
290
|
+
`Dexly Companion currently supports macOS, Windows, and Linux only. Unsupported platform: ${platform}.`
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
function describePlatform(platform = import_node_process.default.platform) {
|
|
295
|
+
switch (platform) {
|
|
296
|
+
case "darwin":
|
|
297
|
+
return "macOS";
|
|
298
|
+
case "linux":
|
|
299
|
+
return "Linux";
|
|
300
|
+
case "win32":
|
|
301
|
+
return "Windows";
|
|
302
|
+
default:
|
|
303
|
+
return platform;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
function defaultChromeAllowedOrigins2() {
|
|
307
|
+
return [...import_companion3.DEXLY_FIXED_ALLOWED_ORIGINS];
|
|
308
|
+
}
|
|
309
|
+
function defaultInstallRoot(options = {}) {
|
|
310
|
+
const platform = assertSupportedPlatform(options.platform);
|
|
311
|
+
const homeDir = options.homeDir ?? import_node_os.default.homedir();
|
|
312
|
+
const env = options.env ?? import_node_process.default.env;
|
|
313
|
+
switch (platform) {
|
|
314
|
+
case "darwin":
|
|
315
|
+
return import_node_path2.default.join(homeDir, "Library", "Application Support", "Dexly", "companion");
|
|
316
|
+
case "linux": {
|
|
317
|
+
const dataHome = env.XDG_DATA_HOME?.trim() || import_node_path2.default.join(homeDir, ".local", "share");
|
|
318
|
+
return import_node_path2.default.join(dataHome, "Dexly", "companion");
|
|
319
|
+
}
|
|
320
|
+
case "win32": {
|
|
321
|
+
const localAppData = env.LOCALAPPDATA?.trim() || import_node_path2.default.join(homeDir, "AppData", "Local");
|
|
322
|
+
return import_node_path2.default.join(localAppData, "Dexly", "companion");
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
function resolveChromeHostRegistration(options = {}) {
|
|
327
|
+
const platform = assertSupportedPlatform(options.platform);
|
|
328
|
+
const homeDir = options.homeDir ?? import_node_os.default.homedir();
|
|
329
|
+
const env = options.env ?? import_node_process.default.env;
|
|
330
|
+
const installRoot = options.installRoot ?? defaultInstallRoot({
|
|
331
|
+
platform,
|
|
332
|
+
homeDir,
|
|
333
|
+
env
|
|
334
|
+
});
|
|
335
|
+
const manifestPath = options.manifestDir ? import_node_path2.default.join(options.manifestDir, `${import_companion3.DEXLY_COMPANION_HOST_NAME}.json`) : defaultChromeManifestPath({
|
|
336
|
+
platform,
|
|
337
|
+
homeDir,
|
|
338
|
+
env,
|
|
339
|
+
installRoot
|
|
340
|
+
});
|
|
341
|
+
if (platform === "win32") {
|
|
342
|
+
return {
|
|
343
|
+
kind: "windows-registry",
|
|
344
|
+
manifestPath,
|
|
345
|
+
allowedOrigins: defaultChromeAllowedOrigins2(),
|
|
346
|
+
registryKey: options.windowsRegistryKey ?? `HKCU\\Software\\Google\\Chrome\\NativeMessagingHosts\\${import_companion3.DEXLY_COMPANION_HOST_NAME}`
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
return {
|
|
350
|
+
kind: "manifest-file",
|
|
351
|
+
manifestPath,
|
|
352
|
+
allowedOrigins: defaultChromeAllowedOrigins2(),
|
|
353
|
+
registryKey: null
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
function resolvePlatformLayout(options = {}) {
|
|
357
|
+
const platform = assertSupportedPlatform(options.platform);
|
|
358
|
+
const installRoot = options.installRoot ?? defaultInstallRoot(options);
|
|
359
|
+
return {
|
|
360
|
+
platform,
|
|
361
|
+
installRoot,
|
|
362
|
+
activationStrategy: platform === "win32" ? "copy" : "symlink",
|
|
363
|
+
launcherKind: platform === "win32" ? "windows-cmd" : "posix",
|
|
364
|
+
launcherFileName: platform === "win32" ? "dexly-companion-host.cmd" : "dexly-companion-host",
|
|
365
|
+
hostRegistration: resolveChromeHostRegistration({
|
|
366
|
+
...options,
|
|
367
|
+
platform,
|
|
368
|
+
installRoot
|
|
369
|
+
})
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
function defaultLauncherPathEntries(platform = import_node_process.default.platform, env = import_node_process.default.env) {
|
|
373
|
+
switch (assertSupportedPlatform(platform)) {
|
|
374
|
+
case "darwin":
|
|
375
|
+
return ["/usr/local/bin", "/opt/homebrew/bin", "/usr/bin", "/bin", "/usr/sbin", "/sbin"];
|
|
376
|
+
case "linux":
|
|
377
|
+
return ["/usr/local/bin", "/usr/bin", "/bin", "/usr/sbin", "/sbin"];
|
|
378
|
+
case "win32": {
|
|
379
|
+
const systemRoot = env.SystemRoot?.trim() || "C:\\Windows";
|
|
380
|
+
return [import_node_path2.default.join(systemRoot, "System32"), systemRoot];
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
function renderHostLauncher(options) {
|
|
385
|
+
const platform = assertSupportedPlatform(options.platform);
|
|
386
|
+
const pathEntries = [
|
|
387
|
+
import_node_path2.default.dirname(options.nodePath),
|
|
388
|
+
options.codexPath ? import_node_path2.default.dirname(options.codexPath) : null,
|
|
389
|
+
...defaultLauncherPathEntries(platform, options.env ?? import_node_process.default.env)
|
|
390
|
+
].filter((entry, index, entries) => typeof entry === "string" && entries.indexOf(entry) === index);
|
|
391
|
+
if (platform === "win32") {
|
|
392
|
+
const lines2 = [
|
|
393
|
+
"@echo off",
|
|
394
|
+
"setlocal",
|
|
395
|
+
`set "PATH=${toBatchLiteral(pathEntries.join(import_node_path2.default.delimiter))};%PATH%"`,
|
|
396
|
+
options.codexPath ? `set "DEXLY_COMPANION_CODEX_PATH=${toBatchLiteral(options.codexPath)}"` : null,
|
|
397
|
+
`set "DEXLY_COMPANION_NODE_PATH=${toBatchLiteral(options.nodePath)}"`,
|
|
398
|
+
`set "DEXLY_COMPANION_HOST_SCRIPT=${toBatchLiteral(options.hostScriptPath)}"`,
|
|
399
|
+
'"%DEXLY_COMPANION_NODE_PATH%" "%DEXLY_COMPANION_HOST_SCRIPT%" %*'
|
|
400
|
+
].filter((line) => typeof line === "string");
|
|
401
|
+
return `${lines2.join("\r\n")}\r
|
|
402
|
+
`;
|
|
403
|
+
}
|
|
404
|
+
const lines = [
|
|
405
|
+
"#!/bin/sh",
|
|
406
|
+
"set -eu",
|
|
407
|
+
`export PATH=${toShellLiteral(pathEntries.join(import_node_path2.default.delimiter))}`,
|
|
408
|
+
options.codexPath ? `export DEXLY_COMPANION_CODEX_PATH=${toShellLiteral(options.codexPath)}` : null,
|
|
409
|
+
`exec ${toShellLiteral(options.nodePath)} ${toShellLiteral(options.hostScriptPath)} "$@"`
|
|
410
|
+
].filter((line) => typeof line === "string");
|
|
411
|
+
return `${lines.join("\n")}
|
|
412
|
+
`;
|
|
413
|
+
}
|
|
414
|
+
function defaultChromeManifestPath(options) {
|
|
415
|
+
switch (options.platform) {
|
|
416
|
+
case "darwin":
|
|
417
|
+
return import_node_path2.default.join(
|
|
418
|
+
options.homeDir,
|
|
419
|
+
"Library",
|
|
420
|
+
"Application Support",
|
|
421
|
+
"Google",
|
|
422
|
+
"Chrome",
|
|
423
|
+
"NativeMessagingHosts",
|
|
424
|
+
`${import_companion3.DEXLY_COMPANION_HOST_NAME}.json`
|
|
425
|
+
);
|
|
426
|
+
case "linux": {
|
|
427
|
+
const configHome = options.env.XDG_CONFIG_HOME?.trim() || import_node_path2.default.join(options.homeDir, ".config");
|
|
428
|
+
return import_node_path2.default.join(
|
|
429
|
+
configHome,
|
|
430
|
+
"google-chrome",
|
|
431
|
+
"NativeMessagingHosts",
|
|
432
|
+
`${import_companion3.DEXLY_COMPANION_HOST_NAME}.json`
|
|
433
|
+
);
|
|
434
|
+
}
|
|
435
|
+
case "win32":
|
|
436
|
+
return import_node_path2.default.join(options.installRoot, "native-host", `${import_companion3.DEXLY_COMPANION_HOST_NAME}.json`);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
function toShellLiteral(value) {
|
|
440
|
+
return `'${value.replace(/'/g, `'"'"'`)}'`;
|
|
441
|
+
}
|
|
442
|
+
function toBatchLiteral(value) {
|
|
443
|
+
return value.replace(/%/g, "%%").replace(/"/g, '""');
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// src/tooling.ts
|
|
447
|
+
var import_node_path3 = __toESM(require("node:path"));
|
|
448
|
+
var import_node_process2 = __toESM(require("node:process"));
|
|
449
|
+
var import_node_child_process = require("node:child_process");
|
|
450
|
+
function detectToolPaths() {
|
|
451
|
+
const nodePath = import_node_process2.default.execPath;
|
|
452
|
+
const npmPath = resolveExecutablePath("npm") ?? "npm";
|
|
453
|
+
const codexPath = resolveExecutablePath("codex");
|
|
454
|
+
return {
|
|
455
|
+
nodePath,
|
|
456
|
+
npmPath,
|
|
457
|
+
codexPath
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
function resolveExecutablePath(command, env = import_node_process2.default.env, platform = import_node_process2.default.platform) {
|
|
461
|
+
const lookupCommand = platform === "win32" ? "where" : "which";
|
|
462
|
+
const result = (0, import_node_child_process.spawnSync)(lookupCommand, [command], {
|
|
463
|
+
encoding: "utf8",
|
|
464
|
+
env
|
|
465
|
+
});
|
|
466
|
+
if (result.error || result.status !== 0) {
|
|
467
|
+
return null;
|
|
468
|
+
}
|
|
469
|
+
const executablePath = result.stdout.split(/\r?\n/).map((value) => value.trim()).find((value) => value.length > 0);
|
|
470
|
+
return executablePath ?? null;
|
|
471
|
+
}
|
|
472
|
+
function buildToolEnv(toolPaths, extraPaths = [], platform = import_node_process2.default.platform) {
|
|
473
|
+
const supportedPlatform = assertSupportedPlatform(platform);
|
|
474
|
+
const pathSeparator = supportedPlatform === "win32" ? ";" : ":";
|
|
475
|
+
const pathEntries = [
|
|
476
|
+
import_node_path3.default.dirname(toolPaths.nodePath),
|
|
477
|
+
import_node_path3.default.dirname(toolPaths.npmPath),
|
|
478
|
+
toolPaths.codexPath ? import_node_path3.default.dirname(toolPaths.codexPath) : null,
|
|
479
|
+
...extraPaths,
|
|
480
|
+
...defaultLauncherPathEntries(supportedPlatform, import_node_process2.default.env),
|
|
481
|
+
import_node_process2.default.env.PATH ?? null
|
|
482
|
+
].filter((entry, index, entries) => typeof entry === "string" && entries.indexOf(entry) === index);
|
|
483
|
+
return {
|
|
484
|
+
...import_node_process2.default.env,
|
|
485
|
+
PATH: pathEntries.join(pathSeparator),
|
|
486
|
+
...toolPaths.codexPath ? { DEXLY_COMPANION_CODEX_PATH: toolPaths.codexPath } : {}
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
async function runCommand(command, args, options = {}) {
|
|
490
|
+
return await new Promise((resolve, reject) => {
|
|
491
|
+
const child = spawnManaged(command, args, {
|
|
492
|
+
cwd: options.cwd,
|
|
493
|
+
env: options.env,
|
|
494
|
+
stdio: "pipe"
|
|
495
|
+
});
|
|
496
|
+
let stdout = "";
|
|
497
|
+
let stderr = "";
|
|
498
|
+
child.stdout.on("data", (chunk) => {
|
|
499
|
+
stdout += (Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)).toString("utf8");
|
|
500
|
+
});
|
|
501
|
+
child.stderr.on("data", (chunk) => {
|
|
502
|
+
stderr += (Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)).toString("utf8");
|
|
503
|
+
});
|
|
504
|
+
child.once("error", (error) => {
|
|
505
|
+
reject(error);
|
|
506
|
+
});
|
|
507
|
+
child.once("exit", (code, signal) => {
|
|
508
|
+
if (code === 0) {
|
|
509
|
+
resolve({ stdout, stderr });
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
const detail = stderr.trim() || stdout.trim();
|
|
513
|
+
reject(new Error(
|
|
514
|
+
detail.length > 0 ? `${command} ${args.join(" ")} failed (${code ?? signal ?? "unknown"}): ${detail}` : `${command} ${args.join(" ")} failed (${code ?? signal ?? "unknown"}).`
|
|
515
|
+
));
|
|
516
|
+
});
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
function resolveCodexVersion(codexCommand = import_node_process2.default.env.DEXLY_COMPANION_CODEX_PATH ?? "codex", env = import_node_process2.default.env) {
|
|
520
|
+
const result = spawnManagedSync(codexCommand, ["--version"], {
|
|
521
|
+
encoding: "utf8",
|
|
522
|
+
env
|
|
523
|
+
});
|
|
524
|
+
if (result.error || result.status !== 0) {
|
|
525
|
+
return null;
|
|
526
|
+
}
|
|
527
|
+
return result.stdout.trim() || null;
|
|
528
|
+
}
|
|
529
|
+
function resolveNpmGlobalBinDir(npmPath, env = import_node_process2.default.env, platform = import_node_process2.default.platform) {
|
|
530
|
+
const result = spawnManagedSync(npmPath, ["config", "get", "prefix"], {
|
|
531
|
+
encoding: "utf8",
|
|
532
|
+
env
|
|
533
|
+
});
|
|
534
|
+
if (result.error || result.status !== 0) {
|
|
535
|
+
return null;
|
|
536
|
+
}
|
|
537
|
+
const prefix = result.stdout.trim();
|
|
538
|
+
if (prefix.length === 0) {
|
|
539
|
+
return null;
|
|
540
|
+
}
|
|
541
|
+
return npmGlobalBinDirFromPrefix(prefix, platform);
|
|
542
|
+
}
|
|
543
|
+
function spawnManaged(command, args, options = {}) {
|
|
544
|
+
const invocation = buildSpawnInvocation(command, args, options.env);
|
|
545
|
+
return (0, import_node_child_process.spawn)(invocation.command, invocation.args, {
|
|
546
|
+
...options,
|
|
547
|
+
windowsVerbatimArguments: invocation.windowsVerbatimArguments
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
function spawnManagedSync(command, args, options = {}) {
|
|
551
|
+
const invocation = buildSpawnInvocation(command, args, options.env);
|
|
552
|
+
return (0, import_node_child_process.spawnSync)(invocation.command, invocation.args, {
|
|
553
|
+
...options,
|
|
554
|
+
windowsVerbatimArguments: invocation.windowsVerbatimArguments
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
function buildSpawnInvocation(command, args, env = import_node_process2.default.env, platform = import_node_process2.default.platform) {
|
|
558
|
+
if (platform !== "win32" || !isWindowsCommandScript(command, platform)) {
|
|
559
|
+
return {
|
|
560
|
+
command,
|
|
561
|
+
args
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
return {
|
|
565
|
+
command: resolveWindowsCommandShell(env),
|
|
566
|
+
args: ["/d", "/s", "/c", quoteWindowsCommand([command, ...args])],
|
|
567
|
+
windowsVerbatimArguments: false
|
|
568
|
+
};
|
|
569
|
+
}
|
|
570
|
+
function isWindowsCommandScript(command, platform = import_node_process2.default.platform) {
|
|
571
|
+
if (platform !== "win32") {
|
|
572
|
+
return false;
|
|
573
|
+
}
|
|
574
|
+
const normalized = command.trim().toLowerCase();
|
|
575
|
+
return normalized.endsWith(".cmd") || normalized.endsWith(".bat");
|
|
576
|
+
}
|
|
577
|
+
function resolveWindowsCommandShell(env = import_node_process2.default.env) {
|
|
578
|
+
const comSpec = env.ComSpec?.trim();
|
|
579
|
+
if (comSpec) {
|
|
580
|
+
return comSpec;
|
|
581
|
+
}
|
|
582
|
+
const systemRoot = env.SystemRoot?.trim() || "C:\\Windows";
|
|
583
|
+
return import_node_path3.default.join(systemRoot, "System32", "cmd.exe");
|
|
584
|
+
}
|
|
585
|
+
function quoteWindowsCommand(parts) {
|
|
586
|
+
return parts.map(quoteWindowsArgument).join(" ");
|
|
587
|
+
}
|
|
588
|
+
function quoteWindowsArgument(value) {
|
|
589
|
+
if (value.length === 0) {
|
|
590
|
+
return '""';
|
|
591
|
+
}
|
|
592
|
+
if (!/[ \t"&()^<>|]/.test(value)) {
|
|
593
|
+
return value;
|
|
594
|
+
}
|
|
595
|
+
return `"${value.replace(/"/g, '""')}"`;
|
|
596
|
+
}
|
|
597
|
+
function npmGlobalBinDirFromPrefix(prefix, platform = import_node_process2.default.platform) {
|
|
598
|
+
return platform === "win32" ? prefix : import_node_path3.default.join(prefix, "bin");
|
|
599
|
+
}
|
|
600
|
+
|
|
227
601
|
// src/doctor.ts
|
|
228
|
-
async function runDoctor(options) {
|
|
229
|
-
const
|
|
230
|
-
const
|
|
231
|
-
const manifestPath =
|
|
232
|
-
const hostLauncherPath = installedHostLauncherPath(installRoot);
|
|
602
|
+
async function runDoctor(options = {}) {
|
|
603
|
+
const layout = resolvePlatformLayout(options);
|
|
604
|
+
const installRoot = layout.installRoot;
|
|
605
|
+
const manifestPath = layout.hostRegistration.manifestPath;
|
|
606
|
+
const hostLauncherPath = installedHostLauncherPath(installRoot, layout.platform);
|
|
233
607
|
const hostScriptPath = installedHostScriptPath(installRoot);
|
|
234
608
|
const metadataPath = installMetadataPath(installRoot);
|
|
235
609
|
const checks = [];
|
|
236
610
|
checks.push({
|
|
237
611
|
label: "platform",
|
|
238
|
-
ok:
|
|
239
|
-
detail:
|
|
612
|
+
ok: true,
|
|
613
|
+
detail: `${describePlatform(layout.platform)} supported.`
|
|
240
614
|
});
|
|
615
|
+
checks.push(await checkHostRegistration(layout.hostRegistration, options.registryReader));
|
|
241
616
|
checks.push(await checkPath("host launcher", hostLauncherPath));
|
|
242
617
|
checks.push(await checkPath("host bundle", hostScriptPath));
|
|
243
618
|
checks.push(await checkPath("install metadata", metadataPath));
|
|
244
619
|
checks.push(await checkPath("native host manifest", manifestPath));
|
|
245
|
-
|
|
246
|
-
checks.push(
|
|
247
|
-
checks.push(await
|
|
248
|
-
const codexVersion = resolveCodexVersion();
|
|
249
|
-
checks.push({
|
|
250
|
-
label: "codex",
|
|
251
|
-
ok: codexVersion != null,
|
|
252
|
-
detail: codexVersion ?? "Codex CLI not found in PATH."
|
|
253
|
-
});
|
|
620
|
+
checks.push(await checkHostManifest(manifestPath, hostLauncherPath));
|
|
621
|
+
checks.push(await checkNativeHostRuntime(layout.hostRegistration, options.registryReader));
|
|
622
|
+
checks.push(await checkCodexAvailability(installRoot, layout.platform));
|
|
254
623
|
return {
|
|
255
624
|
ok: checks.every((check) => check.ok),
|
|
256
625
|
checks
|
|
@@ -258,7 +627,7 @@ async function runDoctor(options) {
|
|
|
258
627
|
}
|
|
259
628
|
async function checkPath(label, filePath) {
|
|
260
629
|
try {
|
|
261
|
-
await (0,
|
|
630
|
+
await (0, import_promises2.access)(filePath);
|
|
262
631
|
return {
|
|
263
632
|
label,
|
|
264
633
|
ok: true,
|
|
@@ -272,16 +641,39 @@ async function checkPath(label, filePath) {
|
|
|
272
641
|
};
|
|
273
642
|
}
|
|
274
643
|
}
|
|
644
|
+
async function checkHostRegistration(registration, registryReader) {
|
|
645
|
+
if (registration.kind === "manifest-file") {
|
|
646
|
+
return {
|
|
647
|
+
label: "native host registration",
|
|
648
|
+
ok: true,
|
|
649
|
+
detail: registration.manifestPath
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
const registeredManifestPath = await (registryReader ?? readWindowsRegistryManifestPath)(registration.registryKey ?? "");
|
|
653
|
+
if (!registeredManifestPath) {
|
|
654
|
+
return {
|
|
655
|
+
label: "native host registration",
|
|
656
|
+
ok: false,
|
|
657
|
+
detail: `Chrome registry key is missing or empty: ${registration.registryKey}`
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
const ok = registeredManifestPath === registration.manifestPath;
|
|
661
|
+
return {
|
|
662
|
+
label: "native host registration",
|
|
663
|
+
ok,
|
|
664
|
+
detail: ok ? `Registry points to ${registeredManifestPath}` : `Registry points to ${registeredManifestPath}, expected ${registration.manifestPath}`
|
|
665
|
+
};
|
|
666
|
+
}
|
|
275
667
|
async function checkHostManifest(filePath, expectedHostPath) {
|
|
276
668
|
try {
|
|
277
|
-
const raw = await (0,
|
|
669
|
+
const raw = await (0, import_promises2.readFile)(filePath, "utf8");
|
|
278
670
|
const manifest = JSON.parse(raw);
|
|
279
671
|
const allowedOrigins = Array.isArray(manifest.allowed_origins) ? manifest.allowed_origins.filter((value) => typeof value === "string") : [];
|
|
280
|
-
const ok = manifest.name ===
|
|
672
|
+
const ok = manifest.name === import_companion4.DEXLY_COMPANION_HOST_NAME && typeof manifest.path === "string" && manifest.path === expectedHostPath && import_companion4.DEXLY_FIXED_ALLOWED_ORIGINS.every((origin) => allowedOrigins.includes(origin));
|
|
281
673
|
return {
|
|
282
674
|
label: "manifest contents",
|
|
283
675
|
ok,
|
|
284
|
-
detail: ok ? `Native host manifest is valid, points to ${expectedHostPath}, and includes ${
|
|
676
|
+
detail: ok ? `Native host manifest is valid, points to ${expectedHostPath}, and includes ${import_companion4.DEXLY_FIXED_ALLOWED_ORIGINS.join(", ")}` : "Native host manifest is missing the expected name, expected launcher path, or one of Dexly's fixed extension origins."
|
|
285
677
|
};
|
|
286
678
|
} catch (error) {
|
|
287
679
|
return {
|
|
@@ -291,10 +683,18 @@ async function checkHostManifest(filePath, expectedHostPath) {
|
|
|
291
683
|
};
|
|
292
684
|
}
|
|
293
685
|
}
|
|
294
|
-
async function checkNativeHostRuntime(
|
|
295
|
-
const defaultOrigin = `chrome-extension://${
|
|
686
|
+
async function checkNativeHostRuntime(registration, registryReader) {
|
|
687
|
+
const defaultOrigin = `chrome-extension://${import_companion4.DEXLY_DEV_EXTENSION_ID}/`;
|
|
688
|
+
const registeredManifestPath = registration.kind === "windows-registry" ? await (registryReader ?? readWindowsRegistryManifestPath)(registration.registryKey ?? "") : registration.manifestPath;
|
|
689
|
+
if (!registeredManifestPath) {
|
|
690
|
+
return {
|
|
691
|
+
label: "native host runtime",
|
|
692
|
+
ok: false,
|
|
693
|
+
detail: "Dexly Companion could not resolve the registered native host manifest path."
|
|
694
|
+
};
|
|
695
|
+
}
|
|
296
696
|
try {
|
|
297
|
-
const raw = await (0,
|
|
697
|
+
const raw = await (0, import_promises2.readFile)(registeredManifestPath, "utf8");
|
|
298
698
|
const manifest = JSON.parse(raw);
|
|
299
699
|
if (typeof manifest.path !== "string" || manifest.path.length === 0) {
|
|
300
700
|
return {
|
|
@@ -333,8 +733,32 @@ async function checkNativeHostRuntime(manifestPath) {
|
|
|
333
733
|
};
|
|
334
734
|
}
|
|
335
735
|
}
|
|
736
|
+
async function checkCodexAvailability(installRoot, platform) {
|
|
737
|
+
const metadata = await loadInstallMetadata(installRoot);
|
|
738
|
+
const env = metadata ? buildToolEnv(metadata.tools, [], platform) : process.env;
|
|
739
|
+
const codexVersion = metadata ? resolveCodexVersion(metadata.tools.codexPath ?? void 0, env) : resolveCodexVersion(void 0, env);
|
|
740
|
+
if (codexVersion) {
|
|
741
|
+
return {
|
|
742
|
+
label: "codex",
|
|
743
|
+
ok: true,
|
|
744
|
+
detail: codexVersion
|
|
745
|
+
};
|
|
746
|
+
}
|
|
747
|
+
if (metadata?.tools.codexPath) {
|
|
748
|
+
return {
|
|
749
|
+
label: "codex",
|
|
750
|
+
ok: false,
|
|
751
|
+
detail: `Codex CLI was not available via stored install metadata (${metadata.tools.codexPath}).`
|
|
752
|
+
};
|
|
753
|
+
}
|
|
754
|
+
return {
|
|
755
|
+
label: "codex",
|
|
756
|
+
ok: false,
|
|
757
|
+
detail: "Codex CLI not found in stored install metadata or PATH."
|
|
758
|
+
};
|
|
759
|
+
}
|
|
336
760
|
async function runHostHealthCheck(hostPath, origin) {
|
|
337
|
-
const child = (
|
|
761
|
+
const child = spawnManaged(hostPath, [origin], {
|
|
338
762
|
stdio: ["pipe", "pipe", "pipe"]
|
|
339
763
|
});
|
|
340
764
|
const parser = new NativeMessageParser();
|
|
@@ -346,8 +770,8 @@ async function runHostHealthCheck(hostPath, origin) {
|
|
|
346
770
|
}, 3e3);
|
|
347
771
|
const cleanup = () => {
|
|
348
772
|
clearTimeout(timeout);
|
|
349
|
-
child.stdout
|
|
350
|
-
child.stderr
|
|
773
|
+
child.stdout?.off("data", handleStdout);
|
|
774
|
+
child.stderr?.off("data", handleStderr);
|
|
351
775
|
child.off("error", handleError);
|
|
352
776
|
child.off("exit", handleExit);
|
|
353
777
|
};
|
|
@@ -376,19 +800,19 @@ async function runHostHealthCheck(hostPath, origin) {
|
|
|
376
800
|
stderrTail ? `Dexly Companion exited before replying (code ${code ?? "null"}, signal ${signal ?? "null"}): ${stderrTail}` : `Dexly Companion exited before replying (code ${code ?? "null"}, signal ${signal ?? "null"}).`
|
|
377
801
|
));
|
|
378
802
|
};
|
|
379
|
-
child.stdout
|
|
380
|
-
child.stderr
|
|
803
|
+
child.stdout?.on("data", handleStdout);
|
|
804
|
+
child.stderr?.on("data", handleStderr);
|
|
381
805
|
child.once("error", handleError);
|
|
382
806
|
child.once("exit", handleExit);
|
|
383
807
|
});
|
|
384
|
-
child.stdin
|
|
808
|
+
child.stdin?.write(
|
|
385
809
|
encodeNativeMessage({
|
|
386
810
|
kind: "host/health",
|
|
387
811
|
requestId: "doctor-health"
|
|
388
812
|
})
|
|
389
813
|
);
|
|
390
814
|
const response = await messagePromise;
|
|
391
|
-
child.stdin
|
|
815
|
+
child.stdin?.end();
|
|
392
816
|
await Promise.race([
|
|
393
817
|
(0, import_node_events.once)(child, "exit"),
|
|
394
818
|
new Promise((resolve) => setTimeout(resolve, 250))
|
|
@@ -398,14 +822,21 @@ async function runHostHealthCheck(hostPath, origin) {
|
|
|
398
822
|
child.kill();
|
|
399
823
|
}
|
|
400
824
|
}
|
|
401
|
-
function
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
}
|
|
405
|
-
|
|
825
|
+
async function readWindowsRegistryManifestPath(registryKey) {
|
|
826
|
+
if (!registryKey.trim()) {
|
|
827
|
+
return null;
|
|
828
|
+
}
|
|
829
|
+
try {
|
|
830
|
+
const result = await runCommand("reg.exe", ["query", registryKey, "/ve"]);
|
|
831
|
+
const match = result.stdout.split(/\r?\n/).map((line) => line.trim()).find((line) => line.includes("REG_SZ"));
|
|
832
|
+
if (!match) {
|
|
833
|
+
return null;
|
|
834
|
+
}
|
|
835
|
+
const [, value] = match.split(/REG_SZ/i);
|
|
836
|
+
return value?.trim() || null;
|
|
837
|
+
} catch {
|
|
406
838
|
return null;
|
|
407
839
|
}
|
|
408
|
-
return result.stdout.trim() || null;
|
|
409
840
|
}
|
|
410
841
|
|
|
411
842
|
// src/host-runtime.ts
|
|
@@ -413,220 +844,62 @@ var import_node_process4 = __toESM(require("node:process"));
|
|
|
413
844
|
|
|
414
845
|
// src/codex-host.ts
|
|
415
846
|
var import_node_process3 = __toESM(require("node:process"));
|
|
416
|
-
var import_node_child_process3 = require("node:child_process");
|
|
417
847
|
var import_node_readline = __toESM(require("node:readline"));
|
|
418
|
-
var
|
|
848
|
+
var import_companion6 = __toESM(require_companion());
|
|
419
849
|
|
|
420
850
|
// src/management.ts
|
|
421
851
|
var import_promises4 = require("node:fs/promises");
|
|
422
|
-
var
|
|
423
|
-
|
|
424
|
-
// src/install-metadata.ts
|
|
425
|
-
var import_promises2 = require("node:fs/promises");
|
|
426
|
-
var import_companion3 = __toESM(require_companion());
|
|
427
|
-
function normalizeString(value) {
|
|
428
|
-
return typeof value === "string" && value.trim().length > 0 ? value : null;
|
|
429
|
-
}
|
|
430
|
-
function normalizeToolPaths(value) {
|
|
431
|
-
if (!value || typeof value !== "object") {
|
|
432
|
-
return null;
|
|
433
|
-
}
|
|
434
|
-
const candidate = value;
|
|
435
|
-
const nodePath = normalizeString(candidate.nodePath);
|
|
436
|
-
const npmPath = normalizeString(candidate.npmPath);
|
|
437
|
-
if (!nodePath || !npmPath) {
|
|
438
|
-
return null;
|
|
439
|
-
}
|
|
440
|
-
return {
|
|
441
|
-
nodePath,
|
|
442
|
-
npmPath,
|
|
443
|
-
codexPath: normalizeString(candidate.codexPath)
|
|
444
|
-
};
|
|
445
|
-
}
|
|
446
|
-
async function loadInstallMetadata(installRoot) {
|
|
447
|
-
try {
|
|
448
|
-
const raw = await (0, import_promises2.readFile)(installMetadataPath(installRoot), "utf8");
|
|
449
|
-
const parsed = JSON.parse(raw);
|
|
450
|
-
const tools = normalizeToolPaths(parsed.tools);
|
|
451
|
-
const currentVersion = normalizeString(parsed.currentVersion);
|
|
452
|
-
const installedAt = normalizeString(parsed.installedAt);
|
|
453
|
-
const updatedAt = normalizeString(parsed.updatedAt);
|
|
454
|
-
if (!tools || !currentVersion || !installedAt || !updatedAt) {
|
|
455
|
-
return null;
|
|
456
|
-
}
|
|
457
|
-
const knownGoodVersions = Array.isArray(parsed.knownGoodVersions) ? parsed.knownGoodVersions.filter((value) => typeof value === "string" && value.trim().length > 0) : [currentVersion];
|
|
458
|
-
return {
|
|
459
|
-
schemaVersion: 1,
|
|
460
|
-
packageName: import_companion3.DEXLY_COMPANION_PACKAGE_NAME,
|
|
461
|
-
executableName: import_companion3.DEXLY_COMPANION_EXECUTABLE_NAME,
|
|
462
|
-
currentVersion,
|
|
463
|
-
previousVersion: normalizeString(parsed.previousVersion),
|
|
464
|
-
knownGoodVersions: knownGoodVersions.length > 0 ? knownGoodVersions : [currentVersion],
|
|
465
|
-
currentChannel: normalizeString(parsed.currentChannel),
|
|
466
|
-
installedAt,
|
|
467
|
-
updatedAt,
|
|
468
|
-
tools
|
|
469
|
-
};
|
|
470
|
-
} catch {
|
|
471
|
-
return null;
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
async function saveInstallMetadata(installRoot, metadata) {
|
|
475
|
-
await (0, import_promises2.writeFile)(
|
|
476
|
-
installMetadataPath(installRoot),
|
|
477
|
-
`${JSON.stringify(metadata, null, 2)}
|
|
478
|
-
`,
|
|
479
|
-
"utf8"
|
|
480
|
-
);
|
|
481
|
-
}
|
|
852
|
+
var import_companion5 = __toESM(require_companion());
|
|
482
853
|
|
|
483
854
|
// src/install.ts
|
|
484
855
|
var import_promises3 = require("node:fs/promises");
|
|
485
|
-
var
|
|
486
|
-
var import_node_process2 = __toESM(require("node:process"));
|
|
487
|
-
|
|
488
|
-
// src/tooling.ts
|
|
489
|
-
var import_node_path2 = __toESM(require("node:path"));
|
|
490
|
-
var import_node_process = __toESM(require("node:process"));
|
|
491
|
-
var import_node_child_process2 = require("node:child_process");
|
|
492
|
-
function detectToolPaths() {
|
|
493
|
-
const nodePath = import_node_process.default.execPath;
|
|
494
|
-
const npmPath = resolveExecutablePath("npm") ?? "npm";
|
|
495
|
-
const codexPath = resolveExecutablePath("codex");
|
|
496
|
-
return {
|
|
497
|
-
nodePath,
|
|
498
|
-
npmPath,
|
|
499
|
-
codexPath
|
|
500
|
-
};
|
|
501
|
-
}
|
|
502
|
-
function resolveExecutablePath(command, env = import_node_process.default.env) {
|
|
503
|
-
const result = (0, import_node_child_process2.spawnSync)("which", [command], {
|
|
504
|
-
encoding: "utf8",
|
|
505
|
-
env
|
|
506
|
-
});
|
|
507
|
-
if (result.status !== 0) {
|
|
508
|
-
return null;
|
|
509
|
-
}
|
|
510
|
-
const executablePath = result.stdout.trim();
|
|
511
|
-
return executablePath.length > 0 ? executablePath : null;
|
|
512
|
-
}
|
|
513
|
-
function buildToolEnv(toolPaths, extraPaths = []) {
|
|
514
|
-
const pathEntries = [
|
|
515
|
-
import_node_path2.default.dirname(toolPaths.nodePath),
|
|
516
|
-
import_node_path2.default.dirname(toolPaths.npmPath),
|
|
517
|
-
toolPaths.codexPath ? import_node_path2.default.dirname(toolPaths.codexPath) : null,
|
|
518
|
-
...extraPaths,
|
|
519
|
-
"/usr/local/bin",
|
|
520
|
-
"/opt/homebrew/bin",
|
|
521
|
-
"/usr/bin",
|
|
522
|
-
"/bin",
|
|
523
|
-
"/usr/sbin",
|
|
524
|
-
"/sbin",
|
|
525
|
-
import_node_process.default.env.PATH ?? null
|
|
526
|
-
].filter((entry, index, entries) => typeof entry === "string" && entries.indexOf(entry) === index);
|
|
527
|
-
return {
|
|
528
|
-
...import_node_process.default.env,
|
|
529
|
-
PATH: pathEntries.join(":"),
|
|
530
|
-
...toolPaths.codexPath ? { DEXLY_COMPANION_CODEX_PATH: toolPaths.codexPath } : {}
|
|
531
|
-
};
|
|
532
|
-
}
|
|
533
|
-
async function runCommand(command, args, options = {}) {
|
|
534
|
-
return await new Promise((resolve, reject) => {
|
|
535
|
-
const child = (0, import_node_child_process2.spawn)(command, args, {
|
|
536
|
-
cwd: options.cwd,
|
|
537
|
-
env: options.env,
|
|
538
|
-
stdio: "pipe"
|
|
539
|
-
});
|
|
540
|
-
let stdout = "";
|
|
541
|
-
let stderr = "";
|
|
542
|
-
child.stdout.on("data", (chunk) => {
|
|
543
|
-
stdout += (Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)).toString("utf8");
|
|
544
|
-
});
|
|
545
|
-
child.stderr.on("data", (chunk) => {
|
|
546
|
-
stderr += (Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)).toString("utf8");
|
|
547
|
-
});
|
|
548
|
-
child.once("error", (error) => {
|
|
549
|
-
reject(error);
|
|
550
|
-
});
|
|
551
|
-
child.once("exit", (code, signal) => {
|
|
552
|
-
if (code === 0) {
|
|
553
|
-
resolve({ stdout, stderr });
|
|
554
|
-
return;
|
|
555
|
-
}
|
|
556
|
-
const detail = stderr.trim() || stdout.trim();
|
|
557
|
-
reject(new Error(
|
|
558
|
-
detail.length > 0 ? `${command} ${args.join(" ")} failed (${code ?? signal ?? "unknown"}): ${detail}` : `${command} ${args.join(" ")} failed (${code ?? signal ?? "unknown"}).`
|
|
559
|
-
));
|
|
560
|
-
});
|
|
561
|
-
});
|
|
562
|
-
}
|
|
563
|
-
function resolveCodexVersion2(codexCommand = import_node_process.default.env.DEXLY_COMPANION_CODEX_PATH ?? "codex", env = import_node_process.default.env) {
|
|
564
|
-
const result = (0, import_node_child_process2.spawnSync)(codexCommand, ["--version"], {
|
|
565
|
-
encoding: "utf8",
|
|
566
|
-
env
|
|
567
|
-
});
|
|
568
|
-
if (result.error || result.status !== 0) {
|
|
569
|
-
return null;
|
|
570
|
-
}
|
|
571
|
-
return result.stdout.trim() || null;
|
|
572
|
-
}
|
|
573
|
-
function resolveNpmGlobalBinDir(npmPath, env = import_node_process.default.env) {
|
|
574
|
-
const result = (0, import_node_child_process2.spawnSync)(npmPath, ["config", "get", "prefix"], {
|
|
575
|
-
encoding: "utf8",
|
|
576
|
-
env
|
|
577
|
-
});
|
|
578
|
-
if (result.error || result.status !== 0) {
|
|
579
|
-
return null;
|
|
580
|
-
}
|
|
581
|
-
const prefix = result.stdout.trim();
|
|
582
|
-
return prefix.length > 0 ? import_node_path2.default.join(prefix, "bin") : null;
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
// src/install.ts
|
|
856
|
+
var import_node_path4 = __toESM(require("node:path"));
|
|
586
857
|
async function installCompanion(options) {
|
|
587
|
-
if (import_node_process2.default.platform !== "darwin") {
|
|
588
|
-
throw new Error("Dexly Companion phase one currently supports macOS only.");
|
|
589
|
-
}
|
|
590
858
|
await assertInstallablePackageExists(options.sourcePackageDir);
|
|
591
|
-
const
|
|
592
|
-
const
|
|
593
|
-
const manifestPath =
|
|
594
|
-
const hostPath = installedHostLauncherPath(installRoot);
|
|
859
|
+
const layout = resolvePlatformLayout(options);
|
|
860
|
+
const installRoot = layout.installRoot;
|
|
861
|
+
const manifestPath = layout.hostRegistration.manifestPath;
|
|
862
|
+
const hostPath = installedHostLauncherPath(installRoot, layout.platform);
|
|
595
863
|
const allowedOrigins = defaultChromeAllowedOrigins();
|
|
596
864
|
const toolPaths = options.toolPaths ?? detectToolPaths();
|
|
597
|
-
const sourceDistDir =
|
|
598
|
-
const sourcePackageJsonPath =
|
|
865
|
+
const sourceDistDir = import_node_path4.default.join(options.sourcePackageDir, "dist");
|
|
866
|
+
const sourcePackageJsonPath = import_node_path4.default.join(options.sourcePackageDir, "package.json");
|
|
599
867
|
const installVersion = await readInstallPackageVersion(sourcePackageJsonPath);
|
|
600
868
|
const versionRoot = versionInstallPath(installRoot, installVersion);
|
|
601
869
|
const stagingVersionRoot = `${versionRoot}.tmp-${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
602
870
|
await (0, import_promises3.mkdir)(versionStorePath(installRoot), { recursive: true });
|
|
603
871
|
await (0, import_promises3.rm)(stagingVersionRoot, { recursive: true, force: true });
|
|
604
872
|
try {
|
|
605
|
-
await (0, import_promises3.mkdir)(
|
|
606
|
-
await (0, import_promises3.cp)(sourceDistDir,
|
|
873
|
+
await (0, import_promises3.mkdir)(import_node_path4.default.join(stagingVersionRoot, "dist"), { recursive: true });
|
|
874
|
+
await (0, import_promises3.cp)(sourceDistDir, import_node_path4.default.join(stagingVersionRoot, "dist"), { recursive: true });
|
|
607
875
|
await (0, import_promises3.copyFile)(sourcePackageJsonPath, versionedPackageJsonPath(stagingVersionRoot));
|
|
608
|
-
await (
|
|
609
|
-
await (
|
|
610
|
-
await (0, import_promises3.mkdir)(
|
|
876
|
+
await chmodIfSupported(layout.platform, versionedCliPath(stagingVersionRoot));
|
|
877
|
+
await chmodIfSupported(layout.platform, versionedHostScriptPath(stagingVersionRoot));
|
|
878
|
+
await (0, import_promises3.mkdir)(import_node_path4.default.dirname(versionedHostLauncherPath(stagingVersionRoot, layout.platform)), { recursive: true });
|
|
611
879
|
await (0, import_promises3.writeFile)(
|
|
612
|
-
versionedHostLauncherPath(stagingVersionRoot),
|
|
880
|
+
versionedHostLauncherPath(stagingVersionRoot, layout.platform),
|
|
613
881
|
renderHostLauncher({
|
|
882
|
+
platform: layout.platform,
|
|
614
883
|
nodePath: toolPaths.nodePath,
|
|
615
884
|
hostScriptPath: installedHostScriptPath(installRoot),
|
|
616
885
|
codexPath: toolPaths.codexPath
|
|
617
886
|
}),
|
|
618
887
|
"utf8"
|
|
619
888
|
);
|
|
620
|
-
await (
|
|
889
|
+
await chmodIfSupported(layout.platform, versionedHostLauncherPath(stagingVersionRoot, layout.platform));
|
|
621
890
|
await (0, import_promises3.rm)(versionRoot, { recursive: true, force: true });
|
|
622
891
|
await (0, import_promises3.rename)(stagingVersionRoot, versionRoot);
|
|
623
892
|
} catch (error) {
|
|
624
893
|
await (0, import_promises3.rm)(stagingVersionRoot, { recursive: true, force: true }).catch(() => void 0);
|
|
625
894
|
throw error;
|
|
626
895
|
}
|
|
627
|
-
await activateInstalledVersion(installRoot, installVersion);
|
|
628
|
-
await rewriteCurrentLauncher(installRoot, toolPaths);
|
|
629
|
-
await
|
|
896
|
+
await activateInstalledVersion(installRoot, installVersion, { platform: layout.platform });
|
|
897
|
+
await rewriteCurrentLauncher(installRoot, toolPaths, { platform: layout.platform });
|
|
898
|
+
await ensureChromeHostRegistration(installRoot, {
|
|
899
|
+
...options,
|
|
900
|
+
platform: layout.platform,
|
|
901
|
+
registryWriter: options.registryWriter
|
|
902
|
+
});
|
|
630
903
|
const existingMetadata = await loadInstallMetadata(installRoot);
|
|
631
904
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
632
905
|
const metadata = {
|
|
@@ -652,13 +925,30 @@ async function installCompanion(options) {
|
|
|
652
925
|
hostPath,
|
|
653
926
|
allowedOrigins,
|
|
654
927
|
version: installVersion,
|
|
655
|
-
metadataPath:
|
|
928
|
+
metadataPath: import_node_path4.default.join(installRoot, "install-metadata.json")
|
|
656
929
|
};
|
|
657
930
|
}
|
|
658
|
-
async function activateInstalledVersion(installRoot, version) {
|
|
931
|
+
async function activateInstalledVersion(installRoot, version, options = {}) {
|
|
932
|
+
const layout = resolvePlatformLayout({
|
|
933
|
+
installRoot,
|
|
934
|
+
platform: options.platform
|
|
935
|
+
});
|
|
659
936
|
const currentPath = currentInstallPath(installRoot);
|
|
937
|
+
const versionPath = versionInstallPath(installRoot, version);
|
|
938
|
+
if (layout.activationStrategy === "copy") {
|
|
939
|
+
const stagingCurrentPath = `${currentPath}.tmp-${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
940
|
+
await (0, import_promises3.rm)(stagingCurrentPath, { recursive: true, force: true });
|
|
941
|
+
await (0, import_promises3.cp)(versionPath, stagingCurrentPath, { recursive: true });
|
|
942
|
+
try {
|
|
943
|
+
await (0, import_promises3.rename)(stagingCurrentPath, currentPath);
|
|
944
|
+
} catch {
|
|
945
|
+
await (0, import_promises3.rm)(currentPath, { recursive: true, force: true });
|
|
946
|
+
await (0, import_promises3.rename)(stagingCurrentPath, currentPath);
|
|
947
|
+
}
|
|
948
|
+
return;
|
|
949
|
+
}
|
|
660
950
|
const tempLinkPath = `${currentPath}.tmp-${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
661
|
-
const targetPath =
|
|
951
|
+
const targetPath = import_node_path4.default.join("versions", version);
|
|
662
952
|
await (0, import_promises3.mkdir)(installRoot, { recursive: true });
|
|
663
953
|
await (0, import_promises3.rm)(tempLinkPath, { recursive: true, force: true });
|
|
664
954
|
await (0, import_promises3.symlink)(targetPath, tempLinkPath);
|
|
@@ -669,30 +959,51 @@ async function activateInstalledVersion(installRoot, version) {
|
|
|
669
959
|
await (0, import_promises3.rename)(tempLinkPath, currentPath);
|
|
670
960
|
}
|
|
671
961
|
}
|
|
672
|
-
async function rewriteCurrentLauncher(installRoot, toolPaths) {
|
|
673
|
-
const
|
|
674
|
-
|
|
962
|
+
async function rewriteCurrentLauncher(installRoot, toolPaths, options = {}) {
|
|
963
|
+
const layout = resolvePlatformLayout({
|
|
964
|
+
installRoot,
|
|
965
|
+
platform: options.platform
|
|
966
|
+
});
|
|
967
|
+
const launcherPath = installedHostLauncherPath(installRoot, layout.platform);
|
|
968
|
+
await (0, import_promises3.mkdir)(import_node_path4.default.dirname(launcherPath), { recursive: true });
|
|
675
969
|
await (0, import_promises3.writeFile)(
|
|
676
970
|
launcherPath,
|
|
677
971
|
renderHostLauncher({
|
|
972
|
+
platform: layout.platform,
|
|
678
973
|
nodePath: toolPaths.nodePath,
|
|
679
974
|
hostScriptPath: installedHostScriptPath(installRoot),
|
|
680
975
|
codexPath: toolPaths.codexPath
|
|
681
976
|
}),
|
|
682
977
|
"utf8"
|
|
683
978
|
);
|
|
684
|
-
await (
|
|
979
|
+
await chmodIfSupported(layout.platform, launcherPath);
|
|
685
980
|
return launcherPath;
|
|
686
981
|
}
|
|
687
|
-
async function
|
|
688
|
-
const
|
|
689
|
-
|
|
982
|
+
async function ensureChromeHostRegistration(installRoot, options = {}) {
|
|
983
|
+
const layout = resolvePlatformLayout({
|
|
984
|
+
installRoot,
|
|
985
|
+
platform: options.platform,
|
|
986
|
+
manifestDir: options.manifestDir,
|
|
987
|
+
windowsRegistryKey: options.windowsRegistryKey
|
|
988
|
+
});
|
|
989
|
+
const manifestPath = layout.hostRegistration.manifestPath;
|
|
990
|
+
await (0, import_promises3.mkdir)(import_node_path4.default.dirname(manifestPath), { recursive: true });
|
|
690
991
|
await (0, import_promises3.writeFile)(
|
|
691
992
|
manifestPath,
|
|
692
|
-
`${JSON.stringify(
|
|
993
|
+
`${JSON.stringify(
|
|
994
|
+
buildChromeHostManifest(installedHostLauncherPath(installRoot, layout.platform), layout.hostRegistration.allowedOrigins),
|
|
995
|
+
null,
|
|
996
|
+
2
|
|
997
|
+
)}
|
|
693
998
|
`,
|
|
694
999
|
"utf8"
|
|
695
1000
|
);
|
|
1001
|
+
if (layout.hostRegistration.kind === "windows-registry" && layout.hostRegistration.registryKey) {
|
|
1002
|
+
await (options.registryWriter ?? writeWindowsRegistryManifestPath)(
|
|
1003
|
+
layout.hostRegistration.registryKey,
|
|
1004
|
+
manifestPath
|
|
1005
|
+
);
|
|
1006
|
+
}
|
|
696
1007
|
return manifestPath;
|
|
697
1008
|
}
|
|
698
1009
|
async function pruneVersionStore(installRoot, keepVersions) {
|
|
@@ -703,14 +1014,14 @@ async function pruneVersionStore(installRoot, keepVersions) {
|
|
|
703
1014
|
if (keep.has(entry)) {
|
|
704
1015
|
return;
|
|
705
1016
|
}
|
|
706
|
-
await (0, import_promises3.rm)(
|
|
1017
|
+
await (0, import_promises3.rm)(import_node_path4.default.join(versionsPath, entry), { recursive: true, force: true });
|
|
707
1018
|
}));
|
|
708
1019
|
}
|
|
709
1020
|
async function assertInstallablePackageExists(sourcePackageDir) {
|
|
710
1021
|
const requiredPaths = [
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
1022
|
+
import_node_path4.default.join(sourcePackageDir, "dist", "cli.js"),
|
|
1023
|
+
import_node_path4.default.join(sourcePackageDir, "dist", "host.js"),
|
|
1024
|
+
import_node_path4.default.join(sourcePackageDir, "package.json")
|
|
714
1025
|
];
|
|
715
1026
|
for (const filePath of requiredPaths) {
|
|
716
1027
|
try {
|
|
@@ -729,29 +1040,23 @@ async function readInstallPackageVersion(packageJsonPath) {
|
|
|
729
1040
|
}
|
|
730
1041
|
return packageJson.version.trim();
|
|
731
1042
|
}
|
|
732
|
-
function
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
"/opt/homebrew/bin",
|
|
738
|
-
"/usr/bin",
|
|
739
|
-
"/bin",
|
|
740
|
-
"/usr/sbin",
|
|
741
|
-
"/sbin"
|
|
742
|
-
].filter((entry, index, entries) => typeof entry === "string" && entries.indexOf(entry) === index);
|
|
743
|
-
const lines = [
|
|
744
|
-
"#!/bin/sh",
|
|
745
|
-
"set -eu",
|
|
746
|
-
`export PATH=${toShellLiteral(pathEntries.join(":"))}`,
|
|
747
|
-
options.codexPath ? `export DEXLY_COMPANION_CODEX_PATH=${toShellLiteral(options.codexPath)}` : null,
|
|
748
|
-
`exec ${toShellLiteral(options.nodePath)} ${toShellLiteral(options.hostScriptPath)} "$@"`
|
|
749
|
-
].filter((line) => typeof line === "string");
|
|
750
|
-
return `${lines.join("\n")}
|
|
751
|
-
`;
|
|
1043
|
+
async function chmodIfSupported(platform, targetPath) {
|
|
1044
|
+
if (platform === "win32") {
|
|
1045
|
+
return;
|
|
1046
|
+
}
|
|
1047
|
+
await (0, import_promises3.chmod)(targetPath, 493);
|
|
752
1048
|
}
|
|
753
|
-
function
|
|
754
|
-
|
|
1049
|
+
async function writeWindowsRegistryManifestPath(registryKey, manifestPath) {
|
|
1050
|
+
await runCommand("reg.exe", [
|
|
1051
|
+
"add",
|
|
1052
|
+
registryKey,
|
|
1053
|
+
"/ve",
|
|
1054
|
+
"/t",
|
|
1055
|
+
"REG_SZ",
|
|
1056
|
+
"/d",
|
|
1057
|
+
manifestPath,
|
|
1058
|
+
"/f"
|
|
1059
|
+
]);
|
|
755
1060
|
}
|
|
756
1061
|
|
|
757
1062
|
// src/management.ts
|
|
@@ -772,19 +1077,19 @@ function nextMetadata(metadata, nextVersion, channel) {
|
|
|
772
1077
|
};
|
|
773
1078
|
}
|
|
774
1079
|
async function upgradeInstalledCompanion(options) {
|
|
775
|
-
const installRoot = options.installRoot ?? defaultInstallRoot();
|
|
1080
|
+
const installRoot = options.installRoot ?? defaultInstallRoot({ platform: options.platform });
|
|
776
1081
|
const metadata = await loadInstallMetadata(installRoot);
|
|
777
1082
|
if (!metadata) {
|
|
778
1083
|
throw new Error("Dexly Companion install metadata is missing. Reinstall Dexly Companion first.");
|
|
779
1084
|
}
|
|
780
1085
|
const specifier = options.version?.trim() ? options.version.trim() : options.distTag.trim();
|
|
781
|
-
const targetSpecifier = `${
|
|
782
|
-
const env = buildToolEnv(metadata.tools);
|
|
1086
|
+
const targetSpecifier = `${import_companion5.DEXLY_COMPANION_PACKAGE_NAME}@${specifier}`;
|
|
1087
|
+
const env = buildToolEnv(metadata.tools, [], options.platform);
|
|
783
1088
|
await runCommand(metadata.tools.npmPath, [
|
|
784
1089
|
"exec",
|
|
785
1090
|
"--yes",
|
|
786
1091
|
`--package=${targetSpecifier}`,
|
|
787
|
-
|
|
1092
|
+
import_companion5.DEXLY_COMPANION_EXECUTABLE_NAME,
|
|
788
1093
|
"install",
|
|
789
1094
|
"--channel",
|
|
790
1095
|
options.distTag
|
|
@@ -800,8 +1105,7 @@ async function upgradeInstalledCompanion(options) {
|
|
|
800
1105
|
};
|
|
801
1106
|
}
|
|
802
1107
|
async function rollbackInstalledCompanion(options) {
|
|
803
|
-
const installRoot = options?.installRoot ?? defaultInstallRoot();
|
|
804
|
-
const manifestDir = options?.manifestDir ?? defaultChromeHostManifestDir();
|
|
1108
|
+
const installRoot = options?.installRoot ?? defaultInstallRoot({ platform: options?.platform });
|
|
805
1109
|
const metadata = await loadInstallMetadata(installRoot);
|
|
806
1110
|
if (!metadata) {
|
|
807
1111
|
throw new Error("Dexly Companion install metadata is missing. Reinstall Dexly Companion first.");
|
|
@@ -811,9 +1115,13 @@ async function rollbackInstalledCompanion(options) {
|
|
|
811
1115
|
throw new Error("Dexly Companion does not have a previous known-good version to roll back to.");
|
|
812
1116
|
}
|
|
813
1117
|
await (0, import_promises4.access)(versionInstallPath(installRoot, previousVersion));
|
|
814
|
-
await activateInstalledVersion(installRoot, previousVersion);
|
|
815
|
-
await rewriteCurrentLauncher(installRoot, metadata.tools);
|
|
816
|
-
await
|
|
1118
|
+
await activateInstalledVersion(installRoot, previousVersion, { platform: options?.platform });
|
|
1119
|
+
await rewriteCurrentLauncher(installRoot, metadata.tools, { platform: options?.platform });
|
|
1120
|
+
await ensureChromeHostRegistration(installRoot, {
|
|
1121
|
+
platform: options?.platform,
|
|
1122
|
+
manifestDir: options?.manifestDir,
|
|
1123
|
+
windowsRegistryKey: options?.windowsRegistryKey
|
|
1124
|
+
});
|
|
817
1125
|
const next = nextMetadata(metadata, previousVersion, metadata.currentChannel);
|
|
818
1126
|
next.previousVersion = metadata.currentVersion;
|
|
819
1127
|
await saveInstallMetadata(installRoot, next);
|
|
@@ -823,16 +1131,15 @@ async function rollbackInstalledCompanion(options) {
|
|
|
823
1131
|
};
|
|
824
1132
|
}
|
|
825
1133
|
async function installCodexWithCompanion(options) {
|
|
826
|
-
const installRoot = options?.installRoot ?? defaultInstallRoot();
|
|
827
|
-
const manifestDir = options?.manifestDir ?? defaultChromeHostManifestDir();
|
|
1134
|
+
const installRoot = options?.installRoot ?? defaultInstallRoot({ platform: options?.platform });
|
|
828
1135
|
const existingMetadata = await loadInstallMetadata(installRoot);
|
|
829
1136
|
const toolPaths = existingMetadata?.tools ?? detectToolPaths();
|
|
830
|
-
const env = buildToolEnv(toolPaths);
|
|
1137
|
+
const env = buildToolEnv(toolPaths, [], options?.platform);
|
|
831
1138
|
await runCommand(toolPaths.npmPath, ["install", "-g", "@openai/codex"], { env });
|
|
832
|
-
const globalBinDir = resolveNpmGlobalBinDir(toolPaths.npmPath, env);
|
|
833
|
-
const nextEnv = buildToolEnv(toolPaths, globalBinDir ? [globalBinDir] : []);
|
|
834
|
-
const codexPath = resolveExecutablePath("codex", nextEnv);
|
|
835
|
-
const codexVersion =
|
|
1139
|
+
const globalBinDir = resolveNpmGlobalBinDir(toolPaths.npmPath, env, options?.platform);
|
|
1140
|
+
const nextEnv = buildToolEnv(toolPaths, globalBinDir ? [globalBinDir] : [], options?.platform);
|
|
1141
|
+
const codexPath = resolveExecutablePath("codex", nextEnv, options?.platform);
|
|
1142
|
+
const codexVersion = resolveCodexVersion(codexPath ?? void 0, nextEnv);
|
|
836
1143
|
if (!codexPath || !codexVersion) {
|
|
837
1144
|
throw new Error("Codex install completed, but Dexly Companion could not resolve the installed codex binary.");
|
|
838
1145
|
}
|
|
@@ -840,8 +1147,12 @@ async function installCodexWithCompanion(options) {
|
|
|
840
1147
|
...toolPaths,
|
|
841
1148
|
codexPath
|
|
842
1149
|
};
|
|
843
|
-
await rewriteCurrentLauncher(installRoot, nextToolPaths);
|
|
844
|
-
await
|
|
1150
|
+
await rewriteCurrentLauncher(installRoot, nextToolPaths, { platform: options?.platform });
|
|
1151
|
+
await ensureChromeHostRegistration(installRoot, {
|
|
1152
|
+
platform: options?.platform,
|
|
1153
|
+
manifestDir: options?.manifestDir,
|
|
1154
|
+
windowsRegistryKey: options?.windowsRegistryKey
|
|
1155
|
+
});
|
|
845
1156
|
if (existingMetadata) {
|
|
846
1157
|
await saveInstallMetadata(installRoot, {
|
|
847
1158
|
...existingMetadata,
|
|
@@ -852,7 +1163,7 @@ async function installCodexWithCompanion(options) {
|
|
|
852
1163
|
return {
|
|
853
1164
|
codexPath,
|
|
854
1165
|
codexVersion,
|
|
855
|
-
installCommand:
|
|
1166
|
+
installCommand: import_companion5.DEXLY_CODEX_INSTALL_COMMAND
|
|
856
1167
|
};
|
|
857
1168
|
}
|
|
858
1169
|
|
|
@@ -870,8 +1181,8 @@ var DexlyNativeHost = class {
|
|
|
870
1181
|
stderrLines = [];
|
|
871
1182
|
constructor(options) {
|
|
872
1183
|
this.send = options.send;
|
|
873
|
-
this.spawnProcess = options.spawnProcess ??
|
|
874
|
-
this.spawnProcessSync = options.spawnProcessSync ??
|
|
1184
|
+
this.spawnProcess = options.spawnProcess ?? ((command, args, spawnOptions) => spawnManaged(command, [...args], spawnOptions));
|
|
1185
|
+
this.spawnProcessSync = options.spawnProcessSync ?? ((command, args, spawnOptions) => spawnManagedSync(command, [...args], spawnOptions));
|
|
875
1186
|
this.codexCommand = options.codexCommand ?? import_node_process3.default.env.DEXLY_COMPANION_CODEX_PATH ?? "codex";
|
|
876
1187
|
this.requestProcessExit = options.requestProcessExit ?? null;
|
|
877
1188
|
}
|
|
@@ -1132,7 +1443,7 @@ var DexlyNativeHost = class {
|
|
|
1132
1443
|
null,
|
|
1133
1444
|
null,
|
|
1134
1445
|
"codex_not_connected",
|
|
1135
|
-
`${
|
|
1446
|
+
`${import_companion6.DEXLY_COMPANION_DISPLAY_NAME} is not connected to Codex app-server.`
|
|
1136
1447
|
));
|
|
1137
1448
|
return;
|
|
1138
1449
|
}
|
|
@@ -1267,7 +1578,7 @@ async function runHost() {
|
|
|
1267
1578
|
async function runInstall(args) {
|
|
1268
1579
|
const parsed = parseArgs(args);
|
|
1269
1580
|
const result = await installCompanion({
|
|
1270
|
-
sourcePackageDir:
|
|
1581
|
+
sourcePackageDir: import_node_path5.default.resolve(__dirname, ".."),
|
|
1271
1582
|
installRoot: parsed.installRoot,
|
|
1272
1583
|
manifestDir: parsed.manifestDir,
|
|
1273
1584
|
channel: parsed.channel
|
|
@@ -1295,7 +1606,7 @@ async function runDoctorCommand(args) {
|
|
|
1295
1606
|
}
|
|
1296
1607
|
if (!result.ok) {
|
|
1297
1608
|
import_node_process5.default.stdout.write(`
|
|
1298
|
-
If Dexly Companion is missing, run ${
|
|
1609
|
+
If Dexly Companion is missing, run ${import_companion7.DEXLY_COMPANION_INSTALL_COMMAND}.
|
|
1299
1610
|
`);
|
|
1300
1611
|
import_node_process5.default.exitCode = 1;
|
|
1301
1612
|
}
|