@parall/daemon 1.29.2 → 1.30.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 +8 -8
- package/bundle/parall-claude-agent.js +122 -72
- package/bundle/parall-codex-agent.js +128 -83
- package/bundle/parall-daemon.js +261 -105
- package/dist/filesystem.d.ts +7 -0
- package/dist/filesystem.d.ts.map +1 -0
- package/dist/filesystem.js +118 -0
- package/dist/supervisor.d.ts +1 -0
- package/dist/supervisor.d.ts.map +1 -1
- package/dist/supervisor.js +30 -0
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +2 -1
- package/package.json +6 -6
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { FilesystemEntry } from "@parall/sdk";
|
|
2
|
+
export declare function browseDenyReason(value: string): string;
|
|
3
|
+
export declare function listDirectory(dirPath: string): Promise<{
|
|
4
|
+
entries: FilesystemEntry[];
|
|
5
|
+
error?: string;
|
|
6
|
+
}>;
|
|
7
|
+
//# sourceMappingURL=filesystem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesystem.d.ts","sourceRoot":"","sources":["../src/filesystem.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAqCnD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAkBtD;AAoBD,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,eAAe,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA8C5G"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import * as os from "os";
|
|
4
|
+
const MAX_ENTRIES = 200;
|
|
5
|
+
const SYSTEM_DIR_PREFIXES = [
|
|
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
|
+
];
|
|
22
|
+
const CREDENTIAL_DIR_NAMES = new Set([
|
|
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
|
+
]);
|
|
36
|
+
export function browseDenyReason(value) {
|
|
37
|
+
const normalized = path.resolve(value).split(path.sep).join("/");
|
|
38
|
+
if (normalized === "/")
|
|
39
|
+
return "";
|
|
40
|
+
for (const prefix of SYSTEM_DIR_PREFIXES) {
|
|
41
|
+
if (normalized === prefix || normalized.startsWith(`${prefix}/`)) {
|
|
42
|
+
return "a system directory";
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const parts = normalized.split("/").filter(Boolean);
|
|
46
|
+
for (const part of parts) {
|
|
47
|
+
if (CREDENTIAL_DIR_NAMES.has(part)) {
|
|
48
|
+
return "a credential or application state directory";
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return "";
|
|
52
|
+
}
|
|
53
|
+
function syntheticRoots() {
|
|
54
|
+
const roots = [];
|
|
55
|
+
const platform = os.platform();
|
|
56
|
+
const candidates = platform === "darwin"
|
|
57
|
+
? ["/Users", os.homedir()]
|
|
58
|
+
: ["/home", os.homedir()];
|
|
59
|
+
for (const dir of [...new Set(candidates)]) {
|
|
60
|
+
try {
|
|
61
|
+
fs.accessSync(dir, fs.constants.R_OK);
|
|
62
|
+
roots.push({ name: dir, type: "dir" });
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// not accessible
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return roots;
|
|
69
|
+
}
|
|
70
|
+
export async function listDirectory(dirPath) {
|
|
71
|
+
const resolved = path.resolve(dirPath);
|
|
72
|
+
const normalized = resolved.split(path.sep).join("/");
|
|
73
|
+
if (normalized === "/") {
|
|
74
|
+
return { entries: syntheticRoots() };
|
|
75
|
+
}
|
|
76
|
+
const deny = browseDenyReason(normalized);
|
|
77
|
+
if (deny) {
|
|
78
|
+
return { entries: [], error: `Access denied: ${deny}` };
|
|
79
|
+
}
|
|
80
|
+
let realPath;
|
|
81
|
+
try {
|
|
82
|
+
realPath = fs.realpathSync(resolved);
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
const code = err.code;
|
|
86
|
+
if (code === "ENOENT")
|
|
87
|
+
return { entries: [], error: "Directory not found" };
|
|
88
|
+
return { entries: [], error: "Permission denied" };
|
|
89
|
+
}
|
|
90
|
+
const realDeny = browseDenyReason(realPath.split(path.sep).join("/"));
|
|
91
|
+
if (realDeny) {
|
|
92
|
+
return { entries: [], error: `Access denied: ${realDeny}` };
|
|
93
|
+
}
|
|
94
|
+
let dirents;
|
|
95
|
+
try {
|
|
96
|
+
dirents = fs.readdirSync(realPath, { withFileTypes: true });
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
const code = err.code;
|
|
100
|
+
if (code === "ENOENT")
|
|
101
|
+
return { entries: [], error: "Directory not found" };
|
|
102
|
+
if (code === "EACCES" || code === "EPERM")
|
|
103
|
+
return { entries: [], error: "Permission denied" };
|
|
104
|
+
return { entries: [], error: `Failed to read directory: ${code ?? String(err)}` };
|
|
105
|
+
}
|
|
106
|
+
const entries = [];
|
|
107
|
+
for (const d of dirents) {
|
|
108
|
+
if (!d.isDirectory())
|
|
109
|
+
continue;
|
|
110
|
+
if (d.name.startsWith("."))
|
|
111
|
+
continue;
|
|
112
|
+
entries.push({ name: d.name, type: "dir" });
|
|
113
|
+
if (entries.length >= MAX_ENTRIES)
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
117
|
+
return { entries };
|
|
118
|
+
}
|
package/dist/supervisor.d.ts
CHANGED
|
@@ -49,6 +49,7 @@ export declare class DaemonSupervisor {
|
|
|
49
49
|
private fetchAttachedAgent;
|
|
50
50
|
private handleAgentAttached;
|
|
51
51
|
private handleAgentDetached;
|
|
52
|
+
private handleFilesystemBrowse;
|
|
52
53
|
private handleWorkspaceSetupRequested;
|
|
53
54
|
private scheduleWorkspaceSetupRetry;
|
|
54
55
|
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,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"supervisor.d.ts","sourceRoot":"","sources":["../src/supervisor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,YAAY,EAA6P,MAAM,aAAa,CAAC;AAEtS,OAAO,EACL,KAAK,kBAAkB,EAMxB,MAAM,aAAa,CAAC;AAiBrB;;;;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;IAazB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,GAAG;IAdtB,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,YAAY,CAAuB;IAC3C,OAAO,CAAC,gBAAgB,CAAoB;IAC5C,OAAO,CAAC,WAAW,CAA6B;gBAG7B,MAAM,EAAE,kBAAkB,EAC1B,MAAM,EAAE,YAAY,EACpB,GAAG,EAAE,aAAa;IAGrC,yEAAyE;IACnE,GAAG,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAsF7C,sEAAsE;IAChE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAiCb,kBAAkB;YAqClB,aAAa;IAqD3B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;YA6CX,kBAAkB;YAqBlB,mBAAmB;YAgBnB,mBAAmB;YAmBnB,sBAAsB;YAwBtB,6BAA6B;IAqC3C,OAAO,CAAC,2BAA2B;IAYnC,OAAO,CAAC,wBAAwB;YAUlB,oBAAoB;YAcpB,kBAAkB;YAYlB,eAAe;YAcf,UAAU;YAoBV,cAAc;IA2D5B,OAAO,CAAC,UAAU;YA0EJ,cAAc;IAyB5B,OAAO,CAAC,0BAA0B;CA8BnC"}
|
package/dist/supervisor.js
CHANGED
|
@@ -2,6 +2,7 @@ import { spawn } from "node:child_process";
|
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import { ParallWs } from "@parall/sdk";
|
|
5
|
+
import { listDirectory } from "./filesystem.js";
|
|
5
6
|
import { agentClaudeCredentialsFileFor, agentClaudeHomeFor, agentStateDirFor, agentWorkspaceDirFor, sharedClaudeCredentialsFileFor, } from "./config.js";
|
|
6
7
|
import { assertAgentKey, getRuntimeAdapter } from "./runtimes.js";
|
|
7
8
|
import { prepareWorkspace } from "./workspace.js";
|
|
@@ -117,6 +118,10 @@ export class DaemonSupervisor {
|
|
|
117
118
|
this.log.info(`WS: workspace setup requested for agent ${data.agent_id}`);
|
|
118
119
|
void this.handleWorkspaceSetupRequested(data.agent_id);
|
|
119
120
|
});
|
|
121
|
+
this.ws.on("machine.filesystem.browse", (data) => {
|
|
122
|
+
this.log.info(`WS: filesystem browse requested: ${data.path}`);
|
|
123
|
+
void this.handleFilesystemBrowse(data.request_id, data.path);
|
|
124
|
+
});
|
|
120
125
|
this.ws.on("machine.stop", (data) => {
|
|
121
126
|
this.log.info(`WS: machine.stop received (reason=${data.reason ?? "none"})`);
|
|
122
127
|
void this.stop();
|
|
@@ -343,6 +348,31 @@ export class DaemonSupervisor {
|
|
|
343
348
|
await this.terminateChild(state);
|
|
344
349
|
this.children.delete(agentId);
|
|
345
350
|
}
|
|
351
|
+
async handleFilesystemBrowse(requestId, dirPath) {
|
|
352
|
+
try {
|
|
353
|
+
const result = await listDirectory(dirPath);
|
|
354
|
+
await this.client.postBrowseResponse(requestId, {
|
|
355
|
+
request_id: requestId,
|
|
356
|
+
path: dirPath,
|
|
357
|
+
entries: result.entries,
|
|
358
|
+
error: result.error,
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
catch (err) {
|
|
362
|
+
this.log.warn(`filesystem browse failed: ${String(err)}`);
|
|
363
|
+
try {
|
|
364
|
+
await this.client.postBrowseResponse(requestId, {
|
|
365
|
+
request_id: requestId,
|
|
366
|
+
path: dirPath,
|
|
367
|
+
entries: [],
|
|
368
|
+
error: String(err),
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
catch {
|
|
372
|
+
// best-effort
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
346
376
|
async handleWorkspaceSetupRequested(agentId) {
|
|
347
377
|
if (this.spawningAgents.has(agentId)) {
|
|
348
378
|
this.log.info(`agent ${agentId}: workspace setup already in progress; queueing one restart`);
|
package/dist/workspace.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAA4C,YAAY,EAAE,MAAM,aAAa,CAAC;AAiBzG,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,YAAY,CAAC;IACrB,QAAQ,EAAE,aAAa,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,GAAG,EAAE,aAAa,CAAC;CACpB;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAA4C,YAAY,EAAE,MAAM,aAAa,CAAC;AAiBzG,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,YAAY,CAAC;IACrB,QAAQ,EAAE,aAAa,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,GAAG,EAAE,aAAa,CAAC;CACpB;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CA8ClF"}
|
package/dist/workspace.js
CHANGED
|
@@ -8,7 +8,8 @@ const DEFAULT_SETUP_TIMEOUT_SEC = 600;
|
|
|
8
8
|
export async function prepareWorkspace(opts) {
|
|
9
9
|
const prior = opts.attached.workspace_state;
|
|
10
10
|
const plan = buildWorkspacePlan(opts.attached.daemon_config, opts.defaultWorkspaceDir, prior?.config_hash);
|
|
11
|
-
|
|
11
|
+
const hasConfig = opts.attached.daemon_config && Object.keys(opts.attached.daemon_config).length > 0;
|
|
12
|
+
if (!hasConfig && !prior) {
|
|
12
13
|
return plan.workspaceDir;
|
|
13
14
|
}
|
|
14
15
|
let forceSetup = false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parall/daemon",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.30.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/
|
|
33
|
-
"@parall/
|
|
34
|
-
"@parall/claude-agent": "1.
|
|
35
|
-
"@parall/agent
|
|
36
|
-
"@parall/openclaw-agent": "1.
|
|
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"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@types/node": "^22.0.0",
|