@rudderhq/cli 0.7.12 → 0.7.14

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/index.js CHANGED
@@ -474,6 +474,15 @@ var init_rudder_mcp_tool_descriptors_generated = __esm({
474
474
  "requiresAgentId": false,
475
475
  "attachesRunIdWhenAvailable": true
476
476
  },
477
+ {
478
+ "capabilityId": "issue.create",
479
+ "name": "rudder_issue_create",
480
+ "description": "Create a new issue or subtask with the generic issue surface; agent-created issues default to the creating agent when no assignee is supplied.",
481
+ "mutating": true,
482
+ "requiresOrgId": true,
483
+ "requiresAgentId": false,
484
+ "attachesRunIdWhenAvailable": true
485
+ },
477
486
  {
478
487
  "capabilityId": "approval.get",
479
488
  "name": "rudder_approval_get",
@@ -1477,6 +1486,20 @@ function coreMcpInputSchema(id) {
1477
1486
  riskSummary: string("Known risks, limitations, or remaining gaps."),
1478
1487
  idempotencyKey: string("Stable key for safe retry.", { maxLength: 500 })
1479
1488
  }, ["goal", "contractRevision", "criteria", "evidenceRefs", "riskSummary", "idempotencyKey"]);
1489
+ case "issue.create":
1490
+ return schema({
1491
+ title: string("Issue title.", { maxLength: 500 }),
1492
+ description: string("Issue description.", { maxLength: 5e5 }),
1493
+ status: string("Issue status.", { maxLength: 100 }),
1494
+ priority: string("Issue priority.", { maxLength: 100 }),
1495
+ assigneeAgentId: string("Assignee agent id or reference.", { maxLength: 200 }),
1496
+ projectId: string("Project id or reference.", { maxLength: 200 }),
1497
+ goalId: string("Goal id or reference.", { maxLength: 200 }),
1498
+ parentId: string("Parent issue id or reference.", { maxLength: 200 }),
1499
+ requestDepth: number("Requested issue depth.", 0, 1e4),
1500
+ billingCode: string("Billing code.", { maxLength: 200 }),
1501
+ labelIds: strings("Issue label ids.", 100)
1502
+ }, ["title"]);
1480
1503
  case "issue.list":
1481
1504
  return schema({
1482
1505
  status: string("Comma-separated issue statuses.", { maxLength: 500 }),
@@ -2397,6 +2420,7 @@ var init_constants = __esm({
2397
2420
  "rudder_library_file_ref",
2398
2421
  "rudder_library_file_link",
2399
2422
  "rudder_library_file_put",
2423
+ "rudder_issue_create",
2400
2424
  "rudder_approval_get",
2401
2425
  "rudder_approval_issues",
2402
2426
  "rudder_approval_comment",
@@ -7440,6 +7464,7 @@ import { execFile } from "node:child_process";
7440
7464
  import { existsSync as existsSync3 } from "node:fs";
7441
7465
  import fs6 from "node:fs/promises";
7442
7466
  import path8 from "node:path";
7467
+ import { performance } from "node:perf_hooks";
7443
7468
  import { fileURLToPath as fileURLToPath3 } from "node:url";
7444
7469
  import { promisify } from "node:util";
7445
7470
  function nativeTarget() {
@@ -7472,14 +7497,14 @@ function parseEnvelope(stdout, capability) {
7472
7497
  }
7473
7498
  return envelope;
7474
7499
  }
7475
- async function runNativePayload(capability, args, commandMayAccept) {
7500
+ async function runNativePayload(capability, args, commandMayAccept, timeoutMs = TIMEOUT_MS) {
7476
7501
  let stdout = "";
7477
7502
  let stderr = "";
7478
7503
  try {
7479
7504
  const command = resolveNativeCommand(resolveNativePayloadBinary(), args);
7480
7505
  const result = await execFileAsync(command.command, command.args, {
7481
7506
  encoding: "utf8",
7482
- timeout: TIMEOUT_MS,
7507
+ timeout: Math.max(1, Math.min(TIMEOUT_MS, timeoutMs)),
7483
7508
  maxBuffer: OUTPUT_LIMIT_BYTES,
7484
7509
  windowsHide: true
7485
7510
  });
@@ -7498,6 +7523,9 @@ async function runNativePayload(capability, args, commandMayAccept) {
7498
7523
  envelope2
7499
7524
  );
7500
7525
  }
7526
+ if (detail.code === "ETIMEDOUT" || detail.killed === true || detail.signal === "SIGTERM") {
7527
+ throw new NativePayloadError("deadline_exceeded", commandMayAccept, detail.code ?? detail.signal);
7528
+ }
7501
7529
  const failedBeforeSpawn = detail.code === "ENOENT" || detail.code === "EACCES";
7502
7530
  throw new NativePayloadError("process_failed", commandMayAccept && !failedBeforeSpawn, stderr || detail.code);
7503
7531
  }
@@ -7520,16 +7548,16 @@ function nativePayloadPolicy() {
7520
7548
  legacyToggleEnvs: ["RUDDER_NATIVE_RUNTIME_PAYLOAD"]
7521
7549
  });
7522
7550
  }
7523
- async function verifyNativePayload(archivePath, expectedSha256, maxArchiveBytes) {
7551
+ async function verifyNativePayload(archivePath, expectedSha256, maxArchiveBytes, timeoutMs) {
7524
7552
  return runNativePayload("payload.verify", [
7525
7553
  "payload",
7526
7554
  "verify",
7527
7555
  path8.resolve(archivePath),
7528
7556
  expectedSha256,
7529
7557
  String(maxArchiveBytes)
7530
- ], false);
7558
+ ], false, timeoutMs);
7531
7559
  }
7532
- async function extractNativePayload(archivePath, stagingPath, maxArchiveBytes) {
7560
+ async function extractNativePayload(archivePath, stagingPath, maxArchiveBytes, timeoutMs) {
7533
7561
  try {
7534
7562
  return await runNativePayload("payload.extract", [
7535
7563
  "payload",
@@ -7541,7 +7569,7 @@ async function extractNativePayload(archivePath, stagingPath, maxArchiveBytes) {
7541
7569
  String(maxArchiveBytes),
7542
7570
  String(maxArchiveBytes * 2),
7543
7571
  "0"
7544
- ], true);
7572
+ ], true, timeoutMs);
7545
7573
  } catch (error) {
7546
7574
  if (error instanceof NativePayloadError && error.code === "process_failed" && !existsSync3(stagingPath)) {
7547
7575
  throw new NativePayloadError("process_failed", false, error.message);
@@ -7549,24 +7577,53 @@ async function extractNativePayload(archivePath, stagingPath, maxArchiveBytes) {
7549
7577
  throw error;
7550
7578
  }
7551
7579
  }
7552
- async function probeNativePayloadVersion(rootPath, executable) {
7580
+ async function probeNativePayloadVersion(rootPath, executable, timeoutMs) {
7553
7581
  return runNativePayload("payload.probeVersion", [
7554
7582
  "payload",
7555
7583
  "probe-version",
7556
7584
  path8.resolve(rootPath),
7557
7585
  executable,
7558
7586
  "PostgreSQL 18.4"
7559
- ], true);
7587
+ ], true, timeoutMs);
7560
7588
  }
7561
- async function publishNativePayload(stagingPath, destinationPath) {
7589
+ async function publishNativePayload(stagingPath, destinationPath, timeoutMs) {
7562
7590
  return runNativePayload("payload.publish", [
7563
7591
  "payload",
7564
7592
  "publish",
7565
7593
  path8.resolve(stagingPath),
7566
7594
  path8.resolve(destinationPath)
7567
- ], true);
7595
+ ], true, timeoutMs);
7568
7596
  }
7569
7597
  async function tryInstallNativePayload(input) {
7598
+ const now = input.now ?? (() => performance.now());
7599
+ const expiresAt = input.timeoutMs === void 0 ? null : now() + input.timeoutMs;
7600
+ const remainingTimeout = (accepted) => {
7601
+ if (expiresAt === null) return void 0;
7602
+ const remaining = Math.ceil(expiresAt - now());
7603
+ if (remaining <= 0) throw new NativePayloadError("deadline_exceeded", accepted);
7604
+ return remaining;
7605
+ };
7606
+ const runCallbackWithinDeadline = async (accepted, callback) => {
7607
+ const controller = new AbortController();
7608
+ const timeoutMs = remainingTimeout(accepted);
7609
+ let timer;
7610
+ const timeoutPromise = timeoutMs === void 0 ? null : new Promise((_resolve, reject) => {
7611
+ timer = setTimeout(() => {
7612
+ controller.abort();
7613
+ reject(new NativePayloadError("deadline_exceeded", accepted));
7614
+ }, timeoutMs);
7615
+ });
7616
+ const context = {
7617
+ signal: controller.signal,
7618
+ remainingMs: () => remainingTimeout(accepted)
7619
+ };
7620
+ try {
7621
+ const operation = callback(context);
7622
+ return timeoutPromise ? await Promise.race([operation, timeoutPromise]) : await operation;
7623
+ } finally {
7624
+ if (timer) clearTimeout(timer);
7625
+ }
7626
+ };
7570
7627
  const policy = nativePayloadPolicy();
7571
7628
  if (!policy.enabled) return {
7572
7629
  installed: false,
@@ -7589,9 +7646,9 @@ async function tryInstallNativePayload(input) {
7589
7646
  }
7590
7647
  try {
7591
7648
  if (expectedSha256) {
7592
- await verifyNativePayload(input.archivePath, expectedSha256, input.maxArchiveBytes);
7649
+ await verifyNativePayload(input.archivePath, expectedSha256, input.maxArchiveBytes, remainingTimeout(false));
7593
7650
  }
7594
- await extractNativePayload(input.archivePath, input.extractPath, input.maxArchiveBytes);
7651
+ await extractNativePayload(input.archivePath, input.extractPath, input.maxArchiveBytes, remainingTimeout(false));
7595
7652
  } catch (error) {
7596
7653
  const fallbackSafe = error instanceof NativePayloadError && error.fallbackSafe;
7597
7654
  if (!policy.fallbackAllowed || !fallbackSafe) throw error;
@@ -7610,10 +7667,16 @@ async function tryInstallNativePayload(input) {
7610
7667
  };
7611
7668
  }
7612
7669
  try {
7613
- const versionExecutable = await input.preparePublish(input.extractPath, input.publishStagingPath);
7614
- await probeNativePayloadVersion(input.publishStagingPath, versionExecutable);
7615
- const published = await publishNativePayload(input.publishStagingPath, input.destinationPath);
7616
- await input.validatePublished(input.destinationPath);
7670
+ const versionExecutable = await runCallbackWithinDeadline(
7671
+ true,
7672
+ (context) => input.preparePublish(input.extractPath, input.publishStagingPath, context)
7673
+ );
7674
+ await probeNativePayloadVersion(input.publishStagingPath, versionExecutable, remainingTimeout(true));
7675
+ const published = await publishNativePayload(input.publishStagingPath, input.destinationPath, remainingTimeout(true));
7676
+ await runCallbackWithinDeadline(
7677
+ true,
7678
+ (context) => input.validatePublished(input.destinationPath, context)
7679
+ );
7617
7680
  return {
7618
7681
  installed: true,
7619
7682
  fallbackCode: null,
@@ -7627,7 +7690,9 @@ async function tryInstallNativePayload(input) {
7627
7690
  }
7628
7691
  };
7629
7692
  } finally {
7630
- await fs6.rm(input.publishStagingPath, { recursive: true, force: true });
7693
+ const cleanup = input.cleanupPublishStaging ?? ((publishStagingPath) => fs6.rm(publishStagingPath, { recursive: true, force: true }));
7694
+ void cleanup(input.publishStagingPath).catch(() => {
7695
+ });
7631
7696
  }
7632
7697
  }
7633
7698
  var execFileAsync, PROTOCOL_VERSION, OUTPUT_LIMIT_BYTES, TIMEOUT_MS, NativePayloadError;
@@ -7665,81 +7730,26 @@ var init_native_payload = __esm({
7665
7730
  }
7666
7731
  });
7667
7732
 
7668
- // src/runtime/postgres-payload.ts
7669
- import { cp, mkdir, stat } from "node:fs/promises";
7670
- import path9 from "node:path";
7671
- async function copyRuntimePostgresPayload(sourceRuntimeDir, targetRuntimeDir, sourceShareDir = path9.join(sourceRuntimeDir, "share")) {
7672
- await mkdir(targetRuntimeDir, { recursive: true });
7673
- for (const directoryName of ["bin", "lib"]) {
7674
- const sourceDirectory = path9.join(sourceRuntimeDir, directoryName);
7675
- if (!await stat(sourceDirectory).catch(() => null)) continue;
7676
- await cp(
7677
- sourceDirectory,
7678
- path9.join(targetRuntimeDir, directoryName),
7679
- { recursive: true, dereference: true }
7680
- );
7681
- }
7682
- await cp(
7683
- sourceShareDir,
7684
- path9.join(targetRuntimeDir, "share"),
7685
- { recursive: true, dereference: true }
7686
- );
7687
- }
7688
- var init_postgres_payload = __esm({
7689
- "src/runtime/postgres-payload.ts"() {
7690
- "use strict";
7691
- }
7692
- });
7693
-
7694
7733
  // src/runtime/postgres-runtime-download.ts
7695
7734
  import { createHash as createHash2 } from "node:crypto";
7696
7735
  import { createReadStream, createWriteStream } from "node:fs";
7697
- import { copyFile, stat as stat2 } from "node:fs/promises";
7698
7736
  import { Readable, Transform } from "node:stream";
7699
7737
  import { pipeline } from "node:stream/promises";
7700
7738
  import { fileURLToPath as fileURLToPath4 } from "node:url";
7701
- async function downloadRuntimePostgresArchive(url, targetPath, trustedSha256) {
7739
+ async function downloadRuntimePostgresArchive(url, targetPath, trustedSha256, options = {}) {
7702
7740
  const expectedSha256 = (trustedSha256 ?? process.env[RUDDER_POSTGRES_RUNTIME_ARCHIVE_SHA256_ENV])?.trim().toLowerCase() || null;
7703
7741
  if (expectedSha256 && !/^[a-f0-9]{64}$/.test(expectedSha256)) {
7704
7742
  throw new Error(`${RUDDER_POSTGRES_RUNTIME_ARCHIVE_SHA256_ENV} must be a 64-character SHA-256 digest`);
7705
7743
  }
7706
7744
  const configuredMaxBytes = Number.parseInt(process.env[RUDDER_POSTGRES_RUNTIME_ARCHIVE_MAX_BYTES_ENV] ?? "", 10);
7707
7745
  const maxBytes = Number.isSafeInteger(configuredMaxBytes) && configuredMaxBytes > 0 ? configuredMaxBytes : DEFAULT_RUNTIME_POSTGRES_ARCHIVE_MAX_BYTES;
7708
- async function verifyFile(filePath) {
7709
- if (!expectedSha256) return;
7710
- const hash = createHash2("sha256");
7711
- await new Promise((resolve, reject) => {
7712
- const stream = createReadStream(filePath);
7713
- stream.on("data", (chunk) => hash.update(chunk));
7714
- stream.on("error", reject);
7715
- stream.on("end", resolve);
7716
- });
7717
- const actual = hash.digest("hex");
7718
- if (actual !== expectedSha256) throw new Error(`PostgreSQL runtime archive SHA-256 mismatch: expected ${expectedSha256}, got ${actual}`);
7719
- }
7720
- if (url.startsWith("file://")) {
7721
- await copyFile(fileURLToPath4(url), targetPath);
7722
- const archiveStat = await stat2(targetPath);
7723
- if (archiveStat.size > maxBytes) throw new Error(`PostgreSQL runtime archive exceeds ${maxBytes} bytes`);
7724
- await verifyFile(targetPath);
7725
- return;
7726
- }
7727
7746
  const parsedTimeout = Number.parseInt(
7728
- process.env[RUDDER_POSTGRES_RUNTIME_DOWNLOAD_TIMEOUT_MS_ENV] ?? "600000",
7747
+ String(options.timeoutMs ?? process.env[RUDDER_POSTGRES_RUNTIME_DOWNLOAD_TIMEOUT_MS_ENV] ?? "600000"),
7729
7748
  10
7730
7749
  );
7731
7750
  const controller = new AbortController();
7732
7751
  const timeout = Number.isFinite(parsedTimeout) && parsedTimeout > 0 ? setTimeout(() => controller.abort(), parsedTimeout) : null;
7733
7752
  try {
7734
- const response = await fetch(url, { signal: controller.signal });
7735
- if (!response.ok) {
7736
- throw new Error(`failed to download ${url}: ${response.status} ${response.statusText}`);
7737
- }
7738
- const contentLength = Number.parseInt(response.headers.get("content-length") ?? "", 10);
7739
- if (Number.isSafeInteger(contentLength) && contentLength > maxBytes) {
7740
- throw new Error(`PostgreSQL runtime archive exceeds ${maxBytes} bytes`);
7741
- }
7742
- if (!response.body) throw new Error("PostgreSQL runtime archive response has no body");
7743
7753
  const hash = createHash2("sha256");
7744
7754
  let bytes = 0;
7745
7755
  const monitor = new Transform({
@@ -7753,15 +7763,39 @@ async function downloadRuntimePostgresArchive(url, targetPath, trustedSha256) {
7753
7763
  callback(null, chunk);
7754
7764
  }
7755
7765
  });
7766
+ if (url.startsWith("file://")) {
7767
+ const readStream = (options.createReadStreamImpl ?? createReadStream)(fileURLToPath4(url));
7768
+ await pipeline(readStream, monitor, createWriteStream(targetPath), { signal: controller.signal });
7769
+ if (expectedSha256) {
7770
+ const actual = hash.digest("hex");
7771
+ if (actual !== expectedSha256) throw new Error(`PostgreSQL runtime archive SHA-256 mismatch: expected ${expectedSha256}, got ${actual}`);
7772
+ }
7773
+ return;
7774
+ }
7775
+ const response = await fetch(url, { signal: controller.signal });
7776
+ if (!response.ok) {
7777
+ throw new Error(`failed to download ${url}: ${response.status} ${response.statusText}`);
7778
+ }
7779
+ const contentLength = Number.parseInt(response.headers.get("content-length") ?? "", 10);
7780
+ if (Number.isSafeInteger(contentLength) && contentLength > maxBytes) {
7781
+ throw new Error(`PostgreSQL runtime archive exceeds ${maxBytes} bytes`);
7782
+ }
7783
+ if (!response.body) throw new Error("PostgreSQL runtime archive response has no body");
7756
7784
  await pipeline(
7757
7785
  Readable.fromWeb(response.body),
7758
7786
  monitor,
7759
- createWriteStream(targetPath, { flags: "wx" })
7787
+ createWriteStream(targetPath, { flags: "wx" }),
7788
+ { signal: controller.signal }
7760
7789
  );
7761
7790
  if (expectedSha256) {
7762
7791
  const actual = hash.digest("hex");
7763
7792
  if (actual !== expectedSha256) throw new Error(`PostgreSQL runtime archive SHA-256 mismatch: expected ${expectedSha256}, got ${actual}`);
7764
7793
  }
7794
+ } catch (error) {
7795
+ if (controller.signal.aborted) {
7796
+ throw new Error(`PostgreSQL runtime archive download timed out after ${parsedTimeout}ms`, { cause: error });
7797
+ }
7798
+ throw error;
7765
7799
  } finally {
7766
7800
  if (timeout) clearTimeout(timeout);
7767
7801
  }
@@ -7816,10 +7850,45 @@ var init_postgres_runtime_source = __esm({
7816
7850
 
7817
7851
  // src/runtime/install.ts
7818
7852
  import { execFileSync, spawnSync as spawnSync2 } from "node:child_process";
7819
- import { mkdir as mkdir2, mkdtemp, readFile, readdir, realpath, rename, rm, stat as stat3, symlink, writeFile } from "node:fs/promises";
7853
+ import { createReadStream as createReadStream2, createWriteStream as createWriteStream2 } from "node:fs";
7854
+ import { chmod, mkdir, mkdtemp, readFile, readdir, realpath, rename, rm, stat, symlink, writeFile } from "node:fs/promises";
7820
7855
  import { createRequire } from "node:module";
7821
- import path10 from "node:path";
7856
+ import path9 from "node:path";
7857
+ import { performance as performance2 } from "node:perf_hooks";
7858
+ import { pipeline as pipeline2 } from "node:stream/promises";
7822
7859
  import { pathToFileURL } from "node:url";
7860
+ function createRuntimeInstallDeadline(options) {
7861
+ if (options.timeoutMs === void 0) return void 0;
7862
+ if (!Number.isFinite(options.timeoutMs) || options.timeoutMs <= 0) {
7863
+ throw new Error("Runtime installation timeout must be a positive number of milliseconds.");
7864
+ }
7865
+ const now = options.now ?? (() => performance2.now());
7866
+ return { expiresAt: now() + options.timeoutMs, now };
7867
+ }
7868
+ function remainingRuntimeInstallMs(deadline, cacheDir, command) {
7869
+ if (!deadline) return void 0;
7870
+ const remaining = Math.ceil(deadline.expiresAt - deadline.now());
7871
+ if (remaining <= 0) {
7872
+ throw new RuntimeInstallError(
7873
+ `Timed out while preparing the Rudder runtime during ${command}`,
7874
+ { cacheDir, command }
7875
+ );
7876
+ }
7877
+ return remaining;
7878
+ }
7879
+ function runtimeInstallDeadlineError(cacheDir, command) {
7880
+ return new RuntimeInstallError(
7881
+ `Timed out while preparing the Rudder runtime during ${command}`,
7882
+ { cacheDir, command }
7883
+ );
7884
+ }
7885
+ function isRuntimeInstallDeadlineError(error) {
7886
+ return error instanceof RuntimeInstallError && error.message.startsWith("Timed out while preparing the Rudder runtime during ");
7887
+ }
7888
+ function isChildProcessTimeoutError(error) {
7889
+ const detail = error;
7890
+ return detail?.code === "ETIMEDOUT" || detail?.killed === true || detail?.signal === "SIGTERM";
7891
+ }
7823
7892
  function sanitizeRuntimeCacheSegment(value) {
7824
7893
  return encodeURIComponent(value.trim() || "latest").replaceAll("%", "_");
7825
7894
  }
@@ -7828,7 +7897,7 @@ function resolveRuntimePackageVersion(version) {
7828
7897
  return normalized.length > 0 ? normalized : "latest";
7829
7898
  }
7830
7899
  function resolveRuntimeCacheDir(version, homeDir = resolveRudderHomeDir()) {
7831
- return path10.join(homeDir, "runtimes", sanitizeRuntimeCacheSegment(resolveRuntimePackageVersion(version)));
7900
+ return path9.join(homeDir, "runtimes", sanitizeRuntimeCacheSegment(resolveRuntimePackageVersion(version)));
7832
7901
  }
7833
7902
  function resolveRuntimePackageSpec(version, packageName = RUNTIME_NPM_PACKAGE_NAME) {
7834
7903
  const packageVersion = resolveRuntimePackageVersion(version);
@@ -7836,7 +7905,7 @@ function resolveRuntimePackageSpec(version, packageName = RUNTIME_NPM_PACKAGE_NA
7836
7905
  }
7837
7906
  async function readRuntimeInstallMetadata(cacheDir) {
7838
7907
  try {
7839
- const raw = await readFile(path10.join(cacheDir, RUNTIME_METADATA_FILE), "utf8");
7908
+ const raw = await readFile(path9.join(cacheDir, RUNTIME_METADATA_FILE), "utf8");
7840
7909
  const parsed = JSON.parse(raw);
7841
7910
  if (parsed.version !== 1) return null;
7842
7911
  if (typeof parsed.packageName !== "string" || typeof parsed.packageVersion !== "string") return null;
@@ -7851,7 +7920,7 @@ async function readRuntimeInstallMetadata(cacheDir) {
7851
7920
  }
7852
7921
  }
7853
7922
  async function writeRuntimeInstallMetadata(cacheDir, metadata) {
7854
- await writeFile(path10.join(cacheDir, RUNTIME_METADATA_FILE), `${JSON.stringify(metadata, null, 2)}
7923
+ await writeFile(path9.join(cacheDir, RUNTIME_METADATA_FILE), `${JSON.stringify(metadata, null, 2)}
7855
7924
  `, "utf8");
7856
7925
  }
7857
7926
  async function touchRuntimeInstallMetadata(cacheDir, postgresRuntime) {
@@ -7879,27 +7948,28 @@ function resolveEmbeddedPostgresPlatformPackage(platform = process.platform, arc
7879
7948
  }
7880
7949
  async function canResolveRuntimePackage(cacheDir, packageName) {
7881
7950
  try {
7882
- await readFile(path10.join(cacheDir, "node_modules", ...packageName.split("/"), "package.json"), "utf8");
7951
+ await readFile(path9.join(cacheDir, "node_modules", ...packageName.split("/"), "package.json"), "utf8");
7883
7952
  return true;
7884
7953
  } catch {
7885
7954
  return false;
7886
7955
  }
7887
7956
  }
7888
- async function hasRequiredRuntimePlatformDependencies(cacheDir, metadata, postgresVersionProbe) {
7957
+ async function hasRequiredRuntimePlatformDependencies(cacheDir, metadata, postgresVersionProbe, deadline) {
7889
7958
  if (!await canResolveRuntimePackage(cacheDir, EMBEDDED_POSTGRES_PACKAGE_NAME)) return true;
7890
7959
  const platformPackage = resolveEmbeddedPostgresPlatformPackage();
7891
7960
  if (!platformPackage) return true;
7892
7961
  if (await canResolveRuntimePackage(cacheDir, platformPackage)) return true;
7893
7962
  const expectedSharedBinDir = resolveSharedRuntimePostgresPayloadBinDir(
7894
- path10.dirname(path10.dirname(cacheDir))
7963
+ path9.dirname(path9.dirname(cacheDir))
7895
7964
  );
7896
- return metadata.postgresRuntime?.scope === "shared" && metadata.postgresRuntime.platform === process.platform && metadata.postgresRuntime.arch === process.arch && path10.resolve(metadata.postgresRuntime.binDir) === path10.resolve(expectedSharedBinDir) && await isRuntimePostgresPayloadUsable(
7965
+ return metadata.postgresRuntime?.scope === "shared" && metadata.postgresRuntime.platform === process.platform && metadata.postgresRuntime.arch === process.arch && path9.resolve(metadata.postgresRuntime.binDir) === path9.resolve(expectedSharedBinDir) && await isRuntimePostgresPayloadUsable(
7897
7966
  cacheDir,
7898
7967
  metadata.postgresRuntime.binDir,
7899
- postgresVersionProbe
7968
+ postgresVersionProbe,
7969
+ deadline
7900
7970
  );
7901
7971
  }
7902
- async function isRuntimeCacheHit(options) {
7972
+ async function isRuntimeCacheHitWithinDeadline(options, deadline) {
7903
7973
  const packageName = options.packageName ?? RUNTIME_NPM_PACKAGE_NAME;
7904
7974
  const packageVersion = resolveRuntimePackageVersion(options.version);
7905
7975
  const metadata = await readRuntimeInstallMetadata(options.cacheDir);
@@ -7907,15 +7977,17 @@ async function isRuntimeCacheHit(options) {
7907
7977
  return false;
7908
7978
  }
7909
7979
  try {
7910
- const packageJsonPath = path10.join(options.cacheDir, "node_modules", ...packageName.split("/"), "package.json");
7980
+ const packageJsonPath = path9.join(options.cacheDir, "node_modules", ...packageName.split("/"), "package.json");
7911
7981
  const packageJson = JSON.parse(await readFile(packageJsonPath, "utf8"));
7912
7982
  const packageVersionMatches = packageVersion === "latest" || packageJson.version === packageVersion;
7913
7983
  return packageVersionMatches && await hasRequiredRuntimePlatformDependencies(
7914
7984
  options.cacheDir,
7915
7985
  metadata,
7916
- options.postgresVersionProbe ?? readPostgresVersion
7986
+ options.postgresVersionProbe ?? readPostgresVersion,
7987
+ deadline
7917
7988
  );
7918
- } catch {
7989
+ } catch (error) {
7990
+ if (isRuntimeInstallDeadlineError(error)) throw error;
7919
7991
  return false;
7920
7992
  }
7921
7993
  }
@@ -7923,15 +7995,45 @@ async function ensureRuntimeInstalled(options) {
7923
7995
  const packageVersion = resolveRuntimePackageVersion(options.version);
7924
7996
  const homeDir = options.homeDir ?? resolveRudderHomeDir();
7925
7997
  const cacheDir = resolveRuntimeCacheDir(packageVersion, homeDir);
7998
+ const deadline = createRuntimeInstallDeadline(options);
7926
7999
  return withRuntimeFilesystemLock(
7927
- path10.join(homeDir, "runtime-payloads", ".postgres-runtime.lifecycle.lock"),
8000
+ path9.join(homeDir, "runtime-payloads", ".postgres-runtime.lifecycle.lock"),
7928
8001
  async () => withRuntimeFilesystemLock(
7929
8002
  `${cacheDir}.install.lock`,
7930
- async () => ensureRuntimeInstalledUnlocked(options)
7931
- )
8003
+ async () => {
8004
+ try {
8005
+ return await ensureRuntimeInstalledUnlocked(options, deadline);
8006
+ } catch (error) {
8007
+ if (options.cleanupIncompleteOnFailure === true) {
8008
+ scheduleIncompleteRuntimeCacheCleanup({
8009
+ cacheDir,
8010
+ packageVersion,
8011
+ remove: options.removeIncompleteCache
8012
+ });
8013
+ }
8014
+ throw error;
8015
+ }
8016
+ },
8017
+ { deadline, cacheDir, command: "acquire target runtime install lock" }
8018
+ ),
8019
+ { deadline, cacheDir, command: "acquire PostgreSQL runtime lifecycle lock" }
7932
8020
  );
7933
8021
  }
7934
- async function ensureRuntimeInstalledUnlocked(options) {
8022
+ function scheduleIncompleteRuntimeCacheCleanup(options) {
8023
+ const remove = options.remove ?? ((cacheDir) => rm(cacheDir, { recursive: true, force: true }));
8024
+ void withRuntimeFilesystemLock(
8025
+ `${options.cacheDir}.install.lock`,
8026
+ async () => {
8027
+ const metadata = await readRuntimeInstallMetadata(options.cacheDir);
8028
+ if (!metadata || metadata.packageVersion !== options.packageVersion) {
8029
+ await remove(options.cacheDir);
8030
+ }
8031
+ },
8032
+ { cacheDir: options.cacheDir, command: "cleanup incomplete target runtime cache" }
8033
+ ).catch(() => {
8034
+ });
8035
+ }
8036
+ async function ensureRuntimeInstalledUnlocked(options, deadline) {
7935
8037
  const packageName = options.packageName ?? RUNTIME_NPM_PACKAGE_NAME;
7936
8038
  const packageVersion = resolveRuntimePackageVersion(options.version);
7937
8039
  const homeDir = options.homeDir ?? resolveRudderHomeDir();
@@ -7939,14 +8041,32 @@ async function ensureRuntimeInstalledUnlocked(options) {
7939
8041
  const packageSpec = resolveRuntimePackageSpec(packageVersion, packageName);
7940
8042
  const command = formatRuntimeInstallCommand(cacheDir, packageSpec);
7941
8043
  const preparePostgresPayload = options.preparePostgresPayload === true;
7942
- const postgresVersionProbe = options.postgresVersionProbe ?? readPostgresVersion;
7943
- if (await isRuntimeCacheHit({ cacheDir, version: packageVersion, packageName, postgresVersionProbe })) {
8044
+ const postgresVersionProbe = options.postgresVersionProbe ?? ((binaryPath) => {
8045
+ const probeCommand = `${binaryPath} --version`;
8046
+ try {
8047
+ return readPostgresVersion(
8048
+ binaryPath,
8049
+ remainingRuntimeInstallMs(deadline, cacheDir, probeCommand)
8050
+ );
8051
+ } catch (error) {
8052
+ if (isChildProcessTimeoutError(error)) {
8053
+ throw runtimeInstallDeadlineError(cacheDir, probeCommand);
8054
+ }
8055
+ throw error;
8056
+ }
8057
+ });
8058
+ if (await isRuntimeCacheHitWithinDeadline(
8059
+ { cacheDir, version: packageVersion, packageName, postgresVersionProbe },
8060
+ deadline
8061
+ )) {
7944
8062
  const postgresPayload2 = await stageRuntimePostgresPayload(
7945
8063
  cacheDir,
7946
8064
  homeDir,
7947
8065
  packageVersion,
7948
8066
  preparePostgresPayload,
7949
- postgresVersionProbe
8067
+ postgresVersionProbe,
8068
+ deadline,
8069
+ options.cleanupPostgresDownloadWorkDir
7950
8070
  );
7951
8071
  await touchRuntimeInstallMetadata(cacheDir, postgresPayload2.metadata);
7952
8072
  const prune2 = await maybePruneRuntimeCache({
@@ -7965,7 +8085,8 @@ async function ensureRuntimeInstalledUnlocked(options) {
7965
8085
  spawnSyncImpl,
7966
8086
  cacheDir,
7967
8087
  packageName,
7968
- packageVersion
8088
+ packageVersion,
8089
+ deadline
7969
8090
  });
7970
8091
  if (existingRuntimeOutput !== null) {
7971
8092
  const postgresPayload2 = await stageRuntimePostgresPayload(
@@ -7973,7 +8094,9 @@ async function ensureRuntimeInstalledUnlocked(options) {
7973
8094
  homeDir,
7974
8095
  packageVersion,
7975
8096
  preparePostgresPayload,
7976
- postgresVersionProbe
8097
+ postgresVersionProbe,
8098
+ deadline,
8099
+ options.cleanupPostgresDownloadWorkDir
7977
8100
  );
7978
8101
  const metadata2 = {
7979
8102
  version: 1,
@@ -7996,30 +8119,32 @@ async function ensureRuntimeInstalledUnlocked(options) {
7996
8119
  );
7997
8120
  }
7998
8121
  await rm(cacheDir, { recursive: true, force: true });
7999
- await mkdir2(cacheDir, { recursive: true });
8000
- await writeFile(path10.join(cacheDir, "package.json"), `${JSON.stringify(RUNTIME_CACHE_PACKAGE_JSON, null, 2)}
8122
+ await mkdir(cacheDir, { recursive: true });
8123
+ await writeFile(path9.join(cacheDir, "package.json"), `${JSON.stringify(RUNTIME_CACHE_PACKAGE_JSON, null, 2)}
8001
8124
  `, "utf8");
8002
- const result = runNpmRuntimeInstall(spawnSyncImpl, cacheDir, packageSpec);
8125
+ const result = runNpmRuntimeInstall(spawnSyncImpl, cacheDir, packageSpec, deadline);
8003
8126
  let output = collectSpawnOutput(result);
8004
- if (result.status !== 0 && packageVersion !== "latest" && isVersionNotFoundError(output)) {
8127
+ if (result.status !== 0 && packageVersion !== "latest" && options.allowLatestFallback !== false && isVersionNotFoundError(output)) {
8005
8128
  const fallbackVersion = "latest";
8006
8129
  const fallbackCacheDir = resolveRuntimeCacheDir(fallbackVersion, options.homeDir);
8007
8130
  const fallbackSpec = resolveRuntimePackageSpec(fallbackVersion, packageName);
8008
8131
  const fallbackInstallResult = await withRuntimeFilesystemLock(
8009
8132
  `${fallbackCacheDir}.install.lock`,
8010
8133
  async () => {
8011
- if (await isRuntimeCacheHit({
8134
+ if (await isRuntimeCacheHitWithinDeadline({
8012
8135
  cacheDir: fallbackCacheDir,
8013
8136
  version: fallbackVersion,
8014
8137
  packageName,
8015
8138
  postgresVersionProbe
8016
- })) {
8139
+ }, deadline)) {
8017
8140
  const fallbackPostgresPayload = await stageRuntimePostgresPayload(
8018
8141
  fallbackCacheDir,
8019
8142
  homeDir,
8020
8143
  fallbackVersion,
8021
8144
  preparePostgresPayload,
8022
- postgresVersionProbe
8145
+ postgresVersionProbe,
8146
+ deadline,
8147
+ options.cleanupPostgresDownloadWorkDir
8023
8148
  );
8024
8149
  await touchRuntimeInstallMetadata(fallbackCacheDir, fallbackPostgresPayload.metadata);
8025
8150
  return withPostgresPayload(
@@ -8034,22 +8159,24 @@ async function ensureRuntimeInstalledUnlocked(options) {
8034
8159
  );
8035
8160
  }
8036
8161
  await rm(fallbackCacheDir, { recursive: true, force: true });
8037
- await mkdir2(fallbackCacheDir, { recursive: true });
8038
- await writeFile(path10.join(fallbackCacheDir, "package.json"), `${JSON.stringify(RUNTIME_CACHE_PACKAGE_JSON, null, 2)}
8162
+ await mkdir(fallbackCacheDir, { recursive: true });
8163
+ await writeFile(path9.join(fallbackCacheDir, "package.json"), `${JSON.stringify(RUNTIME_CACHE_PACKAGE_JSON, null, 2)}
8039
8164
  `, "utf8");
8040
- const fallbackResult = runNpmRuntimeInstall(spawnSyncImpl, fallbackCacheDir, fallbackSpec);
8165
+ const fallbackResult = runNpmRuntimeInstall(spawnSyncImpl, fallbackCacheDir, fallbackSpec, deadline);
8041
8166
  let fallbackOutput = collectSpawnOutput(fallbackResult);
8042
8167
  if (fallbackResult.status !== 0) return null;
8043
8168
  fallbackOutput = collectOutputParts(
8044
8169
  fallbackOutput,
8045
- await ensureRequiredEmbeddedPostgresPlatformPackage(spawnSyncImpl, fallbackCacheDir)
8170
+ await ensureRequiredEmbeddedPostgresPlatformPackage(spawnSyncImpl, fallbackCacheDir, deadline)
8046
8171
  );
8047
8172
  const postgresPayload2 = await stageRuntimePostgresPayload(
8048
8173
  fallbackCacheDir,
8049
8174
  homeDir,
8050
8175
  fallbackVersion,
8051
8176
  preparePostgresPayload,
8052
- postgresVersionProbe
8177
+ postgresVersionProbe,
8178
+ deadline,
8179
+ options.cleanupPostgresDownloadWorkDir
8053
8180
  );
8054
8181
  const fallbackMetadata = {
8055
8182
  version: 1,
@@ -8070,7 +8197,8 @@ async function ensureRuntimeInstalledUnlocked(options) {
8070
8197
  },
8071
8198
  postgresPayload2
8072
8199
  );
8073
- }
8200
+ },
8201
+ { deadline, cacheDir: fallbackCacheDir, command: "acquire fallback runtime install lock" }
8074
8202
  );
8075
8203
  if (fallbackInstallResult) return fallbackInstallResult;
8076
8204
  }
@@ -8082,14 +8210,16 @@ async function ensureRuntimeInstalledUnlocked(options) {
8082
8210
  }
8083
8211
  output = collectOutputParts(
8084
8212
  output,
8085
- await ensureRequiredEmbeddedPostgresPlatformPackage(spawnSyncImpl, cacheDir)
8213
+ await ensureRequiredEmbeddedPostgresPlatformPackage(spawnSyncImpl, cacheDir, deadline)
8086
8214
  );
8087
8215
  const postgresPayload = await stageRuntimePostgresPayload(
8088
8216
  cacheDir,
8089
8217
  homeDir,
8090
8218
  packageVersion,
8091
8219
  preparePostgresPayload,
8092
- postgresVersionProbe
8220
+ postgresVersionProbe,
8221
+ deadline,
8222
+ options.cleanupPostgresDownloadWorkDir
8093
8223
  );
8094
8224
  const metadata = {
8095
8225
  version: 1,
@@ -8112,10 +8242,10 @@ async function ensureRuntimeInstalledUnlocked(options) {
8112
8242
  );
8113
8243
  }
8114
8244
  function resolveRuntimePostgresPayloadBinDir(cacheDir, platform = process.platform, arch = process.arch) {
8115
- return path10.join(cacheDir, RUNTIME_POSTGRES_PAYLOAD_DIR, runtimePostgresPlatformSegment(platform, arch), "bin");
8245
+ return path9.join(cacheDir, RUNTIME_POSTGRES_PAYLOAD_DIR, runtimePostgresPlatformSegment(platform, arch), "bin");
8116
8246
  }
8117
8247
  function resolveSharedRuntimePostgresPayloadBinDir(homeDir = resolveRudderHomeDir(), platform = process.platform, arch = process.arch) {
8118
- return path10.join(
8248
+ return path9.join(
8119
8249
  homeDir,
8120
8250
  "runtime-payloads",
8121
8251
  RUNTIME_POSTGRES_PAYLOAD_DIR,
@@ -8124,19 +8254,21 @@ function resolveSharedRuntimePostgresPayloadBinDir(homeDir = resolveRudderHomeDi
8124
8254
  );
8125
8255
  }
8126
8256
  function resolveRuntimeServerEntrypoint(cacheDir, packageName = RUNTIME_NPM_PACKAGE_NAME) {
8127
- return createRequire(path10.join(cacheDir, "package.json")).resolve(packageName);
8257
+ return createRequire(path9.join(cacheDir, "package.json")).resolve(packageName);
8128
8258
  }
8129
8259
  async function importRuntimeServerModule(cacheDir, packageName = RUNTIME_NPM_PACKAGE_NAME) {
8130
8260
  const entrypoint = resolveRuntimeServerEntrypoint(cacheDir, packageName);
8131
8261
  return await import(pathToFileURL(entrypoint).href);
8132
8262
  }
8133
- function runNpmRuntimeInstall(spawnSyncImpl, cacheDir, packageSpec) {
8263
+ function runNpmRuntimeInstall(spawnSyncImpl, cacheDir, packageSpec, deadline) {
8264
+ const timeout = remainingRuntimeInstallMs(deadline, cacheDir, `npm install ${packageSpec}`);
8134
8265
  return spawnSyncImpl(
8135
8266
  process.platform === "win32" ? "npm.cmd" : "npm",
8136
8267
  ["install", "--prefix", cacheDir, ...RUNTIME_NPM_INSTALL_FLAGS, packageSpec],
8137
8268
  {
8138
8269
  encoding: "utf8",
8139
8270
  stdio: ["ignore", "pipe", "pipe"],
8271
+ ...timeout === void 0 ? {} : { timeout },
8140
8272
  ...process.platform === "win32" ? { shell: true, windowsHide: true } : {}
8141
8273
  }
8142
8274
  );
@@ -8145,7 +8277,7 @@ function formatRuntimeInstallCommand(cacheDir, packageSpec) {
8145
8277
  return `npm install --prefix ${cacheDir} ${RUNTIME_NPM_INSTALL_FLAGS.join(" ")} ${packageSpec}`;
8146
8278
  }
8147
8279
  function formatRuntimePlatformRepairCommand(cacheDir, packageSpec) {
8148
- return `npm pack ${packageSpec} --registry=${NPM_PUBLIC_REGISTRY_URL} --silent, then extract it into ${path10.join(cacheDir, "node_modules")}`;
8280
+ return `npm pack ${packageSpec} --registry=${NPM_PUBLIC_REGISTRY_URL} --silent, then extract it into ${path9.join(cacheDir, "node_modules")}`;
8149
8281
  }
8150
8282
  function collectSpawnOutput(result) {
8151
8283
  return [result.stdout, result.stderr, result.error instanceof Error ? result.error.message : null].filter((value) => typeof value === "string" && value.trim().length > 0).join("\n").trim();
@@ -8162,7 +8294,7 @@ function withPostgresPayload(result, postgresPayload) {
8162
8294
  };
8163
8295
  }
8164
8296
  function runtimePackageJsonPath(cacheDir, packageName) {
8165
- return path10.join(cacheDir, "node_modules", ...packageName.split("/"), "package.json");
8297
+ return path9.join(cacheDir, "node_modules", ...packageName.split("/"), "package.json");
8166
8298
  }
8167
8299
  async function readRuntimePackageJson(cacheDir, packageName) {
8168
8300
  try {
@@ -8175,7 +8307,11 @@ async function tryRepairExistingRuntimePackage(options) {
8175
8307
  const runtimePackage = await readRuntimePackageJson(options.cacheDir, options.packageName);
8176
8308
  if (!runtimePackage) return null;
8177
8309
  if (options.packageVersion !== "latest" && runtimePackage.version !== options.packageVersion) return null;
8178
- const output = await ensureRequiredEmbeddedPostgresPlatformPackage(options.spawnSyncImpl, options.cacheDir);
8310
+ const output = await ensureRequiredEmbeddedPostgresPlatformPackage(
8311
+ options.spawnSyncImpl,
8312
+ options.cacheDir,
8313
+ options.deadline
8314
+ );
8179
8315
  if (!await canResolveRuntimePackage(options.cacheDir, EMBEDDED_POSTGRES_PACKAGE_NAME)) return output;
8180
8316
  const platformPackage = resolveEmbeddedPostgresPlatformPackage();
8181
8317
  return !platformPackage || await canResolveRuntimePackage(options.cacheDir, platformPackage) ? output : null;
@@ -8189,13 +8325,19 @@ async function resolveEmbeddedPostgresPlatformPackageSpec(cacheDir) {
8189
8325
  const packageVersion = normalizeOptionalDependencyVersion(versionRange);
8190
8326
  return packageVersion ? `${packageName}@${packageVersion}` : packageName;
8191
8327
  }
8192
- async function ensureRequiredEmbeddedPostgresPlatformPackage(spawnSyncImpl, cacheDir) {
8328
+ async function ensureRequiredEmbeddedPostgresPlatformPackage(spawnSyncImpl, cacheDir, deadline) {
8193
8329
  const packageSpec = await resolveEmbeddedPostgresPlatformPackageSpec(cacheDir);
8194
8330
  if (!packageSpec) return "";
8195
8331
  const packageName = packageNameFromSpec(packageSpec);
8196
8332
  if (packageName && await canResolveRuntimePackage(cacheDir, packageName)) return "";
8197
8333
  await removeRuntimeInstallLocks(cacheDir);
8198
- const result = await installRuntimePackageInStaging(spawnSyncImpl, cacheDir, packageSpec, packageName);
8334
+ const result = await installRuntimePackageInStaging(
8335
+ spawnSyncImpl,
8336
+ cacheDir,
8337
+ packageSpec,
8338
+ packageName,
8339
+ deadline
8340
+ );
8199
8341
  const output = collectSpawnOutput(result);
8200
8342
  if (result.status === 0 && packageName && await canResolveRuntimePackage(cacheDir, packageName)) {
8201
8343
  return output;
@@ -8206,28 +8348,29 @@ async function ensureRequiredEmbeddedPostgresPlatformPackage(spawnSyncImpl, cach
8206
8348
  { cacheDir, command, output }
8207
8349
  );
8208
8350
  }
8209
- async function installRuntimePackageInStaging(spawnSyncImpl, cacheDir, packageSpec, packageName) {
8210
- const stagingDir = path10.join(cacheDir, `.platform-repair-${process.pid}-${Date.now()}`);
8211
- await mkdir2(stagingDir, { recursive: true });
8351
+ async function installRuntimePackageInStaging(spawnSyncImpl, cacheDir, packageSpec, packageName, deadline) {
8352
+ const stagingDir = path9.join(cacheDir, `.platform-repair-${process.pid}-${Date.now()}`);
8353
+ await mkdir(stagingDir, { recursive: true });
8212
8354
  try {
8213
- const packResult = runNpmPack(spawnSyncImpl, packageSpec, stagingDir);
8355
+ const packResult = runNpmPack(spawnSyncImpl, packageSpec, stagingDir, cacheDir, deadline);
8214
8356
  if (packResult.status !== 0) return packResult;
8215
8357
  const packFilename = parseNpmPackFilename(packResult.stdout);
8216
8358
  if (!packFilename) {
8217
8359
  return createSyntheticSpawnResult(1, "", `Unable to parse npm pack output for ${packageSpec}.`);
8218
8360
  }
8219
- const archivePath = path10.join(stagingDir, packFilename);
8220
- const targetDir = path10.dirname(runtimePackageJsonPath(cacheDir, packageName));
8221
- await mkdir2(path10.dirname(targetDir), { recursive: true });
8361
+ const archivePath = path9.join(stagingDir, packFilename);
8362
+ const targetDir = path9.dirname(runtimePackageJsonPath(cacheDir, packageName));
8363
+ await mkdir(path9.dirname(targetDir), { recursive: true });
8222
8364
  await rm(targetDir, { recursive: true, force: true });
8223
- await mkdir2(targetDir, { recursive: true });
8224
- const extractResult = runTarExtract(spawnSyncImpl, archivePath, targetDir);
8365
+ await mkdir(targetDir, { recursive: true });
8366
+ const extractResult = runTarExtract(spawnSyncImpl, archivePath, targetDir, cacheDir, deadline);
8225
8367
  return combineSpawnResults(packResult, extractResult);
8226
8368
  } finally {
8227
8369
  await rm(stagingDir, { recursive: true, force: true });
8228
8370
  }
8229
8371
  }
8230
- function runNpmPack(spawnSyncImpl, packageSpec, destinationDir) {
8372
+ function runNpmPack(spawnSyncImpl, packageSpec, destinationDir, cacheDir, deadline) {
8373
+ const timeout = remainingRuntimeInstallMs(deadline, cacheDir, `npm pack ${packageSpec}`);
8231
8374
  return spawnSyncImpl(
8232
8375
  process.platform === "win32" ? "npm.cmd" : "npm",
8233
8376
  ["pack", packageSpec, "--pack-destination", destinationDir, ...RUNTIME_NPM_PACK_FLAGS],
@@ -8235,17 +8378,20 @@ function runNpmPack(spawnSyncImpl, packageSpec, destinationDir) {
8235
8378
  encoding: "utf8",
8236
8379
  stdio: ["ignore", "pipe", "pipe"],
8237
8380
  env: { ...process.env, ...NPM_PLATFORM_REPAIR_ENV },
8381
+ ...timeout === void 0 ? {} : { timeout },
8238
8382
  ...process.platform === "win32" ? { shell: true, windowsHide: true } : {}
8239
8383
  }
8240
8384
  );
8241
8385
  }
8242
- function runTarExtract(spawnSyncImpl, archivePath, targetDir) {
8386
+ function runTarExtract(spawnSyncImpl, archivePath, targetDir, cacheDir, deadline) {
8387
+ const timeout = remainingRuntimeInstallMs(deadline, cacheDir, "extract runtime platform package");
8243
8388
  return spawnSyncImpl(
8244
8389
  "tar",
8245
8390
  ["-xzf", archivePath, "-C", targetDir, "--strip-components", "1"],
8246
8391
  {
8247
8392
  encoding: "utf8",
8248
8393
  stdio: ["ignore", "pipe", "pipe"],
8394
+ ...timeout === void 0 ? {} : { timeout },
8249
8395
  ...process.platform === "win32" ? { windowsHide: true } : {}
8250
8396
  }
8251
8397
  );
@@ -8269,8 +8415,8 @@ function combineSpawnResults(...results) {
8269
8415
  }
8270
8416
  async function removeRuntimeInstallLocks(cacheDir) {
8271
8417
  await Promise.all([
8272
- rm(path10.join(cacheDir, "package-lock.json"), { force: true }),
8273
- rm(path10.join(cacheDir, "node_modules", ".package-lock.json"), { force: true })
8418
+ rm(path9.join(cacheDir, "package-lock.json"), { force: true }),
8419
+ rm(path9.join(cacheDir, "node_modules", ".package-lock.json"), { force: true })
8274
8420
  ]);
8275
8421
  }
8276
8422
  function packageNameFromSpec(packageSpec) {
@@ -8294,77 +8440,95 @@ function runtimePostgresExecutableName(baseName) {
8294
8440
  return process.platform === "win32" ? `${baseName}.exe` : baseName;
8295
8441
  }
8296
8442
  function debianSharedirCandidate(binDir) {
8297
- const normalized = path10.resolve(binDir);
8298
- const parts = normalized.split(path10.sep);
8443
+ const normalized = path9.resolve(binDir);
8444
+ const parts = normalized.split(path9.sep);
8299
8445
  const libIndex = parts.lastIndexOf("lib");
8300
8446
  if (libIndex < 0) return null;
8301
8447
  if (parts[libIndex + 1] !== "postgresql") return null;
8302
8448
  const version = parts[libIndex + 2];
8303
8449
  if (!version || parts[libIndex + 3] !== "bin") return null;
8304
- const prefix = parts.slice(0, libIndex).join(path10.sep) || path10.sep;
8305
- return path10.join(prefix, "share", "postgresql", version);
8450
+ const prefix = parts.slice(0, libIndex).join(path9.sep) || path9.sep;
8451
+ return path9.join(prefix, "share", "postgresql", version);
8306
8452
  }
8307
- async function resolveRuntimePostgresTemplateDir(binDir) {
8453
+ async function resolveRuntimePostgresTemplateDir(binDir, cacheDir = binDir, deadline) {
8308
8454
  for (const candidatePath of [
8309
- path10.join(binDir, "..", "share", "postgresql", "postgres.bki"),
8310
- path10.join(binDir, "..", "share", "postgres.bki")
8455
+ path9.join(binDir, "..", "share", "postgresql", "postgres.bki"),
8456
+ path9.join(binDir, "..", "share", "postgres.bki")
8311
8457
  ]) {
8458
+ remainingRuntimeInstallMs(deadline, cacheDir, "discover PostgreSQL runtime templates");
8312
8459
  try {
8313
- await stat3(candidatePath);
8314
- return path10.dirname(candidatePath);
8460
+ await stat(candidatePath);
8461
+ return path9.dirname(candidatePath);
8315
8462
  } catch {
8316
8463
  }
8317
8464
  }
8318
8465
  const debianSharedir = debianSharedirCandidate(binDir);
8319
8466
  if (debianSharedir) {
8467
+ remainingRuntimeInstallMs(deadline, cacheDir, "discover PostgreSQL runtime templates");
8320
8468
  try {
8321
- await stat3(path10.join(debianSharedir, "postgres.bki"));
8469
+ await stat(path9.join(debianSharedir, "postgres.bki"));
8322
8470
  return debianSharedir;
8323
8471
  } catch {
8324
8472
  }
8325
8473
  }
8326
- const pgConfigPath = path10.join(binDir, process.platform === "win32" ? "pg_config.exe" : "pg_config");
8474
+ const pgConfigPath = path9.join(binDir, process.platform === "win32" ? "pg_config.exe" : "pg_config");
8327
8475
  try {
8328
- await stat3(pgConfigPath);
8329
- const sharedir = execFileSync(pgConfigPath, ["--sharedir"], { encoding: "utf8" }).trim();
8476
+ remainingRuntimeInstallMs(deadline, cacheDir, "discover PostgreSQL runtime templates");
8477
+ await stat(pgConfigPath);
8478
+ const timeout = remainingRuntimeInstallMs(deadline, cacheDir, `${pgConfigPath} --sharedir`);
8479
+ let sharedir;
8480
+ try {
8481
+ sharedir = execFileSync(pgConfigPath, ["--sharedir"], {
8482
+ encoding: "utf8",
8483
+ ...timeout === void 0 ? {} : { timeout }
8484
+ }).trim();
8485
+ } catch (error) {
8486
+ if (isChildProcessTimeoutError(error)) {
8487
+ throw runtimeInstallDeadlineError(cacheDir, `${pgConfigPath} --sharedir`);
8488
+ }
8489
+ throw error;
8490
+ }
8330
8491
  if (!sharedir) return null;
8331
- const candidatePath = path10.join(sharedir, "postgres.bki");
8332
- await stat3(candidatePath);
8492
+ remainingRuntimeInstallMs(deadline, cacheDir, "validate PostgreSQL runtime templates");
8493
+ const candidatePath = path9.join(sharedir, "postgres.bki");
8494
+ await stat(candidatePath);
8333
8495
  return sharedir;
8334
- } catch {
8496
+ } catch (error) {
8497
+ if (isRuntimeInstallDeadlineError(error)) throw error;
8335
8498
  return null;
8336
8499
  }
8337
8500
  }
8338
8501
  function resolveRuntimePostgresShareDir(binDir, templateDir) {
8339
- const adjacentShareDir = path10.resolve(binDir, "..", "share");
8502
+ const adjacentShareDir = path9.resolve(binDir, "..", "share");
8340
8503
  return pathIsInside(templateDir, adjacentShareDir) ? adjacentShareDir : templateDir;
8341
8504
  }
8342
- async function assertRuntimePostgresBinDirComplete(cacheDir, binDir) {
8505
+ async function assertRuntimePostgresBinDirComplete(cacheDir, binDir, deadline) {
8343
8506
  const requiredBinaries = ["initdb", "pg_ctl", "postgres"];
8344
8507
  const missing = [];
8345
8508
  for (const binary of requiredBinaries) {
8346
- const binaryPath = path10.join(binDir, runtimePostgresExecutableName(binary));
8509
+ remainingRuntimeInstallMs(deadline, cacheDir, "validate PostgreSQL runtime binaries");
8510
+ const binaryPath = path9.join(binDir, runtimePostgresExecutableName(binary));
8347
8511
  try {
8348
- await stat3(binaryPath);
8512
+ await stat(binaryPath);
8349
8513
  } catch {
8350
8514
  missing.push(binaryPath);
8351
8515
  }
8352
8516
  }
8353
- const templateDir = await resolveRuntimePostgresTemplateDir(binDir);
8517
+ const templateDir = await resolveRuntimePostgresTemplateDir(binDir, cacheDir, deadline);
8354
8518
  if (!templateDir) {
8355
- missing.push(path10.join(binDir, "..", "share", "postgresql", "postgres.bki"));
8519
+ missing.push(path9.join(binDir, "..", "share", "postgresql", "postgres.bki"));
8356
8520
  } else {
8357
8521
  try {
8358
- await stat3(path10.join(templateDir, "postgresql.conf.sample"));
8522
+ await stat(path9.join(templateDir, "postgresql.conf.sample"));
8359
8523
  } catch {
8360
- missing.push(path10.join(templateDir, "postgresql.conf.sample"));
8524
+ missing.push(path9.join(templateDir, "postgresql.conf.sample"));
8361
8525
  }
8362
8526
  const shareDir = resolveRuntimePostgresShareDir(binDir, templateDir);
8363
8527
  const hasTimezoneDir = (await Promise.all([
8364
- path10.join(templateDir, "timezone"),
8365
- path10.join(shareDir, "timezone")
8366
- ].map((candidate) => stat3(candidate).catch(() => null)))).some((candidate) => candidate?.isDirectory());
8367
- if (!hasTimezoneDir) missing.push(path10.join(shareDir, "timezone"));
8528
+ path9.join(templateDir, "timezone"),
8529
+ path9.join(shareDir, "timezone")
8530
+ ].map((candidate) => stat(candidate).catch(() => null)))).some((candidate) => candidate?.isDirectory());
8531
+ if (!hasTimezoneDir) missing.push(path9.join(shareDir, "timezone"));
8368
8532
  }
8369
8533
  if (missing.length > 0) {
8370
8534
  throw new RuntimeInstallError(
@@ -8373,31 +8537,124 @@ async function assertRuntimePostgresBinDirComplete(cacheDir, binDir) {
8373
8537
  );
8374
8538
  }
8375
8539
  }
8376
- function readPostgresVersion(postgresBinary) {
8377
- return execFileSync(postgresBinary, ["--version"], { encoding: "utf8" });
8540
+ function readPostgresVersion(postgresBinary, timeout) {
8541
+ return execFileSync(postgresBinary, ["--version"], {
8542
+ encoding: "utf8",
8543
+ ...timeout === void 0 ? {} : { timeout }
8544
+ });
8378
8545
  }
8379
- async function isRuntimePostgresPayloadUsable(cacheDir, binDir, postgresVersionProbe) {
8546
+ async function isRuntimePostgresPayloadUsable(cacheDir, binDir, postgresVersionProbe, deadline) {
8380
8547
  try {
8381
- await validateRuntimePostgresVersion(cacheDir, binDir, postgresVersionProbe);
8548
+ await validateRuntimePostgresVersion(cacheDir, binDir, postgresVersionProbe, deadline);
8382
8549
  return true;
8383
- } catch {
8550
+ } catch (error) {
8551
+ if (isRuntimeInstallDeadlineError(error)) throw error;
8384
8552
  return false;
8385
8553
  }
8386
8554
  }
8387
8555
  function pathIsInside(candidatePath, rootPath) {
8388
- const relative = path10.relative(path10.resolve(rootPath), path10.resolve(candidatePath));
8389
- return relative === "" || relative !== ".." && !relative.startsWith(`..${path10.sep}`) && !path10.isAbsolute(relative);
8556
+ const relative = path9.relative(path9.resolve(rootPath), path9.resolve(candidatePath));
8557
+ return relative === "" || relative !== ".." && !relative.startsWith(`..${path9.sep}`) && !path9.isAbsolute(relative);
8558
+ }
8559
+ async function copyRuntimePayloadEntry(sourcePath, targetPath, cacheDir, deadline, signal, command) {
8560
+ if (signal.aborted) throw runtimeInstallDeadlineError(cacheDir, command);
8561
+ remainingRuntimeInstallMs(deadline, cacheDir, command);
8562
+ const sourceStats = await stat(sourcePath);
8563
+ if (signal.aborted) throw runtimeInstallDeadlineError(cacheDir, command);
8564
+ remainingRuntimeInstallMs(deadline, cacheDir, command);
8565
+ if (sourceStats.isDirectory()) {
8566
+ await mkdir(targetPath, { recursive: true });
8567
+ const entries = await readdir(sourcePath);
8568
+ for (const entry of entries) {
8569
+ await copyRuntimePayloadEntry(
8570
+ path9.join(sourcePath, entry),
8571
+ path9.join(targetPath, entry),
8572
+ cacheDir,
8573
+ deadline,
8574
+ signal,
8575
+ command
8576
+ );
8577
+ }
8578
+ return;
8579
+ }
8580
+ if (!sourceStats.isFile()) return;
8581
+ await mkdir(path9.dirname(targetPath), { recursive: true });
8582
+ try {
8583
+ await pipeline2(
8584
+ createReadStream2(sourcePath),
8585
+ createWriteStream2(targetPath, { flags: "w", mode: sourceStats.mode }),
8586
+ { signal }
8587
+ );
8588
+ await chmod(targetPath, sourceStats.mode);
8589
+ remainingRuntimeInstallMs(deadline, cacheDir, command);
8590
+ } catch (error) {
8591
+ await rm(targetPath, { force: true });
8592
+ if (signal.aborted || isRuntimeInstallDeadlineError(error)) {
8593
+ throw runtimeInstallDeadlineError(cacheDir, command);
8594
+ }
8595
+ throw error;
8596
+ }
8597
+ }
8598
+ async function copyRuntimePostgresPayloadWithinDeadline(sourceRuntimeDir, targetRuntimeDir, sourceShareDir, cacheDir, deadline, externalSignal) {
8599
+ const command = "copy PostgreSQL runtime payload";
8600
+ const timeoutMs = remainingRuntimeInstallMs(deadline, cacheDir, command);
8601
+ const controller = new AbortController();
8602
+ const abortFromExternal = () => controller.abort(externalSignal?.reason);
8603
+ if (externalSignal?.aborted) abortFromExternal();
8604
+ else externalSignal?.addEventListener("abort", abortFromExternal, { once: true });
8605
+ let timer;
8606
+ const timeoutPromise = timeoutMs === void 0 ? null : new Promise((_resolve, reject) => {
8607
+ timer = setTimeout(() => {
8608
+ controller.abort();
8609
+ reject(runtimeInstallDeadlineError(cacheDir, command));
8610
+ }, timeoutMs);
8611
+ });
8612
+ const copyPromise = (async () => {
8613
+ await mkdir(targetRuntimeDir, { recursive: true });
8614
+ for (const directoryName of ["bin", "lib"]) {
8615
+ const sourceDirectory = path9.join(sourceRuntimeDir, directoryName);
8616
+ if (!await stat(sourceDirectory).catch(() => null)) continue;
8617
+ await copyRuntimePayloadEntry(
8618
+ sourceDirectory,
8619
+ path9.join(targetRuntimeDir, directoryName),
8620
+ cacheDir,
8621
+ deadline,
8622
+ controller.signal,
8623
+ command
8624
+ );
8625
+ }
8626
+ await copyRuntimePayloadEntry(
8627
+ sourceShareDir,
8628
+ path9.join(targetRuntimeDir, "share"),
8629
+ cacheDir,
8630
+ deadline,
8631
+ controller.signal,
8632
+ command
8633
+ );
8634
+ })();
8635
+ try {
8636
+ if (timeoutPromise) await Promise.race([copyPromise, timeoutPromise]);
8637
+ else await copyPromise;
8638
+ } finally {
8639
+ if (timer) clearTimeout(timer);
8640
+ externalSignal?.removeEventListener("abort", abortFromExternal);
8641
+ }
8390
8642
  }
8391
8643
  async function withRuntimeFilesystemLock(lockPath, task, options = {}) {
8392
- const timeoutMs = options.timeoutMs ?? 3e4;
8644
+ const deadlineTimeout = remainingRuntimeInstallMs(
8645
+ options.deadline,
8646
+ options.cacheDir ?? path9.dirname(lockPath),
8647
+ options.command ?? `wait for runtime lock ${lockPath}`
8648
+ );
8649
+ const timeoutMs = Math.min(options.timeoutMs ?? 3e4, deadlineTimeout ?? Number.POSITIVE_INFINITY);
8393
8650
  const pollMs = options.pollMs ?? 50;
8394
8651
  const startedAt = Date.now();
8395
8652
  const lockId = `${process.pid}-${startedAt}-${Math.random().toString(16).slice(2)}`;
8396
- const ownerPath = path10.join(lockPath, "owner.json");
8397
- await mkdir2(path10.dirname(lockPath), { recursive: true });
8653
+ const ownerPath = path9.join(lockPath, "owner.json");
8654
+ await mkdir(path9.dirname(lockPath), { recursive: true });
8398
8655
  while (true) {
8399
8656
  try {
8400
- await mkdir2(lockPath);
8657
+ await mkdir(lockPath);
8401
8658
  await writeFile(
8402
8659
  ownerPath,
8403
8660
  `${JSON.stringify({ pid: process.pid, lockId, createdAt: (/* @__PURE__ */ new Date()).toISOString() })}
@@ -8414,7 +8671,7 @@ async function withRuntimeFilesystemLock(lockPath, task, options = {}) {
8414
8671
  continue;
8415
8672
  }
8416
8673
  } catch {
8417
- const lockStats = await stat3(lockPath).catch(() => null);
8674
+ const lockStats = await stat(lockPath).catch(() => null);
8418
8675
  if (lockStats && Date.now() - lockStats.mtimeMs > 5e3) {
8419
8676
  await rm(lockPath, { recursive: true, force: true });
8420
8677
  continue;
@@ -8423,9 +8680,14 @@ async function withRuntimeFilesystemLock(lockPath, task, options = {}) {
8423
8680
  if (Date.now() - startedAt >= timeoutMs) {
8424
8681
  throw new RuntimeInstallError(
8425
8682
  `Timed out waiting for PostgreSQL runtime install lock ${lockPath}`,
8426
- { cacheDir: path10.dirname(lockPath), command: "prepare shared PostgreSQL runtime", output: "" }
8683
+ { cacheDir: path9.dirname(lockPath), command: "prepare shared PostgreSQL runtime", output: "" }
8427
8684
  );
8428
8685
  }
8686
+ remainingRuntimeInstallMs(
8687
+ options.deadline,
8688
+ options.cacheDir ?? path9.dirname(lockPath),
8689
+ options.command ?? `wait for runtime lock ${lockPath}`
8690
+ );
8429
8691
  await new Promise((resolve) => setTimeout(resolve, pollMs));
8430
8692
  }
8431
8693
  }
@@ -8443,44 +8705,45 @@ async function withRuntimeFilesystemLock(lockPath, task, options = {}) {
8443
8705
  }
8444
8706
  function isManagedRuntimePostgresBinDir(binDir, homeDir) {
8445
8707
  const managedBinDir = process.env[RUDDER_DESKTOP_MANAGED_POSTGRES_BIN_DIR_ENV]?.trim();
8446
- if (managedBinDir && path10.resolve(managedBinDir) === path10.resolve(binDir)) return true;
8447
- const runtimesRelative = path10.relative(
8448
- path10.join(homeDir, "runtimes"),
8449
- path10.resolve(binDir)
8708
+ if (managedBinDir && path9.resolve(managedBinDir) === path9.resolve(binDir)) return true;
8709
+ const runtimesRelative = path9.relative(
8710
+ path9.join(homeDir, "runtimes"),
8711
+ path9.resolve(binDir)
8450
8712
  );
8451
- const runtimeSegments = runtimesRelative.split(path10.sep);
8452
- if (runtimesRelative !== "" && runtimesRelative !== ".." && !runtimesRelative.startsWith(`..${path10.sep}`) && !path10.isAbsolute(runtimesRelative) && runtimeSegments.length === 4 && runtimeSegments[0]?.length > 0 && runtimeSegments[1] === RUNTIME_POSTGRES_PAYLOAD_DIR && runtimeSegments[2] === `${process.platform}-${process.arch}` && runtimeSegments[3] === "bin") {
8713
+ const runtimeSegments = runtimesRelative.split(path9.sep);
8714
+ if (runtimesRelative !== "" && runtimesRelative !== ".." && !runtimesRelative.startsWith(`..${path9.sep}`) && !path9.isAbsolute(runtimesRelative) && runtimeSegments.length === 4 && runtimeSegments[0]?.length > 0 && runtimeSegments[1] === RUNTIME_POSTGRES_PAYLOAD_DIR && runtimeSegments[2] === `${process.platform}-${process.arch}` && runtimeSegments[3] === "bin") {
8453
8715
  return true;
8454
8716
  }
8455
- const payloadsRelative = path10.relative(
8456
- path10.join(homeDir, "runtime-payloads"),
8457
- path10.resolve(binDir)
8717
+ const payloadsRelative = path9.relative(
8718
+ path9.join(homeDir, "runtime-payloads"),
8719
+ path9.resolve(binDir)
8458
8720
  );
8459
- const payloadSegments = payloadsRelative.split(path10.sep);
8460
- return payloadsRelative !== "" && payloadsRelative !== ".." && !payloadsRelative.startsWith(`..${path10.sep}`) && !path10.isAbsolute(payloadsRelative) && payloadSegments.length === 3 && payloadSegments[0] === RUNTIME_POSTGRES_PAYLOAD_DIR && payloadSegments[1] === `${process.platform}-${process.arch}` && payloadSegments[2] === "bin";
8721
+ const payloadSegments = payloadsRelative.split(path9.sep);
8722
+ return payloadsRelative !== "" && payloadsRelative !== ".." && !payloadsRelative.startsWith(`..${path9.sep}`) && !path9.isAbsolute(payloadsRelative) && payloadSegments.length === 3 && payloadSegments[0] === RUNTIME_POSTGRES_PAYLOAD_DIR && payloadSegments[1] === `${process.platform}-${process.arch}` && payloadSegments[2] === "bin";
8461
8723
  }
8462
- async function findLegacyRuntimePostgresBinDir(cacheDir, homeDir, postgresVersionProbe) {
8463
- const runtimesRoot = path10.join(homeDir, "runtimes");
8724
+ async function findLegacyRuntimePostgresBinDir(cacheDir, homeDir, postgresVersionProbe, deadline) {
8725
+ const runtimesRoot = path9.join(homeDir, "runtimes");
8464
8726
  const entries = await readdir(runtimesRoot, { withFileTypes: true }).catch(() => []);
8465
8727
  for (const entry of entries) {
8466
8728
  if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;
8467
- const candidateCacheDir = path10.join(runtimesRoot, entry.name);
8468
- if (path10.resolve(candidateCacheDir) === path10.resolve(cacheDir)) continue;
8729
+ const candidateCacheDir = path9.join(runtimesRoot, entry.name);
8730
+ if (path9.resolve(candidateCacheDir) === path9.resolve(cacheDir)) continue;
8469
8731
  const candidateBinDir = resolveRuntimePostgresPayloadBinDir(candidateCacheDir);
8470
- if (await isRuntimePostgresPayloadUsable(cacheDir, candidateBinDir, postgresVersionProbe)) {
8732
+ remainingRuntimeInstallMs(deadline, cacheDir, "find cached PostgreSQL runtime payload");
8733
+ if (await isRuntimePostgresPayloadUsable(cacheDir, candidateBinDir, postgresVersionProbe, deadline)) {
8471
8734
  return candidateBinDir;
8472
8735
  }
8473
8736
  }
8474
8737
  return null;
8475
8738
  }
8476
8739
  async function readLiveRuntimeDescriptors(homeDir) {
8477
- const instancesRoot = path10.join(homeDir, "instances");
8740
+ const instancesRoot = path9.join(homeDir, "instances");
8478
8741
  const entries = await readdir(instancesRoot, { withFileTypes: true }).catch(() => []);
8479
8742
  const descriptors = [];
8480
8743
  for (const entry of entries) {
8481
8744
  if (!entry.isDirectory()) continue;
8482
8745
  try {
8483
- const raw = JSON.parse(await readFile(path10.join(instancesRoot, entry.name, "runtime", "server.json"), "utf8"));
8746
+ const raw = JSON.parse(await readFile(path9.join(instancesRoot, entry.name, "runtime", "server.json"), "utf8"));
8484
8747
  if (typeof raw.pid !== "number" || !Number.isInteger(raw.pid) || !isPidRunning(raw.pid) || typeof raw.version !== "string") {
8485
8748
  continue;
8486
8749
  }
@@ -8498,13 +8761,13 @@ async function assertSharedPostgresPayloadNotLive(cacheDir, homeDir, sharedBinDi
8498
8761
  const sharedPhysicalBinDir = await realpath(sharedBinDir).catch(() => null);
8499
8762
  const mayReferenceSharedPayload = await Promise.all(liveDescriptors.map(async (descriptor) => {
8500
8763
  if (descriptor.postgresBinDir === void 0) return true;
8501
- if (path10.resolve(descriptor.postgresBinDir) === path10.resolve(sharedBinDir)) return true;
8764
+ if (path9.resolve(descriptor.postgresBinDir) === path9.resolve(sharedBinDir)) return true;
8502
8765
  const descriptorPhysicalBinDir = await realpath(descriptor.postgresBinDir).catch(() => null);
8503
- if (descriptorPhysicalBinDir && sharedPhysicalBinDir && path10.resolve(descriptorPhysicalBinDir) === path10.resolve(sharedPhysicalBinDir)) {
8766
+ if (descriptorPhysicalBinDir && sharedPhysicalBinDir && path9.resolve(descriptorPhysicalBinDir) === path9.resolve(sharedPhysicalBinDir)) {
8504
8767
  return true;
8505
8768
  }
8506
8769
  if (!descriptorPhysicalBinDir) {
8507
- return pathIsInside(descriptor.postgresBinDir, path10.join(homeDir, "runtimes")) || pathIsInside(descriptor.postgresBinDir, path10.join(homeDir, "runtime-payloads"));
8770
+ return pathIsInside(descriptor.postgresBinDir, path9.join(homeDir, "runtimes")) || pathIsInside(descriptor.postgresBinDir, path9.join(homeDir, "runtime-payloads"));
8508
8771
  }
8509
8772
  return false;
8510
8773
  }));
@@ -8515,10 +8778,11 @@ async function assertSharedPostgresPayloadNotLive(cacheDir, homeDir, sharedBinDi
8515
8778
  );
8516
8779
  }
8517
8780
  }
8518
- async function validateRuntimePostgresVersion(cacheDir, binDir, postgresVersionProbe) {
8519
- await assertRuntimePostgresBinDirComplete(cacheDir, binDir);
8781
+ async function validateRuntimePostgresVersion(cacheDir, binDir, postgresVersionProbe, deadline) {
8782
+ await assertRuntimePostgresBinDirComplete(cacheDir, binDir, deadline);
8520
8783
  for (const binary of ["initdb", "pg_ctl", "postgres"]) {
8521
- const binaryPath = path10.join(binDir, runtimePostgresExecutableName(binary));
8784
+ remainingRuntimeInstallMs(deadline, cacheDir, "validate PostgreSQL runtime version");
8785
+ const binaryPath = path9.join(binDir, runtimePostgresExecutableName(binary));
8522
8786
  const result = postgresVersionProbe(binaryPath);
8523
8787
  if (!/\bPostgreSQL\)?\s+18\.4\b/i.test(result)) {
8524
8788
  throw new RuntimeInstallError(
@@ -8528,7 +8792,8 @@ async function validateRuntimePostgresVersion(cacheDir, binDir, postgresVersionP
8528
8792
  }
8529
8793
  }
8530
8794
  }
8531
- function extractRuntimePostgresArchive(archivePath, extractDir) {
8795
+ function extractRuntimePostgresArchive(archivePath, extractDir, cacheDir, deadline) {
8796
+ const timeout = remainingRuntimeInstallMs(deadline, cacheDir, "extract PostgreSQL runtime archive");
8532
8797
  const result = process.platform === "win32" ? spawnSync2("powershell.exe", [
8533
8798
  "-NoProfile",
8534
8799
  "-NonInteractive",
@@ -8539,46 +8804,54 @@ function extractRuntimePostgresArchive(archivePath, extractDir) {
8539
8804
  ], {
8540
8805
  encoding: "utf8",
8541
8806
  env: { ...process.env, PG_ARCHIVE_PATH: archivePath, PG_EXTRACT_DIR: extractDir },
8542
- windowsHide: true
8543
- }) : spawnSync2("tar", ["-xf", archivePath, "-C", extractDir], { encoding: "utf8" });
8807
+ windowsHide: true,
8808
+ ...timeout === void 0 ? {} : { timeout }
8809
+ }) : spawnSync2("tar", ["-xf", archivePath, "-C", extractDir], {
8810
+ encoding: "utf8",
8811
+ ...timeout === void 0 ? {} : { timeout }
8812
+ });
8544
8813
  if (result.status !== 0) {
8545
8814
  throw new Error(`failed to extract PostgreSQL archive: ${result.stderr || result.stdout}`);
8546
8815
  }
8547
8816
  }
8548
- async function findRuntimePostgresBinDir(rootDir, cacheDir, postgresVersionProbe) {
8817
+ async function findRuntimePostgresBinDir(rootDir, cacheDir, postgresVersionProbe, deadline) {
8549
8818
  const queue = [rootDir];
8550
8819
  for (let index = 0; index < queue.length; index += 1) {
8551
8820
  const current = queue[index];
8552
- if (await isRuntimePostgresPayloadUsable(cacheDir, current, postgresVersionProbe)) return current;
8821
+ remainingRuntimeInstallMs(deadline, cacheDir, "find PostgreSQL runtime payload");
8822
+ if (await isRuntimePostgresPayloadUsable(cacheDir, current, postgresVersionProbe, deadline)) return current;
8553
8823
  const entries = await readdir(current, { withFileTypes: true }).catch(() => []);
8554
8824
  for (const entry of entries) {
8555
- if (entry.isDirectory()) queue.push(path10.join(current, entry.name));
8825
+ if (entry.isDirectory()) queue.push(path9.join(current, entry.name));
8556
8826
  }
8557
8827
  }
8558
8828
  return null;
8559
8829
  }
8560
- async function reconcileSharedPostgresPayloadGenerations(cacheDir, sharedPlatformRoot, postgresVersionProbe, cleanupDownloads = false) {
8561
- const parentDir = path10.dirname(sharedPlatformRoot);
8562
- const baseName = path10.basename(sharedPlatformRoot);
8830
+ async function reconcileSharedPostgresPayloadGenerations(cacheDir, sharedPlatformRoot, postgresVersionProbe, cleanupDownloads = false, deadline) {
8831
+ remainingRuntimeInstallMs(deadline, cacheDir, "reconcile shared PostgreSQL payload");
8832
+ const parentDir = path9.dirname(sharedPlatformRoot);
8833
+ const baseName = path9.basename(sharedPlatformRoot);
8563
8834
  const entries = await readdir(parentDir, { withFileTypes: true }).catch(() => []);
8564
- const temporaryRoots = entries.filter((entry) => entry.name.startsWith(`${baseName}.tmp-`)).map((entry) => path10.join(parentDir, entry.name));
8565
- const previousRoots = entries.filter((entry) => entry.name.startsWith(`${baseName}.previous-`)).map((entry) => path10.join(parentDir, entry.name)).sort().reverse();
8566
- const downloadsRoot = path10.join(
8567
- path10.dirname(path10.dirname(sharedPlatformRoot)),
8835
+ const temporaryRoots = entries.filter((entry) => entry.name.startsWith(`${baseName}.tmp-`)).map((entry) => path9.join(parentDir, entry.name));
8836
+ const previousRoots = entries.filter((entry) => entry.name.startsWith(`${baseName}.previous-`)).map((entry) => path9.join(parentDir, entry.name)).sort().reverse();
8837
+ const downloadsRoot = path9.join(
8838
+ path9.dirname(path9.dirname(sharedPlatformRoot)),
8568
8839
  ".downloads"
8569
8840
  );
8570
- const staleDownloadRoots = cleanupDownloads ? (await readdir(downloadsRoot, { withFileTypes: true }).catch(() => [])).filter((entry) => entry.name.startsWith("postgres-18.4-")).map((entry) => path10.join(downloadsRoot, entry.name)) : [];
8571
- const canonicalBinDir = path10.join(sharedPlatformRoot, "bin");
8841
+ const staleDownloadRoots = cleanupDownloads ? (await readdir(downloadsRoot, { withFileTypes: true }).catch(() => [])).filter((entry) => entry.name.startsWith("postgres-18.4-")).map((entry) => path9.join(downloadsRoot, entry.name)) : [];
8842
+ const canonicalBinDir = path9.join(sharedPlatformRoot, "bin");
8572
8843
  if (!await isRuntimePostgresPayloadUsable(
8573
8844
  cacheDir,
8574
8845
  canonicalBinDir,
8575
- postgresVersionProbe
8846
+ postgresVersionProbe,
8847
+ deadline
8576
8848
  )) {
8577
8849
  for (const previousRoot of previousRoots) {
8578
8850
  if (!await isRuntimePostgresPayloadUsable(
8579
8851
  cacheDir,
8580
- path10.join(previousRoot, "bin"),
8581
- postgresVersionProbe
8852
+ path9.join(previousRoot, "bin"),
8853
+ postgresVersionProbe,
8854
+ deadline
8582
8855
  )) {
8583
8856
  continue;
8584
8857
  }
@@ -8593,12 +8866,12 @@ async function reconcileSharedPostgresPayloadGenerations(cacheDir, sharedPlatfor
8593
8866
  ...staleDownloadRoots.map((candidate) => rm(candidate, { recursive: true, force: true }))
8594
8867
  ]);
8595
8868
  }
8596
- async function installSharedRuntimePostgresPayload(cacheDir, homeDir, sourceBinDir, postgresVersionProbe) {
8869
+ async function installSharedRuntimePostgresPayload(cacheDir, homeDir, sourceBinDir, postgresVersionProbe, deadline) {
8597
8870
  const sharedBinDir = resolveSharedRuntimePostgresPayloadBinDir(homeDir);
8598
- const sharedRuntimeDir = path10.dirname(sharedBinDir);
8871
+ const sharedRuntimeDir = path9.dirname(sharedBinDir);
8599
8872
  const sharedPlatformRoot = sharedRuntimeDir;
8600
- const sourceRuntimeDir = path10.dirname(sourceBinDir);
8601
- const sourceTemplateDir = await resolveRuntimePostgresTemplateDir(sourceBinDir);
8873
+ const sourceRuntimeDir = path9.dirname(sourceBinDir);
8874
+ const sourceTemplateDir = await resolveRuntimePostgresTemplateDir(sourceBinDir, cacheDir, deadline);
8602
8875
  if (!sourceTemplateDir) {
8603
8876
  throw new RuntimeInstallError(
8604
8877
  `${RUDDER_POSTGRES_BIN_DIR_ENV} must contain PostgreSQL 18.4 initdb template files`,
@@ -8610,13 +8883,15 @@ async function installSharedRuntimePostgresPayload(cacheDir, homeDir, sourceBinD
8610
8883
  await reconcileSharedPostgresPayloadGenerations(
8611
8884
  cacheDir,
8612
8885
  sharedPlatformRoot,
8613
- postgresVersionProbe
8886
+ postgresVersionProbe,
8887
+ false,
8888
+ deadline
8614
8889
  );
8615
- if (await isRuntimePostgresPayloadUsable(cacheDir, sharedBinDir, postgresVersionProbe)) {
8890
+ if (await isRuntimePostgresPayloadUsable(cacheDir, sharedBinDir, postgresVersionProbe, deadline)) {
8616
8891
  return sharedBinDir;
8617
8892
  }
8618
8893
  await assertSharedPostgresPayloadNotLive(cacheDir, homeDir, sharedBinDir);
8619
- await mkdir2(path10.dirname(sharedPlatformRoot), { recursive: true });
8894
+ await mkdir(path9.dirname(sharedPlatformRoot), { recursive: true });
8620
8895
  const temporaryPlatformRoot = `${sharedPlatformRoot}.tmp-${process.pid}-${Date.now()}`;
8621
8896
  const previousPlatformRoot = `${sharedPlatformRoot}.previous-${process.pid}-${Date.now()}`;
8622
8897
  let previousMoved = false;
@@ -8626,13 +8901,15 @@ async function installSharedRuntimePostgresPayload(cacheDir, homeDir, sourceBinD
8626
8901
  try {
8627
8902
  const temporaryRuntimeDir = temporaryPlatformRoot;
8628
8903
  const sourceShareDir = resolveRuntimePostgresShareDir(sourceBinDir, sourceTemplateDir);
8629
- await copyRuntimePostgresPayload(
8904
+ await copyRuntimePostgresPayloadWithinDeadline(
8630
8905
  sourceRuntimeDir,
8631
8906
  temporaryRuntimeDir,
8632
- sourceShareDir
8907
+ sourceShareDir,
8908
+ cacheDir,
8909
+ deadline
8633
8910
  );
8634
- const temporaryBinDir = path10.join(temporaryRuntimeDir, "bin");
8635
- await validateRuntimePostgresVersion(cacheDir, temporaryBinDir, postgresVersionProbe);
8911
+ const temporaryBinDir = path9.join(temporaryRuntimeDir, "bin");
8912
+ await validateRuntimePostgresVersion(cacheDir, temporaryBinDir, postgresVersionProbe, deadline);
8636
8913
  try {
8637
8914
  await rename(sharedPlatformRoot, previousPlatformRoot);
8638
8915
  previousMoved = true;
@@ -8660,30 +8937,35 @@ async function installSharedRuntimePostgresPayload(cacheDir, homeDir, sourceBinD
8660
8937
  }
8661
8938
  }
8662
8939
  return sharedBinDir;
8663
- });
8940
+ }, { deadline, cacheDir, command: "acquire shared PostgreSQL install lock" });
8664
8941
  }
8665
- async function downloadSharedRuntimePostgresPayload(cacheDir, homeDir, postgresVersionProbe) {
8942
+ async function downloadSharedRuntimePostgresPayload(cacheDir, homeDir, postgresVersionProbe, deadline, cleanupWorkDir) {
8666
8943
  const archiveSource = resolvePostgresRuntimeArchiveSource();
8667
8944
  const archiveUrl = archiveSource?.url ?? null;
8668
8945
  if (!archiveUrl) return null;
8669
8946
  const sharedBinDir = resolveSharedRuntimePostgresPayloadBinDir(homeDir);
8670
- const sharedPlatformRoot = path10.dirname(sharedBinDir);
8947
+ const sharedPlatformRoot = path9.dirname(sharedBinDir);
8671
8948
  const downloadLockPath = `${sharedPlatformRoot}.download.lock`;
8672
8949
  return withRuntimeFilesystemLock(downloadLockPath, async () => {
8673
- if (await isRuntimePostgresPayloadUsable(cacheDir, sharedBinDir, postgresVersionProbe)) {
8950
+ if (await isRuntimePostgresPayloadUsable(cacheDir, sharedBinDir, postgresVersionProbe, deadline)) {
8674
8951
  return sharedBinDir;
8675
8952
  }
8676
- const workRoot = path10.join(homeDir, "runtime-payloads", ".downloads");
8677
- await mkdir2(workRoot, { recursive: true });
8678
- const workDir = await mkdtemp(path10.join(workRoot, "postgres-18.4-"));
8679
- const archivePath = path10.join(workDir, "postgresql-18.4.zip");
8680
- const extractDir = path10.join(workDir, "extract");
8953
+ const workRoot = path9.join(homeDir, "runtime-payloads", ".downloads");
8954
+ await mkdir(workRoot, { recursive: true });
8955
+ const workDir = await mkdtemp(path9.join(workRoot, "postgres-18.4-"));
8956
+ const archivePath = path9.join(workDir, "postgresql-18.4.zip");
8957
+ const extractDir = path9.join(workDir, "extract");
8681
8958
  try {
8682
- await downloadRuntimePostgresArchive(archiveUrl, archivePath, archiveSource?.expectedSha256);
8959
+ await downloadRuntimePostgresArchive(
8960
+ archiveUrl,
8961
+ archivePath,
8962
+ archiveSource?.expectedSha256,
8963
+ { timeoutMs: remainingRuntimeInstallMs(deadline, cacheDir, "download PostgreSQL runtime archive") }
8964
+ );
8683
8965
  const configuredMaxBytes = Number.parseInt(process.env[RUDDER_POSTGRES_RUNTIME_ARCHIVE_MAX_BYTES_ENV2] ?? "", 10);
8684
8966
  const maxArchiveBytes = Number.isSafeInteger(configuredMaxBytes) && configuredMaxBytes > 0 ? configuredMaxBytes : DEFAULT_RUNTIME_POSTGRES_ARCHIVE_MAX_BYTES2;
8685
8967
  const nativePublishStaging = `${sharedPlatformRoot}.tmp-native-${process.pid}-${Date.now()}`;
8686
- await mkdir2(path10.dirname(sharedPlatformRoot), { recursive: true });
8968
+ await mkdir(path9.dirname(sharedPlatformRoot), { recursive: true });
8687
8969
  const nativeInstall = await tryInstallNativePayload({
8688
8970
  archivePath,
8689
8971
  extractPath: extractDir,
@@ -8691,11 +8973,14 @@ async function downloadSharedRuntimePostgresPayload(cacheDir, homeDir, postgresV
8691
8973
  destinationPath: sharedPlatformRoot,
8692
8974
  maxArchiveBytes,
8693
8975
  expectedSha256: archiveSource?.expectedSha256,
8694
- preparePublish: async (nativeExtractPath, publishStagingPath) => {
8976
+ timeoutMs: remainingRuntimeInstallMs(deadline, cacheDir, "prepare native PostgreSQL runtime payload"),
8977
+ now: deadline?.now,
8978
+ preparePublish: async (nativeExtractPath, publishStagingPath, context) => {
8695
8979
  const extractedBinDir2 = await findRuntimePostgresBinDir(
8696
8980
  nativeExtractPath,
8697
8981
  cacheDir,
8698
- postgresVersionProbe
8982
+ postgresVersionProbe,
8983
+ deadline
8699
8984
  );
8700
8985
  if (!extractedBinDir2) {
8701
8986
  throw new RuntimeInstallError(
@@ -8703,41 +8988,46 @@ async function downloadSharedRuntimePostgresPayload(cacheDir, homeDir, postgresV
8703
8988
  { cacheDir, command: "prepare native PostgreSQL runtime payload", output: "" }
8704
8989
  );
8705
8990
  }
8706
- await validateRuntimePostgresVersion(cacheDir, extractedBinDir2, postgresVersionProbe);
8707
- const templateDir = await resolveRuntimePostgresTemplateDir(extractedBinDir2);
8991
+ await validateRuntimePostgresVersion(cacheDir, extractedBinDir2, postgresVersionProbe, deadline);
8992
+ const templateDir = await resolveRuntimePostgresTemplateDir(extractedBinDir2, cacheDir, deadline);
8708
8993
  if (!templateDir) {
8709
8994
  throw new RuntimeInstallError(
8710
8995
  "PostgreSQL 18.4 archive did not contain initdb template files",
8711
8996
  { cacheDir, command: "prepare native PostgreSQL runtime payload", output: "" }
8712
8997
  );
8713
8998
  }
8714
- await copyRuntimePostgresPayload(
8715
- path10.dirname(extractedBinDir2),
8999
+ await copyRuntimePostgresPayloadWithinDeadline(
9000
+ path9.dirname(extractedBinDir2),
8716
9001
  publishStagingPath,
8717
- resolveRuntimePostgresShareDir(extractedBinDir2, templateDir)
9002
+ resolveRuntimePostgresShareDir(extractedBinDir2, templateDir),
9003
+ cacheDir,
9004
+ deadline,
9005
+ context.signal
8718
9006
  );
8719
- return path10.relative(
9007
+ return path9.relative(
8720
9008
  publishStagingPath,
8721
- path10.join(publishStagingPath, "bin", runtimePostgresExecutableName("postgres"))
9009
+ path9.join(publishStagingPath, "bin", runtimePostgresExecutableName("postgres"))
8722
9010
  );
8723
9011
  },
8724
9012
  validatePublished: async (destinationPath) => {
8725
9013
  await validateRuntimePostgresVersion(
8726
9014
  cacheDir,
8727
- path10.join(destinationPath, "bin"),
8728
- postgresVersionProbe
9015
+ path9.join(destinationPath, "bin"),
9016
+ postgresVersionProbe,
9017
+ deadline
8729
9018
  );
8730
9019
  }
8731
9020
  });
8732
9021
  if (nativeInstall.installed) {
8733
9022
  return sharedBinDir;
8734
9023
  }
8735
- await mkdir2(extractDir, { recursive: true });
8736
- extractRuntimePostgresArchive(archivePath, extractDir);
9024
+ await mkdir(extractDir, { recursive: true });
9025
+ extractRuntimePostgresArchive(archivePath, extractDir, cacheDir, deadline);
8737
9026
  const extractedBinDir = await findRuntimePostgresBinDir(
8738
9027
  extractDir,
8739
9028
  cacheDir,
8740
- postgresVersionProbe
9029
+ postgresVersionProbe,
9030
+ deadline
8741
9031
  );
8742
9032
  if (!extractedBinDir) {
8743
9033
  throw new RuntimeInstallError(
@@ -8749,28 +9039,31 @@ async function downloadSharedRuntimePostgresPayload(cacheDir, homeDir, postgresV
8749
9039
  cacheDir,
8750
9040
  homeDir,
8751
9041
  extractedBinDir,
8752
- postgresVersionProbe
9042
+ postgresVersionProbe,
9043
+ deadline
8753
9044
  );
8754
9045
  } finally {
8755
- await rm(workDir, { recursive: true, force: true });
9046
+ const cleanup = cleanupWorkDir ?? ((candidate) => rm(candidate, { recursive: true, force: true }));
9047
+ void cleanup(workDir).catch(() => {
9048
+ });
8756
9049
  }
8757
- });
9050
+ }, { deadline, cacheDir, command: "acquire shared PostgreSQL download lock" });
8758
9051
  }
8759
9052
  async function ensureRuntimePostgresCompatibilityLink(cacheDir, homeDir, packageVersion) {
8760
- const compatibilityRoot = path10.join(cacheDir, RUNTIME_POSTGRES_PAYLOAD_DIR);
8761
- const sharedPayloadRoot = path10.join(homeDir, "runtime-payloads", RUNTIME_POSTGRES_PAYLOAD_DIR);
9053
+ const compatibilityRoot = path9.join(cacheDir, RUNTIME_POSTGRES_PAYLOAD_DIR);
9054
+ const sharedPayloadRoot = path9.join(homeDir, "runtime-payloads", RUNTIME_POSTGRES_PAYLOAD_DIR);
8762
9055
  const runtimeMetadata = await readRuntimeInstallMetadata(cacheDir);
8763
9056
  const liveDescriptors = await readLiveRuntimeDescriptors(homeDir);
8764
9057
  const compatibilityBinDir = resolveRuntimePostgresPayloadBinDir(cacheDir);
8765
9058
  const isProtected = liveDescriptors.some((descriptor) => descriptor.postgresBinDir && pathIsInside(descriptor.postgresBinDir, compatibilityRoot) || !descriptor.postgresBinDir && descriptor.version === (runtimeMetadata?.packageVersion ?? packageVersion));
8766
9059
  if (isProtected) return;
8767
- await mkdir2(path10.dirname(compatibilityRoot), { recursive: true });
9060
+ await mkdir(path9.dirname(compatibilityRoot), { recursive: true });
8768
9061
  const temporaryRoot = `${compatibilityRoot}.next-${process.pid}-${Date.now()}`;
8769
9062
  const previousRoot = `${compatibilityRoot}.previous-${process.pid}-${Date.now()}`;
8770
9063
  await rm(temporaryRoot, { recursive: true, force: true });
8771
9064
  await rm(previousRoot, { recursive: true, force: true });
8772
9065
  await symlink(
8773
- process.platform === "win32" ? sharedPayloadRoot : path10.relative(path10.dirname(compatibilityRoot), sharedPayloadRoot),
9066
+ process.platform === "win32" ? sharedPayloadRoot : path9.relative(path9.dirname(compatibilityRoot), sharedPayloadRoot),
8774
9067
  temporaryRoot,
8775
9068
  process.platform === "win32" ? "junction" : "dir"
8776
9069
  );
@@ -8800,15 +9093,16 @@ async function ensureRuntimePostgresCompatibilityLink(cacheDir, homeDir, package
8800
9093
  if (!previousMoved) await rm(previousRoot, { recursive: true, force: true });
8801
9094
  }
8802
9095
  }
8803
- async function stageRuntimePostgresPayload(cacheDir, homeDir, packageVersion, enabled, postgresVersionProbe) {
9096
+ async function stageRuntimePostgresPayload(cacheDir, homeDir, packageVersion, enabled, postgresVersionProbe, deadline, cleanupDownloadWorkDir) {
8804
9097
  if (!enabled) return { output: "" };
8805
9098
  const explicitSourceBinDir = process.env[RUDDER_POSTGRES_BIN_DIR_ENV]?.trim();
8806
- const resolvedExplicitSourceBinDir = explicitSourceBinDir ? path10.resolve(explicitSourceBinDir) : null;
9099
+ const resolvedExplicitSourceBinDir = explicitSourceBinDir ? path9.resolve(explicitSourceBinDir) : null;
8807
9100
  if (resolvedExplicitSourceBinDir && !isManagedRuntimePostgresBinDir(resolvedExplicitSourceBinDir, homeDir)) {
8808
9101
  await validateRuntimePostgresVersion(
8809
9102
  cacheDir,
8810
9103
  resolvedExplicitSourceBinDir,
8811
- postgresVersionProbe
9104
+ postgresVersionProbe,
9105
+ deadline
8812
9106
  );
8813
9107
  return {
8814
9108
  output: "",
@@ -8823,35 +9117,41 @@ async function stageRuntimePostgresPayload(cacheDir, homeDir, packageVersion, en
8823
9117
  };
8824
9118
  }
8825
9119
  const sharedBinDir = resolveSharedRuntimePostgresPayloadBinDir(homeDir);
8826
- const sharedPlatformRoot = path10.dirname(sharedBinDir);
9120
+ const sharedPlatformRoot = path9.dirname(sharedBinDir);
8827
9121
  await withRuntimeFilesystemLock(
8828
9122
  `${sharedPlatformRoot}.install.lock`,
8829
9123
  async () => reconcileSharedPostgresPayloadGenerations(
8830
9124
  cacheDir,
8831
9125
  sharedPlatformRoot,
8832
9126
  postgresVersionProbe,
8833
- true
8834
- )
9127
+ true,
9128
+ deadline
9129
+ ),
9130
+ { deadline, cacheDir, command: "reconcile shared PostgreSQL payload" }
8835
9131
  );
8836
9132
  let output = "";
8837
- if (!await isRuntimePostgresPayloadUsable(cacheDir, sharedBinDir, postgresVersionProbe)) {
8838
- const sourceBinDir = resolvedExplicitSourceBinDir ?? await findLegacyRuntimePostgresBinDir(cacheDir, homeDir, postgresVersionProbe);
9133
+ if (!await isRuntimePostgresPayloadUsable(cacheDir, sharedBinDir, postgresVersionProbe, deadline)) {
9134
+ const sourceBinDir = resolvedExplicitSourceBinDir ?? await findLegacyRuntimePostgresBinDir(cacheDir, homeDir, postgresVersionProbe, deadline);
8839
9135
  if (sourceBinDir) {
8840
9136
  await validateRuntimePostgresVersion(
8841
9137
  cacheDir,
8842
9138
  sourceBinDir,
8843
- postgresVersionProbe
9139
+ postgresVersionProbe,
9140
+ deadline
8844
9141
  );
8845
9142
  await installSharedRuntimePostgresPayload(
8846
9143
  cacheDir,
8847
9144
  homeDir,
8848
9145
  sourceBinDir,
8849
- postgresVersionProbe
9146
+ postgresVersionProbe,
9147
+ deadline
8850
9148
  );
8851
9149
  } else if (!await downloadSharedRuntimePostgresPayload(
8852
9150
  cacheDir,
8853
9151
  homeDir,
8854
- postgresVersionProbe
9152
+ postgresVersionProbe,
9153
+ deadline,
9154
+ cleanupDownloadWorkDir
8855
9155
  )) {
8856
9156
  return { output: "" };
8857
9157
  }
@@ -8929,13 +9229,13 @@ async function pruneRuntimeCache(options = {}) {
8929
9229
  };
8930
9230
  }
8931
9231
  async function scanRuntimeCacheEntries(homeDir) {
8932
- const runtimesDir = path10.join(homeDir, "runtimes");
9232
+ const runtimesDir = path9.join(homeDir, "runtimes");
8933
9233
  const dirents = await readdir(runtimesDir, { withFileTypes: true }).catch(() => null);
8934
9234
  if (!dirents) return [];
8935
9235
  const entries = [];
8936
9236
  for (const dirent of dirents) {
8937
9237
  if (!dirent.isDirectory()) continue;
8938
- const cacheDir = path10.join(runtimesDir, dirent.name);
9238
+ const cacheDir = path9.join(runtimesDir, dirent.name);
8939
9239
  const metadata = await readRuntimeInstallMetadata(cacheDir);
8940
9240
  if (!metadata) continue;
8941
9241
  const fallbackStat = await safeStat(cacheDir);
@@ -8958,7 +9258,7 @@ function parseTimestampMs(value) {
8958
9258
  }
8959
9259
  async function safeStat(targetPath) {
8960
9260
  try {
8961
- return await stat3(targetPath);
9261
+ return await stat(targetPath);
8962
9262
  } catch {
8963
9263
  return null;
8964
9264
  }
@@ -8968,7 +9268,7 @@ async function directorySizeBytes(targetPath) {
8968
9268
  if (!dirents) return 0;
8969
9269
  let total = 0;
8970
9270
  for (const dirent of dirents) {
8971
- const entryPath = path10.join(targetPath, dirent.name);
9271
+ const entryPath = path9.join(targetPath, dirent.name);
8972
9272
  if (dirent.isSymbolicLink()) continue;
8973
9273
  if (dirent.isDirectory()) {
8974
9274
  total += await directorySizeBytes(entryPath);
@@ -8980,14 +9280,14 @@ async function directorySizeBytes(targetPath) {
8980
9280
  return total;
8981
9281
  }
8982
9282
  async function readActiveRuntimeVersions(homeDir) {
8983
- const instancesDir = path10.join(homeDir, "instances");
9283
+ const instancesDir = path9.join(homeDir, "instances");
8984
9284
  const dirents = await readdir(instancesDir, { withFileTypes: true }).catch(() => null);
8985
9285
  if (!dirents) return [];
8986
9286
  const versions = /* @__PURE__ */ new Set();
8987
9287
  for (const dirent of dirents) {
8988
9288
  if (!dirent.isDirectory()) continue;
8989
9289
  try {
8990
- const descriptorPath = path10.join(instancesDir, dirent.name, "runtime", "server.json");
9290
+ const descriptorPath = path9.join(instancesDir, dirent.name, "runtime", "server.json");
8991
9291
  const parsed = JSON.parse(await readFile(descriptorPath, "utf8"));
8992
9292
  if (typeof parsed.version !== "string") continue;
8993
9293
  if (typeof parsed.pid === "number" && Number.isInteger(parsed.pid) && parsed.pid > 0 && isPidRunning(parsed.pid)) {
@@ -9102,7 +9402,6 @@ var init_install = __esm({
9102
9402
  "use strict";
9103
9403
  init_home();
9104
9404
  init_native_payload();
9105
- init_postgres_payload();
9106
9405
  init_postgres_runtime_download();
9107
9406
  init_postgres_runtime_source();
9108
9407
  RUNTIME_NPM_PACKAGE_NAME = "@rudderhq/server";
@@ -9148,7 +9447,7 @@ var init_install = __esm({
9148
9447
 
9149
9448
  // src/runtime/server-entry.ts
9150
9449
  import fs7 from "node:fs";
9151
- import path11 from "node:path";
9450
+ import path10 from "node:path";
9152
9451
  import { fileURLToPath as fileURLToPath5, pathToFileURL as pathToFileURL2 } from "node:url";
9153
9452
  function formatError(err) {
9154
9453
  if (err instanceof Error) {
@@ -9170,8 +9469,8 @@ function maybeEnableUiDevMiddleware(entrypoint) {
9170
9469
  }
9171
9470
  }
9172
9471
  function resolveDevServerEntry() {
9173
- const projectRoot = path11.resolve(path11.dirname(fileURLToPath5(import.meta.url)), "../../..");
9174
- return path11.resolve(projectRoot, "server/src/index.ts");
9472
+ const projectRoot = path10.resolve(path10.dirname(fileURLToPath5(import.meta.url)), "../../..");
9473
+ return path10.resolve(projectRoot, "server/src/index.ts");
9175
9474
  }
9176
9475
  async function loadServerRuntimeModule(options) {
9177
9476
  const devEntry = resolveDevServerEntry();
@@ -9311,21 +9610,21 @@ var init_auth_bootstrap_ceo = __esm({
9311
9610
 
9312
9611
  // src/utils/path-resolver.ts
9313
9612
  import fs10 from "node:fs";
9314
- import path19 from "node:path";
9613
+ import path18 from "node:path";
9315
9614
  function unique(items) {
9316
9615
  return Array.from(new Set(items));
9317
9616
  }
9318
9617
  function resolveRuntimeLikePath(value, configPath) {
9319
9618
  const expanded = expandHomePrefix(value);
9320
- if (path19.isAbsolute(expanded)) return path19.resolve(expanded);
9619
+ if (path18.isAbsolute(expanded)) return path18.resolve(expanded);
9321
9620
  const cwd = process.cwd();
9322
- const configDir = configPath ? path19.dirname(configPath) : null;
9323
- const workspaceRoot = configDir ? path19.resolve(configDir, "..") : cwd;
9621
+ const configDir = configPath ? path18.dirname(configPath) : null;
9622
+ const workspaceRoot = configDir ? path18.resolve(configDir, "..") : cwd;
9324
9623
  const candidates = unique([
9325
- ...configDir ? [path19.resolve(configDir, expanded)] : [],
9326
- path19.resolve(workspaceRoot, "server", expanded),
9327
- path19.resolve(workspaceRoot, expanded),
9328
- path19.resolve(cwd, expanded)
9624
+ ...configDir ? [path18.resolve(configDir, expanded)] : [],
9625
+ path18.resolve(workspaceRoot, "server", expanded),
9626
+ path18.resolve(workspaceRoot, expanded),
9627
+ path18.resolve(cwd, expanded)
9329
9628
  ]);
9330
9629
  return candidates.find((candidate) => fs10.existsSync(candidate)) ?? candidates[0];
9331
9630
  }
@@ -9339,7 +9638,7 @@ var init_path_resolver = __esm({
9339
9638
  // src/config/secrets-key.ts
9340
9639
  import { randomBytes as randomBytes2 } from "node:crypto";
9341
9640
  import fs11 from "node:fs";
9342
- import path20 from "node:path";
9641
+ import path19 from "node:path";
9343
9642
  function ensureLocalSecretsKeyFile(config, configPath) {
9344
9643
  if (config.secrets.provider !== "local_encrypted") {
9345
9644
  return { status: "skipped_provider", path: null };
@@ -9354,7 +9653,7 @@ function ensureLocalSecretsKeyFile(config, configPath) {
9354
9653
  if (fs11.existsSync(keyFilePath)) {
9355
9654
  return { status: "existing", path: keyFilePath };
9356
9655
  }
9357
- fs11.mkdirSync(path20.dirname(keyFilePath), { recursive: true });
9656
+ fs11.mkdirSync(path19.dirname(keyFilePath), { recursive: true });
9358
9657
  fs11.writeFileSync(keyFilePath, randomBytes2(32).toString("base64"), {
9359
9658
  encoding: "utf8",
9360
9659
  mode: 384
@@ -10440,7 +10739,7 @@ var init_port_check = __esm({
10440
10739
  // src/checks/secrets-check.ts
10441
10740
  import { randomBytes as randomBytes3 } from "node:crypto";
10442
10741
  import fs14 from "node:fs";
10443
- import path21 from "node:path";
10742
+ import path20 from "node:path";
10444
10743
  function decodeMasterKey(raw) {
10445
10744
  const trimmed = raw.trim();
10446
10745
  if (!trimmed) return null;
@@ -10510,7 +10809,7 @@ function secretsCheck(config, configPath) {
10510
10809
  message: `Secrets key file does not exist yet: ${keyFilePath}`,
10511
10810
  canRepair: true,
10512
10811
  repair: () => {
10513
- fs14.mkdirSync(path21.dirname(keyFilePath), { recursive: true });
10812
+ fs14.mkdirSync(path20.dirname(keyFilePath), { recursive: true });
10514
10813
  fs14.writeFileSync(keyFilePath, randomBytes3(32).toString("base64"), {
10515
10814
  encoding: "utf8",
10516
10815
  mode: 384
@@ -11083,7 +11382,7 @@ var init_run = __esm({
11083
11382
 
11084
11383
  // src/commands/onboard.ts
11085
11384
  import * as p14 from "@clack/prompts";
11086
- import path22 from "node:path";
11385
+ import path21 from "node:path";
11087
11386
  import pc13 from "picocolors";
11088
11387
  function parseBooleanFromEnv(rawValue) {
11089
11388
  if (rawValue === void 0) return null;
@@ -11116,7 +11415,7 @@ function parseEnumFromEnv(rawValue, allowedValues) {
11116
11415
  }
11117
11416
  function resolvePathFromEnv(rawValue) {
11118
11417
  if (!rawValue || rawValue.trim().length === 0) return null;
11119
- return path22.resolve(expandHomePrefix(rawValue.trim()));
11418
+ return path21.resolve(expandHomePrefix(rawValue.trim()));
11120
11419
  }
11121
11420
  function quickstartDefaultsFromEnv() {
11122
11421
  const instanceId = resolveRudderInstanceId();
@@ -11548,7 +11847,7 @@ var init_onboard = __esm({
11548
11847
  });
11549
11848
 
11550
11849
  // src/program.ts
11551
- import { Command, CommanderError } from "commander";
11850
+ import { Command, CommanderError, Option } from "commander";
11552
11851
 
11553
11852
  // src/agent-v1-mcp-server.ts
11554
11853
  init_dist();
@@ -12133,7 +12432,7 @@ var AGENT_CLI_CAPABILITIES = [
12133
12432
  category: "issue",
12134
12433
  description: "Create a new issue or subtask with the generic issue surface; agent-created issues default to the creating agent when no assignee is supplied.",
12135
12434
  mutating: true,
12136
- contract: "compat",
12435
+ contract: "agent-v1",
12137
12436
  requiresOrgId: true,
12138
12437
  requiresAgentId: false,
12139
12438
  requiresRunId: false,
@@ -13081,41 +13380,41 @@ var RudderApiClient = class {
13081
13380
  this.signal = opts.signal;
13082
13381
  this.recoverAuth = opts.recoverAuth;
13083
13382
  }
13084
- get(path26, opts) {
13085
- return this.request(path26, { method: "GET" }, opts);
13383
+ get(path25, opts) {
13384
+ return this.request(path25, { method: "GET" }, opts);
13086
13385
  }
13087
- post(path26, body, opts) {
13088
- return this.request(path26, {
13386
+ post(path25, body, opts) {
13387
+ return this.request(path25, {
13089
13388
  method: "POST",
13090
13389
  body: body === void 0 ? void 0 : JSON.stringify(body)
13091
13390
  }, opts);
13092
13391
  }
13093
- postForm(path26, form, opts) {
13094
- return this.request(path26, {
13392
+ postForm(path25, form, opts) {
13393
+ return this.request(path25, {
13095
13394
  method: "POST",
13096
13395
  body: form
13097
13396
  }, opts);
13098
13397
  }
13099
- patch(path26, body, opts) {
13100
- return this.request(path26, {
13398
+ patch(path25, body, opts) {
13399
+ return this.request(path25, {
13101
13400
  method: "PATCH",
13102
13401
  body: body === void 0 ? void 0 : JSON.stringify(body)
13103
13402
  }, opts);
13104
13403
  }
13105
- put(path26, body, opts) {
13106
- return this.request(path26, {
13404
+ put(path25, body, opts) {
13405
+ return this.request(path25, {
13107
13406
  method: "PUT",
13108
13407
  body: body === void 0 ? void 0 : JSON.stringify(body)
13109
13408
  }, opts);
13110
13409
  }
13111
- delete(path26, opts) {
13112
- return this.request(path26, { method: "DELETE" }, opts);
13410
+ delete(path25, opts) {
13411
+ return this.request(path25, { method: "DELETE" }, opts);
13113
13412
  }
13114
13413
  setApiKey(apiKey) {
13115
13414
  this.apiKey = apiKey?.trim() || void 0;
13116
13415
  }
13117
- async request(path26, init, opts, hasRetriedAuth = false) {
13118
- const url = buildUrl(this.apiBase, path26);
13416
+ async request(path25, init, opts, hasRetriedAuth = false) {
13417
+ const url = buildUrl(this.apiBase, path25);
13119
13418
  const headers = {
13120
13419
  accept: "application/json",
13121
13420
  ...toStringRecord(init.headers)
@@ -13146,13 +13445,13 @@ var RudderApiClient = class {
13146
13445
  const apiError = await toApiError(response);
13147
13446
  if (!hasRetriedAuth && this.recoverAuth) {
13148
13447
  const recoveredToken = await this.recoverAuth({
13149
- path: path26,
13448
+ path: path25,
13150
13449
  method: String(init.method ?? "GET").toUpperCase(),
13151
13450
  error: apiError
13152
13451
  });
13153
13452
  if (recoveredToken) {
13154
13453
  this.setApiKey(recoveredToken);
13155
- return this.request(path26, init, opts, true);
13454
+ return this.request(path25, init, opts, true);
13156
13455
  }
13157
13456
  }
13158
13457
  throw apiError;
@@ -13171,8 +13470,8 @@ function shouldAttachAgentContext(method) {
13171
13470
  const normalized = String(method ?? "GET").toUpperCase();
13172
13471
  return normalized !== "GET" && normalized !== "HEAD";
13173
13472
  }
13174
- function buildUrl(apiBase, path26) {
13175
- const normalizedPath = path26.startsWith("/") ? path26 : `/${path26}`;
13473
+ function buildUrl(apiBase, path25) {
13474
+ const normalizedPath = path25.startsWith("/") ? path25 : `/${path25}`;
13176
13475
  const [pathname, query] = normalizedPath.split("?");
13177
13476
  const url = new URL2(apiBase);
13178
13477
  url.pathname = `${url.pathname.replace(/\/+$/, "")}${pathname}`;
@@ -14335,7 +14634,7 @@ async function callToolDirectlyIfSupported(toolName, rawArgs, env, signal) {
14335
14634
  if (hasLocalImageInputs(input.images)) return null;
14336
14635
  const api = mcpApiClient(env, signal);
14337
14636
  const success = (data) => mcpSuccess(
14338
- toCliShortIdOutput(data),
14637
+ capabilityId.startsWith("browser.") ? data : toCliShortIdOutput(data),
14339
14638
  capabilityId.startsWith("browser.") ? RUDDER_BROWSER_MCP_MAX_TOOL_RESULT_BYTES : RUDDER_MCP_MAX_TOOL_RESULT_BYTES
14340
14639
  );
14341
14640
  switch (capabilityId) {
@@ -14425,6 +14724,26 @@ async function callToolDirectlyIfSupported(toolName, rawArgs, env, signal) {
14425
14724
  payload
14426
14725
  ));
14427
14726
  }
14727
+ case "issue.create": {
14728
+ const orgId = requiredRuntimeString(env, "RUDDER_ORG_ID");
14729
+ const payload = createIssueSchema.parse({
14730
+ title: requiredString(input, "title"),
14731
+ description: input.description,
14732
+ status: input.status,
14733
+ priority: input.priority,
14734
+ assigneeAgentId: input.assigneeAgentId,
14735
+ projectId: input.projectId,
14736
+ goalId: input.goalId,
14737
+ parentId: input.parentId,
14738
+ requestDepth: input.requestDepth,
14739
+ billingCode: input.billingCode,
14740
+ labelIds: input.labelIds
14741
+ });
14742
+ return success(await api.post(
14743
+ `/api/orgs/${encodeURIComponent(orgId)}/issues`,
14744
+ payload
14745
+ ));
14746
+ }
14428
14747
  case "issue.get":
14429
14748
  return success(await api.get(`/api/issues/${encodeURIComponent(requiredAnyString(input, ["issue", "issueId"]))}`));
14430
14749
  case "issue.context": {
@@ -14864,6 +15183,22 @@ function cliArgsForCapability(capabilityId, input, tempFiles, env) {
14864
15183
  if (input.resultPayload !== void 0) args.push("--result-payload", JSON.stringify(input.resultPayload));
14865
15184
  return args;
14866
15185
  }
15186
+ case "issue.create": {
15187
+ const args = ["issue", "create", "--title", requiredString(input, "title")];
15188
+ pushOptional(args, "--description", input.description);
15189
+ pushOptional(args, "--status", input.status);
15190
+ pushOptional(args, "--priority", input.priority);
15191
+ pushOptional(args, "--assignee-agent-id", input.assigneeAgentId);
15192
+ pushOptional(args, "--project-id", input.projectId);
15193
+ pushOptional(args, "--goal-id", input.goalId);
15194
+ pushOptional(args, "--parent-id", input.parentId);
15195
+ pushOptional(args, "--request-depth", input.requestDepth);
15196
+ pushOptional(args, "--billing-code", input.billingCode);
15197
+ if (Array.isArray(input.labelIds)) {
15198
+ for (const labelId of input.labelIds) args.push("--label-id", String(labelId));
15199
+ }
15200
+ return args;
15201
+ }
14867
15202
  case "issue.get":
14868
15203
  return ["issue", "get", requiredAnyString(input, ["issue", "issueId"])];
14869
15204
  case "issue.list": {
@@ -15726,8 +16061,8 @@ function registerActivityCommands(program) {
15726
16061
  if (opts.entityType) params.set("entityType", opts.entityType);
15727
16062
  if (opts.entityId) params.set("entityId", opts.entityId);
15728
16063
  const query = params.toString();
15729
- const path26 = `/api/orgs/${ctx.orgId}/activity${query ? `?${query}` : ""}`;
15730
- const rows = await ctx.api.get(path26) ?? [];
16064
+ const path25 = `/api/orgs/${ctx.orgId}/activity${query ? `?${query}` : ""}`;
16065
+ const rows = await ctx.api.get(path25) ?? [];
15731
16066
  if (ctx.json) {
15732
16067
  printOutput(rows, { json: true });
15733
16068
  return;
@@ -15759,7 +16094,7 @@ function registerActivityCommands(program) {
15759
16094
 
15760
16095
  // ../packages/agent-runtime-utils/dist/server-utils.cli.js
15761
16096
  import { promises as fs8 } from "node:fs";
15762
- import path12 from "node:path";
16097
+ import path11 from "node:path";
15763
16098
 
15764
16099
  // ../packages/agent-runtime-utils/dist/native-process-runner.js
15765
16100
  init_dist2();
@@ -16033,12 +16368,11 @@ The prior Run has already persisted the checkpoint named above. Reconstruct the
16033
16368
 
16034
16369
  If the checkpoint instead records a wait or human decision, this wake is unexpected: do not invent authorization or execute the waiting action. Refresh managed Goal context, report the mismatch, and leave the Goal waiting for its named actor or external trigger. If a ready Result Proposal exists, stop and wait for human Acceptance.`;
16035
16370
  var ISSUE_ASSIGNEE_EXECUTION_RAIL = "Before doing issue-scoped execution as the assignee, check out the assigned issue. If checkout returns `409`, do not retry; stop and report the ownership conflict.";
16036
- var ISSUE_ASSIGN_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}}). You have been assigned to work on an issue.
16371
+ var ISSUE_ASSIGN_PROMPT_TEMPLATE = `<wake_context>
16372
+ You are agent {{agent.id}} ({{agent.name}}). You have been assigned to work on an issue.
16037
16373
 
16038
16374
  {{context.rudderWorkspace.orgResourcesPrompt}}
16039
16375
 
16040
- ## Task Context
16041
-
16042
16376
  **Issue:** {{issue.title}}
16043
16377
  **ID:** {{issue.id}}
16044
16378
  **Status:** {{issue.status}}
@@ -16047,21 +16381,23 @@ var ISSUE_ASSIGN_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}}).
16047
16381
  **Reviewer:** {{issue.reviewerLabel}}
16048
16382
  **Created At:** {{issue.createdAt}}
16049
16383
  **Updated At:** {{issue.updatedAt}}
16384
+ </wake_context>
16050
16385
 
16386
+ <quoted_issue_context>
16051
16387
  **Description:**
16052
16388
  {{issue.description}}
16389
+ </quoted_issue_context>
16053
16390
 
16054
16391
 
16055
16392
  Your task is to review this issue, understand what kind of work it asks for, and take the appropriate next action.
16056
16393
 
16057
16394
  Do not assume every issue is a codebase task. If the issue is a question, screenshot check, review, planning request, coordination task, or another non-code request, answer or handle that request directly. Inspect the codebase and implement a change only when the issue actually asks for engineering work or when the relevant project resources make code changes necessary.
16058
16395
  ${ISSUE_ASSIGNEE_EXECUTION_RAIL}`;
16059
- var ISSUE_COMMENTED_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}}). There is a new comment on an issue you own.
16396
+ var ISSUE_COMMENTED_PROMPT_TEMPLATE = `<wake_context>
16397
+ You are agent {{agent.id}} ({{agent.name}}). There is a new comment on an issue you own.
16060
16398
 
16061
16399
  {{context.rudderWorkspace.orgResourcesPrompt}}
16062
16400
 
16063
- ## Context
16064
-
16065
16401
  **Issue:** {{issue.title}}
16066
16402
  **ID:** {{issue.id}}
16067
16403
  **Status:** {{issue.status}}
@@ -16069,7 +16405,9 @@ var ISSUE_COMMENTED_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}
16069
16405
  **Reviewer:** {{issue.reviewerLabel}}
16070
16406
  **Created At:** {{issue.createdAt}}
16071
16407
  **Updated At:** {{issue.updatedAt}}
16408
+ </wake_context>
16072
16409
 
16410
+ <quoted_issue_context>
16073
16411
  **Issue Description:**
16074
16412
  {{issue.description}}
16075
16413
 
@@ -16078,15 +16416,15 @@ var ISSUE_COMMENTED_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}
16078
16416
  From: {{comment.authorLabel}} ({{comment.authorKind}})
16079
16417
 
16080
16418
  {{comment.body}}
16419
+ </quoted_issue_context>
16081
16420
 
16082
16421
  Review the new comment and continue the issue from the current state. Respond or take action as needed.
16083
16422
  ${ISSUE_ASSIGNEE_EXECUTION_RAIL}`;
16084
- var ISSUE_CHANGES_REQUESTED_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}}). A reviewer requested changes on an issue you own.
16423
+ var ISSUE_CHANGES_REQUESTED_PROMPT_TEMPLATE = `<wake_context>
16424
+ You are agent {{agent.id}} ({{agent.name}}). A reviewer requested changes on an issue you own.
16085
16425
 
16086
16426
  {{context.rudderWorkspace.orgResourcesPrompt}}
16087
16427
 
16088
- ## Context
16089
-
16090
16428
  **Issue:** {{issue.title}}
16091
16429
  **ID:** {{issue.id}}
16092
16430
  **Status:** {{issue.status}}
@@ -16094,7 +16432,9 @@ var ISSUE_CHANGES_REQUESTED_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{age
16094
16432
  **Reviewer:** {{issue.reviewerLabel}}
16095
16433
  **Created At:** {{issue.createdAt}}
16096
16434
  **Updated At:** {{issue.updatedAt}}
16435
+ </wake_context>
16097
16436
 
16437
+ <quoted_issue_context>
16098
16438
  **Issue Description:**
16099
16439
  {{issue.description}}
16100
16440
 
@@ -16103,10 +16443,12 @@ var ISSUE_CHANGES_REQUESTED_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{age
16103
16443
  From: {{comment.authorLabel}} ({{comment.authorKind}})
16104
16444
 
16105
16445
  {{comment.body}}
16446
+ </quoted_issue_context>
16106
16447
 
16107
16448
  Review the requested changes and continue the issue from the current state. Address the reviewer feedback before handing it back for review.
16108
16449
  ${ISSUE_ASSIGNEE_EXECUTION_RAIL}`;
16109
- var ISSUE_RECOVERY_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}}). This is a recovery run, not a fresh task.
16450
+ var ISSUE_RECOVERY_PROMPT_TEMPLATE = `<wake_context>
16451
+ You are agent {{agent.id}} ({{agent.name}}). This is a recovery run, not a fresh task.
16110
16452
 
16111
16453
  {{context.rudderWorkspace.orgResourcesPrompt}}
16112
16454
 
@@ -16128,20 +16470,24 @@ var ISSUE_RECOVERY_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}}
16128
16470
  - Reviewer: {{issue.reviewerLabel}}
16129
16471
  - Created At: {{issue.createdAt}}
16130
16472
  - Updated At: {{issue.updatedAt}}
16473
+ </wake_context>
16131
16474
 
16475
+ <quoted_issue_context>
16132
16476
  - Description:
16133
16477
  {{issue.description}}
16478
+ </quoted_issue_context>
16134
16479
 
16135
16480
 
16136
16481
  Before doing anything else, inspect what the previous run already completed and any side effects it may have caused. Continue the remaining work from the current state. Avoid blindly re-running the whole task.
16137
16482
  ${ISSUE_ASSIGNEE_EXECUTION_RAIL}`;
16138
- var ISSUE_PASSIVE_FOLLOWUP_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}}). This is a passive issue follow-up, not a fresh assignment and not a failure recovery.
16483
+ var ISSUE_PASSIVE_FOLLOWUP_PROMPT_TEMPLATE = `<wake_context>
16484
+ You are agent {{agent.id}} ({{agent.name}}). This is a passive issue follow-up, not a fresh assignment and not a failure recovery.
16139
16485
 
16140
16486
  {{context.rudderWorkspace.orgResourcesPrompt}}
16141
16487
 
16142
16488
  ## Why You Were Woken
16143
16489
 
16144
- The previous run ended without sufficient issue close-out.
16490
+ The previous run ended without sufficient issue close-out. Continue to progress the current issue.
16145
16491
 
16146
16492
  - Origin Run ID: {{context.passiveFollowup.originRunId}}
16147
16493
  - Previous Run ID: {{context.passiveFollowup.previousRunId}}
@@ -16158,16 +16504,17 @@ Reason: {{context.passiveFollowup.reason}}
16158
16504
  - Reviewer: {{issue.reviewerLabel}}
16159
16505
  - Created At: {{issue.createdAt}}
16160
16506
  - Updated At: {{issue.updatedAt}}
16507
+ </wake_context>
16161
16508
 
16509
+ <quoted_issue_context>
16162
16510
  - Description:
16163
16511
  {{issue.description}}
16512
+ </quoted_issue_context>
16164
16513
 
16165
16514
 
16166
- Before changing the issue, inspect the current issue state and any side effects from the previous run. Then do exactly one close-out action: add a progress comment, mark the issue done, block it with a reason, or hand it off explicitly with explanation.
16515
+ Before changing the issue, continue to progress the current issue, then inspect the current issue state and any side effects from the previous run. Finally, do exactly one close-out action: add a progress comment, mark the issue done, block it with a reason, or hand it off explicitly with explanation.
16167
16516
  ${ISSUE_ASSIGNEE_EXECUTION_RAIL}`;
16168
16517
  var RUDDER_AGENT_OPERATING_CONTRACT = [
16169
- "# Rudder Agent Operating Contract",
16170
- "",
16171
16518
  "You are a helpful assistant running inside Rudder. Your home directory is `$AGENT_HOME`. Everything personal to you -- life, memory, knowledge -- lives there. Other agents may have their own folders and you may update them when necessary.",
16172
16519
  "",
16173
16520
  "Read Rudder mcp tools to firstly.",
@@ -16228,8 +16575,6 @@ var RUDDER_AGENT_OPERATING_CONTRACT = [
16228
16575
  "- When the user explicitly mentions previously handled issue, tasks or conversations, you need to retrieve the relevant tasks first before proceeding with the next action."
16229
16576
  ].join("\n");
16230
16577
  var RUDDER_AGENT_HEARTBEAT_INSTRUCTION = [
16231
- "# Rudder Heartbeat Instruction",
16232
- "",
16233
16578
  "This section is injected by Rudder only for heartbeat scene runs. It is the platform-owned heartbeat/self-check pipeline.",
16234
16579
  "",
16235
16580
  "## Heartbeat Pipeline",
@@ -16255,8 +16600,8 @@ var RUDDER_AGENT_HEARTBEAT_INSTRUCTION = [
16255
16600
  // ../packages/agent-runtime-utils/dist/server-utils.cli.js
16256
16601
  async function resolveRudderSkillsDir(moduleDir, additionalCandidates = []) {
16257
16602
  const candidates = [
16258
- ...RUDDER_SKILL_ROOT_RELATIVE_CANDIDATES.map((relativePath) => path12.resolve(moduleDir, relativePath)),
16259
- ...additionalCandidates.map((candidate) => path12.resolve(candidate))
16603
+ ...RUDDER_SKILL_ROOT_RELATIVE_CANDIDATES.map((relativePath) => path11.resolve(moduleDir, relativePath)),
16604
+ ...additionalCandidates.map((candidate) => path11.resolve(candidate))
16260
16605
  ];
16261
16606
  const seenRoots = /* @__PURE__ */ new Set();
16262
16607
  for (const root of candidates) {
@@ -16273,26 +16618,26 @@ async function removeMaintainerOnlySkillSymlinks(skillsHome, allowedSkillNames)
16273
16618
  return removeUnselectedRudderSkillSymlinks(skillsHome, allowedSkillNames);
16274
16619
  }
16275
16620
  async function readRudderMaterializedSkillSource(target) {
16276
- const manifestPath = path12.join(target, ".rudder", "materialized-skill.json");
16621
+ const manifestPath = path11.join(target, ".rudder", "materialized-skill.json");
16277
16622
  const raw = await fs8.readFile(manifestPath, "utf8").catch(() => null);
16278
16623
  if (!raw)
16279
16624
  return null;
16280
16625
  try {
16281
16626
  const parsed = parseObject(JSON.parse(raw));
16282
16627
  const sourcePath = asString(parsed.sourcePath, "").trim();
16283
- return sourcePath.length > 0 ? path12.resolve(sourcePath) : null;
16628
+ return sourcePath.length > 0 ? path11.resolve(sourcePath) : null;
16284
16629
  } catch {
16285
16630
  return null;
16286
16631
  }
16287
16632
  }
16288
16633
  async function removeUnselectedRudderSkillSymlinks(skillsHome, allowedSkillNames, knownSkillSources = []) {
16289
16634
  const allowed = new Set(Array.from(allowedSkillNames));
16290
- const knownSources = new Set(Array.from(knownSkillSources).map((value) => value.trim()).filter(Boolean).map((value) => path12.resolve(value)));
16635
+ const knownSources = new Set(Array.from(knownSkillSources).map((value) => value.trim()).filter(Boolean).map((value) => path11.resolve(value)));
16291
16636
  try {
16292
16637
  const entries = await fs8.readdir(skillsHome, { withFileTypes: true });
16293
16638
  const removed = [];
16294
16639
  for (const entry of entries) {
16295
- const target = path12.join(skillsHome, entry.name);
16640
+ const target = path11.join(skillsHome, entry.name);
16296
16641
  const existing = await fs8.lstat(target).catch(() => null);
16297
16642
  if (!existing)
16298
16643
  continue;
@@ -16301,8 +16646,8 @@ async function removeUnselectedRudderSkillSymlinks(skillsHome, allowedSkillNames
16301
16646
  const linkedPath = await fs8.readlink(target).catch(() => null);
16302
16647
  if (!linkedPath)
16303
16648
  continue;
16304
- const resolvedLinkedPath = path12.isAbsolute(linkedPath) ? linkedPath : path12.resolve(path12.dirname(target), linkedPath);
16305
- isRudderManagedSkill = knownSources.has(path12.resolve(resolvedLinkedPath)) || isMaintainerOnlySkillTarget(linkedPath) || isMaintainerOnlySkillTarget(resolvedLinkedPath);
16649
+ const resolvedLinkedPath = path11.isAbsolute(linkedPath) ? linkedPath : path11.resolve(path11.dirname(target), linkedPath);
16650
+ isRudderManagedSkill = knownSources.has(path11.resolve(resolvedLinkedPath)) || isMaintainerOnlySkillTarget(linkedPath) || isMaintainerOnlySkillTarget(resolvedLinkedPath);
16306
16651
  } else if (existing.isDirectory()) {
16307
16652
  const materializedSource = await readRudderMaterializedSkillSource(target);
16308
16653
  isRudderManagedSkill = materializedSource !== null && knownSources.has(materializedSource);
@@ -16324,7 +16669,7 @@ async function removeUnselectedRudderSkillSymlinks(skillsHome, allowedSkillNames
16324
16669
  init_dist2();
16325
16670
  import fs9 from "node:fs/promises";
16326
16671
  import os3 from "node:os";
16327
- import path13 from "node:path";
16672
+ import path12 from "node:path";
16328
16673
  import { fileURLToPath as fileURLToPath6 } from "node:url";
16329
16674
 
16330
16675
  // src/commands/client/help.ts
@@ -16348,16 +16693,16 @@ function formatHelpExample(example) {
16348
16693
  }
16349
16694
 
16350
16695
  // src/commands/client/agent.ts
16351
- var __moduleDir = path13.dirname(fileURLToPath6(import.meta.url));
16696
+ var __moduleDir = path12.dirname(fileURLToPath6(import.meta.url));
16352
16697
  function codexSkillsHome() {
16353
16698
  const fromEnv = process.env.CODEX_HOME?.trim();
16354
- const base = fromEnv && fromEnv.length > 0 ? fromEnv : path13.join(os3.homedir(), ".codex");
16355
- return path13.join(base, "skills");
16699
+ const base = fromEnv && fromEnv.length > 0 ? fromEnv : path12.join(os3.homedir(), ".codex");
16700
+ return path12.join(base, "skills");
16356
16701
  }
16357
16702
  function claudeSkillsHome() {
16358
16703
  const fromEnv = process.env.CLAUDE_HOME?.trim();
16359
- const base = fromEnv && fromEnv.length > 0 ? fromEnv : path13.join(os3.homedir(), ".claude");
16360
- return path13.join(base, "skills");
16704
+ const base = fromEnv && fromEnv.length > 0 ? fromEnv : path12.join(os3.homedir(), ".claude");
16705
+ return path12.join(base, "skills");
16361
16706
  }
16362
16707
  async function installSkillsForTarget(sourceSkillsDir, targetSkillsDir, tool2) {
16363
16708
  const summary = {
@@ -16376,8 +16721,8 @@ async function installSkillsForTarget(sourceSkillsDir, targetSkillsDir, tool2) {
16376
16721
  );
16377
16722
  for (const entry of entries) {
16378
16723
  if (!entry.isDirectory()) continue;
16379
- const source = path13.join(sourceSkillsDir, entry.name);
16380
- const target = path13.join(targetSkillsDir, entry.name);
16724
+ const source = path12.join(sourceSkillsDir, entry.name);
16725
+ const target = path12.join(targetSkillsDir, entry.name);
16381
16726
  const existing = await fs9.lstat(target).catch(() => null);
16382
16727
  if (existing) {
16383
16728
  if (existing.isSymbolicLink()) {
@@ -16398,7 +16743,7 @@ async function installSkillsForTarget(sourceSkillsDir, targetSkillsDir, tool2) {
16398
16743
  continue;
16399
16744
  }
16400
16745
  }
16401
- const resolvedLinkedPath = path13.isAbsolute(linkedPath) ? linkedPath : path13.resolve(path13.dirname(target), linkedPath);
16746
+ const resolvedLinkedPath = path12.isAbsolute(linkedPath) ? linkedPath : path12.resolve(path12.dirname(target), linkedPath);
16402
16747
  const linkedTargetExists = await fs9.stat(resolvedLinkedPath).then(() => true).catch(() => false);
16403
16748
  if (!linkedTargetExists) {
16404
16749
  await fs9.unlink(target);
@@ -16623,7 +16968,7 @@ function registerAgentCommands(program) {
16623
16968
  if (opts.markdown && opts.markdownFile) {
16624
16969
  throw new Error("Pass only one of --markdown or --markdown-file.");
16625
16970
  }
16626
- const markdown = opts.markdownFile ? await fs9.readFile(path13.resolve(opts.markdownFile), "utf8") : opts.markdown;
16971
+ const markdown = opts.markdownFile ? await fs9.readFile(path12.resolve(opts.markdownFile), "utf8") : opts.markdown;
16627
16972
  const payload = organizationSkillCreateSchema.parse({
16628
16973
  name: opts.name,
16629
16974
  slug: opts.slug?.trim() || null,
@@ -16802,7 +17147,7 @@ function registerAgentCommands(program) {
16802
17147
  }
16803
17148
  const installSummaries = [];
16804
17149
  if (opts.installSkills !== false) {
16805
- const skillsDir = await resolveRudderSkillsDir(__moduleDir, [path13.resolve(process.cwd(), "skills")]);
17150
+ const skillsDir = await resolveRudderSkillsDir(__moduleDir, [path12.resolve(process.cwd(), "skills")]);
16806
17151
  if (!skillsDir) {
16807
17152
  throw new Error(
16808
17153
  "Could not locate local Rudder skills directory. Expected ./skills in the repo checkout."
@@ -16890,10 +17235,10 @@ async function buildAgentUpdatePatch(opts) {
16890
17235
  if (opts.capabilities !== void 0) rawPatch.capabilities = opts.capabilities;
16891
17236
  if (opts.description !== void 0) rawPatch.capabilities = opts.description;
16892
17237
  if (opts.capabilitiesFile !== void 0) {
16893
- rawPatch.capabilities = await fs9.readFile(path13.resolve(opts.capabilitiesFile), "utf8");
17238
+ rawPatch.capabilities = await fs9.readFile(path12.resolve(opts.capabilitiesFile), "utf8");
16894
17239
  }
16895
17240
  if (opts.descriptionFile !== void 0) {
16896
- rawPatch.capabilities = await fs9.readFile(path13.resolve(opts.descriptionFile), "utf8");
17241
+ rawPatch.capabilities = await fs9.readFile(path12.resolve(opts.descriptionFile), "utf8");
16897
17242
  }
16898
17243
  if (clearCapabilities) rawPatch.capabilities = null;
16899
17244
  return updateAgentSchema.parse(rawPatch);
@@ -16917,7 +17262,7 @@ function parseJsonObject(value, name) {
16917
17262
  // src/commands/client/approval.ts
16918
17263
  init_dist2();
16919
17264
  import { readFile as readFile2 } from "node:fs/promises";
16920
- import path14 from "node:path";
17265
+ import path13 from "node:path";
16921
17266
  function registerApprovalCommands(program) {
16922
17267
  const approval = program.command("approval").description("Approval operations");
16923
17268
  addCommonClientOptions(
@@ -17108,7 +17453,7 @@ async function readTextInputFile(inputPath, optionName) {
17108
17453
  if (inputPath === "-") {
17109
17454
  return readStdinText();
17110
17455
  }
17111
- const resolvedPath = path14.resolve(process.cwd(), inputPath);
17456
+ const resolvedPath = path13.resolve(process.cwd(), inputPath);
17112
17457
  return readFile2(resolvedPath, "utf8").catch((err) => {
17113
17458
  throw new Error(`Unable to read ${optionName} ${inputPath}: ${err instanceof Error ? err.message : String(err)}`);
17114
17459
  });
@@ -17945,12 +18290,12 @@ async function readStdin() {
17945
18290
 
17946
18291
  // src/commands/client/company.ts
17947
18292
  import * as p3 from "@clack/prompts";
17948
- import { mkdir as mkdir3, readdir as readdir2, readFile as readFile3, stat as stat4, writeFile as writeFile2 } from "node:fs/promises";
17949
- import path16 from "node:path";
18293
+ import { mkdir as mkdir2, readdir as readdir2, readFile as readFile3, stat as stat2, writeFile as writeFile2 } from "node:fs/promises";
18294
+ import path15 from "node:path";
17950
18295
  import pc5 from "picocolors";
17951
18296
 
17952
18297
  // src/commands/client/zip.ts
17953
- import path15 from "node:path";
18298
+ import path14 from "node:path";
17954
18299
  import { inflateRawSync } from "node:zlib";
17955
18300
  var textDecoder = new TextDecoder();
17956
18301
  var binaryContentTypeByExtension = {
@@ -17978,7 +18323,7 @@ function sharedArchiveRoot(paths) {
17978
18323
  return firstSegments.every((parts) => parts.length > 1 && parts[0] === candidate) ? candidate : null;
17979
18324
  }
17980
18325
  function bytesToPortableFileEntry(pathValue, bytes) {
17981
- const contentType = binaryContentTypeByExtension[path15.extname(pathValue).toLowerCase()];
18326
+ const contentType = binaryContentTypeByExtension[path14.extname(pathValue).toLowerCase()];
17982
18327
  if (!contentType) return textDecoder.decode(bytes);
17983
18328
  return {
17984
18329
  encoding: "base64",
@@ -18066,7 +18411,7 @@ var IMPORT_INCLUDE_OPTIONS = [
18066
18411
  ];
18067
18412
  var IMPORT_PREVIEW_SAMPLE_LIMIT = 6;
18068
18413
  function readPortableFileEntry(filePath, contents) {
18069
- const contentType = binaryContentTypeByExtension[path16.extname(filePath).toLowerCase()];
18414
+ const contentType = binaryContentTypeByExtension[path15.extname(filePath).toLowerCase()];
18070
18415
  if (!contentType) return contents.toString("utf8");
18071
18416
  return {
18072
18417
  encoding: "base64",
@@ -18121,10 +18466,10 @@ function normalizePortablePath(filePath) {
18121
18466
  return filePath.replace(/\\/g, "/");
18122
18467
  }
18123
18468
  function shouldIncludePortableFile(filePath) {
18124
- const baseName = path16.basename(filePath);
18469
+ const baseName = path15.basename(filePath);
18125
18470
  const isMarkdown = baseName.endsWith(".md");
18126
18471
  const isPaperclipYaml = baseName === ".rudder.yaml" || baseName === ".rudder.yml";
18127
- const contentType = binaryContentTypeByExtension[path16.extname(baseName).toLowerCase()];
18472
+ const contentType = binaryContentTypeByExtension[path15.extname(baseName).toLowerCase()];
18128
18473
  return isMarkdown || isPaperclipYaml || Boolean(contentType);
18129
18474
  }
18130
18475
  function findPortableExtensionPath(files) {
@@ -18679,7 +19024,7 @@ function normalizeGithubImportSource(input, refOverride) {
18679
19024
  }
18680
19025
  async function pathExists(inputPath) {
18681
19026
  try {
18682
- await stat4(path16.resolve(inputPath));
19027
+ await stat2(path15.resolve(inputPath));
18683
19028
  return true;
18684
19029
  } catch {
18685
19030
  return false;
@@ -18689,45 +19034,45 @@ async function collectPackageFiles(root, current, files) {
18689
19034
  const entries = await readdir2(current, { withFileTypes: true });
18690
19035
  for (const entry of entries) {
18691
19036
  if (entry.name.startsWith(".git")) continue;
18692
- const absolutePath = path16.join(current, entry.name);
19037
+ const absolutePath = path15.join(current, entry.name);
18693
19038
  if (entry.isDirectory()) {
18694
19039
  await collectPackageFiles(root, absolutePath, files);
18695
19040
  continue;
18696
19041
  }
18697
19042
  if (!entry.isFile()) continue;
18698
- const relativePath = path16.relative(root, absolutePath).replace(/\\/g, "/");
19043
+ const relativePath = path15.relative(root, absolutePath).replace(/\\/g, "/");
18699
19044
  if (!shouldIncludePortableFile(relativePath)) continue;
18700
19045
  files[relativePath] = readPortableFileEntry(relativePath, await readFile3(absolutePath));
18701
19046
  }
18702
19047
  }
18703
19048
  async function resolveInlineSourceFromPath(inputPath) {
18704
- const resolved = path16.resolve(inputPath);
18705
- const resolvedStat = await stat4(resolved);
18706
- if (resolvedStat.isFile() && path16.extname(resolved).toLowerCase() === ".zip") {
19049
+ const resolved = path15.resolve(inputPath);
19050
+ const resolvedStat = await stat2(resolved);
19051
+ if (resolvedStat.isFile() && path15.extname(resolved).toLowerCase() === ".zip") {
18707
19052
  const archive = await readZipArchive(await readFile3(resolved));
18708
19053
  const filteredFiles = Object.fromEntries(
18709
19054
  Object.entries(archive.files).filter(([relativePath]) => shouldIncludePortableFile(relativePath))
18710
19055
  );
18711
19056
  return {
18712
- rootPath: archive.rootPath ?? path16.basename(resolved, ".zip"),
19057
+ rootPath: archive.rootPath ?? path15.basename(resolved, ".zip"),
18713
19058
  files: filteredFiles
18714
19059
  };
18715
19060
  }
18716
- const rootDir = resolvedStat.isDirectory() ? resolved : path16.dirname(resolved);
19061
+ const rootDir = resolvedStat.isDirectory() ? resolved : path15.dirname(resolved);
18717
19062
  const files = {};
18718
19063
  await collectPackageFiles(rootDir, rootDir, files);
18719
19064
  return {
18720
- rootPath: path16.basename(rootDir),
19065
+ rootPath: path15.basename(rootDir),
18721
19066
  files
18722
19067
  };
18723
19068
  }
18724
19069
  async function writeExportToFolder(outDir, exported) {
18725
- const root = path16.resolve(outDir);
18726
- await mkdir3(root, { recursive: true });
19070
+ const root = path15.resolve(outDir);
19071
+ await mkdir2(root, { recursive: true });
18727
19072
  for (const [relativePath, content] of Object.entries(exported.files)) {
18728
19073
  const normalized = relativePath.replace(/\\/g, "/");
18729
- const filePath = path16.join(root, normalized);
18730
- await mkdir3(path16.dirname(filePath), { recursive: true });
19074
+ const filePath = path15.join(root, normalized);
19075
+ await mkdir2(path15.dirname(filePath), { recursive: true });
18731
19076
  const writeValue = portableFileEntryToWriteValue(content);
18732
19077
  if (typeof writeValue === "string") {
18733
19078
  await writeFile2(filePath, writeValue, "utf8");
@@ -18737,8 +19082,8 @@ async function writeExportToFolder(outDir, exported) {
18737
19082
  }
18738
19083
  }
18739
19084
  async function confirmOverwriteExportDirectory(outDir) {
18740
- const root = path16.resolve(outDir);
18741
- const stats = await stat4(root).catch(() => null);
19085
+ const root = path15.resolve(outDir);
19086
+ const stats = await stat2(root).catch(() => null);
18742
19087
  if (!stats) return;
18743
19088
  if (!stats.isDirectory()) {
18744
19089
  throw new Error(`Export output path ${root} exists and is not a directory.`);
@@ -18919,7 +19264,7 @@ function registerCompanyCommands(program) {
18919
19264
  printOutput(
18920
19265
  {
18921
19266
  ok: true,
18922
- out: path16.resolve(opts.out),
19267
+ out: path15.resolve(opts.out),
18923
19268
  rootPath: exported.rootPath,
18924
19269
  filesWritten: Object.keys(exported.files).length,
18925
19270
  rudderExtensionPath: exported.rudderExtensionPath,
@@ -19417,8 +19762,8 @@ function parseResultValue(value) {
19417
19762
 
19418
19763
  // src/commands/client/issue.ts
19419
19764
  init_dist2();
19420
- import { readFile as readFile4, stat as stat5 } from "node:fs/promises";
19421
- import path17 from "node:path";
19765
+ import { readFile as readFile4, stat as stat3 } from "node:fs/promises";
19766
+ import path16 from "node:path";
19422
19767
  function registerIssueCommands(program) {
19423
19768
  const issue = program.command("issue").description("Issue operations");
19424
19769
  addCommonClientOptions(
@@ -19782,7 +20127,7 @@ async function readTextInputFile2(inputPath, optionName) {
19782
20127
  if (inputPath === "-") {
19783
20128
  return readStdinText2();
19784
20129
  }
19785
- const resolvedPath = path17.resolve(process.cwd(), inputPath);
20130
+ const resolvedPath = path16.resolve(process.cwd(), inputPath);
19786
20131
  return readFile4(resolvedPath, "utf8").catch((err) => {
19787
20132
  throw new Error(`Unable to read ${optionName} ${inputPath}: ${err instanceof Error ? err.message : String(err)}`);
19788
20133
  });
@@ -19839,14 +20184,14 @@ async function appendUploadedIssueImages(ctx, issueId, body, imagePaths) {
19839
20184
  ${imageBlock}` : imageBlock;
19840
20185
  }
19841
20186
  async function uploadIssueCommentImage(ctx, issue, imagePath) {
19842
- const resolvedPath = path17.resolve(process.cwd(), imagePath);
19843
- const stats = await stat5(resolvedPath).catch((err) => {
20187
+ const resolvedPath = path16.resolve(process.cwd(), imagePath);
20188
+ const stats = await stat3(resolvedPath).catch((err) => {
19844
20189
  throw new Error(`Unable to read image ${imagePath}: ${err instanceof Error ? err.message : String(err)}`);
19845
20190
  });
19846
20191
  if (!stats.isFile()) {
19847
20192
  throw new Error(`Image path must be a file: ${imagePath}`);
19848
20193
  }
19849
- const filename = path17.basename(resolvedPath);
20194
+ const filename = path16.basename(resolvedPath);
19850
20195
  const contentType = inferCommentImageContentType(filename);
19851
20196
  const buffer = await readFile4(resolvedPath);
19852
20197
  if (buffer.length <= 0) {
@@ -19865,7 +20210,7 @@ async function uploadIssueCommentImage(ctx, issue, imagePath) {
19865
20210
  return attachment;
19866
20211
  }
19867
20212
  function inferCommentImageContentType(filename) {
19868
- const ext = path17.extname(filename).toLowerCase();
20213
+ const ext = path16.extname(filename).toLowerCase();
19869
20214
  switch (ext) {
19870
20215
  case ".png":
19871
20216
  return "image/png";
@@ -19969,7 +20314,7 @@ function formatIssueSearchMatch(match) {
19969
20314
 
19970
20315
  // src/commands/client/library.ts
19971
20316
  import { readFile as readFile5 } from "node:fs/promises";
19972
- import path18 from "node:path";
20317
+ import path17 from "node:path";
19973
20318
  function toLibraryFileLinkResult(detail) {
19974
20319
  return {
19975
20320
  filePath: detail.filePath,
@@ -20114,7 +20459,7 @@ async function resolveBodyFileInput(inputPath) {
20114
20459
  if (inputPath === "-") {
20115
20460
  return readStdinText3();
20116
20461
  }
20117
- const resolvedPath = path18.resolve(process.cwd(), inputPath);
20462
+ const resolvedPath = path17.resolve(process.cwd(), inputPath);
20118
20463
  return readFile5(resolvedPath, "utf8").catch((err) => {
20119
20464
  throw new Error(`Unable to read --body-file ${inputPath}: ${err instanceof Error ? err.message : String(err)}`);
20120
20465
  });
@@ -20873,8 +21218,8 @@ function registerUserCommands(program) {
20873
21218
  appendParam(params, "limit", opts.limit);
20874
21219
  appendParam(params, "cursor", opts.cursor);
20875
21220
  const query = params.toString();
20876
- const path26 = `/api/orgs/${ctx.orgId}/users/${encodeURIComponent(userId)}/activity-ledger${query ? `?${query}` : ""}`;
20877
- const result = await ctx.api.get(path26);
21221
+ const path25 = `/api/orgs/${ctx.orgId}/users/${encodeURIComponent(userId)}/activity-ledger${query ? `?${query}` : ""}`;
21222
+ const result = await ctx.api.get(path25);
20878
21223
  if (ctx.json) {
20879
21224
  printOutput(result, { json: true });
20880
21225
  return;
@@ -21691,9 +22036,9 @@ import * as p15 from "@clack/prompts";
21691
22036
  import { spawn as spawn3, spawnSync as spawnSync4 } from "node:child_process";
21692
22037
  import { createHash as createHash4, randomUUID } from "node:crypto";
21693
22038
  import { constants as fsConstants, mkdirSync as mkdirSync2, readFileSync as readFileSync2 } from "node:fs";
21694
- import { access, chmod, copyFile as copyFile2, cp as cp2, lstat, mkdir as mkdir4, mkdtemp as mkdtemp2, readdir as readdir3, readFile as readFile6, rm as rm3, stat as stat6, utimes, writeFile as writeFile3 } from "node:fs/promises";
22039
+ import { access, chmod as chmod2, copyFile, cp, lstat, mkdir as mkdir3, mkdtemp as mkdtemp2, readdir as readdir3, readFile as readFile6, rm as rm3, stat as stat4, utimes, writeFile as writeFile3 } from "node:fs/promises";
21695
22040
  import { homedir, tmpdir } from "node:os";
21696
- import path24 from "node:path";
22041
+ import path23 from "node:path";
21697
22042
  import { clearTimeout as clearTimeout3, setTimeout as setTimeout3 } from "node:timers";
21698
22043
  import { setTimeout as delay2 } from "node:timers/promises";
21699
22044
  import pc14 from "picocolors";
@@ -21722,11 +22067,11 @@ init_home();
21722
22067
 
21723
22068
  // src/desktop-download.ts
21724
22069
  import { createHash as createHash3 } from "node:crypto";
21725
- import { createWriteStream as createWriteStream2, mkdirSync } from "node:fs";
22070
+ import { createWriteStream as createWriteStream3, mkdirSync } from "node:fs";
21726
22071
  import { rm as rm2 } from "node:fs/promises";
21727
- import path23 from "node:path";
22072
+ import path22 from "node:path";
21728
22073
  import { Readable as Readable2, Transform as Transform2 } from "node:stream";
21729
- import { pipeline as pipeline2 } from "node:stream/promises";
22074
+ import { pipeline as pipeline3 } from "node:stream/promises";
21730
22075
  import { clearTimeout as clearTimeout2, setTimeout as setTimeout2 } from "node:timers";
21731
22076
 
21732
22077
  // src/utils/progress.ts
@@ -21964,7 +22309,7 @@ async function resolveDesktopDownloadOrigins(options) {
21964
22309
  }
21965
22310
  async function downloadAsset(asset, outputDir, progressFactory = createByteProgress, expectedChecksum, timeouts = {}) {
21966
22311
  mkdirSync(outputDir, { recursive: true });
21967
- const outputPath = path23.join(outputDir, path23.basename(asset.name));
22312
+ const outputPath = path22.join(outputDir, path22.basename(asset.name));
21968
22313
  const idleTimeoutMs = timeouts.idleMs ?? DESKTOP_ASSET_IDLE_TIMEOUT_MS;
21969
22314
  const responseTimeoutMs = timeouts.responseMs ?? DESKTOP_ASSET_RESPONSE_TIMEOUT_MS;
21970
22315
  const failures = [];
@@ -22004,7 +22349,7 @@ async function downloadAsset(asset, outputDir, progressFactory = createByteProgr
22004
22349
  });
22005
22350
  progress.start(totalBytes);
22006
22351
  armIdleTimeout();
22007
- await pipeline2(Readable2.fromWeb(response.body), monitor, createWriteStream2(outputPath));
22352
+ await pipeline3(Readable2.fromWeb(response.body), monitor, createWriteStream3(outputPath));
22008
22353
  if (idleTimeout) clearTimeout2(idleTimeout);
22009
22354
  idleTimeout = null;
22010
22355
  const actualChecksum = hash.digest("hex");
@@ -22068,6 +22413,15 @@ var DEFAULT_DESKTOP_ASSET_CACHE_MAX_BYTES = 768 * 1024 * 1024;
22068
22413
  var DEFAULT_DESKTOP_ASSET_CACHE_KEEP_PREVIOUS = 1;
22069
22414
  var DESKTOP_INSTALL_LOCK_TIMEOUT_MS = 60 * 60 * 1e3;
22070
22415
  var DESKTOP_INSTALL_LOCK_POLL_MS = 250;
22416
+ var DESKTOP_RUNTIME_PREPARE_TIMEOUT_MS = 9e4;
22417
+ async function waitForDesktopRuntimeSmokeEvidence(envName) {
22418
+ if (process.env.RUDDER_DESKTOP_SMOKE_AUTO_UPDATE_PUBLIC !== "1") return;
22419
+ const value = Number(process.env[envName]);
22420
+ if (!Number.isFinite(value) || value <= 0) return;
22421
+ await delay2(Math.min(value, 1e4));
22422
+ }
22423
+ var DEFAULT_GITHUB_API_BASE_URL = "https://api.github.com";
22424
+ var DEFAULT_GITHUB_DOWNLOAD_BASE_URL = "https://github.com";
22071
22425
  function normalizeProgressTotal(totalBytes) {
22072
22426
  return typeof totalBytes === "number" && Number.isFinite(totalBytes) && totalBytes > 0 ? totalBytes : null;
22073
22427
  }
@@ -22291,38 +22645,38 @@ function resolveDesktopAssetTarget(platform = process.platform, arch = process.a
22291
22645
  throw new Error(`Rudder Desktop does not publish portable assets for ${platform}.`);
22292
22646
  }
22293
22647
  function resolveDefaultDesktopInstallRoot(target, env = process.env, homeDir = homedir()) {
22294
- if (target.platform === "macos") return path24.join(homeDir, "Applications");
22648
+ if (target.platform === "macos") return path23.join(homeDir, "Applications");
22295
22649
  if (target.platform === "windows") {
22296
- const localAppData = env.LOCALAPPDATA?.trim() || path24.join(homeDir, "AppData", "Local");
22297
- return path24.join(localAppData, "Programs", DESKTOP_APP_NAME);
22650
+ const localAppData = env.LOCALAPPDATA?.trim() || path23.join(homeDir, "AppData", "Local");
22651
+ return path23.join(localAppData, "Programs", DESKTOP_APP_NAME);
22298
22652
  }
22299
- return path24.join(homeDir, ".local", "share", "rudder");
22653
+ return path23.join(homeDir, ".local", "share", "rudder");
22300
22654
  }
22301
22655
  function resolveDesktopInstallPaths(target, installRoot) {
22302
- const root = path24.resolve(installRoot);
22656
+ const root = path23.resolve(installRoot);
22303
22657
  if (target.platform === "macos") {
22304
- const appPath2 = path24.join(root, `${DESKTOP_APP_NAME}.app`);
22658
+ const appPath2 = path23.join(root, `${DESKTOP_APP_NAME}.app`);
22305
22659
  return {
22306
22660
  installRoot: root,
22307
22661
  appPath: appPath2,
22308
- executablePath: path24.join(appPath2, "Contents", "MacOS", DESKTOP_APP_NAME),
22309
- metadataPath: path24.join(root, DESKTOP_METADATA_FILE)
22662
+ executablePath: path23.join(appPath2, "Contents", "MacOS", DESKTOP_APP_NAME),
22663
+ metadataPath: path23.join(root, DESKTOP_METADATA_FILE)
22310
22664
  };
22311
22665
  }
22312
22666
  if (target.platform === "windows") {
22313
22667
  return {
22314
22668
  installRoot: root,
22315
22669
  appPath: root,
22316
- executablePath: path24.join(root, `${DESKTOP_APP_NAME}.exe`),
22317
- metadataPath: path24.join(root, DESKTOP_METADATA_FILE)
22670
+ executablePath: path23.join(root, `${DESKTOP_APP_NAME}.exe`),
22671
+ metadataPath: path23.join(root, DESKTOP_METADATA_FILE)
22318
22672
  };
22319
22673
  }
22320
- const appPath = path24.join(root, `${DESKTOP_APP_NAME}.AppImage`);
22674
+ const appPath = path23.join(root, `${DESKTOP_APP_NAME}.AppImage`);
22321
22675
  return {
22322
22676
  installRoot: root,
22323
22677
  appPath,
22324
22678
  executablePath: appPath,
22325
- metadataPath: path24.join(root, DESKTOP_METADATA_FILE)
22679
+ metadataPath: path23.join(root, DESKTOP_METADATA_FILE)
22326
22680
  };
22327
22681
  }
22328
22682
  function normalizeAssetName(name) {
@@ -22381,10 +22735,20 @@ function resolveDesktopAssetCandidates(options) {
22381
22735
  const candidates = [];
22382
22736
  const deterministicShellName = options.directReleaseVersion ? resolveDesktopShellAssetName(options.directReleaseVersion, options.target) : null;
22383
22737
  if (options.allowShellAssets !== false) {
22384
- const shellAsset = selectDesktopShellAsset(options.releaseAssets, options.target) ?? (options.releaseAssets.length === 0 && deterministicShellName ? buildGithubReleaseAsset(options.repo, options.tag, deterministicShellName) : null);
22738
+ const shellAsset = selectDesktopShellAsset(options.releaseAssets, options.target) ?? (options.releaseAssets.length === 0 && deterministicShellName ? buildGithubReleaseAsset(
22739
+ options.repo,
22740
+ options.tag,
22741
+ deterministicShellName,
22742
+ options.downloadBaseUrl
22743
+ ) : null);
22385
22744
  if (shellAsset) candidates.push({ asset: shellAsset, kind: "shell" });
22386
22745
  }
22387
- const fullAsset = selectDesktopAsset(options.releaseAssets, options.target) ?? (options.directReleaseVersion ? buildGithubReleaseAsset(options.repo, options.tag, resolveDesktopAssetName(options.directReleaseVersion, options.target)) : null);
22746
+ const fullAsset = selectDesktopAsset(options.releaseAssets, options.target) ?? (options.directReleaseVersion ? buildGithubReleaseAsset(
22747
+ options.repo,
22748
+ options.tag,
22749
+ resolveDesktopAssetName(options.directReleaseVersion, options.target),
22750
+ options.downloadBaseUrl
22751
+ ) : null);
22388
22752
  if (fullAsset) candidates.push({ asset: fullAsset, kind: "full" });
22389
22753
  return candidates;
22390
22754
  }
@@ -22428,8 +22792,35 @@ function githubApiHeaders() {
22428
22792
  };
22429
22793
  }
22430
22794
  var GITHUB_API_TIMEOUT_MS = 15e3;
22431
- async function fetchGithubRelease(repo, tag) {
22432
- const endpoint = tag === "latest" ? `https://api.github.com/repos/${repo}/releases/latest` : `https://api.github.com/repos/${repo}/releases/tags/${encodeURIComponent(tag)}`;
22795
+ function resolveDesktopSmokeReleaseBaseUrls(env = process.env) {
22796
+ if (env.RUDDER_DESKTOP_SMOKE_AUTO_UPDATE_PUBLIC !== "1") {
22797
+ return {
22798
+ apiBaseUrl: DEFAULT_GITHUB_API_BASE_URL,
22799
+ downloadBaseUrl: DEFAULT_GITHUB_DOWNLOAD_BASE_URL
22800
+ };
22801
+ }
22802
+ const normalizeBaseUrl = (value, fallback) => {
22803
+ const configured = value?.trim();
22804
+ if (!configured) return fallback;
22805
+ const parsed = new URL(configured);
22806
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
22807
+ throw new Error(`Desktop smoke release base URL must use HTTP or HTTPS: ${configured}`);
22808
+ }
22809
+ return configured.replace(/\/+$/u, "");
22810
+ };
22811
+ return {
22812
+ apiBaseUrl: normalizeBaseUrl(
22813
+ env.RUDDER_DESKTOP_SMOKE_RELEASE_API_BASE_URL,
22814
+ DEFAULT_GITHUB_API_BASE_URL
22815
+ ),
22816
+ downloadBaseUrl: normalizeBaseUrl(
22817
+ env.RUDDER_DESKTOP_SMOKE_RELEASE_DOWNLOAD_BASE_URL,
22818
+ DEFAULT_GITHUB_DOWNLOAD_BASE_URL
22819
+ )
22820
+ };
22821
+ }
22822
+ async function fetchGithubRelease(repo, tag, apiBaseUrl = DEFAULT_GITHUB_API_BASE_URL) {
22823
+ const endpoint = tag === "latest" ? `${apiBaseUrl}/repos/${repo}/releases/latest` : `${apiBaseUrl}/repos/${repo}/releases/tags/${encodeURIComponent(tag)}`;
22433
22824
  const response = await fetchWithTimeout2(endpoint, { headers: githubApiHeaders() }, GITHUB_API_TIMEOUT_MS);
22434
22825
  if (!response.ok) {
22435
22826
  throw new Error(`GitHub Release ${tag} was not found in ${repo} (${response.status}).`);
@@ -22457,14 +22848,14 @@ function resolveDesktopShellAssetName(version, target) {
22457
22848
  function encodeReleaseTagForDownloadUrl2(tag) {
22458
22849
  return tag.split("/").map((segment) => encodeURIComponent(segment)).join("/");
22459
22850
  }
22460
- function buildGithubReleaseAssetDownloadUrl(repo, tag, assetName) {
22851
+ function buildGithubReleaseAssetDownloadUrl(repo, tag, assetName, downloadBaseUrl = DEFAULT_GITHUB_DOWNLOAD_BASE_URL) {
22461
22852
  const encodedTag = encodeReleaseTagForDownloadUrl2(tag);
22462
- return `https://github.com/${repo}/releases/download/${encodedTag}/${encodeURIComponent(assetName)}`;
22853
+ return `${downloadBaseUrl}/${repo}/releases/download/${encodedTag}/${encodeURIComponent(assetName)}`;
22463
22854
  }
22464
- function buildGithubReleaseAsset(repo, tag, assetName) {
22855
+ function buildGithubReleaseAsset(repo, tag, assetName, downloadBaseUrl) {
22465
22856
  return {
22466
22857
  name: assetName,
22467
- browser_download_url: buildGithubReleaseAssetDownloadUrl(repo, tag, assetName)
22858
+ browser_download_url: buildGithubReleaseAssetDownloadUrl(repo, tag, assetName, downloadBaseUrl)
22468
22859
  };
22469
22860
  }
22470
22861
  function checksumForFile(filePath) {
@@ -22473,16 +22864,16 @@ function checksumForFile(filePath) {
22473
22864
  return hash.digest("hex");
22474
22865
  }
22475
22866
  function resolveAssetChecksum(checksums, assetName) {
22476
- const expected = checksums.get(path24.basename(assetName));
22867
+ const expected = checksums.get(path23.basename(assetName));
22477
22868
  if (!expected) {
22478
- throw new Error(`Desktop release checksums do not include ${path24.basename(assetName)}.`);
22869
+ throw new Error(`Desktop release checksums do not include ${path23.basename(assetName)}.`);
22479
22870
  }
22480
22871
  return expected;
22481
22872
  }
22482
22873
  function assertChecksumMatch(filePath, expected) {
22483
22874
  const actual = checksumForFile(filePath);
22484
22875
  if (actual !== expected.toLowerCase()) {
22485
- throw new Error(`Checksum mismatch for ${path24.basename(filePath)}.`);
22876
+ throw new Error(`Checksum mismatch for ${path23.basename(filePath)}.`);
22486
22877
  }
22487
22878
  return actual;
22488
22879
  }
@@ -22501,10 +22892,10 @@ function normalizeDesktopAssetChecksum(checksum) {
22501
22892
  return normalized;
22502
22893
  }
22503
22894
  function resolveDesktopAssetCacheDir(assetChecksum, homeDir = resolveRudderHomeDir()) {
22504
- return path24.join(homeDir, DESKTOP_ASSET_CACHE_DIR, normalizeDesktopAssetChecksum(assetChecksum));
22895
+ return path23.join(homeDir, DESKTOP_ASSET_CACHE_DIR, normalizeDesktopAssetChecksum(assetChecksum));
22505
22896
  }
22506
22897
  function resolveDesktopCachedAssetPath(assetName, assetChecksum, homeDir = resolveRudderHomeDir()) {
22507
- return path24.join(resolveDesktopAssetCacheDir(assetChecksum, homeDir), path24.basename(assetName));
22898
+ return path23.join(resolveDesktopAssetCacheDir(assetChecksum, homeDir), path23.basename(assetName));
22508
22899
  }
22509
22900
  async function pruneDesktopAssetCache(options = {}) {
22510
22901
  const homeDir = options.homeDir ?? resolveRudderHomeDir();
@@ -22550,7 +22941,7 @@ async function maybePruneDesktopAssetCache(options) {
22550
22941
  return result.deleted.length > 0 || result.warnings.length > 0 ? result : null;
22551
22942
  }
22552
22943
  async function scanDesktopAssetCacheEntries(homeDir) {
22553
- const cacheRoot = path24.join(homeDir, DESKTOP_ASSET_CACHE_DIR);
22944
+ const cacheRoot = path23.join(homeDir, DESKTOP_ASSET_CACHE_DIR);
22554
22945
  const dirents = await readdir3(cacheRoot, { withFileTypes: true }).catch(() => null);
22555
22946
  if (!dirents) return [];
22556
22947
  const entries = [];
@@ -22562,7 +22953,7 @@ async function scanDesktopAssetCacheEntries(homeDir) {
22562
22953
  } catch {
22563
22954
  continue;
22564
22955
  }
22565
- const cacheDir = path24.join(cacheRoot, dirent.name);
22956
+ const cacheDir = path23.join(cacheRoot, dirent.name);
22566
22957
  const stats = await desktopCacheDirectoryStats(cacheDir);
22567
22958
  entries.push({
22568
22959
  cacheDir,
@@ -22574,7 +22965,7 @@ async function scanDesktopAssetCacheEntries(homeDir) {
22574
22965
  return entries;
22575
22966
  }
22576
22967
  async function desktopCacheDirectoryStats(targetPath) {
22577
- const fallbackStat = await stat6(targetPath).catch(() => null);
22968
+ const fallbackStat = await stat4(targetPath).catch(() => null);
22578
22969
  const dirents = await readdir3(targetPath, { withFileTypes: true }).catch(() => null);
22579
22970
  if (!dirents) {
22580
22971
  return {
@@ -22586,8 +22977,8 @@ async function desktopCacheDirectoryStats(targetPath) {
22586
22977
  let lastUsedAtMs = Number(fallbackStat?.mtimeMs ?? 0);
22587
22978
  for (const dirent of dirents) {
22588
22979
  if (dirent.isSymbolicLink()) continue;
22589
- const entryPath = path24.join(targetPath, dirent.name);
22590
- const entryStat = await stat6(entryPath).catch(() => null);
22980
+ const entryPath = path23.join(targetPath, dirent.name);
22981
+ const entryStat = await stat4(entryPath).catch(() => null);
22591
22982
  if (!entryStat) continue;
22592
22983
  lastUsedAtMs = Math.max(lastUsedAtMs, Number(entryStat.mtimeMs ?? 0));
22593
22984
  if (dirent.isDirectory()) {
@@ -22663,14 +23054,14 @@ async function downloadDesktopAssetWithCache(asset, expectedChecksum, options =
22663
23054
  await rm3(cachePath, { force: true });
22664
23055
  }
22665
23056
  }
22666
- const outputDir = options.outputDir ?? await mkdtemp2(path24.join(tmpdir(), "rudder-desktop-installer."));
23057
+ const outputDir = options.outputDir ?? await mkdtemp2(path23.join(tmpdir(), "rudder-desktop-installer."));
22667
23058
  const removeOutputDir = options.outputDir ? false : true;
22668
23059
  try {
22669
23060
  const downloadedPath = await downloadAsset(asset, outputDir, options.progressFactory, normalizedChecksum);
22670
23061
  const checksum = assertChecksumMatch(downloadedPath, normalizedChecksum);
22671
- await mkdir4(path24.dirname(cachePath), { recursive: true });
22672
- if (path24.resolve(downloadedPath) !== path24.resolve(cachePath)) {
22673
- await copyFile2(downloadedPath, cachePath);
23062
+ await mkdir3(path23.dirname(cachePath), { recursive: true });
23063
+ if (path23.resolve(downloadedPath) !== path23.resolve(cachePath)) {
23064
+ await copyFile(downloadedPath, cachePath);
22674
23065
  }
22675
23066
  return { path: cachePath, checksum, cacheStatus: "miss" };
22676
23067
  } finally {
@@ -22686,8 +23077,8 @@ async function pathExists2(targetPath) {
22686
23077
  }
22687
23078
  }
22688
23079
  function resolveDesktopInstallLockPath(paths) {
22689
- const installRootHash = createHash4("sha256").update(path24.resolve(paths.installRoot)).digest("hex").slice(0, 16);
22690
- return path24.join(path24.dirname(paths.appPath), `.rudder-desktop-install-${installRootHash}.lock`);
23080
+ const installRootHash = createHash4("sha256").update(path23.resolve(paths.installRoot)).digest("hex").slice(0, 16);
23081
+ return path23.join(path23.dirname(paths.appPath), `.rudder-desktop-install-${installRootHash}.lock`);
22691
23082
  }
22692
23083
  async function readDesktopInstallLock(lockPath) {
22693
23084
  try {
@@ -22707,17 +23098,17 @@ async function readDesktopInstallLock(lockPath) {
22707
23098
  }
22708
23099
  async function withDesktopInstallLock(paths, fn, options = {}) {
22709
23100
  const lockPath = resolveDesktopInstallLockPath(paths);
22710
- const lockDir = path24.dirname(lockPath);
23101
+ const lockDir = path23.dirname(lockPath);
22711
23102
  const timeoutMs = options.timeoutMs ?? DESKTOP_INSTALL_LOCK_TIMEOUT_MS;
22712
23103
  const pollMs = options.pollMs ?? DESKTOP_INSTALL_LOCK_POLL_MS;
22713
23104
  const startedAt = Date.now();
22714
23105
  const payload = {
22715
23106
  lockId: randomUUID(),
22716
23107
  pid: process.pid,
22717
- installRoot: path24.resolve(paths.installRoot),
23108
+ installRoot: path23.resolve(paths.installRoot),
22718
23109
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
22719
23110
  };
22720
- await mkdir4(lockDir, { recursive: true });
23111
+ await mkdir3(lockDir, { recursive: true });
22721
23112
  while (true) {
22722
23113
  try {
22723
23114
  await writeFile3(lockPath, `${JSON.stringify(payload, null, 2)}
@@ -22774,7 +23165,7 @@ function isSuccessfulRobocopyExitCode(status) {
22774
23165
  }
22775
23166
  async function extractZip(zipPath, outputDir, target) {
22776
23167
  await rm3(outputDir, { recursive: true, force: true });
22777
- await mkdir4(outputDir, { recursive: true });
23168
+ await mkdir3(outputDir, { recursive: true });
22778
23169
  if (target.platform === "macos") {
22779
23170
  runChecked("ditto", ["-x", "-k", zipPath, outputDir]);
22780
23171
  return;
@@ -22790,7 +23181,7 @@ async function findPath(root, predicate, maxDepth = 5) {
22790
23181
  async function visit(dir, depth) {
22791
23182
  const entries = await readdir3(dir, { withFileTypes: true });
22792
23183
  for (const entry of entries) {
22793
- const fullPath = path24.join(dir, entry.name);
23184
+ const fullPath = path23.join(dir, entry.name);
22794
23185
  if (predicate(fullPath, entry.isDirectory())) return fullPath;
22795
23186
  if (entry.isDirectory() && depth < maxDepth) {
22796
23187
  const nested = await visit(fullPath, depth + 1);
@@ -22802,18 +23193,18 @@ async function findPath(root, predicate, maxDepth = 5) {
22802
23193
  return await visit(root, 0);
22803
23194
  }
22804
23195
  async function findMacApp(extractDir) {
22805
- const direct = path24.join(extractDir, `${DESKTOP_APP_NAME}.app`);
23196
+ const direct = path23.join(extractDir, `${DESKTOP_APP_NAME}.app`);
22806
23197
  if (await pathExists2(direct)) return direct;
22807
- const found = await findPath(extractDir, (filePath, isDirectory) => isDirectory && path24.basename(filePath) === `${DESKTOP_APP_NAME}.app`);
23198
+ const found = await findPath(extractDir, (filePath, isDirectory) => isDirectory && path23.basename(filePath) === `${DESKTOP_APP_NAME}.app`);
22808
23199
  if (!found) throw new Error(`Portable macOS archive did not contain ${DESKTOP_APP_NAME}.app.`);
22809
23200
  return found;
22810
23201
  }
22811
23202
  async function findWindowsAppDir(extractDir) {
22812
- const direct = path24.join(extractDir, `${DESKTOP_APP_NAME}.exe`);
23203
+ const direct = path23.join(extractDir, `${DESKTOP_APP_NAME}.exe`);
22813
23204
  if (await pathExists2(direct)) return extractDir;
22814
- const executable = await findPath(extractDir, (filePath, isDirectory) => !isDirectory && path24.basename(filePath).toLowerCase() === `${DESKTOP_APP_NAME.toLowerCase()}.exe`);
23205
+ const executable = await findPath(extractDir, (filePath, isDirectory) => !isDirectory && path23.basename(filePath).toLowerCase() === `${DESKTOP_APP_NAME.toLowerCase()}.exe`);
22815
23206
  if (!executable) throw new Error(`Portable Windows archive did not contain ${DESKTOP_APP_NAME}.exe.`);
22816
- return path24.dirname(executable);
23207
+ return path23.dirname(executable);
22817
23208
  }
22818
23209
  async function readInstallMetadata(metadataPath) {
22819
23210
  try {
@@ -22881,7 +23272,7 @@ async function waitForUpdateQuitResponse(responsePath, timeoutMs = 8e3) {
22881
23272
  }
22882
23273
  async function requestDesktopQuit(executablePath, target, options = {}) {
22883
23274
  if (!await pathExists2(executablePath)) return { ok: true, status: "not_running" };
22884
- const responsePath = path24.join(tmpdir(), `rudder-update-quit-${process.pid}-${Date.now()}.json`);
23275
+ const responsePath = path23.join(tmpdir(), `rudder-update-quit-${process.pid}-${Date.now()}.json`);
22885
23276
  const result = spawnSync4(executablePath, [
22886
23277
  `${DESKTOP_UPDATE_QUIT_ARG}=${responsePath}`,
22887
23278
  ...options.forceUpdate ? [DESKTOP_UPDATE_FORCE_ARG] : []
@@ -23039,13 +23430,13 @@ async function prepareForDesktopReplace(paths, target, options = {}) {
23039
23430
  throw new Error(`Failed to replace existing Rudder Desktop at ${replacePath}. Close Rudder and rerun start.`);
23040
23431
  }
23041
23432
  async function installPortableDesktop(installerPath, paths, target) {
23042
- await mkdir4(paths.installRoot, { recursive: true });
23433
+ await mkdir3(paths.installRoot, { recursive: true });
23043
23434
  if (target.platform === "linux") {
23044
- await copyFile2(installerPath, paths.appPath);
23045
- await chmod(paths.appPath, 493);
23435
+ await copyFile(installerPath, paths.appPath);
23436
+ await chmod2(paths.appPath, 493);
23046
23437
  return;
23047
23438
  }
23048
- const extractDir = await mkdtemp2(path24.join(tmpdir(), "rudder-desktop-extract."));
23439
+ const extractDir = await mkdtemp2(path23.join(tmpdir(), "rudder-desktop-extract."));
23049
23440
  try {
23050
23441
  await extractZip(installerPath, extractDir, target);
23051
23442
  if (target.platform === "macos") {
@@ -23054,7 +23445,7 @@ async function installPortableDesktop(installerPath, paths, target) {
23054
23445
  return;
23055
23446
  }
23056
23447
  const appSource = await findWindowsAppDir(extractDir);
23057
- await mkdir4(path24.dirname(paths.installRoot), { recursive: true });
23448
+ await mkdir3(path23.dirname(paths.installRoot), { recursive: true });
23058
23449
  await copyPortableAppBundle(appSource, paths.installRoot);
23059
23450
  } finally {
23060
23451
  await rm3(extractDir, { recursive: true, force: true });
@@ -23062,7 +23453,7 @@ async function installPortableDesktop(installerPath, paths, target) {
23062
23453
  }
23063
23454
  async function copyPortableAppBundle(sourcePath, destinationPath) {
23064
23455
  if (process.platform === "win32") {
23065
- await mkdir4(destinationPath, { recursive: true });
23456
+ await mkdir3(destinationPath, { recursive: true });
23066
23457
  const command = buildWindowsRobocopyMirrorCommand(sourcePath, destinationPath);
23067
23458
  const result = spawnSync4(command.command, command.args, {
23068
23459
  encoding: "utf8",
@@ -23071,7 +23462,7 @@ async function copyPortableAppBundle(sourcePath, destinationPath) {
23071
23462
  if (isSuccessfulRobocopyExitCode(result.status)) return;
23072
23463
  throw new Error(formatCommandFailure(command.command, command.args, result.stdout, result.stderr));
23073
23464
  }
23074
- await cp2(sourcePath, destinationPath, { recursive: true, verbatimSymlinks: true });
23465
+ await cp(sourcePath, destinationPath, { recursive: true, verbatimSymlinks: true });
23075
23466
  }
23076
23467
  async function removeMacQuarantine(paths, target) {
23077
23468
  if (target.platform !== "macos") return;
@@ -23095,26 +23486,26 @@ function buildLinuxDesktopEntry(executablePath) {
23095
23486
  ].join("\n");
23096
23487
  }
23097
23488
  async function writeLinuxLaunchers(paths) {
23098
- const desktopDir = path24.join(homedir(), ".local", "share", "applications");
23099
- await mkdir4(desktopDir, { recursive: true });
23100
- await writeFile3(path24.join(desktopDir, "rudder.desktop"), buildLinuxDesktopEntry(paths.executablePath), "utf8");
23101
- const binDir = path24.join(homedir(), ".local", "bin");
23102
- await mkdir4(binDir, { recursive: true });
23103
- const wrapperPath = path24.join(binDir, "rudder-desktop");
23489
+ const desktopDir = path23.join(homedir(), ".local", "share", "applications");
23490
+ await mkdir3(desktopDir, { recursive: true });
23491
+ await writeFile3(path23.join(desktopDir, "rudder.desktop"), buildLinuxDesktopEntry(paths.executablePath), "utf8");
23492
+ const binDir = path23.join(homedir(), ".local", "bin");
23493
+ await mkdir3(binDir, { recursive: true });
23494
+ const wrapperPath = path23.join(binDir, "rudder-desktop");
23104
23495
  const escaped = paths.executablePath.replaceAll("'", `'"'"'`);
23105
23496
  await writeFile3(wrapperPath, `#!/bin/sh
23106
23497
  exec '${escaped}' "$@"
23107
23498
  `, "utf8");
23108
- await chmod(wrapperPath, 493);
23499
+ await chmod2(wrapperPath, 493);
23109
23500
  }
23110
23501
  function buildWindowsShortcutScript(executablePath) {
23111
- const appData = process.env.APPDATA?.trim() || path24.join(homedir(), "AppData", "Roaming");
23112
- const shortcutPath = path24.join(appData, "Microsoft", "Windows", "Start Menu", "Programs", "Rudder.lnk");
23502
+ const appData = process.env.APPDATA?.trim() || path23.join(homedir(), "AppData", "Roaming");
23503
+ const shortcutPath = path23.join(appData, "Microsoft", "Windows", "Start Menu", "Programs", "Rudder.lnk");
23113
23504
  return [
23114
23505
  "$shell = New-Object -ComObject WScript.Shell",
23115
23506
  `$shortcut = $shell.CreateShortcut(${powershellQuote(shortcutPath)})`,
23116
23507
  `$shortcut.TargetPath = ${powershellQuote(executablePath)}`,
23117
- `$shortcut.WorkingDirectory = ${powershellQuote(path24.dirname(executablePath))}`,
23508
+ `$shortcut.WorkingDirectory = ${powershellQuote(path23.dirname(executablePath))}`,
23118
23509
  "$shortcut.Save()"
23119
23510
  ].join("; ");
23120
23511
  }
@@ -23146,7 +23537,7 @@ function launchDesktop(paths, target) {
23146
23537
  spawn3(paths.executablePath, [], { detached: true, stdio: "ignore" }).unref();
23147
23538
  }
23148
23539
  async function writeInstallMetadata(paths, releaseTag, assetName, assetChecksum, assetKind = "full") {
23149
- mkdirSync2(path24.dirname(paths.metadataPath), { recursive: true });
23540
+ mkdirSync2(path23.dirname(paths.metadataPath), { recursive: true });
23150
23541
  const metadata = {
23151
23542
  version: 1,
23152
23543
  releaseTag,
@@ -23193,6 +23584,7 @@ async function startCommand(opts) {
23193
23584
  const version = opts.targetVersion?.trim() || opts.version?.trim() || resolveCurrentCliVersion();
23194
23585
  const dryRun = opts.dryRun === true;
23195
23586
  const desktopProgressJson = opts.desktopProgressJson === true;
23587
+ const desktopRuntimeBestEffort = opts.desktopRuntimeBestEffort === true && installDesktop;
23196
23588
  const exactDesktopAssetPath = opts.desktopAssetPath?.trim() || null;
23197
23589
  const exactDesktopAssetChecksum = opts.desktopAssetChecksum?.trim() || null;
23198
23590
  const exactDesktopAssetName = opts.desktopAssetName?.trim() || null;
@@ -23201,7 +23593,7 @@ async function startCommand(opts) {
23201
23593
  if (!exactDesktopAssetPath || !exactDesktopAssetChecksum || !exactDesktopAssetName || !exactDesktopReleaseDigest) {
23202
23594
  throw new Error("Exact Desktop asset mode requires path, checksum, asset name, and release digest.");
23203
23595
  }
23204
- if (!path24.isAbsolute(exactDesktopAssetPath) || exactDesktopAssetName.includes("/") || !/^[a-f0-9]{64}$/iu.test(exactDesktopAssetChecksum) || !/^[a-f0-9]{64}$/iu.test(exactDesktopReleaseDigest)) {
23596
+ if (!path23.isAbsolute(exactDesktopAssetPath) || exactDesktopAssetName.includes("/") || !/^[a-f0-9]{64}$/iu.test(exactDesktopAssetChecksum) || !/^[a-f0-9]{64}$/iu.test(exactDesktopReleaseDigest)) {
23205
23597
  throw new Error("Exact Desktop asset mode received invalid candidate identity.");
23206
23598
  }
23207
23599
  if (opts.desktopAssetKind && opts.desktopAssetKind !== "full" && opts.desktopAssetKind !== "shell") {
@@ -23224,13 +23616,29 @@ async function startCommand(opts) {
23224
23616
  }
23225
23617
  if (installRuntime) {
23226
23618
  p15.log.step("Preparing Rudder runtime");
23619
+ if (desktopProgressJson && desktopRuntimeBestEffort) {
23620
+ writeDesktopProgress({
23621
+ phase: "preparing_runtime",
23622
+ message: "Preparing the lightweight Desktop update runtime; the full package will be used if this takes too long."
23623
+ });
23624
+ await waitForDesktopRuntimeSmokeEvidence("RUDDER_DESKTOP_SMOKE_RUNTIME_PREPARING_DELAY_MS");
23625
+ }
23227
23626
  if (dryRun) {
23228
23627
  p15.log.message(`[dry-run] Would install or reuse ${pc14.cyan(`@rudderhq/server@${version}`)} in the Rudder runtime cache.`);
23229
23628
  } else {
23230
23629
  const spinner3 = p15.spinner();
23231
23630
  spinner3.start("Installing or reusing Rudder runtime...");
23232
23631
  try {
23233
- const runtime = await ensureRuntimeInstalled({ version, preparePostgresPayload: true });
23632
+ const runtime = await ensureRuntimeInstalled({
23633
+ version,
23634
+ preparePostgresPayload: true,
23635
+ ...desktopRuntimeBestEffort ? {
23636
+ timeoutMs: DESKTOP_RUNTIME_PREPARE_TIMEOUT_MS,
23637
+ cleanupIncompleteOnFailure: true,
23638
+ pruneRuntimeCache: false,
23639
+ allowLatestFallback: false
23640
+ } : {}
23641
+ });
23234
23642
  runtimeSupportsShellAssets = runtimeSupportsDesktopShellAssets(version, runtime);
23235
23643
  spinner3.stop(
23236
23644
  runtime.status === "hit" ? `Rudder runtime cache hit at ${pc14.cyan(runtime.cacheDir)}.` : `Rudder runtime installed at ${pc14.cyan(runtime.cacheDir)}.`
@@ -23241,12 +23649,27 @@ async function startCommand(opts) {
23241
23649
  if (!runtimeSupportsShellAssets && installDesktop) {
23242
23650
  p15.log.warn("Rudder runtime did not resolve to the exact Desktop version; the full portable Desktop asset will be used.");
23243
23651
  }
23652
+ if (desktopProgressJson && desktopRuntimeBestEffort) {
23653
+ writeDesktopProgress({
23654
+ phase: "preparing_runtime",
23655
+ message: runtimeSupportsShellAssets ? "Lightweight Desktop update runtime is ready." : "Lightweight runtime is unavailable; continuing with the full Desktop package."
23656
+ });
23657
+ }
23244
23658
  } catch (error) {
23245
23659
  spinner3.stop(pc14.red("Rudder runtime installation failed."));
23246
23660
  if (error instanceof RuntimeInstallError && error.output) {
23247
23661
  p15.log.message(pc14.dim(error.output));
23248
23662
  }
23249
- throw error;
23663
+ if (!desktopRuntimeBestEffort) throw error;
23664
+ const detail = error instanceof Error ? error.message : String(error);
23665
+ p15.log.warn(`Lightweight Desktop update runtime preparation failed; continuing with the full portable asset. ${detail}`);
23666
+ if (desktopProgressJson) {
23667
+ writeDesktopProgress({
23668
+ phase: "preparing_runtime",
23669
+ message: "Lightweight runtime preparation did not finish; continuing with the full Desktop package."
23670
+ });
23671
+ await waitForDesktopRuntimeSmokeEvidence("RUDDER_DESKTOP_SMOKE_RUNTIME_FALLBACK_DELAY_MS");
23672
+ }
23250
23673
  }
23251
23674
  }
23252
23675
  }
@@ -23281,11 +23704,12 @@ async function startCommand(opts) {
23281
23704
  if (installDesktop) {
23282
23705
  const downloadSource = resolveDesktopDownloadSource(opts.downloadSource);
23283
23706
  const mirrorBaseUrl = resolveDesktopReleaseMirrorBaseUrl(repo);
23707
+ const smokeReleaseBaseUrls = resolveDesktopSmokeReleaseBaseUrls();
23284
23708
  const target = resolveDesktopAssetTarget();
23285
23709
  const tag = resolveDesktopReleaseTag(version);
23286
- const installRoot = opts.desktopInstallDir ? path24.resolve(opts.desktopInstallDir) : resolveDefaultDesktopInstallRoot(target);
23710
+ const installRoot = opts.desktopInstallDir ? path23.resolve(opts.desktopInstallDir) : resolveDefaultDesktopInstallRoot(target);
23287
23711
  const installPaths = resolveDesktopInstallPaths(target, installRoot);
23288
- const outputDir = opts.outputDir ? path24.resolve(opts.outputDir) : await mkdtemp2(path24.join(tmpdir(), "rudder-desktop-installer."));
23712
+ const outputDir = opts.outputDir ? path23.resolve(opts.outputDir) : await mkdtemp2(path23.join(tmpdir(), "rudder-desktop-installer."));
23289
23713
  p15.log.step("Installing desktop app");
23290
23714
  p15.log.message(`Release: ${pc14.cyan(`${repo}@${tag}`)}`);
23291
23715
  p15.log.message(`Target: ${pc14.cyan(`${target.platform}/${target.arch}`)}`);
@@ -23325,13 +23749,13 @@ async function startCommand(opts) {
23325
23749
  if (computedReleaseDigest !== exactDesktopReleaseDigest.toLowerCase()) {
23326
23750
  throw new Error("Exact Desktop asset release digest does not match the candidate identity.");
23327
23751
  }
23328
- const descriptor = await stat6(exactDesktopAssetPath);
23752
+ const descriptor = await stat4(exactDesktopAssetPath);
23329
23753
  if (!descriptor.isFile()) throw new Error("Exact Desktop asset must be a regular file.");
23330
23754
  const linkDescriptor = await lstat(exactDesktopAssetPath);
23331
23755
  if (linkDescriptor.isSymbolicLink()) throw new Error("Exact Desktop asset must not be a symbolic link.");
23332
23756
  const checksum = await runStartPhase(
23333
23757
  "Verifying staged Desktop checksum...",
23334
- `Verified ${pc14.cyan(path24.basename(exactDesktopAssetPath))}.`,
23758
+ `Verified ${pc14.cyan(path23.basename(exactDesktopAssetPath))}.`,
23335
23759
  () => assertChecksumMatch(exactDesktopAssetPath, expectedChecksum),
23336
23760
  desktopProgressJson ? "verifying_checksum" : null
23337
23761
  );
@@ -23343,7 +23767,7 @@ async function startCommand(opts) {
23343
23767
  release = await runStartPhase(
23344
23768
  "Resolving Desktop release...",
23345
23769
  "Desktop release resolved.",
23346
- () => fetchGithubRelease(repo, tag),
23770
+ () => fetchGithubRelease(repo, tag, smokeReleaseBaseUrls.apiBaseUrl),
23347
23771
  desktopProgressJson ? "resolving_release" : null
23348
23772
  );
23349
23773
  } catch (error) {
@@ -23360,12 +23784,18 @@ async function startCommand(opts) {
23360
23784
  repo,
23361
23785
  tag,
23362
23786
  directReleaseVersion,
23363
- allowShellAssets: runtimeSupportsShellAssets
23787
+ allowShellAssets: runtimeSupportsShellAssets,
23788
+ downloadBaseUrl: smokeReleaseBaseUrls.downloadBaseUrl
23364
23789
  });
23365
23790
  if (assetCandidates.length === 0) {
23366
23791
  throw new Error(`No Rudder Desktop portable asset found for ${target.platform}/${target.arch} in ${repo}@${releaseTag}.`);
23367
23792
  }
23368
- const checksumAsset = selectChecksumAsset(release?.assets ?? []) ?? (directReleaseVersion ? buildGithubReleaseAsset(repo, tag, DESKTOP_CHECKSUM_ASSET_NAME) : null);
23793
+ const checksumAsset = selectChecksumAsset(release?.assets ?? []) ?? (directReleaseVersion ? buildGithubReleaseAsset(
23794
+ repo,
23795
+ tag,
23796
+ DESKTOP_CHECKSUM_ASSET_NAME,
23797
+ smokeReleaseBaseUrls.downloadBaseUrl
23798
+ ) : null);
23369
23799
  if (!checksumAsset) {
23370
23800
  throw new Error("Desktop release is missing SHASUMS256.txt.");
23371
23801
  }
@@ -23444,7 +23874,7 @@ async function startCommand(opts) {
23444
23874
  }
23445
23875
  const checksum = await runStartPhase(
23446
23876
  "Verifying Desktop checksum...",
23447
- `Verified ${pc14.cyan(path24.basename(verifiedAsset.path))}.`,
23877
+ `Verified ${pc14.cyan(path23.basename(verifiedAsset.path))}.`,
23448
23878
  () => assertChecksumMatch(verifiedAsset.path, expectedChecksum),
23449
23879
  desktopProgressJson ? "verifying_checksum" : null
23450
23880
  );
@@ -23455,7 +23885,8 @@ async function startCommand(opts) {
23455
23885
  percent: 100,
23456
23886
  assetName: selectedAsset.name,
23457
23887
  assetChecksum: checksum,
23458
- stagedArtifactPath: path24.resolve(verifiedAsset.path),
23888
+ assetKind: selectedAssetKind,
23889
+ stagedArtifactPath: path23.resolve(verifiedAsset.path),
23459
23890
  stagedArtifactDigest: checksum,
23460
23891
  releaseDigest: createHash4("sha256").update(JSON.stringify({
23461
23892
  releaseTag,
@@ -23548,11 +23979,11 @@ async function startCommand(opts) {
23548
23979
 
23549
23980
  // src/config/data-dir.ts
23550
23981
  init_home();
23551
- import path25 from "node:path";
23982
+ import path24 from "node:path";
23552
23983
  function applyDataDirOverride(options, support = {}) {
23553
23984
  const rawDataDir = options.dataDir?.trim();
23554
23985
  if (!rawDataDir) return null;
23555
- const resolvedDataDir = path25.resolve(expandHomePrefix(rawDataDir));
23986
+ const resolvedDataDir = path24.resolve(expandHomePrefix(rawDataDir));
23556
23987
  process.env.RUDDER_HOME = resolvedDataDir;
23557
23988
  if (support.hasConfigOption) {
23558
23989
  const hasConfigOverride = Boolean(options.config?.trim()) || Boolean(process.env.RUDDER_CONFIG?.trim());
@@ -23612,7 +24043,7 @@ function createProgram() {
23612
24043
  });
23613
24044
  loadRudderEnvFile(options.config);
23614
24045
  });
23615
- program.command("start").description("Start Rudder Desktop and prepare the matching persistent CLI").option("--server-only", "Prepare the Rudder server runtime and persistent CLI without installing Desktop").option("--no-cli", "Skip persistent CLI installation").option("--no-runtime", "Skip Rudder runtime installation").option("--no-desktop", "Skip desktop app installation").option("--version <version>", "Rudder version to start (default: current CLI version)").option("--target-version <version>", "Rudder version to start; avoids the root CLI version flag").option("--repo <owner/repo>", "GitHub repository that hosts desktop releases").option("--download-source <source>", "Desktop download source: auto, cn, or global").option("--output-dir <path>", "Directory for downloaded desktop release assets").option("--desktop-install-dir <path>", "Directory for the portable Desktop install").option("--no-open", "Install Desktop without launching it").option("--wait-for-active-runs", "Wait for active Rudder runs to finish before replacing Desktop", false).option("--desktop-progress-json", "Emit newline-delimited Desktop update progress events").option("--desktop-wait-for-apply", "Wait for an apply signal after downloading and verifying the Desktop update", false).option("--desktop-prepare-only", "Download and verify the Desktop update without installing or launching it", false).option("--desktop-asset-path <path>", "Use one previously staged, exact Desktop asset path").option("--desktop-asset-checksum <sha256>", "SHA-256 for the exact staged Desktop asset").option("--desktop-asset-name <name>", "Asset name bound to the exact staged Desktop candidate").option("--desktop-asset-kind <kind>", "Asset kind bound to the exact staged Desktop candidate (full or shell)").option("--desktop-release-digest <sha256>", "Release digest bound to the exact staged Desktop candidate").option("--no-version-check", "Skip checking npm for a newer Rudder CLI version").option("--dry-run", "Print the start actions without changing the machine", false).action(startCommand);
24046
+ program.command("start").description("Start Rudder Desktop and prepare the matching persistent CLI").option("--server-only", "Prepare the Rudder server runtime and persistent CLI without installing Desktop").option("--no-cli", "Skip persistent CLI installation").option("--no-runtime", "Skip Rudder runtime installation").option("--no-desktop", "Skip desktop app installation").option("--version <version>", "Rudder version to start (default: current CLI version)").option("--target-version <version>", "Rudder version to start; avoids the root CLI version flag").option("--repo <owner/repo>", "GitHub repository that hosts desktop releases").option("--download-source <source>", "Desktop download source: auto, cn, or global").option("--output-dir <path>", "Directory for downloaded desktop release assets").option("--desktop-install-dir <path>", "Directory for the portable Desktop install").option("--no-open", "Install Desktop without launching it").option("--wait-for-active-runs", "Wait for active Rudder runs to finish before replacing Desktop", false).option("--desktop-progress-json", "Emit newline-delimited Desktop update progress events").option("--desktop-wait-for-apply", "Wait for an apply signal after downloading and verifying the Desktop update", false).option("--desktop-prepare-only", "Download and verify the Desktop update without installing or launching it", false).option("--desktop-asset-path <path>", "Use one previously staged, exact Desktop asset path").option("--desktop-asset-checksum <sha256>", "SHA-256 for the exact staged Desktop asset").option("--desktop-asset-name <name>", "Asset name bound to the exact staged Desktop candidate").option("--desktop-asset-kind <kind>", "Asset kind bound to the exact staged Desktop candidate (full or shell)").option("--desktop-release-digest <sha256>", "Release digest bound to the exact staged Desktop candidate").addOption(new Option("--desktop-runtime-best-effort").hideHelp()).option("--no-version-check", "Skip checking npm for a newer Rudder CLI version").option("--dry-run", "Print the start actions without changing the machine", false).action(startCommand);
23616
24047
  program.command("onboard").description("Interactive first-run setup wizard").option("-c, --config <path>", "Path to config file").option("-d, --data-dir <path>", DATA_DIR_OPTION_HELP).option("-y, --yes", "Accept defaults (quickstart + start immediately)", false).option("--run", "Start Rudder immediately after saving config", false).action(onboard);
23617
24048
  program.command("doctor").description("Run diagnostic checks on your Rudder setup").option("-c, --config <path>", "Path to config file").option("-d, --data-dir <path>", DATA_DIR_OPTION_HELP).option("--repair", "Attempt to repair issues automatically").alias("--fix").option("-y, --yes", "Skip repair confirmation prompts").action(async (opts) => {
23618
24049
  await doctor(opts);