rnxsim 0.1.469 → 0.1.471

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.
Files changed (61) hide show
  1. package/README.md +5 -1
  2. package/cli/command-registry.ts +1 -0
  3. package/cli/commands/daemon-mac-app.ts +3 -1
  4. package/cli/commands/daemon.ts +3 -1
  5. package/cli/commands/inspect/actions.ts +7 -2
  6. package/cli/commands/inspect.ts +12 -3
  7. package/cli/commands/install-cli.ts +275 -0
  8. package/cli/main.ts +6 -0
  9. package/dist-lib/agent-daemon-client.cjs +1 -1
  10. package/dist-lib/agent-events.cjs +1 -1
  11. package/dist-lib/agent-identity.cjs +1 -1
  12. package/dist-lib/agent-sessions.cjs +1 -1
  13. package/dist-lib/attached-projects.cjs +1 -1
  14. package/dist-lib/auth/shared-session.cjs +1 -1
  15. package/dist-lib/backend-origin.cjs +1 -1
  16. package/dist-lib/beta.cjs +1 -1
  17. package/dist-lib/beta.mjs +1 -1
  18. package/dist-lib/bridge-constants.cjs +1 -1
  19. package/dist-lib/bridge-contract-input.cjs +1 -1
  20. package/dist-lib/bridge-contract-input.mjs +1 -1
  21. package/dist-lib/bridge-contract.cjs +1 -1
  22. package/dist-lib/bridge-contract.mjs +1 -1
  23. package/dist-lib/capture-contract.cjs +1 -1
  24. package/dist-lib/capture-contract.mjs +1 -1
  25. package/dist-lib/cli-constants.cjs +1 -1
  26. package/dist-lib/cloud-contract.cjs +1 -1
  27. package/dist-lib/cloud-contract.mjs +1 -1
  28. package/dist-lib/cloud.cjs +1 -1
  29. package/dist-lib/cloud.mjs +1 -1
  30. package/dist-lib/config.cjs +1 -1
  31. package/dist-lib/detox/index.cjs +1 -1
  32. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  33. package/dist-lib/home-paths.cjs +1 -1
  34. package/dist-lib/host/bridge-host.cjs +6 -2
  35. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  36. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  37. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  38. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  39. package/dist-lib/host/websocket-proxy.cjs +1 -1
  40. package/dist-lib/index.cjs +5 -4
  41. package/dist-lib/jump-to-source-babel.cjs +1 -1
  42. package/dist-lib/jump-to-source-native.cjs +1 -1
  43. package/dist-lib/menu.cjs +1 -1
  44. package/dist-lib/menu.mjs +1 -1
  45. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  46. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  47. package/dist-lib/metro-production-bundle.cjs +1 -1
  48. package/dist-lib/metro-production-bundle.mjs +1 -1
  49. package/dist-lib/metro.cjs +1 -1
  50. package/dist-lib/profiles.cjs +1 -1
  51. package/dist-lib/public-brand.cjs +1 -1
  52. package/dist-lib/react-native-host-modules.cjs +1 -1
  53. package/dist-lib/react-native-host-modules.mjs +1 -1
  54. package/dist-lib/render-mode.cjs +1 -1
  55. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  56. package/dist-lib/sdk.cjs +5 -4
  57. package/dist-lib/sdk.mjs +5 -4
  58. package/dist-lib/skills.cjs +853 -5
  59. package/dist-lib/vite.cjs +1 -1
  60. package/package.json +1 -1
  61. package/src/host/bridge-host.ts +5 -1
package/README.md CHANGED
@@ -252,7 +252,11 @@ daemon is reachable. The background service is strongly recommended for local
252
252
  agent work because inspect, interaction, and test commands reuse one ready bridge
253
253
  and runtime. Enable it at any time with `rnx daemon install`; it is never required
254
254
  in CI. The packaged Desktop app is optional and available through first-run
255
- onboarding or `rnx desktop install`. Native Electron windows created by `rnx open` belong to that CLI
255
+ onboarding or `rnx desktop install`. A downloaded app starts its own bundled
256
+ daemon on first launch, then offers **Install the rnx command** over the running
257
+ simulator. That action installs `~/.local/bin/rnx`, updates shell startup, and
258
+ hands the daemon to launchd or systemd without reloading the window. Windows
259
+ keeps the desktop-owned daemon because it has no daemon service yet. Native Electron windows created by `rnx open` belong to that CLI
256
260
  session and close when the session exits; `rnx desktop` keeps the persistent
