peachsim 0.1.527

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 (324) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +640 -0
  3. package/cli/app-config.ts +82 -0
  4. package/cli/app-fonts.ts +388 -0
  5. package/cli/app-project.ts +59 -0
  6. package/cli/app-splash.ts +171 -0
  7. package/cli/app-state-reset.ts +26 -0
  8. package/cli/auth.ts +184 -0
  9. package/cli/bin.ts +59 -0
  10. package/cli/bridge-diagnostics.ts +226 -0
  11. package/cli/bridge-flow-runner.ts +2806 -0
  12. package/cli/browser-backend.ts +44 -0
  13. package/cli/browser-evals.ts +96 -0
  14. package/cli/cli-update.ts +261 -0
  15. package/cli/cloud-client.ts +1530 -0
  16. package/cli/cloud-dispatch.ts +206 -0
  17. package/cli/cloud-session.ts +227 -0
  18. package/cli/command-contract.ts +221 -0
  19. package/cli/command-registry.ts +304 -0
  20. package/cli/commands/agent-wrapper.ts +1048 -0
  21. package/cli/commands/agent.ts +439 -0
  22. package/cli/commands/app-fonts.ts +99 -0
  23. package/cli/commands/assert.ts +542 -0
  24. package/cli/commands/auth.ts +71 -0
  25. package/cli/commands/box/bundle-plane.ts +71 -0
  26. package/cli/commands/box/checkout-plane.ts +256 -0
  27. package/cli/commands/box/plane-share.ts +208 -0
  28. package/cli/commands/box/rnx-command.ts +60 -0
  29. package/cli/commands/box/search-command.ts +157 -0
  30. package/cli/commands/box.ts +925 -0
  31. package/cli/commands/camera.ts +266 -0
  32. package/cli/commands/cleanup.ts +169 -0
  33. package/cli/commands/compat.ts +176 -0
  34. package/cli/commands/config.ts +34 -0
  35. package/cli/commands/control.ts +2154 -0
  36. package/cli/commands/cpu-profile.ts +941 -0
  37. package/cli/commands/daemon-mac-app.ts +165 -0
  38. package/cli/commands/daemon.ts +800 -0
  39. package/cli/commands/debug.ts +751 -0
  40. package/cli/commands/desktop.ts +39 -0
  41. package/cli/commands/detect.ts +201 -0
  42. package/cli/commands/detox.ts +481 -0
  43. package/cli/commands/device.ts +134 -0
  44. package/cli/commands/diagnose.ts +589 -0
  45. package/cli/commands/do-chain.ts +408 -0
  46. package/cli/commands/electron.ts +94 -0
  47. package/cli/commands/film.ts +379 -0
  48. package/cli/commands/flow.ts +1240 -0
  49. package/cli/commands/inspect/actions.ts +516 -0
  50. package/cli/commands/inspect/core.ts +2086 -0
  51. package/cli/commands/inspect/count.ts +17 -0
  52. package/cli/commands/inspect/describe.ts +119 -0
  53. package/cli/commands/inspect/env.ts +25 -0
  54. package/cli/commands/inspect/find.ts +169 -0
  55. package/cli/commands/inspect/get-layout.ts +53 -0
  56. package/cli/commands/inspect/keyboard.ts +54 -0
  57. package/cli/commands/inspect/list.ts +175 -0
  58. package/cli/commands/inspect/memory.ts +215 -0
  59. package/cli/commands/inspect/redaction.ts +39 -0
  60. package/cli/commands/inspect/resolve-target.ts +77 -0
  61. package/cli/commands/inspect/screens.ts +78 -0
  62. package/cli/commands/inspect/settle.ts +32 -0
  63. package/cli/commands/inspect/settling.ts +197 -0
  64. package/cli/commands/inspect/shared.ts +259 -0
  65. package/cli/commands/inspect/sleep.ts +15 -0
  66. package/cli/commands/inspect/tree.ts +23 -0
  67. package/cli/commands/inspect/url.ts +17 -0
  68. package/cli/commands/inspect/wait-event.ts +211 -0
  69. package/cli/commands/inspect/wait-idle.ts +25 -0
  70. package/cli/commands/inspect/wait-ready.ts +87 -0
  71. package/cli/commands/inspect/wait-selector.ts +59 -0
  72. package/cli/commands/inspect/wait.ts +32 -0
  73. package/cli/commands/inspect.ts +4738 -0
  74. package/cli/commands/install-cli.ts +275 -0
  75. package/cli/commands/install-desktop.ts +385 -0
  76. package/cli/commands/login.ts +357 -0
  77. package/cli/commands/logout.ts +24 -0
  78. package/cli/commands/maestro-generate.ts +375 -0
  79. package/cli/commands/maestro.ts +536 -0
  80. package/cli/commands/mode.ts +58 -0
  81. package/cli/commands/no-bridge-hint.ts +80 -0
  82. package/cli/commands/perf.ts +67 -0
  83. package/cli/commands/permissions.ts +203 -0
  84. package/cli/commands/platform.ts +410 -0
  85. package/cli/commands/preview.ts +103 -0
  86. package/cli/commands/profile.ts +106 -0
  87. package/cli/commands/react.ts +353 -0
  88. package/cli/commands/record.ts +1435 -0
  89. package/cli/commands/report-issue.ts +305 -0
  90. package/cli/commands/reset.ts +89 -0
  91. package/cli/commands/runtime.ts +348 -0
  92. package/cli/commands/screenshot-command.ts +106 -0
  93. package/cli/commands/screenshot-layers.ts +144 -0
  94. package/cli/commands/screenshot-mode.ts +38 -0
  95. package/cli/commands/screenshot.ts +492 -0
  96. package/cli/commands/screenshots-capture.ts +608 -0
  97. package/cli/commands/screenshots.ts +127 -0
  98. package/cli/commands/serve.ts +139 -0
  99. package/cli/commands/setup.ts +416 -0
  100. package/cli/commands/shell-boolean-mode.ts +82 -0
  101. package/cli/commands/skills.ts +468 -0
  102. package/cli/commands/slides.ts +357 -0
  103. package/cli/commands/state.ts +94 -0
  104. package/cli/commands/storage.ts +58 -0
  105. package/cli/commands/telemetry.ts +55 -0
  106. package/cli/commands/test.ts +535 -0
  107. package/cli/commands/three-mode.ts +771 -0
  108. package/cli/commands/timeline.ts +121 -0
  109. package/cli/commands/upgrade.ts +167 -0
  110. package/cli/commands/upload.ts +1203 -0
  111. package/cli/commands/version.ts +63 -0
  112. package/cli/commands/welcome.ts +17 -0
  113. package/cli/commands/what-happened.ts +328 -0
  114. package/cli/current-sim.ts +217 -0
  115. package/cli/desktop-companion.ts +315 -0
  116. package/cli/drivers/electron.ts +70 -0
  117. package/cli/drivers/index.ts +20 -0
  118. package/cli/drivers/playwright-provisioning.ts +184 -0
  119. package/cli/drivers/playwright-sim-host.ts +537 -0
  120. package/cli/drivers/playwright.ts +209 -0
  121. package/cli/drivers/registry.ts +65 -0
  122. package/cli/drivers/types.ts +102 -0
  123. package/cli/flow-export.ts +55 -0
  124. package/cli/flow-file.ts +142 -0
  125. package/cli/flow-live-status.ts +126 -0
  126. package/cli/flow-session.ts +140 -0
  127. package/cli/help-core.ts +143 -0
  128. package/cli/help.ts +44 -0
  129. package/cli/hidden-runtime-alias.ts +19 -0
  130. package/cli/hints.ts +214 -0
  131. package/cli/inspect-notice-state.ts +114 -0
  132. package/cli/internal-child.ts +176 -0
  133. package/cli/maestro-js.ts +323 -0
  134. package/cli/main.ts +704 -0
  135. package/cli/open-url.ts +8 -0
  136. package/cli/outbound-endpoints.ts +830 -0
  137. package/cli/parent-pid.ts +204 -0
  138. package/cli/parse-args.ts +189 -0
  139. package/cli/privacy.ts +53 -0
  140. package/cli/prompt.ts +56 -0
  141. package/cli/recording-access.ts +108 -0
  142. package/cli/registry.ts +2 -0
  143. package/cli/resolve-assets.ts +63 -0
  144. package/cli/rnx-in-process.ts +98 -0
  145. package/cli/run-registry.ts +226 -0
  146. package/cli/run-rnx-core.ts +148 -0
  147. package/cli/run-rnx.ts +137 -0
  148. package/cli/runtime-notes.ts +66 -0
  149. package/cli/runtime-summary.ts +25 -0
  150. package/cli/secure-file.ts +31 -0
  151. package/cli/self-invocation.ts +58 -0
  152. package/cli/send-to-box.ts +109 -0
  153. package/cli/setup-repository.ts +191 -0
  154. package/cli/shell-init.ts +98 -0
  155. package/cli/standalone.ts +4 -0
  156. package/cli/telemetry.ts +84 -0
  157. package/cli/ui.ts +68 -0
  158. package/cli/ws-bridge.ts +1020 -0
  159. package/detox/attempt-events.cjs +23 -0
  160. package/detox/colors.ts +54 -0
  161. package/detox/config-loader.ts +135 -0
  162. package/detox/element-types.ts +48 -0
  163. package/detox/expectations.ts +534 -0
  164. package/detox/gestures.ts +501 -0
  165. package/detox/index.ts +2694 -0
  166. package/detox/jest-preset.cjs +29 -0
  167. package/detox/jest-setup-after-env.cjs +22 -0
  168. package/detox/matchers.ts +30 -0
  169. package/detox/motion-change.cjs +109 -0
  170. package/detox/motion-change.d.cts +35 -0
  171. package/detox/navigation-lifecycle.ts +290 -0
  172. package/detox/navigation.ts +43 -0
  173. package/detox/proof-frame.cjs +114 -0
  174. package/detox/record-block-execution.cjs +78 -0
  175. package/detox/screenshots/animated-color-test-rest-norngh.png +0 -0
  176. package/detox/screenshots/color-test-after-drag-norngh.png +0 -0
  177. package/detox/screenshots/color-test-rest-norngh.png +0 -0
  178. package/detox/screenshots/theme-blue-toggle.png +0 -0
  179. package/detox/screenshots/theme-blue.png +0 -0
  180. package/detox/screenshots/theme-red-toggle.png +0 -0
  181. package/detox/screenshots/theme-red.png +0 -0
  182. package/dist-lib/agent-daemon-client.cjs +502 -0
  183. package/dist-lib/agent-events.cjs +48 -0
  184. package/dist-lib/agent-identity.cjs +53 -0
  185. package/dist-lib/agent-sessions.cjs +759 -0
  186. package/dist-lib/attached-projects.cjs +526 -0
  187. package/dist-lib/auth/shared-session.cjs +208 -0
  188. package/dist-lib/backend-origin.cjs +88 -0
  189. package/dist-lib/beta.cjs +41 -0
  190. package/dist-lib/beta.mjs +13 -0
  191. package/dist-lib/bridge-constants.cjs +161 -0
  192. package/dist-lib/bridge-contract-input.cjs +451 -0
  193. package/dist-lib/bridge-contract-input.mjs +414 -0
  194. package/dist-lib/bridge-contract.cjs +130 -0
  195. package/dist-lib/bridge-contract.mjs +94 -0
  196. package/dist-lib/capture-contract.cjs +220 -0
  197. package/dist-lib/capture-contract.mjs +190 -0
  198. package/dist-lib/cli-constants.cjs +32 -0
  199. package/dist-lib/cloud-contract.cjs +194 -0
  200. package/dist-lib/cloud-contract.mjs +145 -0
  201. package/dist-lib/cloud.cjs +670 -0
  202. package/dist-lib/cloud.mjs +639 -0
  203. package/dist-lib/config.cjs +96 -0
  204. package/dist-lib/detox/index.cjs +3789 -0
  205. package/dist-lib/detox/jest-preset.cjs +29 -0
  206. package/dist-lib/dev-bundle-resolution.cjs +290 -0
  207. package/dist-lib/home-paths.cjs +638 -0
  208. package/dist-lib/host/bridge-host.cjs +10903 -0
  209. package/dist-lib/host/fetch-proxy-handler.cjs +421 -0
  210. package/dist-lib/host/fetch-proxy-overrides.cjs +63 -0
  211. package/dist-lib/host/fetch-proxy-overrides.mjs +37 -0
  212. package/dist-lib/host/replacement-module-handler.cjs +469 -0
  213. package/dist-lib/host/websocket-proxy.cjs +298 -0
  214. package/dist-lib/index.cjs +4268 -0
  215. package/dist-lib/jump-to-source-babel.cjs +93 -0
  216. package/dist-lib/jump-to-source-native.cjs +112 -0
  217. package/dist-lib/menu.cjs +646 -0
  218. package/dist-lib/menu.mjs +604 -0
  219. package/dist-lib/metro-fingerprint-registry.cjs +186 -0
  220. package/dist-lib/metro-fingerprint-registry.mjs +156 -0
  221. package/dist-lib/metro-production-bundle.cjs +329 -0
  222. package/dist-lib/metro-production-bundle.mjs +295 -0
  223. package/dist-lib/metro.cjs +904 -0
  224. package/dist-lib/profiles.cjs +246 -0
  225. package/dist-lib/public-brand.cjs +39 -0
  226. package/dist-lib/react-native-host-modules.cjs +51 -0
  227. package/dist-lib/react-native-host-modules.mjs +25 -0
  228. package/dist-lib/render-mode.cjs +54 -0
  229. package/dist-lib/scripts/dev-server-scanner.cjs +1232 -0
  230. package/dist-lib/sdk.cjs +2433 -0
  231. package/dist-lib/sdk.mjs +2336 -0
  232. package/dist-lib/skills.cjs +39132 -0
  233. package/dist-lib/swift-submit.cjs +92 -0
  234. package/dist-lib/swift-submit.mjs +65 -0
  235. package/dist-lib/swift.cjs +1646 -0
  236. package/dist-lib/vite.cjs +1591 -0
  237. package/package.json +290 -0
  238. package/scripts/dev-server-scanner.ts +1291 -0
  239. package/scripts/optional-demo-registry.ts +113 -0
  240. package/skills/contrast/SKILL.md +165 -0
  241. package/skills/rnx-debug/SKILL.md +433 -0
  242. package/skills/rnx-perf/SKILL.md +399 -0
  243. package/skills/rnx-setup/SKILL.md +172 -0
  244. package/skills/rnx-test/SKILL.md +321 -0
  245. package/skills/rnx-visual/SKILL.md +126 -0
  246. package/src/agent-daemon-client.ts +410 -0
  247. package/src/agent-events.ts +71 -0
  248. package/src/agent-identity.ts +23 -0
  249. package/src/agent-prompt.ts +71 -0
  250. package/src/agent-sessions.ts +580 -0
  251. package/src/app-url.ts +39 -0
  252. package/src/attached-projects.ts +539 -0
  253. package/src/auth/shared-session.ts +235 -0
  254. package/src/backend-origin.ts +70 -0
  255. package/src/beta.ts +19 -0
  256. package/src/bridge-constants.ts +175 -0
  257. package/src/bridge-contract-input.ts +502 -0
  258. package/src/bridge-contract.ts +558 -0
  259. package/src/browser-cache.ts +16 -0
  260. package/src/capture-contract.ts +587 -0
  261. package/src/cli-constants.ts +1 -0
  262. package/src/cli-version.ts +40 -0
  263. package/src/cloud-contract.ts +274 -0
  264. package/src/cloud.ts +762 -0
  265. package/src/codex-client.ts +234 -0
  266. package/src/config.ts +132 -0
  267. package/src/connect.ts +101 -0
  268. package/src/dev-bundle-resolution.ts +346 -0
  269. package/src/dev-server-open.ts +198 -0
  270. package/src/disk-cleanup.ts +540 -0
  271. package/src/flow-timeout-scale.ts +15 -0
  272. package/src/home-paths.ts +806 -0
  273. package/src/host/agent-host.ts +666 -0
  274. package/src/host/bridge-host.ts +2788 -0
  275. package/src/host/fetch-proxy-handler.ts +449 -0
  276. package/src/host/fetch-proxy-overrides.ts +51 -0
  277. package/src/host/open-url.ts +89 -0
  278. package/src/host/plane-host.ts +203 -0
  279. package/src/host/replacement-module-handler.ts +158 -0
  280. package/src/host/websocket-proxy.ts +315 -0
  281. package/src/index.ts +71 -0
  282. package/src/jump-to-source-babel.ts +135 -0
  283. package/src/jump-to-source-native.ts +102 -0
  284. package/src/menu.ts +777 -0
  285. package/src/metro-fingerprint-registry.ts +302 -0
  286. package/src/metro-plugin.ts +341 -0
  287. package/src/metro-production-bundle.ts +471 -0
  288. package/src/native-dev-bundle-url.ts +118 -0
  289. package/src/native-seam-manifest.ts +341 -0
  290. package/src/playwright-host-log.ts +16 -0
  291. package/src/plist.ts +27 -0
  292. package/src/poll-until.ts +123 -0
  293. package/src/profiles.ts +179 -0
  294. package/src/public-brand.ts +9 -0
  295. package/src/react-native-host-modules.ts +26 -0
  296. package/src/render-mode.ts +27 -0
  297. package/src/rolldown-plugin-swift.ts +240 -0
  298. package/src/runtime-assets.ts +233 -0
  299. package/src/runtime-delivery.ts +54 -0
  300. package/src/screenshots/compose.ts +422 -0
  301. package/src/screenshots/frame-compose.ts +514 -0
  302. package/src/screenshots/orchestrate.ts +256 -0
  303. package/src/screenshots/org-deck.ts +91 -0
  304. package/src/screenshots/registry.ts +58 -0
  305. package/src/screenshots/schema.ts +364 -0
  306. package/src/sdk.ts +15 -0
  307. package/src/settings-bundle.ts +418 -0
  308. package/src/shell-bridge-identity.ts +15 -0
  309. package/src/sim-client.ts +697 -0
  310. package/src/skills/builtin/a11y-review.ts +132 -0
  311. package/src/skills/builtin/compat-check.ts +71 -0
  312. package/src/skills/builtin/maestro-test.ts +121 -0
  313. package/src/skills/builtin/perf-profile.ts +90 -0
  314. package/src/skills/builtin/screenshot-all.ts +52 -0
  315. package/src/skills/builtin/visual-diff.ts +100 -0
  316. package/src/skills/registry.ts +107 -0
  317. package/src/skills/types.ts +41 -0
  318. package/src/swift-submit.ts +185 -0
  319. package/src/swift.ts +7 -0
  320. package/src/team-machine-prompt.ts +73 -0
  321. package/src/vite-plugin-one.ts +264 -0
  322. package/src/vite-plugin-swift.ts +620 -0
  323. package/src/vite-plugin.ts +1946 -0
  324. package/src/worklets-babel.ts +250 -0
