@parall/daemon 1.32.0 → 1.33.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.
Files changed (51) hide show
  1. package/bundle/bb-browser-daemon.js +15628 -0
  2. package/bundle/buildDomTree.js +1501 -0
  3. package/bundle/manifest.json +19 -11
  4. package/bundle/parall-claude-agent.js +224 -58
  5. package/bundle/parall-codex-agent.js +224 -58
  6. package/bundle/parall-daemon.js +4507 -2668
  7. package/bundle/parall-openclaw-agent.js +4 -3
  8. package/dist/cli.d.ts.map +1 -1
  9. package/dist/cli.js +8 -2
  10. package/dist/clip-runtime/browser-dependency.d.ts +20 -0
  11. package/dist/clip-runtime/browser-dependency.d.ts.map +1 -0
  12. package/dist/clip-runtime/browser-dependency.js +52 -0
  13. package/dist/clip-runtime/browser-profile-manager.d.ts +67 -0
  14. package/dist/clip-runtime/browser-profile-manager.d.ts.map +1 -0
  15. package/dist/clip-runtime/browser-profile-manager.js +595 -0
  16. package/dist/clip-runtime/bun-resolver.d.ts +24 -0
  17. package/dist/clip-runtime/bun-resolver.d.ts.map +1 -0
  18. package/dist/clip-runtime/bun-resolver.js +58 -0
  19. package/dist/clip-runtime/clip-installer.d.ts.map +1 -1
  20. package/dist/clip-runtime/clip-installer.js +59 -18
  21. package/dist/clip-runtime/clip-provider.d.ts +13 -2
  22. package/dist/clip-runtime/clip-provider.d.ts.map +1 -1
  23. package/dist/clip-runtime/clip-provider.js +106 -36
  24. package/dist/clip-runtime/hub-client.d.ts +79 -0
  25. package/dist/clip-runtime/hub-client.d.ts.map +1 -0
  26. package/dist/clip-runtime/hub-client.js +320 -0
  27. package/dist/clip-runtime/index.d.ts +2 -0
  28. package/dist/clip-runtime/index.d.ts.map +1 -1
  29. package/dist/clip-runtime/index.js +2 -0
  30. package/dist/clip-runtime/ipc.d.ts +6 -0
  31. package/dist/clip-runtime/ipc.d.ts.map +1 -1
  32. package/dist/clip-runtime/manifest.d.ts +16 -8
  33. package/dist/clip-runtime/manifest.d.ts.map +1 -1
  34. package/dist/clip-runtime/manifest.js +13 -0
  35. package/dist/clip-runtime/process-manager.d.ts +55 -3
  36. package/dist/clip-runtime/process-manager.d.ts.map +1 -1
  37. package/dist/clip-runtime/process-manager.js +233 -76
  38. package/dist/clip-runtime/process.d.ts +15 -1
  39. package/dist/clip-runtime/process.d.ts.map +1 -1
  40. package/dist/clip-runtime/process.js +73 -10
  41. package/dist/config.d.ts +9 -0
  42. package/dist/config.d.ts.map +1 -1
  43. package/dist/config.js +12 -0
  44. package/dist/index.js +46 -5
  45. package/dist/runtime-bin-resolver.d.ts +7 -0
  46. package/dist/runtime-bin-resolver.d.ts.map +1 -0
  47. package/dist/runtime-bin-resolver.js +292 -0
  48. package/dist/supervisor.d.ts +53 -4
  49. package/dist/supervisor.d.ts.map +1 -1
  50. package/dist/supervisor.js +449 -117
  51. package/package.json +7 -6
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,2GAA2G;IAC3G,QAAQ,EAAE,MAAM,CAAC;IACjB,yFAAyF;IACzF,YAAY,EAAE,MAAM,CAAC;IACrB,kGAAkG;IAClG,cAAc,EAAE,MAAM,CAAC;IACvB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,cAAc,EAAE,MAAM,CAAC;IACvB,iFAAiF;IACjF,mBAAmB,EAAE,MAAM,CAAC;IAC5B,oDAAoD;IACpD,gBAAgB,EAAE,MAAM,CAAC;IACzB,oFAAoF;IACpF,mBAAmB,EAAE,MAAM,CAAC;IAC5B;;;;;OAKG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAC3B,qBAAqB,EAAE,MAAM,CAAC;IAC9B;;;;OAIG;IACH,0BAA0B,EAAE,MAAM,CAAC;IACnC,6BAA6B,EAAE,MAAM,CAAC;IACtC,yEAAyE;IACzE,YAAY,EAAE,MAAM,CAAC;IACrB,gFAAgF;IAChF,gBAAgB,EAAE,MAAM,CAAC;IACzB,4DAA4D;IAC5D,cAAc,EAAE,OAAO,CAAC;CACzB,CAAC;AA2BF,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAE5E;AAED,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAE7E;AAyBD,wBAAgB,yBAAyB,CACvC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,kBAAkB,CA0DpB;AASD,wDAAwD;AACxD,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAE9E;AAED;;mEAEmE;AACnE,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAElF;AAED,+EAA+E;AAC/E,wBAAgB,8BAA8B,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAE7E;AAED,uEAAuE;AACvE,wBAAgB,6BAA6B,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAE7E;AAED,iEAAiE;AACjE,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAElF;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAG7E;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,aAAa,CAAC,EAAE,MAAM,EACtB,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM,CAMR"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,2GAA2G;IAC3G,QAAQ,EAAE,MAAM,CAAC;IACjB,yFAAyF;IACzF,YAAY,EAAE,MAAM,CAAC;IACrB,kGAAkG;IAClG,cAAc,EAAE,MAAM,CAAC;IACvB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,cAAc,EAAE,MAAM,CAAC;IACvB,iFAAiF;IACjF,mBAAmB,EAAE,MAAM,CAAC;IAC5B,oDAAoD;IACpD,gBAAgB,EAAE,MAAM,CAAC;IACzB,oFAAoF;IACpF,mBAAmB,EAAE,MAAM,CAAC;IAC5B;;;;;OAKG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAC3B,qBAAqB,EAAE,MAAM,CAAC;IAC9B;;;;OAIG;IACH,0BAA0B,EAAE,MAAM,CAAC;IACnC,6BAA6B,EAAE,MAAM,CAAC;IACtC,yEAAyE;IACzE,YAAY,EAAE,MAAM,CAAC;IACrB,gFAAgF;IAChF,gBAAgB,EAAE,MAAM,CAAC;IACzB,4DAA4D;IAC5D,cAAc,EAAE,OAAO,CAAC;CACzB,CAAC;AA2BF;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAI5E;AAED,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAE7E;AAyBD,wBAAgB,yBAAyB,CACvC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,kBAAkB,CA0DpB;AASD,wDAAwD;AACxD,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAE9E;AAED;;mEAEmE;AACnE,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAElF;AAED,+EAA+E;AAC/E,wBAAgB,8BAA8B,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAE7E;AAED,uEAAuE;AACvE,wBAAgB,6BAA6B,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAE7E;AAED,iEAAiE;AACjE,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAElF;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAG7E;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,aAAa,CAAC,EAAE,MAAM,EACtB,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM,CAMR"}
package/dist/config.js CHANGED
@@ -24,7 +24,19 @@ function parseMsAllowZero(value, fallback) {
24
24
  const n = Number(value);
25
25
  return Number.isFinite(n) && n >= 0 ? n : fallback;
26
26
  }
