@viraatdas/rudder 0.6.2 → 0.7.0

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/cloud.js ADDED
@@ -0,0 +1,515 @@
1
+ import { spawn } from "node:child_process";
2
+ import fsp from "node:fs/promises";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import { currentBranch, currentCommit, findRepoRoot } from "./git.js";
6
+ import { cloudAuthPath } from "./state.js";
7
+ import { ensureDir, expandHome, newRunId, nowIso, pathExists, readJson, runCommand, shortenHome, writeJson, } from "./util.js";
8
+ const DEFAULT_LOGIN_INTERVAL_MS = 2000;
9
+ const DEFAULT_LOGIN_TIMEOUT_MS = 5 * 60 * 1000;
10
+ const MAX_HOME_SECRET_SCAN_BYTES = 1024 * 1024;
11
+ const DEFAULT_HOME_PATHS = [
12
+ "~/.claude",
13
+ "~/.codex",
14
+ "~/.config/gh",
15
+ "~/.gitconfig",
16
+ "~/.npmrc",
17
+ "~/.vercel",
18
+ "~/.config/vercel",
19
+ "~/.config/hunk",
20
+ ];
21
+ const SECRET_PATH_PARTS = new Set([
22
+ ".aws",
23
+ ".ssh",
24
+ ".gnupg",
25
+ ".kube",
26
+ ".docker",
27
+ "keychains",
28
+ ]);
29
+ const SECRET_BASENAMES = new Set([
30
+ ".env",
31
+ ".env.local",
32
+ ".env.production",
33
+ ".env.development",
34
+ "id_rsa",
35
+ "id_ed25519",
36
+ "credentials",
37
+ "known_hosts",
38
+ ]);
39
+ export async function runCloudCommand(command, args, options = {}) {
40
+ const subcommand = args[0] ?? (command === "sail" ? "list" : "");
41
+ const rest = args.slice(1);
42
+ if (command === "cloud" && (!subcommand || subcommand === "help")) {
43
+ printCloudHelp();
44
+ return;
45
+ }
46
+ switch (subcommand) {
47
+ case "login":
48
+ await login(options);
49
+ return;
50
+ case "sail":
51
+ case "launch":
52
+ await launch(rest, options);
53
+ return;
54
+ case "list":
55
+ case "ls":
56
+ await listSails(options);
57
+ return;
58
+ case "onload":
59
+ await onload(rest, options);
60
+ return;
61
+ case "pause":
62
+ await mutateSail("pause", rest, options);
63
+ return;
64
+ case "resume":
65
+ await mutateSail("resume", rest, options);
66
+ return;
67
+ default:
68
+ await launch(command === "sail" ? args : [subcommand, ...rest], options);
69
+ return;
70
+ }
71
+ }
72
+ async function login(options) {
73
+ const client = await cloudClient({ requireToken: false });
74
+ const response = await client.request("/api/cli/login", {
75
+ method: "POST",
76
+ body: {
77
+ deviceName: os.hostname(),
78
+ client: "rudder",
79
+ },
80
+ });
81
+ const deviceCode = response.deviceCode;
82
+ const loginUrl = response.loginUrl ?? response.verificationUri ?? withQuery(client.baseUrl, "/cli/login", deviceCode ? { device_code: deviceCode } : {});
83
+ const pollPath = response.pollUrl ?? "/api/cli/login/poll";
84
+ const intervalMs = Math.max(1000, (response.interval ?? DEFAULT_LOGIN_INTERVAL_MS / 1000) * 1000);
85
+ const timeoutMs = Math.max(intervalMs, (response.expiresIn ?? DEFAULT_LOGIN_TIMEOUT_MS / 1000) * 1000);
86
+ console.log(`Opening ${loginUrl}`);
87
+ openBrowser(loginUrl);
88
+ console.log("Waiting for browser login to complete...");
89
+ const startedAt = Date.now();
90
+ while (Date.now() - startedAt < timeoutMs) {
91
+ await sleep(intervalMs);
92
+ const poll = await pollLogin(client, pollPath, deviceCode);
93
+ const token = poll.token ?? poll.accessToken;
94
+ if (token) {
95
+ await saveCloudAuth({
96
+ version: 1,
97
+ token,
98
+ cloudUrl: client.baseUrl,
99
+ accountId: poll.accountId,
100
+ email: poll.email,
101
+ expiresAt: poll.expiresAt ?? (poll.expiresIn ? new Date(Date.now() + poll.expiresIn * 1000).toISOString() : undefined),
102
+ updatedAt: nowIso(),
103
+ });
104
+ if (options.json) {
105
+ const result = { ok: true, cloudUrl: client.baseUrl };
106
+ if (poll.email) {
107
+ result.email = poll.email;
108
+ }
109
+ if (poll.accountId) {
110
+ result.accountId = poll.accountId;
111
+ }
112
+ printJson(result);
113
+ }
114
+ else {
115
+ console.log(`Logged in to ${client.baseUrl}${poll.email ? ` as ${poll.email}` : ""}.`);
116
+ }
117
+ return;
118
+ }
119
+ if (poll.pending === false) {
120
+ throw new Error("Cloud login was not approved.");
121
+ }
122
+ }
123
+ throw new Error("Timed out waiting for cloud login.");
124
+ }
125
+ async function launch(args, options) {
126
+ const task = args.join(" ").trim();
127
+ const repoRoot = findRepoRoot();
128
+ const snapshot = await createSnapshot(repoRoot, options.homePaths ?? []);
129
+ try {
130
+ const client = await cloudClient({ requireToken: true });
131
+ const body = {
132
+ repoName: path.basename(repoRoot),
133
+ snapshot: {
134
+ name: path.basename(snapshot.archivePath),
135
+ contentType: "application/gzip",
136
+ base64: await fsp.readFile(snapshot.archivePath, "base64"),
137
+ manifest: snapshot.manifest,
138
+ },
139
+ };
140
+ if (task) {
141
+ body.task = task;
142
+ }
143
+ const result = await client.request("/api/rudder/sail/launch", {
144
+ method: "POST",
145
+ body,
146
+ });
147
+ printResult(result, options);
148
+ }
149
+ finally {
150
+ await fsp.rm(snapshot.tempDir, { recursive: true, force: true });
151
+ }
152
+ }
153
+ async function onload(args, options) {
154
+ const runId = args[0];
155
+ if (!runId) {
156
+ throw new Error("Missing run id. Usage: rudder cloud onload <runId>");
157
+ }
158
+ const repoRoot = findRepoRoot();
159
+ const runRecord = await readJson(path.join(repoRoot, ".rudder", "runs", runId, "run.json"));
160
+ const worktreePath = runRecord && typeof runRecord === "object" && !Array.isArray(runRecord)
161
+ ? runRecord.worktree
162
+ : undefined;
163
+ const sourceRoot = worktreePath && typeof worktreePath === "object" && !Array.isArray(worktreePath)
164
+ ? worktreePath.path
165
+ : undefined;
166
+ const snapshotRoot = sourceRoot && await pathExists(sourceRoot) ? sourceRoot : repoRoot;
167
+ const snapshot = await createSnapshot(snapshotRoot, options.homePaths ?? []);
168
+ try {
169
+ const client = await cloudClient({ requireToken: true });
170
+ const result = await client.request("/api/rudder/sail/onload", {
171
+ method: "POST",
172
+ body: {
173
+ runId,
174
+ repoName: path.basename(repoRoot),
175
+ run: runRecord ?? null,
176
+ snapshot: {
177
+ name: path.basename(snapshot.archivePath),
178
+ contentType: "application/gzip",
179
+ base64: await fsp.readFile(snapshot.archivePath, "base64"),
180
+ manifest: snapshot.manifest,
181
+ },
182
+ },
183
+ });
184
+ printResult(result, options);
185
+ }
186
+ finally {
187
+ await fsp.rm(snapshot.tempDir, { recursive: true, force: true });
188
+ }
189
+ }
190
+ async function listSails(options) {
191
+ const client = await cloudClient({ requireToken: true });
192
+ const result = await client.request("/api/rudder/sail", { method: "GET" });
193
+ printResult(result, options);
194
+ }
195
+ async function mutateSail(action, args, options) {
196
+ const sailId = args[0];
197
+ if (!sailId) {
198
+ throw new Error(`Missing sail id. Usage: rudder sail ${action} <id>`);
199
+ }
200
+ const client = await cloudClient({ requireToken: true });
201
+ const result = await client.request(`/api/rudder/sail/${encodeURIComponent(sailId)}/${action}`, {
202
+ method: "POST",
203
+ body: args.length > 1 ? { args: args.slice(1) } : {},
204
+ });
205
+ printResult(result, options);
206
+ }
207
+ async function cloudClient(options) {
208
+ const baseUrl = normalizeCloudUrl(process.env.RUDDER_CLOUD_URL);
209
+ const state = await loadCloudAuth();
210
+ const envToken = process.env.RUDDER_CLOUD_TOKEN?.trim();
211
+ const token = envToken || (state?.cloudUrl === baseUrl ? state.token : undefined);
212
+ if (options.requireToken && !token) {
213
+ throw new Error("Not logged in to Rudder Cloud. Run `rudder cloud login` first.");
214
+ }
215
+ return {
216
+ baseUrl,
217
+ async request(pathOrUrl, init) {
218
+ const url = pathOrUrl.startsWith("http://") || pathOrUrl.startsWith("https://")
219
+ ? pathOrUrl
220
+ : new URL(pathOrUrl, `${baseUrl}/`).toString();
221
+ const headers = {
222
+ Accept: "application/json",
223
+ };
224
+ let body;
225
+ if (init.body !== undefined) {
226
+ headers["Content-Type"] = "application/json";
227
+ body = JSON.stringify(init.body);
228
+ }
229
+ if (token) {
230
+ headers.Authorization = `Bearer ${token}`;
231
+ }
232
+ const response = await fetch(url, {
233
+ method: init.method,
234
+ headers,
235
+ body,
236
+ });
237
+ const text = await response.text();
238
+ const parsed = text ? parseJson(text) : null;
239
+ if (!response.ok) {
240
+ const message = responseErrorMessage(parsed) ?? text.trim() ?? `${response.status} ${response.statusText}`;
241
+ throw new Error(`Rudder Cloud request failed: ${message}`);
242
+ }
243
+ return parsed;
244
+ },
245
+ };
246
+ }
247
+ function normalizeCloudUrl(raw) {
248
+ const value = raw?.trim();
249
+ if (!value) {
250
+ throw new Error("RUDDER_CLOUD_URL is not configured. Set it to your Rudder Cloud control plane URL.");
251
+ }
252
+ try {
253
+ const url = new URL(value);
254
+ if (url.protocol !== "http:" && url.protocol !== "https:") {
255
+ throw new Error("bad protocol");
256
+ }
257
+ url.hash = "";
258
+ url.search = "";
259
+ return url.toString().replace(/\/$/, "");
260
+ }
261
+ catch {
262
+ throw new Error("RUDDER_CLOUD_URL must be a valid http(s) URL.");
263
+ }
264
+ }
265
+ async function pollLogin(client, pollPath, deviceCode) {
266
+ if (pollPath.startsWith("http://") || pollPath.startsWith("https://") || !deviceCode) {
267
+ return await client.request(pollPath, { method: "GET" });
268
+ }
269
+ return await client.request(pollPath, {
270
+ method: "POST",
271
+ body: { deviceCode },
272
+ });
273
+ }
274
+ async function loadCloudAuth() {
275
+ const state = await readJson(cloudAuthPath());
276
+ return state?.version === 1 && typeof state.token === "string" ? state : null;
277
+ }
278
+ async function saveCloudAuth(state) {
279
+ await writeJson(cloudAuthPath(), state, { mode: 0o600 });
280
+ }
281
+ async function createSnapshot(repoRoot, requestedHomePaths) {
282
+ const tempDir = await fsp.mkdtemp(path.join(os.tmpdir(), "rudder-cloud-"));
283
+ const stageDir = path.join(tempDir, "snapshot");
284
+ const repoStage = path.join(stageDir, "repo");
285
+ const homeStage = path.join(stageDir, "home");
286
+ await ensureDir(repoStage);
287
+ await copyRepoFiles(repoRoot, repoStage);
288
+ const homePaths = normalizeHomePaths(requestedHomePaths);
289
+ const includedHomePaths = [];
290
+ for (const homePath of homePaths) {
291
+ const copied = await copyHomePath(homePath, homeStage);
292
+ if (copied) {
293
+ includedHomePaths.push(shortenHome(homePath));
294
+ }
295
+ }
296
+ const manifest = {
297
+ version: 1,
298
+ createdAt: nowIso(),
299
+ repo: {
300
+ root: path.basename(repoRoot),
301
+ branch: await currentBranch(repoRoot),
302
+ commit: await currentCommit(repoRoot),
303
+ },
304
+ homePaths: includedHomePaths,
305
+ };
306
+ await writeJson(path.join(stageDir, "manifest.json"), manifest);
307
+ const archivePath = path.join(tempDir, `${newRunId("cloud-snapshot")}.tgz`);
308
+ await runCommand("tar", ["-czf", archivePath, "-C", stageDir, "."], { cwd: stageDir });
309
+ return { tempDir, archivePath, manifest };
310
+ }
311
+ async function copyRepoFiles(repoRoot, repoStage) {
312
+ const result = await runCommand("git", ["ls-files", "-z", "--cached", "--others", "--exclude-standard"], {
313
+ cwd: repoRoot,
314
+ allowFailure: true,
315
+ });
316
+ const files = result.code === 0
317
+ ? result.stdout.split("\0").filter(Boolean)
318
+ : await listFiles(repoRoot);
319
+ for (const relative of files) {
320
+ if (!relative || relative.startsWith(".git/") || relative.startsWith(".rudder/")) {
321
+ continue;
322
+ }
323
+ const source = path.join(repoRoot, relative);
324
+ const target = path.join(repoStage, relative);
325
+ if (!isInside(repoRoot, source) || !isInside(repoStage, target)) {
326
+ continue;
327
+ }
328
+ const stat = await fsp.lstat(source).catch(() => null);
329
+ if (!stat || stat.isDirectory() || !(await shouldIncludeSnapshotPath(source))) {
330
+ continue;
331
+ }
332
+ await ensureDir(path.dirname(target));
333
+ await fsp.cp(source, target, { dereference: false, force: true });
334
+ }
335
+ }
336
+ async function listFiles(dir) {
337
+ const files = [];
338
+ async function walk(current) {
339
+ const entries = await fsp.readdir(current, { withFileTypes: true }).catch(() => []);
340
+ for (const entry of entries) {
341
+ if (entry.name === ".git" || entry.name === ".rudder" || entry.name === "node_modules") {
342
+ continue;
343
+ }
344
+ const full = path.join(current, entry.name);
345
+ if (entry.isDirectory()) {
346
+ await walk(full);
347
+ }
348
+ else {
349
+ files.push(path.relative(dir, full));
350
+ }
351
+ }
352
+ }
353
+ await walk(dir);
354
+ return files;
355
+ }
356
+ function normalizeHomePaths(requested) {
357
+ const raw = [
358
+ ...DEFAULT_HOME_PATHS,
359
+ ...requested,
360
+ ...(process.env.RUDDER_CLOUD_HOME_PATHS?.split(",") ?? []),
361
+ ];
362
+ const home = os.homedir();
363
+ const seen = new Set();
364
+ const paths = [];
365
+ for (const item of raw) {
366
+ const trimmed = item.trim();
367
+ if (!trimmed) {
368
+ continue;
369
+ }
370
+ const resolved = path.resolve(expandHome(trimmed));
371
+ if (!isInside(home, resolved) || seen.has(resolved)) {
372
+ continue;
373
+ }
374
+ seen.add(resolved);
375
+ paths.push(resolved);
376
+ }
377
+ return paths;
378
+ }
379
+ async function copyHomePath(source, homeStage) {
380
+ if (!(await pathExists(source)) || !(await shouldIncludeSnapshotPath(source))) {
381
+ return false;
382
+ }
383
+ const relative = path.relative(os.homedir(), source);
384
+ const target = path.join(homeStage, relative);
385
+ if (!isInside(homeStage, target)) {
386
+ return false;
387
+ }
388
+ await fsp.cp(source, target, {
389
+ dereference: false,
390
+ recursive: true,
391
+ force: true,
392
+ filter: async (candidate) => await shouldIncludeSnapshotPath(candidate),
393
+ });
394
+ return true;
395
+ }
396
+ async function shouldIncludeSnapshotPath(candidate) {
397
+ const normalized = path.resolve(candidate);
398
+ const parts = normalized.split(path.sep).map((part) => part.toLowerCase());
399
+ const basename = path.basename(normalized).toLowerCase();
400
+ if (parts.some((part) => SECRET_PATH_PARTS.has(part)) || SECRET_BASENAMES.has(basename)) {
401
+ return false;
402
+ }
403
+ const stat = await fsp.lstat(normalized).catch(() => null);
404
+ if (!stat || !stat.isFile() || stat.size > MAX_HOME_SECRET_SCAN_BYTES) {
405
+ return true;
406
+ }
407
+ const text = await fsp.readFile(normalized, "utf8").catch(() => "");
408
+ return !/(aws_access_key_id|aws_secret_access_key|aws_session_token|AWS_ACCESS_KEY_ID|AWS_SECRET_ACCESS_KEY|AWS_SESSION_TOKEN)/.test(text);
409
+ }
410
+ function isInside(parent, child) {
411
+ const relative = path.relative(path.resolve(parent), path.resolve(child));
412
+ return relative === "" || (!relative.startsWith("..") && !path.isAbsolute(relative));
413
+ }
414
+ function openBrowser(url) {
415
+ const platform = process.platform;
416
+ const command = platform === "darwin" ? "open" : platform === "win32" ? "cmd" : "xdg-open";
417
+ const args = platform === "win32" ? ["/c", "start", "", url] : [url];
418
+ const child = spawn(command, args, {
419
+ detached: true,
420
+ stdio: "ignore",
421
+ });
422
+ child.on("error", () => undefined);
423
+ child.unref();
424
+ }
425
+ function withQuery(baseUrl, pathname, query) {
426
+ const url = new URL(pathname, `${baseUrl}/`);
427
+ for (const [key, value] of Object.entries(query)) {
428
+ url.searchParams.set(key, value);
429
+ }
430
+ return url.toString();
431
+ }
432
+ function parseJson(text) {
433
+ try {
434
+ return JSON.parse(text);
435
+ }
436
+ catch {
437
+ return text;
438
+ }
439
+ }
440
+ function responseErrorMessage(value) {
441
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
442
+ return undefined;
443
+ }
444
+ const record = value;
445
+ return typeof record.error === "string"
446
+ ? record.error
447
+ : typeof record.message === "string"
448
+ ? record.message
449
+ : undefined;
450
+ }
451
+ function printResult(result, options) {
452
+ if (options.json) {
453
+ printJson(result);
454
+ return;
455
+ }
456
+ if (Array.isArray(result)) {
457
+ printSailList(result);
458
+ return;
459
+ }
460
+ if (result && typeof result === "object" && !Array.isArray(result)) {
461
+ const record = result;
462
+ const sails = record.sails ?? record.items;
463
+ if (Array.isArray(sails)) {
464
+ printSailList(sails);
465
+ return;
466
+ }
467
+ }
468
+ console.log(JSON.stringify(result, null, 2));
469
+ }
470
+ function printSailList(items) {
471
+ if (items.length === 0) {
472
+ console.log("No cloud sails.");
473
+ return;
474
+ }
475
+ for (const item of items) {
476
+ if (!item || typeof item !== "object" || Array.isArray(item)) {
477
+ console.log(String(item));
478
+ continue;
479
+ }
480
+ const sail = item;
481
+ console.log([
482
+ sail.id,
483
+ sail.status,
484
+ sail.branch,
485
+ sail.url,
486
+ sail.updatedAt ?? sail.createdAt,
487
+ ].filter(Boolean).join(" "));
488
+ }
489
+ }
490
+ function printJson(value) {
491
+ console.log(JSON.stringify(value, null, 2));
492
+ }
493
+ function sleep(ms) {
494
+ return new Promise((resolve) => setTimeout(resolve, ms));
495
+ }
496
+ function printCloudHelp() {
497
+ console.log(`rudder cloud
498
+
499
+ Usage:
500
+ rudder cloud login
501
+ rudder cloud <name or task>
502
+ rudder cloud launch [--home-path <path>] ["task"]
503
+ rudder cloud list
504
+ rudder cloud onload <runId>
505
+ rudder sail <name or task>
506
+ rudder sail list
507
+ rudder sail pause <id>
508
+ rudder sail resume <id>
509
+
510
+ Environment:
511
+ RUDDER_CLOUD_URL Cloud control plane URL
512
+ RUDDER_CLOUD_HOME_PATHS Extra comma-separated HOME paths to include in snapshots
513
+ `);
514
+ }
515
+ //# sourceMappingURL=cloud.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloud.js","sourceRoot":"","sources":["../src/cloud.ts"],"names":[],"mappings":"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"}
package/dist/main.js CHANGED
@@ -3,6 +3,7 @@ import fsp from "node:fs/promises";
3
3
  import path from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
