@rallycry/conveyor-agent 10.13.71 → 10.13.72
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/{boot-PKHZUDAC.js → boot-ZNL7X5LQ.js} +8 -4
- package/dist/chunk-2L5THOWD.js +697 -0
- package/dist/{chunk-7MMECTTJ.js → chunk-2SN32LM6.js} +134 -2598
- package/dist/chunk-3F4ZZKCA.js +291 -0
- package/dist/chunk-LSZ2KLJY.js +2527 -0
- package/dist/{chunk-DOB2XE2I.js → chunk-UBDSLM44.js} +4 -2
- package/dist/{chunk-GJXAAPJ6.js → chunk-W4LZ7R6Z.js} +117 -400
- package/dist/{chunk-QU53HND5.js → chunk-WMMBAKPE.js} +4 -48
- package/dist/chunk-XORJ6SII.js +46 -0
- package/dist/cli.js +55 -712
- package/dist/index.js +9 -5
- package/dist/serve-boot-4N3FRXVQ.js +225 -0
- package/dist/{server-CC7KUJOK.js → server-7XH7RYUX.js} +3 -2
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -4,732 +4,57 @@ import {
|
|
|
4
4
|
isLegacyEntrypointLaunch
|
|
5
5
|
} from "./chunk-R3FDJQL6.js";
|
|
6
6
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
WorkspaceCommandSupervisor,
|
|
8
|
+
startWorkspaceCommandsAfterConnect,
|
|
9
|
+
stopWorkspaceCommands
|
|
10
|
+
} from "./chunk-2L5THOWD.js";
|
|
11
|
+
import {
|
|
10
12
|
DEFAULT_SONNET_MODEL,
|
|
11
|
-
Lifecycle,
|
|
12
|
-
PortDiscovery,
|
|
13
13
|
PtyHarness,
|
|
14
14
|
SessionRunner,
|
|
15
|
-
applyBootstrapToEnv,
|
|
16
|
-
awaitGitReady,
|
|
17
15
|
buildProjectTools,
|
|
18
16
|
buildRateLimitEvents,
|
|
19
|
-
buildSessionPreviewPorts,
|
|
20
17
|
buildSynthesizedCredentials,
|
|
21
18
|
buildUnmeasurableEvent,
|
|
22
19
|
claudeJsonPath,
|
|
23
|
-
createServiceLogger,
|
|
24
|
-
fetchBootstrap,
|
|
25
20
|
isPermissionDeniedError,
|
|
26
|
-
loadConveyorConfig,
|
|
27
|
-
loadForwardPorts,
|
|
28
21
|
parseUsageGauges,
|
|
29
|
-
readWorkspaceBytes,
|
|
30
22
|
resolvePlaywrightMcpServer,
|
|
31
23
|
resolveSessionStart,
|
|
32
24
|
resolveTuiAdapter,
|
|
33
25
|
resolveTuiKindFromEnv,
|
|
34
26
|
runUsageProbe,
|
|
35
|
-
sampleKeyUsage
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
} from "./chunk-7MMECTTJ.js";
|
|
27
|
+
sampleKeyUsage
|
|
28
|
+
} from "./chunk-2SN32LM6.js";
|
|
29
|
+
import "./chunk-XORJ6SII.js";
|
|
39
30
|
import {
|
|
40
|
-
|
|
41
|
-
|
|
31
|
+
AgentConnection,
|
|
32
|
+
CodespacePortVisibility,
|
|
33
|
+
DEFAULT_LIFECYCLE_CONFIG,
|
|
34
|
+
Lifecycle,
|
|
35
|
+
PortDiscovery,
|
|
36
|
+
applyBootstrapToEnv,
|
|
37
|
+
createServiceLogger,
|
|
38
|
+
fetchBootstrap,
|
|
39
|
+
loadConveyorConfig
|
|
40
|
+
} from "./chunk-LSZ2KLJY.js";
|
|
41
|
+
import "./chunk-WMMBAKPE.js";
|
|
42
42
|
import "./chunk-IA45XHOA.js";
|
|
43
|
-
import
|
|
44
|
-
|
|
45
|
-
} from "./chunk-EXQ6AHOY.js";
|
|
46
|
-
import {
|
|
47
|
-
workbenchEnabled
|
|
48
|
-
} from "./chunk-KMB3BU4S.js";
|
|
43
|
+
import "./chunk-EXQ6AHOY.js";
|
|
44
|
+
import "./chunk-KMB3BU4S.js";
|
|
49
45
|
import {
|
|
50
46
|
inheritedEnv,
|
|
51
47
|
resolvePtySpawn,
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
terminateProcessGroup
|
|
56
|
-
} from "./chunk-GJXAAPJ6.js";
|
|
48
|
+
sessionTempBase
|
|
49
|
+
} from "./chunk-3F4ZZKCA.js";
|
|
50
|
+
import "./chunk-W4LZ7R6Z.js";
|
|
57
51
|
import "./chunk-6Q6LQBWO.js";
|
|
58
52
|
|
|
59
53
|
// src/cli.ts
|
|
60
54
|
import { readFileSync } from "fs";
|
|
61
|
-
import { join as
|
|
55
|
+
import { join as join2, dirname } from "path";
|
|
62
56
|
import { fileURLToPath } from "url";
|
|
63
57
|
|
|
64
|
-
// src/setup/sidecars.ts
|
|
65
|
-
import net from "net";
|
|
66
|
-
var POSTGRES_TIMEOUT_MS = 12e4;
|
|
67
|
-
var FIREBASE_TIMEOUT_MS = 6e4;
|
|
68
|
-
var FALLBACK_TIMEOUT_MS = 3e4;
|
|
69
|
-
var DEFAULT_SIDECAR_POLL_INTERVAL_MS = 1e3;
|
|
70
|
-
var DEFAULT_PROBE_TIMEOUT_MS = 2e3;
|
|
71
|
-
var POSTGRES_DEFAULT_PORT = 5432;
|
|
72
|
-
var FIREBASE_DEFAULT_PORT = 9099;
|
|
73
|
-
function parseHostPort(value, defaultPort) {
|
|
74
|
-
const trimmed = value.trim().replace(/^[a-z]+:\/\//i, "");
|
|
75
|
-
if (!trimmed) return null;
|
|
76
|
-
const idx = trimmed.lastIndexOf(":");
|
|
77
|
-
if (idx === -1) {
|
|
78
|
-
return { host: trimmed, port: defaultPort };
|
|
79
|
-
}
|
|
80
|
-
const host = trimmed.slice(0, idx) || "localhost";
|
|
81
|
-
const port = Number(trimmed.slice(idx + 1));
|
|
82
|
-
return { host, port: Number.isFinite(port) ? port : defaultPort };
|
|
83
|
-
}
|
|
84
|
-
function resolveSidecarTargets(env = process.env) {
|
|
85
|
-
const targets = [];
|
|
86
|
-
const databaseUrl = env.DATABASE_URL;
|
|
87
|
-
if (databaseUrl) {
|
|
88
|
-
try {
|
|
89
|
-
const url = new URL(databaseUrl);
|
|
90
|
-
const host = url.hostname || "localhost";
|
|
91
|
-
const port = url.port ? Number(url.port) : POSTGRES_DEFAULT_PORT;
|
|
92
|
-
if (Number.isFinite(port)) {
|
|
93
|
-
targets.push({ name: "postgres", host, port, timeoutMs: POSTGRES_TIMEOUT_MS });
|
|
94
|
-
}
|
|
95
|
-
} catch {
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
const firebaseHost = env.FIREBASE_AUTH_EMULATOR_HOST;
|
|
99
|
-
if (firebaseHost) {
|
|
100
|
-
const parsed = parseHostPort(firebaseHost, FIREBASE_DEFAULT_PORT);
|
|
101
|
-
if (parsed) {
|
|
102
|
-
targets.push({
|
|
103
|
-
name: "firebase auth emulator",
|
|
104
|
-
host: parsed.host,
|
|
105
|
-
port: parsed.port,
|
|
106
|
-
timeoutMs: FIREBASE_TIMEOUT_MS
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
return targets;
|
|
111
|
-
}
|
|
112
|
-
function abortError() {
|
|
113
|
-
const error = new Error("Operation aborted");
|
|
114
|
-
error.name = "AbortError";
|
|
115
|
-
return error;
|
|
116
|
-
}
|
|
117
|
-
function throwIfAborted(signal) {
|
|
118
|
-
if (signal?.aborted) throw abortError();
|
|
119
|
-
}
|
|
120
|
-
function defaultProbe(target, signal) {
|
|
121
|
-
throwIfAborted(signal);
|
|
122
|
-
return new Promise((resolve) => {
|
|
123
|
-
let settled = false;
|
|
124
|
-
const socket = net.createConnection({ host: target.host, port: target.port });
|
|
125
|
-
const done = (ok) => {
|
|
126
|
-
if (settled) return;
|
|
127
|
-
settled = true;
|
|
128
|
-
socket.destroy();
|
|
129
|
-
signal?.removeEventListener("abort", onAbort);
|
|
130
|
-
resolve(ok);
|
|
131
|
-
};
|
|
132
|
-
const onAbort = () => done(false);
|
|
133
|
-
socket.once("connect", () => done(true));
|
|
134
|
-
socket.once("error", () => done(false));
|
|
135
|
-
socket.setTimeout(DEFAULT_PROBE_TIMEOUT_MS, () => done(false));
|
|
136
|
-
signal?.addEventListener("abort", onAbort, { once: true });
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
var delay = (ms, signal) => {
|
|
140
|
-
throwIfAborted(signal);
|
|
141
|
-
return new Promise((resolve, reject) => {
|
|
142
|
-
const timer = setTimeout(() => {
|
|
143
|
-
signal?.removeEventListener("abort", onAbort);
|
|
144
|
-
resolve();
|
|
145
|
-
}, ms);
|
|
146
|
-
const onAbort = () => {
|
|
147
|
-
clearTimeout(timer);
|
|
148
|
-
reject(abortError());
|
|
149
|
-
};
|
|
150
|
-
signal?.addEventListener("abort", onAbort, { once: true });
|
|
151
|
-
});
|
|
152
|
-
};
|
|
153
|
-
function raceWithAbort(promise, signal) {
|
|
154
|
-
if (!signal) return promise;
|
|
155
|
-
throwIfAborted(signal);
|
|
156
|
-
return new Promise((resolve, reject) => {
|
|
157
|
-
const onAbort = () => reject(abortError());
|
|
158
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
159
|
-
void promise.then(
|
|
160
|
-
(value) => {
|
|
161
|
-
signal.removeEventListener("abort", onAbort);
|
|
162
|
-
resolve(value);
|
|
163
|
-
},
|
|
164
|
-
(error) => {
|
|
165
|
-
signal.removeEventListener("abort", onAbort);
|
|
166
|
-
reject(error);
|
|
167
|
-
}
|
|
168
|
-
);
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
async function waitForTarget(target, opts) {
|
|
172
|
-
const { onLog, pollIntervalMs, probe, signal } = opts;
|
|
173
|
-
const timeoutMs = opts.timeoutMs ?? target.timeoutMs ?? FALLBACK_TIMEOUT_MS;
|
|
174
|
-
const deadline = Date.now() + timeoutMs;
|
|
175
|
-
onLog(`Waiting for ${target.name} on ${target.host}:${target.port}...`);
|
|
176
|
-
while (true) {
|
|
177
|
-
throwIfAborted(signal);
|
|
178
|
-
if (await raceWithAbort(probe(target, signal), signal)) {
|
|
179
|
-
onLog(`${target.name} is ready`);
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
if (Date.now() >= deadline) {
|
|
183
|
-
onLog(
|
|
184
|
-
`WARNING: ${target.name} not ready after ${Math.round(timeoutMs / 1e3)}s, continuing anyway`
|
|
185
|
-
);
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
await delay(pollIntervalMs, signal);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
async function waitForSidecars(opts = {}) {
|
|
192
|
-
const {
|
|
193
|
-
env = process.env,
|
|
194
|
-
onLog = () => {
|
|
195
|
-
},
|
|
196
|
-
timeoutMs,
|
|
197
|
-
pollIntervalMs = DEFAULT_SIDECAR_POLL_INTERVAL_MS,
|
|
198
|
-
probe = defaultProbe,
|
|
199
|
-
signal
|
|
200
|
-
} = opts;
|
|
201
|
-
throwIfAborted(signal);
|
|
202
|
-
const targets = resolveSidecarTargets(env);
|
|
203
|
-
if (targets.length === 0) return;
|
|
204
|
-
await Promise.all(
|
|
205
|
-
targets.map(
|
|
206
|
-
(target) => waitForTarget(target, { onLog, timeoutMs, pollIntervalMs, probe, signal })
|
|
207
|
-
)
|
|
208
|
-
);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// src/setup/db-schema-sync.ts
|
|
212
|
-
import { basename, dirname, join } from "path";
|
|
213
|
-
var PRISMA_SCHEMA_CANDIDATES = [
|
|
214
|
-
"packages/db/prisma/schema.prisma",
|
|
215
|
-
"prisma/schema.prisma",
|
|
216
|
-
"apps/api/prisma/schema.prisma",
|
|
217
|
-
"packages/db/schema.prisma"
|
|
218
|
-
];
|
|
219
|
-
var PRISMA_DB_PUSH = "bunx prisma db push";
|
|
220
|
-
var SCHEMA_SYNC_TIMEOUT_MS = 18e4;
|
|
221
|
-
function depsInclude(rawDeps, dep) {
|
|
222
|
-
return (rawDeps ?? "").split(",").map((entry) => entry.trim()).includes(dep);
|
|
223
|
-
}
|
|
224
|
-
function isDisabled(env) {
|
|
225
|
-
const flag = env.CONVEYOR_DB_SCHEMA_SYNC?.trim().toLowerCase();
|
|
226
|
-
return flag === "0" || flag === "false";
|
|
227
|
-
}
|
|
228
|
-
function packageRootForSchema(schemaPath) {
|
|
229
|
-
const dir = dirname(schemaPath);
|
|
230
|
-
return basename(dir) === "prisma" ? dirname(dir) : dir;
|
|
231
|
-
}
|
|
232
|
-
async function resolveSchemaSyncPlan(options) {
|
|
233
|
-
const { workspaceDir, env } = options;
|
|
234
|
-
const pathExists = options.pathExists ?? workspacePathExists;
|
|
235
|
-
if (isDisabled(env)) return null;
|
|
236
|
-
const override = env.CONVEYOR_DB_SCHEMA_SYNC_COMMAND?.trim();
|
|
237
|
-
if (override) return { command: override, cwd: workspaceDir, source: "override" };
|
|
238
|
-
if (!depsInclude(env.CONVEYOR_DEPS, "postgresql")) return null;
|
|
239
|
-
if (!env.DATABASE_URL?.trim()) return null;
|
|
240
|
-
for (const relative of PRISMA_SCHEMA_CANDIDATES) {
|
|
241
|
-
const schemaPath = join(workspaceDir, relative);
|
|
242
|
-
if (await pathExists(schemaPath)) {
|
|
243
|
-
return { command: PRISMA_DB_PUSH, cwd: packageRootForSchema(schemaPath), source: "prisma" };
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
return null;
|
|
247
|
-
}
|
|
248
|
-
async function runDbSchemaSync(options) {
|
|
249
|
-
let plan = null;
|
|
250
|
-
try {
|
|
251
|
-
plan = await resolveSchemaSyncPlan(options);
|
|
252
|
-
} catch {
|
|
253
|
-
return "skipped";
|
|
254
|
-
}
|
|
255
|
-
if (!plan) return "skipped";
|
|
256
|
-
const { onOutput, runCommand } = options;
|
|
257
|
-
onOutput("stdout", `[db] syncing schema (${plan.source}): ${plan.command}
|
|
258
|
-
`);
|
|
259
|
-
const controller = new AbortController();
|
|
260
|
-
const abort = () => controller.abort();
|
|
261
|
-
options.signal?.addEventListener("abort", abort, { once: true });
|
|
262
|
-
const timer = setTimeout(abort, options.timeoutMs ?? SCHEMA_SYNC_TIMEOUT_MS);
|
|
263
|
-
timer.unref();
|
|
264
|
-
try {
|
|
265
|
-
await runCommand(plan.command, plan.cwd, onOutput, controller.signal);
|
|
266
|
-
onOutput("stdout", "[db] schema in sync\n");
|
|
267
|
-
return "synced";
|
|
268
|
-
} catch (error) {
|
|
269
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
270
|
-
onOutput("stderr", `[db] schema sync failed: ${message}
|
|
271
|
-
`);
|
|
272
|
-
return "failed";
|
|
273
|
-
} finally {
|
|
274
|
-
clearTimeout(timer);
|
|
275
|
-
options.signal?.removeEventListener("abort", abort);
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
// src/setup/deps-sync.ts
|
|
280
|
-
import { join as join2 } from "path";
|
|
281
|
-
var INSTALLER_SCRIPT_CANDIDATES = ["scripts/install-deps.sh"];
|
|
282
|
-
var BUN_INSTALL = "bun install --frozen-lockfile";
|
|
283
|
-
var DEPS_SYNC_TIMEOUT_MS = 9e5;
|
|
284
|
-
var REGISTRY_KEY_ENV = "NPM_CACHE_READER_KEY";
|
|
285
|
-
function isDisabled2(env) {
|
|
286
|
-
const flag = env.CONVEYOR_DEPS_SYNC?.trim().toLowerCase();
|
|
287
|
-
return flag === "0" || flag === "false";
|
|
288
|
-
}
|
|
289
|
-
var CKSUM_POLYNOMIAL = 79764919;
|
|
290
|
-
var CKSUM_TABLE = (() => {
|
|
291
|
-
const table = new Uint32Array(256);
|
|
292
|
-
for (let index = 0; index < 256; index++) {
|
|
293
|
-
let value = index << 24;
|
|
294
|
-
for (let bit = 0; bit < 8; bit++) {
|
|
295
|
-
value = value & 2147483648 ? (value << 1 ^ CKSUM_POLYNOMIAL) >>> 0 : value << 1 >>> 0;
|
|
296
|
-
}
|
|
297
|
-
table[index] = value >>> 0;
|
|
298
|
-
}
|
|
299
|
-
return table;
|
|
300
|
-
})();
|
|
301
|
-
function posixCksum(bytes) {
|
|
302
|
-
let crc = 0;
|
|
303
|
-
for (const byte of bytes) {
|
|
304
|
-
crc = (crc << 8 ^ CKSUM_TABLE[(crc >>> 24 ^ byte) & 255]) >>> 0;
|
|
305
|
-
}
|
|
306
|
-
for (let length = bytes.length; length > 0; length >>>= 8) {
|
|
307
|
-
crc = (crc << 8 ^ CKSUM_TABLE[(crc >>> 24 ^ length & 255) & 255]) >>> 0;
|
|
308
|
-
}
|
|
309
|
-
return ~crc >>> 0;
|
|
310
|
-
}
|
|
311
|
-
function bunLockFingerprint(bytes) {
|
|
312
|
-
return `${posixCksum(bytes)}:${bytes.length}`;
|
|
313
|
-
}
|
|
314
|
-
async function defaultDirExists(path) {
|
|
315
|
-
return (await statWorkspacePath(path)).isDirectory;
|
|
316
|
-
}
|
|
317
|
-
async function readLockDrift(options) {
|
|
318
|
-
const { workspaceDir, readBytes } = options;
|
|
319
|
-
let baked;
|
|
320
|
-
try {
|
|
321
|
-
const raw = await readBytes(join2(workspaceDir, ".conveyor/prebake-cache.json"));
|
|
322
|
-
const parsed = JSON.parse(Buffer.from(raw).toString("utf8"));
|
|
323
|
-
const value = parsed?.bunLockCrc;
|
|
324
|
-
if (typeof value !== "string" || !value) return null;
|
|
325
|
-
baked = value;
|
|
326
|
-
} catch {
|
|
327
|
-
return null;
|
|
328
|
-
}
|
|
329
|
-
try {
|
|
330
|
-
const actual = bunLockFingerprint(await readBytes(join2(workspaceDir, "bun.lock")));
|
|
331
|
-
return actual === baked ? null : { baked, actual };
|
|
332
|
-
} catch {
|
|
333
|
-
return null;
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
async function resolveDepsSyncPlan(options) {
|
|
337
|
-
const { workspaceDir, env } = options;
|
|
338
|
-
const pathExists = options.pathExists ?? workspacePathExists;
|
|
339
|
-
const dirExists = options.dirExists ?? defaultDirExists;
|
|
340
|
-
const readBytes = options.readBytes ?? readWorkspaceBytes;
|
|
341
|
-
if (isDisabled2(env)) return null;
|
|
342
|
-
if (!await pathExists(join2(workspaceDir, "package.json"))) return null;
|
|
343
|
-
const override = env.CONVEYOR_DEPS_SYNC_COMMAND?.trim();
|
|
344
|
-
const resolveCommand = async () => {
|
|
345
|
-
if (override) return override;
|
|
346
|
-
for (const relative of INSTALLER_SCRIPT_CANDIDATES) {
|
|
347
|
-
if (await pathExists(join2(workspaceDir, relative))) return `bash ${relative}`;
|
|
348
|
-
}
|
|
349
|
-
return BUN_INSTALL;
|
|
350
|
-
};
|
|
351
|
-
if (!await dirExists(join2(workspaceDir, "node_modules"))) {
|
|
352
|
-
return {
|
|
353
|
-
command: await resolveCommand(),
|
|
354
|
-
cwd: workspaceDir,
|
|
355
|
-
reason: "missing_node_modules",
|
|
356
|
-
detail: "the pod booted with no node_modules \u2014 the baked dependency tree is absent"
|
|
357
|
-
};
|
|
358
|
-
}
|
|
359
|
-
const drift = await readLockDrift({ workspaceDir, readBytes });
|
|
360
|
-
if (drift) {
|
|
361
|
-
return {
|
|
362
|
-
command: await resolveCommand(),
|
|
363
|
-
cwd: workspaceDir,
|
|
364
|
-
reason: "lockfile_drift",
|
|
365
|
-
detail: `bun.lock changed since the image bake (baked ${drift.baked}, checked out ${drift.actual})`
|
|
366
|
-
};
|
|
367
|
-
}
|
|
368
|
-
return null;
|
|
369
|
-
}
|
|
370
|
-
function describeFailure(plan, error, env) {
|
|
371
|
-
const cause = error instanceof Error ? error.message : String(error);
|
|
372
|
-
const parts = [
|
|
373
|
-
`Dependency install failed (${plan.reason}): ${plan.detail}.`,
|
|
374
|
-
`Ran \`${plan.command}\` in ${plan.cwd} \u2014 ${cause}.`
|
|
375
|
-
];
|
|
376
|
-
if (!env[REGISTRY_KEY_ENV]?.trim()) {
|
|
377
|
-
parts.push(
|
|
378
|
-
`${REGISTRY_KEY_ENV} is not set on this pod, so packages on the private registry cache cannot be fetched \u2014 set it as a project secret.`
|
|
379
|
-
);
|
|
380
|
-
}
|
|
381
|
-
return parts.join(" ");
|
|
382
|
-
}
|
|
383
|
-
async function runDepsSync(options) {
|
|
384
|
-
let plan = null;
|
|
385
|
-
try {
|
|
386
|
-
plan = await resolveDepsSyncPlan(options);
|
|
387
|
-
} catch {
|
|
388
|
-
return { outcome: "skipped" };
|
|
389
|
-
}
|
|
390
|
-
if (!plan) return { outcome: "skipped" };
|
|
391
|
-
const { onOutput, runCommand, env } = options;
|
|
392
|
-
onOutput("stdout", `[deps] ${plan.detail}
|
|
393
|
-
`);
|
|
394
|
-
onOutput("stdout", `[deps] installing (${plan.reason}): ${plan.command}
|
|
395
|
-
`);
|
|
396
|
-
const controller = new AbortController();
|
|
397
|
-
const abort = () => controller.abort();
|
|
398
|
-
options.signal?.addEventListener("abort", abort, { once: true });
|
|
399
|
-
const timer = setTimeout(abort, options.timeoutMs ?? DEPS_SYNC_TIMEOUT_MS);
|
|
400
|
-
timer.unref();
|
|
401
|
-
try {
|
|
402
|
-
await runCommand(plan.command, plan.cwd, onOutput, controller.signal);
|
|
403
|
-
onOutput("stdout", "[deps] dependencies installed\n");
|
|
404
|
-
return { outcome: "installed" };
|
|
405
|
-
} catch (error) {
|
|
406
|
-
const message = describeFailure(plan, error, env);
|
|
407
|
-
onOutput("stderr", `[deps] ${message}
|
|
408
|
-
`);
|
|
409
|
-
return { outcome: "failed", message };
|
|
410
|
-
} finally {
|
|
411
|
-
clearTimeout(timer);
|
|
412
|
-
options.signal?.removeEventListener("abort", abort);
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
// src/setup/workspace-command-supervisor.ts
|
|
417
|
-
function defaultCommandExecutors() {
|
|
418
|
-
if (workbenchEnabled()) {
|
|
419
|
-
const client = getWorkbenchClient();
|
|
420
|
-
return {
|
|
421
|
-
runStartCommand: (cmd, cwd, onOutput) => client.runStartCommand(cmd, cwd, onOutput),
|
|
422
|
-
runShellCommand: (cmd, cwd, onOutput, signal) => client.runSetupCommand(cmd, cwd, onOutput, signal)
|
|
423
|
-
};
|
|
424
|
-
}
|
|
425
|
-
return { runStartCommand, runShellCommand: runSetupCommand };
|
|
426
|
-
}
|
|
427
|
-
var defaultWriteOutput = (stream, data) => {
|
|
428
|
-
(stream === "stderr" ? process.stderr : process.stdout).write(data);
|
|
429
|
-
};
|
|
430
|
-
function stopWorkspaceCommands(supervisor) {
|
|
431
|
-
return supervisor?.stop() ?? Promise.resolve();
|
|
432
|
-
}
|
|
433
|
-
async function startWorkspaceCommandsAfterConnect(options) {
|
|
434
|
-
const connected = await options.connect();
|
|
435
|
-
if (!connected || options.isShuttingDown()) return null;
|
|
436
|
-
const supervisor = options.create();
|
|
437
|
-
supervisor.start();
|
|
438
|
-
return supervisor;
|
|
439
|
-
}
|
|
440
|
-
var WorkspaceCommandSupervisor = class {
|
|
441
|
-
abortController = new AbortController();
|
|
442
|
-
expectedStartCommandStops = /* @__PURE__ */ new WeakSet();
|
|
443
|
-
config;
|
|
444
|
-
workspaceDir;
|
|
445
|
-
connection;
|
|
446
|
-
env;
|
|
447
|
-
awaitGitReadyFn;
|
|
448
|
-
waitForSidecarsFn;
|
|
449
|
-
runStartCommandFn;
|
|
450
|
-
syncDbSchemaFn;
|
|
451
|
-
syncDepsFn;
|
|
452
|
-
loadForwardPortsFn;
|
|
453
|
-
writeOutput;
|
|
454
|
-
terminateStartCommand;
|
|
455
|
-
reportBootMilestoneFn;
|
|
456
|
-
startCommandChild = null;
|
|
457
|
-
liveStartCommandChildren = /* @__PURE__ */ new Set();
|
|
458
|
-
startCommandTerminations = /* @__PURE__ */ new WeakMap();
|
|
459
|
-
startCommandEndPromises = /* @__PURE__ */ new WeakMap();
|
|
460
|
-
resolveStartCommandEnd = /* @__PURE__ */ new WeakMap();
|
|
461
|
-
backgroundTasks = /* @__PURE__ */ new Set();
|
|
462
|
-
startCommandQueue = Promise.resolve();
|
|
463
|
-
shutdownPromise = null;
|
|
464
|
-
startCommandLaunchRequested = false;
|
|
465
|
-
started = false;
|
|
466
|
-
stopped = false;
|
|
467
|
-
/** Resolved by notifyLoopReady() once the PTY is live — the runner fires it
|
|
468
|
-
* on the first harness event of the initial query (or when a prefill
|
|
469
|
-
* parks), NOT after the first turn completes, so the app's start command
|
|
470
|
-
* isn't held behind a long working turn. Also resolved by stop() if
|
|
471
|
-
* shutdown arrives first — either way unblocks the awaiter in
|
|
472
|
-
* runSetupAndStart so a supervisor stopped before the loop ever signals
|
|
473
|
-
* doesn't hang its background task (and therefore stop()) forever. */
|
|
474
|
-
resolveLoopReady;
|
|
475
|
-
loopReady = new Promise((resolve) => {
|
|
476
|
-
this.resolveLoopReady = resolve;
|
|
477
|
-
});
|
|
478
|
-
constructor(options) {
|
|
479
|
-
this.config = options.config;
|
|
480
|
-
this.workspaceDir = options.workspaceDir;
|
|
481
|
-
this.connection = options.connection;
|
|
482
|
-
this.env = options.env ?? process.env;
|
|
483
|
-
this.awaitGitReadyFn = options.awaitGitReady ?? ((opts) => awaitGitReady({
|
|
484
|
-
onLog: opts.onLog,
|
|
485
|
-
signal: opts.signal
|
|
486
|
-
}));
|
|
487
|
-
this.waitForSidecarsFn = options.waitForSidecars ?? ((opts) => waitForSidecars({ onLog: opts.onLog, signal: opts.signal }));
|
|
488
|
-
const executors = defaultCommandExecutors();
|
|
489
|
-
this.runStartCommandFn = options.runStartCommand ?? executors.runStartCommand;
|
|
490
|
-
this.syncDbSchemaFn = options.syncDbSchema ?? ((opts) => runDbSchemaSync({
|
|
491
|
-
workspaceDir: this.workspaceDir,
|
|
492
|
-
env: this.env,
|
|
493
|
-
runCommand: executors.runShellCommand,
|
|
494
|
-
onOutput: opts.onOutput,
|
|
495
|
-
signal: opts.signal
|
|
496
|
-
}));
|
|
497
|
-
this.syncDepsFn = options.syncDeps ?? ((opts) => runDepsSync({
|
|
498
|
-
workspaceDir: this.workspaceDir,
|
|
499
|
-
env: this.env,
|
|
500
|
-
runCommand: executors.runShellCommand,
|
|
501
|
-
onOutput: opts.onOutput,
|
|
502
|
-
signal: opts.signal
|
|
503
|
-
}));
|
|
504
|
-
this.loadForwardPortsFn = options.loadForwardPorts ?? loadForwardPorts;
|
|
505
|
-
this.writeOutput = options.writeOutput ?? defaultWriteOutput;
|
|
506
|
-
this.terminateStartCommand = options.terminateStartCommand ?? terminateProcessGroup;
|
|
507
|
-
this.reportBootMilestoneFn = options.reportBootMilestone ?? ((key) => {
|
|
508
|
-
void reportBootMilestone({ key, env: this.env });
|
|
509
|
-
});
|
|
510
|
-
}
|
|
511
|
-
start() {
|
|
512
|
-
if (this.started || this.stopped) return;
|
|
513
|
-
this.started = true;
|
|
514
|
-
this.connection.onRunStartCommand(() => this.restartStartCommand());
|
|
515
|
-
if (this.config) {
|
|
516
|
-
this.trackBackgroundTask(
|
|
517
|
-
this.runSetupAndStart().catch((error) => this.reportUnexpectedError(error))
|
|
518
|
-
);
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
/** Release the start-command launch — called once the runner's core loop
|
|
522
|
-
* (the PTY) is live. Idempotent; resolving an already-settled promise is a
|
|
523
|
-
* no-op, so a late/duplicate call (or one after stop() already resolved
|
|
524
|
-
* it) is harmless. */
|
|
525
|
-
notifyLoopReady() {
|
|
526
|
-
this.resolveLoopReady();
|
|
527
|
-
}
|
|
528
|
-
stop() {
|
|
529
|
-
if (this.shutdownPromise) return this.shutdownPromise;
|
|
530
|
-
this.stopped = true;
|
|
531
|
-
this.resolveLoopReady();
|
|
532
|
-
this.abortController.abort();
|
|
533
|
-
const backgroundTasks = [...this.backgroundTasks];
|
|
534
|
-
const termination = this.terminateAllStartCommands();
|
|
535
|
-
this.shutdownPromise = (async () => {
|
|
536
|
-
await Promise.allSettled([termination, this.startCommandQueue, ...backgroundTasks]);
|
|
537
|
-
await this.terminateAllStartCommands();
|
|
538
|
-
})();
|
|
539
|
-
return this.shutdownPromise;
|
|
540
|
-
}
|
|
541
|
-
async runSetupAndStart() {
|
|
542
|
-
const gitState = await this.awaitGitReadyFn({
|
|
543
|
-
onLog: (message) => this.forwardSetupOutput("stdout", `[git] ${message}
|
|
544
|
-
`),
|
|
545
|
-
signal: this.abortController.signal
|
|
546
|
-
});
|
|
547
|
-
if (this.stopped) return;
|
|
548
|
-
if (gitState === "failed" || gitState === "timeout") {
|
|
549
|
-
this.connection.sendEvent({
|
|
550
|
-
type: "setup_error",
|
|
551
|
-
message: "Workspace not ready \u2014 skipping setup/start"
|
|
552
|
-
});
|
|
553
|
-
return;
|
|
554
|
-
}
|
|
555
|
-
await this.waitForSidecarsFn({
|
|
556
|
-
onLog: (message) => this.forwardSetupOutput("stdout", `[sidecars] ${message}
|
|
557
|
-
`),
|
|
558
|
-
signal: this.abortController.signal
|
|
559
|
-
});
|
|
560
|
-
if (this.stopped) return;
|
|
561
|
-
this.reportBootMilestoneFn("sidecars_ready");
|
|
562
|
-
await this.loopReady;
|
|
563
|
-
if (this.stopped) return;
|
|
564
|
-
await this.syncDeps();
|
|
565
|
-
if (this.stopped) return;
|
|
566
|
-
await this.syncDbSchema();
|
|
567
|
-
if (this.stopped) return;
|
|
568
|
-
const startCommandRunning = this.config?.startCommand ? await this.ensureStartCommandLaunched(this.config.startCommand) : false;
|
|
569
|
-
if (this.stopped) return;
|
|
570
|
-
this.reportBootMilestoneFn("start_command_launched");
|
|
571
|
-
const forwardPorts = await this.loadForwardPortsFn(this.workspaceDir);
|
|
572
|
-
if (this.stopped) return;
|
|
573
|
-
const previewPorts = buildSessionPreviewPorts(forwardPorts);
|
|
574
|
-
this.connection.sendEvent({
|
|
575
|
-
type: "setup_complete",
|
|
576
|
-
startCommandRunning,
|
|
577
|
-
// Reported separately so the server can tell "nothing to run" apart from
|
|
578
|
-
// "the dev server failed to launch" — both report startCommandRunning:false.
|
|
579
|
-
startCommandConfigured: Boolean(this.config?.startCommand),
|
|
580
|
-
...previewPorts.length > 0 ? { previewPorts } : {}
|
|
581
|
-
});
|
|
582
|
-
}
|
|
583
|
-
/** Run the dependency sync, forwarding its output as setup output so it lands
|
|
584
|
-
* in the card's setup log. A failure is announced with its own cause rather
|
|
585
|
-
* than thrown: the start command still launches, but the card now carries
|
|
586
|
-
* the reason instead of a generic `start command exited with code 1`. */
|
|
587
|
-
async syncDeps() {
|
|
588
|
-
const result = await this.syncDepsFn({
|
|
589
|
-
onOutput: (stream, data) => this.forwardSetupOutput(stream, data),
|
|
590
|
-
signal: this.abortController.signal
|
|
591
|
-
});
|
|
592
|
-
if (result.outcome !== "failed" || this.stopped) return;
|
|
593
|
-
this.connection.sendEvent({
|
|
594
|
-
type: "setup_error",
|
|
595
|
-
message: result.message ?? "Dependency install failed \u2014 the start command will fail until dependencies are installed (see pod logs)"
|
|
596
|
-
});
|
|
597
|
-
}
|
|
598
|
-
/** Run the schema sync, forwarding its output as setup output so it lands in
|
|
599
|
-
* the card's setup log. A failure is announced rather than thrown: it is the
|
|
600
|
-
* exact condition that used to render as a silent "Displaying 0 results". */
|
|
601
|
-
async syncDbSchema() {
|
|
602
|
-
const outcome = await this.syncDbSchemaFn({
|
|
603
|
-
onOutput: (stream, data) => this.forwardSetupOutput(stream, data),
|
|
604
|
-
signal: this.abortController.signal
|
|
605
|
-
});
|
|
606
|
-
if (outcome !== "failed" || this.stopped) return;
|
|
607
|
-
this.connection.sendEvent({
|
|
608
|
-
type: "setup_error",
|
|
609
|
-
message: "Database schema sync failed \u2014 the app may error on queries touching recently added columns (see pod logs)"
|
|
610
|
-
});
|
|
611
|
-
}
|
|
612
|
-
restartStartCommand() {
|
|
613
|
-
if (this.stopped || !this.config?.startCommand) return;
|
|
614
|
-
this.connection.sendEvent({
|
|
615
|
-
type: "start_command_output",
|
|
616
|
-
stream: "stdout",
|
|
617
|
-
data: "[conveyor-agent] Restarting start command...\n"
|
|
618
|
-
});
|
|
619
|
-
void this.enqueueStartCommandReplacement(this.config.startCommand);
|
|
620
|
-
}
|
|
621
|
-
async ensureStartCommandLaunched(command) {
|
|
622
|
-
if (!this.startCommandLaunchRequested) {
|
|
623
|
-
return this.enqueueStartCommandReplacement(command);
|
|
624
|
-
}
|
|
625
|
-
await this.startCommandQueue;
|
|
626
|
-
return !this.stopped && this.liveStartCommandChildren.size > 0;
|
|
627
|
-
}
|
|
628
|
-
enqueueStartCommandReplacement(command) {
|
|
629
|
-
this.startCommandLaunchRequested = true;
|
|
630
|
-
const operation = this.startCommandQueue.then(async () => {
|
|
631
|
-
if (this.stopped) return false;
|
|
632
|
-
await this.terminateAllStartCommands();
|
|
633
|
-
if (this.stopped) return false;
|
|
634
|
-
return this.launchStartCommand(command);
|
|
635
|
-
});
|
|
636
|
-
this.startCommandQueue = operation.then(
|
|
637
|
-
() => void 0,
|
|
638
|
-
() => void 0
|
|
639
|
-
);
|
|
640
|
-
return operation;
|
|
641
|
-
}
|
|
642
|
-
launchStartCommand(command) {
|
|
643
|
-
if (this.stopped) return false;
|
|
644
|
-
this.connection.sendEvent({ type: "start_command_started" });
|
|
645
|
-
try {
|
|
646
|
-
const child = this.runStartCommandFn(command, this.workspaceDir, (stream, data) => {
|
|
647
|
-
if (this.stopped) return;
|
|
648
|
-
this.connection.sendEvent({ type: "start_command_output", stream, data });
|
|
649
|
-
this.writeOutput(stream, data);
|
|
650
|
-
});
|
|
651
|
-
this.liveStartCommandChildren.add(child);
|
|
652
|
-
const ended = new Promise((resolve) => {
|
|
653
|
-
this.resolveStartCommandEnd.set(child, resolve);
|
|
654
|
-
});
|
|
655
|
-
this.startCommandEndPromises.set(child, ended);
|
|
656
|
-
if (this.stopped) {
|
|
657
|
-
void this.terminateStartCommandChild(child);
|
|
658
|
-
return false;
|
|
659
|
-
}
|
|
660
|
-
this.startCommandChild = child;
|
|
661
|
-
child.on("exit", (code, signal) => {
|
|
662
|
-
if (this.startCommandChild === child) this.startCommandChild = null;
|
|
663
|
-
this.liveStartCommandChildren.delete(child);
|
|
664
|
-
this.settleStartCommandEnd(child);
|
|
665
|
-
if (this.stopped || this.expectedStartCommandStops.has(child)) return;
|
|
666
|
-
const message = `start command exited${code === null ? "" : ` with code ${code}`}${signal ? ` (signal: ${signal})` : ""}`;
|
|
667
|
-
this.connection.sendEvent({ type: "start_command_exited", code, signal, message });
|
|
668
|
-
if (code !== null && code !== 0) {
|
|
669
|
-
this.connection.sendEvent({
|
|
670
|
-
type: "start_command_error",
|
|
671
|
-
message: `start command exited with code ${code}${signal ? ` (signal: ${signal})` : ""}`
|
|
672
|
-
});
|
|
673
|
-
}
|
|
674
|
-
});
|
|
675
|
-
child.on("error", (error) => {
|
|
676
|
-
if (child.pid === void 0) {
|
|
677
|
-
if (this.startCommandChild === child) this.startCommandChild = null;
|
|
678
|
-
this.liveStartCommandChildren.delete(child);
|
|
679
|
-
this.settleStartCommandEnd(child);
|
|
680
|
-
this.startCommandTerminations.delete(child);
|
|
681
|
-
}
|
|
682
|
-
if (this.stopped) return;
|
|
683
|
-
this.connection.sendEvent({ type: "start_command_error", message: error.message });
|
|
684
|
-
});
|
|
685
|
-
return true;
|
|
686
|
-
} catch (error) {
|
|
687
|
-
if (!this.stopped) {
|
|
688
|
-
this.connection.sendEvent({
|
|
689
|
-
type: "start_command_error",
|
|
690
|
-
message: error instanceof Error ? error.message : String(error)
|
|
691
|
-
});
|
|
692
|
-
}
|
|
693
|
-
return false;
|
|
694
|
-
}
|
|
695
|
-
}
|
|
696
|
-
terminateStartCommandChild(child) {
|
|
697
|
-
const existing = this.startCommandTerminations.get(child);
|
|
698
|
-
if (existing) return existing;
|
|
699
|
-
this.expectedStartCommandStops.add(child);
|
|
700
|
-
const processTermination = Promise.resolve(this.terminateStartCommand(child));
|
|
701
|
-
const ended = this.startCommandEndPromises.get(child);
|
|
702
|
-
const termination = (ended ? Promise.race([processTermination, ended]) : processTermination).then(() => void 0).finally(() => this.startCommandTerminations.delete(child));
|
|
703
|
-
this.startCommandTerminations.set(child, termination);
|
|
704
|
-
return termination;
|
|
705
|
-
}
|
|
706
|
-
async terminateAllStartCommands() {
|
|
707
|
-
const live = [...this.liveStartCommandChildren].filter((child) => child.exitCode === null);
|
|
708
|
-
await Promise.all(live.map((child) => this.terminateStartCommandChild(child)));
|
|
709
|
-
}
|
|
710
|
-
settleStartCommandEnd(child) {
|
|
711
|
-
this.resolveStartCommandEnd.get(child)?.();
|
|
712
|
-
this.resolveStartCommandEnd.delete(child);
|
|
713
|
-
this.startCommandEndPromises.delete(child);
|
|
714
|
-
}
|
|
715
|
-
trackBackgroundTask(task) {
|
|
716
|
-
this.backgroundTasks.add(task);
|
|
717
|
-
void task.finally(() => this.backgroundTasks.delete(task));
|
|
718
|
-
}
|
|
719
|
-
forwardSetupOutput(stream, data) {
|
|
720
|
-
if (this.stopped) return;
|
|
721
|
-
this.connection.sendEvent({ type: "setup_output", stream, data });
|
|
722
|
-
this.writeOutput(stream, data);
|
|
723
|
-
}
|
|
724
|
-
reportUnexpectedError(error) {
|
|
725
|
-
if (this.stopped) return;
|
|
726
|
-
this.connection.sendEvent({
|
|
727
|
-
type: "setup_error",
|
|
728
|
-
message: error instanceof Error ? error.message : String(error)
|
|
729
|
-
});
|
|
730
|
-
}
|
|
731
|
-
};
|
|
732
|
-
|
|
733
58
|
// src/utils/session-identity.ts
|
|
734
59
|
async function checkSessionTaskIdentity(params) {
|
|
735
60
|
const { sessionId, taskId, fetchSessionTaskId, logger: logger6 } = params;
|
|
@@ -929,7 +254,7 @@ var ProjectSessionRunner = class {
|
|
|
929
254
|
|
|
930
255
|
// src/usage/multi-key-probe.ts
|
|
931
256
|
import { mkdtemp, writeFile, copyFile, rm } from "fs/promises";
|
|
932
|
-
import { join
|
|
257
|
+
import { join } from "path";
|
|
933
258
|
var logger = createServiceLogger("multi-key-probe");
|
|
934
259
|
function gaugesToSamples(stdout) {
|
|
935
260
|
const { sessionUsage, weeklyUsage, sessionResetsAt, weeklyResetsAt, gauges } = parseUsageGauges(stdout);
|
|
@@ -957,12 +282,12 @@ function gaugesToSamples(stdout) {
|
|
|
957
282
|
async function isolatedProbe(token, now) {
|
|
958
283
|
let dir = null;
|
|
959
284
|
try {
|
|
960
|
-
dir = await mkdtemp(
|
|
961
|
-
await writeFile(
|
|
285
|
+
dir = await mkdtemp(join(sessionTempBase(), "conveyor-usage-"));
|
|
286
|
+
await writeFile(join(dir, ".credentials.json"), buildSynthesizedCredentials(token, now), {
|
|
962
287
|
encoding: "utf8",
|
|
963
288
|
mode: 384
|
|
964
289
|
});
|
|
965
|
-
await copyFile(claudeJsonPath(),
|
|
290
|
+
await copyFile(claudeJsonPath(), join(dir, ".claude.json")).catch(() => {
|
|
966
291
|
});
|
|
967
292
|
return await runUsageProbe({ env: { ...process.env, CLAUDE_CONFIG_DIR: dir } });
|
|
968
293
|
} catch (error) {
|
|
@@ -1715,7 +1040,7 @@ function hostsSpawnedChildren(mode) {
|
|
|
1715
1040
|
|
|
1716
1041
|
// src/cli.ts
|
|
1717
1042
|
if (process.argv[2] === "boot") {
|
|
1718
|
-
const { runBoot } = await import("./boot-
|
|
1043
|
+
const { runBoot } = await import("./boot-ZNL7X5LQ.js");
|
|
1719
1044
|
process.exit(await runBoot(process.argv.slice(3)));
|
|
1720
1045
|
}
|
|
1721
1046
|
if (isLegacyEntrypointLaunch(process.env)) {
|
|
@@ -1724,8 +1049,8 @@ if (isLegacyEntrypointLaunch(process.env)) {
|
|
|
1724
1049
|
process.exit(1);
|
|
1725
1050
|
}
|
|
1726
1051
|
if (process.argv.includes("--version")) {
|
|
1727
|
-
const __dirname =
|
|
1728
|
-
const pkgPath =
|
|
1052
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
1053
|
+
const pkgPath = join2(__dirname, "..", "package.json");
|
|
1729
1054
|
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
1730
1055
|
process.stdout.write(pkg.version + "\n");
|
|
1731
1056
|
process.exit(0);
|
|
@@ -1817,7 +1142,7 @@ process.on("unhandledRejection", (reason) => {
|
|
|
1817
1142
|
process.exit(1);
|
|
1818
1143
|
});
|
|
1819
1144
|
if (process.env.CONVEYOR_MODE === "workbench") {
|
|
1820
|
-
const { startWorkbenchServer } = await import("./server-
|
|
1145
|
+
const { startWorkbenchServer } = await import("./server-7XH7RYUX.js");
|
|
1821
1146
|
const { oomWatchdogOptionsFromEnv } = await import("./oom-watchdog-PAC5OJJG.js");
|
|
1822
1147
|
const { DEFAULT_WORKBENCH_PORT } = await import("./protocol-QBCYO4GI.js");
|
|
1823
1148
|
const port = Number(process.env.CONVEYOR_WORKBENCH_PORT) || DEFAULT_WORKBENCH_PORT;
|
|
@@ -1826,8 +1151,8 @@ if (process.env.CONVEYOR_MODE === "workbench") {
|
|
|
1826
1151
|
logger5.error("workbench mode requires POD_BOOTSTRAP_TOKEN (or CONVEYOR_WORKBENCH_TOKEN)");
|
|
1827
1152
|
process.exit(1);
|
|
1828
1153
|
}
|
|
1829
|
-
const pkgDir =
|
|
1830
|
-
const pkg = JSON.parse(readFileSync(
|
|
1154
|
+
const pkgDir = dirname(fileURLToPath(import.meta.url));
|
|
1155
|
+
const pkg = JSON.parse(readFileSync(join2(pkgDir, "..", "package.json"), "utf-8"));
|
|
1831
1156
|
const handle = await startWorkbenchServer({
|
|
1832
1157
|
port,
|
|
1833
1158
|
token,
|
|
@@ -1962,13 +1287,31 @@ if (!CONVEYOR_TASK_TOKEN || !CONVEYOR_TASK_ID) {
|
|
|
1962
1287
|
);
|
|
1963
1288
|
process.exit(1);
|
|
1964
1289
|
}
|
|
1965
|
-
if (CONVEYOR_MODE !== "task" && CONVEYOR_MODE !== "pm" && CONVEYOR_MODE !== "code-review" && CONVEYOR_MODE !== "adhoc" && CONVEYOR_MODE !== "pack" && CONVEYOR_MODE !== "shell") {
|
|
1290
|
+
if (CONVEYOR_MODE !== "task" && CONVEYOR_MODE !== "pm" && CONVEYOR_MODE !== "code-review" && CONVEYOR_MODE !== "adhoc" && CONVEYOR_MODE !== "pack" && CONVEYOR_MODE !== "shell" && CONVEYOR_MODE !== "serving") {
|
|
1966
1291
|
logger5.error("Invalid CONVEYOR_MODE", {
|
|
1967
1292
|
mode: CONVEYOR_MODE,
|
|
1968
|
-
expected: ["task", "pm", "code-review", "adhoc", "pack", "shell"]
|
|
1293
|
+
expected: ["task", "pm", "code-review", "adhoc", "pack", "shell", "serving"]
|
|
1969
1294
|
});
|
|
1970
1295
|
process.exit(1);
|
|
1971
1296
|
}
|
|
1297
|
+
if (CONVEYOR_MODE === "serving") {
|
|
1298
|
+
const { runServingSession } = await import("./serve-boot-4N3FRXVQ.js");
|
|
1299
|
+
exitContext.runnerMode = "serving";
|
|
1300
|
+
exitContext.sessionId = process.env.CONVEYOR_SESSION_ID ?? exitContext.sessionId;
|
|
1301
|
+
const outcome = await runServingSession({
|
|
1302
|
+
apiUrl: conveyorApiUrl ?? "",
|
|
1303
|
+
taskToken: CONVEYOR_TASK_TOKEN,
|
|
1304
|
+
sessionId: process.env.CONVEYOR_SESSION_ID,
|
|
1305
|
+
taskId: CONVEYOR_TASK_ID,
|
|
1306
|
+
workspaceDir: CONVEYOR_WORKSPACE,
|
|
1307
|
+
// BRANCH is the bundle gitPlan's branch (boot/bundle.ts buildChildEnv):
|
|
1308
|
+
// the branch the preview must check out and serve.
|
|
1309
|
+
branch: process.env.BRANCH,
|
|
1310
|
+
onSignal: () => void (shuttingDown = true)
|
|
1311
|
+
});
|
|
1312
|
+
logAgentExit(outcome.reason, { exitCode: outcome.exitCode, finalState: outcome.finalState });
|
|
1313
|
+
process.exit(outcome.exitCode);
|
|
1314
|
+
}
|
|
1972
1315
|
if (CONVEYOR_MODE === "shell" || CONVEYOR_MODE === "adhoc") {
|
|
1973
1316
|
const spawnedSessionId = process.env.CONVEYOR_SESSION_ID;
|
|
1974
1317
|
if (!spawnedSessionId) {
|