27
+ /**
28
+ * Root dir for all on-disk daemon state: `config.json`, the self-update
29
+ * `bundle/` overlay (versions + current symlink + update-state.json), and
30
+ * bridge-bin resolution all derive from this single path. `PRLL_DAEMON_CONFIG_DIR`
31
+ * overrides it so multiple daemons can coexist on one host without colliding —
32
+ * e.g. a staging desktop install points its launchd agent at
33
+ * `~/.parall-daemon-staging` while prod keeps the default `~/.parall-daemon`.
34
+ * Unset → default (no behavior change for existing single-env installs).
35
+ */
27
36
  export function daemonConfigDir(env = process.env) {
37
+ const override = env.PRLL_DAEMON_CONFIG_DIR?.trim();
38
+ if (override)
39
+ return resolvePath(override);
28
40
  return path.join(env.HOME || os.homedir(), '.parall-daemon');
29
41
  }
30
42
  export function daemonConfigPath(env = process.env) {
package/dist/index.js CHANGED
@@ -1,10 +1,11 @@
1
1
  #!/usr/bin/env node
2
+ import * as path from 'node:path';
2
3
  import { createLogger, createOtelLogger, initAgentTelemetry, } from '@parall/agent-core';
3
4
  import { ParallClient } from '@parall/sdk';
4
- import { resolveClaudeDaemonConfig, resolveBundleDir, resolveWsUrl, } from './config.js';
5
+ import { runCLI } from './cli.js';
6
+ import { resolveBundleDir, resolveClaudeDaemonConfig, resolveWsUrl, } from './config.js';
5
7
  import { DaemonSupervisor, sleepCancellable } from './supervisor.js';
6
8
  import { DaemonUpdater } from './updater.js';
7
- import { runCLI } from './cli.js';
8
9
  const UPDATE_EXIT_CODE = 42;
9
10
  let log = createLogger('daemon');
10
11
  function formatError(reason) {
@@ -13,6 +14,39 @@ function formatError(reason) {
13
14
  }
14
15
  return String(reason);
15
16
  }
17
+ /**
18
+ * Self-update should run only when a service manager supervises the daemon —
19
+ * `parall-daemon service install` (launchd/systemd) or the hosted entrypoint.sh
20
+ * keepalive loop. Those wrappers re-exec the overlay bundle on restart, and
21
+ * exit(UPDATE_EXIT_CODE) is precisely what triggers that restart so the new code
22
+ * loads.
23
+ *
24
+ * A bare `npx @parall/daemon` foreground run has neither property: it never
25
+ * exec's the overlay (so a downloaded bundle is dead weight on disk — this very
26
+ * process keeps running the npm launcher code), and nothing restarts it after
27
+ * exit(42). Self-updating there would just kill the daemon with no recovery. So
28
+ * we gate on two positive "managed" signals:
29
+ * - PRLL_DAEMON_MANAGED=1 — injected into the plist / systemd unit by
30
+ * `service install`; the authoritative marker.
31
+ * - launched from the overlay bundle dir — a service wrapper already exec'd
32
+ * `…/.parall-daemon/bundle/current/parall-daemon.js`. Covers service
33
+ * installs predating the PRLL_DAEMON_MANAGED marker.
34
+ * Foreground users stay current via `npx @parall/daemon@latest`, which pulls the
35
+ * newest launcher on every run.
36
+ */
37
+ function isSelfUpdateManaged(env, bundleDir) {
38
+ if (env.PRLL_DAEMON_MANAGED === '1' || env.PRLL_DAEMON_MANAGED === 'true')
39
+ return true;
40
+ const entry = process.argv[1];
41
+ if (entry) {
42
+ const resolvedEntry = path.resolve(entry);
43
+ const resolvedBundle = path.resolve(bundleDir);
44
+ if (resolvedEntry === resolvedBundle || resolvedEntry.startsWith(resolvedBundle + path.sep)) {
45
+ return true;
46
+ }
47
+ }
48
+ return false;
49
+ }
16
50
  /**
17
51
  * Outer keepalive: runs `supervisor.run()` in a loop, restarting it with
18
52
  * exponential backoff if it rejects. The daemon process only exits when
@@ -61,7 +95,7 @@ async function runForever(config, client, log, signal, updater) {
61
95
  log.error('supervisor keepalive disabled (PRLL_DAEMON_SUPERVISOR_RESTART_BACKOFF_MS=0) — exiting');
62
96
  throw err;
63
97
  }
64
- const delay = Math.min(config.supervisorRestartBackoffMs * Math.pow(2, attempt), config.supervisorRestartBackoffMaxMs);
98
+ const delay = Math.min(config.supervisorRestartBackoffMs * 2 ** attempt, config.supervisorRestartBackoffMaxMs);
65
99
  attempt += 1;
66
100
  log.warn(`restarting supervisor in ${delay}ms (attempt ${attempt})`);
67
101
  const slept = await sleepCancellable(delay, signal);
@@ -77,9 +111,13 @@ async function main() {
77
111
  log.info(`boot: api=${config.apiUrl} pollMs=${config.pollIntervalMs} heartbeatMs=${config.heartbeatIntervalMs} agentBin=${config.agentBin}`);
78
112
  log.info(`keepalive: bootstrapBackoffMs=${config.bootstrapBackoffMs} supervisorRestartBackoffMs=${config.supervisorRestartBackoffMs}`);
79
113
  // --- Self-update: rollback check (before any network calls) ---
114
+ // Only run when a service manager supervises us (see isSelfUpdateManaged):
115
+ // a bare `npx` foreground run can't load the overlay and won't be restarted
116
+ // after exit(42), so self-update there would just kill the daemon.
80
117
  let updater = null;
81
- if (!config.updateDisabled) {
82
- const bundleDir = resolveBundleDir(process.env);
118
+ const bundleDir = resolveBundleDir(process.env);
119
+ const selfUpdateEnabled = !config.updateDisabled && isSelfUpdateManaged(process.env, bundleDir);
120
+ if (selfUpdateEnabled) {
83
121
  updater = new DaemonUpdater(bundleDir, config.updateCdnUrl, log, true);
84
122
  if (updater.checkRollback()) {
85
123
  log.info('rollback applied — exiting for service manager restart');
@@ -88,6 +126,9 @@ async function main() {
88
126
  }
89
127
  log.info(`update: bundleDir=${bundleDir} cdn=${config.updateCdnUrl} interval=${config.updateIntervalMs}ms`);
90
128
  }
129
+ else if (!config.updateDisabled) {
130
+ log.info('update: skipped (foreground mode) — run `parall-daemon service install` for managed auto-update');
131
+ }
91
132
  // The daemon talks to the API as a Machine — the bearer is mck_*.
92
133
  // No orgId is configured here; per-agent subprocesses get their
93
134
  // own org_id via the spawn env.
@@ -0,0 +1,7 @@
1
+ type RuntimeBinLogger = {
2
+ info: (msg: string) => void;
3
+ warn: (msg: string) => void;
4
+ };
5
+ export declare function applyRuntimeBinaryEnv(runtimeType: string, baseEnv: NodeJS.ProcessEnv, log: RuntimeBinLogger): NodeJS.ProcessEnv;
6
+ export {};
7
+ //# sourceMappingURL=runtime-bin-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-bin-resolver.d.ts","sourceRoot":"","sources":["../src/runtime-bin-resolver.ts"],"names":[],"mappings":"AAUA,KAAK,gBAAgB,GAAG;IACtB,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B,CAAC;AA0BF,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,CAAC,UAAU,EAC1B,GAAG,EAAE,gBAAgB,GACpB,MAAM,CAAC,UAAU,CAmCnB"}
@@ -0,0 +1,292 @@
1
+ import { execFileSync } from 'node:child_process';
2
+ import * as fs from 'node:fs';
3
+ import * as os from 'node:os';
4
+ import * as path from 'node:path';
5
+ const RUNTIME_BINARIES = {
6
+ 'claude-code': { command: 'claude', envVar: 'PRLL_CLAUDE_BIN' },
7
+ codex: { command: 'codex', envVar: 'PRLL_CODEX_BIN' },
8
+ openclaw: { command: 'openclaw', envVar: 'PRLL_OPENCLAW_BIN' },
9
+ };
10
+ const RESOLUTION_CACHE_TTL_MS = 5 * 60_000;
11
+ const resolutionCache = new Map();
12
+ export function applyRuntimeBinaryEnv(runtimeType, baseEnv, log) {
13
+ const env = { ...baseEnv };
14
+ const originalPath = env.PATH;
15
+ const pathPlan = candidatePathPlan(env);
16
+ const primaryPath = mergePath(pathPlan.primaryDirs, originalPath);
17
+ env.PATH = mergePath([...pathPlan.primaryDirs, ...pathPlan.versionedFallbackDirs], originalPath);
18
+ const spec = RUNTIME_BINARIES[runtimeType];
19
+ if (!spec)
20
+ return env;
21
+ const configured = env[spec.envVar]?.trim();
22
+ if (configured) {
23
+ const resolved = resolveRuntimeCommand(configured, env, originalPath, primaryPath, env.PATH);
24
+ if (resolved) {
25
+ env[spec.envVar] = resolved.binaryPath;
26
+ env.PATH = anchorResolvedPath(env.PATH, resolved);
27
+ log.info(`runtime ${runtimeType}: using ${spec.envVar}=${resolved.binaryPath}`);
28
+ }
29
+ else {
30
+ log.warn(`runtime ${runtimeType}: configured ${spec.envVar}=${configured} is not executable`);
31
+ }
32
+ return env;
33
+ }
34
+ const resolved = resolveRuntimeCommand(spec.command, env, originalPath, primaryPath, env.PATH);
35
+ if (resolved) {
36
+ env[spec.envVar] = resolved.binaryPath;
37
+ env.PATH = anchorResolvedPath(env.PATH, resolved);
38
+ log.info(`runtime ${runtimeType}: resolved ${spec.command} at ${resolved.binaryPath}`);
39
+ }
40
+ else {
41
+ log.warn(`runtime ${runtimeType}: could not resolve ${spec.command}; child will rely on PATH ` +
42
+ `(${env.PATH ?? '<empty>'})`);
43
+ }
44
+ return env;
45
+ }
46
+ function resolveRuntimeCommand(command, env, inheritedPath, primaryPath, fallbackPath) {
47
+ const cacheKey = `runtime\0${command}\0${primaryPath}\0${fallbackPath}\0${env.SHELL ?? ''}\0${env.HOME ?? ''}`;
48
+ const cached = getCachedResolution(cacheKey);
49
+ if (cached)
50
+ return cached;
51
+ const direct = resolveDirectPath(command);
52
+ if (direct) {
53
+ const resolved = { binaryPath: direct };
54
+ setCachedResolution(cacheKey, resolved);
55
+ return resolved;
56
+ }
57
+ const fromInheritedPath = resolveFromPath(command, inheritedPath, env);
58
+ if (fromInheritedPath) {
59
+ setCachedResolution(cacheKey, fromInheritedPath);
60
+ return fromInheritedPath;
61
+ }
62
+ const fromShell = resolveFromLoginShell(command, { ...env, PATH: inheritedPath });
63
+ if (fromShell) {
64
+ setCachedResolution(cacheKey, fromShell);
65
+ return fromShell;
66
+ }
67
+ const fromPrimaryPath = resolveFromPath(command, primaryPath, env);
68
+ if (fromPrimaryPath) {
69
+ setCachedResolution(cacheKey, fromPrimaryPath);
70
+ return fromPrimaryPath;
71
+ }
72
+ const fromFallbackPath = fallbackPath === primaryPath ? null : resolveFromPath(command, fallbackPath, env);
73
+ if (fromFallbackPath) {
74
+ setCachedResolution(cacheKey, fromFallbackPath);
75
+ return fromFallbackPath;
76
+ }
77
+ return null;
78
+ }
79
+ function resolveDirectPath(command) {
80
+ if (!command.includes('/') && !command.includes('\\'))
81
+ return null;
82
+ const abs = path.isAbsolute(command) ? command : path.resolve(process.cwd(), command);
83
+ return isExecutable(abs) ? abs : null;
84
+ }
85
+ function resolveFromPath(command, pathValue, env) {
86
+ if (!pathValue || command.includes('/') || command.includes('\\'))
87
+ return null;
88
+ const dirs = pathValue.split(path.delimiter).filter(Boolean);
89
+ for (const dir of dirs) {
90
+ for (const file of commandCandidates(command, env)) {
91
+ const candidate = path.join(dir, file);
92
+ if (isExecutable(candidate))
93
+ return { binaryPath: candidate, pathValue };
94
+ }
95
+ }
96
+ return null;
97
+ }
98
+ function resolveFromLoginShell(command, env) {
99
+ if (command.includes('/') || command.includes('\\'))
100
+ return null;
101
+ const shells = unique([
102
+ env.SHELL?.trim(),
103
+ process.platform === 'darwin' ? '/bin/zsh' : undefined,
104
+ '/bin/bash',
105
+ '/bin/sh',
106
+ ]);
107
+ for (const shell of shells) {
108
+ if (!shell || !isExecutable(shell))
109
+ continue;
110
+ try {
111
+ const out = execFileSync(shell, [
112
+ '-lic',
113
+ `resolved=$(command -v ${shellQuote(command)}) || exit $?; printf '__PRLL_BIN__%s\n__PRLL_PATH__%s\n' "$resolved" "$PATH"`,
114
+ ], {
115
+ encoding: 'utf8',
116
+ env,
117
+ stdio: ['ignore', 'pipe', 'pipe'],
118
+ timeout: 2_500,
119
+ });
120
+ let binaryPath = '';
121
+ let pathValue = '';
122
+ for (const line of out.split(/\r?\n/)) {
123
+ if (line.startsWith('__PRLL_BIN__'))
124
+ binaryPath = line.slice('__PRLL_BIN__'.length).trim();
125
+ if (line.startsWith('__PRLL_PATH__'))
126
+ pathValue = line.slice('__PRLL_PATH__'.length);
127
+ }
128
+ if (path.isAbsolute(binaryPath) && isExecutable(binaryPath)) {
129
+ return { binaryPath, pathValue: pathValue || undefined };
130
+ }
131
+ }
132
+ catch {
133
+ // Shell startup files may be noisy or slow. Keep resolution best-effort.
134
+ }
135
+ }
136
+ return null;
137
+ }
138
+ function candidatePathPlan(env) {
139
+ const home = env.HOME || os.homedir();
140
+ const primaryDirs = [
141
+ ...splitPath(env.PRLL_DAEMON_RUNTIME_PATH),
142
+ ...splitPath(env.PRLL_DAEMON_EXTRA_PATH),
143
+ path.dirname(process.execPath),
144
+ path.join(path.dirname(process.execPath), 'bin'),
145
+ path.resolve(path.dirname(process.execPath), '..', 'Resources', 'bin'),
146
+ path.join(home, '.local', 'bin'),
147
+ path.join(home, 'bin'),
148
+ path.join(home, '.npm-global', 'bin'),
149
+ path.join(home, 'Library', 'pnpm'),
150
+ path.join(home, '.local', 'share', 'pnpm'),
151
+ path.join(home, '.volta', 'bin'),
152
+ path.join(home, '.bun', 'bin'),
153
+ path.join(home, '.asdf', 'shims'),
154
+ path.join(home, '.local', 'share', 'mise', 'shims'),
155
+ path.join(home, '.mise', 'shims'),
156
+ path.join(home, '.fnm', 'aliases', 'default', 'bin'),
157
+ path.join(home, 'Library', 'Application Support', 'fnm', 'aliases', 'default', 'bin'),
158
+ '/opt/homebrew/bin',
159
+ '/usr/local/bin',
160
+ '/usr/bin',
161
+ '/bin',
162
+ '/usr/sbin',
163
+ '/sbin',
164
+ '/snap/bin',
165
+ ];
166
+ const versionedFallbackDirs = [
167
+ ...nvmVersionBinDirs(home),
168
+ ...fnmVersionBinDirs(home),
169
+ ];
170
+ return {
171
+ primaryDirs: unique(primaryDirs).filter((dir) => !!dir && isDirectory(dir)),
172
+ versionedFallbackDirs: unique(versionedFallbackDirs).filter((dir) => !!dir && isDirectory(dir)),
173
+ };
174
+ }
175
+ function nvmVersionBinDirs(home) {
176
+ const root = path.join(home, '.nvm', 'versions', 'node');
177
+ let versions;
178
+ try {
179
+ versions = fs.readdirSync(root);
180
+ }
181
+ catch {
182
+ return [];
183
+ }
184
+ return sortVersionNamesDesc(versions).map((version) => path.join(root, version, 'bin'));
185
+ }
186
+ function fnmVersionBinDirs(home) {
187
+ const roots = [
188
+ path.join(home, '.fnm', 'node-versions'),
189
+ path.join(home, 'Library', 'Application Support', 'fnm', 'node-versions'),
190
+ ];
191
+ const dirs = [];
192
+ for (const root of roots) {
193
+ let versions;
194
+ try {
195
+ versions = fs.readdirSync(root);
196
+ }
197
+ catch {
198
+ continue;
199
+ }
200
+ dirs.push(...sortVersionNamesDesc(versions).map((version) => path.join(root, version, 'installation', 'bin')));
201
+ }
202
+ return dirs;
203
+ }
204
+ function sortVersionNamesDesc(values) {
205
+ return [...values].sort((a, b) => compareVersionName(b, a));
206
+ }
207
+ function compareVersionName(a, b) {
208
+ const av = parseVersionName(a);
209
+ const bv = parseVersionName(b);
210
+ const max = Math.max(av.length, bv.length);
211
+ for (let i = 0; i < max; i += 1) {
212
+ const diff = (av[i] ?? 0) - (bv[i] ?? 0);
213
+ if (diff !== 0)
214
+ return diff;
215
+ }
216
+ return a.localeCompare(b);
217
+ }
218
+ function parseVersionName(value) {
219
+ return value
220
+ .replace(/^v/i, '')
221
+ .split('.')
222
+ .map((part) => Number.parseInt(part, 10))
223
+ .filter((part) => Number.isFinite(part));
224
+ }
225
+ function splitPath(value) {
226
+ return value?.split(path.delimiter).filter(Boolean) ?? [];
227
+ }
228
+ function mergePath(prependDirs, existing) {
229
+ return unique([...prependDirs, ...splitPath(existing)]).join(path.delimiter);
230
+ }
231
+ function anchorResolvedPath(pathValue, resolution) {
232
+ return mergePath([path.dirname(resolution.binaryPath), ...splitPath(resolution.pathValue)], pathValue);
233
+ }
234
+ function commandCandidates(command, env) {
235
+ if (process.platform !== 'win32')
236
+ return [command];
237
+ const hasExt = /\.[^\\/]+$/.test(command);
238
+ if (hasExt)
239
+ return [command];
240
+ const exts = (env.PATHEXT || '.EXE;.CMD;.BAT;.COM')
241
+ .split(';')
242
+ .filter(Boolean)
243
+ .map((ext) => ext.toLowerCase());
244
+ return [command, ...exts.map((ext) => `${command}${ext}`)];
245
+ }
246
+ function getCachedResolution(cacheKey) {
247
+ const entry = resolutionCache.get(cacheKey);
248
+ if (!entry)
249
+ return null;
250
+ if (entry.expiresAt <= Date.now()) {
251
+ resolutionCache.delete(cacheKey);
252
+ return null;
253
+ }
254
+ return entry.value;
255
+ }
256
+ function setCachedResolution(cacheKey, value) {
257
+ resolutionCache.set(cacheKey, { value, expiresAt: Date.now() + RESOLUTION_CACHE_TTL_MS });
258
+ }
259
+ function isExecutable(file) {
260
+ try {
261
+ const stat = fs.statSync(file);
262
+ if (!stat.isFile())
263
+ return false;
264
+ fs.accessSync(file, fs.constants.X_OK);
265
+ return true;
266
+ }
267
+ catch {
268
+ return false;
269
+ }
270
+ }
271
+ function isDirectory(dir) {
272
+ try {
273
+ return fs.statSync(dir).isDirectory();
274
+ }
275
+ catch {
276
+ return false;
277
+ }
278
+ }
279
+ function unique(values) {
280
+ const seen = new Set();
281
+ const out = [];
282
+ for (const value of values) {
283
+ if (!value || seen.has(value))
284
+ continue;
285
+ seen.add(value);
286
+ out.push(value);
287
+ }
288
+ return out;
289
+ }
290
+ function shellQuote(value) {
291
+ return `'${value.replaceAll("'", "'\\''")}'`;
292
+ }
@@ -1,7 +1,7 @@
1
1
  import { type GatewayLogger } from '@parall/agent-core';
2
- import { ParallClient } from '@parall/sdk';
3
- import type { DaemonUpdater } from './updater.js';
2
+ import { type ParallClient } from '@parall/sdk';
4
3
  import { type ClaudeDaemonConfig } from './config.js';
4
+ import type { DaemonUpdater } from './updater.js';
5
5
  /**
6
6
  * Sleep that wakes early on abort. Returns true if the full delay elapsed,
7
7
  * false if aborted. Used by bootstrap retry and the outer keepalive in
@@ -27,6 +27,7 @@ export declare class DaemonSupervisor {
27
27
  private readonly children;
28
28
  private readonly spawningAgents;
29
29
  private readonly pendingWorkspaceSetup;
30
+ private readonly browserProfileLifecycleQueues;
30
31
  private readonly workspaceSetupRetryTimers;
31
32
  private readonly cancelledSpawns;
32
33
  private ws;
@@ -34,11 +35,19 @@ export declare class DaemonSupervisor {
34
35
  private machineId;
35
36
  private machineOrgId;
36
37
  private machineLlmSource;
38
+ private machineProviderEnabled;
39
+ private machineClipProviderUrl;
40
+ private connectedClipServiceUrl;
37
41
  private stopResolve;
38
42
  private updater;
39
43
  private healthConfirmed;
44
+ private browserProfileManager;
40
45
  private clipManager;
41
46
  private clipProvider;
47
+ private clipReconcileTimer;
48
+ private clipReconcileInFlight;
49
+ private hubClient;
50
+ private hubClientUrl;
42
51
  constructor(config: ClaudeDaemonConfig, client: ParallClient, log: GatewayLogger);
43
52
  setUpdater(updater: DaemonUpdater): void;
44
53
  /** Start the supervisor. Returns a promise that resolves on `stop()`. */
@@ -47,6 +56,7 @@ export declare class DaemonSupervisor {
47
56
  stop(): Promise<void>;
48
57
  private bootstrapWithRetry;
49
58
  private fullReconcile;
59
+ private reconcileBrowserProfiles;
50
60
  /**
51
61
  * Detects a legacy flat state layout (no agents/ subdir) and migrates it
52
62
  * into the per-agent directory for the owning agent. Ownership is determined
@@ -57,12 +67,51 @@ export declare class DaemonSupervisor {
57
67
  private handleAgentAttached;
58
68
  private handleAgentDetached;
59
69
  private handleFilesystemBrowse;
60
- private handleClipInstall;
61
- private reconcileClipInstalls;
70
+ private handleBrowserProfileLifecycle;
71
+ private enqueueBrowserProfileLifecycle;
72
+ private handleClipSync;
73
+ private reconcileMachineClips;
74
+ private reconcileMachineClipsNow;
75
+ private startClipReconcileTimer;
76
+ private stopClipReconcileTimer;
77
+ private machineClipToConfig;
78
+ private manifestFromMachineClip;
79
+ private dependencyMap;
80
+ private clipConfigSignature;
81
+ private ensureClipInstalled;
82
+ private readInstalledClipVersion;
83
+ private reconnectClipProvider;
62
84
  private handleWorkspaceSetupRequested;
63
85
  private scheduleWorkspaceSetupRetry;
64
86
  private clearWorkspaceSetupRetry;
65
87
  private refreshMachineConfig;
88
+ /**
89
+ * Resolve the ProviderStream endpoint the daemon registers clips against.
90
+ * Priority: PRLL_CLIP_SERVICE_URL (hosted/cluster DNS or explicit operator
91
+ * override) > machine.clip_provider_url (server-delivered grey-cloud
92
+ * clip-rpc host for BYOC) > config.apiUrl (legacy fallback for servers
93
+ * predating clip_provider_url). The grey-cloud host bypasses Cloudflare's
94
+ * proxy, which does not pass Connect-RPC bidi streams (#1430).
95
+ */
96
+ private resolveClipServiceUrl;
97
+ /**
98
+ * Execution-side hub client used to resolve a Clip's dependency
99
+ * binding (GetBindings) and forward the dependency invoke (Invoke). It targets
100
+ * the same grey-cloud clip-rpc endpoint as the provider stream and auths with
101
+ * the daemon's mck_ (the hub scope-gates calls to instances this machine
102
+ * executes). Rebuilt transparently when the resolved endpoint changes.
103
+ */
104
+ private getHubClient;
105
+ /**
106
+ * Connect, reconnect, or disconnect the clip Provider to match
107
+ * machineProviderEnabled and the resolved ProviderStream endpoint. An org
108
+ * admin toggles provider_enabled to withdraw the machine from the org clip
109
+ * provider pool without uninstalling clips; a changed clip_provider_url
110
+ * triggers a transparent reconnect to the new endpoint. No-op when the clip
111
+ * runtime is disabled or identity is not yet resolved. See
112
+ * docs/engineering-design/clip-provider-sharing-design.md.
113
+ */
114
+ private applyClipProviderState;
66
115
  private respawnAllChildren;
67
116
  private restartChildNow;
68
117
  private spawnAgent;
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"supervisor.d.ts","sourceRoot":"","sources":["../src/supervisor.ts"],"names":[],"mappings":"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"}