runcloud 0.1.113 → 0.1.115

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.
@@ -1,7 +1,7 @@
1
1
  import { spawn, spawnSync } from 'node:child_process';
2
2
  import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync, } from 'node:fs';
3
3
  import { homedir, hostname as localHostname } from 'node:os';
4
- import { join } from 'node:path';
4
+ import { dirname, join } from 'node:path';
5
5
  import WebSocket, { createWebSocketStream } from 'ws';
6
6
  import { ApiClient, friendlyApiError } from '../api.js';
7
7
  import { requireCredentials } from '../config.js';
@@ -85,6 +85,22 @@ function sshHome() {
85
85
  function keyPath() {
86
86
  return join(sshHome(), 'id_ed25519');
87
87
  }
88
+ function sshConfigPath() {
89
+ return join(homedir(), '.ssh', 'config');
90
+ }
91
+ export function sshCommandArgs(configPath, alias, command = []) {
92
+ return ['-F', configPath, alias, ...command];
93
+ }
94
+ export function scpCommandArgs(configPath, recursive, source, destination) {
95
+ return [
96
+ '-F',
97
+ configPath,
98
+ ...(recursive ? ['-r'] : []),
99
+ '--',
100
+ source,
101
+ destination,
102
+ ];
103
+ }
88
104
  function exec(command, args) {
89
105
  return new Promise((resolve, reject) => {
90
106
  const child = spawn(command, args, { stdio: 'inherit' });
@@ -119,8 +135,8 @@ function sshAlias(box) {
119
135
  return `runcloud-${box.name}`;
120
136
  }
121
137
  function writeSshConfig(box, privateKey) {
122
- const sshDir = join(homedir(), '.ssh');
123
- const configPath = join(sshDir, 'config');
138
+ const configPath = sshConfigPath();
139
+ const sshDir = dirname(configPath);
124
140
  mkdirSync(sshDir, { recursive: true, mode: 0o700 });
125
141
  const current = existsSync(configPath) ? readFileSync(configPath, 'utf8') : '';
126
142
  const start = `# BEGIN RUN CLOUD ${box.id}`;
@@ -147,7 +163,7 @@ async function setupSsh(reference) {
147
163
  const client = api();
148
164
  const box = await resolveBox(client, reference);
149
165
  const privateKey = await ensureSshKey(client, box);
150
- return { box, alias: writeSshConfig(box, privateKey) };
166
+ return { box, alias: writeSshConfig(box, privateKey), configPath: sshConfigPath() };
151
167
  }
152
168
  function output(value, opts) {
153
169
  if (opts.json)
@@ -221,7 +237,7 @@ export function registerAccessCommands(parent, opts = {}) {
221
237
  note('ssh');
222
238
  return action(async () => {
223
239
  const configured = await setupSsh(reference);
224
- const code = await exec('ssh', [configured.alias, ...command]);
240
+ const code = await exec('ssh', sshCommandArgs(configured.configPath, configured.alias, command));
225
241
  if (code !== 0)
226
242
  process.exitCode = code;
227
243
  });
@@ -252,12 +268,7 @@ export function registerAccessCommands(parent, opts = {}) {
252
268
  }
253
269
  const configured = await setupSsh(reference);
254
270
  const remote = (path) => path.startsWith(':') ? `${configured.alias}:${path.slice(1)}` : path;
255
- const args = [
256
- ...(cmdOpts.recursive ? ['-r'] : []),
257
- '--',
258
- remote(source),
259
- remote(destination),
260
- ];
271
+ const args = scpCommandArgs(configured.configPath, cmdOpts.recursive === true, remote(source), remote(destination));
261
272
  const code = await exec('scp', args);
262
273
  if (code !== 0)
263
274
  process.exitCode = code;
@@ -736,6 +736,9 @@ async function createSimulatorSession(platform, opts) {
736
736
  function registerSimulatorCommands(program, platform) {
737
737
  const label = platform === 'android' ? 'Android emulator' : 'iOS simulator';
738
738
  const article = platform === 'android' ? 'an' : 'an';
739
+ const orientationHelp = platform === 'ios'
740
+ ? 'portrait, landscape_left, or landscape_right; portrait_upside_down returns unsupported_action on iPhone Simulator sessions'
741
+ : 'portrait, portrait_upside_down, landscape_left, or landscape_right';
739
742
  const simulator = program
740
743
  .command(platform)
741
744
  .description(`Create, inspect, interact with, capture, and release ${label} sessions`);
@@ -864,7 +867,7 @@ function registerSimulatorCommands(program, platform) {
864
867
  .command('rotate')
865
868
  .description(`Set the absolute display orientation for ${article} ${label} session`)
866
869
  .argument('<id>', 'session id')
867
- .argument('<orientation>', 'portrait, portrait_upside_down, landscape_left, or landscape_right')).action((id, rawOrientation, opts) => action(() => runSimulatorInteraction(platform, id, {
870
+ .argument('<orientation>', orientationHelp)).action((id, rawOrientation, opts) => action(() => runSimulatorInteraction(platform, id, {
868
871
  action: 'rotate',
869
872
  orientation: simulatorOrientation(rawOrientation),
870
873
  }, opts), opts));
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const CLI_VERSION = '0.1.113';
1
+ export const CLI_VERSION = '0.1.115';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "runcloud",
3
- "version": "0.1.113",
3
+ "version": "0.1.115",
4
4
  "description": "Create and control run.cloud remote mobile simulators and cloud sandboxes",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
Binary file
@@ -76,6 +76,10 @@ not support Digital Crown input, and Android does not support iOS render-debug
76
76
  controls or the `capsLock`, `numLock`, and `scrollLock` keys. Handle structured
77
77
  `unsupported_action` errors instead of retrying them.
78
78
 
79
+ Current iPhone Simulator sessions support `portrait`, `landscape_left`, and
80
+ `landscape_right`. The shared `portrait_upside_down` value is supported on
81
+ Android and returns a non-retryable `unsupported_action` on iOS.
82
+
79
83
  An acknowledgement means input dispatch completed. Confirm visible app effects
80
84
  with a screenshot or the signed viewer when the outcome matters.
81
85
 
Binary file