257
261
  desktop-app lifecycle. In Electron, `File > New Window`
258
262
  duplicates the focused simulator, while `File > New Simulator >` opens a new
@@ -50,6 +50,7 @@ const NODE_COMMAND_NAMES = [
50
50
  'login',
51
51
  'logout',
52
52
  'auth',
53
+ 'cli',
53
54
  'setup',
54
55
  'serve',
55
56
  'daemon',
@@ -135,6 +135,8 @@ function renderLauncherScript(
135
135
  const quoted = parts.map(shellSingleQuote).join(' ')
136
136
  const stdout = shellSingleQuote(logDir.stdout)
137
137
  const stderr = shellSingleQuote(logDir.stderr)
138
+ const rnxHome = process.env.RNX_HOME
139
+ const environment = rnxHome ? `export RNX_HOME=${shellSingleQuote(rnxHome)}\n` : ''
138
140
  return `#!/bin/sh
139
141
  # rnx daemon launcher generated by 'rnx daemon install'.
140
142
  # launchd spawns this; we exec the real rnx invocation in place so
@@ -152,7 +154,7 @@ for log_path in ${stdout} ${stderr}; do
152
154
  fi
153
155
  fi
154
156
  done
155
- exec ${quoted}
157
+ ${environment}exec ${quoted}
156
158
  `
157
159
  }
158
160
 
@@ -148,13 +148,15 @@ ${programArgs}
148
148
  function renderSystemdUnit(invocation: RnxSelfInvocation, port: number): string {
149
149
  mkdirSync(LOG_DIR_LINUX, { recursive: true })
150
150
  const exec = [invocation.executable, ...invocation.prefixArgs].map(shellQuote).join(' ')
151
+ const rnxHome = process.env.RNX_HOME
152
+ const environment = rnxHome ? `Environment=${shellQuote(`RNX_HOME=${rnxHome}`)}\n` : ''
151
153
  return `[Unit]
152
154
  Description=rnx bridge daemon
153
155
  After=default.target
154
156
 
155
157
  [Service]
156
158
  Type=simple
157
- ExecStart=${exec} serve --quiet --port ${port}
159
+ ${environment}ExecStart=${exec} serve --quiet --port ${port}
158
160
  Restart=always
159
161
  RestartSec=${RESPAWN_THROTTLE_SECONDS}
160
162
 
@@ -329,16 +329,21 @@ interface TextCandidate {
329
329
  ancestorTestIDs: string[]
330
330
  }
331
331
 
332
+ // a node repeating the text of its nearest labelled ancestor is that ancestor's
333
+ // own caption (a pressable and its text child), so only the outer node is a
334
+ // candidate. otherwise every labelled button is an ambiguous pair.
332
335
  function collectTextCandidates(
333
336
  nodes: readonly SimSemanticNode[],
334
337
  ancestors: string[] = [],
338
+ ownerText = '',
335
339
  ): TextCandidate[] {
336
340
  const out: TextCandidate[] = []
337
341
  for (const node of nodes) {
338
- out.push({ node, ancestorTestIDs: ancestors })
342
+ const text = nodeText(node)
343
+ if (!text || text !== ownerText) out.push({ node, ancestorTestIDs: ancestors })
339
344
  if (node.children?.length) {
340
345
  const next = node.testID ? [...ancestors, node.testID] : ancestors
341
- out.push(...collectTextCandidates(node.children, next))
346
+ out.push(...collectTextCandidates(node.children, next, text || ownerText))
342
347
  }
343
348
  }
344
349
  return out
@@ -1297,9 +1297,18 @@ export async function runInspect(args: string[], opts: InspectOptions) {
1297
1297
  // dialog button tap missed and the scrim under it answered the press.
1298
1298
  if (b.plane === 'cloud') {
1299
1299
  try {
1300
- await b.send({ type: 'settle' })
1301
- } catch {
1302
- // best-effort never fail the command because of a post-wait probe.
1300
+ // a cloud settle drains the whole transition in the sim rather than
1301
+ // polling from here, so it gets a transport deadline, not the browser
1302
+ // path's poll cap: a full screen transition is seconds of cpu render.
1303
+ await b.send({ type: 'settle' }, { timeoutMs: 15_000 })
1304
+ } catch (error) {
1305
+ // the write itself already landed, so this never fails the command.
1306
+ // it does have to be said out loud: a swallowed settle looks exactly
1307
+ // like a settled sim to the next read, and that read then hands out
1308
+ // coordinates the screen is still animating away from.
1309
+ process.stderr.write(
1310
+ ` ⚠ auto-settle failed (${error instanceof Error ? error.message : String(error)}) — next command may see mid-animation state. use \`rnx do settle\` to retry.\n`,
1311
+ )
1303
1312
  }
