@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.
Files changed (53) hide show
  1. package/bundle/manifest.json +17 -11
  2. package/bundle/package.json +1 -0
  3. package/bundle/parall-claude-agent.js +27671 -337
  4. package/bundle/parall-codex-agent.js +27715 -375
  5. package/bundle/parall-daemon.js +30421 -1355
  6. package/bundle/parall-openclaw-agent.js +51 -26
  7. package/dist/cli.d.ts +1 -1
  8. package/dist/cli.d.ts.map +1 -1
  9. package/dist/cli.js +122 -72
  10. package/dist/clip-runtime/clip-installer.d.ts +44 -0
  11. package/dist/clip-runtime/clip-installer.d.ts.map +1 -0
  12. package/dist/clip-runtime/clip-installer.js +501 -0
  13. package/dist/clip-runtime/clip-provider.d.ts +76 -0
  14. package/dist/clip-runtime/clip-provider.d.ts.map +1 -0
  15. package/dist/clip-runtime/clip-provider.js +402 -0
  16. package/dist/clip-runtime/index.d.ts +7 -0
  17. package/dist/clip-runtime/index.d.ts.map +1 -0
  18. package/dist/clip-runtime/index.js +5 -0
  19. package/dist/clip-runtime/ipc.d.ts +94 -0
  20. package/dist/clip-runtime/ipc.d.ts.map +1 -0
  21. package/dist/clip-runtime/ipc.js +98 -0
  22. package/dist/clip-runtime/manifest.d.ts +74 -0
  23. package/dist/clip-runtime/manifest.d.ts.map +1 -0
  24. package/dist/clip-runtime/manifest.js +181 -0
  25. package/dist/clip-runtime/process-manager.d.ts +57 -0
  26. package/dist/clip-runtime/process-manager.d.ts.map +1 -0
  27. package/dist/clip-runtime/process-manager.js +354 -0
  28. package/dist/clip-runtime/process.d.ts +59 -0
  29. package/dist/clip-runtime/process.d.ts.map +1 -0
  30. package/dist/clip-runtime/process.js +350 -0
  31. package/dist/config.d.ts +13 -0
  32. package/dist/config.d.ts.map +1 -1
  33. package/dist/config.js +36 -19
  34. package/dist/filesystem.d.ts +1 -1
  35. package/dist/filesystem.d.ts.map +1 -1
  36. package/dist/filesystem.js +51 -53
  37. package/dist/index.js +46 -14
  38. package/dist/runtimes.d.ts +10 -8
  39. package/dist/runtimes.d.ts.map +1 -1
  40. package/dist/runtimes.js +63 -95
  41. package/dist/supervisor.d.ts +12 -3
  42. package/dist/supervisor.d.ts.map +1 -1
  43. package/dist/supervisor.js +272 -71
  44. package/dist/updater-manifest.d.ts +41 -0
  45. package/dist/updater-manifest.d.ts.map +1 -0
  46. package/dist/updater-manifest.js +94 -0
  47. package/dist/updater.d.ts +60 -0
  48. package/dist/updater.d.ts.map +1 -0
  49. package/dist/updater.js +427 -0
  50. package/dist/workspace.d.ts +2 -2
  51. package/dist/workspace.d.ts.map +1 -1
  52. package/dist/workspace.js +112 -112
  53. package/package.json +6 -6
package/dist/workspace.js CHANGED
@@ -1,8 +1,8 @@
1
- import { spawn } from "node:child_process";
2
- import { createHash } from "node:crypto";
3
- import * as fs from "node:fs";
4
- import * as path from "node:path";
5
- import { clearAllProviderCreds } from "./runtimes.js";
1
+ import { spawn } from 'node:child_process';
2
+ import { createHash } from 'node:crypto';
3
+ import * as fs from 'node:fs';
4
+ import * as path from 'node:path';
5
+ import { clearAllProviderCreds } from './runtimes.js';
6
6
  const OUTPUT_TAIL_LIMIT = 32 * 1024;
7
7
  const DEFAULT_SETUP_TIMEOUT_SEC = 600;
