rnxsim 0.1.441 → 0.1.443

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 (71) hide show
  1. package/cli/bin.ts +3 -1
  2. package/cli/cloud-client.ts +153 -17
  3. package/cli/cloud-dispatch.ts +15 -0
  4. package/cli/cloud-session.ts +69 -17
  5. package/cli/commands/box/bundle-plane.ts +71 -0
  6. package/cli/commands/box.ts +274 -115
  7. package/cli/commands/control.ts +1 -137
  8. package/cli/commands/flow.ts +1 -1
  9. package/cli/commands/inspect/list.ts +119 -2
  10. package/cli/commands/inspect.ts +3 -2
  11. package/cli/commands/platform.ts +95 -12
  12. package/cli/commands/reset.ts +7 -3
  13. package/cli/commands/state.ts +7 -3
  14. package/cli/flow-export.ts +55 -0
  15. package/cli/flow-session.ts +0 -47
  16. package/cli/outbound-endpoints.ts +5 -0
  17. package/cli/rnx-in-process.ts +98 -0
  18. package/cli/ws-bridge.ts +30 -0
  19. package/dist-lib/agent-daemon-client.cjs +1 -1
  20. package/dist-lib/agent-events.cjs +1 -1
  21. package/dist-lib/agent-identity.cjs +1 -1
  22. package/dist-lib/agent-sessions.cjs +1 -1
  23. package/dist-lib/attached-projects.cjs +1 -1
  24. package/dist-lib/auth/shared-session.cjs +1 -1
  25. package/dist-lib/backend-origin.cjs +1 -1
  26. package/dist-lib/beta.cjs +1 -1
  27. package/dist-lib/beta.mjs +1 -1
  28. package/dist-lib/bridge-constants.cjs +1 -1
  29. package/dist-lib/bridge-contract-input.cjs +1 -1
  30. package/dist-lib/bridge-contract-input.mjs +1 -1
  31. package/dist-lib/bridge-contract.cjs +1 -1
  32. package/dist-lib/bridge-contract.mjs +1 -1
  33. package/dist-lib/capture-contract.cjs +1 -1
  34. package/dist-lib/capture-contract.mjs +1 -1
  35. package/dist-lib/cli-constants.cjs +1 -1
  36. package/dist-lib/cloud-contract.cjs +1 -1
  37. package/dist-lib/cloud-contract.mjs +1 -1
  38. package/dist-lib/cloud.cjs +1 -1
  39. package/dist-lib/cloud.mjs +1 -1
  40. package/dist-lib/config.cjs +1 -1
  41. package/dist-lib/detox/index.cjs +69 -14
  42. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  43. package/dist-lib/home-paths.cjs +17 -1
  44. package/dist-lib/host/bridge-host.cjs +24 -13
  45. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  46. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  47. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  48. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  49. package/dist-lib/host/websocket-proxy.cjs +1 -1
  50. package/dist-lib/index.cjs +1 -3
  51. package/dist-lib/jump-to-source-babel.cjs +1 -1
  52. package/dist-lib/menu.cjs +6 -19
  53. package/dist-lib/menu.mjs +6 -19
  54. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  55. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  56. package/dist-lib/metro-production-bundle.cjs +1 -1
  57. package/dist-lib/metro-production-bundle.mjs +1 -1
  58. package/dist-lib/metro.cjs +1 -1
  59. package/dist-lib/profiles.cjs +1 -1
  60. package/dist-lib/public-brand.cjs +1 -1
  61. package/dist-lib/react-native-host-modules.cjs +1 -1
  62. package/dist-lib/react-native-host-modules.mjs +1 -1
  63. package/dist-lib/render-mode.cjs +1 -1
  64. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  65. package/dist-lib/sdk.cjs +1 -1
  66. package/dist-lib/sdk.mjs +1 -1
  67. package/dist-lib/skills.cjs +274 -195
  68. package/dist-lib/vite.cjs +1 -1
  69. package/package.json +8 -1
  70. package/src/home-paths.ts +31 -1
  71. package/src/menu.ts +4 -17
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.441 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.443 | (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;
@@ -89,6 +89,16 @@ function assertGpuBrowserCommand(command, runtime = currentRuntime()) {
89
89
  `[reap-browser] Chrome process did not retain the required ${angle} GPU arguments`
90
90
  );
91
91
  }
