@solar_orb/agent_orb 0.1.0 → 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 +10 -2
- package/dist/adapter.js +2 -0
- package/dist/config.js +1 -1
- package/dist/download.js +68 -5
- package/dist/index.js +12 -1
- package/dist/setup.js +123 -19
- package/dist/shell.js +16 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,7 +23,15 @@ npm --prefix packages/agent_orb run package-runtime
|
|
|
23
23
|
npx --yes ./packages/agent_orb setup --yes
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
If `packages/agent_orb/releases` contains a matching native bundle, setup installs that bundle directly with SHA256 verification. Otherwise it falls back to source build.
|
|
26
|
+
If `packages/agent_orb/releases` contains a matching native bundle, setup installs that bundle directly with SHA256 verification. Otherwise it falls back to source build. On Windows, setup also adds the runtime bin directory to the user PATH so a new terminal can run `agent_orb-codex`, `agent_orb-claude`, `agent_orb`, `codex-orb`, and `claude-orb` directly. The adapter launchers start the orb UI if needed before running the target CLI.
|
|
27
|
+
|
|
28
|
+
Upgrade or repair an existing install:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx @solar_orb/agent_orb upgrade --yes
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The upgrade flow verifies the new bundle before stopping the old daemon/orb UI and removing old runtime files.
|
|
27
35
|
|
|
28
36
|
## Windows local path
|
|
29
37
|
|
|
@@ -55,5 +63,5 @@ For Windows-host testing, prefer either:
|
|
|
55
63
|
|
|
56
64
|
```powershell
|
|
57
65
|
cd $env:TEMP\agent-orb-npx
|
|
58
|
-
npx --yes .\agent_orb-0.1.
|
|
66
|
+
npx --yes .\solar_orb-agent_orb-0.1.3.tgz --help
|
|
59
67
|
```
|
package/dist/adapter.js
CHANGED
|
@@ -5,6 +5,7 @@ export const adapters = [
|
|
|
5
5
|
displayName: 'Codex CLI',
|
|
6
6
|
binaryCandidates: process.platform === 'win32' ? ['codex.exe', 'codex'] : ['codex'],
|
|
7
7
|
wrapperCommand: process.platform === 'win32' ? 'codex-orb.cmd' : 'codex-orb',
|
|
8
|
+
launcherCommand: process.platform === 'win32' ? 'agent_orb-codex.cmd' : 'agent_orb-codex',
|
|
8
9
|
promptPatterns: ['approve', 'permission', 'continue?', 'yes/no'],
|
|
9
10
|
},
|
|
10
11
|
{
|
|
@@ -12,6 +13,7 @@ export const adapters = [
|
|
|
12
13
|
displayName: 'Claude Code CLI',
|
|
13
14
|
binaryCandidates: process.platform === 'win32' ? ['claude.exe', 'claude'] : ['claude'],
|
|
14
15
|
wrapperCommand: process.platform === 'win32' ? 'claude-orb.cmd' : 'claude-orb',
|
|
16
|
+
launcherCommand: process.platform === 'win32' ? 'agent_orb-claude.cmd' : 'agent_orb-claude',
|
|
15
17
|
promptPatterns: ['continue?', 'permission', 'press enter', 'approve'],
|
|
16
18
|
},
|
|
17
19
|
];
|
package/dist/config.js
CHANGED
|
@@ -14,7 +14,7 @@ export function writeConfig(configDir, selectedAdapters, runtime = runtimeConfig
|
|
|
14
14
|
fs.mkdirSync(configDir, { recursive: true });
|
|
15
15
|
const configPath = path.join(configDir, 'config.toml');
|
|
16
16
|
const enabled = new Set(selectedAdapters.map((adapter) => adapter.name));
|
|
17
|
-
const content = `# Generated by npx agent_orb\n\n[install]\nmethod = "npx"\nversion = "0.1.
|
|
17
|
+
const content = `# Generated by npx agent_orb\n\n[install]\nmethod = "npx"\nversion = "0.1.3"\n\n[adapters.codex]\nenabled = ${enabled.has('codex')}\nbinary = "codex"\nwrapper = "agent_orb-codex"\n\n[adapters.claude]\nenabled = ${enabled.has('claude')}\nbinary = "claude"\nwrapper = "agent_orb-claude"\n\n[daemon]\nhost = "${runtime.daemonHost}"\nport = ${runtime.daemonPort}\nauto_start = true\n\n[orb]\nposition = "top-right"\nsize = 36\nopacity = 0.88\nalways_on_top = true\nclick_through = false\n\n[colors]\ndisconnected = "#6B7280"\nidle = "#9CA3AF"\nstarting = "#60A5FA"\nactive = "#3B82F6"\nthinking_like = "#8B5CF6"\nwaiting_input = "#FBBF24"\ncompleted = "#22C55E"\nerror = "#EF4444"\nwarning = "#F97316"\n\n[behavior]\nsilent_threshold_seconds = 20\nstuck_threshold_seconds = 180\ncompleted_hold_seconds = 10\nerror_requires_click_to_clear = true\n\n[privacy]\ninclude_output_sample = false\nmax_sample_chars = 512\n`;
|
|
18
18
|
fs.writeFileSync(configPath, content, 'utf8');
|
|
19
19
|
return configPath;
|
|
20
20
|
}
|
package/dist/download.js
CHANGED
|
@@ -3,7 +3,7 @@ import os from 'node:os';
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
5
5
|
import { parseChecksums, verifyChecksum } from './checksum.js';
|
|
6
|
-
import { run } from './shell.js';
|
|
6
|
+
import { commandExists, run } from './shell.js';
|
|
7
7
|
export async function installRuntimeBundle(platform, options = {}) {
|
|
8
8
|
if (!options.force && runtimeLooksInstalled(platform)) {
|
|
9
9
|
console.log('\n==> Runtime bundle');
|
|
@@ -28,6 +28,7 @@ export async function installRuntimeBundle(platform, options = {}) {
|
|
|
28
28
|
}
|
|
29
29
|
verifyChecksum(bundlePath, expected);
|
|
30
30
|
console.log(`✓ checksum verified: ${platform.bundleName}`);
|
|
31
|
+
cleanupInstalledRuntime(platform);
|
|
31
32
|
extractBundle(bundlePath, tempDir, platform);
|
|
32
33
|
writeInstallManifest(platform, {
|
|
33
34
|
bundle: platform.bundleName,
|
|
@@ -45,6 +46,55 @@ export function runtimeLooksInstalled(platform) {
|
|
|
45
46
|
const required = ['agent_orb', 'agent_orbd'].map((name) => path.join(platform.runtimeDir, `${name}${platform.exeSuffix}`));
|
|
46
47
|
return required.every((file) => fs.existsSync(file));
|
|
47
48
|
}
|
|
49
|
+
export function cleanupInstalledRuntime(platform) {
|
|
50
|
+
if (!fs.existsSync(platform.runtimeDir))
|
|
51
|
+
return;
|
|
52
|
+
console.log('\n==> Cleaning previous runtime files');
|
|
53
|
+
stopRuntimeProcesses(platform);
|
|
54
|
+
for (const filename of knownRuntimeFiles(platform)) {
|
|
55
|
+
const filePath = path.join(platform.runtimeDir, filename);
|
|
56
|
+
if (!fs.existsSync(filePath))
|
|
57
|
+
continue;
|
|
58
|
+
fs.rmSync(filePath, { force: true });
|
|
59
|
+
console.log(`✓ removed ${filePath}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function stopRuntimeProcesses(platform) {
|
|
63
|
+
if (platform.platform === 'windows') {
|
|
64
|
+
for (const imageName of ['agent_orbd.exe', 'agent-orb-ui.exe']) {
|
|
65
|
+
run('taskkill', ['/F', '/T', '/IM', imageName], {
|
|
66
|
+
allowFailure: true,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (!commandExists('pkill'))
|
|
72
|
+
return;
|
|
73
|
+
for (const processName of ['agent_orbd', 'agent-orb-ui']) {
|
|
74
|
+
run('pkill', ['-x', processName], {
|
|
75
|
+
allowFailure: true,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function knownRuntimeFiles(platform) {
|
|
80
|
+
const executableNames = [
|
|
81
|
+
`agent_orb${platform.exeSuffix}`,
|
|
82
|
+
`agent_orbd${platform.exeSuffix}`,
|
|
83
|
+
`agent-orb-ui${platform.exeSuffix}`,
|
|
84
|
+
];
|
|
85
|
+
return [
|
|
86
|
+
...executableNames,
|
|
87
|
+
'agent-orb-runtime.json',
|
|
88
|
+
'agent_orb-codex',
|
|
89
|
+
'agent_orb-claude',
|
|
90
|
+
'codex-orb',
|
|
91
|
+
'claude-orb',
|
|
92
|
+
'agent_orb-codex.cmd',
|
|
93
|
+
'agent_orb-claude.cmd',
|
|
94
|
+
'codex-orb.cmd',
|
|
95
|
+
'claude-orb.cmd',
|
|
96
|
+
];
|
|
97
|
+
}
|
|
48
98
|
function releaseBaseUrl(platform, options) {
|
|
49
99
|
if (options.releaseDir) {
|
|
50
100
|
return pathToFileURL(path.resolve(options.releaseDir)).href;
|
|
@@ -61,12 +111,18 @@ function releaseBaseUrl(platform, options) {
|
|
|
61
111
|
const bundled = bundledReleaseBaseUrl(platform);
|
|
62
112
|
if (bundled)
|
|
63
113
|
return bundled;
|
|
64
|
-
const version = process.env.AGENT_ORB_VERSION ?? 'v0.1.0';
|
|
114
|
+
const version = process.env.AGENT_ORB_VERSION ?? defaultReleaseVersion() ?? 'v0.1.0';
|
|
65
115
|
const repo = githubRepository();
|
|
66
116
|
if (repo)
|
|
67
117
|
return `https://github.com/${repo}/releases/download/${version}`;
|
|
68
118
|
return undefined;
|
|
69
119
|
}
|
|
120
|
+
function defaultReleaseVersion() {
|
|
121
|
+
const version = readPackageVersion();
|
|
122
|
+
if (!version)
|
|
123
|
+
return undefined;
|
|
124
|
+
return version.startsWith('v') ? version : `v${version}`;
|
|
125
|
+
}
|
|
70
126
|
function githubRepository() {
|
|
71
127
|
const configured = process.env.AGENT_ORB_GITHUB_REPOSITORY;
|
|
72
128
|
if (configured?.trim())
|
|
@@ -80,11 +136,18 @@ function githubRepository() {
|
|
|
80
136
|
return undefined;
|
|
81
137
|
}
|
|
82
138
|
function readPackageGithubRepository() {
|
|
139
|
+
const packageJson = readPackageJson();
|
|
140
|
+
const repo = packageJson?.config?.github_repository;
|
|
141
|
+
return typeof repo === 'string' && repo.trim() ? repo.trim() : undefined;
|
|
142
|
+
}
|
|
143
|
+
function readPackageVersion() {
|
|
144
|
+
const version = readPackageJson()?.version;
|
|
145
|
+
return typeof version === 'string' && version.trim() ? version.trim() : undefined;
|
|
146
|
+
}
|
|
147
|
+
function readPackageJson() {
|
|
83
148
|
try {
|
|
84
149
|
const packageJsonPath = fileURLToPath(new URL('../package.json', import.meta.url));
|
|
85
|
-
|
|
86
|
-
const repo = packageJson.config?.github_repository;
|
|
87
|
-
return typeof repo === 'string' && repo.trim() ? repo.trim() : undefined;
|
|
150
|
+
return JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
88
151
|
}
|
|
89
152
|
catch {
|
|
90
153
|
return undefined;
|
package/dist/index.js
CHANGED
|
@@ -21,10 +21,20 @@ async function main() {
|
|
|
21
21
|
case 'doctor':
|
|
22
22
|
await doctor();
|
|
23
23
|
break;
|
|
24
|
+
case 'upgrade':
|
|
25
|
+
await setup({
|
|
26
|
+
yes: flags.has('--yes') || flags.has('-y'),
|
|
27
|
+
smoke: !flags.has('--no-smoke'),
|
|
28
|
+
force: true,
|
|
29
|
+
buildFromSource: flags.has('--build-from-source'),
|
|
30
|
+
releaseBaseUrl: flagValue(args, '--release-base-url'),
|
|
31
|
+
releaseDir: flagValue(args, '--release-dir'),
|
|
32
|
+
});
|
|
33
|
+
break;
|
|
24
34
|
case 'version':
|
|
25
35
|
case '--version':
|
|
26
36
|
case '-v':
|
|
27
|
-
console.log('agent_orb bootstrapper 0.1.
|
|
37
|
+
console.log('agent_orb bootstrapper 0.1.3');
|
|
28
38
|
break;
|
|
29
39
|
case 'help':
|
|
30
40
|
case '--help':
|
|
@@ -65,6 +75,7 @@ Usage:
|
|
|
65
75
|
[--release-dir <dir> | --release-base-url <url>]
|
|
66
76
|
[--build-from-source]
|
|
67
77
|
agent_orb doctor
|
|
78
|
+
agent_orb upgrade [--yes] [--no-smoke]
|
|
68
79
|
agent_orb version
|
|
69
80
|
|
|
70
81
|
Local development:
|
package/dist/setup.js
CHANGED
|
@@ -5,9 +5,9 @@ import { stdin as input, stdout as output } from 'node:process';
|
|
|
5
5
|
import { fileURLToPath } from 'node:url';
|
|
6
6
|
import { detectAdapters } from './adapter.js';
|
|
7
7
|
import { runtimeConfigFromEnv, writeConfig } from './config.js';
|
|
8
|
-
import { installRuntimeBundle } from './download.js';
|
|
8
|
+
import { cleanupInstalledRuntime, installRuntimeBundle } from './download.js';
|
|
9
9
|
import { detectPlatform } from './platform.js';
|
|
10
|
-
import { commandExists, run, spawnDetached } from './shell.js';
|
|
10
|
+
import { commandExists, getPathEnv, run, setPathEnv, spawnDetached } from './shell.js';
|
|
11
11
|
export async function setup(options = {}) {
|
|
12
12
|
const platform = detectPlatform();
|
|
13
13
|
const runtime = runtimeConfigFromEnv();
|
|
@@ -39,17 +39,24 @@ export async function setup(options = {}) {
|
|
|
39
39
|
}
|
|
40
40
|
const configPath = writeConfig(platform.configDir, selectedAdapters, runtime);
|
|
41
41
|
createAdapterShims(platform, selectedAdapters);
|
|
42
|
-
|
|
42
|
+
ensurePathConfigured(platform);
|
|
43
43
|
await ensureDaemon(platform, runtime);
|
|
44
|
+
const orbStarted = startOrbUiIfAvailable(platform);
|
|
44
45
|
if (options.smoke ?? true) {
|
|
45
46
|
smokeTest(platform);
|
|
46
47
|
}
|
|
47
48
|
console.log('\n✓ Agent Orb setup complete');
|
|
48
49
|
console.log(`Config: ${configPath}`);
|
|
49
|
-
console.log(`Try:
|
|
50
|
+
console.log(`Try: agent_orb run -- ${platform.platform === 'windows' ? 'cmd /C echo hello' : 'echo hello'}`);
|
|
51
|
+
if (selectedAdapters.some((adapter) => adapter.name === 'codex')) {
|
|
52
|
+
console.log('Codex: agent_orb-codex');
|
|
53
|
+
}
|
|
54
|
+
if (selectedAdapters.some((adapter) => adapter.name === 'claude')) {
|
|
55
|
+
console.log('Claude: agent_orb-claude');
|
|
56
|
+
}
|
|
50
57
|
const orb = runtimeExe(platform, 'agent-orb-ui');
|
|
51
58
|
if (fs.existsSync(orb)) {
|
|
52
|
-
console.log(`Orb: ${orb}`);
|
|
59
|
+
console.log(`Orb: ${orbStarted ? 'started' : orb}`);
|
|
53
60
|
}
|
|
54
61
|
}
|
|
55
62
|
function installRuntimeFromSource(platform) {
|
|
@@ -58,6 +65,7 @@ function installRuntimeFromSource(platform) {
|
|
|
58
65
|
const repoRoot = findRepoRoot();
|
|
59
66
|
console.log(`Repository: ${repoRoot}`);
|
|
60
67
|
buildRuntime(repoRoot);
|
|
68
|
+
cleanupInstalledRuntime(platform);
|
|
61
69
|
installRuntime(repoRoot, platform);
|
|
62
70
|
}
|
|
63
71
|
export async function doctor(platform = detectPlatform(), runtime = runtimeConfigFromEnv()) {
|
|
@@ -188,32 +196,128 @@ function createAdapterShims(platform, adapters) {
|
|
|
188
196
|
return;
|
|
189
197
|
console.log('\n==> Creating adapter shims');
|
|
190
198
|
for (const adapter of adapters) {
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
const
|
|
194
|
-
|
|
199
|
+
const commands = uniqueStrings([adapter.launcherCommand, adapter.wrapperCommand]);
|
|
200
|
+
for (const command of commands) {
|
|
201
|
+
const shimPath = path.join(platform.runtimeDir, command);
|
|
202
|
+
if (platform.platform === 'windows') {
|
|
203
|
+
fs.writeFileSync(shimPath, windowsAdapterShim(adapter.name), 'ascii');
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
fs.writeFileSync(shimPath, unixAdapterShim(adapter.name), 'utf8');
|
|
207
|
+
fs.chmodSync(shimPath, 0o755);
|
|
208
|
+
}
|
|
209
|
+
console.log(`✓ ${shimPath}`);
|
|
195
210
|
}
|
|
196
|
-
else {
|
|
197
|
-
fs.writeFileSync(shimPath, `#!/usr/bin/env sh\n"$(dirname "$0")/agent_orb" run -- ${adapter.name} "$@"\n`, 'utf8');
|
|
198
|
-
fs.chmodSync(shimPath, 0o755);
|
|
199
|
-
}
|
|
200
|
-
console.log(`✓ ${shimPath}`);
|
|
201
211
|
}
|
|
202
212
|
}
|
|
203
|
-
function
|
|
204
|
-
|
|
213
|
+
function uniqueStrings(values) {
|
|
214
|
+
return [...new Set(values)];
|
|
215
|
+
}
|
|
216
|
+
function windowsAdapterShim(adapterName) {
|
|
217
|
+
return `@echo off\r\nsetlocal\r\nset "ORB_UI=%~dp0agent-orb-ui.exe"\r\nif exist "%ORB_UI%" (\r\n tasklist /FI "IMAGENAME eq agent-orb-ui.exe" 2>NUL | find /I "agent-orb-ui.exe" >NUL\r\n if errorlevel 1 start "" "%ORB_UI%"\r\n)\r\n"%~dp0agent_orb.exe" run -- ${adapterName} %*\r\nexit /b %ERRORLEVEL%\r\n`;
|
|
218
|
+
}
|
|
219
|
+
function unixAdapterShim(adapterName) {
|
|
220
|
+
return `#!/usr/bin/env sh\nset -eu\nDIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)\nORB_UI="$DIR/agent-orb-ui"\nif [ -x "$ORB_UI" ] && { [ -n "\${DISPLAY:-}" ] || [ -n "\${WAYLAND_DISPLAY:-}" ]; }; then\n running=0\n if command -v pgrep >/dev/null 2>&1 && pgrep -x agent-orb-ui >/dev/null 2>&1; then\n running=1\n fi\n if [ "$running" = "0" ]; then\n "$ORB_UI" >/dev/null 2>&1 &\n fi\nfi\nexec "$DIR/agent_orb" run -- ${adapterName} "$@"\n`;
|
|
221
|
+
}
|
|
222
|
+
function ensurePathConfigured(platform) {
|
|
223
|
+
const currentPath = getPathEnv();
|
|
205
224
|
const parts = currentPath.split(platform.pathDelimiter).filter(Boolean);
|
|
206
|
-
if (parts
|
|
225
|
+
if (pathPartsContain(parts, platform.runtimeDir, platform)) {
|
|
226
|
+
console.log(`✓ runtime dir already on PATH: ${platform.runtimeDir}`);
|
|
207
227
|
return;
|
|
228
|
+
}
|
|
229
|
+
setPathEnv(`${platform.runtimeDir}${platform.pathDelimiter}${currentPath}`);
|
|
208
230
|
console.log('\nPATH note:');
|
|
209
231
|
if (platform.platform === 'windows') {
|
|
210
|
-
|
|
211
|
-
|
|
232
|
+
if (addWindowsUserPath(platform.runtimeDir)) {
|
|
233
|
+
console.log(` ✓ added runtime dir to user PATH: ${platform.runtimeDir}`);
|
|
234
|
+
console.log(' Open a new terminal to use agent_orb-codex, agent_orb-claude, and agent_orb globally.');
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
console.log(` Could not update user PATH automatically. Add manually if needed: ${platform.runtimeDir}`);
|
|
238
|
+
}
|
|
212
239
|
}
|
|
213
240
|
else {
|
|
214
241
|
console.log(` export PATH="${platform.runtimeDir}:$PATH"`);
|
|
215
242
|
}
|
|
216
243
|
}
|
|
244
|
+
function pathPartsContain(parts, target, platform) {
|
|
245
|
+
const normalizedTarget = normalizePathForCompare(target, platform);
|
|
246
|
+
return parts.some((part) => normalizePathForCompare(part, platform) === normalizedTarget);
|
|
247
|
+
}
|
|
248
|
+
function normalizePathForCompare(value, platform) {
|
|
249
|
+
const trimmed = value.trim().replace(/[\\/]+$/, '');
|
|
250
|
+
return platform.platform === 'windows' ? trimmed.toLowerCase() : trimmed;
|
|
251
|
+
}
|
|
252
|
+
function addWindowsUserPath(targetDir) {
|
|
253
|
+
const script = [
|
|
254
|
+
'$target = $env:AGENT_ORB_TARGET_PATH',
|
|
255
|
+
"$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')",
|
|
256
|
+
'$parts = @()',
|
|
257
|
+
'if ($userPath) { $parts = $userPath -split \';\' | Where-Object { $_ } }',
|
|
258
|
+
'$normalizedTarget = $target.TrimEnd("\\").ToLowerInvariant()',
|
|
259
|
+
'$exists = $false',
|
|
260
|
+
'foreach ($part in $parts) {',
|
|
261
|
+
' if ($part.TrimEnd("\\").ToLowerInvariant() -eq $normalizedTarget) { $exists = $true; break }',
|
|
262
|
+
'}',
|
|
263
|
+
'if (-not $exists) {',
|
|
264
|
+
" [Environment]::SetEnvironmentVariable('Path', (($parts + $target) -join ';'), 'User')",
|
|
265
|
+
'}',
|
|
266
|
+
].join('; ');
|
|
267
|
+
try {
|
|
268
|
+
run('powershell.exe', ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', script], {
|
|
269
|
+
env: {
|
|
270
|
+
...process.env,
|
|
271
|
+
AGENT_ORB_TARGET_PATH: targetDir,
|
|
272
|
+
},
|
|
273
|
+
});
|
|
274
|
+
return true;
|
|
275
|
+
}
|
|
276
|
+
catch {
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
function startOrbUiIfAvailable(platform) {
|
|
281
|
+
const orb = runtimeExe(platform, 'agent-orb-ui');
|
|
282
|
+
if (!fs.existsSync(orb))
|
|
283
|
+
return false;
|
|
284
|
+
if (platform.platform === 'windows') {
|
|
285
|
+
if (isWindowsProcessRunning('agent-orb-ui.exe'))
|
|
286
|
+
return true;
|
|
287
|
+
spawnDetached(orb, []);
|
|
288
|
+
return true;
|
|
289
|
+
}
|
|
290
|
+
if (!process.env.DISPLAY && !process.env.WAYLAND_DISPLAY)
|
|
291
|
+
return false;
|
|
292
|
+
if (isUnixProcessRunning('agent-orb-ui'))
|
|
293
|
+
return true;
|
|
294
|
+
spawnDetached(orb, []);
|
|
295
|
+
return true;
|
|
296
|
+
}
|
|
297
|
+
function isWindowsProcessRunning(imageName) {
|
|
298
|
+
try {
|
|
299
|
+
const result = run('tasklist', ['/FI', `IMAGENAME eq ${imageName}`], {
|
|
300
|
+
allowFailure: true,
|
|
301
|
+
});
|
|
302
|
+
return result.stdout.toLowerCase().includes(imageName.toLowerCase());
|
|
303
|
+
}
|
|
304
|
+
catch {
|
|
305
|
+
return false;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
function isUnixProcessRunning(processName) {
|
|
309
|
+
if (!commandExists('pgrep'))
|
|
310
|
+
return false;
|
|
311
|
+
try {
|
|
312
|
+
const result = run('pgrep', ['-x', processName], {
|
|
313
|
+
allowFailure: true,
|
|
314
|
+
});
|
|
315
|
+
return result.status === 0;
|
|
316
|
+
}
|
|
317
|
+
catch {
|
|
318
|
+
return false;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
217
321
|
async function ensureDaemon(platform, runtime) {
|
|
218
322
|
console.log('\n==> Starting daemon');
|
|
219
323
|
const tokenPath = path.join(platform.configDir, 'token');
|
package/dist/shell.js
CHANGED
|
@@ -5,7 +5,7 @@ export function commandExists(command) {
|
|
|
5
5
|
return findCommand(command) !== undefined;
|
|
6
6
|
}
|
|
7
7
|
export function findCommand(command) {
|
|
8
|
-
const pathEnv =
|
|
8
|
+
const pathEnv = getPathEnv();
|
|
9
9
|
const searchDirs = pathEnv.split(process.platform === 'win32' ? ';' : ':').filter(Boolean);
|
|
10
10
|
const candidates = process.platform === 'win32'
|
|
11
11
|
? commandCandidates(command)
|
|
@@ -19,6 +19,21 @@ export function findCommand(command) {
|
|
|
19
19
|
}
|
|
20
20
|
return undefined;
|
|
21
21
|
}
|
|
22
|
+
export function getPathEnv() {
|
|
23
|
+
if (process.platform !== 'win32')
|
|
24
|
+
return process.env.PATH ?? '';
|
|
25
|
+
const pathKey = Object.keys(process.env).find((key) => key.toLowerCase() === 'path');
|
|
26
|
+
return pathKey ? process.env[pathKey] ?? '' : process.env.PATH ?? '';
|
|
27
|
+
}
|
|
28
|
+
export function setPathEnv(value) {
|
|
29
|
+
if (process.platform !== 'win32') {
|
|
30
|
+
process.env.PATH = value;
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const pathKey = Object.keys(process.env).find((key) => key.toLowerCase() === 'path') ?? 'Path';
|
|
34
|
+
process.env[pathKey] = value;
|
|
35
|
+
process.env.PATH = value;
|
|
36
|
+
}
|
|
22
37
|
export function run(command, args, options = {}) {
|
|
23
38
|
const result = spawnSync(command, args, {
|
|
24
39
|
cwd: options.cwd,
|