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,274 @@
1
+ import type { BridgeCommandType } from './bridge-contract.ts'
2
+
3
+ export const RNX_CLOUD_MAX_ARTIFACT_BYTES = 20 * 1024 * 1024
4
+ export const RNX_CLOUD_DESIGN_MAX_STORAGE_ENTRIES = 256
5
+ export const RNX_CLOUD_DESIGN_MAX_STORAGE_BYTES = 1024 * 1024
6
+ export const RNX_CLOUD_TEST_FILES_MAX_COUNT = 256
7
+ export const RNX_CLOUD_TEST_FILES_MAX_BYTES = 500_000
8
+
9
+ export type RnxCloudCommandScope =
10
+ | 'read'
11
+ | 'drive'
12
+ | 'reset'
13
+ | 'media'
14
+ | 'debug'
15
+ | 'watch'
16
+
17
+ const RNX_CLOUD_COMMAND_SCOPE_SET = new Set<string>([
18
+ 'read',
19
+ 'drive',
20
+ 'reset',
21
+ 'media',
22
+ 'debug',
23
+ 'watch',
24
+ ])
25
+
26
+ export function isRnxCloudCommandScope(value: string): value is RnxCloudCommandScope {
27
+ return RNX_CLOUD_COMMAND_SCOPE_SET.has(value)
28
+ }
29
+
30
+ // scoped simulator tokens: one simulator, one verb set, one expiry, one
31
+ // origin list. minted by the full per-simulator token or the account api key,
32
+ // never by another scoped token, and never carrying debug.
33
+ export const RNX_CLOUD_SCOPED_TOKEN_PREFIX = 'sk_rnx_sim_'
34
+ export const RNX_CLOUD_SCOPED_TOKEN_DEFAULT_TTL_SECONDS = 3600
35
+ export const RNX_CLOUD_SCOPED_TOKEN_MIN_TTL_SECONDS = 1
36
+ export const RNX_CLOUD_SCOPED_TOKEN_MAX_TTL_SECONDS = 14400
37
+ export const RNX_CLOUD_SCOPED_TOKEN_MAX_ORIGINS = 16
38
+
39
+ export interface RnxCloudScopedTokenMint {
40
+ scopes: RnxCloudCommandScope[]
41
+ ttlSeconds?: number
42
+ origins?: string[]
43
+ }
44
+
45
+ export interface RnxCloudScopedToken {
46
+ tokenId: string
47
+ token: string
48
+ scopes: RnxCloudCommandScope[]
49
+ expiresAt: number
50
+ origins: string[]
51
+ }
52
+
53
+ // one scope table for both remote planes: every bridge verb names the scope
54
+ // that may send it, so the nano service and the box relay admit the same
55
+ // vocabulary and differ only by caller scope. reads observe, drive moves,
56
+ // reset wipes, media injects camera fixtures, and debug evaluates.
57
+ export const RNX_CLOUD_COMMAND_SCOPES = {
58
+ state: 'read',
59
+ tree: 'read',
60
+ query: 'read',
61
+ resolve: 'read',
62
+ screenshot: 'read',
63
+ capture: 'read',
64
+ captureRegions: 'read',
65
+ memory: 'read',
66
+ diagnostics: 'read',
67
+ storageSnapshot: 'read',
68
+ perform: 'drive',
69
+ waitFor: 'drive',
70
+ tap: 'drive',
71
+ longPress: 'drive',
72
+ settle: 'drive',
73
+ openUrl: 'drive',
74
+ setAppearance: 'drive',
75
+ keyboard: 'drive',
76
+ focus: 'drive',
77
+ flowStatus: 'drive',
78
+ reset: 'reset',
79
+ camera: 'media',
80
+ // string evaluation and arbitrary bridge calls are maestro's boundary: the
81
+ // customer sdk never carries this scope, and the service grants it only to
82
+ // the account api key caller. close rides along, since ending the page ends
83
+ // the sim and belongs to the sim's owner rather than any driver.
84
+ evaluate: 'debug',
85
+ call: 'debug',
86
+ close: 'debug',
87
+ } satisfies Record<BridgeCommandType, RnxCloudCommandScope>
88
+
89
+ function scopeTableKeys(): BridgeCommandType[] {
90
+ return Object.keys(RNX_CLOUD_COMMAND_SCOPES).filter((key): key is BridgeCommandType =>
91
+ Object.prototype.hasOwnProperty.call(RNX_CLOUD_COMMAND_SCOPES, key),
92
+ )
93
+ }
94
+
95
+ export const RNX_CLOUD_COMMAND_TYPES = Object.freeze(scopeTableKeys())
96
+
97
+ const RNX_CLOUD_COMMAND_TYPE_SET = new Set<string>(RNX_CLOUD_COMMAND_TYPES)
98
+
99
+ export function isRnxCloudCommandType(
100
+ value: string,
101
+ ): value is (typeof RNX_CLOUD_COMMAND_TYPES)[number] {
102
+ return RNX_CLOUD_COMMAND_TYPE_SET.has(value)
103
+ }
104
+
105
+ export function rnxCloudCommandScope(type: BridgeCommandType): RnxCloudCommandScope {
106
+ return RNX_CLOUD_COMMAND_SCOPES[type]
107
+ }
108
+
109
+ // what the full per-simulator token and the box token carry until scoped
110
+ // tokens exist: every scope except debug.
111
+ export const RNX_CLOUD_TOKEN_SCOPES: readonly RnxCloudCommandScope[] = Object.freeze([
112
+ 'read',
113
+ 'drive',
114
+ 'reset',
115
+ 'media',
116
+ ])
117
+
118
+ // every scope, granted only to the account api key caller through the account
119
+ // service. the only credential the services accept for it today is the shared
120
+ // service key, which only the account service holds.
121
+ export const RNX_CLOUD_ALL_COMMAND_SCOPES: readonly RnxCloudCommandScope[] =
122
+ Object.freeze(['read', 'drive', 'reset', 'media', 'debug'])
123
+
124
+ export function rnxCloudScopesAllowCommand(
125
+ scopes: readonly RnxCloudCommandScope[],
126
+ type: BridgeCommandType,
127
+ ): boolean {
128
+ return scopes.includes(RNX_CLOUD_COMMAND_SCOPES[type])
129
+ }
130
+
131
+ export interface RnxCloudClaim {
132
+ id: string
133
+ expiresAt: number
134
+ }
135
+
136
+ export interface RnxCloudCreateReceipt {
137
+ simId: string
138
+ artifact: {
139
+ id: `sha256:${string}`
140
+ bytes: number
141
+ }
142
+ claim: RnxCloudClaim
143
+ }
144
+
145
+ // a nano box is created around one artifact with its first simulator
146
+ export interface RnxCloudBoxCreateReceipt {
147
+ boxId: string
148
+ size: 'nano'
149
+ artifact: {
150
+ id: `sha256:${string}`
151
+ bytes: number
152
+ }
153
+ simulator: RnxCloudCreateReceipt
154
+ }
155
+
156
+ // what a cloud simulator reports. the stored lifecycle values are
157
+ // `creating`/`open`/`hibernated`/`deleting`; `deleted` is only ever a response,
158
+ // answered by a delete, because a deleted simulator has no row left to read.
159
+ export type RnxCloudSimStatus =
160
+ | 'creating'
161
+ | 'open'
162
+ | 'hibernated'
163
+ | 'deleting'
164
+ | 'deleted'
165
+
166
+ // one simulator as the instance list reports it: the lifecycle view plus the
167
+ // labels it was created with.
168
+ export interface RnxCloudSimView {
169
+ simId: string
170
+ status: RnxCloudSimStatus
171
+ labels: Record<string, string>
172
+ artifact: { sha256: string; bytes: number }
173
+ claim: RnxCloudClaim | null
174
+ createdAt: number
175
+ lastActiveAt: number
176
+ lastHibernatedAt?: number
177
+ storageFrom?: string
178
+ /** the idle window the creator set, or null for the service default. */
179
+ inactivityTimeoutMs: number | null
180
+ /** the instant the creator's hard timeout stops this simulator, or null. */
181
+ hardTimeoutAt: number | null
182
+ }
183
+
184
+ // one simulator as create and get report it, with the watch URL a browser
185
+ // opens to see it.
186
+ export interface RnxCloudSimInstance extends RnxCloudSimView {
187
+ /** a watch URL with its grant in the fragment, or null when none can be
188
+ * minted yet: an unconfirmed simulator is not watchable. */
189
+ streamUrl: string | null
190
+ }
191
+
192
+ // the create/reuse answer: the receipt the box path also returns, plus what
193
+ // only the instance API knows.
194
+ export interface RnxCloudSimCreateResponse extends RnxCloudCreateReceipt {
195
+ token: string
196
+ status: RnxCloudSimStatus
197
+ labels: Record<string, string>
198
+ streamUrl: string | null
199
+ }
200
+
201
+ // one grammar for the create map and the list selector: `key=value,key2=value2`.
202
+ // a value may be empty; a key may not; a repeated key is the caller's mistake
203
+ // rather than a silent last-one-wins. commas and control characters never
204
+ // belong in a key or value, and 63 characters is the ceiling for either.
205
+ export const RNX_CLOUD_LABELS_MAX_COUNT = 16
206
+ export const RNX_CLOUD_LABEL_MAX_LENGTH = 63
207
+
208
+ const RNX_CLOUD_LABEL_CONTROL = /[\u0000-\u001f\u007f]/
209
+
210
+ export function isValidRnxCloudLabel(key: string, value: string): boolean {
211
+ return (
212
+ key.length > 0 &&
213
+ key.length <= RNX_CLOUD_LABEL_MAX_LENGTH &&
214
+ value.length <= RNX_CLOUD_LABEL_MAX_LENGTH &&
215
+ !key.includes(',') &&
216
+ !key.includes('=') &&
217
+ !value.includes(',') &&
218
+ !RNX_CLOUD_LABEL_CONTROL.test(key) &&
219
+ !RNX_CLOUD_LABEL_CONTROL.test(value)
220
+ )
221
+ }
222
+
223
+ /** the wire form, or null when it is not one. `''` is the empty map. */
224
+ export function parseRnxCloudLabels(value: string): Record<string, string> | null {
225
+ if (value === '') return {}
226
+ const entries = value.split(',')
227
+ if (entries.length > RNX_CLOUD_LABELS_MAX_COUNT) return null
228
+ const labels: Record<string, string> = {}
229
+ for (const entry of entries) {
230
+ const separator = entry.indexOf('=')
231
+ if (separator < 1) return null
232
+ const key = entry.slice(0, separator).trim()
233
+ const label = entry.slice(separator + 1).trim()
234
+ if (!isValidRnxCloudLabel(key, label)) return null
235
+ if (Object.hasOwn(labels, key)) return null
236
+ labels[key] = label
237
+ }
238
+ return labels
239
+ }
240
+
241
+ /** the same grammar with the map already split apart, as a json body carries
242
+ * it. anything the wire form would refuse is refused here too. */
243
+ export function readRnxCloudLabels(value: unknown): Record<string, string> | null {
244
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) return null
245
+ const entries = Object.entries(value)
246
+ if (entries.length > RNX_CLOUD_LABELS_MAX_COUNT) return null
247
+ const labels: Record<string, string> = {}
248
+ for (const [key, label] of entries) {
249
+ if (typeof label !== 'string') return null
250
+ if (!isValidRnxCloudLabel(key, label)) return null
251
+ labels[key] = label
252
+ }
253
+ return labels
254
+ }
255
+
256
+ /** every selector entry must be present with the same value. an empty
257
+ * selector selects everything. */
258
+ export function matchesRnxCloudLabels(
259
+ labels: Record<string, string>,
260
+ selector: Record<string, string>,
261
+ ): boolean {
262
+ return Object.entries(selector).every(([key, value]) => labels[key] === value)
263
+ }
264
+
265
+ /** the selector an instance list filters by, given the statuses it accepts. */
266
+ export function isRnxCloudSimStatus(value: string): value is RnxCloudSimStatus {
267
+ return (
268
+ value === 'creating' ||
269
+ value === 'open' ||
270
+ value === 'hibernated' ||
271
+ value === 'deleting' ||
272
+ value === 'deleted'
273
+ )
274
+ }