peachsim 0.1.577 → 0.1.579
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.
- package/LICENSE +1 -1
- package/README.md +11 -9
- package/cli/app-catalog.ts +77 -0
- package/cli/app-fonts.ts +4 -20
- package/cli/app-splash.ts +2 -18
- package/cli/bridge-flow-runner.ts +505 -139
- package/cli/cloud-client.ts +1 -4
- package/cli/cloud-session.ts +1 -4
- package/cli/cloud-test-result-files.ts +3 -0
- package/cli/cloud-test-tunnel.ts +2 -5
- package/cli/command-registry.ts +2 -0
- package/cli/commands/agent.ts +149 -23
- package/cli/commands/assert.ts +1 -4
- package/cli/commands/box/peach-command.ts +62 -0
- package/cli/commands/box/plane-share.ts +0 -70
- package/cli/commands/box/rnx-command.ts +1 -60
- package/cli/commands/box/search-command.ts +14 -0
- package/cli/commands/box.ts +2 -2
- package/cli/commands/control.ts +121 -27
- package/cli/commands/cpu-profile.ts +23 -10
- package/cli/commands/daemon.ts +1 -9
- package/cli/commands/detox.ts +26 -18
- package/cli/commands/device.ts +129 -1
- package/cli/commands/film.ts +25 -16
- package/cli/commands/flow.ts +9 -2
- package/cli/commands/inspect/actions.ts +75 -1
- package/cli/commands/inspect/core.ts +81 -2
- package/cli/commands/inspect/describe.ts +2 -6
- package/cli/commands/inspect/env.ts +1 -1
- package/cli/commands/inspect/settling.ts +20 -3
- package/cli/commands/inspect/shared.ts +1 -4
- package/cli/commands/inspect/sleep.ts +1 -1
- package/cli/commands/inspect.ts +16 -49
- package/cli/commands/install-desktop.ts +8 -6
- package/cli/commands/login.ts +3 -5
- package/cli/commands/maestro-generate.ts +1 -4
- package/cli/commands/maestro.ts +38 -21
- package/cli/commands/no-bridge-hint.ts +0 -14
- package/cli/commands/permissions.ts +2 -2
- package/cli/commands/platform.ts +13 -6
- package/cli/commands/screenshot.ts +6 -1
- package/cli/commands/skills.ts +1 -1
- package/cli/commands/test.ts +6 -2
- package/cli/commands/three-mode.ts +162 -19
- package/cli/commands/upload.ts +3 -18
- package/cli/current-sim.ts +0 -1
- package/cli/desktop-companion.ts +40 -8
- package/cli/drivers/playwright-provisioning.ts +1 -4
- package/cli/flow-export.ts +1 -8
- package/cli/flow-session.ts +0 -4
- package/cli/hints.ts +1 -16
- package/cli/inspect-notice-state.ts +0 -4
- package/cli/main.ts +2 -4
- package/cli/outbound-endpoints.ts +1 -24
- package/cli/parse-args.ts +1 -2
- package/cli/rnx-in-process.ts +3 -1
- package/cli/run-rnx-core.ts +4 -2
- package/cli/run-rnx.ts +18 -10
- package/cli/send-to-box.ts +1 -4
- package/cli/telemetry.ts +1 -1
- package/cli/ws-bridge.ts +1 -5
- package/detox/gestures.ts +20 -6
- package/detox/index.ts +379 -123
- package/detox/navigation-lifecycle.ts +22 -13
- package/dist-lib/agent-daemon-client.cjs +21 -15
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +3 -17
- package/dist-lib/agent-sessions.cjs +5 -4
- package/dist-lib/attached-projects.cjs +1 -77
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +11 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/bridge-contract-input.cjs +7 -5
- package/dist-lib/bridge-contract-input.mjs +7 -5
- package/dist-lib/bridge-contract.cjs +1 -1
- package/dist-lib/bridge-contract.mjs +1 -1
- package/dist-lib/capture-contract.cjs +30 -7
- package/dist-lib/capture-contract.mjs +30 -7
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/cloud-contract.cjs +1 -1
- package/dist-lib/cloud-contract.mjs +1 -1
- package/dist-lib/cloud-test-args.cjs +1 -1
- package/dist-lib/cloud-test-args.mjs +1 -1
- package/dist-lib/cloud.cjs +17 -11
- package/dist-lib/cloud.mjs +17 -11
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +321 -122
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +427 -212
- package/dist-lib/host/fetch-proxy-handler.cjs +5 -28
- package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
- package/dist-lib/host/replacement-module-handler.cjs +1 -1
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +315 -58
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/jump-to-source-native.cjs +1 -1
- package/dist-lib/menu.cjs +67 -31
- package/dist-lib/menu.mjs +64 -28
- package/dist-lib/metro-fingerprint-registry.cjs +8 -4
- package/dist-lib/metro-fingerprint-registry.mjs +6 -4
- package/dist-lib/metro-production-bundle.cjs +2 -2
- package/dist-lib/metro-production-bundle.mjs +2 -2
- package/dist-lib/metro.cjs +8 -4
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +7 -4
- package/dist-lib/react-native-host-modules.cjs +1 -1
- package/dist-lib/react-native-host-modules.mjs +1 -1
- package/dist-lib/render-mode.cjs +3 -13
- package/dist-lib/scripts/dev-server-scanner.cjs +5 -17
- package/dist-lib/sdk.cjs +129 -10
- package/dist-lib/sdk.mjs +127 -10
- package/dist-lib/skills.cjs +1635 -1121
- package/dist-lib/swift-compile.cjs +277 -70
- package/dist-lib/swift-compile.mjs +275 -70
- package/dist-lib/swift-package.cjs +17 -5
- package/dist-lib/swift-package.mjs +15 -4
- package/dist-lib/swift-submit.cjs +32 -8
- package/dist-lib/swift-submit.mjs +29 -7
- package/dist-lib/swift.cjs +30912 -577
- package/dist-lib/vite-kotlin.cjs +356 -0
- package/dist-lib/vite-swift.cjs +1743 -0
- package/dist-lib/vite.cjs +208 -1039
- package/kotlin/README.md +18 -0
- package/kotlin/Sources/androidx/annotation/Keep.kt +4 -0
- package/kotlin/Sources/dev/onejs/one/OneNativeSourceDispatch.kt +7 -0
- package/kotlin/Sources/dev/onejs/one/source/OneModule.kt +4 -0
- package/kotlin/Sources/org/json/JSON.kt +244 -0
- package/kotlin/toolchain.json +19 -0
- package/package.json +14 -2
- package/scripts/dev-server-scanner.ts +0 -18
- package/scripts/optional-demo-registry.ts +0 -17
- package/skills/contrast/SKILL.md +2 -2
- package/skills/peach-setup/SKILL.md +16 -0
- package/src/agent-daemon-client.ts +36 -22
- package/src/agent-identity.ts +0 -15
- package/src/agent-prompt.ts +12 -0
- package/src/attached-projects.ts +0 -72
- package/src/backend-origin.ts +10 -0
- package/src/bridge-contract-input.ts +2 -5
- package/src/bridge-contract.ts +2 -0
- package/src/capture-contract.ts +53 -11
- package/src/cloud.ts +4 -9
- package/src/dev-server-open.ts +0 -99
- package/src/home-paths.ts +2 -3
- package/src/host/agent-host.ts +82 -36
- package/src/host/bridge-host.ts +5 -11
- package/src/host/fetch-proxy-handler.ts +19 -43
- package/src/is-record.ts +4 -0
- package/src/menu.ts +82 -37
- package/src/metro-fingerprint-registry.ts +1 -4
- package/src/metro-production-bundle.ts +1 -1
- package/src/plist.ts +1 -4
- package/src/public-brand.ts +5 -3
- package/src/render-mode.ts +0 -12
- package/src/runtime-assets.ts +9 -2
- package/src/screenshots/compose.ts +7 -1
- package/src/screenshots/frame-compose.ts +21 -10
- package/src/screenshots/schema.ts +1 -4
- package/src/sim-client.ts +2 -4
- package/src/skills/builtin/maestro-test.ts +1 -4
- package/src/sleep.ts +4 -0
- package/src/swift-compile.ts +209 -47
- package/src/swift-icu.ts +140 -0
- package/src/swift-package.ts +26 -2
- package/src/swift-submit.ts +84 -4
- package/src/swift.ts +2 -0
- package/src/vite-plugin-kotlin.ts +376 -0
- package/src/vite-plugin-one.ts +224 -36
- package/src/vite-plugin-swift.ts +382 -96
- package/src/vite-plugin.ts +121 -134
- package/src/vite.d.ts +10 -0
- package/cli/resolve-assets.ts +0 -63
- package/src/rolldown-plugin-swift.ts +0 -244
- package/src/team-machine-prompt.ts +0 -73
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.579 | (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;
|
|
@@ -57,10 +57,19 @@ var init_backend_origin = __esm({
|
|
|
57
57
|
}
|
|
58
58
|
});
|
|
59
59
|
|
|
60
|
+
// src/is-record.ts
|
|
61
|
+
function isRecord(value) {
|
|
62
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
63
|
+
}
|
|
64
|
+
var init_is_record = __esm({
|
|
65
|
+
"src/is-record.ts"() {
|
|
66
|
+
"use strict";
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
60
70
|
// scripts/optional-demo-registry.ts
|
|
61
71
|
var optional_demo_registry_exports = {};
|
|
62
72
|
__export(optional_demo_registry_exports, {
|
|
63
|
-
__withOptionalDemoAppsForTests: () => __withOptionalDemoAppsForTests,
|
|
64
73
|
findInternalDemoRegistry: () => findInternalDemoRegistry,
|
|
65
74
|
loadOptionalDemoApps: () => loadOptionalDemoApps,
|
|
66
75
|
optionalDemoAppsSync: () => optionalDemoAppsSync
|
|
@@ -98,15 +107,6 @@ async function loadOptionalDemoApps() {
|
|
|
98
107
|
function optionalDemoAppsSync() {
|
|
99
108
|
return cached ?? [];
|
|
100
109
|
}
|
|
101
|
-
function __withOptionalDemoAppsForTests(apps) {
|
|
102
|
-
const previous = cached;
|
|
103
|
-
cached = apps;
|
|
104
|
-
return {
|
|
105
|
-
restore: () => {
|
|
106
|
-
cached = previous;
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
110
|
var import_node_fs, import_node_path2, import_node_url, REGISTRY_REPO_PATH, MAX_ANCESTOR_STEPS, cached;
|
|
111
111
|
var init_optional_demo_registry = __esm({
|
|
112
112
|
"scripts/optional-demo-registry.ts"() {
|
|
@@ -121,18 +121,19 @@ var init_optional_demo_registry = __esm({
|
|
|
121
121
|
});
|
|
122
122
|
|
|
123
123
|
// src/public-brand.ts
|
|
124
|
-
var name, rnxPublicBrand;
|
|
124
|
+
var name, peachPublicBrand, rnxPublicBrand;
|
|
125
125
|
var init_public_brand = __esm({
|
|
126
126
|
"src/public-brand.ts"() {
|
|
127
127
|
"use strict";
|
|
128
128
|
name = "Peach";
|
|
129
|
-
|
|
129
|
+
peachPublicBrand = Object.freeze({
|
|
130
130
|
name,
|
|
131
131
|
packageName: "peachsim",
|
|
132
132
|
commandName: "peach",
|
|
133
|
-
domain: "
|
|
134
|
-
origin: "https://
|
|
133
|
+
domain: "peachsim.com",
|
|
134
|
+
origin: "https://peachsim.com"
|
|
135
135
|
});
|
|
136
|
+
rnxPublicBrand = peachPublicBrand;
|
|
136
137
|
}
|
|
137
138
|
});
|
|
138
139
|
|
|
@@ -586,23 +587,24 @@ var init_shared_session = __esm({
|
|
|
586
587
|
});
|
|
587
588
|
|
|
588
589
|
// cli/run-rnx.ts
|
|
589
|
-
function
|
|
590
|
-
throw new
|
|
590
|
+
function peachExit(code) {
|
|
591
|
+
throw new PeachExit(code);
|
|
591
592
|
}
|
|
592
|
-
var import_node_async_hooks,
|
|
593
|
+
var import_node_async_hooks, PeachExit, sinks, rnxExit;
|
|
593
594
|
var init_run_rnx = __esm({
|
|
594
595
|
"cli/run-rnx.ts"() {
|
|
595
596
|
"use strict";
|
|
596
597
|
import_node_async_hooks = require("node:async_hooks");
|
|
597
|
-
|
|
598
|
+
PeachExit = class extends Error {
|
|
598
599
|
code;
|
|
599
600
|
constructor(code) {
|
|
600
601
|
super(`peach exited with code ${code}`);
|
|
601
|
-
this.name = "
|
|
602
|
+
this.name = "PeachExit";
|
|
602
603
|
this.code = code;
|
|
603
604
|
}
|
|
604
605
|
};
|
|
605
606
|
sinks = new import_node_async_hooks.AsyncLocalStorage();
|
|
607
|
+
rnxExit = peachExit;
|
|
606
608
|
}
|
|
607
609
|
});
|
|
608
610
|
|
|
@@ -817,6 +819,53 @@ function uniformFrameInsets(value) {
|
|
|
817
819
|
function cornerRadii(value) {
|
|
818
820
|
return { topLeft: value, topRight: value, bottomRight: value, bottomLeft: value };
|
|
819
821
|
}
|
|
822
|
+
function erodeCornerRadii(radii, by) {
|
|
823
|
+
return {
|
|
824
|
+
topLeft: Math.max(0, radii.topLeft - (by.top + by.left) / 2),
|
|
825
|
+
topRight: Math.max(0, radii.topRight - (by.top + by.right) / 2),
|
|
826
|
+
bottomRight: Math.max(0, radii.bottomRight - (by.bottom + by.right) / 2),
|
|
827
|
+
bottomLeft: Math.max(0, radii.bottomLeft - (by.bottom + by.left) / 2)
|
|
828
|
+
};
|
|
829
|
+
}
|
|
830
|
+
function resolveDeviceFrameCorners(device) {
|
|
831
|
+
const { top, right, bottom, left } = device.frameInsets;
|
|
832
|
+
return {
|
|
833
|
+
frameRadius: device.frameCornerRadius ?? {
|
|
834
|
+
topLeft: device.cornerRadius.topLeft + (top + left) / 2,
|
|
835
|
+
topRight: device.cornerRadius.topRight + (top + right) / 2,
|
|
836
|
+
bottomRight: device.cornerRadius.bottomRight + (bottom + right) / 2,
|
|
837
|
+
bottomLeft: device.cornerRadius.bottomLeft + (bottom + left) / 2
|
|
838
|
+
},
|
|
839
|
+
frameRadiusApproximationError: Math.max(
|
|
840
|
+
Math.abs(top - left),
|
|
841
|
+
Math.abs(top - right),
|
|
842
|
+
Math.abs(bottom - right),
|
|
843
|
+
Math.abs(bottom - left)
|
|
844
|
+
) / 2,
|
|
845
|
+
screenRadius: device.cornerRadius
|
|
846
|
+
};
|
|
847
|
+
}
|
|
848
|
+
function resolveDeviceFrameGeometry(device) {
|
|
849
|
+
const corners = resolveDeviceFrameCorners(device);
|
|
850
|
+
const housing = device.housing ? {
|
|
851
|
+
...device.housing,
|
|
852
|
+
// the black glass ring is the body eroded by the rail, so it stays
|
|
853
|
+
// concentric with the body however the body's own corners were set
|
|
854
|
+
glassRadius: erodeCornerRadii(corners.frameRadius, device.housing.rail)
|
|
855
|
+
} : null;
|
|
856
|
+
const bodyLeft = housing?.hingeBarrel?.protrusion ?? 0;
|
|
857
|
+
return {
|
|
858
|
+
...corners,
|
|
859
|
+
housing,
|
|
860
|
+
bodyLeft,
|
|
861
|
+
frameHeight: device.frameInsets.top + device.height + device.frameInsets.bottom,
|
|
862
|
+
frameWidth: bodyLeft + device.frameInsets.left + device.width + device.frameInsets.right,
|
|
863
|
+
screenBottomInset: device.frameInsets.bottom,
|
|
864
|
+
screenLeft: bodyLeft + device.frameInsets.left,
|
|
865
|
+
screenRightInset: device.frameInsets.right,
|
|
866
|
+
screenTop: device.frameInsets.top
|
|
867
|
+
};
|
|
868
|
+
}
|
|
820
869
|
function iosDevice(spec) {
|
|
821
870
|
return {
|
|
822
871
|
...spec,
|
|
@@ -848,12 +897,147 @@ function deviceDefaultOrientation(model, posture) {
|
|
|
848
897
|
}
|
|
849
898
|
return "portrait";
|
|
850
899
|
}
|
|
851
|
-
function
|
|
900
|
+
function rotateFrameInsets(insets, side) {
|
|
901
|
+
return side === "left" ? { top: insets.left, right: insets.top, bottom: insets.right, left: insets.bottom } : { top: insets.right, right: insets.bottom, bottom: insets.left, left: insets.top };
|
|
902
|
+
}
|
|
903
|
+
function rotateCorners(radii, side) {
|
|
904
|
+
return side === "left" ? {
|
|
905
|
+
topLeft: radii.bottomLeft,
|
|
906
|
+
topRight: radii.topLeft,
|
|
907
|
+
bottomRight: radii.topRight,
|
|
908
|
+
bottomLeft: radii.bottomRight
|
|
909
|
+
} : {
|
|
910
|
+
topLeft: radii.topRight,
|
|
911
|
+
topRight: radii.bottomRight,
|
|
912
|
+
bottomRight: radii.bottomLeft,
|
|
913
|
+
bottomLeft: radii.topLeft
|
|
914
|
+
};
|
|
915
|
+
}
|
|
916
|
+
function rotateHardwareButtons(buttons, portraitFrameHeight, side) {
|
|
917
|
+
const rotate = (button) => side === "left" ? {
|
|
918
|
+
side: button.side === "left" ? "top" : "bottom",
|
|
919
|
+
top: portraitFrameHeight - button.top - button.height,
|
|
920
|
+
height: button.height
|
|
921
|
+
} : {
|
|
922
|
+
side: button.side === "left" ? "bottom" : "top",
|
|
923
|
+
top: button.top,
|
|
924
|
+
height: button.height
|
|
925
|
+
};
|
|
926
|
+
return {
|
|
927
|
+
width: buttons.width,
|
|
928
|
+
lock: rotate(buttons.lock),
|
|
929
|
+
ringToggle: rotate(buttons.ringToggle),
|
|
930
|
+
volumeUp: rotate(buttons.volumeUp),
|
|
931
|
+
volumeDown: rotate(buttons.volumeDown)
|
|
932
|
+
};
|
|
933
|
+
}
|
|
934
|
+
function rotateDevice(device, side) {
|
|
935
|
+
const frameHeight = resolveDeviceFrameGeometry(device).frameHeight;
|
|
936
|
+
const insets = rotateFrameInsets(device.frameInsets, side);
|
|
937
|
+
const barrelProtrusion = device.housing?.hingeBarrel?.protrusion ?? 0;
|
|
938
|
+
if (side === "left") insets.top += barrelProtrusion;
|
|
939
|
+
else insets.bottom += barrelProtrusion;
|
|
940
|
+
const safeArea = device.model === "ipad-pro-11" ? { top: 10, bottom: 20, left: 0, right: 0 } : device.model === "iphone-duo" ? { top: 0, bottom: 20, left: 0, right: 84 } : device.platform === "ios" && device.homeIndicatorHeight > 0 ? {
|
|
941
|
+
top: 0,
|
|
942
|
+
bottom: 20,
|
|
943
|
+
left: device.safeAreaInsets.top,
|
|
944
|
+
right: device.safeAreaInsets.top
|
|
945
|
+
} : device.platform === "ios" ? { top: 0, bottom: 0, left: 0, right: 0 } : {
|
|
946
|
+
top: device.safeAreaInsets.top,
|
|
947
|
+
bottom: device.safeAreaInsets.bottom,
|
|
948
|
+
left: 0,
|
|
949
|
+
right: device.displayCutout.top
|
|
950
|
+
};
|
|
951
|
+
return {
|
|
952
|
+
...device,
|
|
953
|
+
width: device.height,
|
|
954
|
+
height: device.width,
|
|
955
|
+
orientation: "landscape",
|
|
956
|
+
landscapeSide: side,
|
|
957
|
+
frameInsets: insets,
|
|
958
|
+
frameCornerRadius: device.frameCornerRadius ? rotateCorners(device.frameCornerRadius, side) : void 0,
|
|
959
|
+
cornerRadius: rotateCorners(device.cornerRadius, side),
|
|
960
|
+
continuousCornerRadius: rotateCorners(device.continuousCornerRadius, side),
|
|
961
|
+
housing: device.housing ? {
|
|
962
|
+
rail: rotateFrameInsets(device.housing.rail, side),
|
|
963
|
+
// the rotated barrel is accounted for in frameInsets.
|
|
964
|
+
hingeBarrel: null
|
|
965
|
+
} : void 0,
|
|
966
|
+
hardwareButtons: rotateHardwareButtons(device.hardwareButtons, frameHeight, side),
|
|
967
|
+
cameraCutout: device.cameraCutout ? {
|
|
968
|
+
...device.cameraCutout,
|
|
969
|
+
top: device.cameraCutout.top ?? (device.statusBarHeight - device.cameraCutout.diameter) / 2
|
|
970
|
+
} : null,
|
|
971
|
+
displayCutout: rotateFrameInsets(device.displayCutout, side),
|
|
972
|
+
// the bars stay on the interface's top and bottom; a cutout's inset moves
|
|
973
|
+
// to whichever side the cutout turned to.
|
|
974
|
+
safeAreaInsets: side === "left" ? safeArea : { ...safeArea, left: safeArea.right, right: safeArea.left },
|
|
975
|
+
statusBarHeight: device.platform === "ios" && device.model !== "ipad-pro-11" && device.model !== "iphone-duo" ? 0 : device.statusBarHeight,
|
|
976
|
+
homeIndicatorHeight: device.platform === "ios" && device.homeIndicatorHeight > 0 ? 20 : device.homeIndicatorHeight
|
|
977
|
+
};
|
|
978
|
+
}
|
|
979
|
+
function getDevice(model, posture, orientation, landscapeSide = "left") {
|
|
852
980
|
const device = devices[model];
|
|
853
|
-
if (!device.supportedPostures)
|
|
981
|
+
if (!device.supportedPostures) {
|
|
982
|
+
return orientation === "landscape" && model !== "canvas-workspace" ? rotateDevice(device, landscapeSide) : device;
|
|
983
|
+
}
|
|
854
984
|
const resolvedPosture = resolveDevicePosture(model, posture);
|
|
855
|
-
if (resolvedPosture === "closed") return device;
|
|
856
985
|
const resolvedOrientation = orientation ?? deviceDefaultOrientation(model, resolvedPosture);
|
|
986
|
+
if (resolvedPosture === "closed") {
|
|
987
|
+
if (resolvedOrientation === "portrait") return device;
|
|
988
|
+
const insets = device.frameInsets;
|
|
989
|
+
const radii = device.cornerRadius;
|
|
990
|
+
const body = device.frameCornerRadius ?? resolveDeviceFrameCorners(device).frameRadius;
|
|
991
|
+
const housing = device.housing;
|
|
992
|
+
const protrusion = housing?.hingeBarrel?.protrusion ?? 0;
|
|
993
|
+
return {
|
|
994
|
+
...device,
|
|
995
|
+
width: device.height,
|
|
996
|
+
height: device.width,
|
|
997
|
+
orientation: "landscape",
|
|
998
|
+
cornerRadius: {
|
|
999
|
+
topLeft: radii.topRight,
|
|
1000
|
+
topRight: radii.bottomRight,
|
|
1001
|
+
bottomRight: radii.bottomLeft,
|
|
1002
|
+
bottomLeft: radii.topLeft
|
|
1003
|
+
},
|
|
1004
|
+
continuousCornerRadius: {
|
|
1005
|
+
topLeft: device.continuousCornerRadius.topRight,
|
|
1006
|
+
topRight: device.continuousCornerRadius.bottomRight,
|
|
1007
|
+
bottomRight: device.continuousCornerRadius.bottomLeft,
|
|
1008
|
+
bottomLeft: device.continuousCornerRadius.topLeft
|
|
1009
|
+
},
|
|
1010
|
+
frameInsets: {
|
|
1011
|
+
top: insets.right,
|
|
1012
|
+
right: insets.bottom,
|
|
1013
|
+
bottom: insets.left + protrusion,
|
|
1014
|
+
left: insets.top
|
|
1015
|
+
},
|
|
1016
|
+
frameCornerRadius: {
|
|
1017
|
+
topLeft: body.topRight,
|
|
1018
|
+
topRight: body.bottomRight,
|
|
1019
|
+
bottomRight: body.bottomLeft,
|
|
1020
|
+
bottomLeft: body.topLeft
|
|
1021
|
+
},
|
|
1022
|
+
housing: housing ? {
|
|
1023
|
+
rail: {
|
|
1024
|
+
top: housing.rail.right,
|
|
1025
|
+
right: housing.rail.bottom,
|
|
1026
|
+
bottom: housing.rail.left,
|
|
1027
|
+
left: housing.rail.top
|
|
1028
|
+
},
|
|
1029
|
+
hingeBarrel: null
|
|
1030
|
+
} : void 0,
|
|
1031
|
+
cameraCutout: device.cameraCutout ? {
|
|
1032
|
+
diameter: device.cameraCutout.diameter,
|
|
1033
|
+
top: device.cameraCutout.top,
|
|
1034
|
+
leading: device.cameraCutout.trailing
|
|
1035
|
+
} : null,
|
|
1036
|
+
safeAreaInsets: { top: 0, bottom: 34, left: 84, right: 0 },
|
|
1037
|
+
// vertically compact, so the status bar is hidden.
|
|
1038
|
+
statusBarHeight: 0
|
|
1039
|
+
};
|
|
1040
|
+
}
|
|
857
1041
|
const isRotatedPortrait = resolvedOrientation === "portrait";
|
|
858
1042
|
return {
|
|
859
1043
|
...device,
|
|
@@ -873,6 +1057,10 @@ function getDevice(model, posture, orientation) {
|
|
|
873
1057
|
cameraCutout: null,
|
|
874
1058
|
physicalPPI: 430,
|
|
875
1059
|
posture: "open",
|
|
1060
|
+
// the fold band exists on the open profile even though the os region
|
|
1061
|
+
// reads inactive while flat; two-group compositions anchor to its centre.
|
|
1062
|
+
reservedDivisionWidth: DUO_DIVISION_REGION_WIDTH,
|
|
1063
|
+
orientation: resolvedOrientation,
|
|
876
1064
|
// open inner display in landscape carries the same trailing column as
|
|
877
1065
|
// the closed outer display, so it takes the same 84pt inset: a ~50pt
|
|
878
1066
|
// control at a ~23pt inset needs 73pt, and anything narrower would shift
|
|
@@ -888,11 +1076,10 @@ function listDeviceModels() {
|
|
|
888
1076
|
function getRuntimePlatform(model) {
|
|
889
1077
|
return getDevice(model).platform;
|
|
890
1078
|
}
|
|
891
|
-
var
|
|
1079
|
+
var LEGACY_HARDWARE_BUTTONS, PIXEL_HARDWARE_BUTTONS, GALAXY_HARDWARE_BUTTONS, ANDROID_GESTURE_NAV_BAR_HEIGHT, ANDROID_OS_VERSION, ANDROID_API_LEVEL, PIXEL_8_WIDTH, PIXEL_8_HEIGHT, PIXEL_8_STATUS_BAR_HEIGHT, DUO_DIVISION_REGION_WIDTH, devices, DEFAULT_DEVICE, DEFAULT_DEVICE_BY_PLATFORM;
|
|
892
1080
|
var init_devices = __esm({
|
|
893
1081
|
"../peach-engine/src/settings/devices.ts"() {
|
|
894
1082
|
"use strict";
|
|
895
|
-
import_menu = require("peachsim/menu");
|
|
896
1083
|
init_development_mode();
|
|
897
1084
|
LEGACY_HARDWARE_BUTTONS = {
|
|
898
1085
|
width: 2.5,
|
|
@@ -923,6 +1110,7 @@ var init_devices = __esm({
|
|
|
923
1110
|
PIXEL_8_WIDTH = 1080 / 2.625;
|
|
924
1111
|
PIXEL_8_HEIGHT = 2400 / 2.625;
|
|
925
1112
|
PIXEL_8_STATUS_BAR_HEIGHT = 132 / 2.625;
|
|
1113
|
+
DUO_DIVISION_REGION_WIDTH = 40;
|
|
926
1114
|
devices = {
|
|
927
1115
|
"canvas-workspace": iosDevice({
|
|
928
1116
|
model: "canvas-workspace",
|
|
@@ -937,7 +1125,7 @@ var init_devices = __esm({
|
|
|
937
1125
|
frameInsets: uniformFrameInsets(16),
|
|
938
1126
|
dynamicIsland: null,
|
|
939
1127
|
safeAreaInsets: { top: 0, bottom: 0, left: 0, right: 0 },
|
|
940
|
-
iosVersion: "
|
|
1128
|
+
iosVersion: "27.0",
|
|
941
1129
|
// no native device has this geometry; carries the iphone 16 keyboard
|
|
942
1130
|
// height so the experimental profile still shows a keyboard.
|
|
943
1131
|
keyboardHeight: 308,
|
|
@@ -966,7 +1154,7 @@ var init_devices = __esm({
|
|
|
966
1154
|
frameInsets: uniformFrameInsets(28.7),
|
|
967
1155
|
dynamicIsland: null,
|
|
968
1156
|
safeAreaInsets: { top: 20, bottom: 0, left: 0, right: 0 },
|
|
969
|
-
iosVersion: "
|
|
1157
|
+
iosVersion: "27.0",
|
|
970
1158
|
keyboardHeight: 233,
|
|
971
1159
|
physicalPPI: 326,
|
|
972
1160
|
hardwareButtons: LEGACY_HARDWARE_BUTTONS
|
|
@@ -984,7 +1172,7 @@ var init_devices = __esm({
|
|
|
984
1172
|
frameInsets: uniformFrameInsets(19.5),
|
|
985
1173
|
dynamicIsland: null,
|
|
986
1174
|
safeAreaInsets: { top: 47, bottom: 34, left: 0, right: 0 },
|
|
987
|
-
iosVersion: "
|
|
1175
|
+
iosVersion: "27.0",
|
|
988
1176
|
keyboardHeight: 308,
|
|
989
1177
|
physicalPPI: 460,
|
|
990
1178
|
hardwareButtons: modernButtons(
|
|
@@ -1005,9 +1193,10 @@ var init_devices = __esm({
|
|
|
1005
1193
|
cornerRadius: cornerRadii(53.9),
|
|
1006
1194
|
continuousCornerRadius: cornerRadii(73.402),
|
|
1007
1195
|
frameInsets: uniformFrameInsets(18.2),
|
|
1008
|
-
dynamicIsland: { width:
|
|
1196
|
+
dynamicIsland: { width: 125, height: 110 / 3, top: 34 / 3 },
|
|
1197
|
+
statusRowCenter: 32.75,
|
|
1009
1198
|
safeAreaInsets: { top: 59, bottom: 34, left: 0, right: 0 },
|
|
1010
|
-
iosVersion: "
|
|
1199
|
+
iosVersion: "27.0",
|
|
1011
1200
|
keyboardHeight: 308,
|
|
1012
1201
|
physicalPPI: 460,
|
|
1013
1202
|
hardwareButtons: modernButtons(
|
|
@@ -1028,9 +1217,10 @@ var init_devices = __esm({
|
|
|
1028
1217
|
cornerRadius: cornerRadii(53.9),
|
|
1029
1218
|
continuousCornerRadius: cornerRadii(74.654),
|
|
1030
1219
|
frameInsets: uniformFrameInsets(17.3),
|
|
1031
|
-
dynamicIsland: { width:
|
|
1220
|
+
dynamicIsland: { width: 376 / 3, height: 110 / 3, top: 34 / 3 },
|
|
1221
|
+
statusRowCenter: 30.05,
|
|
1032
1222
|
safeAreaInsets: { top: 59, bottom: 34, left: 0, right: 0 },
|
|
1033
|
-
iosVersion: "
|
|
1223
|
+
iosVersion: "27.0",
|
|
1034
1224
|
keyboardHeight: 318,
|
|
1035
1225
|
physicalPPI: 460,
|
|
1036
1226
|
hardwareButtons: modernButtons(
|
|
@@ -1051,9 +1241,10 @@ var init_devices = __esm({
|
|
|
1051
1241
|
cornerRadius: cornerRadii(53.9),
|
|
1052
1242
|
continuousCornerRadius: cornerRadii(73.402),
|
|
1053
1243
|
frameInsets: uniformFrameInsets(15.3),
|
|
1054
|
-
dynamicIsland: { width:
|
|
1244
|
+
dynamicIsland: { width: 125, height: 110 / 3, top: 34 / 3 },
|
|
1245
|
+
statusRowCenter: 32.4,
|
|
1055
1246
|
safeAreaInsets: { top: 59, bottom: 34, left: 0, right: 0 },
|
|
1056
|
-
iosVersion: "
|
|
1247
|
+
iosVersion: "27.0",
|
|
1057
1248
|
keyboardHeight: 308,
|
|
1058
1249
|
physicalPPI: 460,
|
|
1059
1250
|
hardwareButtons: modernButtons(
|
|
@@ -1074,9 +1265,10 @@ var init_devices = __esm({
|
|
|
1074
1265
|
cornerRadius: cornerRadii(53.9),
|
|
1075
1266
|
continuousCornerRadius: cornerRadii(74.654),
|
|
1076
1267
|
frameInsets: uniformFrameInsets(15.3),
|
|
1077
|
-
dynamicIsland: { width:
|
|
1268
|
+
dynamicIsland: { width: 376 / 3, height: 110 / 3, top: 34 / 3 },
|
|
1269
|
+
statusRowCenter: 32.3,
|
|
1078
1270
|
safeAreaInsets: { top: 59, bottom: 34, left: 0, right: 0 },
|
|
1079
|
-
iosVersion: "
|
|
1271
|
+
iosVersion: "27.0",
|
|
1080
1272
|
keyboardHeight: 318,
|
|
1081
1273
|
physicalPPI: 460,
|
|
1082
1274
|
hardwareButtons: modernButtons(
|
|
@@ -1101,11 +1293,10 @@ var init_devices = __esm({
|
|
|
1101
1293
|
cornerRadius: cornerRadii(53.9),
|
|
1102
1294
|
continuousCornerRadius: cornerRadii(73.402),
|
|
1103
1295
|
frameInsets: uniformFrameInsets(15.3),
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
dynamicIsland: { width: 126, height: 37.3, top: 11 },
|
|
1296
|
+
dynamicIsland: { width: 125, height: 110 / 3, top: 34 / 3 },
|
|
1297
|
+
statusRowCenter: 29.65,
|
|
1107
1298
|
safeAreaInsets: { top: 59, bottom: 34, left: 0, right: 0 },
|
|
1108
|
-
iosVersion: "
|
|
1299
|
+
iosVersion: "27.0",
|
|
1109
1300
|
keyboardHeight: 308,
|
|
1110
1301
|
physicalPPI: 460,
|
|
1111
1302
|
hardwareButtons: modernButtons(
|
|
@@ -1126,9 +1317,10 @@ var init_devices = __esm({
|
|
|
1126
1317
|
cornerRadius: cornerRadii(53.9),
|
|
1127
1318
|
continuousCornerRadius: cornerRadii(74.654),
|
|
1128
1319
|
frameInsets: uniformFrameInsets(15.3),
|
|
1129
|
-
dynamicIsland: { width:
|
|
1320
|
+
dynamicIsland: { width: 376 / 3, height: 110 / 3, top: 34 / 3 },
|
|
1321
|
+
statusRowCenter: 30.05,
|
|
1130
1322
|
safeAreaInsets: { top: 59, bottom: 34, left: 0, right: 0 },
|
|
1131
|
-
iosVersion: "
|
|
1323
|
+
iosVersion: "27.0",
|
|
1132
1324
|
keyboardHeight: 318,
|
|
1133
1325
|
physicalPPI: 460,
|
|
1134
1326
|
hardwareButtons: modernButtons(
|
|
@@ -1151,9 +1343,10 @@ var init_devices = __esm({
|
|
|
1151
1343
|
cornerRadius: cornerRadii(61),
|
|
1152
1344
|
continuousCornerRadius: cornerRadii(84.661),
|
|
1153
1345
|
frameInsets: uniformFrameInsets(15.3),
|
|
1154
|
-
dynamicIsland: { width:
|
|
1346
|
+
dynamicIsland: { width: 125, height: 110 / 3, top: 14 },
|
|
1347
|
+
statusRowCenter: 32.5,
|
|
1155
1348
|
safeAreaInsets: { top: 62, bottom: 34, left: 0, right: 0 },
|
|
1156
|
-
iosVersion: "
|
|
1349
|
+
iosVersion: "27.0",
|
|
1157
1350
|
keyboardHeight: 308,
|
|
1158
1351
|
physicalPPI: 460,
|
|
1159
1352
|
hardwareButtons: modernButtons(
|
|
@@ -1177,9 +1370,10 @@ var init_devices = __esm({
|
|
|
1177
1370
|
cornerRadius: cornerRadii(61.3),
|
|
1178
1371
|
continuousCornerRadius: cornerRadii(85.163),
|
|
1179
1372
|
frameInsets: uniformFrameInsets(15.4),
|
|
1180
|
-
dynamicIsland: { width:
|
|
1373
|
+
dynamicIsland: { width: 376 / 3, height: 110 / 3, top: 14 },
|
|
1374
|
+
statusRowCenter: 33,
|
|
1181
1375
|
safeAreaInsets: { top: 62, bottom: 34, left: 0, right: 0 },
|
|
1182
|
-
iosVersion: "
|
|
1376
|
+
iosVersion: "27.0",
|
|
1183
1377
|
keyboardHeight: 318,
|
|
1184
1378
|
physicalPPI: 460,
|
|
1185
1379
|
hardwareButtons: modernButtons(
|
|
@@ -1201,9 +1395,10 @@ var init_devices = __esm({
|
|
|
1201
1395
|
continuousCornerRadius: cornerRadii(84.661),
|
|
1202
1396
|
// display border 1.44mm plus the visible flat housing rail.
|
|
1203
1397
|
frameInsets: uniformFrameInsets(15.3),
|
|
1204
|
-
dynamicIsland: { width:
|
|
1398
|
+
dynamicIsland: { width: 125, height: 110 / 3, top: 14 },
|
|
1399
|
+
statusRowCenter: 32.65,
|
|
1205
1400
|
safeAreaInsets: { top: 59, bottom: 34, left: 0, right: 0 },
|
|
1206
|
-
iosVersion: "
|
|
1401
|
+
iosVersion: "27.0",
|
|
1207
1402
|
keyboardHeight: 308,
|
|
1208
1403
|
physicalPPI: 460,
|
|
1209
1404
|
hardwareButtons: modernButtons(
|
|
@@ -1242,9 +1437,10 @@ var init_devices = __esm({
|
|
|
1242
1437
|
// face-on. The 17 Pro's flat rail contributes ~6.6pt on the same basis,
|
|
1243
1438
|
// which is why it sits at 15.3 and the Air should not.
|
|
1244
1439
|
frameInsets: uniformFrameInsets(10.7),
|
|
1245
|
-
dynamicIsland: { width:
|
|
1440
|
+
dynamicIsland: { width: 125, height: 110 / 3, top: 20 },
|
|
1441
|
+
statusRowCenter: 39,
|
|
1246
1442
|
safeAreaInsets: { top: 59, bottom: 34, left: 0, right: 0 },
|
|
1247
|
-
iosVersion: "
|
|
1443
|
+
iosVersion: "27.0",
|
|
1248
1444
|
keyboardHeight: 318,
|
|
1249
1445
|
physicalPPI: 460,
|
|
1250
1446
|
hardwareButtons: modernButtons(
|
|
@@ -1268,11 +1464,15 @@ var init_devices = __esm({
|
|
|
1268
1464
|
homeIndicatorHeight: 34,
|
|
1269
1465
|
cornerRadius: cornerRadii(61),
|
|
1270
1466
|
continuousCornerRadius: cornerRadii(84.661),
|
|
1467
|
+
// the ios 27 simulator's ContainerRelativeShape at the root draws 62
|
|
1468
|
+
// less its smallest inset from the display (54 at 8pt, 32 at 30pt).
|
|
1469
|
+
systemCornerRadius: cornerRadii(62),
|
|
1271
1470
|
// display border 1.44mm plus the visible flat housing rail.
|
|
1272
1471
|
frameInsets: uniformFrameInsets(15.3),
|
|
1273
|
-
dynamicIsland: { width:
|
|
1472
|
+
dynamicIsland: { width: 125, height: 110 / 3, top: 14 },
|
|
1473
|
+
statusRowCenter: 33,
|
|
1274
1474
|
safeAreaInsets: { top: 62, bottom: 34, left: 0, right: 0 },
|
|
1275
|
-
iosVersion: "
|
|
1475
|
+
iosVersion: "27.0",
|
|
1276
1476
|
keyboardHeight: 308,
|
|
1277
1477
|
physicalPPI: 460,
|
|
1278
1478
|
hardwareButtons: modernButtons(
|
|
@@ -1296,9 +1496,10 @@ var init_devices = __esm({
|
|
|
1296
1496
|
continuousCornerRadius: cornerRadii(85.163),
|
|
1297
1497
|
// display border 1.36mm plus the visible flat housing rail.
|
|
1298
1498
|
frameInsets: uniformFrameInsets(15.4),
|
|
1299
|
-
dynamicIsland: { width:
|
|
1499
|
+
dynamicIsland: { width: 376 / 3, height: 110 / 3, top: 14 },
|
|
1500
|
+
statusRowCenter: 33,
|
|
1300
1501
|
safeAreaInsets: { top: 62, bottom: 34, left: 0, right: 0 },
|
|
1301
|
-
iosVersion: "
|
|
1502
|
+
iosVersion: "27.0",
|
|
1302
1503
|
keyboardHeight: 318,
|
|
1303
1504
|
physicalPPI: 460,
|
|
1304
1505
|
hardwareButtons: modernButtons(
|
|
@@ -1319,7 +1520,10 @@ var init_devices = __esm({
|
|
|
1319
1520
|
height: 678,
|
|
1320
1521
|
scale: 3,
|
|
1321
1522
|
statusBarHeight: 66,
|
|
1322
|
-
|
|
1523
|
+
// the ios 27.1 duo simulator draws the gesture home indicator in both
|
|
1524
|
+
// postures: a 167pt x 5pt pill 8pt above the display bottom on the
|
|
1525
|
+
// cover, sized by the same rule as the other iphones (HomeIndicator).
|
|
1526
|
+
homeIndicatorHeight: 34,
|
|
1323
1527
|
// hinge on the left. the hinge-side display corners measure 5pt in
|
|
1324
1528
|
// apple's 2d outer product art; the free side keeps the 61pt pro curve.
|
|
1325
1529
|
cornerRadius: { topLeft: 5, topRight: 61, bottomRight: 61, bottomLeft: 5 },
|
|
@@ -1329,6 +1533,9 @@ var init_devices = __esm({
|
|
|
1329
1533
|
bottomRight: 61,
|
|
1330
1534
|
bottomLeft: 5
|
|
1331
1535
|
},
|
|
1536
|
+
// the ios 27.1 duo simulator reports 59, and sheets 8pt in on the free
|
|
1537
|
+
// side carry 51 there (41 at 18pt in).
|
|
1538
|
+
systemCornerRadius: { topLeft: 5, topRight: 59, bottomRight: 59, bottomLeft: 5 },
|
|
1332
1539
|
// display edge to silhouette, measured off apple's 2d outer product art
|
|
1333
1540
|
// at 3x. the barrel is not part of the body: it protrudes 11.67pt past
|
|
1334
1541
|
// the left silhouette, so the full outer width is frame + protrusion.
|
|
@@ -1362,6 +1569,45 @@ var init_devices = __esm({
|
|
|
1362
1569
|
trailing: 29
|
|
1363
1570
|
}
|
|
1364
1571
|
},
|
|
1572
|
+
"ipad-pro-11": {
|
|
1573
|
+
// frame and hardware buttons are not sourced yet, so this stays off the
|
|
1574
|
+
// shipping picker the same way the duo does.
|
|
1575
|
+
developmentOnly: true,
|
|
1576
|
+
...iosDevice({
|
|
1577
|
+
model: "ipad-pro-11",
|
|
1578
|
+
name: "iPad Pro 11-inch (M5)",
|
|
1579
|
+
// iPad Pro 11-inch (M5) 12GB, iOS 27.0, simulator DBD4B183, UIKit probe
|
|
1580
|
+
// scenario `metrics`. portrait UIScreen.bounds 834×1210, scale 2,
|
|
1581
|
+
// nativeBounds 1668×2420. the window matched the screen.
|
|
1582
|
+
width: 834,
|
|
1583
|
+
height: 1210,
|
|
1584
|
+
scale: 2,
|
|
1585
|
+
// portrait statusBarFrame was 834×32 at the top, and safeAreaInsets.top
|
|
1586
|
+
// was 32. landscape statusBarFrame stayed 32 tall while safeAreaInsets.top
|
|
1587
|
+
// was 10; this field is the portrait bar.
|
|
1588
|
+
statusBarHeight: 32,
|
|
1589
|
+
// portrait and landscape safeAreaInsets.bottom were both 20. the probe
|
|
1590
|
+
// has no separate home-indicator height.
|
|
1591
|
+
homeIndicatorHeight: 20,
|
|
1592
|
+
// UIScreen _displayCornerRadius, both orientations. the framebuffer
|
|
1593
|
+
// mask's tangent extent was not measured separately.
|
|
1594
|
+
cornerRadius: cornerRadii(30),
|
|
1595
|
+
continuousCornerRadius: cornerRadii(30),
|
|
1596
|
+
// housing is unsourced. the frame is the display until it is measured.
|
|
1597
|
+
frameInsets: uniformFrameInsets(0),
|
|
1598
|
+
dynamicIsland: null,
|
|
1599
|
+
// portrait safeAreaInsets. landscape was top 10, left 0, bottom 20, right 0.
|
|
1600
|
+
safeAreaInsets: { top: 32, bottom: 20, left: 0, right: 0 },
|
|
1601
|
+
iosVersion: "27.0",
|
|
1602
|
+
// portrait docked keyboard, UIKeyboardFrameEndUserInfoKey
|
|
1603
|
+
// {0, 870, 834, 340}. landscape posted a zero-height frame.
|
|
1604
|
+
keyboardHeight: 340,
|
|
1605
|
+
// hypot(1668, 2420) / 11, measured native pixels over the device type's
|
|
1606
|
+
// 11-inch name. not a separate density read.
|
|
1607
|
+
physicalPPI: 267.19578360606573,
|
|
1608
|
+
hardwareButtons: modernButtons([0, 0], [0, 0], [0, 0], [0, 0])
|
|
1609
|
+
})
|
|
1610
|
+
},
|
|
1365
1611
|
"pixel-8": {
|
|
1366
1612
|
model: "pixel-8",
|
|
1367
1613
|
platform: "android",
|
|
@@ -2810,6 +3056,28 @@ var init_stub_manifest = __esm({
|
|
|
2810
3056
|
"../peach-compat/src/stub-manifest.ts"() {
|
|
2811
3057
|
"use strict";
|
|
2812
3058
|
COMPAT_REACT_NATIVE_DEEP_STUBS = {
|
|
3059
|
+
assetRegistry: {
|
|
3060
|
+
specifier: "react-native/asset-registry",
|
|
3061
|
+
stubFile: "rn-libraries/AssetRegistry.ts",
|
|
3062
|
+
runtimeTier: "core",
|
|
3063
|
+
buildResolvers: ["dep-prebundle"]
|
|
3064
|
+
},
|
|
3065
|
+
// react native 0.87 absorbed this package into react-native. packages built
|
|
3066
|
+
// against older releases still import the identical legacy entry.
|
|
3067
|
+
assetRegistryLegacy: {
|
|
3068
|
+
specifier: "@react-native/assets-registry/registry",
|
|
3069
|
+
stubFile: "rn-libraries/AssetRegistry.ts",
|
|
3070
|
+
runtimeTier: "core",
|
|
3071
|
+
buildResolvers: ["dep-prebundle"]
|
|
3072
|
+
},
|
|
3073
|
+
// expo 58's keyboard interop deep-imports TextInputState, whose flow source
|
|
3074
|
+
// does not parse outside metro. preserve its focus bookkeeping in the stub.
|
|
3075
|
+
textInputState: {
|
|
3076
|
+
specifier: "react-native/Libraries/Components/TextInput/TextInputState",
|
|
3077
|
+
stubFile: "rn-libraries/TextInputState.ts",
|
|
3078
|
+
runtimeTier: "core",
|
|
3079
|
+
buildResolvers: ["vite", "dep-prebundle"]
|
|
3080
|
+
},
|
|
2813
3081
|
usePressability: {
|
|
2814
3082
|
specifier: "react-native/Libraries/Pressability/usePressability",
|
|
2815
3083
|
stubFile: "rn-libraries/usePressability.ts",
|
|
@@ -2846,6 +3114,12 @@ var init_stub_manifest = __esm({
|
|
|
2846
3114
|
runtimeTier: "core",
|
|
2847
3115
|
buildResolvers: ["vite", "dep-prebundle"]
|
|
2848
3116
|
},
|
|
3117
|
+
reactFabricPublicInstance: {
|
|
3118
|
+
specifier: "react-native/Libraries/ReactNative/ReactFabricPublicInstance/ReactFabricPublicInstance",
|
|
3119
|
+
stubFile: "rn-libraries/ReactFabricPublicInstance.ts",
|
|
3120
|
+
runtimeTier: "core",
|
|
3121
|
+
buildResolvers: ["vite", "dep-prebundle"]
|
|
3122
|
+
},
|
|
2849
3123
|
reactNativeRenderer: {
|
|
2850
3124
|
specifier: "react-native/Libraries/Renderer/shims/ReactNative",
|
|
2851
3125
|
stubFile: "rn-libraries/ReactNative.ts",
|
|
@@ -3689,6 +3963,7 @@ var init_cloud_session = __esm({
|
|
|
3689
3963
|
"cli/cloud-session.ts"() {
|
|
3690
3964
|
"use strict";
|
|
3691
3965
|
init_backend_origin();
|
|
3966
|
+
init_is_record();
|
|
3692
3967
|
CLOUD_SESSION_VERSION = 3;
|
|
3693
3968
|
MAX_ENCODED_SESSION_BYTES = 32 * 1024;
|
|
3694
3969
|
RNX_SHELL_UPDATE_PREFIX = "__RNX_SHELL_UPDATE_V1__";
|
|
@@ -3743,9 +4018,6 @@ var init_detect = __esm({
|
|
|
3743
4018
|
});
|
|
3744
4019
|
|
|
3745
4020
|
// cli/cloud-client.ts
|
|
3746
|
-
function isRecord4(value) {
|
|
3747
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
3748
|
-
}
|
|
3749
4021
|
function failureSentence(text) {
|
|
3750
4022
|
let parsed;
|
|
3751
4023
|
try {
|
|
@@ -3753,8 +4025,8 @@ function failureSentence(text) {
|
|
|
3753
4025
|
} catch {
|
|
3754
4026
|
return null;
|
|
3755
4027
|
}
|
|
3756
|
-
if (!
|
|
3757
|
-
if (
|
|
4028
|
+
if (!isRecord(parsed)) return null;
|
|
4029
|
+
if (isRecord(parsed.error) && typeof parsed.error.message === "string") {
|
|
3758
4030
|
const code = typeof parsed.error.code === "string" && parsed.error.code ? ` [${parsed.error.code}]` : "";
|
|
3759
4031
|
return `${parsed.error.message}${code}`;
|
|
3760
4032
|
}
|
|
@@ -3881,7 +4153,7 @@ function listMetroAssetDest(assetsPath) {
|
|
|
3881
4153
|
return { directory, files, truncated };
|
|
3882
4154
|
}
|
|
3883
4155
|
function metroDescriptorHash(scaleBytes) {
|
|
3884
|
-
const hasher = (0,
|
|
4156
|
+
const hasher = (0, import_node_crypto6.createHash)("md5");
|
|
3885
4157
|
for (const bytes of scaleBytes) hasher.update(bytes);
|
|
3886
4158
|
return hasher.digest("hex");
|
|
3887
4159
|
}
|
|
@@ -3910,7 +4182,7 @@ function distinctByContent(directory, options) {
|
|
|
3910
4182
|
} catch {
|
|
3911
4183
|
continue;
|
|
3912
4184
|
}
|
|
3913
|
-
const digest = (0,
|
|
4185
|
+
const digest = (0, import_node_crypto6.createHash)("md5").update(bytes).digest("hex");
|
|
3914
4186
|
if (!byContent.has(digest)) byContent.set(digest, relative2);
|
|
3915
4187
|
}
|
|
3916
4188
|
return [...byContent.values()];
|
|
@@ -3944,7 +4216,7 @@ function placeMetroDescriptor(listing, descriptor) {
|
|
|
3944
4216
|
continue;
|
|
3945
4217
|
}
|
|
3946
4218
|
const identical = fileHashes ? bytes.every((file, index) => {
|
|
3947
|
-
const digest = (0,
|
|
4219
|
+
const digest = (0, import_node_crypto6.createHash)("md5").update(file).digest("hex");
|
|
3948
4220
|
return descriptor.scales.some(
|
|
3949
4221
|
(scale, declared) => scale === scales[index] && fileHashes[declared] === digest
|
|
3950
4222
|
);
|
|
@@ -4179,23 +4451,23 @@ async function produceArtifact(bundlePath, maxBytes, command, assetPolicy) {
|
|
|
4179
4451
|
}
|
|
4180
4452
|
return {
|
|
4181
4453
|
bytes,
|
|
4182
|
-
sha256: (0,
|
|
4454
|
+
sha256: (0, import_node_crypto6.createHash)("sha256").update(bytes).digest("hex"),
|
|
4183
4455
|
receipt: artifact.receipt,
|
|
4184
4456
|
assetsDirectory: prepared.dest?.directory ?? null,
|
|
4185
4457
|
warnings
|
|
4186
4458
|
};
|
|
4187
4459
|
}
|
|
4188
4460
|
function readCreateResponse(value, expectedBytes, expectedSha256) {
|
|
4189
|
-
if (!
|
|
4461
|
+
if (!isRecord(value)) throw new Error("remote simulator create returned invalid JSON");
|
|
4190
4462
|
const artifactId = `sha256:${expectedSha256}`;
|
|
4191
|
-
const isExpectedArtifact = (artifact) =>
|
|
4463
|
+
const isExpectedArtifact = (artifact) => isRecord(artifact) && artifact.id === artifactId && typeof artifact.bytes === "number" && Number.isInteger(artifact.bytes) && artifact.bytes === expectedBytes;
|
|
4192
4464
|
const boxId = value.boxId;
|
|
4193
4465
|
const boxToken = value.token;
|
|
4194
4466
|
const simulator = value.simulator;
|
|
4195
|
-
const simId =
|
|
4196
|
-
const claim =
|
|
4197
|
-
const simulatorToken =
|
|
4198
|
-
if (typeof boxId !== "string" || !boxId || value.size !== "nano" || typeof boxToken !== "string" || !boxToken || !isExpectedArtifact(value.artifact) || !
|
|
4467
|
+
const simId = isRecord(simulator) ? simulator.simId : null;
|
|
4468
|
+
const claim = isRecord(simulator) ? simulator.claim : null;
|
|
4469
|
+
const simulatorToken = isRecord(simulator) ? simulator.token : null;
|
|
4470
|
+
if (typeof boxId !== "string" || !boxId || value.size !== "nano" || typeof boxToken !== "string" || !boxToken || !isExpectedArtifact(value.artifact) || !isRecord(simulator) || typeof simId !== "string" || !simId || !isExpectedArtifact(simulator.artifact) || !isRecord(claim) || typeof claim.id !== "string" || !claim.id || typeof claim.expiresAt !== "number" || typeof simulatorToken !== "string" || !simulatorToken) {
|
|
4199
4471
|
throw new Error("remote simulator create returned an invalid receipt");
|
|
4200
4472
|
}
|
|
4201
4473
|
return {
|
|
@@ -4284,11 +4556,11 @@ async function createCloudBox(options) {
|
|
|
4284
4556
|
warnings: artifact.warnings
|
|
4285
4557
|
};
|
|
4286
4558
|
}
|
|
4287
|
-
var
|
|
4559
|
+
var import_node_crypto6, 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;
|
|
4288
4560
|
var init_cloud_client = __esm({
|
|
4289
4561
|
"cli/cloud-client.ts"() {
|
|
4290
4562
|
"use strict";
|
|
4291
|
-
|
|
4563
|
+
import_node_crypto6 = require("node:crypto");
|
|
4292
4564
|
import_node_fs14 = require("node:fs");
|
|
4293
4565
|
import_node_path15 = require("node:path");
|
|
4294
4566
|
init_metroAssetArtifact();
|
|
@@ -4302,6 +4574,7 @@ var init_cloud_client = __esm({
|
|
|
4302
4574
|
init_auth();
|
|
4303
4575
|
init_cloud_session();
|
|
4304
4576
|
init_detect();
|
|
4577
|
+
init_is_record();
|
|
4305
4578
|
DEFAULT_RNX_CLOUD_ORIGIN = rnxPublicBrand.origin;
|
|
4306
4579
|
MAX_RNX_CLOUD_BUNDLE_BYTES = RNX_CLOUD_MAX_ARTIFACT_BYTES;
|
|
4307
4580
|
REMOTE_COMMAND = "peach remote";
|
|
@@ -4329,9 +4602,6 @@ var send_to_box_exports = {};
|
|
|
4329
4602
|
__export(send_to_box_exports, {
|
|
4330
4603
|
sendToBox: () => sendToBox
|
|
4331
4604
|
});
|
|
4332
|
-
function isRecord5(value) {
|
|
4333
|
-
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
4334
|
-
}
|
|
4335
4605
|
function cloudDevice(capturedModel) {
|
|
4336
4606
|
const captured = listDeviceModels().find((model) => model === capturedModel);
|
|
4337
4607
|
return captured && getRuntimePlatform(captured) === "ios" ? captured : DEFAULT_DEVICE_BY_PLATFORM.ios;
|
|
@@ -4342,8 +4612,8 @@ async function sendToBox(options) {
|
|
|
4342
4612
|
simId: options.simId,
|
|
4343
4613
|
code: '(typeof window.__sootsimCaptureBundle === "function") ? window.__sootsimCaptureBundle() : null'
|
|
4344
4614
|
});
|
|
4345
|
-
const bundleUrl =
|
|
4346
|
-
if (!
|
|
4615
|
+
const bundleUrl = isRecord(captured) ? captured.bundleUrl : null;
|
|
4616
|
+
if (!isRecord(captured) || typeof bundleUrl !== "string" || !bundleUrl) {
|
|
4347
4617
|
throw new Error(
|
|
4348
4618
|
"send to box needs a simulator running an app: this one has no bundle loaded"
|
|
4349
4619
|
);
|
|
@@ -4359,7 +4629,7 @@ async function sendToBox(options) {
|
|
|
4359
4629
|
const storage = dumped;
|
|
4360
4630
|
const created = await createCloudBox({
|
|
4361
4631
|
bundlePath: toRNXProductionBundleUrl(bundleUrl),
|
|
4362
|
-
device: options.device ?? cloudDevice(
|
|
4632
|
+
device: options.device ?? cloudDevice(isRecord(captured.deviceSpec) ? captured.deviceSpec.model : null),
|
|
4363
4633
|
authorization: options.authorization,
|
|
4364
4634
|
accountId: options.accountId,
|
|
4365
4635
|
apiOrigin: options.apiOrigin,
|
|
@@ -4386,6 +4656,7 @@ var init_send_to_box = __esm({
|
|
|
4386
4656
|
init_devices();
|
|
4387
4657
|
init_metro_production_bundle();
|
|
4388
4658
|
init_cloud_client();
|
|
4659
|
+
init_is_record();
|
|
4389
4660
|
}
|
|
4390
4661
|
});
|
|
4391
4662
|
|
|
@@ -4481,9 +4752,7 @@ var import_node_path = require("node:path");
|
|
|
4481
4752
|
|
|
4482
4753
|
// src/plist.ts
|
|
4483
4754
|
var import_plist = __toESM(require("@expo/plist"), 1);
|
|
4484
|
-
|
|
4485
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4486
|
-
}
|
|
4755
|
+
init_is_record();
|
|
4487
4756
|
function resolvePlistParser(value) {
|
|
4488
4757
|
if (!isRecord(value)) return null;
|
|
4489
4758
|
const direct = value.parse;
|
|
@@ -6052,6 +6321,7 @@ var RNX_RUNTIME_PRODUCT = {
|
|
|
6052
6321
|
var rnxRuntime = createRuntimeDelivery(RNX_RUNTIME_PRODUCT);
|
|
6053
6322
|
|
|
6054
6323
|
// src/host/agent-host.ts
|
|
6324
|
+
var import_node_crypto5 = require("node:crypto");
|
|
6055
6325
|
var import_node_fs10 = __toESM(require("node:fs"), 1);
|
|
6056
6326
|
var import_node_path10 = __toESM(require("node:path"), 1);
|
|
6057
6327
|
|
|
@@ -6838,78 +7108,6 @@ async function waitForFirstEvent(fifo, predicate, timeoutMs) {
|
|
|
6838
7108
|
}
|
|
6839
7109
|
}
|
|
6840
7110
|
|
|
6841
|
-
// src/team-machine-prompt.ts
|
|
6842
|
-
var import_node_child_process3 = require("node:child_process");
|
|
6843
|
-
|
|
6844
|
-
// src/agent-identity.ts
|
|
6845
|
-
var TEAM_MACHINE_SESSION_RE = /^[A-Za-z0-9._:-]{1,160}$/;
|
|
6846
|
-
function teamMachineSessionIdFromCliIdentity(identity) {
|
|
6847
|
-
if (!identity?.startsWith("TM_SESSION:")) return null;
|
|
6848
|
-
const sessionId = identity.slice("TM_SESSION:".length).trim();
|
|
6849
|
-
if (!TEAM_MACHINE_SESSION_RE.test(sessionId)) return null;
|
|
6850
|
-
return sessionId;
|
|
6851
|
-
}
|
|
6852
|
-
function isValidTeamMachineSessionId(sessionId) {
|
|
6853
|
-
return TEAM_MACHINE_SESSION_RE.test(sessionId);
|
|
6854
|
-
}
|
|
6855
|
-
|
|
6856
|
-
// src/team-machine-prompt.ts
|
|
6857
|
-
function formatTeamMachinePromptText(prompt) {
|
|
6858
|
-
return typeof prompt.text === "string" ? prompt.text.trim() : "";
|
|
6859
|
-
}
|
|
6860
|
-
function resolveTeamMachineCommand(explicit) {
|
|
6861
|
-
const fromArg = explicit?.trim();
|
|
6862
|
-
if (fromArg) return fromArg;
|
|
6863
|
-
return "tm";
|
|
6864
|
-
}
|
|
6865
|
-
async function sendPromptToTeamMachineSession(input) {
|
|
6866
|
-
const sessionId = input.sessionId.trim();
|
|
6867
|
-
if (!isValidTeamMachineSessionId(sessionId)) {
|
|
6868
|
-
throw new Error(`invalid Team Machine session id: ${sessionId || "<empty>"}`);
|
|
6869
|
-
}
|
|
6870
|
-
const text = formatTeamMachinePromptText(input.prompt);
|
|
6871
|
-
if (!text) {
|
|
6872
|
-
throw new Error("prompt text is empty");
|
|
6873
|
-
}
|
|
6874
|
-
const command = resolveTeamMachineCommand(input.command);
|
|
6875
|
-
const timeoutMs = input.timeoutMs ?? 15e3;
|
|
6876
|
-
await new Promise((resolve5, reject) => {
|
|
6877
|
-
const child = (0, import_node_child_process3.spawn)(command, ["send", sessionId, text], {
|
|
6878
|
-
stdio: ["ignore", "ignore", "pipe"],
|
|
6879
|
-
env: process.env
|
|
6880
|
-
});
|
|
6881
|
-
let stderr = "";
|
|
6882
|
-
const timer = setTimeout(() => {
|
|
6883
|
-
try {
|
|
6884
|
-
child.kill("SIGTERM");
|
|
6885
|
-
} catch {
|
|
6886
|
-
}
|
|
6887
|
-
reject(new Error(`tm send timed out after ${Math.round(timeoutMs / 1e3)}s`));
|
|
6888
|
-
}, timeoutMs);
|
|
6889
|
-
child.stderr?.setEncoding("utf8");
|
|
6890
|
-
child.stderr?.on("data", (chunk) => {
|
|
6891
|
-
if (stderr.length < 4e3) stderr += String(chunk);
|
|
6892
|
-
});
|
|
6893
|
-
child.on("error", (err) => {
|
|
6894
|
-
clearTimeout(timer);
|
|
6895
|
-
reject(err);
|
|
6896
|
-
});
|
|
6897
|
-
child.on("close", (code, signal) => {
|
|
6898
|
-
clearTimeout(timer);
|
|
6899
|
-
if (code === 0) {
|
|
6900
|
-
resolve5();
|
|
6901
|
-
return;
|
|
6902
|
-
}
|
|
6903
|
-
const detail = stderr.trim();
|
|
6904
|
-
reject(
|
|
6905
|
-
new Error(
|
|
6906
|
-
detail || `tm send exited with ${signal ? `signal ${signal}` : `code ${code ?? "unknown"}`}`
|
|
6907
|
-
)
|
|
6908
|
-
);
|
|
6909
|
-
});
|
|
6910
|
-
});
|
|
6911
|
-
}
|
|
6912
|
-
|
|
6913
7111
|
// src/host/agent-host.ts
|
|
6914
7112
|
var WS_OPEN = 1;
|
|
6915
7113
|
var SESSION_STATUS_PERSIST_DELAY_MS = 25;
|
|
@@ -6931,6 +7129,8 @@ var AgentHost = class {
|
|
|
6931
7129
|
// pushes so a CLI `peach agent sessions --watch` can react to state
|
|
6932
7130
|
// changes driven by another client.
|
|
6933
7131
|
allSockets = /* @__PURE__ */ new Set();
|
|
7132
|
+
inspectQueues = /* @__PURE__ */ new Map();
|
|
7133
|
+
inspectListeners = /* @__PURE__ */ new Map();
|
|
6934
7134
|
// agent wrappers also emit prompt-received from the FIFO reader, but the
|
|
6935
7135
|
// shell/daemon already knows the user-facing display text when send-prompt
|
|
6936
7136
|
// is accepted. emit the friendly prompt immediately and suppress the raw
|
|
@@ -6962,6 +7162,18 @@ var AgentHost = class {
|
|
|
6962
7162
|
}
|
|
6963
7163
|
this.sessionsBySocket.delete(ws);
|
|
6964
7164
|
}
|
|
7165
|
+
for (const [simId, listeners] of this.inspectListeners) {
|
|
7166
|
+
const remaining = [];
|
|
7167
|
+
for (const listener of listeners) {
|
|
7168
|
+
if (listener.socket === ws) {
|
|
7169
|
+
listener.reject(new AgentSessionError("DISCONNECT", "listener disconnected"));
|
|
7170
|
+
} else {
|
|
7171
|
+
remaining.push(listener);
|
|
7172
|
+
}
|
|
7173
|
+
}
|
|
7174
|
+
if (remaining.length > 0) this.inspectListeners.set(simId, remaining);
|
|
7175
|
+
else this.inspectListeners.delete(simId);
|
|
7176
|
+
}
|
|
6965
7177
|
this.allSockets.delete(ws);
|
|
6966
7178
|
}
|
|
6967
7179
|
/** handle an agent:* message. returns true iff the message was recognized
|
|
@@ -7010,6 +7222,13 @@ var AgentHost = class {
|
|
|
7010
7222
|
}
|
|
7011
7223
|
this.subscriptions.clear();
|
|
7012
7224
|
this.sessionsBySocket.clear();
|
|
7225
|
+
for (const listeners of this.inspectListeners.values()) {
|
|
7226
|
+
for (const listener of listeners) {
|
|
7227
|
+
listener.reject(new AgentSessionError("DISCONNECT", "daemon closed"));
|
|
7228
|
+
}
|
|
7229
|
+
}
|
|
7230
|
+
this.inspectListeners.clear();
|
|
7231
|
+
this.inspectQueues.clear();
|
|
7013
7232
|
this.allSockets.clear();
|
|
7014
7233
|
}
|
|
7015
7234
|
// --- dispatch ---
|
|
@@ -7028,8 +7247,17 @@ var AgentHost = class {
|
|
|
7028
7247
|
return listSessions(msg.projectId ? String(msg.projectId) : void 0);
|
|
7029
7248
|
case "agent:start-session":
|
|
7030
7249
|
return this.doStartSession(msg.input ?? {});
|
|
7031
|
-
case "agent:
|
|
7032
|
-
return this.
|
|
7250
|
+
case "agent:listen-inspect":
|
|
7251
|
+
return this.listenForInspect(ws, this.requireSimId(msg, type));
|
|
7252
|
+
case "agent:get-inspect-listener-status": {
|
|
7253
|
+
const simId = this.requireSimId(msg, type);
|
|
7254
|
+
return { simId, listening: (this.inspectListeners.get(simId)?.length ?? 0) > 0 };
|
|
7255
|
+
}
|
|
7256
|
+
case "agent:send-inspect-message":
|
|
7257
|
+
return this.sendInspectMessage(
|
|
7258
|
+
this.requireSimId(msg, type),
|
|
7259
|
+
this.normalizePromptEnvelope(msg)
|
|
7260
|
+
);
|
|
7033
7261
|
case "agent:send-prompt": {
|
|
7034
7262
|
const sessionId = String(msg.sessionId);
|
|
7035
7263
|
const session = findSessionById(sessionId);
|
|
@@ -7061,27 +7289,45 @@ var AgentHost = class {
|
|
|
7061
7289
|
}
|
|
7062
7290
|
}
|
|
7063
7291
|
// --- operation impls ---
|
|
7064
|
-
|
|
7292
|
+
requireSimId(msg, type) {
|
|
7065
7293
|
const simId = typeof msg.simId === "string" ? msg.simId.trim() : "";
|
|
7066
|
-
if (!simId) {
|
|
7067
|
-
|
|
7068
|
-
|
|
7069
|
-
|
|
7070
|
-
|
|
7071
|
-
|
|
7072
|
-
|
|
7073
|
-
|
|
7074
|
-
|
|
7075
|
-
throw new AgentSessionError(
|
|
7076
|
-
"UNSUPPORTED_CLAIM",
|
|
7077
|
-
`sim ${simId} is claimed by a CLI identity that is not promptable`
|
|
7078
|
-
);
|
|
7294
|
+
if (!simId) throw new AgentSessionError("NO_SIM", `${type} requires simId`);
|
|
7295
|
+
return simId;
|
|
7296
|
+
}
|
|
7297
|
+
listenForInspect(socket, simId) {
|
|
7298
|
+
const queue = this.inspectQueues.get(simId);
|
|
7299
|
+
const queued = queue?.shift();
|
|
7300
|
+
if (queued && queue) {
|
|
7301
|
+
if (queue.length === 0) this.inspectQueues.delete(simId);
|
|
7302
|
+
return Promise.resolve(queued);
|
|
7079
7303
|
}
|
|
7080
|
-
|
|
7081
|
-
|
|
7082
|
-
|
|
7304
|
+
return new Promise((resolve5, reject) => {
|
|
7305
|
+
const listeners = this.inspectListeners.get(simId) ?? [];
|
|
7306
|
+
listeners.push({ socket, resolve: resolve5, reject });
|
|
7307
|
+
this.inspectListeners.set(simId, listeners);
|
|
7083
7308
|
});
|
|
7084
|
-
|
|
7309
|
+
}
|
|
7310
|
+
sendInspectMessage(simId, prompt) {
|
|
7311
|
+
if (!prompt.text.trim()) {
|
|
7312
|
+
throw new AgentSessionError("EMPTY_PROMPT", "inspect message cannot be empty");
|
|
7313
|
+
}
|
|
7314
|
+
const message = {
|
|
7315
|
+
id: `inspect-${(0, import_node_crypto5.randomUUID)()}`,
|
|
7316
|
+
simId,
|
|
7317
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7318
|
+
prompt
|
|
7319
|
+
};
|
|
7320
|
+
const listeners = this.inspectListeners.get(simId);
|
|
7321
|
+
const listener = listeners?.shift();
|
|
7322
|
+
if (listener && listeners) {
|
|
7323
|
+
if (listeners.length === 0) this.inspectListeners.delete(simId);
|
|
7324
|
+
listener.resolve(message);
|
|
7325
|
+
return { ok: true, queued: false, messageId: message.id };
|
|
7326
|
+
}
|
|
7327
|
+
const queue = this.inspectQueues.get(simId) ?? [];
|
|
7328
|
+
queue.push(message);
|
|
7329
|
+
this.inspectQueues.set(simId, queue);
|
|
7330
|
+
return { ok: true, queued: true, messageId: message.id };
|
|
7085
7331
|
}
|
|
7086
7332
|
async doStartSession(input) {
|
|
7087
7333
|
const project = findProjectById(input.projectId);
|
|
@@ -7537,20 +7783,6 @@ function applyFetchProxyCors(res) {
|
|
|
7537
7783
|
res.setHeader(key, value);
|
|
7538
7784
|
}
|
|
7539
7785
|
}
|
|
7540
|
-
function formatFetchProxyError(targetUrl, err) {
|
|
7541
|
-
const details = [];
|
|
7542
|
-
const error = err;
|
|
7543
|
-
if (error?.code) details.push(error.code);
|
|
7544
|
-
if (error?.message) details.push(error.message);
|
|
7545
|
-
if (error?.cause?.code) details.push(error.cause.code);
|
|
7546
|
-
if (error?.cause?.message) details.push(error.cause.message);
|
|
7547
|
-
const uniqueDetails = [...new Set(details.filter(Boolean))];
|
|
7548
|
-
const message = uniqueDetails.join(" | ") || String(err);
|
|
7549
|
-
if (targetUrl.includes("stored-in-.env.local")) {
|
|
7550
|
-
return `${message} | upstream url still contains placeholder env values`;
|
|
7551
|
-
}
|
|
7552
|
-
return message;
|
|
7553
|
-
}
|
|
7554
7786
|
function buildFetchProxyHeaders(reqHeaders, targetUrl) {
|
|
7555
7787
|
const headers = {};
|
|
7556
7788
|
for (const [key, value] of Object.entries(reqHeaders)) {
|
|
@@ -7572,7 +7804,7 @@ function buildAppApiProxyHeaders(reqHeaders, targetUrl) {
|
|
|
7572
7804
|
headers[key] = value;
|
|
7573
7805
|
}
|
|
7574
7806
|
headers.host = targetUrl.host;
|
|
7575
|
-
if (!Object.keys(headers).some((name2) => name2.toLowerCase() === "
|
|
7807
|
+
if (!Object.keys(headers).some((name2) => name2.toLowerCase() === "mobile-origin")) {
|
|
7576
7808
|
headers.origin = targetUrl.origin;
|
|
7577
7809
|
headers.referer = `${targetUrl.origin}/`;
|
|
7578
7810
|
}
|
|
@@ -7694,12 +7926,8 @@ async function handleFetchProxyRequest(req, res) {
|
|
|
7694
7926
|
try {
|
|
7695
7927
|
await proxy(upstreamUrl, originalMethod, body, 0);
|
|
7696
7928
|
} catch (err) {
|
|
7697
|
-
if (res.headersSent) {
|
|
7698
|
-
res.destroy(err instanceof Error ? err : new Error(String(err)));
|
|
7699
|
-
return;
|
|
7700
|
-
}
|
|
7701
7929
|
const norm = normalizeHostname(upstreamUrl.hostname);
|
|
7702
|
-
if (isLoopbackHost(norm) && err?.code === "ECONNREFUSED") {
|
|
7930
|
+
if (!res.headersSent && isLoopbackHost(norm) && err?.code === "ECONNREFUSED") {
|
|
7703
7931
|
const altHost = norm === "::1" ? "127.0.0.1" : norm === "127.0.0.1" ? "::1" : "127.0.0.1";
|
|
7704
7932
|
if (altHost !== norm) {
|
|
7705
7933
|
try {
|
|
@@ -7711,9 +7939,7 @@ async function handleFetchProxyRequest(req, res) {
|
|
|
7711
7939
|
}
|
|
7712
7940
|
}
|
|
7713
7941
|
}
|
|
7714
|
-
|
|
7715
|
-
res.writeHead(502, { "Content-Type": "text/plain" });
|
|
7716
|
-
res.end(`fetch proxy error: ${formatFetchProxyError(upstreamUrl.href, err)}`);
|
|
7942
|
+
req.socket.destroy();
|
|
7717
7943
|
}
|
|
7718
7944
|
}
|
|
7719
7945
|
async function handleBundleProxyRequest(req, res) {
|
|
@@ -7804,10 +8030,7 @@ function handleAppApiRequest(req, res) {
|
|
|
7804
8030
|
proxyRes.pipe(res);
|
|
7805
8031
|
}
|
|
7806
8032
|
);
|
|
7807
|
-
proxyReq.on("error", (
|
|
7808
|
-
res.statusCode = 502;
|
|
7809
|
-
res.end(`app proxy error: ${err.message}`);
|
|
7810
|
-
});
|
|
8033
|
+
proxyReq.on("error", () => req.socket.destroy());
|
|
7811
8034
|
req.pipe(proxyReq);
|
|
7812
8035
|
return true;
|
|
7813
8036
|
}
|
|
@@ -7944,7 +8167,7 @@ async function dispatchPlaneCommand(plane, type, msg, mutationOptions) {
|
|
|
7944
8167
|
}
|
|
7945
8168
|
|
|
7946
8169
|
// cli/commands/box/checkout-plane.ts
|
|
7947
|
-
var
|
|
8170
|
+
var import_node_child_process3 = require("node:child_process");
|
|
7948
8171
|
var import_node_fs11 = __toESM(require("node:fs"), 1);
|
|
7949
8172
|
var import_node_path11 = __toESM(require("node:path"), 1);
|
|
7950
8173
|
var CheckoutRequiresGitError = class extends Error {
|
|
@@ -7986,7 +8209,7 @@ var CheckoutFilePlane = class {
|
|
|
7986
8209
|
}
|
|
7987
8210
|
listFiles() {
|
|
7988
8211
|
const args = this.trackedOnly ? ["ls-files", "-z"] : ["ls-files", "-co", "--exclude-standard", "-z"];
|
|
7989
|
-
const stdout = (0,
|
|
8212
|
+
const stdout = (0, import_node_child_process3.execFileSync)("git", args, {
|
|
7990
8213
|
cwd: this.root,
|
|
7991
8214
|
encoding: "utf8",
|
|
7992
8215
|
maxBuffer: 64 * 1024 * 1024,
|
|
@@ -9084,16 +9307,7 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
9084
9307
|
this.portFallbackCount = Math.max(1, opts.portFallbackCount ?? 10);
|
|
9085
9308
|
this.openUrlHandler = opts.openUrl;
|
|
9086
9309
|
this.agentHost = new AgentHost({
|
|
9087
|
-
getExcludePorts: opts.agentScanExcludes
|
|
9088
|
-
resolveCliLease: (simId) => {
|
|
9089
|
-
const sim = this.sims.get(simId);
|
|
9090
|
-
const lease = sim ? this.getActiveLease(sim) : null;
|
|
9091
|
-
return lease ? {
|
|
9092
|
-
kind: lease.kind,
|
|
9093
|
-
cliIdentityKey: lease.cliIdentityKey,
|
|
9094
|
-
expiresAt: lease.expiresAt
|
|
9095
|
-
} : null;
|
|
9096
|
-
}
|
|
9310
|
+
getExcludePorts: opts.agentScanExcludes
|
|
9097
9311
|
});
|
|
9098
9312
|
this.contrastOrigin = opts.contrastOrigin?.replace(/\/$/, "") || null;
|
|
9099
9313
|
this.simIdleReapTtlMs = opts.simIdleReapTtlMs ?? _SootSimBridgeHost.SIM_IDLE_REAP_TTL_MS;
|
|
@@ -9123,6 +9337,7 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
9123
9337
|
async startAsync(options) {
|
|
9124
9338
|
if (this.httpServer || this.wss) return this.effectivePort;
|
|
9125
9339
|
this.refreshActiveRuntime();
|
|
9340
|
+
this.bootstrapping = !this.activeRuntimeDirPath || !import_fs3.default.existsSync(import_path3.default.join(this.activeRuntimeDirPath, "index.html"));
|
|
9126
9341
|
for (let attempt = 0; attempt < this.portFallbackCount; attempt++) {
|
|
9127
9342
|
const candidate = this.preferredPort + attempt;
|
|
9128
9343
|
try {
|