crewx-bridge 0.1.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/LICENSE +21 -0
- package/README.md +102 -0
- package/dist/api.d.ts +16 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +157 -0
- package/dist/api.js.map +1 -0
- package/dist/config.d.ts +83 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +233 -0
- package/dist/config.js.map +1 -0
- package/dist/constants.d.ts +7 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +13 -0
- package/dist/constants.js.map +1 -0
- package/dist/daemon.d.ts +36 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +313 -0
- package/dist/daemon.js.map +1 -0
- package/dist/errors.d.ts +8 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +32 -0
- package/dist/errors.js.map +1 -0
- package/dist/folders.d.ts +13 -0
- package/dist/folders.d.ts.map +1 -0
- package/dist/folders.js +63 -0
- package/dist/folders.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +322 -0
- package/dist/index.js.map +1 -0
- package/dist/journal.d.ts +76 -0
- package/dist/journal.d.ts.map +1 -0
- package/dist/journal.js +106 -0
- package/dist/journal.js.map +1 -0
- package/dist/policy.d.ts +4 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +19 -0
- package/dist/policy.js.map +1 -0
- package/dist/service.d.ts +45 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +221 -0
- package/dist/service.js.map +1 -0
- package/dist/supervisor.d.ts +23 -0
- package/dist/supervisor.d.ts.map +1 -0
- package/dist/supervisor.js +149 -0
- package/dist/supervisor.js.map +1 -0
- package/package.json +52 -0
package/dist/service.js
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { unlink } from "node:fs/promises";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { promisify } from "node:util";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
import { bridgeStateDirectory, ensureSecureDirectory, writeSecureText, } from "./config.js";
|
|
8
|
+
import { BridgeError } from "./errors.js";
|
|
9
|
+
const execFileAsync = promisify(execFile);
|
|
10
|
+
function escapeXml(value) {
|
|
11
|
+
return value
|
|
12
|
+
.replaceAll("&", "&")
|
|
13
|
+
.replaceAll("<", "<")
|
|
14
|
+
.replaceAll(">", ">")
|
|
15
|
+
.replaceAll('"', """)
|
|
16
|
+
.replaceAll("'", "'");
|
|
17
|
+
}
|
|
18
|
+
function systemdQuote(value) {
|
|
19
|
+
if (/[\0\r\n]/.test(value)) {
|
|
20
|
+
throw new BridgeError("unsafe_service_path", "Service paths must not contain line breaks.");
|
|
21
|
+
}
|
|
22
|
+
return `"${value
|
|
23
|
+
.replaceAll("\\", "\\\\")
|
|
24
|
+
.replaceAll('"', '\\"')
|
|
25
|
+
.replaceAll("%", "%%")}"`;
|
|
26
|
+
}
|
|
27
|
+
function safePathEnvironment(value) {
|
|
28
|
+
if (/[\0\r\n]/.test(value)) {
|
|
29
|
+
throw new BridgeError("unsafe_service_path", "The service PATH must not contain control characters.");
|
|
30
|
+
}
|
|
31
|
+
return value;
|
|
32
|
+
}
|
|
33
|
+
export function bridgeServiceEntrypoint() {
|
|
34
|
+
return fileURLToPath(new URL("./index.js", import.meta.url));
|
|
35
|
+
}
|
|
36
|
+
export function launchdDefinition(options) {
|
|
37
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
38
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
39
|
+
<plist version="1.0">
|
|
40
|
+
<dict>
|
|
41
|
+
<key>Label</key>
|
|
42
|
+
<string>com.crewx.bridge</string>
|
|
43
|
+
<key>EnvironmentVariables</key>
|
|
44
|
+
<dict>
|
|
45
|
+
<key>PATH</key>
|
|
46
|
+
<string>${escapeXml(safePathEnvironment(options.pathEnvironment ?? "/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin"))}</string>
|
|
47
|
+
</dict>
|
|
48
|
+
<key>ProgramArguments</key>
|
|
49
|
+
<array>
|
|
50
|
+
<string>${escapeXml(options.nodePath)}</string>
|
|
51
|
+
<string>${escapeXml(options.entrypoint)}</string>
|
|
52
|
+
<string>serve</string>
|
|
53
|
+
</array>
|
|
54
|
+
<key>RunAtLoad</key>
|
|
55
|
+
<true/>
|
|
56
|
+
<key>KeepAlive</key>
|
|
57
|
+
<true/>
|
|
58
|
+
<key>ThrottleInterval</key>
|
|
59
|
+
<integer>5</integer>
|
|
60
|
+
<key>ProcessType</key>
|
|
61
|
+
<string>Background</string>
|
|
62
|
+
<key>StandardOutPath</key>
|
|
63
|
+
<string>${escapeXml(options.stdoutPath)}</string>
|
|
64
|
+
<key>StandardErrorPath</key>
|
|
65
|
+
<string>${escapeXml(options.stderrPath)}</string>
|
|
66
|
+
<key>Umask</key>
|
|
67
|
+
<integer>63</integer>
|
|
68
|
+
</dict>
|
|
69
|
+
</plist>
|
|
70
|
+
`;
|
|
71
|
+
}
|
|
72
|
+
export function systemdDefinition(options) {
|
|
73
|
+
return `[Unit]
|
|
74
|
+
Description=CrewX Bridge
|
|
75
|
+
After=network-online.target
|
|
76
|
+
Wants=network-online.target
|
|
77
|
+
|
|
78
|
+
[Service]
|
|
79
|
+
Type=simple
|
|
80
|
+
ExecStart=${systemdQuote(options.nodePath)} ${systemdQuote(options.entrypoint)} serve
|
|
81
|
+
Environment=${systemdQuote(`PATH=${safePathEnvironment(options.pathEnvironment ?? "/usr/local/bin:/usr/bin:/bin")}`)}
|
|
82
|
+
Restart=on-failure
|
|
83
|
+
RestartSec=5
|
|
84
|
+
TimeoutStopSec=45
|
|
85
|
+
UMask=0077
|
|
86
|
+
NoNewPrivileges=true
|
|
87
|
+
PrivateTmp=true
|
|
88
|
+
ProtectControlGroups=true
|
|
89
|
+
ProtectKernelModules=true
|
|
90
|
+
ProtectKernelTunables=true
|
|
91
|
+
RestrictSUIDSGID=true
|
|
92
|
+
|
|
93
|
+
[Install]
|
|
94
|
+
WantedBy=default.target
|
|
95
|
+
`;
|
|
96
|
+
}
|
|
97
|
+
function refuseRoot(platform = process.platform, effectiveUid = typeof process.getuid === "function" ? process.getuid() : undefined) {
|
|
98
|
+
if (["darwin", "linux"].includes(platform) &&
|
|
99
|
+
effectiveUid === 0) {
|
|
100
|
+
throw new BridgeError("root_refused", "CrewX Bridge must be installed as the OS user who owns the project folders, not root.");
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
export function servicePath(platform = process.platform, userHome = homedir()) {
|
|
104
|
+
if (platform === "darwin") {
|
|
105
|
+
return join(userHome, "Library", "LaunchAgents", "com.crewx.bridge.plist");
|
|
106
|
+
}
|
|
107
|
+
if (platform === "linux") {
|
|
108
|
+
return join(userHome, ".config", "systemd", "user", "crewx-bridge.service");
|
|
109
|
+
}
|
|
110
|
+
throw new BridgeError("unsupported_platform", "CrewX Bridge services currently support macOS and Linux.");
|
|
111
|
+
}
|
|
112
|
+
async function defaultExecutor(file, args) {
|
|
113
|
+
const result = await execFileAsync(file, [...args], {
|
|
114
|
+
encoding: "utf8",
|
|
115
|
+
timeout: 30_000,
|
|
116
|
+
maxBuffer: 1024 * 1024,
|
|
117
|
+
});
|
|
118
|
+
return { stdout: result.stdout, stderr: result.stderr };
|
|
119
|
+
}
|
|
120
|
+
export async function installService(options = {}) {
|
|
121
|
+
const platform = options.platform ?? process.platform;
|
|
122
|
+
refuseRoot(platform, options.effectiveUid);
|
|
123
|
+
const userHome = options.userHome ?? homedir();
|
|
124
|
+
const path = servicePath(platform, userHome);
|
|
125
|
+
const executor = options.executor ?? defaultExecutor;
|
|
126
|
+
const nodePath = options.nodePath ?? process.execPath;
|
|
127
|
+
const entrypoint = options.entrypoint ?? bridgeServiceEntrypoint();
|
|
128
|
+
const pathEnvironment = process.env.PATH ?? "/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin";
|
|
129
|
+
if (platform === "darwin") {
|
|
130
|
+
const state = bridgeStateDirectory(options.environment, platform);
|
|
131
|
+
await ensureSecureDirectory(state);
|
|
132
|
+
await writeSecureText(path, launchdDefinition({
|
|
133
|
+
nodePath,
|
|
134
|
+
entrypoint,
|
|
135
|
+
stdoutPath: join(state, "bridge.log"),
|
|
136
|
+
stderrPath: join(state, "bridge.error.log"),
|
|
137
|
+
pathEnvironment,
|
|
138
|
+
}));
|
|
139
|
+
const uid = options.uid ??
|
|
140
|
+
(typeof process.getuid === "function" ? process.getuid() : undefined);
|
|
141
|
+
if (uid === undefined) {
|
|
142
|
+
throw new BridgeError("uid_unavailable", "Unable to determine the current user ID.");
|
|
143
|
+
}
|
|
144
|
+
await executor("launchctl", ["bootout", `gui/${uid}`, path]).catch(() => ({
|
|
145
|
+
stdout: "",
|
|
146
|
+
stderr: "",
|
|
147
|
+
}));
|
|
148
|
+
await executor("launchctl", ["bootstrap", `gui/${uid}`, path]);
|
|
149
|
+
return path;
|
|
150
|
+
}
|
|
151
|
+
if (platform === "linux") {
|
|
152
|
+
await writeSecureText(path, systemdDefinition({ nodePath, entrypoint, pathEnvironment }));
|
|
153
|
+
await executor("systemctl", ["--user", "daemon-reload"]);
|
|
154
|
+
await executor("systemctl", ["--user", "enable", "--now", "crewx-bridge.service"]);
|
|
155
|
+
return path;
|
|
156
|
+
}
|
|
157
|
+
throw new BridgeError("unsupported_platform", "CrewX Bridge services currently support macOS and Linux.");
|
|
158
|
+
}
|
|
159
|
+
export async function uninstallService(options = {}) {
|
|
160
|
+
const platform = options.platform ?? process.platform;
|
|
161
|
+
refuseRoot(platform, options.effectiveUid);
|
|
162
|
+
const userHome = options.userHome ?? homedir();
|
|
163
|
+
const path = servicePath(platform, userHome);
|
|
164
|
+
const executor = options.executor ?? defaultExecutor;
|
|
165
|
+
if (platform === "darwin") {
|
|
166
|
+
const uid = options.uid ??
|
|
167
|
+
(typeof process.getuid === "function" ? process.getuid() : undefined);
|
|
168
|
+
if (uid === undefined) {
|
|
169
|
+
throw new BridgeError("uid_unavailable", "Unable to determine the current user ID.");
|
|
170
|
+
}
|
|
171
|
+
await executor("launchctl", ["bootout", `gui/${uid}`, path]).catch(() => ({
|
|
172
|
+
stdout: "",
|
|
173
|
+
stderr: "",
|
|
174
|
+
}));
|
|
175
|
+
}
|
|
176
|
+
else if (platform === "linux") {
|
|
177
|
+
await executor("systemctl", ["--user", "disable", "--now", "crewx-bridge.service"]).catch(() => ({ stdout: "", stderr: "" }));
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
throw new BridgeError("unsupported_platform", "CrewX Bridge services currently support macOS and Linux.");
|
|
181
|
+
}
|
|
182
|
+
await unlink(path).catch((error) => {
|
|
183
|
+
if (error.code !== "ENOENT")
|
|
184
|
+
throw error;
|
|
185
|
+
});
|
|
186
|
+
if (platform === "linux") {
|
|
187
|
+
await executor("systemctl", ["--user", "daemon-reload"]);
|
|
188
|
+
}
|
|
189
|
+
return path;
|
|
190
|
+
}
|
|
191
|
+
export async function serviceStatus(options = {}) {
|
|
192
|
+
const platform = options.platform ?? process.platform;
|
|
193
|
+
const executor = options.executor ?? defaultExecutor;
|
|
194
|
+
try {
|
|
195
|
+
if (platform === "darwin") {
|
|
196
|
+
const uid = options.uid ??
|
|
197
|
+
(typeof process.getuid === "function" ? process.getuid() : undefined);
|
|
198
|
+
if (uid === undefined) {
|
|
199
|
+
throw new BridgeError("uid_unavailable", "Unable to determine the current user ID.");
|
|
200
|
+
}
|
|
201
|
+
const result = await executor("launchctl", ["print", `gui/${uid}/com.crewx.bridge`]);
|
|
202
|
+
return { running: true, detail: result.stdout.trim() };
|
|
203
|
+
}
|
|
204
|
+
if (platform === "linux") {
|
|
205
|
+
const result = await executor("systemctl", [
|
|
206
|
+
"--user",
|
|
207
|
+
"is-active",
|
|
208
|
+
"crewx-bridge.service",
|
|
209
|
+
]);
|
|
210
|
+
return { running: result.stdout.trim() === "active", detail: result.stdout.trim() };
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
return {
|
|
215
|
+
running: false,
|
|
216
|
+
detail: error instanceof Error ? error.message : String(error),
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
throw new BridgeError("unsupported_platform", "CrewX Bridge services currently support macOS and Linux.");
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type ChildProcess, type SpawnOptions } from "node:child_process";
|
|
2
|
+
import { type BridgeStartAgentPayload, type BridgeCommandSecret } from "crewx-agent-protocol";
|
|
3
|
+
import { type BridgeConfig, type BridgeFolderConfig } from "./config.js";
|
|
4
|
+
export type SpawnProcess = (command: string, args: readonly string[], options: SpawnOptions) => ChildProcess;
|
|
5
|
+
export declare function minimalChildEnvironment(additions: Record<string, string>, source?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
|
|
6
|
+
export declare function resolveAgentCliEntrypoint(): string;
|
|
7
|
+
export declare class ProcessSupervisor {
|
|
8
|
+
private readonly config;
|
|
9
|
+
private readonly spawnProcess;
|
|
10
|
+
private readonly cliEntrypoint;
|
|
11
|
+
private readonly runs;
|
|
12
|
+
constructor(config: BridgeConfig, spawnProcess?: SpawnProcess, cliEntrypoint?: string);
|
|
13
|
+
activeCount(): number;
|
|
14
|
+
activeRuns(): Array<{
|
|
15
|
+
id: string;
|
|
16
|
+
pid: number;
|
|
17
|
+
}>;
|
|
18
|
+
isRunning(runId: string, _journalPid?: number | null): boolean;
|
|
19
|
+
start(payload: BridgeStartAgentPayload, secret: BridgeCommandSecret, folder: BridgeFolderConfig): number;
|
|
20
|
+
stop(runId: string, _journalPid?: number | null): Promise<void>;
|
|
21
|
+
stopAll(): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=supervisor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supervisor.d.ts","sourceRoot":"","sources":["../src/supervisor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGjF,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,EACzB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAGzE,MAAM,MAAM,YAAY,GAAG,CACzB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,YAAY,KAClB,YAAY,CAAC;AA0BlB,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACjC,MAAM,GAAE,MAAM,CAAC,UAAwB,GACtC,MAAM,CAAC,UAAU,CAOnB;AAED,wBAAgB,yBAAyB,IAAI,MAAM,CAElD;AAgCD,qBAAa,iBAAiB;IAI1B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,aAAa;IALhC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiC;gBAGnC,MAAM,EAAE,YAAY,EACpB,YAAY,GAAE,YAAoB,EAClC,aAAa,SAA8B;IAG9D,WAAW,IAAI,MAAM;IAIrB,UAAU,IAAI,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAMhD,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO;IAK9D,KAAK,CACH,OAAO,EAAE,uBAAuB,EAChC,MAAM,EAAE,mBAAmB,EAC3B,MAAM,EAAE,kBAAkB,GACzB,MAAM;IA4CH,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB/D,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAK/B"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { BridgeError } from "./errors.js";
|
|
4
|
+
const PASSTHROUGH_ENVIRONMENT = [
|
|
5
|
+
"PATH",
|
|
6
|
+
"HOME",
|
|
7
|
+
"USER",
|
|
8
|
+
"LOGNAME",
|
|
9
|
+
"SHELL",
|
|
10
|
+
"TMPDIR",
|
|
11
|
+
"LANG",
|
|
12
|
+
"LC_ALL",
|
|
13
|
+
"XDG_CONFIG_HOME",
|
|
14
|
+
"XDG_CACHE_HOME",
|
|
15
|
+
"XDG_DATA_HOME",
|
|
16
|
+
"XDG_STATE_HOME",
|
|
17
|
+
"OPENAI_API_KEY",
|
|
18
|
+
"ANTHROPIC_API_KEY",
|
|
19
|
+
"CODEX_HOME",
|
|
20
|
+
"CLAUDE_CONFIG_DIR",
|
|
21
|
+
];
|
|
22
|
+
export function minimalChildEnvironment(additions, source = process.env) {
|
|
23
|
+
const environment = {};
|
|
24
|
+
for (const key of PASSTHROUGH_ENVIRONMENT) {
|
|
25
|
+
const value = source[key];
|
|
26
|
+
if (value !== undefined)
|
|
27
|
+
environment[key] = value;
|
|
28
|
+
}
|
|
29
|
+
return { ...environment, ...additions };
|
|
30
|
+
}
|
|
31
|
+
export function resolveAgentCliEntrypoint() {
|
|
32
|
+
return fileURLToPath(import.meta.resolve("crewx-agent-cli"));
|
|
33
|
+
}
|
|
34
|
+
function processAlive(pid) {
|
|
35
|
+
try {
|
|
36
|
+
process.kill(pid, 0);
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function signalProcessGroup(pid, signal) {
|
|
44
|
+
try {
|
|
45
|
+
process.kill(-pid, signal);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
try {
|
|
49
|
+
process.kill(pid, signal);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// It may have exited between the liveness check and signal.
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async function waitForExit(pid, timeoutMs) {
|
|
57
|
+
const deadline = Date.now() + timeoutMs;
|
|
58
|
+
while (Date.now() < deadline) {
|
|
59
|
+
if (!processAlive(pid))
|
|
60
|
+
return true;
|
|
61
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
62
|
+
}
|
|
63
|
+
return !processAlive(pid);
|
|
64
|
+
}
|
|
65
|
+
export class ProcessSupervisor {
|
|
66
|
+
config;
|
|
67
|
+
spawnProcess;
|
|
68
|
+
cliEntrypoint;
|
|
69
|
+
runs = new Map();
|
|
70
|
+
constructor(config, spawnProcess = spawn, cliEntrypoint = resolveAgentCliEntrypoint()) {
|
|
71
|
+
this.config = config;
|
|
72
|
+
this.spawnProcess = spawnProcess;
|
|
73
|
+
this.cliEntrypoint = cliEntrypoint;
|
|
74
|
+
}
|
|
75
|
+
activeCount() {
|
|
76
|
+
return [...this.runs.values()].filter(({ pid }) => processAlive(pid)).length;
|
|
77
|
+
}
|
|
78
|
+
activeRuns() {
|
|
79
|
+
return [...this.runs.entries()]
|
|
80
|
+
.filter(([, { pid }]) => processAlive(pid))
|
|
81
|
+
.map(([id, { pid }]) => ({ id, pid }));
|
|
82
|
+
}
|
|
83
|
+
isRunning(runId, _journalPid) {
|
|
84
|
+
const pid = this.runs.get(runId)?.pid;
|
|
85
|
+
return typeof pid === "number" && processAlive(pid);
|
|
86
|
+
}
|
|
87
|
+
start(payload, secret, folder) {
|
|
88
|
+
if (this.isRunning(payload.run_id)) {
|
|
89
|
+
const existing = this.runs.get(payload.run_id);
|
|
90
|
+
if (existing)
|
|
91
|
+
return existing.pid;
|
|
92
|
+
}
|
|
93
|
+
if (this.activeCount() >= this.config.policy.maxConcurrentRuns) {
|
|
94
|
+
throw new BridgeError("policy_concurrency_exceeded", "The local concurrent-run limit has been reached.");
|
|
95
|
+
}
|
|
96
|
+
const args = [
|
|
97
|
+
this.cliEntrypoint,
|
|
98
|
+
"daemon",
|
|
99
|
+
"--adapter",
|
|
100
|
+
payload.adapter,
|
|
101
|
+
"--cwd",
|
|
102
|
+
folder.path,
|
|
103
|
+
];
|
|
104
|
+
const child = this.spawnProcess(process.execPath, args, {
|
|
105
|
+
cwd: folder.path,
|
|
106
|
+
env: minimalChildEnvironment({
|
|
107
|
+
CREWX_URL: secret.api_url,
|
|
108
|
+
CREWX_TOKEN: secret.agent_token,
|
|
109
|
+
CREWX_ADAPTER: payload.adapter,
|
|
110
|
+
CREWX_BRIDGE_ROOT: folder.path,
|
|
111
|
+
}),
|
|
112
|
+
detached: true,
|
|
113
|
+
shell: false,
|
|
114
|
+
stdio: "ignore",
|
|
115
|
+
});
|
|
116
|
+
if (!child.pid) {
|
|
117
|
+
child.kill();
|
|
118
|
+
throw new BridgeError("spawn_failed", "The agent runner did not return a process ID.");
|
|
119
|
+
}
|
|
120
|
+
this.runs.set(payload.run_id, { pid: child.pid, child });
|
|
121
|
+
child.once("exit", () => {
|
|
122
|
+
const current = this.runs.get(payload.run_id);
|
|
123
|
+
if (current?.child === child)
|
|
124
|
+
this.runs.delete(payload.run_id);
|
|
125
|
+
});
|
|
126
|
+
return child.pid;
|
|
127
|
+
}
|
|
128
|
+
async stop(runId, _journalPid) {
|
|
129
|
+
// A PID restored from disk is not a process identity: after a restart it
|
|
130
|
+
// may belong to an unrelated process. Only signal children this
|
|
131
|
+
// supervisor spawned and still tracks in memory.
|
|
132
|
+
const pid = this.runs.get(runId)?.pid;
|
|
133
|
+
if (!pid || !processAlive(pid)) {
|
|
134
|
+
this.runs.delete(runId);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
signalProcessGroup(pid, "SIGTERM");
|
|
138
|
+
const exited = await waitForExit(pid, this.config.policy.shutdownGraceMs);
|
|
139
|
+
if (!exited) {
|
|
140
|
+
signalProcessGroup(pid, "SIGKILL");
|
|
141
|
+
await waitForExit(pid, 1_000);
|
|
142
|
+
}
|
|
143
|
+
this.runs.delete(runId);
|
|
144
|
+
}
|
|
145
|
+
async stopAll() {
|
|
146
|
+
await Promise.all([...this.runs.entries()].map(([runId, { pid }]) => this.stop(runId, pid)));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=supervisor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supervisor.js","sourceRoot":"","sources":["../src/supervisor.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "crewx-bridge",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Secure macOS and Linux machine bridge for CrewX agent runtimes.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"crewx-bridge": "./dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"README.md",
|
|
20
|
+
"LICENSE"
|
|
21
|
+
],
|
|
22
|
+
"engines": {
|
|
23
|
+
"node": ">=22"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"crewx",
|
|
27
|
+
"daemon",
|
|
28
|
+
"bridge",
|
|
29
|
+
"codex",
|
|
30
|
+
"claude-code",
|
|
31
|
+
"agent-runner"
|
|
32
|
+
],
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"commander": "^14.0.2",
|
|
38
|
+
"zod": "^4.1.12",
|
|
39
|
+
"crewx-agent-cli": "0.2.1",
|
|
40
|
+
"crewx-agent-protocol": "0.2.1"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/node": "^24.10.1",
|
|
44
|
+
"typescript": "^5.9.3"
|
|
45
|
+
},
|
|
46
|
+
"license": "MIT",
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "tsc -p tsconfig.json && node --input-type=module -e \"import { chmodSync } from 'node:fs'; chmodSync('dist/index.js', 0o755)\"",
|
|
49
|
+
"test": "pnpm --filter crewx-agent-protocol build && pnpm --filter crewx-agent-cli build && pnpm run build && node --test test/*.test.mjs",
|
|
50
|
+
"types:check": "tsc -p tsconfig.json --noEmit"
|
|
51
|
+
}
|
|
52
|
+
}
|