1304
1313
  return
1305
1314
  }
@@ -0,0 +1,275 @@
1
+ // installs the standalone rnx executable into the user's command path.
2
+ //
3
+ // the public shell installer owns download and checksum verification. this
4
+ // command mirrors its local mutation after those bytes are trusted, while the
5
+ // desktop app copies its bundled executable without a network download.
6
+
7
+ import { spawnSync } from 'node:child_process'
8
+ import {
9
+ appendFileSync,
10
+ chmodSync,
11
+ copyFileSync,
12
+ existsSync,
13
+ mkdirSync,
14
+ readFileSync,
15
+ renameSync,
16
+ unlinkSync,
17
+ } from 'node:fs'
18
+ import { createServer } from 'node:net'
19
+ import { homedir } from 'node:os'
20
+ import { dirname, join } from 'node:path'
21
+ import { isDaemonLockfileFresh, readDaemonLockfile } from '../../src/home-paths'
22
+ import { IS_STANDALONE } from '../standalone'
23
+
24
+ const INSTALL_WAIT_MS = 10_000
25
+
26
+ type CliInstallOptions = {
27
+ alreadyInstalled: boolean
28
+ handoffPid: number | null
29
+ port: number | null
30
+ }
31
+
32
+ export async function runCliInstall(args: string[]): Promise<void> {
33
+ const options = parseCliInstallOptions(args)
34
+ if (!IS_STANDALONE) {
35
+ throw new Error('rnx cli install requires the standalone rnx executable')
36
+ }
37
+
38
+ const target = installedCliPath()
39
+ if (!options.alreadyInstalled) installCurrentExecutable(target)
40
+ else if (!existsSync(target)) {
41
+ throw new Error(`rnx cli install expected ${target} to exist`)
42
+ }
43
+
44
+ const profile = installCommandPath(target)
45
+ console.log(` command: ${target}`)
46
+ if (profile) console.log(` shell: ${profile}`)
47
+
48
+ if (options.handoffPid === null) return
49
+ if (process.platform === 'win32') {
50
+ console.log(' desktop daemon: remains app-owned on Windows')
51
+ return
52
+ }
53
+
54
+ await handOffDaemon({ target, pid: options.handoffPid, port: options.port })
55
+ }
56
+
57
+ function parseCliInstallOptions(args: string[]): CliInstallOptions {
58
+ const [subcommand] = args
59
+ if (subcommand === '--help' || subcommand === '-h') {
60
+ console.log(`\nrnx cli install - install the rnx command in your PATH
61
+
62
+ usage:
63
+ rnx cli install
64
+
65
+ internal options:
66
+ --installed update shell startup after an installer copied rnx
67
+ --handoff-pid <pid> replace this desktop-owned daemon with the service
68
+ --port <port> daemon bridge port to preserve during handoff
69
+ `)
70
+ process.exit(0)
71
+ }
72
+ if (subcommand !== 'install') {
73
+ throw new Error('usage: rnx cli install')
74
+ }
75
+
76
+ const handoffPid = readHandoffPid(args)
77
+ const port = readPort(args)
78
+ if (handoffPid !== null && port === null) {
79
+ throw new Error('--handoff-pid requires --port')
80
+ }
81
+ return {
82
+ alreadyInstalled: args.includes('--installed'),
83
+ handoffPid,
84
+ port,
85
+ }
86
+ }
87
+
88
+ function readHandoffPid(args: string[]): number | null {
89
+ const flag = '--handoff-pid'
90
+ const index = args.indexOf(flag)
91
+ if (index < 0) return null
92
+ const value = Number(args[index + 1])
93
+ if (!Number.isSafeInteger(value) || value < 2) {
94
+ throw new Error(`${flag} requires a process id`)
95
+ }
96
+ return value
97
+ }
98
+
99
+ function readPort(args: string[]): number | null {
100
+ const flag = '--port'
101
+ const index = args.indexOf(flag)
102
+ if (index < 0) return null
103
+ const value = Number(args[index + 1])
104
+ if (!Number.isInteger(value) || value < 1 || value > 65_535) {
105
+ throw new Error(`${flag} requires a port number`)
106
+ }
107
+ return value
108
+ }
109
+
110
+ function installedCliPath(): string {
111
+ const home = process.env.HOME || homedir()
112
+ const prefix = process.env.RNX_CLI_PREFIX || join(home, '.local')
113
+ return join(prefix, 'bin', process.platform === 'win32' ? 'rnx.exe' : 'rnx')
114
+ }
115
+
116
+ function installCurrentExecutable(target: string): void {
117
+ if (process.execPath === target) return
118
+ mkdirSync(dirname(target), { recursive: true })
119
+ const temporary = join(dirname(target), `.rnx-install-${process.pid}`)
120
+ try {
121
+ copyFileSync(process.execPath, temporary)
122
+ chmodSync(temporary, 0o755)
123
+ renameSync(temporary, target)
124
+ } finally {
125
+ try {
126
+ unlinkSync(temporary)
127
+ } catch {}
128
+ }
129
+ }
130
+
131
+ function installCommandPath(target: string): string | null {
132
+ if (process.platform === 'win32') {
133
+ const bin = dirname(target)
134
+ const pathValue = process.env.Path || process.env.PATH || ''
135
+ if (
136
+ !pathValue.split(';').some((entry) => entry.toLowerCase() === bin.toLowerCase())
137
+ ) {
138
+ const next = pathValue ? `${bin};${pathValue}` : bin
139
+ const result = spawnSync(
140
+ 'reg.exe',
141
+ [
142
+ 'add',
143
+ 'HKCU\\Environment',
144
+ '/v',
145
+ 'Path',
146
+ '/t',
147
+ 'REG_EXPAND_SZ',
148
+ '/d',
149
+ next,
150
+ '/f',
151
+ ],
152
+ { encoding: 'utf8' },
153
+ )
154
+ if (result.status !== 0) {
155
+ throw new Error(`could not add rnx to the user PATH: ${result.stderr.trim()}`)
156
+ }
157
+ }
158
+ return 'the user PATH'
159
+ }
160
+
161
+ const home = process.env.HOME || homedir()
162
+ const shell = process.env.SHELL || ''
163
+ const shellName = shell.endsWith('/zsh') ? 'zsh' : shell.endsWith('/bash') ? 'bash' : ''
164
+ const profile = join(
165
+ home,
166
+ shellName === 'zsh' ? '.zshrc' : shellName === 'bash' ? '.bashrc' : '.profile',
167
+ )
168
+ const bin = dirname(target)
169
+ const pathLine = `export PATH="${bin}:$PATH"`
170
+ const integration = shellName ? `eval "$(command rnx __shell-init ${shellName})"` : ''
171
+ const current = existsSync(profile) ? readFileSync(profile, 'utf8') : ''
172
+ if (current.includes(pathLine) && (!integration || current.includes(integration)))
173
+ return null
174
+
175
+ const additions = [
176
+ '',
177
+ '# added by the rnx installer; delete this block to remove rnx from your shell',
178
+ ...(current.includes(pathLine) ? [] : [pathLine]),
179
+ ...(integration && !current.includes(integration) ? [integration] : []),
180
+ ]
181
+ appendFileSync(profile, `${additions.join('\n')}\n`)
182
+ return profile
183
+ }
184
+
185
+ async function handOffDaemon({
186
+ target,
187
+ pid,
188
+ port,
189
+ }: {
190
+ target: string
191
+ pid: number
192
+ port: number | null
193
+ }): Promise<void> {
194
+ if (port === null) throw new Error('the desktop daemon did not report its port')
195
+ const deadline = Date.now() + INSTALL_WAIT_MS
196
+ try {
197
+ process.kill(pid, 'SIGTERM')
198
+ } catch (error) {
199
+ const code = error && typeof error === 'object' ? Reflect.get(error, 'code') : null
200
+ if (code !== 'ESRCH') throw error
201
+ }
202
+ await waitFor(
203
+ () => {
204
+ const lock = readDaemonLockfile()
205
+ return !isDaemonLockfileFresh(lock) || lock.pid !== pid
206
+ },
207
+ 'the desktop daemon to stop',
208
+ deadline,
209
+ )
210
+ await waitForPortToClose(port, deadline)
211
+
212
+ const result = spawnSync(
213
+ target,
214
+ ['--port', String(port), 'daemon', 'install', '--force'],
215
+ {
216
+ encoding: 'utf8',
217
+ timeout: Math.max(1, deadline - Date.now()),
218
+ env: {
219
+ ...process.env,
220
+ SOOTSIM_FORCE_DAEMON_INSTALL: '1',
221
+ },
222
+ },
223
+ )
224
+ if (result.status !== 0) {
225
+ throw new Error(
226
+ `could not register the rnx daemon: ${(result.stderr || result.stdout || 'unknown error').trim()}`,
227
+ )
228
+ }
229
+
230
+ await waitFor(
231
+ () => {
232
+ const lock = readDaemonLockfile()
233
+ return isDaemonLockfileFresh(lock) && lock.pid !== pid && lock.bridgePort === port
234
+ },
235
+ 'the installed rnx daemon to start',
236
+ deadline,
237
+ )
238
+ console.log(' desktop daemon: handed off to the installed rnx command')
239
+ }
240
+
241
+ async function waitFor(
242
+ condition: () => boolean,
243
+ description: string,
244
+ deadline: number,
245
+ ): Promise<void> {
246
+ while (Date.now() < deadline) {
247
+ if (condition()) return
248
+ await new Promise((resolve) => setTimeout(resolve, 100))
249
+ }
250
+ throw new Error(`timed out waiting for ${description}`)
251
+ }
252
+
253
+ async function waitForPortToClose(port: number, deadline: number): Promise<void> {
254
+ while (Date.now() < deadline) {
255
+ const available = await new Promise<boolean>((resolve, reject) => {
256
+ const server = createServer()
257
+ server.once('error', (error) => {
258
+ if ('code' in error && error.code === 'EADDRINUSE') {
259
+ resolve(false)
260
+ return
261
+ }
262
+ reject(error)
263
+ })
264
+ server.listen(port, '127.0.0.1', () => {
265
+ server.close((error) => {
266
+ if (error) reject(error)
267
+ else resolve(true)
268
+ })
269
+ })
270
+ })
271
+ if (available) return
272
+ await new Promise((resolve) => setTimeout(resolve, 100))
273
+ }
274
+ throw new Error(`timed out waiting for port ${port} to close`)
275
+ }
package/cli/main.ts CHANGED
@@ -561,6 +561,12 @@ try {
561
561
  break
562
562
  }