5
  import { authStoreExists, runDoctor, runOnboard } from "./auth.js";
6
+ import { runCloudCommand } from "./cloud.js";
6
7
  import { findRepoRoot } from "./git.js";
7
8
  import { discoverModelOptions } from "./models.js";
8
9
  import { resolveNativeBinaryPath } from "./native-binary.js";
@@ -141,6 +142,19 @@ export async function main() {
141
142
  case "doctor":
142
143
  await runDoctor({ json: parsed.flags.json });
143
144
  return;
145
+ case "login":
146
+ await runCloudCommand("cloud", ["login", ...parsed.args], {
147
+ json: parsed.flags.json,
148
+ homePaths: parsed.flags.homePaths,
149
+ });
150
+ return;
151
+ case "cloud":
152
+ case "sail":
153
+ await runCloudCommand(parsed.command, parsed.args, {
154
+ json: parsed.flags.json,
155
+ homePaths: parsed.flags.homePaths,
156
+ });
157
+ return;
144
158
  case "run": {
145
159
  await maybeOnboard();
146
160
  const task = parsed.args.join(" ").trim();
@@ -343,6 +357,10 @@ function parseArgs(argv) {
343
357
  parsed.flags.tmuxSession = readValue(argv, ++i, arg);
344
358
  continue;
345
359
  }
360
+ if (takesValue(arg, "--home-path")) {
361
+ parsed.flags.homePaths = [...(parsed.flags.homePaths ?? []), readValue(argv, ++i, arg)];
362
+ continue;
363
+ }
346
364
  if (arg.startsWith("--model=")) {
347
365
  parsed.flags.model = arg.slice("--model=".length);
348
366
  continue;
@@ -367,6 +385,10 @@ function parseArgs(argv) {
367
385
  parsed.flags.tmuxSession = arg.slice("--tmux-session=".length);
368
386
  continue;
369
387
  }
388
+ if (arg.startsWith("--home-path=")) {
389
+ parsed.flags.homePaths = [...(parsed.flags.homePaths ?? []), arg.slice("--home-path=".length)];
390
+ continue;
391
+ }
370
392
  if (!parsed.command && !arg.startsWith("-")) {
371
393
  parsed.command = arg;
372
394
  continue;
@@ -538,6 +560,11 @@ Usage:
538
560
  rudder run [options] "task"
539
561
  rudder claude [options] "task"
540
562
  rudder codex [options] "task"
563
+ rudder login
564
+ rudder cloud <name or task>
565
+ rudder cloud list
566
+ rudder cloud onload <runId>
567
+ rudder sail <name or task>
541
568
 
542
569
  Run management:
543
570
  rudder watch [run] Attach to live output
@@ -553,6 +580,14 @@ Setup:
553
580
  rudder onboard
554
581
  rudder doctor [--json]
555
582
 
583
+ Cloud:
584
+ rudder login Open browser login and store cloud token
585
+ rudder cloud list List cloud workers/runs
586
+ rudder cloud onload <runId> Move a local Rudder run to cloud
587
+ rudder cloud pause <id> Pause an idle cloud worker
588
+ rudder cloud resume <id> Resume a cloud worker
589
+ rudder sail <name or task> Alias for starting a cloud worker
590
+
556
591
  Options:
557
592
  -d, --detach Start in background
558
593
  --worktree Always isolate in a git worktree
@@ -563,6 +598,7 @@ Options:
563
598
  --no-tmux Use the legacy TUI for bare rudder
564
599
  --no-native Use the tmux dashboard instead of native
565
600
  --headless Alias for --no-tmux on bare rudder
601
+ --home-path <path> Include extra HOME path in cloud snapshot
566
602
  --json Machine-readable output
567
603
  -v, --version Print version
568
604
  --allow-dirty Allow merge into dirty target branch