@parall/daemon 1.30.0 → 1.32.0
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/bundle/manifest.json +17 -11
- package/bundle/package.json +1 -0
- package/bundle/parall-claude-agent.js +27671 -337
- package/bundle/parall-codex-agent.js +27715 -375
- package/bundle/parall-daemon.js +30421 -1355
- package/bundle/parall-openclaw-agent.js +51 -26
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +122 -72
- package/dist/clip-runtime/clip-installer.d.ts +44 -0
- package/dist/clip-runtime/clip-installer.d.ts.map +1 -0
- package/dist/clip-runtime/clip-installer.js +501 -0
- package/dist/clip-runtime/clip-provider.d.ts +76 -0
- package/dist/clip-runtime/clip-provider.d.ts.map +1 -0
- package/dist/clip-runtime/clip-provider.js +402 -0
- package/dist/clip-runtime/index.d.ts +7 -0
- package/dist/clip-runtime/index.d.ts.map +1 -0
- package/dist/clip-runtime/index.js +5 -0
- package/dist/clip-runtime/ipc.d.ts +94 -0
- package/dist/clip-runtime/ipc.d.ts.map +1 -0
- package/dist/clip-runtime/ipc.js +98 -0
- package/dist/clip-runtime/manifest.d.ts +74 -0
- package/dist/clip-runtime/manifest.d.ts.map +1 -0
- package/dist/clip-runtime/manifest.js +181 -0
- package/dist/clip-runtime/process-manager.d.ts +57 -0
- package/dist/clip-runtime/process-manager.d.ts.map +1 -0
- package/dist/clip-runtime/process-manager.js +354 -0
- package/dist/clip-runtime/process.d.ts +59 -0
- package/dist/clip-runtime/process.d.ts.map +1 -0
- package/dist/clip-runtime/process.js +350 -0
- package/dist/config.d.ts +13 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +36 -19
- package/dist/filesystem.d.ts +1 -1
- package/dist/filesystem.d.ts.map +1 -1
- package/dist/filesystem.js +51 -53
- package/dist/index.js +46 -14
- package/dist/runtimes.d.ts +10 -8
- package/dist/runtimes.d.ts.map +1 -1
- package/dist/runtimes.js +63 -95
- package/dist/supervisor.d.ts +12 -3
- package/dist/supervisor.d.ts.map +1 -1
- package/dist/supervisor.js +272 -71
- package/dist/updater-manifest.d.ts +41 -0
- package/dist/updater-manifest.d.ts.map +1 -0
- package/dist/updater-manifest.js +94 -0
- package/dist/updater.d.ts +60 -0
- package/dist/updater.d.ts.map +1 -0
- package/dist/updater.js +427 -0
- package/dist/workspace.d.ts +2 -2
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +112 -112
- package/package.json +6 -6
package/dist/filesystem.js
CHANGED
|
@@ -1,65 +1,63 @@
|
|
|
1
|
-
import * as fs from
|
|
2
|
-
import * as path from
|
|
3
|
-
import * as os from
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as os from 'os';
|
|
4
4
|
const MAX_ENTRIES = 200;
|
|
5
5
|
const SYSTEM_DIR_PREFIXES = [
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
6
|
+
'/Applications',
|
|
7
|
+
'/bin',
|
|
8
|
+
'/boot',
|
|
9
|
+
'/dev',
|
|
10
|
+
'/etc',
|
|
11
|
+
'/Library',
|
|
12
|
+
'/private',
|
|
13
|
+
'/proc',
|
|
14
|
+
'/root',
|
|
15
|
+
'/run',
|
|
16
|
+
'/sbin',
|
|
17
|
+
'/System',
|
|
18
|
+
'/sys',
|
|
19
|
+
'/usr',
|
|
20
|
+
'/var',
|
|
21
21
|
];
|
|
22
22
|
const CREDENTIAL_DIR_NAMES = new Set([
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
23
|
+
'.aws',
|
|
24
|
+
'.azure',
|
|
25
|
+
'.claude',
|
|
26
|
+
'.codex',
|
|
27
|
+
'.config',
|
|
28
|
+
'.docker',
|
|
29
|
+
'.gnupg',
|
|
30
|
+
'.kube',
|
|
31
|
+
'.npm',
|
|
32
|
+
'.ssh',
|
|
33
|
+
'.parall-agent',
|
|
34
|
+
'.parall-daemon',
|
|
35
35
|
]);
|
|
36
36
|
export function browseDenyReason(value) {
|
|
37
|
-
const normalized = path.resolve(value).split(path.sep).join(
|
|
38
|
-
if (normalized ===
|
|
39
|
-
return
|
|
37
|
+
const normalized = path.resolve(value).split(path.sep).join('/');
|
|
38
|
+
if (normalized === '/')
|
|
39
|
+
return '';
|
|
40
40
|
for (const prefix of SYSTEM_DIR_PREFIXES) {
|
|
41
41
|
if (normalized === prefix || normalized.startsWith(`${prefix}/`)) {
|
|
42
|
-
return
|
|
42
|
+
return 'a system directory';
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
-
const parts = normalized.split(
|
|
45
|
+
const parts = normalized.split('/').filter(Boolean);
|
|
46
46
|
for (const part of parts) {
|
|
47
47
|
if (CREDENTIAL_DIR_NAMES.has(part)) {
|
|
48
|
-
return
|
|
48
|
+
return 'a credential or application state directory';
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
-
return
|
|
51
|
+
return '';
|
|
52
52
|
}
|
|
53
53
|
function syntheticRoots() {
|
|
54
54
|
const roots = [];
|
|
55
55
|
const platform = os.platform();
|
|
56
|
-
const candidates = platform ===
|
|
57
|
-
? ["/Users", os.homedir()]
|
|
58
|
-
: ["/home", os.homedir()];
|
|
56
|
+
const candidates = platform === 'darwin' ? ['/Users', os.homedir()] : ['/home', os.homedir()];
|
|
59
57
|
for (const dir of [...new Set(candidates)]) {
|
|
60
58
|
try {
|
|
61
59
|
fs.accessSync(dir, fs.constants.R_OK);
|
|
62
|
-
roots.push({ name: dir, type:
|
|
60
|
+
roots.push({ name: dir, type: 'dir' });
|
|
63
61
|
}
|
|
64
62
|
catch {
|
|
65
63
|
// not accessible
|
|
@@ -69,8 +67,8 @@ function syntheticRoots() {
|
|
|
69
67
|
}
|
|
70
68
|
export async function listDirectory(dirPath) {
|
|
71
69
|
const resolved = path.resolve(dirPath);
|
|
72
|
-
const normalized = resolved.split(path.sep).join(
|
|
73
|
-
if (normalized ===
|
|
70
|
+
const normalized = resolved.split(path.sep).join('/');
|
|
71
|
+
if (normalized === '/') {
|
|
74
72
|
return { entries: syntheticRoots() };
|
|
75
73
|
}
|
|
76
74
|
const deny = browseDenyReason(normalized);
|
|
@@ -83,11 +81,11 @@ export async function listDirectory(dirPath) {
|
|
|
83
81
|
}
|
|
84
82
|
catch (err) {
|
|
85
83
|
const code = err.code;
|
|
86
|
-
if (code ===
|
|
87
|
-
return { entries: [], error:
|
|
88
|
-
return { entries: [], error:
|
|
84
|
+
if (code === 'ENOENT')
|
|
85
|
+
return { entries: [], error: 'Directory not found' };
|
|
86
|
+
return { entries: [], error: 'Permission denied' };
|
|
89
87
|
}
|
|
90
|
-
const realDeny = browseDenyReason(realPath.split(path.sep).join(
|
|
88
|
+
const realDeny = browseDenyReason(realPath.split(path.sep).join('/'));
|
|
91
89
|
if (realDeny) {
|
|
92
90
|
return { entries: [], error: `Access denied: ${realDeny}` };
|
|
93
91
|
}
|
|
@@ -97,19 +95,19 @@ export async function listDirectory(dirPath) {
|
|
|
97
95
|
}
|
|
98
96
|
catch (err) {
|
|
99
97
|
const code = err.code;
|
|
100
|
-
if (code ===
|
|
101
|
-
return { entries: [], error:
|
|
102
|
-
if (code ===
|
|
103
|
-
return { entries: [], error:
|
|
98
|
+
if (code === 'ENOENT')
|
|
99
|
+
return { entries: [], error: 'Directory not found' };
|
|
100
|
+
if (code === 'EACCES' || code === 'EPERM')
|
|
101
|
+
return { entries: [], error: 'Permission denied' };
|
|
104
102
|
return { entries: [], error: `Failed to read directory: ${code ?? String(err)}` };
|
|
105
103
|
}
|
|
106
104
|
const entries = [];
|
|
107
105
|
for (const d of dirents) {
|
|
108
106
|
if (!d.isDirectory())
|
|
109
107
|
continue;
|
|
110
|
-
if (d.name.startsWith(
|
|
108
|
+
if (d.name.startsWith('.'))
|
|
111
109
|
continue;
|
|
112
|
-
entries.push({ name: d.name, type:
|
|
110
|
+
entries.push({ name: d.name, type: 'dir' });
|
|
113
111
|
if (entries.length >= MAX_ENTRIES)
|
|
114
112
|
break;
|
|
115
113
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { createLogger } from
|
|
3
|
-
import { ParallClient } from
|
|
4
|
-
import { resolveClaudeDaemonConfig, resolveWsUrl } from
|
|
5
|
-
import { DaemonSupervisor, sleepCancellable } from
|
|
6
|
-
import {
|
|
7
|
-
|
|
2
|
+
import { createLogger, createOtelLogger, initAgentTelemetry, } from '@parall/agent-core';
|
|
3
|
+
import { ParallClient } from '@parall/sdk';
|
|
4
|
+
import { resolveClaudeDaemonConfig, resolveBundleDir, resolveWsUrl, } from './config.js';
|
|
5
|
+
import { DaemonSupervisor, sleepCancellable } from './supervisor.js';
|
|
6
|
+
import { DaemonUpdater } from './updater.js';
|
|
7
|
+
import { runCLI } from './cli.js';
|
|
8
|
+
const UPDATE_EXIT_CODE = 42;
|
|
9
|
+
let log = createLogger('daemon');
|
|
8
10
|
function formatError(reason) {
|
|
9
11
|
if (reason instanceof Error) {
|
|
10
12
|
return reason.stack ?? reason.message;
|
|
@@ -30,10 +32,12 @@ function formatError(reason) {
|
|
|
30
32
|
* any supervisor.run() rejection and rely entirely on the shell wrapper +
|
|
31
33
|
* K8s for restart.
|
|
32
34
|
*/
|
|
33
|
-
async function runForever(config, client, log, signal) {
|
|
35
|
+
async function runForever(config, client, log, signal, updater) {
|
|
34
36
|
let attempt = 0;
|
|
35
37
|
while (!signal.aborted) {
|
|
36
38
|
const supervisor = new DaemonSupervisor(config, client, log);
|
|
39
|
+
if (updater)
|
|
40
|
+
supervisor.setUpdater(updater);
|
|
37
41
|
try {
|
|
38
42
|
await supervisor.run(signal);
|
|
39
43
|
// Clean exit (signal aborted) — done.
|
|
@@ -54,7 +58,7 @@ async function runForever(config, client, log, signal) {
|
|
|
54
58
|
log.warn(`supervisor.stop() after crash threw: ${String(stopErr)}`);
|
|
55
59
|
}
|
|
56
60
|
if (config.supervisorRestartBackoffMs === 0) {
|
|
57
|
-
log.error(
|
|
61
|
+
log.error('supervisor keepalive disabled (PRLL_DAEMON_SUPERVISOR_RESTART_BACKOFF_MS=0) — exiting');
|
|
58
62
|
throw err;
|
|
59
63
|
}
|
|
60
64
|
const delay = Math.min(config.supervisorRestartBackoffMs * Math.pow(2, attempt), config.supervisorRestartBackoffMaxMs);
|
|
@@ -68,8 +72,22 @@ async function runForever(config, client, log, signal) {
|
|
|
68
72
|
}
|
|
69
73
|
async function main() {
|
|
70
74
|
const config = resolveClaudeDaemonConfig(process.env);
|
|
75
|
+
const telemetry = await initAgentTelemetry('parall-daemon', 'daemon');
|
|
76
|
+
log = createOtelLogger('daemon', 'daemon');
|
|
71
77
|
log.info(`boot: api=${config.apiUrl} pollMs=${config.pollIntervalMs} heartbeatMs=${config.heartbeatIntervalMs} agentBin=${config.agentBin}`);
|
|
72
78
|
log.info(`keepalive: bootstrapBackoffMs=${config.bootstrapBackoffMs} supervisorRestartBackoffMs=${config.supervisorRestartBackoffMs}`);
|
|
79
|
+
// --- Self-update: rollback check (before any network calls) ---
|
|
80
|
+
let updater = null;
|
|
81
|
+
if (!config.updateDisabled) {
|
|
82
|
+
const bundleDir = resolveBundleDir(process.env);
|
|
83
|
+
updater = new DaemonUpdater(bundleDir, config.updateCdnUrl, log, true);
|
|
84
|
+
if (updater.checkRollback()) {
|
|
85
|
+
log.info('rollback applied — exiting for service manager restart');
|
|
86
|
+
await telemetry.shutdown();
|
|
87
|
+
process.exit(UPDATE_EXIT_CODE);
|
|
88
|
+
}
|
|
89
|
+
log.info(`update: bundleDir=${bundleDir} cdn=${config.updateCdnUrl} interval=${config.updateIntervalMs}ms`);
|
|
90
|
+
}
|
|
73
91
|
// The daemon talks to the API as a Machine — the bearer is mck_*.
|
|
74
92
|
// No orgId is configured here; per-agent subprocesses get their
|
|
75
93
|
// own org_id via the spawn env.
|
|
@@ -83,26 +101,40 @@ async function main() {
|
|
|
83
101
|
log.info(`received ${sig} — initiating shutdown`);
|
|
84
102
|
abortController.abort();
|
|
85
103
|
};
|
|
86
|
-
process.on(
|
|
87
|
-
process.on(
|
|
104
|
+
process.on('SIGINT', () => onSignal('SIGINT'));
|
|
105
|
+
process.on('SIGTERM', () => onSignal('SIGTERM'));
|
|
88
106
|
// Defensive: unexpected async failures are logged explicitly. Rejections
|
|
89
107
|
// stay in-process so the supervisor loop can recover; uncaught exceptions
|
|
90
108
|
// exit so entrypoint.sh's shell-level keepalive restarts from a clean VM.
|
|
91
|
-
process.on(
|
|
109
|
+
process.on('unhandledRejection', (reason) => {
|
|
92
110
|
log.error(`unhandledRejection: ${formatError(reason)}`);
|
|
93
111
|
});
|
|
94
|
-
process.on(
|
|
112
|
+
process.on('uncaughtException', (err) => {
|
|
95
113
|
log.error(`uncaughtException: ${formatError(err)}`);
|
|
96
114
|
process.exitCode = 1;
|
|
97
115
|
process.exit(1);
|
|
98
116
|
});
|
|
99
117
|
config.wsUrl = resolveWsUrl(config.apiUrl, config.wsUrl, config.swimlaneName);
|
|
100
|
-
|
|
118
|
+
// --- Self-update: boot check + periodic timer ---
|
|
119
|
+
if (updater) {
|
|
120
|
+
const applied = await updater.checkAndApply().catch((err) => {
|
|
121
|
+
log.warn(`boot update check failed: ${String(err)}`);
|
|
122
|
+
return false;
|
|
123
|
+
});
|
|
124
|
+
if (applied) {
|
|
125
|
+
log.info('boot update applied — exiting for restart');
|
|
126
|
+
await telemetry.shutdown();
|
|
127
|
+
process.exit(UPDATE_EXIT_CODE);
|
|
128
|
+
}
|
|
129
|
+
updater.startPeriodicCheck(config.updateIntervalMs);
|
|
130
|
+
}
|
|
131
|
+
await runForever(config, client, log, abortController.signal, updater);
|
|
132
|
+
await telemetry.shutdown();
|
|
101
133
|
}
|
|
102
134
|
const cliArgs = process.argv.slice(2);
|
|
103
135
|
runCLI(cliArgs)
|
|
104
136
|
.then((result) => {
|
|
105
|
-
if (result ===
|
|
137
|
+
if (result === 'handled')
|
|
106
138
|
return;
|
|
107
139
|
main().catch((err) => {
|
|
108
140
|
log.error(`fatal: ${formatError(err)}`);
|
package/dist/runtimes.d.ts
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
anthropic_auth_token?: string;
|
|
6
|
-
anthropic_base_url?: string;
|
|
7
|
-
}
|
|
1
|
+
import { clearAllProviderCreds } from '@parall/agent-core';
|
|
2
|
+
import type { ProviderConfig } from '@parall/agent-core';
|
|
3
|
+
export type { ProviderConfig };
|
|
4
|
+
export { clearAllProviderCreds };
|
|
8
5
|
export interface RuntimeAdapter {
|
|
9
6
|
bin: string;
|
|
7
|
+
args: string[];
|
|
10
8
|
buildEnv(baseEnv: NodeJS.ProcessEnv, agentId: string, orgId: string, apiKey: string, dirs: AgentDirs, pc?: ProviderConfig): NodeJS.ProcessEnv;
|
|
11
9
|
}
|
|
12
10
|
export interface AgentDirs {
|
|
@@ -14,7 +12,11 @@ export interface AgentDirs {
|
|
|
14
12
|
workspaceDir: string;
|
|
15
13
|
claudeHome: string;
|
|
16
14
|
}
|
|
17
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Resolve a runtime adapter, preferring overlay bundle paths when available.
|
|
17
|
+
* When the daemon has self-updated into ~/.parall-daemon/bundle/, bridge
|
|
18
|
+
* binaries should also load from overlay to keep versions in sync.
|
|
19
|
+
*/
|
|
18
20
|
export declare function getRuntimeAdapter(runtimeType: string): RuntimeAdapter;
|
|
19
21
|
export declare function assertAgentKey(apiKey: string): void;
|
|
20
22
|
//# sourceMappingURL=runtimes.d.ts.map
|
package/dist/runtimes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtimes.d.ts","sourceRoot":"","sources":["../src/runtimes.ts"],"names":[],"mappings":"AAEA,
|
|
1
|
+
{"version":3,"file":"runtimes.d.ts","sourceRoot":"","sources":["../src/runtimes.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGzD,YAAY,EAAE,cAAc,EAAE,CAAC;AAC/B,OAAO,EAAE,qBAAqB,EAAE,CAAC;AAEjC,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,CACN,OAAO,EAAE,MAAM,CAAC,UAAU,EAC1B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,SAAS,EACf,EAAE,CAAC,EAAE,cAAc,GAClB,MAAM,CAAC,UAAU,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAuED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,cAAc,CAerE;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAInD"}
|
package/dist/runtimes.js
CHANGED
|
@@ -1,120 +1,88 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
delete env.
|
|
18
|
-
|
|
19
|
-
delete env.PRLL_CLAUDE_ALLOW_API_KEY;
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import { clearAllProviderCreds } from '@parall/agent-core';
|
|
4
|
+
import { resolveBundleDir } from './config.js';
|
|
5
|
+
export { clearAllProviderCreds };
|
|
6
|
+
function buildStandardEnv(baseEnv, agentId, orgId, apiKey, dirs, pc) {
|
|
7
|
+
const env = { ...baseEnv };
|
|
8
|
+
clearAllProviderCreds(env);
|
|
9
|
+
env.PRLL_API_KEY = apiKey;
|
|
10
|
+
env.PRLL_ORG_ID = orgId;
|
|
11
|
+
env.AGENT_ID = agentId;
|
|
12
|
+
env.PRLL_AGENT_ID = agentId;
|
|
13
|
+
env.PRLL_STATE_DIR = dirs.stateDir;
|
|
14
|
+
env.PRLL_WORKSPACE_DIR = dirs.workspaceDir;
|
|
15
|
+
if (pc)
|
|
16
|
+
env.PRLL_PROVIDER_CONFIG = JSON.stringify(pc);
|
|
17
|
+
delete env.PRLL_DAEMON_MODE;
|
|
18
|
+
return env;
|
|
20
19
|
}
|
|
21
20
|
const claudeCodeAdapter = {
|
|
22
|
-
bin:
|
|
21
|
+
bin: 'parall-claude-agent',
|
|
22
|
+
args: [],
|
|
23
23
|
buildEnv(baseEnv, agentId, orgId, apiKey, dirs, pc) {
|
|
24
|
-
const env =
|
|
25
|
-
clearAllProviderCreds(env);
|
|
26
|
-
env.PRLL_API_KEY = apiKey;
|
|
27
|
-
env.PRLL_ORG_ID = orgId;
|
|
28
|
-
env.AGENT_ID = agentId;
|
|
29
|
-
env.PRLL_AGENT_ID = agentId;
|
|
24
|
+
const env = buildStandardEnv(baseEnv, agentId, orgId, apiKey, dirs, pc);
|
|
30
25
|
env.PRLL_CLAUDE_HOME = dirs.claudeHome;
|
|
31
|
-
env.PRLL_CLAUDE_STATE_DIR = dirs.stateDir;
|
|
32
|
-
env.PRLL_CLAUDE_WORKSPACE_DIR = dirs.workspaceDir;
|
|
33
|
-
const source = llmSource(pc);
|
|
34
|
-
if (source === "parall") {
|
|
35
|
-
env.ANTHROPIC_AUTH_TOKEN = apiKey;
|
|
36
|
-
env.ANTHROPIC_BASE_URL = `${baseEnv.PRLL_API_URL}/api/llm`;
|
|
37
|
-
env.PRLL_CLAUDE_ALLOW_API_KEY = "1";
|
|
38
|
-
}
|
|
39
|
-
else if (source === "custom") {
|
|
40
|
-
if (pc?.anthropic_auth_token) {
|
|
41
|
-
env.ANTHROPIC_AUTH_TOKEN = pc.anthropic_auth_token;
|
|
42
|
-
env.PRLL_CLAUDE_ALLOW_API_KEY = "1";
|
|
43
|
-
}
|
|
44
|
-
if (pc?.anthropic_base_url)
|
|
45
|
-
env.ANTHROPIC_BASE_URL = pc.anthropic_base_url;
|
|
46
|
-
}
|
|
47
|
-
delete env.PRLL_DAEMON_MODE;
|
|
48
26
|
return env;
|
|
49
27
|
},
|
|
50
28
|
};
|
|
51
29
|
const codexAdapter = {
|
|
52
|
-
bin:
|
|
30
|
+
bin: 'parall-codex-agent',
|
|
31
|
+
args: [],
|
|
53
32
|
buildEnv(baseEnv, agentId, orgId, apiKey, dirs, pc) {
|
|
54
|
-
const env =
|
|
55
|
-
|
|
56
|
-
env.PRLL_API_KEY = apiKey;
|
|
57
|
-
env.PRLL_ORG_ID = orgId;
|
|
58
|
-
env.AGENT_ID = agentId;
|
|
59
|
-
env.PRLL_AGENT_ID = agentId;
|
|
60
|
-
env.PRLL_CODEX_STATE_DIR = dirs.stateDir;
|
|
61
|
-
env.PRLL_CODEX_WORKSPACE_DIR = dirs.workspaceDir;
|
|
62
|
-
env.PRLL_CODEX_HOME = path.join(dirs.stateDir, ".codex");
|
|
63
|
-
const source = llmSource(pc);
|
|
64
|
-
if (source === "parall") {
|
|
65
|
-
env.OPENAI_API_KEY = apiKey;
|
|
66
|
-
env.OPENAI_BASE_URL = `${baseEnv.PRLL_API_URL}/api/llm/v1`;
|
|
67
|
-
}
|
|
68
|
-
else if (source === "custom") {
|
|
69
|
-
if (pc?.openai_api_key)
|
|
70
|
-
env.OPENAI_API_KEY = pc.openai_api_key;
|
|
71
|
-
if (pc?.openai_base_url)
|
|
72
|
-
env.OPENAI_BASE_URL = pc.openai_base_url;
|
|
73
|
-
}
|
|
74
|
-
delete env.PRLL_DAEMON_MODE;
|
|
33
|
+
const env = buildStandardEnv(baseEnv, agentId, orgId, apiKey, dirs, pc);
|
|
34
|
+
env.PRLL_CODEX_HOME = path.join(dirs.stateDir, '.codex');
|
|
75
35
|
return env;
|
|
76
36
|
},
|
|
77
37
|
};
|
|
78
38
|
const defaultAdapter = {
|
|
79
|
-
bin:
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
env.PRLL_API_KEY = apiKey;
|
|
83
|
-
env.PRLL_ORG_ID = orgId;
|
|
84
|
-
env.AGENT_ID = agentId;
|
|
85
|
-
env.PRLL_AGENT_ID = agentId;
|
|
86
|
-
env.PRLL_STATE_DIR = dirs.stateDir;
|
|
87
|
-
env.PRLL_WORKSPACE_DIR = dirs.workspaceDir;
|
|
88
|
-
delete env.PRLL_DAEMON_MODE;
|
|
89
|
-
return env;
|
|
90
|
-
},
|
|
39
|
+
bin: 'parall-agent',
|
|
40
|
+
args: [],
|
|
41
|
+
buildEnv: buildStandardEnv,
|
|
91
42
|
};
|
|
92
43
|
const openclawAdapter = {
|
|
93
|
-
bin:
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
env.
|
|
98
|
-
env.PRLL_ORG_ID = orgId;
|
|
99
|
-
env.AGENT_ID = agentId;
|
|
100
|
-
env.PRLL_AGENT_ID = agentId;
|
|
101
|
-
env.PRLL_OPENCLAW_STATE_DIR = dirs.stateDir;
|
|
102
|
-
env.PRLL_OPENCLAW_WORKSPACE_DIR = dirs.workspaceDir;
|
|
103
|
-
env.OPENCLAW_GATEWAY_PORT = env.OPENCLAW_GATEWAY_PORT || "0";
|
|
104
|
-
delete env.PRLL_DAEMON_MODE;
|
|
44
|
+
bin: 'parall-openclaw-agent',
|
|
45
|
+
args: [],
|
|
46
|
+
buildEnv(baseEnv, agentId, orgId, apiKey, dirs, pc) {
|
|
47
|
+
const env = buildStandardEnv(baseEnv, agentId, orgId, apiKey, dirs, pc);
|
|
48
|
+
env.OPENCLAW_GATEWAY_PORT = env.OPENCLAW_GATEWAY_PORT || '0';
|
|
105
49
|
return env;
|
|
106
50
|
},
|
|
107
51
|
};
|
|
108
52
|
const RUNTIME_ADAPTERS = {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
53
|
+
'claude-code': claudeCodeAdapter,
|
|
54
|
+
codex: codexAdapter,
|
|
55
|
+
openclaw: openclawAdapter,
|
|
56
|
+
};
|
|
57
|
+
const OVERLAY_BIN_NAMES = {
|
|
58
|
+
'claude-code': 'parall-claude-agent.js',
|
|
59
|
+
codex: 'parall-codex-agent.js',
|
|
60
|
+
openclaw: 'parall-openclaw-agent.js',
|
|
112
61
|
};
|
|
62
|
+
/**
|
|
63
|
+
* Resolve a runtime adapter, preferring overlay bundle paths when available.
|
|
64
|
+
* When the daemon has self-updated into ~/.parall-daemon/bundle/, bridge
|
|
65
|
+
* binaries should also load from overlay to keep versions in sync.
|
|
66
|
+
*/
|
|
113
67
|
export function getRuntimeAdapter(runtimeType) {
|
|
114
|
-
|
|
68
|
+
const base = RUNTIME_ADAPTERS[runtimeType] ?? defaultAdapter;
|
|
69
|
+
const overlayName = OVERLAY_BIN_NAMES[runtimeType];
|
|
70
|
+
if (!overlayName)
|
|
71
|
+
return base;
|
|
72
|
+
try {
|
|
73
|
+
const bundleDir = resolveBundleDir();
|
|
74
|
+
const overlayBin = path.join(bundleDir, 'current', overlayName);
|
|
75
|
+
if (fs.existsSync(overlayBin)) {
|
|
76
|
+
return { ...base, bin: process.execPath, args: [overlayBin] };
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// resolveBundleDir may fail in unusual setups; fall through
|
|
81
|
+
}
|
|
82
|
+
return base;
|
|
115
83
|
}
|
|
116
84
|
export function assertAgentKey(apiKey) {
|
|
117
|
-
if (apiKey.startsWith(
|
|
118
|
-
throw new Error(
|
|
85
|
+
if (apiKey.startsWith('mck_')) {
|
|
86
|
+
throw new Error('BUG: machine key leaked to child process — expected agk_, got mck_');
|
|
119
87
|
}
|
|
120
88
|
}
|
package/dist/supervisor.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import { ParallClient } from
|
|
3
|
-
import {
|
|
1
|
+
import { type GatewayLogger } from '@parall/agent-core';
|
|
2
|
+
import { ParallClient } from '@parall/sdk';
|
|
3
|
+
import type { DaemonUpdater } from './updater.js';
|
|
4
|
+
import { type ClaudeDaemonConfig } from './config.js';
|
|
4
5
|
/**
|
|
5
6
|
* Sleep that wakes early on abort. Returns true if the full delay elapsed,
|
|
6
7
|
* false if aborted. Used by bootstrap retry and the outer keepalive in
|
|
@@ -30,10 +31,16 @@ export declare class DaemonSupervisor {
|
|
|
30
31
|
private readonly cancelledSpawns;
|
|
31
32
|
private ws;
|
|
32
33
|
private running;
|
|
34
|
+
private machineId;
|
|
33
35
|
private machineOrgId;
|
|
34
36
|
private machineLlmSource;
|
|
35
37
|
private stopResolve;
|
|
38
|
+
private updater;
|
|
39
|
+
private healthConfirmed;
|
|
40
|
+
private clipManager;
|
|
41
|
+
private clipProvider;
|
|
36
42
|
constructor(config: ClaudeDaemonConfig, client: ParallClient, log: GatewayLogger);
|
|
43
|
+
setUpdater(updater: DaemonUpdater): void;
|
|
37
44
|
/** Start the supervisor. Returns a promise that resolves on `stop()`. */
|
|
38
45
|
run(signal: AbortSignal): Promise<void>;
|
|
39
46
|
/** Disconnect WS, cancel timers, SIGTERM all children, await exit. */
|
|
@@ -50,6 +57,8 @@ export declare class DaemonSupervisor {
|
|
|
50
57
|
private handleAgentAttached;
|
|
51
58
|
private handleAgentDetached;
|
|
52
59
|
private handleFilesystemBrowse;
|
|
60
|
+
private handleClipInstall;
|
|
61
|
+
private reconcileClipInstalls;
|
|
53
62
|
private handleWorkspaceSetupRequested;
|
|
54
63
|
private scheduleWorkspaceSetupRetry;
|
|
55
64
|
private clearWorkspaceSetupRetry;
|
package/dist/supervisor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"supervisor.d.ts","sourceRoot":"","sources":["../src/supervisor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"supervisor.d.ts","sourceRoot":"","sources":["../src/supervisor.ts"],"names":[],"mappings":"AAGA,OAAO,EAA8B,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACpF,OAAO,EACL,YAAY,EAab,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EACL,KAAK,kBAAkB,EAMxB,MAAM,aAAa,CAAC;AAmBrB;;;;GAIG;AACH,iBAAS,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAa3E;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAyB5B;;;;;;;;;;GAUG;AACH,qBAAa,gBAAgB;IAkBzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,GAAG;IAnBtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiC;IAC1D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAqB;IAC3D,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAqC;IAC/E,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqB;IACrD,OAAO,CAAC,EAAE,CAAyB;IACnC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,gBAAgB,CAAoB;IAC5C,OAAO,CAAC,WAAW,CAA6B;IAChD,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,WAAW,CAAmC;IACtD,OAAO,CAAC,YAAY,CAA6B;gBAG9B,MAAM,EAAE,kBAAkB,EAC1B,MAAM,EAAE,YAAY,EACpB,GAAG,EAAE,aAAa;IAGrC,UAAU,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAIxC,yEAAyE;IACnE,GAAG,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IA+J7C,sEAAsE;IAChE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAyCb,kBAAkB;YAsClB,aAAa;IA2D3B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;YA6CX,kBAAkB;YAqBlB,mBAAmB;YAgBnB,mBAAmB;YAmBnB,sBAAsB;YAwBtB,iBAAiB;YAmEjB,qBAAqB;YAqBrB,6BAA6B;IAqC3C,OAAO,CAAC,2BAA2B;IAYnC,OAAO,CAAC,wBAAwB;YAUlB,oBAAoB;YAgBpB,kBAAkB;YAYlB,eAAe;YAcf,UAAU;YAoBV,cAAc;IAkE5B,OAAO,CAAC,UAAU;YA2GJ,cAAc;IAyB5B,OAAO,CAAC,0BAA0B;CAkCnC"}
|