563
563
 
564
+ case 'cli': {
565
+ const { runCliInstall } = await import('./commands/install-cli')
566
+ await runCliInstall(parsed.commandArgs)
567
+ break
568
+ }
569
+
564
570
  case 'serve': {
565
571
  const { runServe } = await import('./commands/serve')
566
572
  await runServe(parsed.commandArgs, { port })
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
package/dist-lib/beta.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
package/dist-lib/beta.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/beta.ts
4
4
  var IS_BETA = true;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/bridge-contract.ts
4
4
  var SIM_LONG_PRESS_MAX_MS = 5e3;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/bridge-contract.ts
4
4
  var SIM_LONG_PRESS_DEFAULT_MS = 500;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/capture-contract.ts
4
4
  var RNX_SCREEN_CAPTURE_VERSION = 1;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/cloud-contract.ts
4
4
  var RNX_CLOUD_MAX_ARTIFACT_BYTES = 20 * 1024 * 1024;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  var __defProp = Object.defineProperty;
3
3
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
4
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -9526,7 +9526,11 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
9526
9526
  }
9527
9527
  startRuntimeUpdater() {
9528
9528
  if (!this.shouldWriteLockfile || this.runtimeUpdateTimer) return;
9529
- if (import_fs3.default.existsSync(import_path3.default.join(rnxHomeDir(), "runtime-update-disabled"))) return;
9529
+ if (import_fs3.default.existsSync(import_path3.default.join(rnxHomeDir(), "runtime-update-disabled"))) {
9530
+ this.bootstrapping = false;
9531
+ if (this.httpServer) this.writeLockfileSnapshot();
9532
+ return;
9533
+ }
9530
9534
  if (process.env.RNX_HOME && isSootsimDevCheckout() && !readActiveRuntime()) {
9531
9535
  return;
9532
9536
  }
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/host/fetch-proxy-overrides.ts
4
4
  var FETCH_PROXY_BROWSER_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.469 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.471 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;