@@ -0,0 +1,121 @@
1
+ // rnx timeline — control the semantic agent-facing event log
2
+ //
3
+ // `rnx record` is for video/screen capture; `rnx debug record` is
4
+ // for the engine-internal debug-channel ring; this command is the third
5
+ // surface and explicitly distinct: it manages the SootSim.bridges.timeline API,
6
+ // the unified, agent-facing semantic event stream across host / shell
7
+ // worker / tenant worker.
8
+ //
9
+ // usage:
10
+ // rnx timeline status # what's enabled
11
+ // rnx timeline start [kinds] # enable kinds (default: opt-in defaults)
12
+ // rnx timeline stop [kinds] # disable kinds (or 'all')
13
+ // rnx timeline clear # drop all events + cursors
14
+ // rnx timeline dump <file> # write current ring to JSON
15
+ //
16
+ // see `rnx what-happened` for the read side.
17
+
18
+ import { writeFileSync } from 'fs'
19
+ import { rnxExit } from '../run-rnx'
20
+ import { callInBridge, createBridgeFromParsed, parseBridgeCliArgs } from '../ws-bridge'
21
+
22
+ interface TimelineOptions {
23
+ port?: number
24
+ verbose?: boolean
25
+ }
26
+
27
+ function printHelp() {
28
+ console.log(`
29
+ rnx timeline — control the semantic event timeline
30
+
31
+ usage:
32
+ rnx timeline <subcommand> [args]
33
+
34
+ subcommands:
35
+ status show enabled kinds and ring sizes
36
+ start [kinds] enable kinds (csv); 'all' for every opt-in
37
+ stop [kinds] disable kinds (csv); 'all' for every kind
38
+ clear drop all events + cursors
39
+ dump <file> write current merged ring to JSON
40
+
41
+ note: cheap kinds (console, fetch, app-launch, keyboard, screen, alert,
42
+ toast, notification, route, shell, actionsheet, picker) record at all times.
43
+ start/stop enables opt-in kinds (react-commit, scroll, gesture, text-input,
44
+ layout, reanimated, animation).
45
+
46
+ read the timeline with: rnx what-happened
47
+ `)
48
+ }
49
+
50
+ export async function runTimeline(args: string[], opts: TimelineOptions) {
51
+ const parsed = parseBridgeCliArgs(args, {
52
+ port: opts.port,
53
+ stripBooleanFlags: ['--json', '--help', '-h'],
54
+ })
55
+ const sub = parsed.positional[0]
56
+ if (!sub || args.includes('--help') || args.includes('-h')) {
57
+ printHelp()
58
+ rnxExit(0)
59
+ }
60
+ const json = args.includes('--json')
61
+ const bridge = createBridgeFromParsed(parsed)
62
+
63
+ const rest = parsed.positional.slice(1)
64
+ const kinds = rest[0]
65
+ ? rest[0]
66
+ .split(',')
67
+ .map((s) => s.trim())
68
+ .filter(Boolean)
69
+ : []
70
+
71
+ try {
72
+ switch (sub) {
73
+ case 'status': {
74
+ const status = await callInBridge(bridge, 'SootSim.bridges.timeline.status')
75
+ console.log(JSON.stringify(status, null, json ? 0 : 2))
76
+ break
77
+ }
78
+ case 'start': {
79
+ if (kinds.length === 0) kinds.push('all')
80
+ await callInBridge(bridge, 'SootSim.bridges.timeline.enable', ...kinds)
81
+ const status = await callInBridge(bridge, 'SootSim.bridges.timeline.status')
82
+ console.log(JSON.stringify(status, null, json ? 0 : 2))
83
+ break
84
+ }
85
+ case 'stop': {
86
+ if (kinds.length === 0) kinds.push('all')
87
+ await callInBridge(bridge, 'SootSim.bridges.timeline.disable', ...kinds)
88
+ const status = await callInBridge(bridge, 'SootSim.bridges.timeline.status')
89
+ console.log(JSON.stringify(status, null, json ? 0 : 2))
90
+ break
91
+ }
92
+ case 'clear': {
93
+ await callInBridge(bridge, 'SootSim.bridges.timeline.clear')
94
+ console.log(' cleared')
95
+ break
96
+ }
97
+ case 'dump': {
98
+ const outPath = rest[0]
99
+ if (!outPath) {
100
+ console.error(' usage: rnx timeline dump <file>')
101
+ rnxExit(1)
102
+ }
103
+ const result = await callInBridge<{ events: unknown[] }>(
104
+ bridge,
105
+ 'SootSim.bridges.timeline.recent',
106
+ { limit: 1_000_000 },
107
+ )
108
+ writeFileSync(outPath, JSON.stringify(result.events, null, 2) + '\n')
109
+ console.log(` wrote ${result.events.length} event(s) to ${outPath}`)
110
+ break
111
+ }
112
+ default: {
113
+ console.error(` unknown subcommand: ${sub}`)
114
+ printHelp()
115
+ rnxExit(1)
116
+ }
117
+ }
118
+ } finally {
119
+ bridge.close()
120
+ }
121
+ }
@@ -0,0 +1,167 @@
1
+ // rnx upgrade updates the separately delivered runtime first, then atomically
2
+ // replaces the standalone cli executable. runtime stays first because replacing
3
+ // the running cli's files before later dynamic imports can strand the command.
4
+
5
+ import { spawnSync } from 'node:child_process'
6
+ import { createHash } from 'node:crypto'
7
+ import fs from 'node:fs'
8
+ import path from 'node:path'
9
+ import { compareSemver } from '@contrast/runtime-delivery'
10
+ import { getCliVersion } from '../../src/cli-version'
11
+ import { isSootsimDevCheckout, readActiveRuntime, runtimeDir } from '../../src/home-paths'
12
+ import { resolveRNXAppConfig } from '../app-config'
13
+ import {
14
+ DEFAULT_CLI_RELEASE_ORIGIN,
15
+ fetchCliReleaseFile,
16
+ refreshCliUpdateCache,
17
+ } from '../cli-update'
18
+ import { fetchRuntimeReleaseNotes, formatRuntimeReleaseNotes } from '../runtime-notes'
19
+ import { IS_STANDALONE } from '../standalone'
20
+ import { runRuntime } from './runtime'
21
+
22
+ const SHA256_PATTERN = /^[a-f0-9]{64}$/
23
+
24
+ export interface UpgradeOptions {
25
+ cliExecutablePath?: string
26
+ cliReleaseOrigin?: string
27
+ standalone?: boolean
28
+ includeReleaseNotes?: boolean
29
+ }
30
+
31
+ export async function runUpgrade(
32
+ args: string[],
33
+ options: UpgradeOptions = {},
34
+ ): Promise<void> {
35
+ const channelIdx = args.indexOf('--channel')
36
+ const channel =
37
+ channelIdx >= 0 && args[channelIdx + 1] ? args[channelIdx + 1] : undefined
38
+
39
+ console.log('rnx upgrade\n')
40
+
41
+ console.log('runtime:')
42
+ const beforeRuntime = readActiveRuntime()
43
+ const { config } = await resolveRNXAppConfig()
44
+ const configuredRuntime = config?.runtimeVersion
45
+ const configuredRuntimeWasInstalled = configuredRuntime
46
+ ? fs.existsSync(path.join(runtimeDir(configuredRuntime), 'index.html'))
47
+ : false
48
+ if (configuredRuntime) {
49
+ console.log(` project config: v${configuredRuntime}`)
50
+ }
51
+ const install =
52
+ configuredRuntime && configuredRuntimeWasInstalled
53
+ ? null
54
+ : await runRuntime(
55
+ [
56
+ 'install',
57
+ ...(configuredRuntime ? [configuredRuntime, '--set-active=false'] : []),
58
+ ...(channel ? ['--channel', channel] : []),
59
+ ],
60
+ {},
61
+ )
62
+ const installedRuntime = install?.version ?? configuredRuntime ?? readActiveRuntime()
63
+ if (installedRuntime) {
64
+ console.log(
65
+ configuredRuntime
66
+ ? configuredRuntimeWasInstalled
67
+ ? ` result: v${installedRuntime} already installed for this project`
68
+ : ` result: not installed → v${installedRuntime} for this project`
69
+ : beforeRuntime && beforeRuntime !== installedRuntime
70
+ ? ` result: v${beforeRuntime} → v${installedRuntime}`
71
+ : !beforeRuntime
72
+ ? ` result: not installed → v${installedRuntime}`
73
+ : ` result: v${installedRuntime} already current`,
74
+ )
75
+ }
76
+ const releaseNotes =
77
+ installedRuntime && options.includeReleaseNotes !== false
78
+ ? await fetchRuntimeReleaseNotes(installedRuntime)
79
+ : null
80
+
81
+ console.log('\ncli:')
82
+ await upgradeCli(options)
83
+
84
+ if (installedRuntime && options.includeReleaseNotes !== false) {
85
+ console.log(`\n${formatRuntimeReleaseNotes(installedRuntime, releaseNotes)}`)
86
+ }
87
+ }
88
+
89
+ export async function upgradeCli(options: UpgradeOptions = {}): Promise<void> {
90
+ const standalone = options.standalone ?? IS_STANDALONE
91
+ if (!standalone) {
92
+ if (isSootsimDevCheckout()) {
93
+ console.log(' running from the Contrast checkout; pull instead of upgrading')
94
+ return
95
+ }
96
+ throw new Error(
97
+ 'this is not the standalone rnx executable; reinstall from https://rnxsim.com/install.sh',
98
+ )
99
+ }
100
+
101
+ const releaseOrigin = (options.cliReleaseOrigin ?? DEFAULT_CLI_RELEASE_ORIGIN).replace(
102
+ /\/+$/,
103
+ '',
104
+ )
105
+ const current = getCliVersion()
106
+ const { latestVersion: latest } = await refreshCliUpdateCache({ releaseOrigin })
107
+ if (compareSemver(latest, current) <= 0) {
108
+ console.log(` v${current} (latest)`)
109
+ return
110
+ }
111
+
112
+ const artifact = cliArtifactName()
113
+ const artifactUrl = `${releaseOrigin}/${latest}/${artifact}`
114
+ const expectedSha = (await fetchCliReleaseFile(`${artifactUrl}.sha256`, 8_000))
115
+ .toString('utf8')
116
+ .trim()
117
+ if (!SHA256_PATTERN.test(expectedSha)) {
118
+ throw new Error('rnx update service returned an invalid executable checksum')
119
+ }
120
+
121
+ console.log(` v${current} → v${latest}`)
122
+ console.log(` downloading ${artifact}...`)
123
+ const executable = await fetchCliReleaseFile(artifactUrl, 120_000)
124
+ const actualSha = createHash('sha256').update(executable).digest('hex')
125
+ if (actualSha !== expectedSha) {
126
+ throw new Error(
127
+ `downloaded rnx executable failed verification (expected ${expectedSha}, got ${actualSha})`,
128
+ )
129
+ }
130
+
131
+ const executablePath = path.resolve(options.cliExecutablePath ?? process.execPath)
132
+ const tempDir = fs.mkdtempSync(path.join(path.dirname(executablePath), '.rnx-update-'))
133
+ const candidatePath = path.join(tempDir, path.basename(executablePath))
134
+ try {
135
+ fs.writeFileSync(candidatePath, executable, { mode: 0o755 })
136
+ fs.chmodSync(candidatePath, 0o755)
137
+ verifyCandidate(candidatePath, latest)
138
+ fs.renameSync(candidatePath, executablePath)
139
+ } finally {
140
+ fs.rmSync(tempDir, { recursive: true, force: true })
141
+ }
142
+ console.log(` updated to v${latest}`)
143
+ }
144
+
145
+ function cliArtifactName(): string {
146
+ const platform = process.platform === 'darwin' ? 'darwin' : process.platform
147
+ if (platform !== 'darwin' && platform !== 'linux') {
148
+ throw new Error('standalone rnx self-update currently supports macOS and Linux')
149
+ }
150
+ if (process.arch !== 'arm64' && process.arch !== 'x64') {
151
+ throw new Error(`standalone rnx does not support ${process.arch}`)
152
+ }
153
+ return `rnx-${platform}-${process.arch}`
154
+ }
155
+
156
+ function verifyCandidate(candidatePath: string, expectedVersion: string): void {
157
+ const result = spawnSync(candidatePath, ['--version'], {
158
+ encoding: 'utf8',
159
+ timeout: 15_000,
160
+ })
161
+ const reported = result.stdout.match(/^rnx v([^\s]+)/m)?.[1]
162
+ if (result.status !== 0 || reported !== expectedVersion) {
163
+ throw new Error(
164
+ `downloaded rnx executable reported ${reported ? `v${reported}` : 'no version'}; expected v${expectedVersion}`,
165
+ )
166
+ }
167
+ }