peachsim 0.1.626 → 0.1.627

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 (82) hide show
  1. package/README.md +3 -2
  2. package/cli/commands/box/bundle-plane.ts +7 -2
  3. package/cli/commands/box.ts +9 -2
  4. package/cli/commands/control.ts +32 -1
  5. package/cli/commands/flow.ts +17 -6
  6. package/cli/commands/maestro-generate.ts +5 -12
  7. package/cli/commands/maestro.ts +16 -6
  8. package/cli/commands/platform.ts +1 -0
  9. package/cli/commands/test.ts +14 -0
  10. package/cli/commands/upload.ts +18 -8
  11. package/cli/drivers/playwright-sim-host.ts +10 -3
  12. package/cli/drivers/playwright.ts +8 -5
  13. package/cli/run-rnx.ts +8 -4
  14. package/dist-lib/agent-daemon-client.cjs +2 -1
  15. package/dist-lib/agent-events.cjs +1 -1
  16. package/dist-lib/agent-identity.cjs +1 -1
  17. package/dist-lib/agent-sessions.cjs +1 -1
  18. package/dist-lib/attached-projects.cjs +1 -1
  19. package/dist-lib/auth/shared-session.cjs +1 -1
  20. package/dist-lib/backend-origin.cjs +1 -1
  21. package/dist-lib/beta.cjs +1 -1
  22. package/dist-lib/beta.mjs +1 -1
  23. package/dist-lib/bridge-constants.cjs +4 -1
  24. package/dist-lib/bridge-contract-input.cjs +1 -1
  25. package/dist-lib/bridge-contract-input.mjs +1 -1
  26. package/dist-lib/bridge-contract.cjs +1 -1
  27. package/dist-lib/bridge-contract.mjs +1 -1
  28. package/dist-lib/capture-contract.cjs +18 -8
  29. package/dist-lib/capture-contract.mjs +18 -8
  30. package/dist-lib/cli-constants.cjs +1 -1
  31. package/dist-lib/cloud-contract.cjs +1 -1
  32. package/dist-lib/cloud-contract.mjs +1 -1
  33. package/dist-lib/cloud-test-args.cjs +1 -1
  34. package/dist-lib/cloud-test-args.mjs +1 -1
  35. package/dist-lib/cloud.cjs +1 -1
  36. package/dist-lib/cloud.mjs +1 -1
  37. package/dist-lib/config.cjs +1 -1
  38. package/dist-lib/detox/index.cjs +1 -1
  39. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  40. package/dist-lib/home-paths.cjs +1 -1
  41. package/dist-lib/host/bridge-host.cjs +239 -102
  42. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  43. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  44. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  45. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  46. package/dist-lib/host/websocket-proxy.cjs +1 -1
  47. package/dist-lib/index.cjs +19 -8
  48. package/dist-lib/jump-to-source-babel.cjs +1 -1
  49. package/dist-lib/jump-to-source-native.cjs +1 -1
  50. package/dist-lib/menu.cjs +1 -1
  51. package/dist-lib/menu.mjs +1 -1
  52. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  53. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  54. package/dist-lib/metro-production-bundle.cjs +1 -1
  55. package/dist-lib/metro-production-bundle.mjs +1 -1
  56. package/dist-lib/metro.cjs +1 -1
  57. package/dist-lib/profiles.cjs +1 -1
  58. package/dist-lib/public-brand.cjs +1 -1
  59. package/dist-lib/react-native-host-modules.cjs +1 -1
  60. package/dist-lib/react-native-host-modules.mjs +1 -1
  61. package/dist-lib/render-mode.cjs +1 -1
  62. package/dist-lib/scripts/dev-server-scanner.cjs +215 -28
  63. package/dist-lib/sdk.cjs +1 -1
  64. package/dist-lib/sdk.mjs +1 -1
  65. package/dist-lib/skills.cjs +292 -128
  66. package/dist-lib/swift-compile.cjs +1 -1
  67. package/dist-lib/swift-compile.mjs +1 -1
  68. package/dist-lib/swift-package.cjs +1 -1
  69. package/dist-lib/swift-package.mjs +1 -1
  70. package/dist-lib/swift-submit.cjs +1 -1
  71. package/dist-lib/swift-submit.mjs +1 -1
  72. package/dist-lib/swift.cjs +14488 -14349
  73. package/dist-lib/vite-kotlin.cjs +1 -1
  74. package/dist-lib/vite-swift.cjs +1 -1
  75. package/dist-lib/vite.cjs +2 -1
  76. package/install.mjs +16 -0
  77. package/install.sh +199 -0
  78. package/package.json +6 -1
  79. package/scripts/dev-server-scanner.ts +77 -46
  80. package/src/bridge-constants.ts +11 -0
  81. package/src/capture-contract.ts +40 -7
  82. package/src/host/bridge-host.ts +24 -103
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.626 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.627 | (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.626 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.627 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/metro-production-bundle.ts
4
4
  var RNXSIM_METRO_MODULE_PATHS_PREFIX = "globalThis.__sootsimModulePaths=";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.626 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.627 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.626 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.627 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.626 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.627 | (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.626 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.627 | (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.626 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.627 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/react-native-host-modules.ts
4
4
  var REACT_NATIVE_PASSTHROUGH_SPECIFIERS = [
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.626 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.627 | (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.626 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.627 | (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;
@@ -47,6 +47,161 @@ __export(dev_server_scanner_exports, {
47
47
  });
48
48
  module.exports = __toCommonJS(dev_server_scanner_exports);
49
49
  var import_child_process = require("child_process");
50
+
51
+ // ../contrast/src/runtime/process-group.ts
52
+ var import_node_child_process = require("node:child_process");
53
+
54
+ // ../contrast/src/sleep.ts
55
+ function sleep(ms) {
56
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
57
+ }
58
+
59
+ // ../contrast/src/runtime/process-group.ts
60
+ var GRACEFUL_TIMEOUT_MS = 3e3;
61
+ var FORCED_EXIT_TIMEOUT_MS = 1e3;
62
+ function signalProcessGroup(child, signal) {
63
+ if (!child.pid) return;
64
+ try {
65
+ process.kill(-child.pid, signal);
66
+ } catch {
67
+ try {
68
+ process.kill(child.pid, signal);
69
+ } catch {
70
+ }
71
+ }
72
+ }
73
+ function runningPids(pids) {
74
+ return pids.filter((pid) => {
75
+ try {
76
+ process.kill(pid, 0);
77
+ return true;
78
+ } catch (error) {
79
+ return error instanceof Error && "code" in error && error.code === "EPERM";
80
+ }
81
+ });
82
+ }
83
+ function groupIsEmpty(pgid) {
84
+ try {
85
+ process.kill(-pgid, 0);
86
+ } catch (error) {
87
+ if (!(error instanceof Error && "code" in error && error.code === "EPERM"))
88
+ return true;
89
+ }
90
+ const result = (0, import_node_child_process.spawnSync)("ps", ["-A", "-o", "pgid=,stat="], {
91
+ encoding: "utf8",
92
+ stdio: ["ignore", "pipe", "pipe"]
93
+ });
94
+ if (result.error || result.status !== 0) return false;
95
+ return !result.stdout.split("\n").some((line) => {
96
+ const [group, state] = line.trim().split(/\s+/);
97
+ return Number(group) === pgid && state !== void 0 && !state.startsWith("Z");
98
+ });
99
+ }
100
+ async function waitForExit(pids, pgid, timeoutMs) {
101
+ const deadline = Date.now() + timeoutMs;
102
+ const gone = () => runningPids(pids).length === 0 && groupIsEmpty(pgid);
103
+ while (Date.now() < deadline) {
104
+ if (gone()) return true;
105
+ await sleep(50);
106
+ }
107
+ return gone();
108
+ }
109
+ async function terminateProcessGroup(child, signal = "SIGTERM", gracefulTimeoutMs = GRACEFUL_TIMEOUT_MS) {
110
+ if (!child.pid) {
111
+ try {
112
+ child.kill(signal);
113
+ } catch {
114
+ }
115
+ return;
116
+ }
117
+ signalProcessGroup(child, "SIGSTOP");
118
+ const descendants = /* @__PURE__ */ new Set();
119
+ let parents = [child.pid];
120
+ let inspectionError = null;
121
+ while (parents.length > 0) {
122
+ const result = (0, import_node_child_process.spawnSync)("pgrep", ["-P", parents.join(",")], {
123
+ encoding: "utf8",
124
+ stdio: ["ignore", "pipe", "pipe"]
125
+ });
126
+ if (result.error || result.status !== 0 && result.status !== 1) {
127
+ inspectionError = new Error(
128
+ `could not inspect descendants of processes ${parents.join(",")}: ${result.error?.message || result.stderr.trim() || `pgrep exited ${result.status}`}`
129
+ );
130
+ break;
131
+ }
132
+ const next = [];
133
+ for (const line of result.stdout.split("\n")) {
134
+ const descendantPid = Number(line.trim());
135
+ if (Number.isInteger(descendantPid) && descendantPid > 1 && !descendants.has(descendantPid)) {
136
+ descendants.add(descendantPid);
137
+ next.push(descendantPid);
138
+ try {
139
+ process.kill(descendantPid, "SIGSTOP");
140
+ } catch {
141
+ }
142
+ }
143
+ }
144
+ parents = next;
145
+ }
146
+ const pids = [child.pid, ...descendants];
147
+ const gracefulDeadline = Date.now() + gracefulTimeoutMs;
148
+ try {
149
+ process.kill(child.pid, signal);
150
+ } catch {
151
+ }
152
+ signalProcessGroup(child, "SIGCONT");
153
+ for (const pid of descendants) {
154
+ try {
155
+ process.kill(pid, "SIGCONT");
156
+ } catch {
157
+ }
158
+ }
159
+ let rootExited = child.exitCode !== null || child.signalCode !== null;
160
+ if (!rootExited) {
161
+ rootExited = await new Promise((resolveExit) => {
162
+ const onExit = () => {
163
+ clearTimeout(deadlineTimer);
164
+ resolveExit(true);
165
+ };
166
+ const deadlineTimer = setTimeout(
167
+ () => {
168
+ child.removeListener("exit", onExit);
169
+ resolveExit(false);
170
+ },
171
+ Math.max(0, gracefulDeadline - Date.now())
172
+ );
173
+ child.once("exit", onExit);
174
+ if (child.exitCode !== null || child.signalCode !== null) {
175
+ child.removeListener("exit", onExit);
176
+ onExit();
177
+ }
178
+ });
179
+ }
180
+ if (rootExited) {
181
+ signalProcessGroup(child, signal);
182
+ for (const pid of descendants) {
183
+ try {
184
+ process.kill(pid, signal);
185
+ } catch {
186
+ }
187
+ }
188
+ }
189
+ if (await waitForExit(pids, child.pid, Math.max(0, gracefulDeadline - Date.now()))) {
190
+ if (inspectionError) throw inspectionError;
191
+ return;
192
+ }
193
+ for (const pid of pids) {
194
+ try {
195
+ process.kill(pid, "SIGKILL");
196
+ } catch {
197
+ }
198
+ }
199
+ signalProcessGroup(child, "SIGKILL");
200
+ await waitForExit(pids, child.pid, FORCED_EXIT_TIMEOUT_MS);
201
+ if (inspectionError) throw inspectionError;
202
+ }
203
+
204
+ // scripts/dev-server-scanner.ts
50
205
  var import_promises2 = require("fs/promises");
51
206
  var import_http = __toESM(require("http"), 1);
52
207
  var import_net = __toESM(require("net"), 1);
@@ -522,29 +677,51 @@ function optionalDemoAppsSync() {
522
677
  }
523
678
 
524
679
  // scripts/dev-server-scanner.ts
525
- var EXEC_EXIT_GRACE_MS = 2e3;
526
- async function execGuarded(command, timeout, extra = {}) {
527
- let child;
528
- const ran = new Promise((resolve2, reject) => {
529
- child = (0, import_child_process.exec)(command, { encoding: "utf8", timeout, ...extra }, (err, stdout) => {
680
+ function execGuarded(command, timeout, extra = {}) {
681
+ const maxBuffer = extra.maxBuffer ?? 1024 * 1024;
682
+ return new Promise((resolve2, reject) => {
683
+ const child = (0, import_child_process.spawn)("/bin/sh", ["-c", command], {
684
+ detached: true,
685
+ stdio: ["ignore", "pipe", "ignore"]
686
+ });
687
+ let stdout = "";
688
+ let settled = false;
689
+ let killing = false;
690
+ const settle = (err) => {
691
+ if (settled) return;
692
+ settled = true;
693
+ clearTimeout(deadline);
530
694
  if (err) reject(err);
531
695
  else resolve2({ stdout });
696
+ };
697
+ const killThenSettle = (err) => {
698
+ if (killing) return;
699
+ killing = true;
700
+ clearTimeout(deadline);
701
+ terminateProcessGroup(child, "SIGKILL", 0).finally(() => settle(err));
702
+ };
703
+ const deadline = setTimeout(() => {
704
+ killThenSettle(
705
+ Object.assign(new Error(`\`${command}\` did not exit within ${timeout}ms`), {
706
+ killed: true
707
+ })
708
+ );
709
+ }, timeout);
710
+ child.stdout.setEncoding("utf8");
711
+ child.stdout.on("data", (chunk) => {
712
+ stdout += chunk;
713
+ if (stdout.length > maxBuffer) {
714
+ killThenSettle(new Error(`\`${command}\` exceeded maxBuffer ${maxBuffer}`));
715
+ }
716
+ });
717
+ child.on("error", (err) => {
718
+ if (!killing) settle(err);
719
+ });
720
+ child.on("close", (code) => {
721
+ if (killing) return;
722
+ settle(code === 0 ? null : new Error(`\`${command}\` exited with ${code}`));
532
723
  });
533
724
  });
534
- let deadlineTimer;
535
- const deadline = new Promise((_resolve, reject) => {
536
- deadlineTimer = setTimeout(() => {
537
- child?.kill("SIGKILL");
538
- const err = new Error(`\`${command}\` did not exit within ${timeout}ms`);
539
- Object.assign(err, { killed: true });
540
- reject(err);
541
- }, timeout + EXEC_EXIT_GRACE_MS);
542
- });
543
- try {
544
- return await Promise.race([ran, deadline]);
545
- } finally {
546
- clearTimeout(deadlineTimer);
547
- }
548
725
  }
549
726
  var TIMEOUT_MS = 250;
550
727
  var MANIFEST_TIMEOUT_MS = 1500;
@@ -579,6 +756,7 @@ async function tcpPing(port, timeout = TCP_GATE_MS) {
579
756
  function httpGet(hostname, port, path, method = "GET", timeout = TIMEOUT_MS, headers = {}) {
580
757
  return new Promise((resolve2) => {
581
758
  let settled = false;
759
+ let killing = false;
582
760
  const settle = (value) => {
583
761
  if (settled) return;
584
762
  settled = true;
@@ -657,6 +835,21 @@ async function discoverListeningProcesses(excludePorts = []) {
657
835
  }
658
836
  async function scanListeningProcesses(excludePorts = []) {
659
837
  const excluded = new Set(excludePorts);
838
+ const listing = await listListenersShared();
839
+ if (listing.state === "could-not-look") return listing;
840
+ return {
841
+ state: "looked",
842
+ processes: listing.processes.filter((p) => acceptPort(p.port, excluded))
843
+ };
844
+ }
845
+ var inflightListing = null;
846
+ function listListenersShared() {
847
+ inflightListing ??= listListeners().finally(() => {
848
+ inflightListing = null;
849
+ });
850
+ return inflightListing;
851
+ }
852
+ async function listListeners() {
660
853
  let timedOut = false;
661
854
  try {
662
855
  const { stdout } = await execGuarded(
@@ -668,11 +861,9 @@ async function scanListeningProcesses(excludePorts = []) {
668
861
  const parts = line.trim().split(/\s+/);
669
862
  if (parts.length < 9) continue;
670
863
  const pid = Number(parts[1]);
671
- const addr = parts[8];
672
- const m = addr.match(/:(\d+)$/);
864
+ const m = parts[8].match(/:(\d+)$/);
673
865
  if (!m) continue;
674
866
  const port = Number(m[1]);
675
- if (!acceptPort(port, excluded)) continue;
676
867
  if (!seen.has(port)) seen.set(port, pid);
677
868
  }
678
869
  return {
@@ -694,7 +885,6 @@ async function scanListeningProcesses(excludePorts = []) {
694
885
  if (!portMatch) continue;
695
886
  const port = Number(portMatch[1]);
696
887
  const pid = pidMatch ? Number(pidMatch[1]) : 0;
697
- if (!acceptPort(port, excluded)) continue;
698
888
  if (!seen.has(port)) seen.set(port, pid);
699
889
  }
700
890
  return {
@@ -705,10 +895,7 @@ async function scanListeningProcesses(excludePorts = []) {
705
895
  if (wasKilledByTimeout(err)) timedOut = true;
706
896
  }
707
897
  if (timedOut) return { state: "could-not-look" };
708
- return {
709
- state: "looked",
710
- processes: FALLBACK_PORTS.filter((p) => acceptPort(p.port, excluded))
711
- };
898
+ return { state: "looked", processes: FALLBACK_PORTS };
712
899
  }
713
900
  async function discoverListeningPorts(excludePorts = []) {
714
901
  const processes = await discoverListeningProcesses(excludePorts);
package/dist-lib/sdk.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.626 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.627 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
package/dist-lib/sdk.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.626 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.627 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  var __defProp = Object.defineProperty;
3
3
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
4
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);