@rallycry/conveyor-agent 10.13.8 → 10.13.10
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/dist/chunk-2K6RRTQC.js +451 -0
- package/dist/chunk-2K6RRTQC.js.map +1 -0
- package/dist/chunk-4VUQ2NPF.js +25 -0
- package/dist/chunk-4VUQ2NPF.js.map +1 -0
- package/dist/chunk-IE7EOKMD.js +55 -0
- package/dist/chunk-IE7EOKMD.js.map +1 -0
- package/dist/{chunk-AJZIO5QI.js → chunk-UVR5XFE4.js} +371 -587
- package/dist/chunk-UVR5XFE4.js.map +1 -0
- package/dist/chunk-YRC57EYG.js +413 -0
- package/dist/chunk-YRC57EYG.js.map +1 -0
- package/dist/cli.js +53 -9
- package/dist/cli.js.map +1 -1
- package/dist/client-ICIWKSK2.js +17 -0
- package/dist/client-ICIWKSK2.js.map +1 -0
- package/dist/index.js +24 -8
- package/dist/index.js.map +1 -1
- package/dist/mode-6RL3SVMV.js +13 -0
- package/dist/mode-6RL3SVMV.js.map +1 -0
- package/dist/protocol-QJRHTTMQ.js +15 -0
- package/dist/protocol-QJRHTTMQ.js.map +1 -0
- package/dist/server-UGE67KIZ.js +313 -0
- package/dist/server-UGE67KIZ.js.map +1 -0
- package/package.json +1 -1
- package/runtime/entrypoint.sh +97 -11
- package/dist/chunk-AJZIO5QI.js.map +0 -1
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
RemoteProcessHandle,
|
|
3
|
+
WorkbenchClient,
|
|
4
|
+
WorkbenchError,
|
|
5
|
+
getWorkbenchClient,
|
|
6
|
+
resetWorkbenchClient
|
|
7
|
+
} from "./chunk-YRC57EYG.js";
|
|
8
|
+
import "./chunk-4VUQ2NPF.js";
|
|
9
|
+
import "./chunk-IE7EOKMD.js";
|
|
10
|
+
export {
|
|
11
|
+
RemoteProcessHandle,
|
|
12
|
+
WorkbenchClient,
|
|
13
|
+
WorkbenchError,
|
|
14
|
+
getWorkbenchClient,
|
|
15
|
+
resetWorkbenchClient
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=client-ICIWKSK2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -12,25 +12,41 @@ import {
|
|
|
12
12
|
loadForwardPorts,
|
|
13
13
|
pushToOrigin,
|
|
14
14
|
restoreOnBoot,
|
|
15
|
-
runAuthTokenCommand,
|
|
16
|
-
runSetupCommand,
|
|
17
|
-
runStartCommand,
|
|
18
15
|
stageAndCommit,
|
|
19
16
|
startPeriodic,
|
|
20
17
|
stop,
|
|
21
18
|
unshallowRepo,
|
|
22
19
|
updateRemoteToken,
|
|
23
|
-
uploadSnapshotToGcs
|
|
24
|
-
|
|
20
|
+
uploadSnapshotToGcs,
|
|
21
|
+
workspacePathExists
|
|
22
|
+
} from "./chunk-UVR5XFE4.js";
|
|
25
23
|
import "./chunk-7TQO4ZF4.js";
|
|
24
|
+
import {
|
|
25
|
+
getWorkbenchClient
|
|
26
|
+
} from "./chunk-YRC57EYG.js";
|
|
27
|
+
import {
|
|
28
|
+
workbenchEnabled
|
|
29
|
+
} from "./chunk-4VUQ2NPF.js";
|
|
30
|
+
import {
|
|
31
|
+
runAuthTokenCommand,
|
|
32
|
+
runSetupCommand,
|
|
33
|
+
runStartCommand
|
|
34
|
+
} from "./chunk-2K6RRTQC.js";
|
|
35
|
+
import "./chunk-IE7EOKMD.js";
|
|
26
36
|
|
|
27
37
|
// src/runner/worktree.ts
|
|
28
38
|
import { execFile } from "child_process";
|
|
29
|
-
import { existsSync } from "fs";
|
|
30
39
|
import { join } from "path";
|
|
31
40
|
import { promisify } from "util";
|
|
32
41
|
var execFileAsync = promisify(execFile);
|
|
33
42
|
async function git(cwd, args) {
|
|
43
|
+
if (workbenchEnabled()) {
|
|
44
|
+
const { stdout: stdout2 } = await getWorkbenchClient().execFile("git", args, {
|
|
45
|
+
cwd,
|
|
46
|
+
timeout: GIT_TIMEOUT_MS
|
|
47
|
+
});
|
|
48
|
+
return stdout2;
|
|
49
|
+
}
|
|
34
50
|
const { stdout } = await execFileAsync("git", args, { cwd, timeout: GIT_TIMEOUT_MS });
|
|
35
51
|
return stdout.toString();
|
|
36
52
|
}
|
|
@@ -40,7 +56,7 @@ async function ensureWorktree(projectDir, taskId, branch) {
|
|
|
40
56
|
return projectDir;
|
|
41
57
|
}
|
|
42
58
|
const worktreePath = join(projectDir, WORKTREE_DIR, taskId);
|
|
43
|
-
if (
|
|
59
|
+
if (await workspacePathExists(worktreePath)) {
|
|
44
60
|
if (branch) {
|
|
45
61
|
if (await hasUncommittedChanges(worktreePath)) {
|
|
46
62
|
return worktreePath;
|
|
@@ -77,7 +93,7 @@ async function detachWorktreeBranch(projectDir, branch) {
|
|
|
77
93
|
}
|
|
78
94
|
async function removeWorktree(projectDir, taskId) {
|
|
79
95
|
const worktreePath = join(projectDir, WORKTREE_DIR, taskId);
|
|
80
|
-
if (!
|
|
96
|
+
if (!await workspacePathExists(worktreePath)) return;
|
|
81
97
|
try {
|
|
82
98
|
await git(projectDir, ["worktree", "remove", worktreePath, "--force"]);
|
|
83
99
|
} catch {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/runner/worktree.ts"],"sourcesContent":["import { execFile } from \"node:child_process\";\nimport {
|
|
1
|
+
{"version":3,"sources":["../src/runner/worktree.ts"],"sourcesContent":["import { execFile } from \"node:child_process\";\nimport { join } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { GIT_TIMEOUT_MS, hasUncommittedChanges } from \"./git-utils.js\";\nimport { getWorkbenchClient } from \"../workbench/client.js\";\nimport { workbenchEnabled } from \"../workbench/mode.js\";\nimport { workspacePathExists } from \"../workbench/fs.js\";\n\n// Async git (execFile, no shell) — synchronous child processes freeze the\n// agent's event loop and starve the socket heartbeat; see git-utils.ts.\n// Split-mode pods route over the launcher (the repo lives in the workbench).\nconst execFileAsync = promisify(execFile);\n\nasync function git(cwd: string, args: string[]): Promise<string> {\n if (workbenchEnabled()) {\n const { stdout } = await getWorkbenchClient().execFile(\"git\", args, {\n cwd,\n timeout: GIT_TIMEOUT_MS,\n });\n return stdout;\n }\n const { stdout } = await execFileAsync(\"git\", args, { cwd, timeout: GIT_TIMEOUT_MS });\n return stdout.toString();\n}\n\nconst WORKTREE_DIR = \".worktrees\";\n\nexport async function ensureWorktree(\n projectDir: string,\n taskId: string,\n branch?: string,\n): Promise<string> {\n if (projectDir.includes(`/${WORKTREE_DIR}/`)) {\n return projectDir;\n }\n\n const worktreePath = join(projectDir, WORKTREE_DIR, taskId);\n\n if (await workspacePathExists(worktreePath)) {\n if (branch) {\n if (await hasUncommittedChanges(worktreePath)) {\n return worktreePath;\n }\n try {\n await git(worktreePath, [\"checkout\", \"--detach\", `origin/${branch}`]);\n } catch {\n /* branch doesn't exist on remote yet */\n }\n }\n return worktreePath;\n }\n\n const ref = branch ? `origin/${branch}` : \"HEAD\";\n await git(projectDir, [\"worktree\", \"add\", \"--detach\", worktreePath, ref]);\n\n return worktreePath;\n}\n\n/**\n * Detach any task worktree that has `branch` checked out, releasing the branch lock\n * so the main project directory can check it out. Only touches worktrees inside\n * `.worktrees/` — never the main project directory.\n */\nexport async function detachWorktreeBranch(projectDir: string, branch: string): Promise<void> {\n try {\n const output = await git(projectDir, [\"worktree\", \"list\", \"--porcelain\"]);\n const entries = output.split(\"\\n\\n\");\n for (const entry of entries) {\n const lines = entry.trim().split(\"\\n\");\n const worktreeLine = lines.find((l) => l.startsWith(\"worktree \"));\n const branchLine = lines.find((l) => l.startsWith(\"branch \"));\n if (!worktreeLine || branchLine !== `branch refs/heads/${branch}`) continue;\n\n const worktreePath = worktreeLine.replace(\"worktree \", \"\");\n if (!worktreePath.includes(`/${WORKTREE_DIR}/`)) continue;\n\n try {\n await git(worktreePath, [\"checkout\", \"--detach\"]);\n } catch {\n /* best effort */\n }\n }\n } catch {\n /* best effort */\n }\n}\n\n/**\n * Force-remove is intentional: this runs after task completion or explicit stop.\n * Any uncommitted changes at this point are scratch artifacts, not valuable work.\n */\nexport async function removeWorktree(projectDir: string, taskId: string): Promise<void> {\n const worktreePath = join(projectDir, WORKTREE_DIR, taskId);\n if (!(await workspacePathExists(worktreePath))) return;\n try {\n await git(projectDir, [\"worktree\", \"remove\", worktreePath, \"--force\"]);\n } catch {\n /* best effort */\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,gBAAgB;AACzB,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAS1B,IAAM,gBAAgB,UAAU,QAAQ;AAExC,eAAe,IAAI,KAAa,MAAiC;AAC/D,MAAI,iBAAiB,GAAG;AACtB,UAAM,EAAE,QAAAA,QAAO,IAAI,MAAM,mBAAmB,EAAE,SAAS,OAAO,MAAM;AAAA,MAClE;AAAA,MACA,SAAS;AAAA,IACX,CAAC;AACD,WAAOA;AAAA,EACT;AACA,QAAM,EAAE,OAAO,IAAI,MAAM,cAAc,OAAO,MAAM,EAAE,KAAK,SAAS,eAAe,CAAC;AACpF,SAAO,OAAO,SAAS;AACzB;AAEA,IAAM,eAAe;AAErB,eAAsB,eACpB,YACA,QACA,QACiB;AACjB,MAAI,WAAW,SAAS,IAAI,YAAY,GAAG,GAAG;AAC5C,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,KAAK,YAAY,cAAc,MAAM;AAE1D,MAAI,MAAM,oBAAoB,YAAY,GAAG;AAC3C,QAAI,QAAQ;AACV,UAAI,MAAM,sBAAsB,YAAY,GAAG;AAC7C,eAAO;AAAA,MACT;AACA,UAAI;AACF,cAAM,IAAI,cAAc,CAAC,YAAY,YAAY,UAAU,MAAM,EAAE,CAAC;AAAA,MACtE,QAAQ;AAAA,MAER;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,SAAS,UAAU,MAAM,KAAK;AAC1C,QAAM,IAAI,YAAY,CAAC,YAAY,OAAO,YAAY,cAAc,GAAG,CAAC;AAExE,SAAO;AACT;AAOA,eAAsB,qBAAqB,YAAoB,QAA+B;AAC5F,MAAI;AACF,UAAM,SAAS,MAAM,IAAI,YAAY,CAAC,YAAY,QAAQ,aAAa,CAAC;AACxE,UAAM,UAAU,OAAO,MAAM,MAAM;AACnC,eAAW,SAAS,SAAS;AAC3B,YAAM,QAAQ,MAAM,KAAK,EAAE,MAAM,IAAI;AACrC,YAAM,eAAe,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,WAAW,CAAC;AAChE,YAAM,aAAa,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,SAAS,CAAC;AAC5D,UAAI,CAAC,gBAAgB,eAAe,qBAAqB,MAAM,GAAI;AAEnE,YAAM,eAAe,aAAa,QAAQ,aAAa,EAAE;AACzD,UAAI,CAAC,aAAa,SAAS,IAAI,YAAY,GAAG,EAAG;AAEjD,UAAI;AACF,cAAM,IAAI,cAAc,CAAC,YAAY,UAAU,CAAC;AAAA,MAClD,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AACF;AAMA,eAAsB,eAAe,YAAoB,QAA+B;AACtF,QAAM,eAAe,KAAK,YAAY,cAAc,MAAM;AAC1D,MAAI,CAAE,MAAM,oBAAoB,YAAY,EAAI;AAChD,MAAI;AACF,UAAM,IAAI,YAAY,CAAC,YAAY,UAAU,cAAc,SAAS,CAAC;AAAA,EACvE,QAAQ;AAAA,EAER;AACF;","names":["stdout"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_WORKBENCH_PORT,
|
|
3
|
+
FrameReader,
|
|
4
|
+
parseLine,
|
|
5
|
+
timingSafeTokenEqual,
|
|
6
|
+
writeFrame
|
|
7
|
+
} from "./chunk-IE7EOKMD.js";
|
|
8
|
+
export {
|
|
9
|
+
DEFAULT_WORKBENCH_PORT,
|
|
10
|
+
FrameReader,
|
|
11
|
+
parseLine,
|
|
12
|
+
timingSafeTokenEqual,
|
|
13
|
+
writeFrame
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=protocol-QJRHTTMQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildSnapshotTar,
|
|
3
|
+
extractSnapshotTar,
|
|
4
|
+
loadPtySpawn,
|
|
5
|
+
terminateProcessGroup
|
|
6
|
+
} from "./chunk-2K6RRTQC.js";
|
|
7
|
+
import {
|
|
8
|
+
FrameReader,
|
|
9
|
+
timingSafeTokenEqual,
|
|
10
|
+
writeFrame
|
|
11
|
+
} from "./chunk-IE7EOKMD.js";
|
|
12
|
+
|
|
13
|
+
// src/workbench/server.ts
|
|
14
|
+
import { spawn } from "child_process";
|
|
15
|
+
import { createReadStream, createWriteStream } from "fs";
|
|
16
|
+
import { mkdtemp, readdir, readFile, rm, stat } from "fs/promises";
|
|
17
|
+
import { createServer } from "net";
|
|
18
|
+
import { tmpdir } from "os";
|
|
19
|
+
import { join } from "path";
|
|
20
|
+
var TAR_CHUNK_BYTES = 64 * 1024;
|
|
21
|
+
function errCode(err) {
|
|
22
|
+
return typeof err?.code === "string" ? err.code : void 0;
|
|
23
|
+
}
|
|
24
|
+
function sendError(socket, err) {
|
|
25
|
+
const frame = {
|
|
26
|
+
t: "error",
|
|
27
|
+
message: err instanceof Error ? err.message : String(err),
|
|
28
|
+
...errCode(err) ? { code: errCode(err) } : {}
|
|
29
|
+
};
|
|
30
|
+
writeFrame(socket, frame);
|
|
31
|
+
}
|
|
32
|
+
function mergedEnv(overrides) {
|
|
33
|
+
return overrides ? { ...process.env, ...overrides } : { ...process.env };
|
|
34
|
+
}
|
|
35
|
+
var FrameSink = class {
|
|
36
|
+
pending = [];
|
|
37
|
+
handler = null;
|
|
38
|
+
push(frame) {
|
|
39
|
+
if (this.handler) this.handler(frame);
|
|
40
|
+
else this.pending.push(frame);
|
|
41
|
+
}
|
|
42
|
+
setHandler(handler) {
|
|
43
|
+
this.handler = handler;
|
|
44
|
+
for (const frame of this.pending.splice(0)) handler(frame);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
async function startWorkbenchServer(opts) {
|
|
48
|
+
const server = createServer((socket) => handleConnection(socket, opts));
|
|
49
|
+
await new Promise((resolve, reject) => {
|
|
50
|
+
server.once("error", reject);
|
|
51
|
+
server.listen(opts.port, "127.0.0.1", () => resolve());
|
|
52
|
+
});
|
|
53
|
+
const address = server.address();
|
|
54
|
+
const port = typeof address === "object" && address ? address.port : opts.port;
|
|
55
|
+
return {
|
|
56
|
+
port,
|
|
57
|
+
close: () => new Promise((resolve) => {
|
|
58
|
+
server.close(() => resolve());
|
|
59
|
+
})
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function handleConnection(socket, opts) {
|
|
63
|
+
socket.on("error", () => void 0);
|
|
64
|
+
const sink = new FrameSink();
|
|
65
|
+
let dispatched = false;
|
|
66
|
+
const reader = new FrameReader((frame) => {
|
|
67
|
+
if (dispatched) {
|
|
68
|
+
sink.push(frame);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
dispatched = true;
|
|
72
|
+
dispatch(socket, frame, sink, opts);
|
|
73
|
+
});
|
|
74
|
+
socket.on("data", (chunk) => reader.push(chunk));
|
|
75
|
+
}
|
|
76
|
+
function dispatch(socket, req, sink, opts) {
|
|
77
|
+
if (!req || typeof req !== "object" || !timingSafeTokenEqual(req.token ?? "", opts.token)) {
|
|
78
|
+
writeFrame(socket, { t: "error", message: "unauthorized", code: "unauthorized" });
|
|
79
|
+
socket.destroy();
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
switch (req.op) {
|
|
83
|
+
case "ping":
|
|
84
|
+
writeFrame(socket, { t: "pong", version: opts.version });
|
|
85
|
+
socket.end();
|
|
86
|
+
return;
|
|
87
|
+
case "exec":
|
|
88
|
+
runExec(socket, req, sink);
|
|
89
|
+
return;
|
|
90
|
+
case "pty":
|
|
91
|
+
void runPty(socket, req, sink);
|
|
92
|
+
return;
|
|
93
|
+
case "snapshotBuild":
|
|
94
|
+
void runSnapshotBuild(socket, req);
|
|
95
|
+
return;
|
|
96
|
+
case "snapshotExtract":
|
|
97
|
+
void runSnapshotExtract(socket, req, sink);
|
|
98
|
+
return;
|
|
99
|
+
case "readFile":
|
|
100
|
+
void runReadFile(socket, req);
|
|
101
|
+
return;
|
|
102
|
+
case "stat":
|
|
103
|
+
void runStat(socket, req);
|
|
104
|
+
return;
|
|
105
|
+
case "readdir":
|
|
106
|
+
void runReaddir(socket, req);
|
|
107
|
+
return;
|
|
108
|
+
default:
|
|
109
|
+
writeFrame(socket, { t: "error", message: "unknown op", code: "bad_request" });
|
|
110
|
+
socket.end();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function runExec(socket, req, sink) {
|
|
114
|
+
let child;
|
|
115
|
+
try {
|
|
116
|
+
const [argvFile, ...argvRest] = req.argv ?? [];
|
|
117
|
+
child = argvFile ? spawn(argvFile, argvRest, {
|
|
118
|
+
cwd: req.cwd,
|
|
119
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
120
|
+
detached: true,
|
|
121
|
+
env: mergedEnv(req.env)
|
|
122
|
+
}) : spawn("sh", ["-c", req.command ?? ""], {
|
|
123
|
+
cwd: req.cwd,
|
|
124
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
125
|
+
detached: true,
|
|
126
|
+
env: mergedEnv(req.env)
|
|
127
|
+
});
|
|
128
|
+
} catch (err) {
|
|
129
|
+
sendError(socket, err);
|
|
130
|
+
socket.end();
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
let settled = false;
|
|
134
|
+
sink.setHandler((frame) => {
|
|
135
|
+
if (frame.t === "signal" && frame.mode === "term-group" && !settled) {
|
|
136
|
+
void terminateProcessGroup(child);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
child.stdout?.on("data", (chunk) => {
|
|
140
|
+
writeFrame(socket, { t: "out", s: "stdout", d: chunk.toString("base64") });
|
|
141
|
+
});
|
|
142
|
+
child.stderr?.on("data", (chunk) => {
|
|
143
|
+
writeFrame(socket, { t: "out", s: "stderr", d: chunk.toString("base64") });
|
|
144
|
+
});
|
|
145
|
+
child.on("close", (code, signal) => {
|
|
146
|
+
settled = true;
|
|
147
|
+
writeFrame(socket, { t: "exit", code, signal });
|
|
148
|
+
socket.end();
|
|
149
|
+
});
|
|
150
|
+
child.on("error", (err) => {
|
|
151
|
+
if (settled) return;
|
|
152
|
+
settled = true;
|
|
153
|
+
sendError(socket, err);
|
|
154
|
+
socket.end();
|
|
155
|
+
});
|
|
156
|
+
socket.on("close", () => {
|
|
157
|
+
if (!settled) void terminateProcessGroup(child);
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
async function runPty(socket, req, sink) {
|
|
161
|
+
let pty;
|
|
162
|
+
try {
|
|
163
|
+
const ptySpawn = await loadPtySpawn();
|
|
164
|
+
pty = ptySpawn(req.file, req.args, {
|
|
165
|
+
name: "xterm-color",
|
|
166
|
+
cols: req.cols,
|
|
167
|
+
rows: req.rows,
|
|
168
|
+
cwd: req.cwd,
|
|
169
|
+
env: req.env
|
|
170
|
+
});
|
|
171
|
+
} catch (err) {
|
|
172
|
+
sendError(socket, err);
|
|
173
|
+
socket.end();
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
let exited = false;
|
|
177
|
+
sink.setHandler((frame) => {
|
|
178
|
+
try {
|
|
179
|
+
if (frame.t === "input" && typeof frame.d === "string") {
|
|
180
|
+
pty.write(Buffer.from(frame.d, "base64").toString("utf8"));
|
|
181
|
+
} else if (frame.t === "resize" && typeof frame.cols === "number" && typeof frame.rows === "number") {
|
|
182
|
+
pty.resize(frame.cols, frame.rows);
|
|
183
|
+
} else if (frame.t === "kill") {
|
|
184
|
+
pty.kill(typeof frame.sig === "string" ? frame.sig : void 0);
|
|
185
|
+
}
|
|
186
|
+
} catch {
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
pty.onData((data) => {
|
|
190
|
+
writeFrame(socket, { t: "data", d: Buffer.from(data, "utf8").toString("base64") });
|
|
191
|
+
});
|
|
192
|
+
pty.onExit((event) => {
|
|
193
|
+
exited = true;
|
|
194
|
+
writeFrame(socket, { t: "exit", code: event.exitCode, signal: null });
|
|
195
|
+
socket.end();
|
|
196
|
+
});
|
|
197
|
+
socket.on("close", () => {
|
|
198
|
+
if (!exited) {
|
|
199
|
+
try {
|
|
200
|
+
pty.kill();
|
|
201
|
+
} catch {
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
async function runSnapshotBuild(socket, req) {
|
|
207
|
+
try {
|
|
208
|
+
const result = await buildSnapshotTar(req.cwd);
|
|
209
|
+
try {
|
|
210
|
+
writeFrame(socket, {
|
|
211
|
+
t: "meta",
|
|
212
|
+
sizeBytes: result.sizeBytes,
|
|
213
|
+
fileCount: result.fileCount,
|
|
214
|
+
deletionCount: result.deletionCount,
|
|
215
|
+
capturedAt: result.capturedAt
|
|
216
|
+
});
|
|
217
|
+
await new Promise((resolve, reject) => {
|
|
218
|
+
const stream = createReadStream(result.tarPath, { highWaterMark: TAR_CHUNK_BYTES });
|
|
219
|
+
stream.on("data", (chunk) => {
|
|
220
|
+
writeFrame(socket, { t: "data", d: Buffer.from(chunk).toString("base64") });
|
|
221
|
+
});
|
|
222
|
+
stream.on("end", () => resolve());
|
|
223
|
+
stream.on("error", reject);
|
|
224
|
+
socket.on("close", () => stream.destroy());
|
|
225
|
+
});
|
|
226
|
+
writeFrame(socket, { t: "end" });
|
|
227
|
+
} finally {
|
|
228
|
+
await result.cleanup();
|
|
229
|
+
}
|
|
230
|
+
} catch (err) {
|
|
231
|
+
sendError(socket, err);
|
|
232
|
+
}
|
|
233
|
+
socket.end();
|
|
234
|
+
}
|
|
235
|
+
async function runSnapshotExtract(socket, req, sink) {
|
|
236
|
+
const staging = await mkdtemp(join(tmpdir(), "conveyor-workbench-extract-"));
|
|
237
|
+
const tarPath = join(staging, "snapshot.tar.gz");
|
|
238
|
+
const out = createWriteStream(tarPath);
|
|
239
|
+
try {
|
|
240
|
+
await new Promise((resolve, reject) => {
|
|
241
|
+
sink.setHandler((frame) => {
|
|
242
|
+
if (frame.t === "data" && typeof frame.d === "string") {
|
|
243
|
+
out.write(Buffer.from(frame.d, "base64"));
|
|
244
|
+
} else if (frame.t === "end") {
|
|
245
|
+
out.end(() => resolve());
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
out.on("error", reject);
|
|
249
|
+
socket.on("close", () => reject(new Error("connection closed before end frame")));
|
|
250
|
+
});
|
|
251
|
+
const value = await extractSnapshotTar(req.cwd, tarPath);
|
|
252
|
+
writeFrame(socket, { t: "result", value });
|
|
253
|
+
} catch (err) {
|
|
254
|
+
sendError(socket, err);
|
|
255
|
+
} finally {
|
|
256
|
+
await rm(staging, { recursive: true, force: true }).catch(() => void 0);
|
|
257
|
+
socket.end();
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
async function runReadFile(socket, req) {
|
|
261
|
+
try {
|
|
262
|
+
const content = await readFile(req.path);
|
|
263
|
+
for (let offset = 0; offset < content.length; offset += TAR_CHUNK_BYTES) {
|
|
264
|
+
writeFrame(socket, {
|
|
265
|
+
t: "data",
|
|
266
|
+
d: content.subarray(offset, offset + TAR_CHUNK_BYTES).toString("base64")
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
writeFrame(socket, { t: "end" });
|
|
270
|
+
} catch (err) {
|
|
271
|
+
sendError(socket, err);
|
|
272
|
+
}
|
|
273
|
+
socket.end();
|
|
274
|
+
}
|
|
275
|
+
async function runStat(socket, req) {
|
|
276
|
+
try {
|
|
277
|
+
const s = await stat(req.path);
|
|
278
|
+
writeFrame(socket, {
|
|
279
|
+
t: "stat",
|
|
280
|
+
exists: true,
|
|
281
|
+
isFile: s.isFile(),
|
|
282
|
+
isDirectory: s.isDirectory(),
|
|
283
|
+
size: s.size,
|
|
284
|
+
mtimeMs: s.mtimeMs
|
|
285
|
+
});
|
|
286
|
+
} catch (err) {
|
|
287
|
+
if (errCode(err) === "ENOENT") {
|
|
288
|
+
writeFrame(socket, {
|
|
289
|
+
t: "stat",
|
|
290
|
+
exists: false,
|
|
291
|
+
isFile: false,
|
|
292
|
+
isDirectory: false,
|
|
293
|
+
size: 0,
|
|
294
|
+
mtimeMs: 0
|
|
295
|
+
});
|
|
296
|
+
} else {
|
|
297
|
+
sendError(socket, err);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
socket.end();
|
|
301
|
+
}
|
|
302
|
+
async function runReaddir(socket, req) {
|
|
303
|
+
try {
|
|
304
|
+
writeFrame(socket, { t: "entries", names: await readdir(req.path) });
|
|
305
|
+
} catch (err) {
|
|
306
|
+
sendError(socket, err);
|
|
307
|
+
}
|
|
308
|
+
socket.end();
|
|
309
|
+
}
|
|
310
|
+
export {
|
|
311
|
+
startWorkbenchServer
|
|
312
|
+
};
|
|
313
|
+
//# sourceMappingURL=server-UGE67KIZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/workbench/server.ts"],"sourcesContent":["/**\n * The workbench launcher — PID 1 of the workbench container in split-mode\n * pods (CONVEYOR_MODE=workbench). A token-authed, loopback-only exec daemon:\n * the agent container drives every workspace-touching operation through it\n * (shell commands, the claude PTY, git, snapshot build/extract, file reads)\n * while staying insulated from workload OOMs in its own container cgroup.\n *\n * One connection = one operation. A dropped connection kills the operation's\n * process (group) — the agent dying, restarting, or timing out must never\n * leave orphans accumulating against the workbench memory budget.\n */\n\nimport { spawn, type ChildProcess } from \"node:child_process\";\nimport { createReadStream, createWriteStream } from \"node:fs\";\nimport { mkdtemp, readdir, readFile, rm, stat } from \"node:fs/promises\";\nimport { createServer, type Socket } from \"node:net\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { terminateProcessGroup } from \"../setup/commands.js\";\nimport { loadPtySpawn, type PtyProcess } from \"../harness/pty/pty-support.js\";\nimport { buildSnapshotTar, extractSnapshotTar } from \"../runner/work-preservation/snapshot-tar.js\";\nimport {\n FrameReader,\n timingSafeTokenEqual,\n writeFrame,\n type WorkbenchFrame,\n type WorkbenchRequest,\n} from \"./protocol.js\";\n\nconst TAR_CHUNK_BYTES = 64 * 1024;\n\nexport interface WorkbenchServerOptions {\n port: number;\n token: string;\n version: string;\n}\n\nexport interface WorkbenchServerHandle {\n port: number;\n close(): Promise<void>;\n}\n\nfunction errCode(err: unknown): string | undefined {\n return typeof (err as { code?: unknown })?.code === \"string\"\n ? (err as { code: string }).code\n : undefined;\n}\n\nfunction sendError(socket: Socket, err: unknown): void {\n const frame: WorkbenchFrame = {\n t: \"error\",\n message: err instanceof Error ? err.message : String(err),\n ...(errCode(err) ? { code: errCode(err) } : {}),\n };\n writeFrame(socket, frame);\n}\n\n/** Merge request env over the daemon's own (mirrors the local spawn paths,\n * which inherit process.env and let callers override). */\nfunction mergedEnv(overrides?: Record<string, string>): NodeJS.ProcessEnv {\n return overrides ? { ...process.env, ...overrides } : { ...process.env };\n}\n\n/**\n * Post-dispatch inbound frames for the connection's operation. Handlers\n * assign `onNext`; frames arriving before assignment are queued so an input\n * racing the (async) pty spawn is never dropped.\n */\nclass FrameSink {\n private pending: WorkbenchFrame[] = [];\n private handler: ((frame: WorkbenchFrame) => void) | null = null;\n\n push(frame: WorkbenchFrame): void {\n if (this.handler) this.handler(frame);\n else this.pending.push(frame);\n }\n\n setHandler(handler: (frame: WorkbenchFrame) => void): void {\n this.handler = handler;\n for (const frame of this.pending.splice(0)) handler(frame);\n }\n}\n\nexport async function startWorkbenchServer(\n opts: WorkbenchServerOptions,\n): Promise<WorkbenchServerHandle> {\n const server = createServer((socket) => handleConnection(socket, opts));\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(opts.port, \"127.0.0.1\", () => resolve());\n });\n const address = server.address();\n const port = typeof address === \"object\" && address ? address.port : opts.port;\n return {\n port,\n close: () =>\n new Promise<void>((resolve) => {\n server.close(() => resolve());\n }),\n };\n}\n\nfunction handleConnection(socket: Socket, opts: WorkbenchServerOptions): void {\n socket.on(\"error\", () => undefined);\n const sink = new FrameSink();\n let dispatched = false;\n const reader = new FrameReader((frame) => {\n if (dispatched) {\n sink.push(frame as unknown as WorkbenchFrame);\n return;\n }\n dispatched = true;\n dispatch(socket, frame as unknown as WorkbenchRequest, sink, opts);\n });\n socket.on(\"data\", (chunk: Buffer) => reader.push(chunk));\n}\n\nfunction dispatch(\n socket: Socket,\n req: WorkbenchRequest,\n sink: FrameSink,\n opts: WorkbenchServerOptions,\n): void {\n if (!req || typeof req !== \"object\" || !timingSafeTokenEqual(req.token ?? \"\", opts.token)) {\n writeFrame(socket, { t: \"error\", message: \"unauthorized\", code: \"unauthorized\" });\n socket.destroy();\n return;\n }\n switch (req.op) {\n case \"ping\":\n writeFrame(socket, { t: \"pong\", version: opts.version });\n socket.end();\n return;\n case \"exec\":\n runExec(socket, req, sink);\n return;\n case \"pty\":\n void runPty(socket, req, sink);\n return;\n case \"snapshotBuild\":\n void runSnapshotBuild(socket, req);\n return;\n case \"snapshotExtract\":\n void runSnapshotExtract(socket, req, sink);\n return;\n case \"readFile\":\n void runReadFile(socket, req);\n return;\n case \"stat\":\n void runStat(socket, req);\n return;\n case \"readdir\":\n void runReaddir(socket, req);\n return;\n default:\n writeFrame(socket, { t: \"error\", message: \"unknown op\", code: \"bad_request\" });\n socket.end();\n }\n}\n\nfunction runExec(\n socket: Socket,\n req: Extract<WorkbenchRequest, { op: \"exec\" }>,\n sink: FrameSink,\n): void {\n let child: ChildProcess;\n try {\n // Argv form (git and friends) spawns directly with no shell; shell form\n // (setup/start commands) mirrors the local `spawn(\"sh\", [\"-c\", cmd])`.\n const [argvFile, ...argvRest] = req.argv ?? [];\n child = argvFile\n ? spawn(argvFile, argvRest, {\n cwd: req.cwd,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n detached: true,\n env: mergedEnv(req.env),\n })\n : spawn(\"sh\", [\"-c\", req.command ?? \"\"], {\n cwd: req.cwd,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n detached: true,\n env: mergedEnv(req.env),\n });\n } catch (err) {\n sendError(socket, err);\n socket.end();\n return;\n }\n\n let settled = false;\n sink.setHandler((frame) => {\n if (frame.t === \"signal\" && frame.mode === \"term-group\" && !settled) {\n void terminateProcessGroup(child);\n }\n });\n child.stdout?.on(\"data\", (chunk: Buffer) => {\n writeFrame(socket, { t: \"out\", s: \"stdout\", d: chunk.toString(\"base64\") });\n });\n child.stderr?.on(\"data\", (chunk: Buffer) => {\n writeFrame(socket, { t: \"out\", s: \"stderr\", d: chunk.toString(\"base64\") });\n });\n child.on(\"close\", (code, signal) => {\n settled = true;\n writeFrame(socket, { t: \"exit\", code, signal });\n socket.end();\n });\n child.on(\"error\", (err) => {\n if (settled) return;\n settled = true;\n sendError(socket, err);\n socket.end();\n });\n // Agent gone (crash, timeout-abort, container death) → no orphans.\n socket.on(\"close\", () => {\n if (!settled) void terminateProcessGroup(child);\n });\n}\n\nasync function runPty(\n socket: Socket,\n req: Extract<WorkbenchRequest, { op: \"pty\" }>,\n sink: FrameSink,\n): Promise<void> {\n let pty: PtyProcess;\n try {\n const ptySpawn = await loadPtySpawn();\n pty = ptySpawn(req.file, req.args, {\n name: \"xterm-color\",\n cols: req.cols,\n rows: req.rows,\n cwd: req.cwd,\n env: req.env,\n });\n } catch (err) {\n sendError(socket, err);\n socket.end();\n return;\n }\n\n let exited = false;\n sink.setHandler((frame) => {\n try {\n if (frame.t === \"input\" && typeof frame.d === \"string\") {\n pty.write(Buffer.from(frame.d, \"base64\").toString(\"utf8\"));\n } else if (\n frame.t === \"resize\" &&\n typeof frame.cols === \"number\" &&\n typeof frame.rows === \"number\"\n ) {\n pty.resize(frame.cols, frame.rows);\n } else if (frame.t === \"kill\") {\n pty.kill(typeof frame.sig === \"string\" ? frame.sig : undefined);\n }\n } catch {\n /* pty already dead — exit handler owns teardown */\n }\n });\n pty.onData((data) => {\n writeFrame(socket, { t: \"data\", d: Buffer.from(data, \"utf8\").toString(\"base64\") });\n });\n pty.onExit((event) => {\n exited = true;\n writeFrame(socket, { t: \"exit\", code: event.exitCode, signal: null });\n socket.end();\n });\n socket.on(\"close\", () => {\n if (!exited) {\n try {\n pty.kill();\n } catch {\n /* already dead */\n }\n }\n });\n}\n\nasync function runSnapshotBuild(\n socket: Socket,\n req: Extract<WorkbenchRequest, { op: \"snapshotBuild\" }>,\n): Promise<void> {\n try {\n const result = await buildSnapshotTar(req.cwd);\n try {\n writeFrame(socket, {\n t: \"meta\",\n sizeBytes: result.sizeBytes,\n fileCount: result.fileCount,\n deletionCount: result.deletionCount,\n capturedAt: result.capturedAt,\n });\n await new Promise<void>((resolve, reject) => {\n const stream = createReadStream(result.tarPath, { highWaterMark: TAR_CHUNK_BYTES });\n stream.on(\"data\", (chunk) => {\n writeFrame(socket, { t: \"data\", d: Buffer.from(chunk).toString(\"base64\") });\n });\n stream.on(\"end\", () => resolve());\n stream.on(\"error\", reject);\n socket.on(\"close\", () => stream.destroy());\n });\n writeFrame(socket, { t: \"end\" });\n } finally {\n await result.cleanup();\n }\n } catch (err) {\n sendError(socket, err);\n }\n socket.end();\n}\n\nasync function runSnapshotExtract(\n socket: Socket,\n req: Extract<WorkbenchRequest, { op: \"snapshotExtract\" }>,\n sink: FrameSink,\n): Promise<void> {\n const staging = await mkdtemp(join(tmpdir(), \"conveyor-workbench-extract-\"));\n const tarPath = join(staging, \"snapshot.tar.gz\");\n const out = createWriteStream(tarPath);\n try {\n await new Promise<void>((resolve, reject) => {\n sink.setHandler((frame) => {\n if (frame.t === \"data\" && typeof frame.d === \"string\") {\n out.write(Buffer.from(frame.d, \"base64\"));\n } else if (frame.t === \"end\") {\n out.end(() => resolve());\n }\n });\n out.on(\"error\", reject);\n socket.on(\"close\", () => reject(new Error(\"connection closed before end frame\")));\n });\n const value = await extractSnapshotTar(req.cwd, tarPath);\n writeFrame(socket, { t: \"result\", value });\n } catch (err) {\n sendError(socket, err);\n } finally {\n await rm(staging, { recursive: true, force: true }).catch(() => undefined);\n socket.end();\n }\n}\n\nasync function runReadFile(\n socket: Socket,\n req: Extract<WorkbenchRequest, { op: \"readFile\" }>,\n): Promise<void> {\n try {\n const content = await readFile(req.path);\n for (let offset = 0; offset < content.length; offset += TAR_CHUNK_BYTES) {\n writeFrame(socket, {\n t: \"data\",\n d: content.subarray(offset, offset + TAR_CHUNK_BYTES).toString(\"base64\"),\n });\n }\n writeFrame(socket, { t: \"end\" });\n } catch (err) {\n sendError(socket, err);\n }\n socket.end();\n}\n\nasync function runStat(\n socket: Socket,\n req: Extract<WorkbenchRequest, { op: \"stat\" }>,\n): Promise<void> {\n try {\n const s = await stat(req.path);\n writeFrame(socket, {\n t: \"stat\",\n exists: true,\n isFile: s.isFile(),\n isDirectory: s.isDirectory(),\n size: s.size,\n mtimeMs: s.mtimeMs,\n });\n } catch (err) {\n if (errCode(err) === \"ENOENT\") {\n writeFrame(socket, {\n t: \"stat\",\n exists: false,\n isFile: false,\n isDirectory: false,\n size: 0,\n mtimeMs: 0,\n });\n } else {\n sendError(socket, err);\n }\n }\n socket.end();\n}\n\nasync function runReaddir(\n socket: Socket,\n req: Extract<WorkbenchRequest, { op: \"readdir\" }>,\n): Promise<void> {\n try {\n writeFrame(socket, { t: \"entries\", names: await readdir(req.path) });\n } catch (err) {\n sendError(socket, err);\n }\n socket.end();\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rallycry/conveyor-agent",
|
|
3
|
-
"version": "10.13.
|
|
3
|
+
"version": "10.13.10",
|
|
4
4
|
"description": "Conveyor Agent Runner v10 - PTY harness for the task chat (SDK harness for audit/project-chat). Agent-as-User architecture with BaseService patterns. Works locally too.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|