peachsim 0.1.571 → 0.1.572
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 +106 -106
- package/cli/app-config.ts +1 -1
- package/cli/app-fonts.ts +4 -4
- package/cli/auth.ts +11 -11
- package/cli/bin.ts +4 -4
- package/cli/bridge-flow-runner.ts +13 -13
- package/cli/browser-evals.ts +2 -2
- package/cli/cli-update.ts +6 -6
- package/cli/cloud-client.ts +16 -16
- package/cli/cloud-dispatch.ts +2 -2
- package/cli/cloud-session.ts +12 -12
- package/cli/cloud-test-tunnel.ts +4 -4
- package/cli/command-registry.ts +7 -7
- package/cli/commands/agent-wrapper.ts +7 -7
- package/cli/commands/agent.ts +16 -16
- package/cli/commands/app-fonts.ts +3 -3
- package/cli/commands/assert.ts +10 -10
- package/cli/commands/auth.ts +5 -5
- package/cli/commands/box/checkout-plane.ts +1 -1
- package/cli/commands/box/plane-share.ts +2 -2
- package/cli/commands/box/rnx-command.ts +5 -5
- package/cli/commands/box.ts +38 -38
- package/cli/commands/camera.ts +13 -13
- package/cli/commands/cleanup.ts +13 -13
- package/cli/commands/compat.ts +7 -7
- package/cli/commands/config.ts +5 -5
- package/cli/commands/control.ts +63 -63
- package/cli/commands/cpu-profile.ts +11 -11
- package/cli/commands/daemon-mac-app.ts +10 -10
- package/cli/commands/daemon.ts +29 -27
- package/cli/commands/debug.ts +35 -35
- package/cli/commands/desktop.ts +3 -3
- package/cli/commands/detox.ts +33 -33
- package/cli/commands/device.ts +9 -9
- package/cli/commands/diagnose.ts +17 -17
- package/cli/commands/do-chain.ts +4 -4
- package/cli/commands/electron.ts +9 -9
- package/cli/commands/film.ts +9 -9
- package/cli/commands/flow.ts +49 -49
- package/cli/commands/inspect/core.ts +12 -12
- package/cli/commands/inspect/count.ts +1 -1
- package/cli/commands/inspect/describe.ts +1 -1
- package/cli/commands/inspect/env.ts +2 -2
- package/cli/commands/inspect/find.ts +2 -2
- package/cli/commands/inspect/get-layout.ts +2 -2
- package/cli/commands/inspect/keyboard.ts +1 -1
- package/cli/commands/inspect/list.ts +4 -4
- package/cli/commands/inspect/memory.ts +1 -1
- package/cli/commands/inspect/resolve-target.ts +1 -1
- package/cli/commands/inspect/screens.ts +1 -1
- package/cli/commands/inspect/shared.ts +1 -1
- package/cli/commands/inspect/tree.ts +1 -1
- package/cli/commands/inspect/url.ts +1 -1
- package/cli/commands/inspect/wait-event.ts +5 -5
- package/cli/commands/inspect.ts +82 -82
- package/cli/commands/install-cli.ts +16 -16
- package/cli/commands/install-desktop.ts +26 -26
- package/cli/commands/login.ts +11 -11
- package/cli/commands/maestro-generate.ts +10 -10
- package/cli/commands/maestro.ts +77 -67
- package/cli/commands/mode.ts +4 -4
- package/cli/commands/no-bridge-hint.ts +12 -12
- package/cli/commands/perf.ts +11 -11
- package/cli/commands/permissions.ts +5 -5
- package/cli/commands/platform.ts +21 -21
- package/cli/commands/preview.ts +5 -5
- package/cli/commands/profile.ts +12 -12
- package/cli/commands/react.ts +15 -15
- package/cli/commands/record.ts +31 -31
- package/cli/commands/report-issue.ts +4 -4
- package/cli/commands/reset.ts +2 -2
- package/cli/commands/runtime.ts +23 -23
- package/cli/commands/screenshot-command.ts +2 -2
- package/cli/commands/screenshot-layers.ts +5 -5
- package/cli/commands/screenshot-mode.ts +7 -7
- package/cli/commands/screenshot.ts +24 -24
- package/cli/commands/screenshots-capture.ts +13 -13
- package/cli/commands/screenshots.ts +6 -6
- package/cli/commands/serve.ts +12 -12
- package/cli/commands/setup.ts +25 -25
- package/cli/commands/skills.ts +30 -23
- package/cli/commands/slides.ts +20 -20
- package/cli/commands/state.ts +2 -2
- package/cli/commands/storage.ts +3 -3
- package/cli/commands/telemetry.ts +2 -2
- package/cli/commands/test.ts +15 -15
- package/cli/commands/three-mode.ts +17 -17
- package/cli/commands/timeline.ts +12 -12
- package/cli/commands/upgrade.ts +11 -11
- package/cli/commands/upload.ts +26 -26
- package/cli/commands/version.ts +7 -7
- package/cli/commands/what-happened.ts +20 -20
- package/cli/current-sim.ts +3 -3
- package/cli/desktop-companion.ts +16 -16
- package/cli/drivers/electron.ts +4 -4
- package/cli/drivers/playwright-sim-host.ts +7 -7
- package/cli/drivers/playwright.ts +4 -4
- package/cli/drivers/registry.ts +1 -1
- package/cli/drivers/types.ts +5 -5
- package/cli/flow-export.ts +1 -1
- package/cli/flow-file.ts +5 -5
- package/cli/flow-session.ts +1 -1
- package/cli/help-core.ts +13 -13
- package/cli/hints.ts +14 -14
- package/cli/inspect-notice-state.ts +1 -1
- package/cli/internal-child.ts +2 -2
- package/cli/maestro-js.ts +4 -4
- package/cli/maestro-report.ts +1 -1
- package/cli/main.ts +14 -14
- package/cli/outbound-endpoints.ts +30 -30
- package/cli/parse-args.ts +7 -7
- package/cli/privacy.ts +1 -1
- package/cli/recording-access.ts +10 -10
- package/cli/resolve-assets.ts +2 -2
- package/cli/rnx-in-process.ts +5 -5
- package/cli/run-registry.ts +1 -1
- package/cli/run-rnx-core.ts +3 -3
- package/cli/run-rnx.ts +1 -1
- package/cli/runtime-notes.ts +1 -1
- package/cli/self-invocation.ts +1 -1
- package/cli/send-to-box.ts +1 -1
- package/cli/shell-init.ts +40 -40
- package/cli/ui.ts +1 -1
- package/cli/ws-bridge.ts +22 -22
- package/detox/config-loader.ts +1 -1
- package/detox/index.ts +28 -28
- package/detox/navigation.ts +2 -2
- package/dist-lib/agent-daemon-client.cjs +12 -12
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +2 -2
- package/dist-lib/agent-sessions.cjs +12 -12
- package/dist-lib/attached-projects.cjs +4 -4
- package/dist-lib/auth/shared-session.cjs +4 -4
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +4 -4
- package/dist-lib/bridge-contract-input.cjs +1 -1
- package/dist-lib/bridge-contract-input.mjs +1 -1
- package/dist-lib/bridge-contract.cjs +2 -2
- package/dist-lib/bridge-contract.mjs +2 -2
- package/dist-lib/capture-contract.cjs +1 -1
- package/dist-lib/capture-contract.mjs +1 -1
- 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 +42 -42
- package/dist-lib/cloud.mjs +42 -42
- package/dist-lib/config.cjs +2 -2
- package/dist-lib/detox/index.cjs +29 -29
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +12 -12
- package/dist-lib/host/bridge-host.cjs +72 -71
- package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
- 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 +6 -6
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +48 -48
- 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 +5 -5
- package/dist-lib/menu.mjs +5 -5
- package/dist-lib/metro-fingerprint-registry.cjs +1 -1
- package/dist-lib/metro-fingerprint-registry.mjs +1 -1
- package/dist-lib/metro-production-bundle.cjs +1 -1
- package/dist-lib/metro-production-bundle.mjs +1 -1
- package/dist-lib/metro.cjs +15 -15
- package/dist-lib/profiles.cjs +4 -4
- package/dist-lib/public-brand.cjs +3 -3
- 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 +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +2 -1
- package/dist-lib/sdk.cjs +9 -9
- package/dist-lib/sdk.mjs +9 -9
- package/dist-lib/skills.cjs +416 -415
- package/dist-lib/swift-compile.cjs +1 -1
- package/dist-lib/swift-compile.mjs +1 -1
- package/dist-lib/swift-package.cjs +1 -1
- package/dist-lib/swift-package.mjs +1 -1
- package/dist-lib/swift-submit.cjs +1 -1
- package/dist-lib/swift-submit.mjs +1 -1
- package/dist-lib/swift.cjs +1 -1
- package/dist-lib/vite.cjs +24 -24
- package/package.json +1 -1
- package/scripts/dev-server-scanner.ts +4 -3
- package/skills/contrast/SKILL.md +75 -75
- package/skills/{rnx-debug → peach-debug}/SKILL.md +90 -90
- package/skills/{rnx-perf → peach-perf}/SKILL.md +13 -13
- package/skills/{rnx-setup → peach-setup}/SKILL.md +60 -60
- package/skills/{rnx-test → peach-test}/SKILL.md +44 -44
- package/skills/{rnx-visual → peach-visual}/SKILL.md +26 -26
- package/src/agent-daemon-client.ts +5 -5
- package/src/agent-events.ts +1 -1
- package/src/agent-identity.ts +1 -1
- package/src/agent-sessions.ts +13 -13
- package/src/attached-projects.ts +1 -1
- package/src/auth/shared-session.ts +1 -1
- package/src/bridge-constants.ts +3 -3
- package/src/bridge-contract-input.ts +1 -1
- package/src/bridge-contract.ts +3 -3
- package/src/cli-version.ts +6 -6
- package/src/cloud.ts +40 -40
- package/src/config.ts +1 -1
- package/src/connect.ts +6 -6
- package/src/dev-server-open.ts +8 -8
- package/src/disk-cleanup.ts +3 -3
- package/src/home-paths.ts +26 -26
- package/src/host/agent-host.ts +3 -3
- package/src/host/bridge-host.ts +33 -33
- package/src/host/fetch-proxy-handler.ts +1 -1
- package/src/host/plane-host.ts +2 -2
- package/src/host/replacement-module-handler.ts +2 -2
- package/src/menu.ts +2 -2
- package/src/metro-plugin.ts +7 -7
- package/src/metro-production-bundle.ts +2 -2
- package/src/native-dev-bundle-url.ts +2 -2
- package/src/playwright-host-log.ts +1 -1
- package/src/public-brand.ts +2 -2
- package/src/react-native-host-modules.ts +1 -1
- package/src/rolldown-plugin-swift.ts +3 -3
- package/src/runtime-assets.ts +11 -11
- package/src/runtime-delivery.ts +6 -6
- package/src/screenshots/orchestrate.ts +1 -1
- package/src/screenshots/org-deck.ts +1 -1
- package/src/screenshots/schema.ts +2 -2
- package/src/sim-client.ts +1 -1
- package/src/skills/builtin/compat-check.ts +2 -2
- package/src/vite-plugin-one.ts +8 -8
- package/src/vite-plugin-swift.ts +3 -3
- package/src/vite-plugin.ts +6 -19
package/dist-lib/cloud.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.572 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
4
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
@@ -140,11 +140,11 @@ function rnxCloudScopesAllowCommand(scopes, type) {
|
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
// src/public-brand.ts
|
|
143
|
-
var name = "
|
|
143
|
+
var name = "Peach";
|
|
144
144
|
var rnxPublicBrand = Object.freeze({
|
|
145
145
|
name,
|
|
146
146
|
packageName: "peachsim",
|
|
147
|
-
commandName: "
|
|
147
|
+
commandName: "peach",
|
|
148
148
|
domain: "rnxsim.com",
|
|
149
149
|
origin: "https://rnxsim.com"
|
|
150
150
|
});
|
|
@@ -162,18 +162,18 @@ function normalizeCloudOrigin(source) {
|
|
|
162
162
|
try {
|
|
163
163
|
parsed = new URL(source);
|
|
164
164
|
} catch {
|
|
165
|
-
throw new Error(`invalid
|
|
165
|
+
throw new Error(`invalid Peach Cloud origin: ${source}`);
|
|
166
166
|
}
|
|
167
167
|
if (parsed.protocol !== "https:" && parsed.protocol !== "http:" || parsed.username || parsed.password || parsed.pathname !== "/" || parsed.search || parsed.hash) {
|
|
168
|
-
throw new Error(`
|
|
168
|
+
throw new Error(`Peach Cloud origin must be an HTTP(S) origin: ${source}`);
|
|
169
169
|
}
|
|
170
170
|
if (parsed.protocol === "http:" && !isLoopbackHost(parsed.hostname)) {
|
|
171
|
-
throw new Error(`
|
|
171
|
+
throw new Error(`Peach Cloud origin requires HTTPS outside loopback: ${source}`);
|
|
172
172
|
}
|
|
173
173
|
return parsed.origin;
|
|
174
174
|
}
|
|
175
175
|
function resolveOrigin(value) {
|
|
176
|
-
const configured = value?.trim() || process.env.
|
|
176
|
+
const configured = value?.trim() || process.env.PEACH_CLOUD_ORIGIN?.trim();
|
|
177
177
|
return normalizeCloudOrigin(configured || rnxPublicBrand.origin);
|
|
178
178
|
}
|
|
179
179
|
function responseError(status, text) {
|
|
@@ -182,13 +182,13 @@ function responseError(status, text) {
|
|
|
182
182
|
const parsed = JSON.parse(text);
|
|
183
183
|
const error = isRecord(parsed) ? parsed.error : null;
|
|
184
184
|
if (isRecord(error) && typeof error.message === "string") {
|
|
185
|
-
return new Error(`
|
|
185
|
+
return new Error(`Peach Cloud request failed (${status}): ${error.message}`);
|
|
186
186
|
}
|
|
187
187
|
} catch {
|
|
188
188
|
}
|
|
189
189
|
}
|
|
190
190
|
return new Error(
|
|
191
|
-
`
|
|
191
|
+
`Peach Cloud request failed (${status})${text.trim() ? `: ${text.trim()}` : ""}`
|
|
192
192
|
);
|
|
193
193
|
}
|
|
194
194
|
function readCloudErrorCode(text) {
|
|
@@ -264,16 +264,16 @@ function readJsArtifact(bytes) {
|
|
|
264
264
|
try {
|
|
265
265
|
source = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
266
266
|
} catch {
|
|
267
|
-
throw new Error("
|
|
267
|
+
throw new Error("peach Cloud artifact must be valid UTF-8 JavaScript, not bytecode");
|
|
268
268
|
}
|
|
269
269
|
if (source.includes("\0") || !source.includes("__d(") || !source.includes("__r(")) {
|
|
270
|
-
throw new Error("
|
|
270
|
+
throw new Error("peach Cloud artifact must be a Metro JavaScript bundle");
|
|
271
271
|
}
|
|
272
272
|
return source;
|
|
273
273
|
}
|
|
274
274
|
function readClaim(value) {
|
|
275
275
|
if (!isRecord(value) || typeof value.id !== "string" || !value.id || typeof value.expiresAt !== "number") {
|
|
276
|
-
throw new Error("
|
|
276
|
+
throw new Error("Peach Cloud returned an invalid claim");
|
|
277
277
|
}
|
|
278
278
|
return { id: value.id, expiresAt: value.expiresAt };
|
|
279
279
|
}
|
|
@@ -282,15 +282,15 @@ function artifactDigestId(sha256) {
|
|
|
282
282
|
}
|
|
283
283
|
function readArtifact(value, expectedId, expectedBytes) {
|
|
284
284
|
if (!isRecord(value) || value.id !== expectedId || typeof value.bytes !== "number" || !Number.isInteger(value.bytes) || value.bytes !== expectedBytes) {
|
|
285
|
-
throw new Error("
|
|
285
|
+
throw new Error("Peach Cloud returned an invalid artifact receipt");
|
|
286
286
|
}
|
|
287
287
|
return { id: expectedId, bytes: expectedBytes };
|
|
288
288
|
}
|
|
289
289
|
function readSimulatorCreate(value, expectedId, expectedBytes) {
|
|
290
|
-
if (!isRecord(value)) throw new Error("
|
|
290
|
+
if (!isRecord(value)) throw new Error("Peach Cloud create returned an invalid simulator");
|
|
291
291
|
const claim = readClaim(value.claim);
|
|
292
292
|
if (typeof value.simId !== "string" || !value.simId || typeof value.token !== "string") {
|
|
293
|
-
throw new Error("
|
|
293
|
+
throw new Error("Peach Cloud create returned an invalid simulator");
|
|
294
294
|
}
|
|
295
295
|
return {
|
|
296
296
|
simId: value.simId,
|
|
@@ -301,10 +301,10 @@ function readSimulatorCreate(value, expectedId, expectedBytes) {
|
|
|
301
301
|
}
|
|
302
302
|
function readBoxCreate(value, expectedBytes, expectedSha256) {
|
|
303
303
|
const artifactId = artifactDigestId(expectedSha256);
|
|
304
|
-
if (!isRecord(value)) throw new Error("
|
|
304
|
+
if (!isRecord(value)) throw new Error("Peach Cloud create returned invalid JSON");
|
|
305
305
|
const simulator = readSimulatorCreate(value.simulator, artifactId, expectedBytes);
|
|
306
306
|
if (typeof value.boxId !== "string" || !value.boxId || value.size !== "nano" || typeof value.token !== "string" || !value.token) {
|
|
307
|
-
throw new Error("
|
|
307
|
+
throw new Error("Peach Cloud create returned an invalid box receipt");
|
|
308
308
|
}
|
|
309
309
|
return {
|
|
310
310
|
receipt: {
|
|
@@ -327,11 +327,11 @@ function cloudCommand(command, scopes) {
|
|
|
327
327
|
if (key !== "id" && key !== "simId") clean[key] = value;
|
|
328
328
|
}
|
|
329
329
|
if (!isRnxCloudCommandType(command.type)) {
|
|
330
|
-
throw new Error(`
|
|
330
|
+
throw new Error(`Peach Cloud does not support bridge command type ${command.type}`);
|
|
331
331
|
}
|
|
332
332
|
if (!rnxCloudScopesAllowCommand(scopes, command.type)) {
|
|
333
333
|
throw new Error(
|
|
334
|
-
`
|
|
334
|
+
`Peach Cloud command ${command.type} requires the ${rnxCloudCommandScope(command.type)} scope`
|
|
335
335
|
);
|
|
336
336
|
}
|
|
337
337
|
return { ...clean, type: command.type };
|
|
@@ -365,23 +365,23 @@ var RemoteSimulator = class {
|
|
|
365
365
|
layers: options?.layers ?? "tenant"
|
|
366
366
|
});
|
|
367
367
|
if (typeof result !== "string" || !result.startsWith("data:image/")) {
|
|
368
|
-
throw new Error("
|
|
368
|
+
throw new Error("Peach Cloud screenshot did not return an image data url");
|
|
369
369
|
}
|
|
370
370
|
return result;
|
|
371
371
|
},
|
|
372
372
|
capture: async () => {
|
|
373
373
|
const result = await this.sendCommand({ type: "capture" });
|
|
374
374
|
if (!isRnxScreenCapture(result)) {
|
|
375
|
-
throw new Error("
|
|
375
|
+
throw new Error("Peach Cloud capture returned an invalid screen capture");
|
|
376
376
|
}
|
|
377
377
|
return result;
|
|
378
378
|
},
|
|
379
379
|
reset: (options) => {
|
|
380
380
|
if (options?.strategy !== void 0 && options.strategy !== "data" && options.strategy !== "full") {
|
|
381
|
-
throw new Error("
|
|
381
|
+
throw new Error("Peach Cloud reset strategy must be data or full");
|
|
382
382
|
}
|
|
383
383
|
if (options?.from !== void 0 && (typeof options.from !== "string" || options.from.length === 0)) {
|
|
384
|
-
throw new Error("
|
|
384
|
+
throw new Error("Peach Cloud reset from must name a simulator");
|
|
385
385
|
}
|
|
386
386
|
return this.sendCommand(
|
|
387
387
|
options === void 0 ? { type: "reset" } : {
|
|
@@ -441,7 +441,7 @@ var RemoteSimulator = class {
|
|
|
441
441
|
);
|
|
442
442
|
} catch (error) {
|
|
443
443
|
throw new Error(
|
|
444
|
-
`could not reach
|
|
444
|
+
`could not reach Peach Cloud at ${this.session.origin}: ${error instanceof Error ? error.message : String(error)}`
|
|
445
445
|
);
|
|
446
446
|
}
|
|
447
447
|
const text = await response.text();
|
|
@@ -450,14 +450,14 @@ var RemoteSimulator = class {
|
|
|
450
450
|
try {
|
|
451
451
|
parsed = JSON.parse(text);
|
|
452
452
|
} catch {
|
|
453
|
-
throw new Error("
|
|
453
|
+
throw new Error("Peach Cloud command returned unreadable JSON");
|
|
454
454
|
}
|
|
455
455
|
if (!isRecord(parsed) || parsed.id !== body.id) {
|
|
456
|
-
throw new Error("
|
|
456
|
+
throw new Error("Peach Cloud command returned an invalid command receipt");
|
|
457
457
|
}
|
|
458
458
|
if (typeof parsed.error === "string" && parsed.error) throw new Error(parsed.error);
|
|
459
459
|
if (!Object.hasOwn(parsed, "result")) {
|
|
460
|
-
throw new Error("
|
|
460
|
+
throw new Error("Peach Cloud command receipt has no result");
|
|
461
461
|
}
|
|
462
462
|
return parsed.result;
|
|
463
463
|
}
|
|
@@ -483,11 +483,11 @@ var RemoteSimulator = class {
|
|
|
483
483
|
try {
|
|
484
484
|
parsed = JSON.parse(text);
|
|
485
485
|
} catch {
|
|
486
|
-
throw new Error("
|
|
486
|
+
throw new Error("Peach Cloud claim returned unreadable JSON");
|
|
487
487
|
}
|
|
488
488
|
const claim = readClaim(isRecord(parsed) ? parsed.claim : null);
|
|
489
489
|
if (claim.id !== claimId) {
|
|
490
|
-
throw new Error("
|
|
490
|
+
throw new Error("Peach Cloud confirmation replaced the initial claim");
|
|
491
491
|
}
|
|
492
492
|
this.session = { ...this.session, claim };
|
|
493
493
|
return claim;
|
|
@@ -513,17 +513,17 @@ var RemoteSimulator = class {
|
|
|
513
513
|
async function createRemoteSimulator(input) {
|
|
514
514
|
if (input.artifact.byteLength > RNX_CLOUD_MAX_ARTIFACT_BYTES) {
|
|
515
515
|
throw new Error(
|
|
516
|
-
`
|
|
516
|
+
`peach Cloud artifact is ${input.artifact.byteLength} bytes and exceeds the ${RNX_CLOUD_MAX_ARTIFACT_BYTES}-byte limit`
|
|
517
517
|
);
|
|
518
518
|
}
|
|
519
519
|
if (input.artifact.byteLength <= 0) {
|
|
520
|
-
throw new Error("
|
|
520
|
+
throw new Error("peach Cloud artifact is empty");
|
|
521
521
|
}
|
|
522
522
|
readJsArtifact(input.artifact);
|
|
523
523
|
const origin = resolveOrigin(input.origin);
|
|
524
524
|
const sha256 = await sha256Hex(input.artifact);
|
|
525
525
|
if (input.sha256 && input.sha256 !== sha256) {
|
|
526
|
-
throw new Error("
|
|
526
|
+
throw new Error("peach Cloud artifact sha256 does not match the provided digest");
|
|
527
527
|
}
|
|
528
528
|
const device = input.device?.trim() || DEFAULT_DEVICE;
|
|
529
529
|
let response;
|
|
@@ -542,7 +542,7 @@ async function createRemoteSimulator(input) {
|
|
|
542
542
|
});
|
|
543
543
|
} catch (error) {
|
|
544
544
|
throw new Error(
|
|
545
|
-
`could not reach
|
|
545
|
+
`could not reach Peach Cloud at ${origin}: ${error instanceof Error ? error.message : String(error)}`
|
|
546
546
|
);
|
|
547
547
|
}
|
|
548
548
|
const responseText = await response.text();
|
|
@@ -551,7 +551,7 @@ async function createRemoteSimulator(input) {
|
|
|
551
551
|
try {
|
|
552
552
|
parsed = JSON.parse(responseText);
|
|
553
553
|
} catch {
|
|
554
|
-
throw new Error("
|
|
554
|
+
throw new Error("Peach Cloud create returned unreadable JSON");
|
|
555
555
|
}
|
|
556
556
|
const created = readBoxCreate(parsed, input.artifact.byteLength, sha256);
|
|
557
557
|
const simulator = new RemoteSimulator({
|
|
@@ -569,7 +569,7 @@ async function createRemoteSimulator(input) {
|
|
|
569
569
|
}
|
|
570
570
|
function readSimArtifact(value) {
|
|
571
571
|
if (!isRecord(value) || typeof value.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(value.sha256) || typeof value.bytes !== "number" || !Number.isInteger(value.bytes) || value.bytes <= 0) {
|
|
572
|
-
throw new Error("
|
|
572
|
+
throw new Error("Peach Cloud returned an invalid simulator artifact");
|
|
573
573
|
}
|
|
574
574
|
return { id: `sha256:${value.sha256}`, bytes: value.bytes };
|
|
575
575
|
}
|
|
@@ -582,13 +582,13 @@ function readConnectScopes(value, token) {
|
|
|
582
582
|
if (!isRecord(value) || typeof value.id !== "string" || !value.id || !Array.isArray(value.scopes) || value.scopes.length === 0 || !value.scopes.every(
|
|
583
583
|
(scope) => typeof scope === "string" && isRnxCloudCommandScope(scope)
|
|
584
584
|
) || typeof value.expiresAt !== "number") {
|
|
585
|
-
throw new Error("
|
|
585
|
+
throw new Error("Peach Cloud returned an invalid scoped token");
|
|
586
586
|
}
|
|
587
587
|
return Object.freeze([...value.scopes]);
|
|
588
588
|
}
|
|
589
589
|
async function connect(input) {
|
|
590
|
-
if (!input.id) throw new Error("
|
|
591
|
-
if (!input.token) throw new Error("
|
|
590
|
+
if (!input.id) throw new Error("Peach Cloud connect needs a simulator id");
|
|
591
|
+
if (!input.token) throw new Error("Peach Cloud connect needs a token");
|
|
592
592
|
const origin = resolveOrigin(input.origin);
|
|
593
593
|
let response;
|
|
594
594
|
try {
|
|
@@ -598,7 +598,7 @@ async function connect(input) {
|
|
|
598
598
|
);
|
|
599
599
|
} catch (error) {
|
|
600
600
|
throw new Error(
|
|
601
|
-
`could not reach
|
|
601
|
+
`could not reach Peach Cloud at ${origin}: ${error instanceof Error ? error.message : String(error)}`
|
|
602
602
|
);
|
|
603
603
|
}
|
|
604
604
|
const text = await response.text();
|
|
@@ -607,14 +607,14 @@ async function connect(input) {
|
|
|
607
607
|
try {
|
|
608
608
|
parsed = JSON.parse(text);
|
|
609
609
|
} catch {
|
|
610
|
-
throw new Error("
|
|
610
|
+
throw new Error("Peach Cloud connect returned unreadable JSON");
|
|
611
611
|
}
|
|
612
612
|
if (!isRecord(parsed) || !isRecord(parsed.sim)) {
|
|
613
|
-
throw new Error("
|
|
613
|
+
throw new Error("Peach Cloud connect returned an invalid simulator");
|
|
614
614
|
}
|
|
615
615
|
const sim = parsed.sim;
|
|
616
616
|
if (typeof sim.simId !== "string" || !sim.simId) {
|
|
617
|
-
throw new Error("
|
|
617
|
+
throw new Error("Peach Cloud connect returned an invalid simulator");
|
|
618
618
|
}
|
|
619
619
|
return new RemoteSimulator({
|
|
620
620
|
origin,
|
package/dist-lib/config.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.572 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -72,7 +72,7 @@ function readRNXConfigFromSearchParams(searchParams) {
|
|
|
72
72
|
return hasRNXConfig(parsed) ? parsed : void 0;
|
|
73
73
|
} catch (error) {
|
|
74
74
|
const message = error instanceof Error ? error.message : String(error);
|
|
75
|
-
console.warn(`[
|
|
75
|
+
console.warn(`[peach] invalid ${RNX_CONFIG_QUERY_PARAM}: ${message}`);
|
|
76
76
|
return void 0;
|
|
77
77
|
}
|
|
78
78
|
}
|
package/dist-lib/detox/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.572 | (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;
|
|
@@ -1934,9 +1934,9 @@ function getSootsimNavigationDiagnostics(page) {
|
|
|
1934
1934
|
|
|
1935
1935
|
// detox/index.ts
|
|
1936
1936
|
var import_proof_frame = __toESM(require_proof_frame(), 1);
|
|
1937
|
-
var BASE_URL = process.env.
|
|
1938
|
-
var SCREENSHOT_DIR = process.env.
|
|
1939
|
-
var DETOX_PLATFORM = process.env.
|
|
1937
|
+
var BASE_URL = process.env.PEACH_URL || "http://localhost:5173";
|
|
1938
|
+
var SCREENSHOT_DIR = process.env.PEACH_SCREENSHOT_DIR || path.join(process.cwd(), "test", "detox-driver", "screenshots");
|
|
1939
|
+
var DETOX_PLATFORM = process.env.PEACH_PLATFORM === "android" ? "android" : "ios";
|
|
1940
1940
|
var _browser = null;
|
|
1941
1941
|
var _reapBrowserNow = null;
|
|
1942
1942
|
var _context = null;
|
|
@@ -2441,7 +2441,7 @@ function decodePngDataUrl(dataUrl) {
|
|
|
2441
2441
|
const match = /^data:image\/png;base64,(.+)$/.exec(dataUrl);
|
|
2442
2442
|
if (!match) {
|
|
2443
2443
|
throw new Error(
|
|
2444
|
-
`
|
|
2444
|
+
`peach screenshot bridge returned a non-png payload: ${JSON.stringify(dataUrl.slice(0, 120))}`
|
|
2445
2445
|
);
|
|
2446
2446
|
}
|
|
2447
2447
|
return Buffer.from(match[1], "base64");
|
|
@@ -2465,14 +2465,14 @@ async function captureSootsimPngFast(opts) {
|
|
|
2465
2465
|
async (captureOpts) => {
|
|
2466
2466
|
const screenshot = window.SootSim?.bridges?.screenshot;
|
|
2467
2467
|
if (typeof screenshot !== "function") {
|
|
2468
|
-
throw new Error("
|
|
2468
|
+
throw new Error("peach screenshot bridge is not installed");
|
|
2469
2469
|
}
|
|
2470
2470
|
return screenshot(captureOpts);
|
|
2471
2471
|
},
|
|
2472
2472
|
{ crop: opts?.crop, format: "png" }
|
|
2473
2473
|
);
|
|
2474
2474
|
if (!dataUrl) {
|
|
2475
|
-
throw new Error("
|
|
2475
|
+
throw new Error("peach screenshot bridge returned an empty image");
|
|
2476
2476
|
}
|
|
2477
2477
|
return decodePngDataUrl(dataUrl);
|
|
2478
2478
|
}
|
|
@@ -2506,7 +2506,7 @@ async function captureSootsimPng(opts) {
|
|
|
2506
2506
|
previous = current;
|
|
2507
2507
|
}
|
|
2508
2508
|
throw new Error(
|
|
2509
|
-
`
|
|
2509
|
+
`peach screenshot did not reach ${import_proof_frame.REQUIRED_IDENTICAL_PROOF_FRAMES} identical idle frames in ${attempts} captures`
|
|
2510
2510
|
);
|
|
2511
2511
|
} finally {
|
|
2512
2512
|
await setSootsimCursorCaptureActive(page, false);
|
|
@@ -3173,7 +3173,7 @@ var device = {
|
|
|
3173
3173
|
},
|
|
3174
3174
|
// record the SootSim canvas via the engine's headless recorder
|
|
3175
3175
|
// (window.__sootsimRecorder — @rnx/plugin-recording). this is the
|
|
3176
|
-
// SAME code path `
|
|
3176
|
+
// SAME code path `peach record video` drives, NOT the rail-button
|
|
3177
3177
|
// path (SootSim.bridges.startRecording wires the dialog state machine
|
|
3178
3178
|
// and never stashes the resulting blob into __sootsimRecorder.lastBlob,
|
|
3179
3179
|
// which is what getBlobBase64 streams from).
|
|
@@ -3203,7 +3203,7 @@ var device = {
|
|
|
3203
3203
|
}
|
|
3204
3204
|
},
|
|
3205
3205
|
// stop the headless recorder, stream the resulting blob in chunks (same
|
|
3206
|
-
// protocol as `
|
|
3206
|
+
// protocol as `peach record`), and write the webm to outPath.
|
|
3207
3207
|
async stopAndSaveBridgeRecording(outPath) {
|
|
3208
3208
|
const page = getPage();
|
|
3209
3209
|
const stopResult = await page.evaluate(async () => {
|
|
@@ -3233,7 +3233,7 @@ var device = {
|
|
|
3233
3233
|
},
|
|
3234
3234
|
{ offset, chunk: CHUNK }
|
|
3235
3235
|
);
|
|
3236
|
-
if (!result) throw new Error("
|
|
3236
|
+
if (!result) throw new Error("peach recorder produced no blob");
|
|
3237
3237
|
chunks.push(Buffer.from(result.data, "base64"));
|
|
3238
3238
|
offset = result.offset;
|
|
3239
3239
|
if (result.done) break;
|
|
@@ -3253,7 +3253,7 @@ var device = {
|
|
|
3253
3253
|
const token = `motion-${process.pid}-${Date.now()}-${Math.random()}`;
|
|
3254
3254
|
const settleMs = options.settleMs ?? 0;
|
|
3255
3255
|
if (!Number.isFinite(settleMs) || settleMs < 0) {
|
|
3256
|
-
throw new Error("
|
|
3256
|
+
throw new Error("peach motion capture needs a non-negative settleMs");
|
|
3257
3257
|
}
|
|
3258
3258
|
await page.evaluate(import_motion_change.measureMotionChange, {
|
|
3259
3259
|
definition: import_motion_change.MOTION_CHANGE_DEFINITION,
|
|
@@ -3265,7 +3265,7 @@ var device = {
|
|
|
3265
3265
|
const live = captureWindow.SootSim?.bridges?.liveComposite;
|
|
3266
3266
|
const lockstep = captureWindow.SootSim?.bridges?.lockstepCapture;
|
|
3267
3267
|
if (!live || typeof live.captureFresh !== "function") {
|
|
3268
|
-
throw new Error("
|
|
3268
|
+
throw new Error("peach live composite bridge is not installed");
|
|
3269
3269
|
}
|
|
3270
3270
|
if (!lockstep || typeof lockstep.begin !== "function") {
|
|
3271
3271
|
throw new Error("SootSim lockstep capture bridge is not installed");
|
|
@@ -3279,11 +3279,11 @@ var device = {
|
|
|
3279
3279
|
registry[input.token] = state;
|
|
3280
3280
|
const measureChange = captureWindow.__sootsimMeasureMotionChange;
|
|
3281
3281
|
if (!measureChange) {
|
|
3282
|
-
throw new Error("
|
|
3282
|
+
throw new Error("peach motion change definition is not installed");
|
|
3283
3283
|
}
|
|
3284
3284
|
const captureBitmap = async () => {
|
|
3285
3285
|
const { canvas } = await live.captureFresh();
|
|
3286
|
-
if (!canvas) throw new Error("
|
|
3286
|
+
if (!canvas) throw new Error("peach live composite produced no canvas");
|
|
3287
3287
|
return createImageBitmap(canvas);
|
|
3288
3288
|
};
|
|
3289
3289
|
const boundsFor = (bitmap) => {
|
|
@@ -3313,7 +3313,7 @@ var device = {
|
|
|
3313
3313
|
canvas.width = bounds.width;
|
|
3314
3314
|
canvas.height = bounds.height;
|
|
3315
3315
|
const context = canvas.getContext("2d", { willReadFrequently: true });
|
|
3316
|
-
if (!context) throw new Error("
|
|
3316
|
+
if (!context) throw new Error("peach motion detector needs a 2d canvas");
|
|
3317
3317
|
context.drawImage(
|
|
3318
3318
|
bitmap,
|
|
3319
3319
|
bounds.left,
|
|
@@ -3332,7 +3332,7 @@ var device = {
|
|
|
3332
3332
|
canvas.width = snapshot.bitmap.width;
|
|
3333
3333
|
canvas.height = snapshot.bitmap.height;
|
|
3334
3334
|
const context = canvas.getContext("2d");
|
|
3335
|
-
if (!context) throw new Error("
|
|
3335
|
+
if (!context) throw new Error("peach motion capture needs a 2d canvas");
|
|
3336
3336
|
context.drawImage(snapshot.bitmap, 0, 0);
|
|
3337
3337
|
snapshot.bitmap.close();
|
|
3338
3338
|
return {
|
|
@@ -3346,7 +3346,7 @@ var device = {
|
|
|
3346
3346
|
};
|
|
3347
3347
|
const interact = captureWindow.SootSim?.bridges?.interact;
|
|
3348
3348
|
if (input.hold && (!interact || typeof interact.touchDown !== "function")) {
|
|
3349
|
-
throw new Error("
|
|
3349
|
+
throw new Error("peach interact bridge is not installed");
|
|
3350
3350
|
}
|
|
3351
3351
|
const frameMs = 1e3 / 60;
|
|
3352
3352
|
const controller = await lockstep.begin(60);
|
|
@@ -3389,11 +3389,11 @@ var device = {
|
|
|
3389
3389
|
if (input.hold && interact) {
|
|
3390
3390
|
const hit = await interact.touchDown(input.hold.x, input.hold.y);
|
|
3391
3391
|
if (!hit) {
|
|
3392
|
-
throw new Error(`
|
|
3392
|
+
throw new Error(`peach motion hold missed at ${input.hold.x},${input.hold.y}`);
|
|
3393
3393
|
}
|
|
3394
3394
|
} else {
|
|
3395
3395
|
while (!state.triggerCompleted) {
|
|
3396
|
-
if (state.cancelled) throw new Error("
|
|
3396
|
+
if (state.cancelled) throw new Error("peach motion capture was cancelled");
|
|
3397
3397
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
3398
3398
|
}
|
|
3399
3399
|
}
|
|
@@ -3401,7 +3401,7 @@ var device = {
|
|
|
3401
3401
|
let detectedMeasurement = null;
|
|
3402
3402
|
const detectionFrameLimit = Math.ceil(input.detectionTimeoutMs * 60 / 1e3);
|
|
3403
3403
|
for (let frame = 0; frame < detectionFrameLimit; frame++) {
|
|
3404
|
-
if (state.cancelled) throw new Error("
|
|
3404
|
+
if (state.cancelled) throw new Error("peach motion capture was cancelled");
|
|
3405
3405
|
const receipt = await controller.stepFrame();
|
|
3406
3406
|
await advanceHold(receipt);
|
|
3407
3407
|
const candidateBitmap = await captureBitmap();
|
|
@@ -3423,12 +3423,12 @@ var device = {
|
|
|
3423
3423
|
}
|
|
3424
3424
|
if (!visibleStart || !detectedMeasurement) {
|
|
3425
3425
|
throw new Error(
|
|
3426
|
-
`
|
|
3426
|
+
`peach motion had no visible change before ${input.detectionTimeoutMs}ms`
|
|
3427
3427
|
);
|
|
3428
3428
|
}
|
|
3429
3429
|
const snapshots = [];
|
|
3430
3430
|
for (const stage of input.stages) {
|
|
3431
|
-
if (state.cancelled) throw new Error("
|
|
3431
|
+
if (state.cancelled) throw new Error("peach motion capture was cancelled");
|
|
3432
3432
|
const stageFrameIndex = visibleStart.frameIndex + Math.ceil(stage.offsetMs / frameMs);
|
|
3433
3433
|
for (let eventFrameIndex = nextHoldEventFrameIndex(); eventFrameIndex !== null && stageFrameIndex > eventFrameIndex; eventFrameIndex = nextHoldEventFrameIndex()) {
|
|
3434
3434
|
await advanceHold(await controller.stepFrame());
|
|
@@ -3493,7 +3493,7 @@ var device = {
|
|
|
3493
3493
|
try {
|
|
3494
3494
|
if (!options.hold) {
|
|
3495
3495
|
if (typeof options.trigger !== "function") {
|
|
3496
|
-
throw new Error("
|
|
3496
|
+
throw new Error("peach motion capture needs a trigger or a hold");
|
|
3497
3497
|
}
|
|
3498
3498
|
await Promise.resolve(options.trigger());
|
|
3499
3499
|
}
|
|
@@ -3501,7 +3501,7 @@ var device = {
|
|
|
3501
3501
|
await page.evaluate((captureToken) => {
|
|
3502
3502
|
const registry = window.__sootsimVisibleChangeCaptures;
|
|
3503
3503
|
const capture2 = registry?.[captureToken];
|
|
3504
|
-
if (!capture2) throw new Error("
|
|
3504
|
+
if (!capture2) throw new Error("peach motion capture disarmed before trigger");
|
|
3505
3505
|
capture2.triggerCompleted = true;
|
|
3506
3506
|
}, token);
|
|
3507
3507
|
const capture = await capturePromise;
|
|
@@ -3550,7 +3550,7 @@ var device = {
|
|
|
3550
3550
|
const screenshot = captureWindow.SootSim?.bridges?.screenshot;
|
|
3551
3551
|
const live = captureWindow.SootSim?.bridges?.liveComposite;
|
|
3552
3552
|
if (typeof screenshot !== "function") {
|
|
3553
|
-
throw new Error("
|
|
3553
|
+
throw new Error("peach screenshot bridge is not installed");
|
|
3554
3554
|
}
|
|
3555
3555
|
const registry = captureWindow.__sootsimTimedCaptures ?? (captureWindow.__sootsimTimedCaptures = {});
|
|
3556
3556
|
const state = {
|
|
@@ -3565,7 +3565,7 @@ var device = {
|
|
|
3565
3565
|
}
|
|
3566
3566
|
state.ready = true;
|
|
3567
3567
|
while (state.anchorPerformanceMs === null || state.anchorWallMs === null) {
|
|
3568
|
-
if (state.cancelled) throw new Error("
|
|
3568
|
+
if (state.cancelled) throw new Error("peach timed capture was cancelled");
|
|
3569
3569
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
3570
3570
|
}
|
|
3571
3571
|
const captureAnchorMs = state.anchorWallMs;
|
|
@@ -3653,7 +3653,7 @@ var device = {
|
|
|
3653
3653
|
({ anchorMs: anchorMs2, captureToken }) => {
|
|
3654
3654
|
const registry = window.__sootsimTimedCaptures;
|
|
3655
3655
|
const capture = registry?.[captureToken];
|
|
3656
|
-
if (!capture?.ready) throw new Error("
|
|
3656
|
+
if (!capture?.ready) throw new Error("peach timed capture was not armed");
|
|
3657
3657
|
const nowMs = Date.now();
|
|
3658
3658
|
capture.anchorWallMs = anchorMs2 ?? nowMs;
|
|
3659
3659
|
capture.anchorPerformanceMs = performance.now() - (nowMs - capture.anchorWallMs);
|
|
@@ -3714,7 +3714,7 @@ var device = {
|
|
|
3714
3714
|
async (input) => {
|
|
3715
3715
|
const screenshot = window.SootSim?.bridges?.screenshot;
|
|
3716
3716
|
if (typeof screenshot !== "function") {
|
|
3717
|
-
throw new Error("
|
|
3717
|
+
throw new Error("peach screenshot bridge is not installed");
|
|
3718
3718
|
}
|
|
3719
3719
|
const start = Date.now();
|
|
3720
3720
|
const out = [];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.572 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/dist-lib/home-paths.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.572 | (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;
|
|
@@ -38,7 +38,7 @@ __export(home_paths_exports, {
|
|
|
38
38
|
DAEMON_HEARTBEAT_STALE_MS: () => DAEMON_HEARTBEAT_STALE_MS,
|
|
39
39
|
DAEMON_LOCKFILE: () => DAEMON_LOCKFILE,
|
|
40
40
|
DEV_BRIDGES_DIR: () => DEV_BRIDGES_DIR,
|
|
41
|
-
|
|
41
|
+
PEACH_HOME_ENV: () => PEACH_HOME_ENV,
|
|
42
42
|
activeRuntimeDir: () => activeRuntimeDir,
|
|
43
43
|
activeRuntimeFile: () => activeRuntimeFile,
|
|
44
44
|
cacheDir: () => cacheDir,
|
|
@@ -93,7 +93,7 @@ var import_node_crypto = require("node:crypto");
|
|
|
93
93
|
var import_node_fs = __toESM(require("node:fs"), 1);
|
|
94
94
|
var import_node_os = require("node:os");
|
|
95
95
|
var import_node_path = __toESM(require("node:path"), 1);
|
|
96
|
-
var
|
|
96
|
+
var PEACH_HOME_ENV = "PEACH_HOME";
|
|
97
97
|
var ACTIVE_RUNTIME_FILE = "active";
|
|
98
98
|
var DAEMON_LOCKFILE = "daemon.json";
|
|
99
99
|
var DEV_BRIDGES_DIR = "dev-bridges";
|
|
@@ -101,9 +101,9 @@ var CONFIG_FILE = "config.json";
|
|
|
101
101
|
var CLI_UPDATE_FILE = "cli-update.json";
|
|
102
102
|
var DAEMON_HEARTBEAT_STALE_MS = 3e4;
|
|
103
103
|
function rnxHomeDir() {
|
|
104
|
-
const override = process.env[
|
|
104
|
+
const override = process.env[PEACH_HOME_ENV];
|
|
105
105
|
if (override && override.length > 0) return import_node_path.default.resolve(override);
|
|
106
|
-
return import_node_path.default.join((0, import_node_os.homedir)(), ".
|
|
106
|
+
return import_node_path.default.join((0, import_node_os.homedir)(), ".peach");
|
|
107
107
|
}
|
|
108
108
|
function isSootsimDevCheckout() {
|
|
109
109
|
if (process.env.SOOTSIM_FORCE_DAEMON_INSTALL === "1") return false;
|
|
@@ -114,7 +114,7 @@ function isSootsimDevCheckout() {
|
|
|
114
114
|
if (!argv1) return false;
|
|
115
115
|
try {
|
|
116
116
|
const real = import_node_fs.default.realpathSync(argv1);
|
|
117
|
-
return real.includes(`${import_node_path.default.sep}packages${import_node_path.default.sep}
|
|
117
|
+
return real.includes(`${import_node_path.default.sep}packages${import_node_path.default.sep}peachsim${import_node_path.default.sep}`);
|
|
118
118
|
} catch {
|
|
119
119
|
return false;
|
|
120
120
|
}
|
|
@@ -154,10 +154,10 @@ function daemonAppDir() {
|
|
|
154
154
|
return import_node_path.default.join(rnxHomeDir(), "daemon-app");
|
|
155
155
|
}
|
|
156
156
|
function daemonAppBundlePath() {
|
|
157
|
-
return import_node_path.default.join(daemonAppDir(), "
|
|
157
|
+
return import_node_path.default.join(daemonAppDir(), "Peach Daemon.app");
|
|
158
158
|
}
|
|
159
159
|
function daemonAppLauncherPath() {
|
|
160
|
-
return import_node_path.default.join(daemonAppBundlePath(), "Contents", "MacOS", "
|
|
160
|
+
return import_node_path.default.join(daemonAppBundlePath(), "Contents", "MacOS", "peach-daemon");
|
|
161
161
|
}
|
|
162
162
|
function cacheDir() {
|
|
163
163
|
return import_node_path.default.join(rnxHomeDir(), "cache");
|
|
@@ -412,10 +412,10 @@ function writeDaemonLockfile(data) {
|
|
|
412
412
|
const existing = readDaemonLockfile();
|
|
413
413
|
if (!existing) {
|
|
414
414
|
if (createDaemonLockfileExclusive(data)) return;
|
|
415
|
-
throw new Error("another
|
|
415
|
+
throw new Error("another peach daemon claimed the lockfile before this write");
|
|
416
416
|
}
|
|
417
417
|
if (!sameDaemonOwner(existing, data)) {
|
|
418
|
-
throw new Error("refusing to overwrite another
|
|
418
|
+
throw new Error("refusing to overwrite another peach daemon lockfile");
|
|
419
419
|
}
|
|
420
420
|
const tmp = `${lockfilePath}.${data.pid}.${(0, import_node_crypto.randomUUID)()}.tmp`;
|
|
421
421
|
import_node_fs.default.writeFileSync(tmp, `${JSON.stringify(data, null, 2)}
|
|
@@ -423,7 +423,7 @@ function writeDaemonLockfile(data) {
|
|
|
423
423
|
try {
|
|
424
424
|
const current = readDaemonLockfile();
|
|
425
425
|
if (!current || !sameDaemonOwner(current, data)) {
|
|
426
|
-
throw new Error("
|
|
426
|
+
throw new Error("peach daemon lock ownership changed during heartbeat");
|
|
427
427
|
}
|
|
428
428
|
import_node_fs.default.renameSync(tmp, lockfilePath);
|
|
429
429
|
} finally {
|
|
@@ -586,7 +586,7 @@ function removeDevBridgeLockfile(owner) {
|
|
|
586
586
|
DAEMON_HEARTBEAT_STALE_MS,
|
|
587
587
|
DAEMON_LOCKFILE,
|
|
588
588
|
DEV_BRIDGES_DIR,
|
|
589
|
-
|
|
589
|
+
PEACH_HOME_ENV,
|
|
590
590
|
activeRuntimeDir,
|
|
591
591
|
activeRuntimeFile,
|
|
592
592
|
cacheDir,
|