8
8
  export async function prepareWorkspace(opts) {
@@ -13,7 +13,7 @@ export async function prepareWorkspace(opts) {
13
13
  return plan.workspaceDir;
14
14
  }
15
15
  let forceSetup = false;
16
- if (prior?.status === "ready" && prior.config_hash === plan.configHash) {
16
+ if (prior?.status === 'ready' && prior.config_hash === plan.configHash) {
17
17
  if (await verifyExistingWorkspace(plan, opts.log)) {
18
18
  return plan.workspaceDir;
19
19
  }
@@ -21,9 +21,9 @@ export async function prepareWorkspace(opts) {
21
21
  }
22
22
  await opts.client.reportAgentWorkspaceState(opts.agentId, {
23
23
  config_hash: plan.configHash,
24
- status: "preparing",
24
+ status: 'preparing',
25
25
  });
26
- let outputTail = "";
26
+ let outputTail = '';
27
27
  try {
28
28
  await ensureWorkspace(plan, opts.log);
29
29
  if (shouldRunSetup(plan.workspace.setup, prior, plan.configHash, forceSetup)) {
@@ -31,19 +31,21 @@ export async function prepareWorkspace(opts) {
31
31
  }
32
32
  await opts.client.reportAgentWorkspaceState(opts.agentId, {
33
33
  config_hash: plan.configHash,
34
- status: "ready",
34
+ status: 'ready',
35
35
  output_tail: outputTail || null,
36
36
  });
37
37
  return plan.workspaceDir;
38
38
  }
39
39
  catch (err) {
40
40
  const message = err instanceof Error ? err.message : String(err);
41
- await opts.client.reportAgentWorkspaceState(opts.agentId, {
41
+ await opts.client
42
+ .reportAgentWorkspaceState(opts.agentId, {
42
43
  config_hash: plan.configHash,
43
- status: "failed",
44
+ status: 'failed',
44
45
  last_error: message,
45
46
  output_tail: outputTail || null,
46
- }).catch((reportErr) => {
47
+ })
48
+ .catch((reportErr) => {
47
49
  opts.log.warn(`workspace state report failed after setup error: ${String(reportErr)}`);
48
50
  });
49
51
  throw err;
@@ -56,19 +58,17 @@ function buildWorkspacePlan(input, defaultWorkspaceDir, serverConfigHash) {
56
58
  // The server is the source of truth for config_hash. Go and TypeScript JSON
57
59
  // normalization can differ in harmless ways (field order, omitted defaults),
58
60
  // so use the server-computed pending/ready row hash whenever it is present.
59
- const configHash = serverConfigHash || createHash("sha256")
60
- .update(JSON.stringify(config))
61
- .digest("hex");
61
+ const configHash = serverConfigHash || createHash('sha256').update(JSON.stringify(config)).digest('hex');
62
62
  return { config, workspace, workspaceDir, defaultWorkspaceDir, customWorkspaceField, configHash };
63
63
  }
64
64
  function normalizeConfig(input, defaultWorkspaceDir) {
65
65
  const cfg = input ? JSON.parse(JSON.stringify(input)) : {};
66
66
  cfg.workspace_path = cfg.workspace_path?.trim() || undefined;
67
67
  if (!cfg.workspace && cfg.workspace_path) {
68
- cfg.workspace = { mode: "local_path", path: cfg.workspace_path };
68
+ cfg.workspace = { mode: 'local_path', path: cfg.workspace_path };
69
69
  }
70
70
  if (!cfg.workspace) {
71
- cfg.workspace = { mode: "default" };
71
+ cfg.workspace = { mode: 'default' };
72
72
  }
73
73
  const ws = cfg.workspace;
74
74
  ws.mode = (ws.mode?.trim() || undefined);
@@ -78,26 +78,26 @@ function normalizeConfig(input, defaultWorkspaceDir) {
78
78
  ws.git.ref = ws.git.ref?.trim() || undefined;
79
79
  ws.git.target_path = ws.git.target_path?.trim() || undefined;
80
80
  }
81
- ws.mode ||= ws.git ? "git" : ws.path ? "local_path" : "default";
82
- if (ws.mode === "local_path" && !ws.path) {
83
- ws.mode = "default";
81
+ ws.mode ||= ws.git ? 'git' : ws.path ? 'local_path' : 'default';
82
+ if (ws.mode === 'local_path' && !ws.path) {
83
+ ws.mode = 'default';
84
84
  }
85
- if (ws.mode === "git") {
85
+ if (ws.mode === 'git') {
86
86
  ws.git ||= {};
87
87
  if (!ws.git.target_path && ws.path) {
88
88
  ws.git.target_path = ws.path;
89
89
  }
90
90
  }
91
- if (ws.mode === "default") {
91
+ if (ws.mode === 'default') {
92
92
  ws.path = undefined;
93
93
  ws.git = undefined;
94
94
  }
95
- if (ws.mode === "local_path") {
95
+ if (ws.mode === 'local_path') {
96
96
  ws.git = undefined;
97
97
  }
98
98
  if (ws.setup) {
99
99
  ws.setup.command = ws.setup.command?.trim();
100
- ws.setup.run_on ||= "first_attach";
100
+ ws.setup.run_on ||= 'first_attach';
101
101
  if (!ws.setup.command) {
102
102
  ws.setup = undefined;
103
103
  }
@@ -108,19 +108,19 @@ function normalizeConfig(input, defaultWorkspaceDir) {
108
108
  return cfg;
109
109
  }
110
110
  function resolveWorkspaceDir(workspace, defaultWorkspaceDir) {
111
- if (workspace.mode === "local_path") {
111
+ if (workspace.mode === 'local_path') {
112
112
  if (!workspace.path)
113
113
  return { workspaceDir: defaultWorkspaceDir };
114
114
  return {
115
- workspaceDir: requireAbsolute(workspace.path, "workspace.path"),
116
- customWorkspaceField: "workspace.path",
115
+ workspaceDir: requireAbsolute(workspace.path, 'workspace.path'),
116
+ customWorkspaceField: 'workspace.path',
117
117
  };
118
118
  }
119
- if (workspace.mode === "git") {
119
+ if (workspace.mode === 'git') {
120
120
  return workspace.git?.target_path
121
121
  ? {
122
- workspaceDir: requireAbsolute(workspace.git.target_path, "workspace.git.target_path"),
123
- customWorkspaceField: "workspace.git.target_path",
122
+ workspaceDir: requireAbsolute(workspace.git.target_path, 'workspace.git.target_path'),
123
+ customWorkspaceField: 'workspace.git.target_path',
124
124
  }
125
125
  : { workspaceDir: defaultWorkspaceDir };
126
126
  }
@@ -128,19 +128,19 @@ function resolveWorkspaceDir(workspace, defaultWorkspaceDir) {
128
128
  }
129
129
  async function ensureWorkspace(plan, log) {
130
130
  const ws = plan.workspace;
131
- if (ws.mode === "default") {
131
+ if (ws.mode === 'default') {
132
132
  fs.mkdirSync(plan.workspaceDir, { recursive: true });
133
133
  assertWritableWorkspaceDir(plan.workspaceDir);
134
134
  return;
135
135
  }
136
- if (ws.mode === "local_path") {
136
+ if (ws.mode === 'local_path') {
137
137
  assertSafeCustomWorkspacePath(plan);
138
138
  let st;
139
139
  try {
140
140
  st = fs.statSync(plan.workspaceDir);
141
141
  }
142
142
  catch (err) {
143
- if (isNodeError(err) && err.code === "ENOENT") {
143
+ if (isNodeError(err) && err.code === 'ENOENT') {
144
144
  throw new Error(`workspace path does not exist: ${plan.workspaceDir}`);
145
145
  }
146
146
  throw err;
@@ -152,17 +152,17 @@ async function ensureWorkspace(plan, log) {
152
152
  assertWritableWorkspaceDir(plan.workspaceDir);
153
153
  return;
154
154
  }
155
- if (ws.mode === "git") {
155
+ if (ws.mode === 'git') {
156
156
  const remote = ws.git?.remote?.trim();
157
157
  if (!remote)
158
- throw new Error("workspace git remote is required");
158
+ throw new Error('workspace git remote is required');
159
159
  if (plan.customWorkspaceField) {
160
160
  assertSafeCustomWorkspacePath(plan);
161
161
  }
162
162
  if (!fs.existsSync(plan.workspaceDir)) {
163
163
  fs.mkdirSync(path.dirname(plan.workspaceDir), { recursive: true });
164
164
  assertWritableWorkspaceDir(path.dirname(plan.workspaceDir));
165
- await runCommand("git", ["clone", remote, plan.workspaceDir], process.cwd());
165
+ await runCommand('git', ['clone', remote, plan.workspaceDir], process.cwd());
166
166
  }
167
167
  else {
168
168
  const st = fs.statSync(plan.workspaceDir);
@@ -177,17 +177,17 @@ async function ensureWorkspace(plan, log) {
177
177
  await ensureGitRemote(plan.workspaceDir, remote);
178
178
  }
179
179
  if (ws.git?.ref) {
180
- const dirty = await commandOutput("git", ["status", "--porcelain"], plan.workspaceDir);
180
+ const dirty = await commandOutput('git', ['status', '--porcelain'], plan.workspaceDir);
181
181
  if (dirty.trim()) {
182
182
  throw new Error(`workspace git tree has local changes; refusing checkout: ${plan.workspaceDir}`);
183
183
  }
184
- await runCommand("git", ["fetch", "origin", "--prune"], plan.workspaceDir);
184
+ await runCommand('git', ['fetch', 'origin', '--prune'], plan.workspaceDir);
185
185
  await checkoutGitRef(plan.workspaceDir, ws.git.ref);
186
186
  }
187
187
  log.info(`workspace ready: git ${remote} -> ${plan.workspaceDir}`);
188
188
  return;
189
189
  }
190
- throw new Error(`unsupported workspace mode: ${ws.mode ?? "(empty)"}`);
190
+ throw new Error(`unsupported workspace mode: ${ws.mode ?? '(empty)'}`);
191
191
  }
192
192
  async function verifyExistingWorkspace(plan, log) {
193
193
  try {
@@ -203,14 +203,14 @@ async function verifyExistingWorkspace(plan, log) {
203
203
  assertSafeCustomWorkspacePath(plan, fs.realpathSync(plan.workspaceDir));
204
204
  }
205
205
  assertWritableWorkspaceDir(plan.workspaceDir);
206
- if (plan.workspace.mode === "git") {
206
+ if (plan.workspace.mode === 'git') {
207
207
  await ensureGitWorktree(plan.workspaceDir);
208
208
  const remote = plan.workspace.git?.remote?.trim();
209
209
  if (remote) {
210
210
  await ensureGitRemote(plan.workspaceDir, remote);
211
211
  }
212
212
  if (plan.workspace.git?.ref) {
213
- const head = (await commandOutput("git", ["rev-parse", "HEAD"], plan.workspaceDir)).trim();
213
+ const head = (await commandOutput('git', ['rev-parse', 'HEAD'], plan.workspaceDir)).trim();
214
214
  const expected = await resolveConfiguredGitRef(plan.workspaceDir, plan.workspace.git.ref);
215
215
  if (head !== expected) {
216
216
  log.warn(`workspace ready state ignored: git HEAD ${head} does not match ${plan.workspace.git.ref} (${expected})`);
@@ -226,13 +226,13 @@ async function verifyExistingWorkspace(plan, log) {
226
226
  }
227
227
  }
228
228
  async function ensureGitWorktree(cwd) {
229
- const result = await commandOutput("git", ["rev-parse", "--is-inside-work-tree"], cwd);
230
- if (result.trim() !== "true") {
229
+ const result = await commandOutput('git', ['rev-parse', '--is-inside-work-tree'], cwd);
230
+ if (result.trim() !== 'true') {
231
231
  throw new Error(`workspace path exists but is not a git worktree: ${cwd}`);
232
232
  }
233
233
  }
234
234
  async function ensureGitRemote(cwd, expectedRemote) {
235
- const actualRemote = (await commandOutput("git", ["remote", "get-url", "origin"], cwd)).trim();
235
+ const actualRemote = (await commandOutput('git', ['remote', 'get-url', 'origin'], cwd)).trim();
236
236
  if (actualRemote !== expectedRemote) {
237
237
  throw new Error(`workspace git remote mismatch: expected ${expectedRemote}, got ${actualRemote}`);
238
238
  }
@@ -240,23 +240,23 @@ async function ensureGitRemote(cwd, expectedRemote) {
240
240
  async function checkoutGitRef(cwd, ref) {
241
241
  const remoteCommit = await resolveRemoteGitRef(cwd, ref);
242
242
  if (remoteCommit) {
243
- await runCommand("git", ["checkout", "-B", ref, remoteCommit], cwd);
243
+ await runCommand('git', ['checkout', '-B', ref, remoteCommit], cwd);
244
244
  return;
245
245
  }
246
246
  const targetCommit = await resolveGitCommit(cwd, ref);
247
- await runCommand("git", ["checkout", "--detach", targetCommit], cwd);
247
+ await runCommand('git', ['checkout', '--detach', targetCommit], cwd);
248
248
  }
249
249
  async function resolveConfiguredGitRef(cwd, ref) {
250
250
  const remote = await resolveRemoteGitRef(cwd, ref);
251
- return remote || await resolveGitCommit(cwd, ref);
251
+ return remote || (await resolveGitCommit(cwd, ref));
252
252
  }
253
253
  async function resolveRemoteGitRef(cwd, ref) {
254
- return (await tryGitOutput("git", ["rev-parse", "--verify", `refs/remotes/origin/${ref}^{commit}`], cwd)).trim();
254
+ return (await tryGitOutput('git', ['rev-parse', '--verify', `refs/remotes/origin/${ref}^{commit}`], cwd)).trim();
255
255
  }
256
256
  async function resolveGitCommit(cwd, ref) {
257
257
  const candidates = [`refs/tags/${ref}^{commit}`, `${ref}^{commit}`];
258
258
  for (const candidate of candidates) {
259
- const commit = await tryGitOutput("git", ["rev-parse", "--verify", candidate], cwd);
259
+ const commit = await tryGitOutput('git', ['rev-parse', '--verify', candidate], cwd);
260
260
  if (commit.trim()) {
261
261
  return commit.trim();
262
262
  }
@@ -268,14 +268,14 @@ function shouldRunSetup(setup, prior, configHash, forceSetup = false) {
268
268
  return false;
269
269
  if (forceSetup)
270
270
  return true;
271
- if (setup.run_on === "config_change") {
272
- return prior?.config_hash !== configHash || prior.status === "pending" || prior.status === "failed";
271
+ if (setup.run_on === 'config_change') {
272
+ return (prior?.config_hash !== configHash || prior.status === 'pending' || prior.status === 'failed');
273
273
  }
274
- return prior?.status !== "ready" || !prior.prepared_at;
274
+ return prior?.status !== 'ready' || !prior.prepared_at;
275
275
  }
276
276
  async function runSetup(cwd, command, timeoutSec) {
277
277
  const effectiveTimeoutSec = timeoutSec && timeoutSec > 0 ? timeoutSec : DEFAULT_SETUP_TIMEOUT_SEC;
278
- return runCommand(process.env.SHELL || "/bin/sh", ["-lc", command], cwd, effectiveTimeoutSec * 1000, scrubSetupEnv());
278
+ return runCommand(process.env.SHELL || '/bin/sh', ['-lc', command], cwd, effectiveTimeoutSec * 1000, scrubSetupEnv());
279
279
  }
280
280
  function scrubSetupEnv() {
281
281
  const env = { ...process.env };
@@ -291,12 +291,12 @@ async function tryGitOutput(cmd, args, cwd) {
291
291
  return await runCommand(cmd, args, cwd);
292
292
  }
293
293
  catch {
294
- return "";
294
+ return '';
295
295
  }
296
296
  }
297
297
  function runCommand(cmd, args, cwd, timeoutMs = 120_000, env = process.env) {
298
298
  return new Promise((resolve, reject) => {
299
- let tail = "";
299
+ let tail = '';
300
300
  let timedOut = false;
301
301
  let settled = false;
302
302
  let timeoutTimer = null;
@@ -317,29 +317,29 @@ function runCommand(cmd, args, cwd, timeoutMs = 120_000, env = process.env) {
317
317
  clearTimeout(killTimer);
318
318
  fn();
319
319
  };
320
- const child = spawn(cmd, args, { cwd, env, stdio: ["ignore", "pipe", "pipe"] });
320
+ const child = spawn(cmd, args, { cwd, env, stdio: ['ignore', 'pipe', 'pipe'] });
321
321
  timeoutTimer = setTimeout(() => {
322
322
  timedOut = true;
323
- child.kill("SIGTERM");
323
+ child.kill('SIGTERM');
324
324
  killTimer = setTimeout(() => {
325
- child.kill("SIGKILL");
325
+ child.kill('SIGKILL');
326
326
  }, 5_000);
327
327
  }, timeoutMs);
328
- child.stdout?.on("data", append);
329
- child.stderr?.on("data", append);
330
- child.once("error", (err) => {
328
+ child.stdout?.on('data', append);
329
+ child.stderr?.on('data', append);
330
+ child.once('error', (err) => {
331
331
  settle(() => reject(err));
332
332
  });
333
- child.once("close", (code, signal) => {
333
+ child.once('close', (code, signal) => {
334
334
  if (timedOut) {
335
- settle(() => reject(new Error(`command timed out after ${timeoutMs}ms: ${cmd} ${args.join(" ")}\n${tail}`)));
335
+ settle(() => reject(new Error(`command timed out after ${timeoutMs}ms: ${cmd} ${args.join(' ')}\n${tail}`)));
336
336
  return;
337
337
  }
338
338
  if (code === 0) {
339
339
  settle(() => resolve(tail));
340
340
  }
341
341
  else {
342
- settle(() => reject(new Error(`command failed (${code ?? signal}): ${cmd} ${args.join(" ")}\n${tail}`)));
342
+ settle(() => reject(new Error(`command failed (${code ?? signal}): ${cmd} ${args.join(' ')}\n${tail}`)));
343
343
  }
344
344
  });
345
345
  });
@@ -366,75 +366,75 @@ function assertSafeCustomWorkspacePath(plan, candidate = plan.workspaceDir) {
366
366
  function assertWritableWorkspaceDir(dir) {
367
367
  fs.accessSync(dir, fs.constants.R_OK | fs.constants.W_OK | fs.constants.X_OK);
368
368
  const probe = path.join(dir, `.parall-workspace-check-${process.pid}-${Date.now()}`);
369
- const fd = fs.openSync(probe, "wx", 0o600);
369
+ const fd = fs.openSync(probe, 'wx', 0o600);
370
370
  fs.closeSync(fd);
371
371
  fs.unlinkSync(probe);
372
372
  }
373
373
  function workspacePathDenyReason(value) {
374
- if (value === "/")
375
- return "the filesystem root";
376
- if (["/tmp", "/private/tmp", "/var/tmp", "/Users", "/home"].includes(value)) {
377
- return "a shared or home root directory";
374
+ if (value === '/')
375
+ return 'the filesystem root';
376
+ if (['/tmp', '/private/tmp', '/var/tmp', '/Users', '/home'].includes(value)) {
377
+ return 'a shared or home root directory';
378
378
  }
379
379
  for (const root of [
380
- "/Applications",
381
- "/bin",
382
- "/boot",
383
- "/dev",
384
- "/etc",
385
- "/Library",
386
- "/private/etc",
387
- "/private/var/db",
388
- "/proc",
389
- "/root",
390
- "/run",
391
- "/sbin",
392
- "/System",
393
- "/sys",
394
- "/usr",
395
- "/var/db",
396
- "/var/root",
380
+ '/Applications',
381
+ '/bin',
382
+ '/boot',
383
+ '/dev',
384
+ '/etc',
385
+ '/Library',
386
+ '/private/etc',
387
+ '/private/var/db',
388
+ '/proc',
389
+ '/root',
390
+ '/run',
391
+ '/sbin',
392
+ '/System',
393
+ '/sys',
394
+ '/usr',
395
+ '/var/db',
396
+ '/var/root',
397
397
  ]) {
398
398
  if (value === root || value.startsWith(`${root}/`)) {
399
- return "a system directory";
399
+ return 'a system directory';
400
400
  }
401
401
  }
402
- const parts = value.split("/").filter(Boolean);
403
- if (parts.includes(".git"))
404
- return "a git metadata directory";
405
- if (parts.length === 2 && (parts[0] === "Users" || parts[0] === "home")) {
406
- return "a home directory";
402
+ const parts = value.split('/').filter(Boolean);
403
+ if (parts.includes('.git'))
404
+ return 'a git metadata directory';
405
+ if (parts.length === 2 && (parts[0] === 'Users' || parts[0] === 'home')) {
406
+ return 'a home directory';
407
407
  }
408
- if (parts.length >= 3 && (parts[0] === "Users" || parts[0] === "home")) {
408
+ if (parts.length >= 3 && (parts[0] === 'Users' || parts[0] === 'home')) {
409
409
  const homeChild = parts[2];
410
410
  if ([
411
- ".aws",
412
- ".azure",
413
- ".claude",
414
- ".codex",
415
- ".config",
416
- ".docker",
417
- ".gnupg",
418
- ".kube",
419
- ".local",
420
- ".npm",
421
- ".ssh",
422
- ".parall-agent",
423
- ".parall-daemon",
424
- "Library",
411
+ '.aws',
412
+ '.azure',
413
+ '.claude',
414
+ '.codex',
415
+ '.config',
416
+ '.docker',
417
+ '.gnupg',
418
+ '.kube',
419
+ '.local',
420
+ '.npm',
421
+ '.ssh',
422
+ '.parall-agent',
423
+ '.parall-daemon',
424
+ 'Library',
425
425
  ].includes(homeChild)) {
426
- return "a credential or application state directory";
426
+ return 'a credential or application state directory';
427
427
  }
428
428
  }
429
- return "";
429
+ return '';
430
430
  }
431
431
  function isAncestorPath(parent, child) {
432
432
  const relative = path.relative(parent, child);
433
- return relative !== "" && !relative.startsWith("..") && !path.isAbsolute(relative);
433
+ return relative !== '' && !relative.startsWith('..') && !path.isAbsolute(relative);
434
434
  }
435
435
  function toPolicyPath(value) {
436
- return path.resolve(value).split(path.sep).join("/");
436
+ return path.resolve(value).split(path.sep).join('/');
437
437
  }
438
438
  function isNodeError(err) {
439
- return err instanceof Error && "code" in err;
439
+ return err instanceof Error && 'code' in err;
440
440
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parall/daemon",
3
- "version": "1.30.0",
3
+ "version": "1.32.0",
4
4
  "description": "Parall local agent runtime — daemon supervisor + bridge runtimes, bundled as standalone JS files",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -29,11 +29,11 @@
29
29
  "dist"
30
30
  ],
31
31
  "dependencies": {
32
- "@parall/agent-core": "1.30.0",
33
- "@parall/sdk": "1.30.0",
34
- "@parall/claude-agent": "1.30.0",
35
- "@parall/codex-agent": "1.30.0",
36
- "@parall/openclaw-agent": "1.30.0"
32
+ "@parall/agent-core": "1.32.0",
33
+ "@parall/claude-agent": "1.32.0",
34
+ "@parall/codex-agent": "1.32.0",
35
+ "@parall/openclaw-agent": "1.32.0",
36
+ "@parall/sdk": "1.32.0"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/node": "^22.0.0",