92
+ for (const name2 of ["--enable-features=", "--disable-features="]) {
93
+ const lists = args.filter((arg) => arg.startsWith(name2)).map((arg) => arg.slice(name2.length).split(",").filter(Boolean));
94
+ const kept = new Set(lists.at(-1) ?? []);
95
+ const dropped = lists.slice(0, -1).flat().filter((feature) => !kept.has(feature));
96
+ if (dropped.length > 0) {
97
+ throw new Error(
98
+ `[reap-browser] Chrome keeps only its last ${name2.slice(0, -1)} switch, which dropped ${dropped.join(",")}; add them to the merged list in scripts/lib/reap-browser.ts`
99
+ );
100
+ }
101
+ }
92
102
  if (runtime.platform === "darwin" && command.includes("/Applications/Google Chrome.app/")) {
93
103
  throw new Error(
94
104
  "[reap-browser] refused the user's installed Google Chrome; use Playwright channel chromium"
@@ -361,6 +371,26 @@ function gpuChromeArgs(platform = process.platform) {
361
371
  "--ignore-gpu-blocklist"
362
372
  ];
363
373
  }
374
+ function mergeFeatureSwitches(args, enabled = []) {
375
+ const enable = /* @__PURE__ */ new Set([...PLAYWRIGHT_ENABLED_FEATURES, ...enabled]);
376
+ const disable = /* @__PURE__ */ new Set([...PLAYWRIGHT_DISABLED_FEATURES, ...DISABLED_FEATURES]);
377
+ const rest = [];
378
+ for (const arg of args) {
379
+ const match = /^--(enable|disable)-features=(.*)$/.exec(arg);
380
+ if (!match) {
381
+ rest.push(arg);
382
+ continue;
383
+ }
384
+ for (const feature of match[2].split(",")) {
385
+ if (feature) (match[1] === "enable" ? enable : disable).add(feature);
386
+ }
387
+ }
388
+ return [
389
+ ...rest,
390
+ `--enable-features=${[...enable].join(",")}`,
391
+ `--disable-features=${[...disable].join(",")}`
392
+ ];
393
+ }
364
394
  function gpuChromeLaunchOptions(opts = {}, runtime = currentRuntime()) {
365
395
  const callerArgs = Array.isArray(opts.args) ? opts.args : [];
366
396
  const unsafe = callerArgs.find(isSoftwareRendererArgument);
@@ -401,7 +431,10 @@ function gpuChromeLaunchOptions(opts = {}, runtime = currentRuntime()) {
401
431
  // com.google.chrome.for.testing, so automation cannot become the target of
402
432
  // Dock open/quit events intended for the user's com.google.Chrome browser.
403
433
  channel: "chromium",
404
- args: [...unmanagedCallerArgs, ...gpuChromeArgs(runtime.platform)],
434
+ args: mergeFeatureSwitches([
435
+ ...unmanagedCallerArgs,
436
+ ...gpuChromeArgs(runtime.platform)
437
+ ]),
405
438
  ignoreDefaultArgs: ignoredDefaults
406
439
  };
407
440
  }
@@ -449,21 +482,23 @@ function softwareChromeLaunchOptions(opts) {
449
482
  }
450
483
  const callerArgs = Array.isArray(opts.args) ? opts.args.map(String) : [];
451
484
  const unmanagedCallerArgs = callerArgs.filter((arg) => {
452
- return !arg.startsWith("--use-angle=") && arg !== "--enable-gpu" && arg !== "--enable-gpu-rasterization" && arg !== "--enable-zero-copy" && arg !== "--ignore-gpu-blocklist" && !/^--enable-unsafe-webgpu(?:=.*)?$/i.test(arg) && !/^--enable-features=(?:Vulkan|WebGPU)(?:,(?:Vulkan|WebGPU))*$/i.test(arg) && !/^--enable-unsafe-swiftshader(?:=.*)?$/i.test(arg);
485
+ return !arg.startsWith("--use-angle=") && arg !== "--enable-gpu" && arg !== "--enable-gpu-rasterization" && arg !== "--enable-zero-copy" && arg !== "--ignore-gpu-blocklist" && !/^--enable-unsafe-webgpu(?:=.*)?$/i.test(arg) && !/^--enable-unsafe-swiftshader(?:=.*)?$/i.test(arg);
453
486
  });
454
487
  const software = {
455
488
  ...opts,
456
- args: [
457
- ...unmanagedCallerArgs,
458
- "--use-angle=swiftshader",
459
- "--enable-unsafe-swiftshader",
460
- // playwright's bundled software chromium exposes no navigator.gpu without
461
- // these two, and the compositor's only backend is webgpu. emitted here
462
- // rather than per caller so a hosted-linux launch and a local gpu launch
463
- // agree on what a sim needs.
464
- "--enable-unsafe-webgpu",
465
- "--enable-features=Vulkan"
466
- ]
489
+ // playwright's bundled software chromium exposes no navigator.gpu without
490
+ // --enable-unsafe-webgpu plus the Vulkan feature, and the compositor's only
491
+ // backend is webgpu. emitted here rather than per caller so a hosted-linux
492
+ // launch and a local gpu launch agree on what a sim needs.
493
+ args: mergeFeatureSwitches(
494
+ [
495
+ ...unmanagedCallerArgs,
496
+ "--use-angle=swiftshader",
497
+ "--enable-unsafe-swiftshader",
498
+ "--enable-unsafe-webgpu"
499
+ ],
500
+ ["Vulkan"]
501
+ )
467
502
  };
468
503
  delete software.channel;
469
504
  delete software.executablePath;
@@ -478,7 +513,7 @@ async function launchReapedChrome(launch3, opts = {}, rendererTarget, policy = {
478
513
  policy.processIdentity
479
514
  );
480
515
  }
481
- var import_node_child_process, discoveredChromePids, discoveredChromeProcesses, reapPids, installed, signalShutdownClaimed;
516
+ var import_node_child_process, discoveredChromePids, discoveredChromeProcesses, reapPids, installed, signalShutdownClaimed, PLAYWRIGHT_DISABLED_FEATURES, PLAYWRIGHT_ENABLED_FEATURES, DISABLED_FEATURES;
482
517
  var init_reap_browser = __esm({
483
518
  "../../scripts/lib/reap-browser.ts"() {
484
519
  "use strict";
@@ -488,6 +523,26 @@ var init_reap_browser = __esm({
488
523
  reapPids = /* @__PURE__ */ new Map();
489
524
  installed = false;
490
525
  signalShutdownClaimed = false;
526
+ PLAYWRIGHT_DISABLED_FEATURES = [
527
+ "AvoidUnnecessaryBeforeUnloadCheckSync",
528
+ "BoundaryEventDispatchTracksNodeRemoval",
529
+ "DestroyProfileOnBrowserClose",
530
+ "DialMediaRouteProvider",
531
+ "GlobalMediaControls",
532
+ "HttpsUpgrades",
533
+ "LensOverlay",
534
+ "MediaRouter",
535
+ "PaintHolding",
536
+ "ThirdPartyStoragePartitioning",
537
+ "Translate",
538
+ "AutoDeElevate",
539
+ "RenderDocument",
540
+ "OptimizationHints",
541
+ "msForceBrowserSignIn",
542
+ "msEdgeUpdateLaunchServicesPreferredVersion"
543
+ ];
544
+ PLAYWRIGHT_ENABLED_FEATURES = ["CDPScreenshotNewSurface"];
545
+ DISABLED_FEATURES = ["NetworkTimeServiceQuerying"];
491
546
  }
492
547
  });
493
548
 
@@ -522,7 +577,7 @@ var init_capability_inventory_coverage = __esm({
522
577
  weighted: {
523
578
  covered: 0,
524
579
  ratio: 0,
525
- total: 11841
580
+ total: 4.92390995252
526
581
  }
527
582
  },
528
583
  semantic: {
@@ -534,7 +589,7 @@ var init_capability_inventory_coverage = __esm({
534
589
  weighted: {
535
590
  covered: 0,
536
591
  ratio: 0,
537
- total: 7842
592
+ total: 2.52717561504
538
593
  }
539
594
  },
540
595
  visual: {
@@ -546,7 +601,7 @@ var init_capability_inventory_coverage = __esm({
546
601
  weighted: {
547
602
  covered: 0,
548
603
  ratio: 0,
549
- total: 3999
604
+ total: 2.39673433748
550
605
  }
551
606
  },
552
607
  byPlatform: {
@@ -560,7 +615,7 @@ var init_capability_inventory_coverage = __esm({
560
615
  weighted: {
561
616
  covered: 0,
562
617
  ratio: 0,
563
- total: 10747
618
+ total: 4.82231702104
564
619
  }
565
620
  },
566
621
  semantic: {
@@ -572,7 +627,7 @@ var init_capability_inventory_coverage = __esm({
572
627
  weighted: {
573
628
  covered: 0,
574
629
  ratio: 0,
575
- total: 6998
630
+ total: 2.46477911515
576
631
  }
577
632
  },
578
633
  visual: {
@@ -584,7 +639,7 @@ var init_capability_inventory_coverage = __esm({
584
639
  weighted: {
585
640
  covered: 0,
586
641
  ratio: 0,
587
- total: 3749
642
+ total: 2.35753790589
588
643
  }
589
644
  }
590
645
  },
@@ -598,7 +653,7 @@ var init_capability_inventory_coverage = __esm({
598
653
  weighted: {
599
654
  covered: 0,
600
655
  ratio: 0,
601
- total: 10787
656
+ total: 4.78141583721
602
657
  }
603
658
  },
604
659
  semantic: {
@@ -610,7 +665,7 @@ var init_capability_inventory_coverage = __esm({
610
665
  weighted: {
611
666
  covered: 0,
612
667
  ratio: 0,
613
- total: 7077
668
+ total: 2.39581119032
614
669
  }
615
670
  },
616
671
  visual: {
@@ -622,7 +677,7 @@ var init_capability_inventory_coverage = __esm({
622
677
  weighted: {
623
678
  covered: 0,
624
679
  ratio: 0,
625
- total: 3710
680
+ total: 2.38560464689
626
681
  }
627
682
  }
628
683
  }
@@ -638,7 +693,7 @@ var init_capability_inventory_coverage = __esm({
638
693
  weighted: {
639
694
  covered: 0,
640
695
  ratio: 0,
641
- total: 734
696
+ total: 5.68951644615
642
697
  }
643
698
  },
644
699
  semantic: {
@@ -650,7 +705,7 @@ var init_capability_inventory_coverage = __esm({
650
705
  weighted: {
651
706
  covered: 0,
652
707
  ratio: 0,
653
- total: 379
708
+ total: 4.25353097536
654
709
  }
655
710
  },
656
711
  visual: {
@@ -662,7 +717,7 @@ var init_capability_inventory_coverage = __esm({
662
717
  weighted: {
663
718
  covered: 0,
664
719
  ratio: 0,
665
- total: 355
720
+ total: 1.43598547079
666
721
  }
667
722
  },
668
723
  byPlatform: {
@@ -676,7 +731,7 @@ var init_capability_inventory_coverage = __esm({
676
731
  weighted: {
677
732
  covered: 0,
678
733
  ratio: 0,
679
- total: 734
734
+ total: 5.68951644615
680
735
  }
681
736
  },
682
737
  semantic: {
@@ -688,7 +743,7 @@ var init_capability_inventory_coverage = __esm({
688
743
  weighted: {
689
744
  covered: 0,
690
745
  ratio: 0,
691
- total: 379
746
+ total: 4.25353097536
692
747
  }
693
748
  },
694
749
  visual: {
@@ -700,7 +755,7 @@ var init_capability_inventory_coverage = __esm({
700
755
  weighted: {
701
756
  covered: 0,
702
757
  ratio: 0,
703
- total: 355
758
+ total: 1.43598547079
704
759
  }
705
760
  }
706
761
  },
@@ -714,7 +769,7 @@ var init_capability_inventory_coverage = __esm({
714
769
  weighted: {
715
770
  covered: 0,
716
771
  ratio: 0,
717
- total: 734
772
+ total: 5.68951644615
718
773
  }
719
774
  },
720
775
  semantic: {
@@ -726,7 +781,7 @@ var init_capability_inventory_coverage = __esm({
726
781
  weighted: {
727
782
  covered: 0,
728
783
  ratio: 0,
729
- total: 379
784
+ total: 4.25353097536
730
785
  }
731
786
  },
732
787
  visual: {
@@ -738,7 +793,7 @@ var init_capability_inventory_coverage = __esm({
738
793
  weighted: {
739
794
  covered: 0,
740
795
  ratio: 0,
741
- total: 355
796
+ total: 1.43598547079
742
797
  }
743
798
  }
744
799
  }
@@ -754,7 +809,7 @@ var init_capability_inventory_coverage = __esm({
754
809
  weighted: {
755
810
  covered: 0,
756
811
  ratio: 0,
757
- total: 389
812
+ total: 7.7344109777
758
813
  }
759
814
  },
760
815
  semantic: {
@@ -766,7 +821,7 @@ var init_capability_inventory_coverage = __esm({
766
821
  weighted: {
767
822
  covered: 0,
768
823
  ratio: 0,
769
- total: 317
824
+ total: 4.998
770
825
  }
771
826
  },
772
827
  visual: {
@@ -778,7 +833,7 @@ var init_capability_inventory_coverage = __esm({
778
833
  weighted: {
779
834
  covered: 0,
780
835
  ratio: 0,
781
- total: 72
836
+ total: 2.7364109777
782
837
  }
783
838
  },
784
839
  byPlatform: {
@@ -792,7 +847,7 @@ var init_capability_inventory_coverage = __esm({
792
847
  weighted: {
793
848
  covered: 0,
794
849
  ratio: 0,
795
- total: 389
850
+ total: 7.7344109777
796
851
  }
797
852
  },
798
853
  semantic: {
@@ -804,7 +859,7 @@ var init_capability_inventory_coverage = __esm({
804
859
  weighted: {
805
860
  covered: 0,
806
861
  ratio: 0,
807
- total: 317
862
+ total: 4.998
808
863
  }
809
864
  },
810
865
  visual: {
@@ -816,7 +871,7 @@ var init_capability_inventory_coverage = __esm({
816
871
  weighted: {
817
872
  covered: 0,
818
873
  ratio: 0,
819
- total: 72
874
+ total: 2.7364109777
820
875
  }
821
876
  }
822
877
  },
@@ -830,7 +885,7 @@ var init_capability_inventory_coverage = __esm({
830
885
  weighted: {
831
886
  covered: 0,
832
887
  ratio: 0,
833
- total: 389
888
+ total: 7.7344109777
834
889
  }
835
890
  },
836
891
  semantic: {
@@ -842,7 +897,7 @@ var init_capability_inventory_coverage = __esm({
842
897
  weighted: {
843
898
  covered: 0,
844
899
  ratio: 0,
845
- total: 317
900
+ total: 4.998
846
901
  }
847
902
  },
848
903
  visual: {
@@ -854,7 +909,7 @@ var init_capability_inventory_coverage = __esm({
854
909
  weighted: {
855
910
  covered: 0,
856
911
  ratio: 0,
857
- total: 72
912
+ total: 2.7364109777
858
913
  }
859
914
  }
860
915
  }
@@ -870,7 +925,7 @@ var init_capability_inventory_coverage = __esm({
870
925
  weighted: {
871
926
  covered: 0,
872
927
  ratio: 0,
873
- total: 2526
928
+ total: 7.61737830756
874
929
  }
875
930
  },
876
931
  semantic: {
@@ -882,7 +937,7 @@ var init_capability_inventory_coverage = __esm({
882
937
  weighted: {
883
938
  covered: 0,
884
939
  ratio: 0,
885
- total: 1331
940
+ total: 4.15717529811
886
941
  }
887
942
  },
888
943
  visual: {
@@ -894,7 +949,7 @@ var init_capability_inventory_coverage = __esm({
894
949
  weighted: {
895
950
  covered: 0,
896
951
  ratio: 0,
897
- total: 1195
952
+ total: 3.46020300945
898
953
  }
899
954
  },
900
955
  byPlatform: {
@@ -908,7 +963,7 @@ var init_capability_inventory_coverage = __esm({
908
963
  weighted: {
909
964
  covered: 0,
910
965
  ratio: 0,
911
- total: 2526
966
+ total: 7.61737830756
912
967
  }
913
968
  },
914
969
  semantic: {
@@ -920,7 +975,7 @@ var init_capability_inventory_coverage = __esm({
920
975
  weighted: {
921
976
  covered: 0,
922
977
  ratio: 0,
923
- total: 1331
978
+ total: 4.15717529811
924
979
  }
925
980
  },
926
981
  visual: {
@@ -932,7 +987,7 @@ var init_capability_inventory_coverage = __esm({
932
987
  weighted: {
933
988
  covered: 0,
934
989
  ratio: 0,
935
- total: 1195
990
+ total: 3.46020300945
936
991
  }
937
992
  }
938
993
  },
@@ -946,7 +1001,7 @@ var init_capability_inventory_coverage = __esm({
946
1001
  weighted: {
947
1002
  covered: 0,
948
1003
  ratio: 0,
949
- total: 2526
1004
+ total: 7.61737830756
950
1005
  }
951
1006
  },
952
1007
  semantic: {
@@ -958,7 +1013,7 @@ var init_capability_inventory_coverage = __esm({
958
1013
  weighted: {
959
1014
  covered: 0,
960
1015
  ratio: 0,
961
- total: 1331
1016
+ total: 4.15717529811
962
1017
  }
963
1018
  },
964
1019
  visual: {
@@ -970,7 +1025,7 @@ var init_capability_inventory_coverage = __esm({
970
1025
  weighted: {
971
1026
  covered: 0,
972
1027
  ratio: 0,
973
- total: 1195
1028
+ total: 3.46020300945
974
1029
  }
975
1030
  }
976
1031
  }
@@ -986,7 +1041,7 @@ var init_capability_inventory_coverage = __esm({
986
1041
  weighted: {
987
1042
  covered: 0,
988
1043
  ratio: 0,
989
- total: 519
1044
+ total: 7.9894117647
990
1045
  }
991
1046
  },
992
1047
  semantic: {
@@ -998,7 +1053,7 @@ var init_capability_inventory_coverage = __esm({
998
1053
  weighted: {
999
1054
  covered: 0,
1000
1055
  ratio: 0,
1001
- total: 267
1056
+ total: 4.00352941176
1002
1057
  }
1003
1058
  },
1004
1059
  visual: {
@@ -1010,7 +1065,7 @@ var init_capability_inventory_coverage = __esm({
1010
1065
  weighted: {
1011
1066
  covered: 0,
1012
1067
  ratio: 0,
1013
- total: 252
1068
+ total: 3.98588235294
1014
1069
  }
1015
1070
  },
1016
1071
  byPlatform: {
@@ -1024,7 +1079,7 @@ var init_capability_inventory_coverage = __esm({
1024
1079
  weighted: {
1025
1080
  covered: 0,
1026
1081
  ratio: 0,
1027
- total: 519
1082
+ total: 7.9894117647
1028
1083
  }
1029
1084
  },
1030
1085
  semantic: {
@@ -1036,7 +1091,7 @@ var init_capability_inventory_coverage = __esm({
1036
1091
  weighted: {
1037
1092
  covered: 0,
1038
1093
  ratio: 0,
1039
- total: 267
1094
+ total: 4.00352941176
1040
1095
  }
1041
1096
  },
1042
1097
  visual: {
@@ -1048,7 +1103,7 @@ var init_capability_inventory_coverage = __esm({
1048
1103
  weighted: {
1049
1104
  covered: 0,
1050
1105
  ratio: 0,
1051
- total: 252
1106
+ total: 3.98588235294
1052
1107
  }
1053
1108
  }
1054
1109
  },
@@ -1062,7 +1117,7 @@ var init_capability_inventory_coverage = __esm({
1062
1117
  weighted: {
1063
1118
  covered: 0,
1064
1119
  ratio: 0,
1065
- total: 519
1120
+ total: 7.9894117647
1066
1121
  }
1067
1122
  },
1068
1123
  semantic: {
@@ -1074,7 +1129,7 @@ var init_capability_inventory_coverage = __esm({
1074
1129
  weighted: {
1075
1130
  covered: 0,
1076
1131
  ratio: 0,
1077
- total: 267
1132
+ total: 4.00352941176
1078
1133
  }
1079
1134
  },
1080
1135
  visual: {
@@ -1086,7 +1141,7 @@ var init_capability_inventory_coverage = __esm({
1086
1141
  weighted: {
1087
1142
  covered: 0,
1088
1143
  ratio: 0,
1089
- total: 252
1144
+ total: 3.98588235294
1090
1145
  }
1091
1146
  }
1092
1147
  }
@@ -1102,7 +1157,7 @@ var init_capability_inventory_coverage = __esm({
1102
1157
  weighted: {
1103
1158
  covered: 0,
1104
1159
  ratio: 0,
1105
- total: 932
1160
+ total: 4.1022362527
1106
1161
  }
1107
1162
  },
1108
1163
  semantic: {
@@ -1114,7 +1169,7 @@ var init_capability_inventory_coverage = __esm({
1114
1169
  weighted: {
1115
1170
  covered: 0,
1116
1171
  ratio: 0,
1117
- total: 154
1172
+ total: 0.0952595085136
1118
1173
  }
1119
1174
  },
1120
1175
  visual: {
@@ -1126,7 +1181,7 @@ var init_capability_inventory_coverage = __esm({
1126
1181
  weighted: {
1127
1182
  covered: 0,
1128
1183
  ratio: 0,
1129
- total: 778
1184
+ total: 4.00697674419
1130
1185
  }
1131
1186
  },
1132
1187
  byPlatform: {
@@ -1140,7 +1195,7 @@ var init_capability_inventory_coverage = __esm({
1140
1195
  weighted: {
1141
1196
  covered: 0,
1142
1197
  ratio: 0,
1143
- total: 932
1198
+ total: 4.1022362527
1144
1199
  }
1145
1200
  },
1146
1201
  semantic: {
@@ -1152,7 +1207,7 @@ var init_capability_inventory_coverage = __esm({
1152
1207
  weighted: {
1153
1208
  covered: 0,
1154
1209
  ratio: 0,
1155
- total: 154
1210
+ total: 0.0952595085136
1156
1211
  }
1157
1212
  },
1158
1213
  visual: {
@@ -1164,7 +1219,7 @@ var init_capability_inventory_coverage = __esm({
1164
1219
  weighted: {
1165
1220
  covered: 0,
1166
1221
  ratio: 0,
1167
- total: 778
1222
+ total: 4.00697674419
1168
1223
  }
1169
1224
  }
1170
1225
  },
@@ -1178,7 +1233,7 @@ var init_capability_inventory_coverage = __esm({
1178
1233
  weighted: {
1179
1234
  covered: 0,
1180
1235
  ratio: 0,
1181
- total: 932
1236
+ total: 4.1022362527
1182
1237
  }
1183
1238
  },
1184
1239
  semantic: {
@@ -1190,7 +1245,7 @@ var init_capability_inventory_coverage = __esm({
1190
1245
  weighted: {
1191
1246
  covered: 0,
1192
1247
  ratio: 0,
1193
- total: 154
1248
+ total: 0.0952595085136
1194
1249
  }
1195
1250
  },
1196
1251
  visual: {
@@ -1202,7 +1257,7 @@ var init_capability_inventory_coverage = __esm({
1202
1257
  weighted: {
1203
1258
  covered: 0,
1204
1259
  ratio: 0,
1205
- total: 778
1260
+ total: 4.00697674419
1206
1261
  }
1207
1262
  }
1208
1263
  }
@@ -1826,8 +1881,7 @@ var init_registry = __esm({
1826
1881
  coverageSource: "estimated",
1827
1882
  capabilityCoverage: CAPABILITY_INVENTORY_PACKAGE_COVERAGE["react-native-gesture-handler"],
1828
1883
  note: "tap, pan, pinch, rotation, fling, long press, race, manual, simultaneous, force touch unavailable-hardware parity",
1829
- working: "GestureDetector, Gesture.Tap/Pan/Pinch/Rotation/Fling/LongPress/ForceTouch/Manual/Race/Simultaneous/Exclusive/Hover, ForceTouchGestureHandler unavailable-hardware fallback (children render, forceTouchAvailable false, no force events), simultaneousWithExternalGesture/requireExternalGestureToFail/blocksExternalGesture, ScrollView/FlatList, Switch/RefreshControl, Pressable/Text, Touchables, BaseButton/RawButton/RectButton/BorderlessButton/PureNativeButton, Swipeable, ReanimatedSwipeable, DrawerLayout (the upstream component running on this seam: renderNavigationView, drawerPosition/drawerType/drawerWidth/edgeWidth, openDrawer/closeDrawer, edge-swipe drag, onDrawerOpen/onDrawerClose/onDrawerStateChanged), GestureHandlerRootView, createNativeWrapper, gestureHandlerRootHOC, PointerType/MouseButton/HoverEffect exports, velocity tracking, activeOffsets, multi-tap",
1830
- missing: "Force Touch recognition is unavailable because browser pointer input has no pressure signal; both public APIs expose the upstream unavailable-hardware behavior instead of inventing force events"
1884
+ working: "GestureDetector, Gesture.Tap/Pan/Pinch/Rotation/Fling/LongPress/ForceTouch/Manual/Race/Simultaneous/Exclusive/Hover, ForceTouchGestureHandler unavailable-hardware fallback (children render, forceTouchAvailable false, no force events), simultaneousWithExternalGesture/requireExternalGestureToFail/blocksExternalGesture, ScrollView/FlatList, Switch/RefreshControl, Pressable/Text, Touchables, BaseButton/RawButton/RectButton/BorderlessButton/PureNativeButton, Swipeable, ReanimatedSwipeable, DrawerLayout (the upstream component running on this seam: renderNavigationView, drawerPosition/drawerType/drawerWidth/edgeWidth, openDrawer/closeDrawer, edge-swipe drag, onDrawerOpen/onDrawerClose/onDrawerStateChanged), GestureHandlerRootView, createNativeWrapper, gestureHandlerRootHOC, PointerType/MouseButton/HoverEffect exports, velocity tracking, activeOffsets, multi-tap"
1831
1885
  }
1832
1886
  ]
1833
1887
  },
@@ -1872,9 +1926,9 @@ var init_registry = __esm({
1872
1926
  coverage: 0.85,
1873
1927
  coverageSource: "estimated",
1874
1928
  capabilityCoverage: CAPABILITY_INVENTORY_PACKAGE_COVERAGE["react-native-svg"],
1875
- note: "full CanvasKit rendering for shapes/text/XML; SVG filter elements skipped",
1876
- working: "Svg, Path, Circle, Rect, Line, Ellipse, Polygon, Polyline, G, Text, TSpan, Defs, LinearGradient and RadialGradient with objectBoundingBox/userSpaceOnUse coordinates, focal points and gradientTransform, Stop, SvgXml, SvgUri, SvgFromXml, SvgCss, shape transforms, fill/stroke/opacity/dasharray, currentColor, viewBox scaling",
1877
- missing: "SVG filter primitives (Filter, FeBlend, FeColorMatrix, FeGaussianBlur, FeComposite, etc) are skipped; ClipPath, Mask, Use, Pattern, Symbol, Marker, ForeignObject, TextPath, and Image are also skipped by the renderer"
1929
+ note: "full CanvasKit rendering for shapes, text, XML, gradients, references, masks, clipping, and images; SVG filter elements skipped",
1930
+ working: "Svg, Path, Circle, Rect, Line, Ellipse, Polygon, Polyline, G, Text, TSpan, Defs, LinearGradient and RadialGradient with objectBoundingBox/userSpaceOnUse coordinates, focal points and gradientTransform, Stop, Mask, ClipPath, Image, Use and Symbol references, SvgXml, SvgUri, SvgFromXml, SvgCss, shape transforms, fill/stroke/opacity/dasharray, currentColor, viewBox scaling",
1931
+ missing: "SVG filter primitives (Filter, FeBlend, FeColorMatrix, FeGaussianBlur, FeComposite, etc), Pattern, Marker, ForeignObject, and TextPath are skipped by the renderer"
1878
1932
  }
1879
1933
  ]
1880
1934
  },
@@ -15724,6 +15778,7 @@ __export(home_paths_exports, {
15724
15778
  profilesDir: () => profilesDir,
15725
15779
  readActiveRuntime: () => readActiveRuntime,
15726
15780
  readDaemonLockfile: () => readDaemonLockfile,
15781
+ readDefaultBox: () => readDefaultBox,
15727
15782
  readDevBridgeLockfiles: () => readDevBridgeLockfiles,
15728
15783
  readLiveRuntimeVersions: () => readLiveRuntimeVersions,
15729
15784
  readOrCreateAnonymousId: () => readOrCreateAnonymousId,
@@ -15739,6 +15794,7 @@ __export(home_paths_exports, {
15739
15794
  shouldSkipPersistentDaemon: () => shouldSkipPersistentDaemon,
15740
15795
  writeActiveRuntime: () => writeActiveRuntime,
15741
15796
  writeDaemonLockfile: () => writeDaemonLockfile,
15797
+ writeDefaultBox: () => writeDefaultBox,
15742
15798
  writeDevBridgeLockfile: () => writeDevBridgeLockfile,
15743
15799
  writeOnboardingPreferences: () => writeOnboardingPreferences,
15744
15800
  writePrivacyPreferences: () => writePrivacyPreferences,
@@ -15888,6 +15944,18 @@ function readOrCreateAnonymousId() {
15888
15944
  writeSharedConfig({ anonymousId: created });
15889
15945
  return created;
15890
15946
  }
15947
+ function readDefaultBox() {
15948
+ const stored = readSharedConfig().defaultBox;
15949
+ if (typeof stored !== "object" || stored === null) return null;
15950
+ if (!("boxId" in stored) || typeof stored.boxId !== "string" || !stored.boxId) {
15951
+ return null;
15952
+ }
15953
+ const name2 = "name" in stored && typeof stored.name === "string" ? stored.name : null;
15954
+ return { boxId: stored.boxId, name: name2 };
15955
+ }
15956
+ function writeDefaultBox(box) {
15957
+ writeSharedConfig({ defaultBox: box });
15958
+ }
15891
15959
  function runtimeUpgradeNoticePath() {
15892
15960
  return import_node_path4.default.join(rnxHomeDir(), "runtime-upgraded.json");
15893
15961
  }
@@ -22726,6 +22794,7 @@ function normalizeCloudOrigin(source) {
22726
22794
  function createCloudSession(input) {
22727
22795
  const session = {
22728
22796
  version: CLOUD_SESSION_VERSION,
22797
+ service: "sim",
22729
22798
  boxId: input.boxId.trim(),
22730
22799
  boxToken: input.boxToken,
22731
22800
  simId: input.simId.trim(),
@@ -22738,6 +22807,19 @@ function createCloudSession(input) {
22738
22807
  }
22739
22808
  return session;
22740
22809
  }
22810
+ function createCloudBoxSession(input) {
22811
+ const session = {
22812
+ version: CLOUD_SESSION_VERSION,
22813
+ service: "box",
22814
+ boxId: input.boxId.trim(),
22815
+ boxToken: input.boxToken,
22816
+ apiOrigin: normalizeCloudOrigin(input.apiOrigin.trim())
22817
+ };
22818
+ if (!session.boxId || !session.boxToken) {
22819
+ throw new Error("cloud box session requires a box, an origin, and a box token");
22820
+ }
22821
+ return session;
22822
+ }
22741
22823
  function parseCloudSession(encoded) {
22742
22824
  const value = encoded.trim();
22743
22825
  if (!value || value.length > MAX_ENCODED_SESSION_BYTES || !/^[A-Za-z0-9_-]+$/.test(value)) {
@@ -22758,14 +22840,20 @@ function parseCloudSession(encoded) {
22758
22840
  }
22759
22841
  const boxId = parsed.boxId;
22760
22842
  const boxToken = parsed.boxToken;
22761
- const simId = parsed.simId;
22762
22843
  const apiOrigin = parsed.apiOrigin;
22763
- const claimId = parsed.claimId;
22764
- const token = parsed.token;
22765
- if (typeof boxId !== "string" || typeof boxToken !== "string" || typeof simId !== "string" || typeof apiOrigin !== "string" || typeof claimId !== "string" || typeof token !== "string") {
22844
+ if (typeof boxId !== "string" || typeof boxToken !== "string" || typeof apiOrigin !== "string") {
22766
22845
  throw new Error(`${RNX_CLOUD_SESSION_ENV} is invalid`);
22767
22846
  }
22768
22847
  try {
22848
+ if (parsed.service === "box") {
22849
+ return createCloudBoxSession({ boxId, boxToken, apiOrigin });
22850
+ }
22851
+ const simId = parsed.simId;
22852
+ const claimId = parsed.claimId;
22853
+ const token = parsed.token;
22854
+ if (parsed.service !== "sim" || typeof simId !== "string" || typeof claimId !== "string" || typeof token !== "string") {
22855
+ throw new Error("unreadable cloud session");
22856
+ }
22769
22857
  return createCloudSession({ boxId, boxToken, simId, apiOrigin, claimId, token });
22770
22858
  } catch {
22771
22859
  throw new Error(`${RNX_CLOUD_SESSION_ENV} is invalid`);
@@ -22780,7 +22868,7 @@ var init_cloud_session = __esm({
22780
22868
  "cli/cloud-session.ts"() {
22781
22869
  "use strict";
22782
22870
  init_backend_origin();
22783
- CLOUD_SESSION_VERSION = 2;
22871
+ CLOUD_SESSION_VERSION = 3;
22784
22872
  MAX_ENCODED_SESSION_BYTES = 32 * 1024;
22785
22873
  RNX_CLOUD_SESSION_ENV = "RNX_CLOUD_SESSION";
22786
22874
  RNX_SHELL_UPDATE_PREFIX = "__RNX_SHELL_UPDATE_V1__";
@@ -23027,7 +23115,8 @@ function distinctByContent(directory, options) {
23027
23115
  return [...byContent.values()];
23028
23116
  }
23029
23117
  function placeMetroDescriptor(listing, descriptor) {
23030
- const perScale = descriptor.scales.map(
23118
+ const scales = [...new Set(descriptor.scales)];
23119
+ const perScale = scales.map(
23031
23120
  (scale) => distinctByContent(
23032
23121
  listing.directory,
23033
23122
  resolveMetroIosAssetDestFiles(listing.files, descriptor, scale)
@@ -23035,7 +23124,7 @@ function placeMetroDescriptor(listing, descriptor) {
23035
23124
  );
23036
23125
  const files = /* @__PURE__ */ new Map();
23037
23126
  const ambiguous = [];
23038
- descriptor.scales.forEach((scale, index) => {
23127
+ scales.forEach((scale, index) => {
23039
23128
  const options = perScale[index] ?? [];
23040
23129
  if (options.length === 1 && options[0]) files.set(scale, options[0]);
23041
23130
  else if (options.length > 1) ambiguous.push(...options);
@@ -23043,6 +23132,7 @@ function placeMetroDescriptor(listing, descriptor) {
23043
23132
  if (perScale.length === 0 || perScale.some((options) => options.length === 0)) {
23044
23133
  return { files, ambiguous, verified: false, mismatched: false };
23045
23134
  }
23135
+ const fileHashes = !descriptor.fileUris && descriptor.fileHashes?.length === descriptor.scales.length ? descriptor.fileHashes : null;
23046
23136
  for (const combination of placementCombinations(perScale)) {
23047
23137
  let bytes;
23048
23138
  try {
@@ -23052,14 +23142,23 @@ function placeMetroDescriptor(listing, descriptor) {
23052
23142
  } catch {
23053
23143
  continue;
23054
23144
  }
23055
- if (metroDescriptorHash(bytes) !== descriptor.hash) continue;
23145
+ const identical = fileHashes ? bytes.every((file, index) => {
23146
+ const digest = (0, import_node_crypto5.createHash)("md5").update(file).digest("hex");
23147
+ return descriptor.scales.some(
23148
+ (scale, declared) => scale === scales[index] && fileHashes[declared] === digest
23149
+ );
23150
+ }) : scales.length === descriptor.scales.length && metroDescriptorHash(bytes) === descriptor.hash;
23151
+ if (!identical) continue;
23056
23152
  const chosen = /* @__PURE__ */ new Map();
23057
- descriptor.scales.forEach((scale, index) => {
23153
+ scales.forEach((scale, index) => {
23058
23154
  const relative2 = combination[index];
23059
23155
  if (relative2) chosen.set(scale, relative2);
23060
23156
  });
23061
23157
  return { files: chosen, ambiguous: [], verified: true, mismatched: false };
23062
23158
  }
23159
+ if (!fileHashes && scales.length !== descriptor.scales.length) {
23160
+ return { files, ambiguous, verified: false, mismatched: false };
23161
+ }
23063
23162
  return { files, ambiguous, verified: false, mismatched: true };
23064
23163
  }
23065
23164
  function unverifiedFileKey(dest) {
@@ -23172,7 +23271,7 @@ async function inferCloudModuleIdentity(source) {
23172
23271
  );
23173
23272
  }
23174
23273
  }
23175
- async function produceCloudArtifact(bundlePath, assetsPath) {
23274
+ async function produceCloudArtifact(bundlePath, assetsPath, maxBytes = MAX_RNX_CLOUD_BUNDLE_BYTES) {
23176
23275
  const source = await loadBundleSource(bundlePath);
23177
23276
  const descriptors = extractAssetDescriptors(source);
23178
23277
  const search = assetsPath ? explicitMetroAssetDest((0, import_node_path15.resolve)(assetsPath), descriptors) : descriptors.length > 0 && !isRemoteBundleInput(bundlePath) ? searchMetroAssetDest(bundlePath, descriptors) : { dest: null, searched: [], truncated: false };
@@ -23229,9 +23328,9 @@ async function produceCloudArtifact(bundlePath, assetsPath) {
23229
23328
  });
23230
23329
  const bytes = Buffer.from(artifact.code, "utf8");
23231
23330
  const assets = artifact.receipt.assets;
23232
- if (bytes.length > MAX_RNX_CLOUD_BUNDLE_BYTES) {
23331
+ if (bytes.length > maxBytes) {
23233
23332
  throw new Error(
23234
- `${REMOTE_COMMAND} artifact is ${bytes.length} bytes and exceeds the ${MAX_RNX_CLOUD_BUNDLE_BYTES}-byte limit. Embedded assets weigh ${assets.bytes} bytes on disk, and base64 embedding costs about a third on top of that, so the practical asset budget is roughly 15 MB.${largestEmbeddedAssets(assets.sizes, 10)}`
23333
+ `${REMOTE_COMMAND} artifact is ${bytes.length} bytes and exceeds the ${maxBytes}-byte limit. Embedded assets weigh ${assets.bytes} bytes on disk, and base64 embedding costs about a third on top of that, so the practical asset budget is roughly ${Math.round(maxBytes * 0.75 / 1e6)} MB.${largestEmbeddedAssets(assets.sizes, 10)}`
23235
23334
  );
23236
23335
  }
23237
23336
  const warnings = [];
@@ -23240,9 +23339,9 @@ async function produceCloudArtifact(bundlePath, assetsPath) {
23240
23339
  `${REMOTE_COMMAND} embedded a placeholder image for ${substituted.length} asset(s) no scale of which is in ${search.searched.join(", ") || "any asset dest directory"}: ${substituted.join(", ")}. Build the bundle with --assets-dest, or pass --assets <dir>, to ship the real images.`
23241
23340
  );
23242
23341
  }
23243
- if (bytes.length >= WARN_ARTIFACT_BYTES) {
23342
+ if (bytes.length >= Math.floor(maxBytes * 0.8)) {
23244
23343
  warnings.push(
23245
- `${REMOTE_COMMAND} artifact is ${bytes.length} bytes, ${Math.round(bytes.length / MAX_RNX_CLOUD_BUNDLE_BYTES * 100)}% of the ${MAX_RNX_CLOUD_BUNDLE_BYTES}-byte limit.${largestEmbeddedAssets(assets.sizes, 5)}`
23344
+ `${REMOTE_COMMAND} artifact is ${bytes.length} bytes, ${Math.round(bytes.length / maxBytes * 100)}% of the ${maxBytes}-byte limit.${largestEmbeddedAssets(assets.sizes, 5)}`
23246
23345
  );
23247
23346
  }
23248
23347
  return {
@@ -23348,6 +23447,14 @@ async function createCloudBox(options) {
23348
23447
  function resolveCloudSessionForParsed(parsed) {
23349
23448
  const session = readCloudSession();
23350
23449
  if (!session) return null;
23450
+ if (session.service === "box") {
23451
+ if (parsed.simIdSource === "flag" && parsed.simId !== session.boxId) {
23452
+ throw new Error(
23453
+ `this shell is connected to box ${session.boxId}; ${parsed.simId ? `--sim ${parsed.simId}` : "the requested simulator"} is not available in this shell`
23454
+ );
23455
+ }
23456
+ return session;
23457
+ }
23351
23458
  if (parsed.simIdSource === "flag" && parsed.simId !== session.simId) {
23352
23459
  throw new Error(
23353
23460
  `this shell is connected to remote simulator ${session.simId}; ${parsed.simId ? `--sim ${parsed.simId}` : "the requested simulator"} is not available in this shell`
@@ -23367,9 +23474,10 @@ function cloudCommand(command) {
23367
23474
  }
23368
23475
  function createCloudBridgeForParsed(parsed) {
23369
23476
  const session = resolveCloudSessionForParsed(parsed);
23370
- return session ? new CloudBridge(session) : null;
23477
+ if (!session) return null;
23478
+ return session.service === "box" ? new CloudBoxBridge(session) : new CloudBridge(session);
23371
23479
  }
23372
- var import_node_crypto5, import_node_fs14, import_node_path15, DEFAULT_RNX_CLOUD_ORIGIN, MAX_RNX_CLOUD_BUNDLE_BYTES, REMOTE_COMMAND, WARN_ARTIFACT_BYTES, MAX_ASSET_DEST_FILES, ACCOUNT_CHOICE_REFUSALS, PROJECT_ONLY_DIRECTORIES, MAX_PLACEMENT_COMBINATIONS, CloudBridge;
23480
+ var import_node_crypto5, import_node_fs14, import_node_path15, DEFAULT_RNX_CLOUD_ORIGIN, MAX_RNX_CLOUD_BUNDLE_BYTES, REMOTE_COMMAND, MAX_ASSET_DEST_FILES, ACCOUNT_CHOICE_REFUSALS, PROJECT_ONLY_DIRECTORIES, MAX_PLACEMENT_COMBINATIONS, CloudBridge, CloudBoxBridge;
23373
23481
  var init_cloud_client = __esm({
23374
23482
  "cli/cloud-client.ts"() {
23375
23483
  "use strict";
@@ -23390,7 +23498,6 @@ var init_cloud_client = __esm({
23390
23498
  DEFAULT_RNX_CLOUD_ORIGIN = rnxPublicBrand.origin;
23391
23499
  MAX_RNX_CLOUD_BUNDLE_BYTES = RNX_CLOUD_MAX_ARTIFACT_BYTES;
23392
23500
  REMOTE_COMMAND = "rnx ios --remote";
23393
- WARN_ARTIFACT_BYTES = Math.floor(MAX_RNX_CLOUD_BUNDLE_BYTES * 0.8);
23394
23501
  MAX_ASSET_DEST_FILES = 25e3;
23395
23502
  ACCOUNT_CHOICE_REFUSALS = /* @__PURE__ */ new Set([
23396
23503
  "accountId is required",
@@ -23475,6 +23582,70 @@ var init_cloud_client = __esm({
23475
23582
  close() {
23476
23583
  }
23477
23584
  };
23585
+ CloudBoxBridge = class {
23586
+ constructor(session) {
23587
+ this.session = session;
23588
+ }
23589
+ plane = "cloud";
23590
+ async send(command, options) {
23591
+ const id = (0, import_node_crypto5.randomUUID)();
23592
+ const payload = {};
23593
+ for (const [key, value] of Object.entries(command)) {
23594
+ if (key !== "id" && key !== "simId") payload[key] = value;
23595
+ }
23596
+ let response;
23597
+ try {
23598
+ response = await fetch(
23599
+ `${this.session.apiOrigin}/v1/boxes/${encodeURIComponent(this.session.boxId)}/commands`,
23600
+ {
23601
+ method: "POST",
23602
+ headers: {
23603
+ authorization: `Bearer ${this.session.boxToken}`,
23604
+ "content-type": "application/json"
23605
+ },
23606
+ body: JSON.stringify({ id, command: payload }),
23607
+ ...options?.timeoutMs ? { signal: AbortSignal.timeout(options.timeoutMs) } : {}
23608
+ }
23609
+ );
23610
+ } catch (error) {
23611
+ throw new Error(
23612
+ `could not reach box ${this.session.boxId} at ${this.session.apiOrigin}: ${error instanceof Error ? error.message : String(error)}`
23613
+ );
23614
+ }
23615
+ const text = await response.text();
23616
+ if (!response.ok) throw responseError(response.status, text);
23617
+ let parsed;
23618
+ try {
23619
+ parsed = JSON.parse(text);
23620
+ } catch {
23621
+ throw new Error("box command returned unreadable JSON");
23622
+ }
23623
+ if (!isRecord5(parsed) || parsed.id !== id) {
23624
+ throw new Error("box command returned an invalid command receipt");
23625
+ }
23626
+ if (typeof parsed.error === "string" && parsed.error) throw new Error(parsed.error);
23627
+ if (!Object.hasOwn(parsed, "result")) {
23628
+ throw new Error("box command receipt has no result");
23629
+ }
23630
+ return parsed.result;
23631
+ }
23632
+ listSims() {
23633
+ return Promise.reject(new Error("a box does not expose a local simulator list"));
23634
+ }
23635
+ focusSim() {
23636
+ return Promise.reject(new Error("a box simulator has no browser window to focus"));
23637
+ }
23638
+ closeSim() {
23639
+ return Promise.reject(new Error("close a box simulator with rnx box stop"));
23640
+ }
23641
+ claim() {
23642
+ return Promise.reject(
23643
+ new Error("a box simulator is held by its Box page and has nothing to claim")
23644
+ );
23645
+ }
23646
+ close() {
23647
+ }
23648
+ };
23478
23649
  }
23479
23650
  });
23480
23651
 
@@ -26015,6 +26186,7 @@ __export(ws_bridge_exports, {
26015
26186
  createBridge: () => createBridge,
26016
26187
  createBridgeFromParsed: () => createBridgeFromParsed,
26017
26188
  evalInBridge: () => evalInBridge,
26189
+ formatLockOwner: () => formatLockOwner,
26018
26190
  parseBridgeCliArgs: () => parseBridgeCliArgs,
26019
26191
  printBridgeWorldNotice: () => printBridgeWorldNotice,
26020
26192
  resolveBridgePortForPin: () => resolveBridgePortForPin,
@@ -26179,6 +26351,17 @@ function describeSimIdSource(source) {
26179
26351
  if (source === "saved") return "saved via `rnx use`";
26180
26352
  return "primary fallback \u2014 no sim pinned";
26181
26353
  }
26354
+ function formatLockOwner(owner) {
26355
+ const colon = owner.indexOf(":");
26356
+ if (colon <= 0) return owner.length > 24 ? `${owner.slice(0, 21)}\u2026` : owner;
26357
+ const source = owner.slice(0, colon);
26358
+ const value = owner.slice(colon + 1);
26359
+ const short = value.length > 12 ? `${value.slice(0, 8)}\u2026` : value;
26360
+ if (source === "TM_SESSION" || source === "CLAUDE_CODE_SESSION_ID" || source === "CODEX_THREAD_ID") {
26361
+ return `agent ${short}`;
26362
+ }
26363
+ return `${source} ${short}`;
26364
+ }
26182
26365
  function parseBridgeCliArgs(args, opts = {}) {
26183
26366
  const flagIndices = /* @__PURE__ */ new Set();
26184
26367
  const state = {
@@ -28960,7 +29143,6 @@ __export(control_exports, {
28960
29143
  ensureBridgeForOpen: () => ensureBridgeForOpen,
28961
29144
  planBulkCloseTargets: () => planBulkCloseTargets,
28962
29145
  playwrightHostPidForSim: () => playwrightHostPidForSim,
28963
- printConnectedSims: () => printConnectedSims,
28964
29146
  printOpenedSim: () => printOpenedSim,
28965
29147
  resolveBundleTarget: () => resolveBundleTarget,
28966
29148
  resolveDefaultShellBaseUrl: () => resolveDefaultShellBaseUrl,
@@ -28973,7 +29155,6 @@ __export(control_exports, {
28973
29155
  runOpenCommand: () => runOpenCommand,
28974
29156
  runUseCommand: () => runUseCommand,
28975
29157
  signalDriverLaunchConnected: () => signalDriverLaunchConnected,
28976
- summarizeSimUrl: () => summarizeSimUrl,
28977
29158
  terminatePlaywrightHostsForSims: () => terminatePlaywrightHostsForSims,
28978
29159
  waitForSimMatch: () => waitForSimMatch,
28979
29160
  waitForSimMatchOrHostExit: () => waitForSimMatchOrHostExit
@@ -29470,108 +29651,6 @@ async function waitForSimReady(wsPort, commandTimeoutMs, simId, opts = {}) {
29470
29651
  }
29471
29652
  return null;
29472
29653
  }
29473
- function summarizeSimUrl(url) {
29474
- if (!url) return null;
29475
- try {
29476
- const parsed = new URL(url);
29477
- if (parsed.searchParams.has("bundle")) {
29478
- const bundleUrl = parsed.searchParams.get("bundle") || "";
29479
- try {
29480
- const bundle = new URL(bundleUrl);
29481
- const shortPath = bundle.pathname.length > 36 ? `...${bundle.pathname.slice(-36)}` : bundle.pathname;
29482
- return `bundle ${bundle.host}${shortPath}`;
29483
- } catch {
29484
- return "bundle";
29485
- }
29486
- }
29487
- if (parsed.searchParams.has("port")) {
29488
- return `connect :${parsed.searchParams.get("port") || ""}`;
29489
- }
29490
- if (parsed.searchParams.has("open")) {
29491
- return `connect ${parsed.searchParams.get("open") || ""}`;
29492
- }
29493
- if (parsed.searchParams.has("demo")) {
29494
- return `demo ${parsed.searchParams.get("demo") || "default"}`;
29495
- }
29496
- if (parsed.pathname.includes("/sootsim/index.html") || parsed.pathname === "/sootsim/" || parsed.pathname === "/sootsim") {
29497
- return "embedded rnx";
29498
- }
29499
- return null;
29500
- } catch {
29501
- return null;
29502
- }
29503
- }
29504
- function formatLockOwner(owner) {
29505
- const colon = owner.indexOf(":");
29506
- if (colon <= 0) return owner.length > 24 ? `${owner.slice(0, 21)}\u2026` : owner;
29507
- const source = owner.slice(0, colon);
29508
- const value = owner.slice(colon + 1);
29509
- const short = value.length > 12 ? `${value.slice(0, 8)}\u2026` : value;
29510
- if (source === "TM_SESSION" || source === "CLAUDE_CODE_SESSION_ID" || source === "CODEX_THREAD_ID") {
29511
- return `agent ${short}`;
29512
- }
29513
- return `${source} ${short}`;
29514
- }
29515
- function printConnectedSims(sims, selectedId) {
29516
- if (sims.length === 0) {
29517
- console.log(" no sims connected");
29518
- return;
29519
- }
29520
- console.log(` connected sims (${sims.length}):
29521
- `);
29522
- for (const sim of sims) {
29523
- const lockTag = sim.lockedBy && sim.lockExpiresAt ? `locked by ${formatLockOwner(sim.lockedBy)} (${Math.max(0, Math.round((sim.lockExpiresAt - Date.now()) / 1e3))}s)` : "";
29524
- const tags = [
29525
- sim.isPrimary ? "primary" : "",
29526
- sim.id === selectedId ? "selected" : "",
29527
- sim.readyState,
29528
- sim.userVisible === false ? "hidden" : sim.userVisible === true ? "visible" : "",
29529
- sim.attachedCliCount && sim.attachedCliCount > 0 ? "in use" : "",
29530
- sim.userFocused ? "focused" : "",
29531
- lockTag
29532
- ].filter(Boolean);
29533
- console.log(` ${sim.id}${tags.length ? ` [${tags.join(", ")}]` : ""}`);
29534
- const loaded = summarizeSimUrl(sim.url);
29535
- if (loaded) {
29536
- console.log(` loaded: ${loaded}`);
29537
- } else if (sim.url) {
29538
- const shown = sim.url.length > 96 ? `${sim.url.slice(0, 93)}\u2026` : sim.url;
29539
- console.log(` url: ${shown}`);
29540
- } else if (sim.origin) {
29541
- console.log(` origin: ${sim.origin}`);
29542
- }
29543
- const engine = describeEngineSource(sim);
29544
- if (engine) console.log(` engine: ${engine}`);
29545
- if (sim.title) console.log(` title: ${sim.title}`);
29546
- if (sim.visibilityState && sim.visibilityState !== "visible") {
29547
- console.log(` visibility: ${sim.visibilityState}`);
29548
- }
29549
- console.log(` connected: ${formatRelativeAge(Date.now() - sim.connectedAt)}`);
29550
- if (sim.lastActiveAt && sim.lastActiveAt > 0) {
29551
- console.log(` last active: ${formatRelativeAge(Date.now() - sim.lastActiveAt)}`);
29552
- }
29553
- }
29554
- }
29555
- function describeEngineSource(sim) {
29556
- const ref = sim.url || sim.origin || "";
29557
- if (!ref) return null;
29558
- try {
29559
- const port = new URL(ref).port;
29560
- if (port === "5173") return "dev \u2014 local source (:5173)";
29561
- if (port === "3000") return "Contrast app embedded (:3000)";
29562
- if (resolveDevCheckoutRuntimeRoot()) return `dev \u2014 local build (:${port || "?"})`;
29563
- return `runtime \u2014 published engine (:${port || "?"})`;
29564
- } catch {
29565
- return null;
29566
- }
29567
- }
29568
- function formatRelativeAge(ms) {
29569
- const sec = Math.max(0, Math.round(ms / 1e3));
29570
- if (sec < 60) return `${sec}s ago`;
29571
- if (sec < 3600) return `${Math.round(sec / 60)}m ago`;
29572
- if (sec < 86400) return `${Math.round(sec / 3600)}h ago`;
29573
- return `${Math.round(sec / 86400)}d ago`;
29574
- }
29575
29654
  async function waitForSimMatch(wsPort, commandTimeoutMs, predicate, opts = {}) {
29576
29655
  const attempts = opts.attempts ?? 30;
29577
29656
  const intervalMs = opts.intervalMs ?? 500;