rnxsim 0.1.381 → 0.1.383

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 (138) hide show
  1. package/README.md +19 -6
  2. package/cli/app-fonts.ts +1 -1
  3. package/cli/bin.ts +118 -26
  4. package/cli/bridge-diagnostics.ts +1 -1
  5. package/cli/bridge-flow-runner.ts +9 -9
  6. package/cli/browser-evals.ts +3 -3
  7. package/cli/cli-update.ts +261 -0
  8. package/cli/cloud-client.ts +407 -0
  9. package/cli/cloud-dispatch.ts +165 -0
  10. package/cli/cloud-session.ts +156 -0
  11. package/cli/command-contract.ts +2 -2
  12. package/cli/command-registry.ts +9 -0
  13. package/cli/commands/agent-wrapper.ts +4 -4
  14. package/cli/commands/agent.ts +3 -3
  15. package/cli/commands/box/checkout-plane.ts +16 -8
  16. package/cli/commands/box/rnx-command.ts +2 -2
  17. package/cli/commands/box/search-command.ts +2 -2
  18. package/cli/commands/box.ts +123 -70
  19. package/cli/commands/config.ts +3 -2
  20. package/cli/commands/control.ts +6 -6
  21. package/cli/commands/cpu-profile.ts +2 -2
  22. package/cli/commands/daemon.ts +7 -7
  23. package/cli/commands/debug.ts +2 -2
  24. package/cli/commands/detox.ts +7 -7
  25. package/cli/commands/diagnose.ts +1 -1
  26. package/cli/commands/electron.ts +1 -1
  27. package/cli/commands/film.ts +1 -1
  28. package/cli/commands/flow.ts +4 -4
  29. package/cli/commands/inspect/core.ts +58 -7
  30. package/cli/commands/inspect/env.ts +5 -3
  31. package/cli/commands/inspect/shared.ts +2 -1
  32. package/cli/commands/inspect/wait-event.ts +1 -1
  33. package/cli/commands/inspect/wait-ready.ts +15 -5
  34. package/cli/commands/inspect.ts +31 -9
  35. package/cli/commands/install-desktop.ts +2 -2
  36. package/cli/commands/maestro.ts +3 -3
  37. package/cli/commands/permissions.ts +1 -1
  38. package/cli/commands/platform.ts +91 -0
  39. package/cli/commands/record.ts +3 -3
  40. package/cli/commands/report-issue.ts +1 -1
  41. package/cli/commands/runtime.ts +1 -1
  42. package/cli/commands/screenshot-mode.ts +1 -1
  43. package/cli/commands/screenshot.ts +25 -0
  44. package/cli/commands/serve.ts +1 -1
  45. package/cli/commands/skills.ts +1 -1
  46. package/cli/commands/timeline.ts +1 -1
  47. package/cli/commands/upgrade.ts +8 -34
  48. package/cli/commands/upload.ts +3 -3
  49. package/cli/commands/version.ts +14 -3
  50. package/cli/commands/what-happened.ts +2 -2
  51. package/cli/current-sim.ts +43 -30
  52. package/cli/desktop-companion.ts +1 -1
  53. package/cli/drivers/electron.ts +1 -1
  54. package/cli/drivers/playwright.ts +3 -3
  55. package/cli/drivers/types.ts +4 -4
  56. package/cli/flow-file.ts +3 -3
  57. package/cli/help-core.ts +18 -11
  58. package/cli/hidden-runtime-alias.ts +1 -1
  59. package/cli/hints.ts +2 -2
  60. package/cli/maestro-js.ts +2 -2
  61. package/cli/outbound-endpoints.ts +40 -6
  62. package/cli/parse-args.ts +1 -1
  63. package/cli/registry.ts +1 -1
  64. package/cli/resolve-assets.ts +2 -2
  65. package/cli/secure-file.ts +31 -0
  66. package/cli/shell-init.ts +98 -0
  67. package/cli/ws-bridge.ts +18 -8
  68. package/detox/expectations.ts +1 -1
  69. package/detox/gestures.ts +3 -3
  70. package/detox/index.ts +3 -3
  71. package/dist-lib/agent-daemon-client.cjs +1 -1
  72. package/dist-lib/agent-events.cjs +1 -1
  73. package/dist-lib/agent-identity.cjs +1 -1
  74. package/dist-lib/agent-sessions.cjs +1 -1
  75. package/dist-lib/attached-projects.cjs +1 -1
  76. package/dist-lib/auth/shared-session.cjs +1 -1
  77. package/dist-lib/backend-origin.cjs +1 -1
  78. package/dist-lib/beta.cjs +1 -1
  79. package/dist-lib/beta.mjs +1 -1
  80. package/dist-lib/bridge-constants.cjs +1 -1
  81. package/dist-lib/bridge-contract-input.cjs +20 -8
  82. package/dist-lib/bridge-contract-input.mjs +20 -8
  83. package/dist-lib/bridge-contract.cjs +1 -1
  84. package/dist-lib/bridge-contract.mjs +1 -1
  85. package/dist-lib/capture-contract.cjs +217 -0
  86. package/dist-lib/capture-contract.mjs +187 -0
  87. package/dist-lib/cli-constants.cjs +1 -1
  88. package/dist-lib/cloud-contract.cjs +41 -0
  89. package/dist-lib/cloud-contract.mjs +13 -0
  90. package/dist-lib/config.cjs +1 -1
  91. package/dist-lib/detox/index.cjs +4 -4
  92. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  93. package/dist-lib/home-paths.cjs +9 -1
  94. package/dist-lib/host/bridge-host.cjs +15 -10
  95. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  96. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  97. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  98. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  99. package/dist-lib/host/websocket-proxy.cjs +1 -1
  100. package/dist-lib/index.cjs +361 -75
  101. package/dist-lib/jump-to-source-babel.cjs +1 -1
  102. package/dist-lib/menu.cjs +1 -1
  103. package/dist-lib/menu.mjs +1 -1
  104. package/dist-lib/metro-production-bundle.cjs +1 -1
  105. package/dist-lib/metro-production-bundle.mjs +1 -1
  106. package/dist-lib/metro.cjs +1 -1
  107. package/dist-lib/profiles.cjs +1 -1
  108. package/dist-lib/public-brand.cjs +1 -1
  109. package/dist-lib/react-native-host-modules.cjs +1 -1
  110. package/dist-lib/react-native-host-modules.mjs +1 -1
  111. package/dist-lib/render-mode.cjs +1 -1
  112. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  113. package/dist-lib/sdk.cjs +44 -6
  114. package/dist-lib/sdk.mjs +44 -6
  115. package/dist-lib/skills.cjs +436 -155
  116. package/dist-lib/vite.cjs +1 -1
  117. package/package.json +20 -4
  118. package/scripts/dev-server-scanner.ts +3 -3
  119. package/skills/contrast/SKILL.md +1 -1
  120. package/skills/rnx-perf/SKILL.md +68 -52
  121. package/src/app-url.ts +2 -3
  122. package/src/bridge-contract-input.ts +25 -6
  123. package/src/bridge-contract.ts +35 -5
  124. package/src/capture-contract.ts +576 -0
  125. package/src/cloud-contract.ts +18 -0
  126. package/src/home-paths.ts +9 -3
  127. package/src/host/agent-host.ts +1 -1
  128. package/src/host/bridge-host.ts +13 -11
  129. package/src/host/plane-host.ts +2 -2
  130. package/src/index.ts +25 -0
  131. package/src/native-dev-bundle-url.ts +2 -2
  132. package/src/screenshots/orchestrate.ts +1 -1
  133. package/src/screenshots/org-deck.ts +1 -1
  134. package/src/settings-bundle.ts +1 -1
  135. package/src/sim-client.ts +4 -0
  136. package/src/vite-plugin-one.ts +2 -2
  137. package/src/vite-plugin.ts +1 -1
  138. package/cli/commands/box/cloud-box.ts +0 -294
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.381 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.383 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/bridge-contract-input.ts
4
4
  var BridgeInputError = class extends Error {
@@ -150,10 +150,15 @@ function parsePerformStep(value, index) {
150
150
  return { type, ms: numberValue(step.ms, `${path}.ms`) };
151
151
  case "waitFor": {
152
152
  const timeoutMs = semanticWaitTimeout(step, path);
153
+ const condition = step.condition === void 0 ? void 0 : stringValue(step.condition, `${path}.condition`);
154
+ if (condition !== void 0 && condition !== "present" && condition !== "absent") {
155
+ return validationFailure(`${path}.condition`, "must be present or absent");
156
+ }
153
157
  const selector = step.testID === void 0 ? { id: stringValue(step.id, `${path}.id`) } : { testID: stringValue(step.testID, `${path}.testID`) };
154
158
  return {
155
159
  type,
156
160
  ...selector,
161
+ ...condition === void 0 ? {} : { condition },
157
162
  ...timeoutMs === void 0 ? {} : { timeoutMs }
158
163
  };
159
164
  }
@@ -165,8 +170,10 @@ function parseStateOptions(value) {
165
170
  const input = recordValue(value, "state");
166
171
  const route = optionalBoolean(input, "route", "state");
167
172
  const errors = optionalBoolean(input, "errors", "state");
173
+ const logs = optionalBoolean(input, "logs", "state");
168
174
  const depth = optionalNumber(input, "depth", "state");
169
175
  const errorLimit = optionalNumber(input, "errorLimit", "state");
176
+ const logLimit = optionalNumber(input, "logLimit", "state");
170
177
  const layers = input.layers === void 0 ? void 0 : stringValue(input.layers, "state.layers");
171
178
  if (layers !== void 0 && layers !== "full" && layers !== "tenant" && layers !== "shell") {
172
179
  return validationFailure("state.layers", "must be full, tenant, or shell");
@@ -176,9 +183,11 @@ function parseStateOptions(value) {
176
183
  tree: optionalBoolean(input, "tree", "state") ?? true,
177
184
  ...route === void 0 ? {} : { route },
178
185
  ...errors === void 0 ? {} : { errors },
186
+ ...logs === void 0 ? {} : { logs },
179
187
  ...depth === void 0 ? {} : { depth },
180
188
  ...layers === void 0 ? {} : { layers },
181
- ...errorLimit === void 0 ? {} : { errorLimit }
189
+ ...errorLimit === void 0 ? {} : { errorLimit },
190
+ ...logLimit === void 0 ? {} : { logLimit }
182
191
  };
183
192
  }
184
193
  function parseSemanticSelector(value, path) {
@@ -225,15 +234,18 @@ function parseSemanticQuery(value) {
225
234
  }
226
235
  return validationFailure("query.kind", "must be tree, find, or count");
227
236
  }
228
- function parseSemanticResolveSelector(value) {
229
- const selector = recordValue(value, "selector");
237
+ function semanticResolveSelector(value, path) {
238
+ const selector = recordValue(value, path);
230
239
  if (selector.testID !== void 0) {
231
- return { testID: stringValue(selector.testID, "selector.testID") };
240
+ return { testID: stringValue(selector.testID, `${path}.testID`) };
232
241
  }
233
242
  if (selector.text !== void 0) {
234
- return { text: stringValue(selector.text, "selector.text") };
243
+ return { text: stringValue(selector.text, `${path}.text`) };
235
244
  }
236
- return validationFailure("selector", "must select testID or text");
245
+ return validationFailure(path, "must select testID or text");
246
+ }
247
+ function parseSemanticResolveSelector(value) {
248
+ return semanticResolveSelector(value, "selector");
237
249
  }
238
250
  function parseSemanticWaitOptions(value) {
239
251
  const input = recordValue(value, "waitFor");
@@ -255,7 +267,7 @@ function parseSemanticWaitOptions(value) {
255
267
  return {
256
268
  condition: {
257
269
  type,
258
- testID: stringValue(condition.testID, "waitFor.condition.testID")
270
+ selector: semanticResolveSelector(condition.selector, "waitFor.condition.selector")
259
271
  },
260
272
  ...timeoutMs === void 0 ? {} : { timeoutMs }
261
273
  };
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.381 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.383 | (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.381 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.383 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/bridge-contract.ts
4
4
  var SEMANTIC_READY_CONTENT_NODE_FLOOR = 100;
@@ -0,0 +1,217 @@
1
+ /*! rnx v0.1.383 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
+ "use strict";
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
+
22
+ // src/capture-contract.ts
23
+ var capture_contract_exports = {};
24
+ __export(capture_contract_exports, {
25
+ RNX_SCREEN_CAPTURE_VERSION: () => RNX_SCREEN_CAPTURE_VERSION,
26
+ isRnxCaptureRegionAtlas: () => isRnxCaptureRegionAtlas,
27
+ isRnxScreenCapture: () => isRnxScreenCapture,
28
+ rnxCaptureRasterRegions: () => rnxCaptureRasterRegions,
29
+ rnxRasterFrames: () => rnxRasterFrames,
30
+ selectRnxRasterNodeIds: () => selectRnxRasterNodeIds
31
+ });
32
+ module.exports = __toCommonJS(capture_contract_exports);
33
+ var RNX_SCREEN_CAPTURE_VERSION = 1;
34
+ function selectRnxRasterNodeIds(tree) {
35
+ const nodesById = new Map(tree.nodes.map((node) => [node.nodeId, node]));
36
+ const unsupported = /* @__PURE__ */ new Set();
37
+ for (const node of tree.nodes) {
38
+ const visibleFrame = node.visibleFrame ?? node.frame;
39
+ if (!visibleFrame || visibleFrame.width <= 0 || visibleFrame.height <= 0) continue;
40
+ if (node.type === "masked-view" || node.style._liquidGlass !== void 0 || node.style._liquidGlassEdge !== void 0) {
41
+ unsupported.add(node.nodeId);
42
+ }
43
+ }
44
+ for (const nodeId of [...unsupported]) {
45
+ let parentNodeId = nodesById.get(nodeId)?.parentNodeId ?? null;
46
+ while (parentNodeId !== null) {
47
+ if (unsupported.has(parentNodeId)) {
48
+ unsupported.delete(nodeId);
49
+ break;
50
+ }
51
+ parentNodeId = nodesById.get(parentNodeId)?.parentNodeId ?? null;
52
+ }
53
+ }
54
+ const screenArea = tree.width * tree.height;
55
+ const maxLayerArea = screenArea * 0.25;
56
+ const maxAtlasArea = screenArea * 0.5;
57
+ const candidates = [...unsupported].map((nodeId) => {
58
+ const node = nodesById.get(nodeId);
59
+ const frame = node?.visibleFrame ?? node?.frame;
60
+ return frame ? { nodeId, area: frame.width * frame.height } : null;
61
+ }).filter(
62
+ (candidate) => candidate !== null && candidate.area <= maxLayerArea
63
+ ).sort((left, right) => left.area - right.area || left.nodeId - right.nodeId);
64
+ const selected = /* @__PURE__ */ new Set();
65
+ let atlasArea = 0;
66
+ for (const candidate of candidates) {
67
+ if (atlasArea + candidate.area > maxAtlasArea) continue;
68
+ selected.add(candidate.nodeId);
69
+ atlasArea += candidate.area;
70
+ }
71
+ return selected;
72
+ }
73
+ function rnxRasterFrames(tree, nodeIds) {
74
+ const frames = /* @__PURE__ */ new Map();
75
+ for (const node of tree.nodes) {
76
+ if (!nodeIds.has(node.nodeId)) continue;
77
+ const frame = node.frame ?? {
78
+ x: node.absolutePosition.x,
79
+ y: node.absolutePosition.y,
80
+ width: node.layout.width,
81
+ height: node.layout.height
82
+ };
83
+ const liquidGlass = node.style._liquidGlass;
84
+ const capturePadding = liquidGlass && typeof liquidGlass === "object" && typeof Reflect.get(liquidGlass, "capturePadding") === "number" ? Reflect.get(liquidGlass, "capturePadding") : 0;
85
+ const shadowRadius = typeof node.style.shadowRadius === "number" ? node.style.shadowRadius : 0;
86
+ const shadowOffset = node.style.shadowOffset;
87
+ const shadowOffsetX = shadowOffset && typeof shadowOffset === "object" && typeof Reflect.get(shadowOffset, "width") === "number" ? Reflect.get(shadowOffset, "width") : 0;
88
+ const shadowOffsetY = shadowOffset && typeof shadowOffset === "object" && typeof Reflect.get(shadowOffset, "height") === "number" ? Reflect.get(shadowOffset, "height") : 0;
89
+ const left = Math.max(
90
+ 0,
91
+ frame.x - Math.max(capturePadding, shadowRadius - shadowOffsetX)
92
+ );
93
+ const top = Math.max(
94
+ 0,
95
+ frame.y - Math.max(capturePadding, shadowRadius - shadowOffsetY)
96
+ );
97
+ const right = Math.min(
98
+ tree.width,
99
+ frame.x + frame.width + Math.max(capturePadding, shadowRadius + shadowOffsetX)
100
+ );
101
+ const bottom = Math.min(
102
+ tree.height,
103
+ frame.y + frame.height + Math.max(capturePadding, shadowRadius + shadowOffsetY)
104
+ );
105
+ if (right > left && bottom > top) {
106
+ frames.set(node.nodeId, {
107
+ x: left,
108
+ y: top,
109
+ width: right - left,
110
+ height: bottom - top
111
+ });
112
+ }
113
+ }
114
+ return frames;
115
+ }
116
+ function rnxCaptureRasterRegions(capture) {
117
+ const tree = {
118
+ width: capture.tree.viewport.width,
119
+ height: capture.tree.viewport.height,
120
+ nodes: capture.tree.nodes.map((node) => ({
121
+ nodeId: node.nodeId,
122
+ parentNodeId: node.parentNodeId,
123
+ type: node.type,
124
+ style: node.style.resolved,
125
+ layout: node.layout.local,
126
+ frame: node.layout.frame,
127
+ absolutePosition: node.layout.absolutePosition,
128
+ visibleFrame: node.layout.visibleFrame
129
+ }))
130
+ };
131
+ const nodeIds = selectRnxRasterNodeIds(tree);
132
+ const frames = rnxRasterFrames(tree, nodeIds);
133
+ return [...nodeIds].flatMap((nodeId) => {
134
+ const frame = frames.get(nodeId);
135
+ return frame ? [{ key: String(nodeId), nodeId, frame }] : [];
136
+ });
137
+ }
138
+ function captureRecord(value) {
139
+ return value !== null && typeof value === "object" && !Array.isArray(value);
140
+ }
141
+ function captureInteger(value) {
142
+ return typeof value === "number" && Number.isSafeInteger(value);
143
+ }
144
+ function captureNumber(value) {
145
+ return typeof value === "number" && Number.isFinite(value);
146
+ }
147
+ function captureNullableString(value) {
148
+ return value === null || typeof value === "string";
149
+ }
150
+ function captureRect(value) {
151
+ return captureRecord(value) && captureNumber(value.x) && captureNumber(value.y) && captureNumber(value.width) && captureNumber(value.height);
152
+ }
153
+ function captureOptionalString(value) {
154
+ return value === void 0 || typeof value === "string";
155
+ }
156
+ function captureOptionalNullableString(value) {
157
+ return value === void 0 || captureNullableString(value);
158
+ }
159
+ function captureFontRegistration(value) {
160
+ return captureRecord(value) && typeof value.family === "string" && value.family.length > 0 && captureOptionalString(value.url) && captureOptionalString(value.sourceLabel) && captureOptionalNullableString(value.parsedFamily) && captureOptionalNullableString(value.parsedPostScript) && captureOptionalNullableString(value.fullName);
161
+ }
162
+ function capturePoint(value) {
163
+ return captureRecord(value) && captureNumber(value.x) && captureNumber(value.y);
164
+ }
165
+ function captureNode(value) {
166
+ if (!captureRecord(value) || !captureInteger(value.nodeId) || !(value.parentNodeId === null || captureInteger(value.parentNodeId)) || !Array.isArray(value.childNodeIds) || !value.childNodeIds.every(captureInteger) || !captureInteger(value.paintIndex) || typeof value.type !== "string" || !captureNullableString(value.id) || !captureNullableString(value.testID) || !captureNullableString(value.text) || !captureInteger(value.childCount) || !captureRecord(value.accessibility) || !captureRecord(value.interaction) || !captureRecord(value.layout) || !captureRecord(value.style) || !captureRecord(value.source) || !captureRecord(value.props) || !captureRecord(value.inspection)) {
167
+ return false;
168
+ }
169
+ const accessibility = value.accessibility;
170
+ if (typeof accessibility.accessible !== "boolean" || !captureNullableString(accessibility.label) || !captureNullableString(accessibility.role) || !captureNullableString(accessibility.hint) || !(accessibility.liveRegion === null || accessibility.liveRegion === "none" || accessibility.liveRegion === "polite" || accessibility.liveRegion === "assertive") || !(accessibility.state === null || captureRecord(accessibility.state)) || !(accessibility.value === null || captureRecord(accessibility.value))) {
171
+ return false;
172
+ }
173
+ const interaction = value.interaction;
174
+ if (typeof interaction.pressed !== "boolean" || typeof interaction.pressable !== "boolean" || typeof interaction.textInput !== "boolean" || !(interaction.textSelection === null || captureRecord(interaction.textSelection)) || typeof interaction.secureTextEntry !== "boolean" || !captureNullableString(interaction.placeholder) || !capturePoint(interaction.scrollOffset) || !(interaction.zoomScale === null || captureNumber(interaction.zoomScale)) || typeof interaction.nativePinchEnabled !== "boolean" || !(interaction.contentOffsetProp === null || captureRecord(interaction.contentOffsetProp)) || !(interaction.strokeDashoffsetProp === null || captureNumber(interaction.strokeDashoffsetProp))) {
175
+ return false;
176
+ }
177
+ const layout = value.layout;
178
+ if (!captureRect(layout.local) || !(layout.frame === null || captureRect(layout.frame)) || !capturePoint(layout.absolutePosition) || !(layout.visibleFrame === null || captureRect(layout.visibleFrame))) {
179
+ return false;
180
+ }
181
+ const style = value.style;
182
+ return captureRecord(style.resolved) && captureRecord(style.authored) && captureRecord(style.computed) && captureRecord(style.tokenBindings) && (value.textLines === void 0 || Array.isArray(value.textLines));
183
+ }
184
+ function isRnxScreenCapture(value) {
185
+ if (!captureRecord(value) || value.contractVersion !== RNX_SCREEN_CAPTURE_VERSION || !captureInteger(value.capturedAt) || !captureRecord(value.tree) || !(value.fonts === void 0 || Array.isArray(value.fonts) && value.fonts.length <= 200 && value.fonts.every(captureFontRegistration)) || !(value.visual === void 0 || captureRecord(value.visual))) {
186
+ return false;
187
+ }
188
+ const tree = value.tree;
189
+ const visual = value.visual;
190
+ return captureRecord(tree.viewport) && captureInteger(tree.viewport.width) && tree.viewport.width > 0 && captureInteger(tree.viewport.height) && tree.viewport.height > 0 && captureInteger(tree.rootNodeId) && Array.isArray(tree.nodes) && tree.nodes.every(captureNode) && (visual === void 0 || visual.kind === "png" && (visual.producer === "headless-cpu-app-surface" || visual.producer === "browser-compositor-app-surface") && typeof visual.dataUri === "string" && visual.dataUri.startsWith("data:image/png;base64,") && captureInteger(visual.pixelWidth) && visual.pixelWidth > 0 && captureInteger(visual.pixelHeight) && visual.pixelHeight > 0);
191
+ }
192
+ function isRnxCaptureRegionAtlas(value) {
193
+ if (!captureRecord(value) || value.kind !== "png-atlas" || value.producer !== "headless-cpu-app-surface" || typeof value.dataUri !== "string" || !value.dataUri.startsWith("data:image/png;base64,") || !captureNumber(value.width) || value.width <= 0 || !captureNumber(value.height) || value.height <= 0 || !captureInteger(value.pixelWidth) || value.pixelWidth <= 0 || !captureInteger(value.pixelHeight) || value.pixelHeight <= 0 || !Array.isArray(value.regions) || value.regions.length === 0 || value.regions.length > 256) {
194
+ return false;
195
+ }
196
+ const scale = value.pixelWidth / value.width;
197
+ if (!Number.isInteger(scale) || scale < 1 || scale > 4 || Math.abs(value.height * scale - value.pixelHeight) > 1e-6) {
198
+ return false;
199
+ }
200
+ const keys = /* @__PURE__ */ new Set();
201
+ for (const region of value.regions) {
202
+ if (!captureRecord(region) || typeof region.key !== "string" || region.key.length === 0 || keys.has(region.key) || !captureInteger(region.nodeId) || region.nodeId <= 0 || !captureRect(region.frame) || region.frame.width <= 0 || region.frame.height <= 0 || !captureRect(region.source) || region.source.x < 0 || region.source.y < 0 || region.source.width !== region.frame.width || region.source.height !== region.frame.height || region.source.x + region.source.width > value.width || region.source.y + region.source.height > value.height) {
203
+ return false;
204
+ }
205
+ keys.add(region.key);
206
+ }
207
+ return true;
208
+ }
209
+ // Annotate the CommonJS export names for ESM import in node:
210
+ 0 && (module.exports = {
211
+ RNX_SCREEN_CAPTURE_VERSION,
212
+ isRnxCaptureRegionAtlas,
213
+ isRnxScreenCapture,
214
+ rnxCaptureRasterRegions,
215
+ rnxRasterFrames,
216
+ selectRnxRasterNodeIds
217
+ });
@@ -0,0 +1,187 @@
1
+ /*! rnx v0.1.383 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+
3
+ // src/capture-contract.ts
4
+ var RNX_SCREEN_CAPTURE_VERSION = 1;
5
+ function selectRnxRasterNodeIds(tree) {
6
+ const nodesById = new Map(tree.nodes.map((node) => [node.nodeId, node]));
7
+ const unsupported = /* @__PURE__ */ new Set();
8
+ for (const node of tree.nodes) {
9
+ const visibleFrame = node.visibleFrame ?? node.frame;
10
+ if (!visibleFrame || visibleFrame.width <= 0 || visibleFrame.height <= 0) continue;
11
+ if (node.type === "masked-view" || node.style._liquidGlass !== void 0 || node.style._liquidGlassEdge !== void 0) {
12
+ unsupported.add(node.nodeId);
13
+ }
14
+ }
15
+ for (const nodeId of [...unsupported]) {
16
+ let parentNodeId = nodesById.get(nodeId)?.parentNodeId ?? null;
17
+ while (parentNodeId !== null) {
18
+ if (unsupported.has(parentNodeId)) {
19
+ unsupported.delete(nodeId);
20
+ break;
21
+ }
22
+ parentNodeId = nodesById.get(parentNodeId)?.parentNodeId ?? null;
23
+ }
24
+ }
25
+ const screenArea = tree.width * tree.height;
26
+ const maxLayerArea = screenArea * 0.25;
27
+ const maxAtlasArea = screenArea * 0.5;
28
+ const candidates = [...unsupported].map((nodeId) => {
29
+ const node = nodesById.get(nodeId);
30
+ const frame = node?.visibleFrame ?? node?.frame;
31
+ return frame ? { nodeId, area: frame.width * frame.height } : null;
32
+ }).filter(
33
+ (candidate) => candidate !== null && candidate.area <= maxLayerArea
34
+ ).sort((left, right) => left.area - right.area || left.nodeId - right.nodeId);
35
+ const selected = /* @__PURE__ */ new Set();
36
+ let atlasArea = 0;
37
+ for (const candidate of candidates) {
38
+ if (atlasArea + candidate.area > maxAtlasArea) continue;
39
+ selected.add(candidate.nodeId);
40
+ atlasArea += candidate.area;
41
+ }
42
+ return selected;
43
+ }
44
+ function rnxRasterFrames(tree, nodeIds) {
45
+ const frames = /* @__PURE__ */ new Map();
46
+ for (const node of tree.nodes) {
47
+ if (!nodeIds.has(node.nodeId)) continue;
48
+ const frame = node.frame ?? {
49
+ x: node.absolutePosition.x,
50
+ y: node.absolutePosition.y,
51
+ width: node.layout.width,
52
+ height: node.layout.height
53
+ };
54
+ const liquidGlass = node.style._liquidGlass;
55
+ const capturePadding = liquidGlass && typeof liquidGlass === "object" && typeof Reflect.get(liquidGlass, "capturePadding") === "number" ? Reflect.get(liquidGlass, "capturePadding") : 0;
56
+ const shadowRadius = typeof node.style.shadowRadius === "number" ? node.style.shadowRadius : 0;
57
+ const shadowOffset = node.style.shadowOffset;
58
+ const shadowOffsetX = shadowOffset && typeof shadowOffset === "object" && typeof Reflect.get(shadowOffset, "width") === "number" ? Reflect.get(shadowOffset, "width") : 0;
59
+ const shadowOffsetY = shadowOffset && typeof shadowOffset === "object" && typeof Reflect.get(shadowOffset, "height") === "number" ? Reflect.get(shadowOffset, "height") : 0;
60
+ const left = Math.max(
61
+ 0,
62
+ frame.x - Math.max(capturePadding, shadowRadius - shadowOffsetX)
63
+ );
64
+ const top = Math.max(
65
+ 0,
66
+ frame.y - Math.max(capturePadding, shadowRadius - shadowOffsetY)
67
+ );
68
+ const right = Math.min(
69
+ tree.width,
70
+ frame.x + frame.width + Math.max(capturePadding, shadowRadius + shadowOffsetX)
71
+ );
72
+ const bottom = Math.min(
73
+ tree.height,
74
+ frame.y + frame.height + Math.max(capturePadding, shadowRadius + shadowOffsetY)
75
+ );
76
+ if (right > left && bottom > top) {
77
+ frames.set(node.nodeId, {
78
+ x: left,
79
+ y: top,
80
+ width: right - left,
81
+ height: bottom - top
82
+ });
83
+ }
84
+ }
85
+ return frames;
86
+ }
87
+ function rnxCaptureRasterRegions(capture) {
88
+ const tree = {
89
+ width: capture.tree.viewport.width,
90
+ height: capture.tree.viewport.height,
91
+ nodes: capture.tree.nodes.map((node) => ({
92
+ nodeId: node.nodeId,
93
+ parentNodeId: node.parentNodeId,
94
+ type: node.type,
95
+ style: node.style.resolved,
96
+ layout: node.layout.local,
97
+ frame: node.layout.frame,
98
+ absolutePosition: node.layout.absolutePosition,
99
+ visibleFrame: node.layout.visibleFrame
100
+ }))
101
+ };
102
+ const nodeIds = selectRnxRasterNodeIds(tree);
103
+ const frames = rnxRasterFrames(tree, nodeIds);
104
+ return [...nodeIds].flatMap((nodeId) => {
105
+ const frame = frames.get(nodeId);
106
+ return frame ? [{ key: String(nodeId), nodeId, frame }] : [];
107
+ });
108
+ }
109
+ function captureRecord(value) {
110
+ return value !== null && typeof value === "object" && !Array.isArray(value);
111
+ }
112
+ function captureInteger(value) {
113
+ return typeof value === "number" && Number.isSafeInteger(value);
114
+ }
115
+ function captureNumber(value) {
116
+ return typeof value === "number" && Number.isFinite(value);
117
+ }
118
+ function captureNullableString(value) {
119
+ return value === null || typeof value === "string";
120
+ }
121
+ function captureRect(value) {
122
+ return captureRecord(value) && captureNumber(value.x) && captureNumber(value.y) && captureNumber(value.width) && captureNumber(value.height);
123
+ }
124
+ function captureOptionalString(value) {
125
+ return value === void 0 || typeof value === "string";
126
+ }
127
+ function captureOptionalNullableString(value) {
128
+ return value === void 0 || captureNullableString(value);
129
+ }
130
+ function captureFontRegistration(value) {
131
+ return captureRecord(value) && typeof value.family === "string" && value.family.length > 0 && captureOptionalString(value.url) && captureOptionalString(value.sourceLabel) && captureOptionalNullableString(value.parsedFamily) && captureOptionalNullableString(value.parsedPostScript) && captureOptionalNullableString(value.fullName);
132
+ }
133
+ function capturePoint(value) {
134
+ return captureRecord(value) && captureNumber(value.x) && captureNumber(value.y);
135
+ }
136
+ function captureNode(value) {
137
+ if (!captureRecord(value) || !captureInteger(value.nodeId) || !(value.parentNodeId === null || captureInteger(value.parentNodeId)) || !Array.isArray(value.childNodeIds) || !value.childNodeIds.every(captureInteger) || !captureInteger(value.paintIndex) || typeof value.type !== "string" || !captureNullableString(value.id) || !captureNullableString(value.testID) || !captureNullableString(value.text) || !captureInteger(value.childCount) || !captureRecord(value.accessibility) || !captureRecord(value.interaction) || !captureRecord(value.layout) || !captureRecord(value.style) || !captureRecord(value.source) || !captureRecord(value.props) || !captureRecord(value.inspection)) {
138
+ return false;
139
+ }
140
+ const accessibility = value.accessibility;
141
+ if (typeof accessibility.accessible !== "boolean" || !captureNullableString(accessibility.label) || !captureNullableString(accessibility.role) || !captureNullableString(accessibility.hint) || !(accessibility.liveRegion === null || accessibility.liveRegion === "none" || accessibility.liveRegion === "polite" || accessibility.liveRegion === "assertive") || !(accessibility.state === null || captureRecord(accessibility.state)) || !(accessibility.value === null || captureRecord(accessibility.value))) {
142
+ return false;
143
+ }
144
+ const interaction = value.interaction;
145
+ if (typeof interaction.pressed !== "boolean" || typeof interaction.pressable !== "boolean" || typeof interaction.textInput !== "boolean" || !(interaction.textSelection === null || captureRecord(interaction.textSelection)) || typeof interaction.secureTextEntry !== "boolean" || !captureNullableString(interaction.placeholder) || !capturePoint(interaction.scrollOffset) || !(interaction.zoomScale === null || captureNumber(interaction.zoomScale)) || typeof interaction.nativePinchEnabled !== "boolean" || !(interaction.contentOffsetProp === null || captureRecord(interaction.contentOffsetProp)) || !(interaction.strokeDashoffsetProp === null || captureNumber(interaction.strokeDashoffsetProp))) {
146
+ return false;
147
+ }
148
+ const layout = value.layout;
149
+ if (!captureRect(layout.local) || !(layout.frame === null || captureRect(layout.frame)) || !capturePoint(layout.absolutePosition) || !(layout.visibleFrame === null || captureRect(layout.visibleFrame))) {
150
+ return false;
151
+ }
152
+ const style = value.style;
153
+ return captureRecord(style.resolved) && captureRecord(style.authored) && captureRecord(style.computed) && captureRecord(style.tokenBindings) && (value.textLines === void 0 || Array.isArray(value.textLines));
154
+ }
155
+ function isRnxScreenCapture(value) {
156
+ if (!captureRecord(value) || value.contractVersion !== RNX_SCREEN_CAPTURE_VERSION || !captureInteger(value.capturedAt) || !captureRecord(value.tree) || !(value.fonts === void 0 || Array.isArray(value.fonts) && value.fonts.length <= 200 && value.fonts.every(captureFontRegistration)) || !(value.visual === void 0 || captureRecord(value.visual))) {
157
+ return false;
158
+ }
159
+ const tree = value.tree;
160
+ const visual = value.visual;
161
+ return captureRecord(tree.viewport) && captureInteger(tree.viewport.width) && tree.viewport.width > 0 && captureInteger(tree.viewport.height) && tree.viewport.height > 0 && captureInteger(tree.rootNodeId) && Array.isArray(tree.nodes) && tree.nodes.every(captureNode) && (visual === void 0 || visual.kind === "png" && (visual.producer === "headless-cpu-app-surface" || visual.producer === "browser-compositor-app-surface") && typeof visual.dataUri === "string" && visual.dataUri.startsWith("data:image/png;base64,") && captureInteger(visual.pixelWidth) && visual.pixelWidth > 0 && captureInteger(visual.pixelHeight) && visual.pixelHeight > 0);
162
+ }
163
+ function isRnxCaptureRegionAtlas(value) {
164
+ if (!captureRecord(value) || value.kind !== "png-atlas" || value.producer !== "headless-cpu-app-surface" || typeof value.dataUri !== "string" || !value.dataUri.startsWith("data:image/png;base64,") || !captureNumber(value.width) || value.width <= 0 || !captureNumber(value.height) || value.height <= 0 || !captureInteger(value.pixelWidth) || value.pixelWidth <= 0 || !captureInteger(value.pixelHeight) || value.pixelHeight <= 0 || !Array.isArray(value.regions) || value.regions.length === 0 || value.regions.length > 256) {
165
+ return false;
166
+ }
167
+ const scale = value.pixelWidth / value.width;
168
+ if (!Number.isInteger(scale) || scale < 1 || scale > 4 || Math.abs(value.height * scale - value.pixelHeight) > 1e-6) {
169
+ return false;
170
+ }
171
+ const keys = /* @__PURE__ */ new Set();
172
+ for (const region of value.regions) {
173
+ if (!captureRecord(region) || typeof region.key !== "string" || region.key.length === 0 || keys.has(region.key) || !captureInteger(region.nodeId) || region.nodeId <= 0 || !captureRect(region.frame) || region.frame.width <= 0 || region.frame.height <= 0 || !captureRect(region.source) || region.source.x < 0 || region.source.y < 0 || region.source.width !== region.frame.width || region.source.height !== region.frame.height || region.source.x + region.source.width > value.width || region.source.y + region.source.height > value.height) {
174
+ return false;
175
+ }
176
+ keys.add(region.key);
177
+ }
178
+ return true;
179
+ }
180
+ export {
181
+ RNX_SCREEN_CAPTURE_VERSION,
182
+ isRnxCaptureRegionAtlas,
183
+ isRnxScreenCapture,
184
+ rnxCaptureRasterRegions,
185
+ rnxRasterFrames,
186
+ selectRnxRasterNodeIds
187
+ };
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.381 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.383 | (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;
@@ -0,0 +1,41 @@
1
+ /*! rnx v0.1.383 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
+ "use strict";
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
+
22
+ // src/cloud-contract.ts
23
+ var cloud_contract_exports = {};
24
+ __export(cloud_contract_exports, {
25
+ RNX_CLOUD_DESIGN_MAX_STORAGE_BYTES: () => RNX_CLOUD_DESIGN_MAX_STORAGE_BYTES,
26
+ RNX_CLOUD_DESIGN_MAX_STORAGE_ENTRIES: () => RNX_CLOUD_DESIGN_MAX_STORAGE_ENTRIES,
27
+ RNX_CLOUD_DESIGN_PARALLEL_JOB_LIMIT: () => RNX_CLOUD_DESIGN_PARALLEL_JOB_LIMIT,
28
+ RNX_CLOUD_MAX_ARTIFACT_BYTES: () => RNX_CLOUD_MAX_ARTIFACT_BYTES
29
+ });
30
+ module.exports = __toCommonJS(cloud_contract_exports);
31
+ var RNX_CLOUD_MAX_ARTIFACT_BYTES = 20 * 1024 * 1024;
32
+ var RNX_CLOUD_DESIGN_PARALLEL_JOB_LIMIT = 16;
33
+ var RNX_CLOUD_DESIGN_MAX_STORAGE_ENTRIES = 256;
34
+ var RNX_CLOUD_DESIGN_MAX_STORAGE_BYTES = 1024 * 1024;
35
+ // Annotate the CommonJS export names for ESM import in node:
36
+ 0 && (module.exports = {
37
+ RNX_CLOUD_DESIGN_MAX_STORAGE_BYTES,
38
+ RNX_CLOUD_DESIGN_MAX_STORAGE_ENTRIES,
39
+ RNX_CLOUD_DESIGN_PARALLEL_JOB_LIMIT,
40
+ RNX_CLOUD_MAX_ARTIFACT_BYTES
41
+ });
@@ -0,0 +1,13 @@
1
+ /*! rnx v0.1.383 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+
3
+ // src/cloud-contract.ts
4
+ var RNX_CLOUD_MAX_ARTIFACT_BYTES = 20 * 1024 * 1024;
5
+ var RNX_CLOUD_DESIGN_PARALLEL_JOB_LIMIT = 16;
6
+ var RNX_CLOUD_DESIGN_MAX_STORAGE_ENTRIES = 256;
7
+ var RNX_CLOUD_DESIGN_MAX_STORAGE_BYTES = 1024 * 1024;
8
+ export {
9
+ RNX_CLOUD_DESIGN_MAX_STORAGE_BYTES,
10
+ RNX_CLOUD_DESIGN_MAX_STORAGE_ENTRIES,
11
+ RNX_CLOUD_DESIGN_PARALLEL_JOB_LIMIT,
12
+ RNX_CLOUD_MAX_ARTIFACT_BYTES
13
+ };
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.381 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.383 | (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.381 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.383 | (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;
@@ -2536,8 +2536,8 @@ var device = {
2536
2536
  return screenshotPath;
2537
2537
  },
2538
2538
  // record the SootSim canvas via the engine's headless recorder
2539
- // (window.__sootsimRecorder — @sootsim/plugin-recording). this is the
2540
- // SAME code path `sootsim record video` drives, NOT the rail-button
2539
+ // (window.__sootsimRecorder — @rnx/plugin-recording). this is the
2540
+ // SAME code path `rnx record video` drives, NOT the rail-button
2541
2541
  // path (SootSim.bridges.startRecording wires the dialog state machine
2542
2542
  // and never stashes the resulting blob into __sootsimRecorder.lastBlob,
2543
2543
  // which is what getBlobBase64 streams from).
@@ -2567,7 +2567,7 @@ var device = {
2567
2567
  }
2568
2568
  },
2569
2569
  // stop the headless recorder, stream the resulting blob in chunks (same
2570
- // protocol as `sootsim record`), and write the webm to outPath.
2570
+ // protocol as `rnx record`), and write the webm to outPath.
2571
2571
  async stopAndSaveBridgeRecording(outPath) {
2572
2572
  const page = getPage();
2573
2573
  const stopResult = await page.evaluate(async () => {
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.381 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.383 | (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.381 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.383 | (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;
@@ -33,6 +33,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
33
33
  var home_paths_exports = {};
34
34
  __export(home_paths_exports, {
35
35
  ACTIVE_RUNTIME_FILE: () => ACTIVE_RUNTIME_FILE,
36
+ CLI_UPDATE_FILE: () => CLI_UPDATE_FILE,
36
37
  CONFIG_FILE: () => CONFIG_FILE,
37
38
  DAEMON_HEARTBEAT_STALE_MS: () => DAEMON_HEARTBEAT_STALE_MS,
38
39
  DAEMON_LOCKFILE: () => DAEMON_LOCKFILE,
@@ -43,6 +44,7 @@ __export(home_paths_exports, {
43
44
  cacheDir: () => cacheDir,
44
45
  cameraFixturesDir: () => cameraFixturesDir,
45
46
  claimDaemonLockfile: () => claimDaemonLockfile,
47
+ cliUpdateFilePath: () => cliUpdateFilePath,
46
48
  configFilePath: () => configFilePath,
47
49
  consumeRuntimeUpgradeNotice: () => consumeRuntimeUpgradeNotice,
48
50
  daemonAppBundlePath: () => daemonAppBundlePath,
@@ -94,6 +96,7 @@ var ACTIVE_RUNTIME_FILE = "active";
94
96
  var DAEMON_LOCKFILE = "daemon.json";
95
97
  var DEV_BRIDGES_DIR = "dev-bridges";
96
98
  var CONFIG_FILE = "config.json";
99
+ var CLI_UPDATE_FILE = "cli-update.json";
97
100
  var DAEMON_HEARTBEAT_STALE_MS = 3e4;
98
101
  function rnxHomeDir() {
99
102
  const override = process.env[RNX_HOME_ENV];
@@ -172,6 +175,9 @@ function devBridgeLockfilePath(bridgePort) {
172
175
  function configFilePath() {
173
176
  return import_node_path.default.join(rnxHomeDir(), CONFIG_FILE);
174
177
  }
178
+ function cliUpdateFilePath() {
179
+ return import_node_path.default.join(rnxHomeDir(), CLI_UPDATE_FILE);
180
+ }
175
181
  function readSharedConfig() {
176
182
  try {
177
183
  const raw = import_node_fs.default.readFileSync(configFilePath(), "utf8");
@@ -561,6 +567,7 @@ function removeDevBridgeLockfile(owner) {
561
567
  // Annotate the CommonJS export names for ESM import in node:
562
568
  0 && (module.exports = {
563
569
  ACTIVE_RUNTIME_FILE,
570
+ CLI_UPDATE_FILE,
564
571
  CONFIG_FILE,
565
572
  DAEMON_HEARTBEAT_STALE_MS,
566
573
  DAEMON_LOCKFILE,
@@ -571,6 +578,7 @@ function removeDevBridgeLockfile(owner) {
571
578
  cacheDir,
572
579
  cameraFixturesDir,
573
580
  claimDaemonLockfile,
581
+ cliUpdateFilePath,
574
582
  configFilePath,
575
583
  consumeRuntimeUpgradeNotice,
576
584
  daemonAppBundlePath,