@rudderhq/cli 0.2.1 → 0.2.2-canary.1

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/README.md CHANGED
@@ -8,8 +8,6 @@ Rudder began from a fork of an early version of Paperclip. That gave us a practi
8
8
 
9
9
  Rudder is built for the moment when agent work stops looking like a single prompt and starts looking like a real team.
10
10
 
11
- Current status: V1 is under active development. The current north-star metric is the weekly count of real agent-work loops completed end-to-end through Rudder.
12
-
13
11
  ## The Design Idea
14
12
 
15
13
  Rudder is shaped by a simple belief: the most useful way to work with agents is closer to the way humans coordinate with each other.
package/dist/index.js CHANGED
@@ -117,6 +117,7 @@ var init_constants = __esm({
117
117
  CHAT_MESSAGE_ROLES = ["user", "assistant", "system"];
118
118
  CHAT_MESSAGE_KINDS = [
119
119
  "message",
120
+ "ask_user",
120
121
  "issue_proposal",
121
122
  "operation_proposal",
122
123
  "system_event"
@@ -579,7 +580,7 @@ var init_resource = __esm({
579
580
 
580
581
  // ../packages/shared/src/validators/chat.ts
581
582
  import { z as z5 } from "zod";
582
- var chatConversationStatusSchema, chatIssueCreationModeSchema, chatMessageRoleSchema, chatMessageKindSchema, chatMessageStatusSchema, chatContextEntityTypeSchema, createChatContextLinkSchema, createChatConversationSchema, setChatProjectContextSchema, updateChatConversationSchema, addChatMessageSchema, createChatAttachmentMetadataSchema, chatIssueProposalSchema, convertChatToIssueSchema, chatOperationProposalSchema, resolveChatOperationProposalSchema, updateChatConversationUserStateSchema;
583
+ var chatConversationStatusSchema, chatIssueCreationModeSchema, chatMessageRoleSchema, chatMessageKindSchema, chatMessageStatusSchema, chatContextEntityTypeSchema, createChatContextLinkSchema, createChatConversationSchema, setChatProjectContextSchema, updateChatConversationSchema, addChatMessageSchema, chatRichReferenceDisplaySchema, chatIssueIdentifierSchema, chatAskUserIdentifierSchema, chatAskUserOptionSchema, chatAskUserQuestionSchema, chatAskUserRequestSchema, chatIssueRichReferenceSchema, chatIssueCommentRichReferenceSchema, chatRichReferenceSchema, chatRichReferencesSchema, createChatAttachmentMetadataSchema, chatIssueProposalSchema, convertChatToIssueSchema, chatOperationProposalSchema, resolveChatOperationProposalSchema, updateChatConversationUserStateSchema;
583
584
  var init_chat = __esm({
584
585
  "../packages/shared/src/validators/chat.ts"() {
585
586
  "use strict";
@@ -616,6 +617,47 @@ var init_chat = __esm({
616
617
  body: z5.string().trim().min(1).max(2e4),
617
618
  editUserMessageId: z5.string().uuid().optional().nullable()
618
619
  });
620
+ chatRichReferenceDisplaySchema = z5.enum(["card", "inline"]);
621
+ chatIssueIdentifierSchema = z5.string().trim().min(1).max(64).regex(/^[A-Z0-9][A-Z0-9-]*$/i);
622
+ chatAskUserIdentifierSchema = z5.string().trim().min(1).max(64).regex(/^[a-zA-Z0-9_-]+$/);
623
+ chatAskUserOptionSchema = z5.object({
624
+ id: chatAskUserIdentifierSchema,
625
+ label: z5.string().trim().min(1).max(80),
626
+ description: z5.string().trim().min(1).max(220).optional(),
627
+ recommended: z5.boolean().optional()
628
+ });
629
+ chatAskUserQuestionSchema = z5.object({
630
+ id: chatAskUserIdentifierSchema,
631
+ header: z5.string().trim().min(1).max(32).optional(),
632
+ question: z5.string().trim().min(1).max(240),
633
+ options: z5.array(chatAskUserOptionSchema).min(2).max(3),
634
+ allowFreeform: z5.boolean().optional()
635
+ });
636
+ chatAskUserRequestSchema = z5.object({
637
+ questions: z5.array(chatAskUserQuestionSchema).min(1).max(3)
638
+ });
639
+ chatIssueRichReferenceSchema = z5.object({
640
+ type: z5.literal("issue"),
641
+ issueId: z5.string().uuid().optional(),
642
+ identifier: chatIssueIdentifierSchema.optional(),
643
+ display: chatRichReferenceDisplaySchema.optional()
644
+ }).refine((value) => Boolean(value.issueId || value.identifier), {
645
+ message: "issueId or identifier is required"
646
+ });
647
+ chatIssueCommentRichReferenceSchema = z5.object({
648
+ type: z5.literal("issue_comment"),
649
+ issueId: z5.string().uuid().optional(),
650
+ identifier: chatIssueIdentifierSchema.optional(),
651
+ commentId: z5.string().uuid(),
652
+ display: chatRichReferenceDisplaySchema.optional()
653
+ }).refine((value) => Boolean(value.issueId || value.identifier), {
654
+ message: "issueId or identifier is required"
655
+ });
656
+ chatRichReferenceSchema = z5.union([
657
+ chatIssueRichReferenceSchema,
658
+ chatIssueCommentRichReferenceSchema
659
+ ]);
660
+ chatRichReferencesSchema = z5.array(chatRichReferenceSchema).max(5);
619
661
  createChatAttachmentMetadataSchema = z5.object({
620
662
  messageId: z5.string().uuid()
621
663
  });
@@ -2491,7 +2533,10 @@ var init_organization_skill_reference = __esm({
2491
2533
  "para-memory-files",
2492
2534
  "rudder",
2493
2535
  "rudder-create-agent",
2494
- "rudder-create-plugin"
2536
+ "rudder-create-plugin",
2537
+ "skill-creator",
2538
+ "skill-optimizer",
2539
+ "conversation-to-skill"
2495
2540
  ];
2496
2541
  RUDDER_BUNDLED_SKILL_KEYS = new Set(
2497
2542
  RUDDER_BUNDLED_SKILL_SLUGS.map((slug) => `rudder/${slug}`)
@@ -6132,6 +6177,103 @@ var CLI_REGISTRY_LATEST_URL = "https://registry.npmjs.org/@rudderhq%2fcli/latest
6132
6177
  var DESKTOP_APP_NAME = "Rudder";
6133
6178
  var DESKTOP_METADATA_FILE = ".rudder-desktop-install.json";
6134
6179
  var DESKTOP_CHECKSUM_ASSET_NAME = "SHASUMS256.txt";
6180
+ var GITHUB_ASSET_DOWNLOAD_ACCEPT = "application/octet-stream";
6181
+ function normalizeProgressTotal(totalBytes) {
6182
+ return typeof totalBytes === "number" && Number.isFinite(totalBytes) && totalBytes > 0 ? totalBytes : null;
6183
+ }
6184
+ function writeDesktopProgress(event) {
6185
+ const payload = {
6186
+ source: "rudder-desktop-update",
6187
+ ...event,
6188
+ at: (/* @__PURE__ */ new Date()).toISOString()
6189
+ };
6190
+ try {
6191
+ process.stdout.write(`${JSON.stringify(payload)}
6192
+ `);
6193
+ } catch (error) {
6194
+ const code = typeof error === "object" && error && "code" in error ? String(error.code) : "";
6195
+ if (code !== "EPIPE") throw error;
6196
+ }
6197
+ }
6198
+ function desktopDownloadPhase(label) {
6199
+ return label.toLowerCase().includes("shasums") ? "downloading_checksums" : "downloading_asset";
6200
+ }
6201
+ function createDesktopProgressFactory() {
6202
+ return (label) => {
6203
+ const phase = desktopDownloadPhase(label);
6204
+ let latestReceivedBytes = 0;
6205
+ let latestTotalBytes = null;
6206
+ function emitByteProgress(message, receivedBytes, totalBytes) {
6207
+ const total = normalizeProgressTotal(totalBytes);
6208
+ writeDesktopProgress({
6209
+ phase,
6210
+ message,
6211
+ transferredBytes: Math.max(0, receivedBytes),
6212
+ ...total === null ? {} : {
6213
+ totalBytes: total,
6214
+ percent: Math.max(0, Math.min(100, Math.floor(Math.max(0, receivedBytes) / total * 100)))
6215
+ }
6216
+ });
6217
+ }
6218
+ return {
6219
+ start(totalBytes) {
6220
+ latestReceivedBytes = 0;
6221
+ latestTotalBytes = totalBytes;
6222
+ emitByteProgress(label, 0, totalBytes);
6223
+ },
6224
+ update(receivedBytes, totalBytes) {
6225
+ latestReceivedBytes = receivedBytes;
6226
+ latestTotalBytes = totalBytes;
6227
+ emitByteProgress(label, receivedBytes, totalBytes);
6228
+ },
6229
+ finish(receivedBytes = latestReceivedBytes, totalBytes = latestTotalBytes) {
6230
+ latestReceivedBytes = receivedBytes;
6231
+ latestTotalBytes = totalBytes;
6232
+ emitByteProgress(`${label} complete`, receivedBytes, totalBytes);
6233
+ },
6234
+ fail() {
6235
+ writeDesktopProgress({
6236
+ phase,
6237
+ message: `${label} failed`,
6238
+ transferredBytes: Math.max(0, latestReceivedBytes),
6239
+ error: `${label} failed`
6240
+ });
6241
+ }
6242
+ };
6243
+ };
6244
+ }
6245
+ async function waitForDesktopApplySignal() {
6246
+ process.stdin.setEncoding("utf8");
6247
+ process.stdin.resume();
6248
+ await new Promise((resolve, reject) => {
6249
+ let buffer = "";
6250
+ const cleanup = () => {
6251
+ process.stdin.off("data", onData);
6252
+ process.stdin.off("end", onEnd);
6253
+ process.stdin.off("error", onError);
6254
+ };
6255
+ const onData = (chunk) => {
6256
+ buffer += chunk;
6257
+ const lines = buffer.split(/\r?\n/);
6258
+ buffer = lines.pop() ?? "";
6259
+ if (lines.some((line) => line.trim() === "apply")) {
6260
+ cleanup();
6261
+ resolve();
6262
+ }
6263
+ };
6264
+ const onEnd = () => {
6265
+ cleanup();
6266
+ reject(new Error("Desktop update apply signal ended before confirmation."));
6267
+ };
6268
+ const onError = (error) => {
6269
+ cleanup();
6270
+ reject(error);
6271
+ };
6272
+ process.stdin.on("data", onData);
6273
+ process.stdin.on("end", onEnd);
6274
+ process.stdin.on("error", onError);
6275
+ });
6276
+ }
6135
6277
  function resolveCurrentCliVersion(env = process.env) {
6136
6278
  const version = resolveCliVersion(import.meta.url, env);
6137
6279
  return version === "0.0.0" ? "latest" : version;
@@ -6313,6 +6455,26 @@ function buildGithubReleaseAsset(repo, tag, assetName) {
6313
6455
  browser_download_url: buildGithubReleaseAssetDownloadUrl(repo, tag, assetName)
6314
6456
  };
6315
6457
  }
6458
+ function uniqueAssetDownloadUrls(asset) {
6459
+ const urls = [asset.url, asset.browser_download_url].filter((url) => Boolean(url));
6460
+ return Array.from(new Set(urls));
6461
+ }
6462
+ function downloadHeadersForAssetUrl(asset, url) {
6463
+ return {
6464
+ Accept: url === asset.url ? GITHUB_ASSET_DOWNLOAD_ACCEPT : "*/*",
6465
+ "User-Agent": "rudder-cli-installer"
6466
+ };
6467
+ }
6468
+ function formatFetchError(error) {
6469
+ if (!(error instanceof Error)) return String(error);
6470
+ const cause = error.cause;
6471
+ if (cause instanceof Error) {
6472
+ const code = cause.code;
6473
+ const suffix = typeof code === "string" ? ` [${code}]` : "";
6474
+ return `${error.message}: ${cause.message}${suffix}`;
6475
+ }
6476
+ return error.message;
6477
+ }
6316
6478
  function contentLengthFromHeaders(headers) {
6317
6479
  const raw = headers.get("content-length");
6318
6480
  if (!raw) return null;
@@ -6322,11 +6484,24 @@ function contentLengthFromHeaders(headers) {
6322
6484
  async function downloadAsset(asset, outputDir, progressFactory = createByteProgress) {
6323
6485
  mkdirSync(outputDir, { recursive: true });
6324
6486
  const outputPath = path11.join(outputDir, path11.basename(asset.name));
6325
- const response = await fetch(asset.browser_download_url, {
6326
- headers: { "User-Agent": "rudder-cli-installer" }
6327
- });
6328
- if (!response.ok || !response.body) {
6329
- throw new Error(`Failed to download ${asset.name} from ${asset.browser_download_url} (${response.status}).`);
6487
+ let response = null;
6488
+ const failures = [];
6489
+ for (const url of uniqueAssetDownloadUrls(asset)) {
6490
+ try {
6491
+ const candidate = await fetch(url, {
6492
+ headers: downloadHeadersForAssetUrl(asset, url)
6493
+ });
6494
+ if (candidate.ok && candidate.body) {
6495
+ response = candidate;
6496
+ break;
6497
+ }
6498
+ failures.push(`Failed to download ${asset.name} from ${url} (${candidate.status}).`);
6499
+ } catch (error) {
6500
+ failures.push(`Failed to download ${asset.name} from ${url}: ${formatFetchError(error)}.`);
6501
+ }
6502
+ }
6503
+ if (!response) {
6504
+ throw new Error(failures.join("\n"));
6330
6505
  }
6331
6506
  const totalBytes = contentLengthFromHeaders(response.headers);
6332
6507
  const progress = progressFactory(`Downloading ${asset.name}`);
@@ -6401,9 +6576,25 @@ function runChecked(command, args, options = {}) {
6401
6576
  const output = [result.stdout, result.stderr].filter((value) => typeof value === "string" && value.trim().length > 0).join("\n").trim();
6402
6577
  throw new Error(`${command} ${args.join(" ")} failed${output ? `: ${output}` : ""}`);
6403
6578
  }
6579
+ function formatCommandFailure(command, args, stdout, stderr) {
6580
+ const output = [stdout, stderr].filter((value) => typeof value === "string" && value.trim().length > 0).join("\n").trim();
6581
+ return `${command} ${args.join(" ")} failed${output ? `: ${output}` : ""}`;
6582
+ }
6404
6583
  function powershellQuote(value) {
6405
6584
  return `'${value.replaceAll("'", "''")}'`;
6406
6585
  }
6586
+ function buildWindowsZipExtractCommand(zipPath, outputDir) {
6587
+ return { command: "tar.exe", args: ["-xf", zipPath, "-C", outputDir] };
6588
+ }
6589
+ function buildWindowsRobocopyMirrorCommand(sourcePath, destinationPath) {
6590
+ return {
6591
+ command: "robocopy.exe",
6592
+ args: [sourcePath, destinationPath, "/MIR", "/R:2", "/W:1", "/NFL", "/NDL", "/NJH", "/NJS", "/NP"]
6593
+ };
6594
+ }
6595
+ function isSuccessfulRobocopyExitCode(status) {
6596
+ return typeof status === "number" && status >= 0 && status <= 7;
6597
+ }
6407
6598
  async function extractZip(zipPath, outputDir, target) {
6408
6599
  await rm(outputDir, { recursive: true, force: true });
6409
6600
  await mkdir2(outputDir, { recursive: true });
@@ -6412,13 +6603,8 @@ async function extractZip(zipPath, outputDir, target) {
6412
6603
  return;
6413
6604
  }
6414
6605
  if (target.platform === "windows") {
6415
- runChecked("powershell.exe", [
6416
- "-NoProfile",
6417
- "-ExecutionPolicy",
6418
- "Bypass",
6419
- "-Command",
6420
- `Expand-Archive -LiteralPath ${powershellQuote(zipPath)} -DestinationPath ${powershellQuote(outputDir)} -Force`
6421
- ]);
6606
+ const command = buildWindowsZipExtractCommand(zipPath, outputDir);
6607
+ runChecked(command.command, command.args);
6422
6608
  return;
6423
6609
  }
6424
6610
  throw new Error(`Zip assets are not supported for ${target.platform}.`);
@@ -6564,6 +6750,16 @@ async function installPortableDesktop(installerPath, paths, target) {
6564
6750
  }
6565
6751
  }
6566
6752
  async function copyPortableAppBundle(sourcePath, destinationPath) {
6753
+ if (process.platform === "win32") {
6754
+ await mkdir2(destinationPath, { recursive: true });
6755
+ const command = buildWindowsRobocopyMirrorCommand(sourcePath, destinationPath);
6756
+ const result = spawnSync3(command.command, command.args, {
6757
+ encoding: "utf8",
6758
+ stdio: ["ignore", "pipe", "pipe"]
6759
+ });
6760
+ if (isSuccessfulRobocopyExitCode(result.status)) return;
6761
+ throw new Error(formatCommandFailure(command.command, command.args, result.stdout, result.stderr));
6762
+ }
6567
6763
  await cp(sourcePath, destinationPath, { recursive: true, verbatimSymlinks: true });
6568
6764
  }
6569
6765
  async function removeMacQuarantine(paths, target) {
@@ -6651,15 +6847,28 @@ async function writeInstallMetadata(paths, releaseTag, assetName, assetChecksum)
6651
6847
  await writeFile2(paths.metadataPath, `${JSON.stringify(metadata, null, 2)}
6652
6848
  `, "utf8");
6653
6849
  }
6654
- async function runStartPhase(message, successMessage, task) {
6850
+ async function runStartPhase(message, successMessage, task, progressPhase) {
6851
+ if (progressPhase) {
6852
+ writeDesktopProgress({ phase: progressPhase, message });
6853
+ }
6655
6854
  const spinner3 = p13.spinner();
6656
6855
  spinner3.start(message);
6657
6856
  try {
6658
6857
  const result = await task();
6659
6858
  spinner3.stop(successMessage);
6859
+ if (progressPhase) {
6860
+ writeDesktopProgress({ phase: progressPhase, message: successMessage });
6861
+ }
6660
6862
  return result;
6661
6863
  } catch (error) {
6662
6864
  spinner3.stop(pc8.red(`${message} failed.`));
6865
+ if (progressPhase) {
6866
+ writeDesktopProgress({
6867
+ phase: "failed",
6868
+ message: `${message} failed.`,
6869
+ error: error instanceof Error ? error.message : String(error)
6870
+ });
6871
+ }
6663
6872
  throw error;
6664
6873
  }
6665
6874
  }
@@ -6670,6 +6879,12 @@ async function startCommand(opts) {
6670
6879
  const repo = opts.repo?.trim() || DEFAULT_DESKTOP_RELEASE_REPO;
6671
6880
  const version = opts.targetVersion?.trim() || opts.version?.trim() || resolveCurrentCliVersion();
6672
6881
  const dryRun = opts.dryRun === true;
6882
+ const desktopProgressJson = opts.desktopProgressJson === true;
6883
+ if (desktopProgressJson) {
6884
+ process.stdout.on("error", (error) => {
6885
+ if (error.code !== "EPIPE") throw error;
6886
+ });
6887
+ }
6673
6888
  if (!installCli && !installDesktop && !installRuntime) {
6674
6889
  throw new Error("Nothing to start. Remove --no-cli, --no-runtime, or --no-desktop.");
6675
6890
  }
@@ -6743,21 +6958,30 @@ async function startCommand(opts) {
6743
6958
  return;
6744
6959
  }
6745
6960
  const directReleaseVersion = resolveDesktopReleaseVersion(tag);
6746
- const progressFactory = createByteProgress;
6747
- const release = directReleaseVersion ? null : await runStartPhase(
6748
- "Resolving Desktop release...",
6749
- "Desktop release resolved.",
6750
- () => fetchGithubRelease(repo, tag)
6751
- );
6752
- const releaseTag = directReleaseVersion ? tag : release?.tag_name;
6961
+ const progressFactory = desktopProgressJson ? createDesktopProgressFactory() : createByteProgress;
6962
+ let release = null;
6963
+ try {
6964
+ release = await runStartPhase(
6965
+ "Resolving Desktop release...",
6966
+ "Desktop release resolved.",
6967
+ () => fetchGithubRelease(repo, tag),
6968
+ desktopProgressJson ? "resolving_release" : null
6969
+ );
6970
+ } catch (error) {
6971
+ if (!directReleaseVersion) throw error;
6972
+ p13.log.warn(
6973
+ `Desktop release metadata could not be resolved; falling back to deterministic download URLs. ${formatFetchError(error)}`
6974
+ );
6975
+ }
6976
+ const releaseTag = release?.tag_name ?? (directReleaseVersion ? tag : null);
6753
6977
  if (!releaseTag) {
6754
6978
  throw new Error(`Unable to resolve Rudder Desktop release tag for ${repo}@${tag}.`);
6755
6979
  }
6756
- const asset = directReleaseVersion ? buildGithubReleaseAsset(repo, tag, resolveDesktopAssetName(directReleaseVersion, target)) : selectDesktopAsset(release?.assets ?? [], target);
6980
+ const asset = selectDesktopAsset(release?.assets ?? [], target) ?? (directReleaseVersion ? buildGithubReleaseAsset(repo, tag, resolveDesktopAssetName(directReleaseVersion, target)) : null);
6757
6981
  if (!asset) {
6758
6982
  throw new Error(`No Rudder Desktop portable asset found for ${target.platform}/${target.arch} in ${repo}@${releaseTag}.`);
6759
6983
  }
6760
- const checksumAsset = directReleaseVersion ? buildGithubReleaseAsset(repo, tag, DESKTOP_CHECKSUM_ASSET_NAME) : selectChecksumAsset(release?.assets ?? []);
6984
+ const checksumAsset = selectChecksumAsset(release?.assets ?? []) ?? (directReleaseVersion ? buildGithubReleaseAsset(repo, tag, DESKTOP_CHECKSUM_ASSET_NAME) : null);
6761
6985
  const checksums = await downloadChecksums(checksumAsset, outputDir, progressFactory);
6762
6986
  const expectedChecksum = resolveAssetChecksum(checksums, asset.name);
6763
6987
  const metadata = await readInstallMetadata(installPaths.metadataPath);
@@ -6769,24 +6993,40 @@ async function startCommand(opts) {
6769
6993
  async () => {
6770
6994
  await removeMacQuarantine(installPaths, target);
6771
6995
  await createPlatformLaunchers(installPaths, target);
6772
- }
6996
+ },
6997
+ desktopProgressJson ? "preparing_restart" : null
6773
6998
  );
6774
6999
  } else {
6775
7000
  const installerPath = await downloadAsset(asset, outputDir, progressFactory);
6776
7001
  const checksum = await runStartPhase(
6777
7002
  "Verifying Desktop checksum...",
6778
7003
  `Verified ${pc8.cyan(path11.basename(installerPath))}.`,
6779
- () => assertChecksumMatch(installerPath, expectedChecksum)
7004
+ () => assertChecksumMatch(installerPath, expectedChecksum),
7005
+ desktopProgressJson ? "verifying_checksum" : null
6780
7006
  );
7007
+ if (desktopProgressJson && opts.desktopWaitForApply === true) {
7008
+ writeDesktopProgress({
7009
+ phase: "ready_to_install",
7010
+ message: "Desktop update is downloaded and verified.",
7011
+ percent: 100
7012
+ });
7013
+ await waitForDesktopApplySignal();
7014
+ writeDesktopProgress({
7015
+ phase: "preparing_restart",
7016
+ message: "Applying Desktop update..."
7017
+ });
7018
+ }
6781
7019
  await runStartPhase(
6782
7020
  "Replacing existing Rudder Desktop if needed...",
6783
7021
  "Existing Desktop install is ready for replacement.",
6784
- () => prepareForDesktopReplace(installPaths, target, { waitForActiveRuns: opts.waitForActiveRuns === true })
7022
+ () => prepareForDesktopReplace(installPaths, target, { waitForActiveRuns: opts.waitForActiveRuns === true }),
7023
+ desktopProgressJson ? opts.waitForActiveRuns === true ? "waiting_for_active_runs" : "preparing_restart" : null
6785
7024
  );
6786
7025
  await runStartPhase(
6787
7026
  "Installing portable Desktop app...",
6788
7027
  `Installed Rudder Desktop to ${pc8.cyan(installPaths.appPath)}.`,
6789
- () => installPortableDesktop(installerPath, installPaths, target)
7028
+ () => installPortableDesktop(installerPath, installPaths, target),
7029
+ desktopProgressJson ? "preparing_restart" : null
6790
7030
  );
6791
7031
  await runStartPhase(
6792
7032
  "Preparing Desktop launchers...",
@@ -6794,7 +7034,8 @@ async function startCommand(opts) {
6794
7034
  async () => {
6795
7035
  await removeMacQuarantine(installPaths, target);
6796
7036
  await createPlatformLaunchers(installPaths, target);
6797
- }
7037
+ },
7038
+ desktopProgressJson ? "preparing_restart" : null
6798
7039
  );
6799
7040
  await writeInstallMetadata(installPaths, releaseTag, asset.name, checksum);
6800
7041
  }
@@ -6802,7 +7043,8 @@ async function startCommand(opts) {
6802
7043
  await runStartPhase(
6803
7044
  "Launching Rudder Desktop...",
6804
7045
  "Rudder Desktop launched.",
6805
- () => launchDesktop(installPaths, target)
7046
+ () => launchDesktop(installPaths, target),
7047
+ desktopProgressJson ? "closing" : null
6806
7048
  );
6807
7049
  }
6808
7050
  }
@@ -11357,7 +11599,7 @@ function createProgram() {
11357
11599
  });
11358
11600
  loadRudderEnvFile(options.config);
11359
11601
  });
11360
- program.command("start").description("Start Rudder Desktop and prepare the matching persistent CLI").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("--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("--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);
11602
+ program.command("start").description("Start Rudder Desktop and prepare the matching persistent CLI").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("--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("--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);
11361
11603
  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);
11362
11604
  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) => {
11363
11605
  await doctor(opts);