@pushpalsdev/cli 1.1.16 → 1.1.18
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/pushpals-cli.js
CHANGED
|
@@ -1641,6 +1641,7 @@ var DEFAULT_REMOTEBUDDY_CONSUMER_STARTUP_GRACE_MS = 8000;
|
|
|
1641
1641
|
var DEFAULT_COMMAND_OUTPUT_DRAIN_TIMEOUT_MS = 2000;
|
|
1642
1642
|
var DEFAULT_COMMAND_OUTPUT_MAX_CHARS = 512000;
|
|
1643
1643
|
var DEFAULT_REMOTEBUDDY_SILENT_STARTUP_FALLBACK_MS = 20000;
|
|
1644
|
+
var DEFAULT_WORKERPAL_STARTUP_STATUS_FETCH_TIMEOUT_MS = 2000;
|
|
1644
1645
|
var WINDOWS_TASKKILL_TIMEOUT_MS2 = 5000;
|
|
1645
1646
|
var RUNTIME_BINARY_DOWNLOAD_ATTEMPTS = 3;
|
|
1646
1647
|
var DEFAULT_STARTUP_GIT_PROBE_TIMEOUT_MS = 5000;
|
|
@@ -1648,6 +1649,7 @@ var DEFAULT_STARTUP_GIT_REMOTE_TIMEOUT_MS = 1e4;
|
|
|
1648
1649
|
var DEFAULT_EMBEDDED_SERVICE_LAUNCH_WARN_MS = 5000;
|
|
1649
1650
|
var EMBEDDED_SERVICE_RESTART_MAX_ATTEMPTS = 4;
|
|
1650
1651
|
var WORKERPAL_STARTUP_READINESS_PROBE_MAX_MS = 15000;
|
|
1652
|
+
var BLOCKING_WORKERPAL_IMAGE_BUILD_ENV = "PUSHPALS_BLOCKING_WORKERPAL_IMAGE_BUILD";
|
|
1651
1653
|
var CLI_SESSION_JOB_LOG_MAX_CHARS = 700;
|
|
1652
1654
|
var CLI_SESSION_SHOW_JOB_EVENTS_ENV = "PUSHPALS_CLI_SHOW_JOB_EVENTS";
|
|
1653
1655
|
var EMBEDDED_RUNTIME_SAFETY_CAP_DISABLE_ENV = "PUSHPALS_DISABLE_EMBEDDED_SAFETY_CAPS";
|
|
@@ -3900,6 +3902,13 @@ function resolveWorkerpalCapacityTimeoutMs(config) {
|
|
|
3900
3902
|
function resolveWorkerpalStartupReadinessProbeTimeoutMs(config) {
|
|
3901
3903
|
return Math.max(5000, Math.min(resolveWorkerpalCapacityTimeoutMs(config), WORKERPAL_STARTUP_READINESS_PROBE_MAX_MS));
|
|
3902
3904
|
}
|
|
3905
|
+
function shouldPrepareEmbeddedWorkerpalDockerImageBlocking(opts = {}) {
|
|
3906
|
+
const env = opts.env ?? process.env;
|
|
3907
|
+
const explicit = String(env[BLOCKING_WORKERPAL_IMAGE_BUILD_ENV] ?? "").trim();
|
|
3908
|
+
if (explicit)
|
|
3909
|
+
return isTruthyCliEnvValue(explicit);
|
|
3910
|
+
return (opts.platform ?? process.platform) !== "win32";
|
|
3911
|
+
}
|
|
3903
3912
|
function shouldRunEmbeddedRuntimeStartupPrechecks(opts) {
|
|
3904
3913
|
return !opts.serverHealthy && !opts.noAutoStart;
|
|
3905
3914
|
}
|
|
@@ -4287,8 +4296,8 @@ async function probeSourceControlManager(port) {
|
|
|
4287
4296
|
return false;
|
|
4288
4297
|
}
|
|
4289
4298
|
}
|
|
4290
|
-
async function fetchWorkerStatusRows(serverUrl, ttlMs) {
|
|
4291
|
-
const payload = await fetchJsonWithTimeout(`${serverUrl}/workers?ttlMs=${Math.max(1000, Math.floor(ttlMs))}`, {},
|
|
4299
|
+
async function fetchWorkerStatusRows(serverUrl, ttlMs, timeoutMs = 1e4) {
|
|
4300
|
+
const payload = await fetchJsonWithTimeout(`${serverUrl}/workers?ttlMs=${Math.max(1000, Math.floor(ttlMs))}`, {}, Math.max(250, Math.floor(timeoutMs)));
|
|
4292
4301
|
if (!payload?.ok || !Array.isArray(payload.workers)) {
|
|
4293
4302
|
return [];
|
|
4294
4303
|
}
|
|
@@ -4298,7 +4307,8 @@ async function waitForWorkerpalCapacity(opts) {
|
|
|
4298
4307
|
const deadline = Date.now() + Math.max(1000, opts.timeoutMs);
|
|
4299
4308
|
let lastObservedOnline = 0;
|
|
4300
4309
|
while (Date.now() < deadline) {
|
|
4301
|
-
const
|
|
4310
|
+
const remainingMs = Math.max(250, deadline - Date.now());
|
|
4311
|
+
const workers = await (opts.fetchWorkersFn ?? fetchWorkerStatusRows)(opts.serverUrl, opts.ttlMs, Math.min(DEFAULT_WORKERPAL_STARTUP_STATUS_FETCH_TIMEOUT_MS, remainingMs));
|
|
4302
4312
|
const summary = summarizeWorkerStatusRows(workers);
|
|
4303
4313
|
if (summary.onlineWorkers > 0) {
|
|
4304
4314
|
lastObservedOnline = Math.max(lastObservedOnline, summary.onlineWorkers);
|
|
@@ -5726,7 +5736,10 @@ async function main() {
|
|
|
5726
5736
|
console.error("[pushpals] Precheck failed: start Docker Desktop or the Docker daemon, then retry pushpals.");
|
|
5727
5737
|
process.exit(1);
|
|
5728
5738
|
}
|
|
5729
|
-
if (runEmbeddedRuntimeStartupPrechecks && workerpalDockerPrecheck.status !== "failed"
|
|
5739
|
+
if (runEmbeddedRuntimeStartupPrechecks && workerpalDockerPrecheck.status !== "failed" && shouldPrepareEmbeddedWorkerpalDockerImageBlocking({
|
|
5740
|
+
platform: process.platform,
|
|
5741
|
+
env: process.env
|
|
5742
|
+
})) {
|
|
5730
5743
|
const workerpalImagePrecheck = await prepareEmbeddedWorkerpalDockerImageIfNeeded({
|
|
5731
5744
|
preparedRuntime,
|
|
5732
5745
|
config,
|
|
@@ -5740,6 +5753,8 @@ async function main() {
|
|
|
5740
5753
|
if (workerpalImagePrecheck.runtimeTag) {
|
|
5741
5754
|
resolvedRuntimeTagForAutoStart = workerpalImagePrecheck.runtimeTag;
|
|
5742
5755
|
}
|
|
5756
|
+
} else if (runEmbeddedRuntimeStartupPrechecks && workerpalDockerPrecheck.status !== "failed") {
|
|
5757
|
+
console.log(`[pushpals] Skipping blocking WorkerPal sandbox image build during CLI startup; WorkerPal warmup will prepare it in the background. Set ${BLOCKING_WORKERPAL_IMAGE_BUILD_ENV}=1 to force the old foreground behavior.`);
|
|
5743
5758
|
}
|
|
5744
5759
|
let remoteBuddyConsumerHealth = {
|
|
5745
5760
|
ok: false,
|
|
@@ -6064,6 +6079,7 @@ export {
|
|
|
6064
6079
|
shouldShowCliSessionOperationalEvents,
|
|
6065
6080
|
shouldRunEmbeddedRuntimeStartupPrechecks,
|
|
6066
6081
|
shouldRestartEmbeddedService,
|
|
6082
|
+
shouldPrepareEmbeddedWorkerpalDockerImageBlocking,
|
|
6067
6083
|
shouldDeferRemoteBuddySessionConsumerReadiness,
|
|
6068
6084
|
runCommandWithEnv,
|
|
6069
6085
|
resolveWorkerpalDockerProbe,
|
package/package.json
CHANGED
|
@@ -1213,16 +1213,7 @@ export class DockerExecutor {
|
|
|
1213
1213
|
);
|
|
1214
1214
|
await this.ensureWorktreeDependencyArtifacts(containerWorktreePath, onLog);
|
|
1215
1215
|
|
|
1216
|
-
const args
|
|
1217
|
-
"exec",
|
|
1218
|
-
"-w",
|
|
1219
|
-
containerWorktreePath,
|
|
1220
|
-
this.warmContainerName,
|
|
1221
|
-
"bun",
|
|
1222
|
-
"run",
|
|
1223
|
-
"/workspace/apps/workerpals/src/job_runner.ts",
|
|
1224
|
-
"--spec-stdin",
|
|
1225
|
-
];
|
|
1216
|
+
const args = this.buildWarmContainerExecArgs(containerWorktreePath);
|
|
1226
1217
|
|
|
1227
1218
|
console.log(
|
|
1228
1219
|
`[DockerExecutor] Running job in warm container: ${this.warmContainerName} (${this.executionConfigSummary()})`,
|
|
@@ -1321,26 +1312,62 @@ export class DockerExecutor {
|
|
|
1321
1312
|
return result;
|
|
1322
1313
|
}
|
|
1323
1314
|
|
|
1315
|
+
private buildWarmContainerExecArgs(containerWorktreePath: string): string[] {
|
|
1316
|
+
return [
|
|
1317
|
+
"exec",
|
|
1318
|
+
"-i",
|
|
1319
|
+
"-w",
|
|
1320
|
+
containerWorktreePath,
|
|
1321
|
+
this.warmContainerName,
|
|
1322
|
+
"bun",
|
|
1323
|
+
"run",
|
|
1324
|
+
"/workspace/apps/workerpals/src/job_runner.ts",
|
|
1325
|
+
"--spec-stdin",
|
|
1326
|
+
];
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1324
1329
|
private async writeJobSpecToStdin(
|
|
1325
1330
|
proc: ReturnType<typeof Bun.spawn>,
|
|
1326
1331
|
base64Spec: string,
|
|
1327
1332
|
): Promise<void> {
|
|
1328
|
-
const stdin = proc.stdin as
|
|
1333
|
+
const stdin = proc.stdin as
|
|
1334
|
+
| WritableStream<Uint8Array>
|
|
1335
|
+
| {
|
|
1336
|
+
write?: (chunk: Uint8Array | string) => unknown;
|
|
1337
|
+
end?: () => unknown;
|
|
1338
|
+
flush?: () => unknown;
|
|
1339
|
+
}
|
|
1340
|
+
| undefined;
|
|
1329
1341
|
if (!stdin) {
|
|
1330
1342
|
throw new Error("docker exec stdin pipe was not available");
|
|
1331
1343
|
}
|
|
1332
|
-
const
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
await writer.close();
|
|
1336
|
-
} catch (err) {
|
|
1344
|
+
const bytes = new TextEncoder().encode(base64Spec);
|
|
1345
|
+
if ("getWriter" in stdin && typeof stdin.getWriter === "function") {
|
|
1346
|
+
const writer = stdin.getWriter();
|
|
1337
1347
|
try {
|
|
1338
|
-
await writer.
|
|
1339
|
-
|
|
1340
|
-
|
|
1348
|
+
await writer.write(bytes);
|
|
1349
|
+
await writer.close();
|
|
1350
|
+
} catch (err) {
|
|
1351
|
+
try {
|
|
1352
|
+
await writer.abort(err);
|
|
1353
|
+
} catch {
|
|
1354
|
+
// Ignore abort failures; the original write error is more useful.
|
|
1355
|
+
}
|
|
1356
|
+
throw err;
|
|
1341
1357
|
}
|
|
1342
|
-
|
|
1358
|
+
return;
|
|
1343
1359
|
}
|
|
1360
|
+
|
|
1361
|
+
if (typeof stdin.write === "function" && typeof stdin.end === "function") {
|
|
1362
|
+
await stdin.write(bytes);
|
|
1363
|
+
if (typeof stdin.flush === "function") {
|
|
1364
|
+
await stdin.flush();
|
|
1365
|
+
}
|
|
1366
|
+
await stdin.end();
|
|
1367
|
+
return;
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1370
|
+
throw new Error("docker exec stdin pipe does not support write/end or getWriter");
|
|
1344
1371
|
}
|
|
1345
1372
|
|
|
1346
1373
|
private async ensureWorktreeDependencyArtifacts(
|