@nomac/cli 0.11.2 → 0.11.4
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/package.json +1 -1
- package/src/hosted-sessions.mjs +9 -5
- package/src/session-ssh.mjs +7 -1
- package/src/session-transfer.mjs +3 -0
- package/src/sessions.mjs +2 -2
package/package.json
CHANGED
package/src/hosted-sessions.mjs
CHANGED
|
@@ -4,8 +4,8 @@ import { join, resolve } from "node:path";
|
|
|
4
4
|
import { parseArgs } from "node:util";
|
|
5
5
|
import { api, CliError } from "./api.mjs";
|
|
6
6
|
import { sessionStore } from "./session-store.mjs";
|
|
7
|
-
import { forwardingArg, runProcess, sshArgs, workspaceCommand } from "./session-ssh.mjs";
|
|
8
|
-
import { pullProject, syncProject } from "./session-transfer.mjs";
|
|
7
|
+
import { forwardingArg, isShellLine, runProcess, sshArgs, workspaceCommand } from "./session-ssh.mjs";
|
|
8
|
+
import { describePull, describeSync, pullProject, syncProject } from "./session-transfer.mjs";
|
|
9
9
|
import { macRequest, sessionId, transportOptions } from "./mac-transport.mjs";
|
|
10
10
|
import { copyToClipboard, desktop, DESKTOP_HELP, screenSharing } from "./desktop.mjs";
|
|
11
11
|
import { screenshot, startRecording, stopRecording } from "./mac-screen.mjs";
|
|
@@ -386,7 +386,7 @@ export async function hostedSessionCommand(command, argv, { store = sessionStore
|
|
|
386
386
|
// A command may run an hour (the gateway's limit); waiting can cover all of it.
|
|
387
387
|
const waitFor = integer(values.wait, 30, 0, 3600);
|
|
388
388
|
const timeout = integer(values.timeout, values["request-key"] === undefined ? Math.max(300, waitFor) : 600, 1, 3600);
|
|
389
|
-
method = "POST"; path = `${base}/jobs`; params = { requestKey: values["request-key"] ?? `cli-${randomUUID()}`, body: { argv: positionals, timeout_seconds: timeout } };
|
|
389
|
+
method = "POST"; path = `${base}/jobs`; params = { requestKey: values["request-key"] ?? `cli-${randomUUID()}`, body: { argv: isShellLine(positionals) ? ["/bin/bash", "-lc", positionals[0]] : positionals, timeout_seconds: timeout } };
|
|
390
390
|
} else {
|
|
391
391
|
if (positionals.length !== 1 || !/^job_[a-f0-9]{40}$/.test(positionals[0])) throw new CliError("Supply the existing job ID.");
|
|
392
392
|
path = `${base}/jobs/${positionals[0]}`;
|
|
@@ -583,11 +583,15 @@ export async function hostedSessionCommand(command, argv, { store = sessionStore
|
|
|
583
583
|
await ready(local);
|
|
584
584
|
if (command === "sync") {
|
|
585
585
|
if (positionals.length > 1 || (positionals[0] && resolve(positionals[0]) !== store.project)) throw new CliError("Run nomac sync . from the attached project.");
|
|
586
|
-
|
|
586
|
+
const result = await syncProject(local, store, { overwrite: values.overwrite, dryRun: values["dry-run"], run });
|
|
587
|
+
if (!values.json) { print(describeSync(result)); return result; }
|
|
588
|
+
return output(result);
|
|
587
589
|
}
|
|
588
590
|
if (command === "pull") {
|
|
589
591
|
if (positionals.length !== 1) throw new CliError("Usage: nomac pull LOCAL_PATH [--from REMOTE_PATH]");
|
|
590
|
-
|
|
592
|
+
const result = await pullProject(local, store, positionals[0], { from: values.from ?? positionals[0], overwrite: values.overwrite, dryRun: values["dry-run"], run });
|
|
593
|
+
if (!values.json) { print(describePull(result)); return result; }
|
|
594
|
+
return output(result);
|
|
591
595
|
}
|
|
592
596
|
throw new CliError("Unknown cloud session command.");
|
|
593
597
|
});
|
package/src/session-ssh.mjs
CHANGED
|
@@ -127,8 +127,14 @@ export async function prepareWorkspace(session, options) {
|
|
|
127
127
|
return { workspace, capabilities: { os: "macOS", version: osVersion, architecture, administrator: admin, available_disk_bytes: Number(availableKb) * 1024 } };
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
+
/**
|
|
131
|
+
* One argument with spaces or shell syntax is a shell command line, as ssh host 'a; b' runs it;
|
|
132
|
+
* several are a program and its arguments, passed exactly.
|
|
133
|
+
*/
|
|
134
|
+
export const isShellLine = (args) => args.length === 1 && /[\s;&|<>()$`*?{}~#'"\\]/.test(args[0]);
|
|
135
|
+
|
|
130
136
|
export function workspaceCommand(session, args = []) {
|
|
131
|
-
const command = args.length ? args.map(shellQuote).join(" ")
|
|
137
|
+
const command = !args.length ? '"$SHELL" -l' : isShellLine(args) ? `"$SHELL" -lc ${shellQuote(args[0])}` : args.map(shellQuote).join(" ");
|
|
132
138
|
return `cd ${shellQuote(validateWorkspace(session.workspace))} && exec ${command}`;
|
|
133
139
|
}
|
|
134
140
|
|
package/src/session-transfer.mjs
CHANGED
|
@@ -186,6 +186,9 @@ export function describeSync(result) {
|
|
|
186
186
|
return lines.join("\n");
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
+
/** The human summary of a pull. */
|
|
190
|
+
export const describePull = (result) => `${result.dry_run ? "Would retrieve" : "Retrieved"} ${result.changed.length} changed files (${result.files} considered).${result.recovery_directory ? `\nPrevious local files: ${result.recovery_directory}` : ""}`;
|
|
191
|
+
|
|
189
192
|
const transferEnv = (session, remoteDirectory = ".") => ({ ...process.env, NOMAC_TRANSFER_SESSION: JSON.stringify({ ...session, remoteDirectory }) });
|
|
190
193
|
|
|
191
194
|
function conflictError(paths, side) {
|
package/src/sessions.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { parseArgs } from "node:util";
|
|
|
5
5
|
import { CliError } from "./api.mjs";
|
|
6
6
|
import { sessionStore } from "./session-store.mjs";
|
|
7
7
|
import { forwardingArg, prepareWorkspace, runProcess, shellQuote, sshArgs, validateTarget, workspaceCommand } from "./session-ssh.mjs";
|
|
8
|
-
import { describeSync, pullProject, syncProject } from "./session-transfer.mjs";
|
|
8
|
+
import { describePull, describeSync, pullProject, syncProject } from "./session-transfer.mjs";
|
|
9
9
|
|
|
10
10
|
export const SESSION_HELP = `Nomac 2.0 — SSH workspace preview
|
|
11
11
|
|
|
@@ -137,7 +137,7 @@ export async function sessionCommand(command, argv, { store: suppliedStore, run
|
|
|
137
137
|
if (command === "pull") {
|
|
138
138
|
if (positionals.length !== 1) throw new CliError("pull usage", "Usage: nomac pull LOCAL_DIRECTORY [--from REMOTE_DIRECTORY] [--dry-run] [--overwrite]");
|
|
139
139
|
const result = await pullProject(session, store, positionals[0], { from: values.from ?? positionals[0], overwrite: values.overwrite, dryRun: values["dry-run"], run });
|
|
140
|
-
return output(result,
|
|
140
|
+
return output(result, describePull(result));
|
|
141
141
|
}
|
|
142
142
|
throw new CliError("unknown session command");
|
|
143
143
|
});
|