peachsim 0.1.570 → 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 +108 -108
- 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 +28 -20
- 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 +3 -2
- package/cli/cloud-session.ts +12 -12
- package/cli/cloud-test-result-files.ts +97 -0
- 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 +173 -71
- 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 +176 -18
- 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 +4 -2
- package/cli/main.ts +14 -14
- package/cli/outbound-endpoints.ts +32 -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 +3 -2
- 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/jest-preset.cjs +2 -2
- 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 +116 -0
- package/dist-lib/cloud-test-args.mjs +86 -0
- 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/detox/jest-preset.cjs +2 -2
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +12 -12
- package/dist-lib/host/bridge-host.cjs +87 -77
- 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 +63 -73
- 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 +534 -520
- package/dist-lib/swift-compile.cjs +372 -0
- package/dist-lib/swift-compile.mjs +339 -0
- package/dist-lib/swift-package.cjs +78 -0
- package/dist-lib/swift-package.mjs +52 -0
- 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 +479 -161
- package/package.json +22 -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 +47 -47
- 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-test-args.ts +100 -0
- 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 +11 -10
- 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/swift-compile.ts +359 -0
- package/src/swift-package.ts +69 -0
- package/src/swift-submit.ts +3 -2
- package/src/vite-plugin-one.ts +8 -8
- package/src/vite-plugin-swift.ts +106 -110
- package/src/vite-plugin.ts +6 -19
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
//
|
|
1
|
+
// peach desktop install — download and install the optional desktop GUI
|
|
2
2
|
//
|
|
3
|
-
// the CLI + daemon are the canonical
|
|
3
|
+
// the CLI + daemon are the canonical peach surface; this command is only
|
|
4
4
|
// for users who want the Electron-based GUI companion on top of that.
|
|
5
5
|
//
|
|
6
6
|
// fetches the right platform artifact from https://contrast.dev/api/electron-release/
|
|
7
7
|
// and installs it into the OS-native location that findDesktopCompanion() looks for:
|
|
8
|
-
// macos: ~/Applications/
|
|
9
|
-
// linux: ~/Applications/
|
|
8
|
+
// macos: ~/Applications/peach.app (or /Applications if writable)
|
|
9
|
+
// linux: ~/Applications/peach.AppImage
|
|
10
10
|
// win: spawns the NSIS installer
|
|
11
11
|
//
|
|
12
12
|
// post-install the electron-updater feed (same URL) handles upgrades inside the
|
|
@@ -45,7 +45,7 @@ function detectTarget(): Target | null {
|
|
|
45
45
|
const arch = process.arch
|
|
46
46
|
if (process.platform === 'darwin') {
|
|
47
47
|
const platform: TargetPlatform = arch === 'arm64' ? 'mac-arm64' : 'mac-x64'
|
|
48
|
-
const filename = `
|
|
48
|
+
const filename = `peach-latest-${platform}.dmg`
|
|
49
49
|
return {
|
|
50
50
|
platform,
|
|
51
51
|
filename,
|
|
@@ -60,7 +60,7 @@ function detectTarget(): Target | null {
|
|
|
60
60
|
// /lib64/ld-linux-x86-64.so.2". detect the running arch and pick the
|
|
61
61
|
// matching artifact.
|
|
62
62
|
const platform: TargetPlatform = arch === 'arm64' ? 'linux-arm64' : 'linux-x64'
|
|
63
|
-
const filename = `
|
|
63
|
+
const filename = `peach-latest-${platform}.AppImage`
|
|
64
64
|
return {
|
|
65
65
|
platform,
|
|
66
66
|
filename,
|
|
@@ -69,7 +69,7 @@ function detectTarget(): Target | null {
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
if (process.platform === 'win32') {
|
|
72
|
-
const filename = `
|
|
72
|
+
const filename = `peach-latest-win-x64.exe`
|
|
73
73
|
return {
|
|
74
74
|
platform: 'win-x64',
|
|
75
75
|
filename,
|
|
@@ -148,10 +148,10 @@ async function installMacDmg(dmgPath: string): Promise<string> {
|
|
|
148
148
|
throw new Error(`could not determine dmg mount point (output: ${mountOutput.stdout})`)
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
-
const appSource = join(mountPoint, '
|
|
151
|
+
const appSource = join(mountPoint, 'peach.app')
|
|
152
152
|
if (!existsSync(appSource)) {
|
|
153
153
|
spawnSync('hdiutil', ['detach', '-force', mountPoint])
|
|
154
|
-
throw new Error(`
|
|
154
|
+
throw new Error(`peach.app not found inside ${mountPoint}`)
|
|
155
155
|
}
|
|
156
156
|
|
|
157
157
|
// prefer /Applications if writable, otherwise ~/Applications (same paths
|
|
@@ -160,7 +160,7 @@ async function installMacDmg(dmgPath: string): Promise<string> {
|
|
|
160
160
|
const userApps = resolve(process.env.HOME || '', 'Applications')
|
|
161
161
|
let destRoot = systemApps
|
|
162
162
|
try {
|
|
163
|
-
const probe = join(systemApps, `.
|
|
163
|
+
const probe = join(systemApps, `.peach-write-probe-${process.pid}`)
|
|
164
164
|
spawnSync('touch', [probe])
|
|
165
165
|
if (existsSync(probe)) rmSync(probe, { force: true })
|
|
166
166
|
else destRoot = userApps
|
|
@@ -171,13 +171,13 @@ async function installMacDmg(dmgPath: string): Promise<string> {
|
|
|
171
171
|
mkdirSync(destRoot, { recursive: true })
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
const appDest = join(destRoot, '
|
|
174
|
+
const appDest = join(destRoot, 'peach.app')
|
|
175
175
|
|
|
176
176
|
// copy alongside the destination and swap, rather than deleting the installed
|
|
177
177
|
// app first. removing it up front means a failed copy leaves the user with no
|
|
178
178
|
// app at all, having destroyed a working install to do it. the staging path is
|
|
179
179
|
// in the same directory so the swap is a rename on one volume.
|
|
180
|
-
const staging = join(destRoot, `.
|
|
180
|
+
const staging = join(destRoot, `.peach-incoming-${process.pid}.app`)
|
|
181
181
|
rmSync(staging, { recursive: true, force: true })
|
|
182
182
|
|
|
183
183
|
const copy = spawnSync('cp', ['-R', appSource, staging])
|
|
@@ -188,7 +188,7 @@ async function installMacDmg(dmgPath: string): Promise<string> {
|
|
|
188
188
|
}
|
|
189
189
|
const detach = spawnSync('hdiutil', ['detach', '-force', mountPoint])
|
|
190
190
|
|
|
191
|
-
const previous = join(destRoot, `.
|
|
191
|
+
const previous = join(destRoot, `.peach-previous-${process.pid}.app`)
|
|
192
192
|
if (existsSync(appDest)) {
|
|
193
193
|
const park = spawnSync('mv', [appDest, previous])
|
|
194
194
|
if (park.status !== 0) {
|
|
@@ -225,7 +225,7 @@ async function installMacDmg(dmgPath: string): Promise<string> {
|
|
|
225
225
|
async function installLinuxAppImage(appImagePath: string): Promise<string> {
|
|
226
226
|
const destDir = resolve(process.env.HOME || '', 'Applications')
|
|
227
227
|
mkdirSync(destDir, { recursive: true })
|
|
228
|
-
const dest = join(destDir, '
|
|
228
|
+
const dest = join(destDir, 'peach.AppImage')
|
|
229
229
|
if (existsSync(dest)) rmSync(dest, { force: true })
|
|
230
230
|
// copyFile + unlink instead of rename: /tmp and ~/Applications are
|
|
231
231
|
// routinely on separate mounts in containers / VMs, where renameSync
|
|
@@ -251,7 +251,7 @@ async function installWindowsExe(exePath: string): Promise<string> {
|
|
|
251
251
|
})
|
|
252
252
|
const installed = findDesktopCompanion()
|
|
253
253
|
if (!installed) {
|
|
254
|
-
throw new Error('the installer finished but the
|
|
254
|
+
throw new Error('the installer finished but the peach application was not registered')
|
|
255
255
|
}
|
|
256
256
|
return installed.path
|
|
257
257
|
}
|
|
@@ -259,21 +259,21 @@ async function installWindowsExe(exePath: string): Promise<string> {
|
|
|
259
259
|
export async function runInstallDesktop(args: string[]) {
|
|
260
260
|
if (args.includes('--help') || args.includes('-h')) {
|
|
261
261
|
console.log(`
|
|
262
|
-
|
|
262
|
+
peach desktop install
|
|
263
263
|
|
|
264
|
-
Download and install the optional
|
|
264
|
+
Download and install the optional peach Desktop app.
|
|
265
265
|
The CLI works without it. Choose Desktop when you want a dedicated native window.
|
|
266
266
|
|
|
267
267
|
usage:
|
|
268
|
-
|
|
268
|
+
peach desktop install [options]
|
|
269
269
|
|
|
270
270
|
options:
|
|
271
271
|
-y, --yes skip confirmation and install immediately
|
|
272
272
|
--force reinstall even if the companion is already present
|
|
273
273
|
|
|
274
274
|
examples:
|
|
275
|
-
|
|
276
|
-
|
|
275
|
+
peach desktop install
|
|
276
|
+
peach desktop install --yes
|
|
277
277
|
`)
|
|
278
278
|
rnxExit(0)
|
|
279
279
|
}
|
|
@@ -281,7 +281,7 @@ examples:
|
|
|
281
281
|
const skipConfirm =
|
|
282
282
|
args.includes('--yes') ||
|
|
283
283
|
args.includes('-y') ||
|
|
284
|
-
process.env.
|
|
284
|
+
process.env.PEACH_NO_PROMPT === '1' ||
|
|
285
285
|
process.env.CI === '1' ||
|
|
286
286
|
!process.stdin.isTTY
|
|
287
287
|
const force = args.includes('--force')
|
|
@@ -318,7 +318,7 @@ examples:
|
|
|
318
318
|
console.log()
|
|
319
319
|
}
|
|
320
320
|
|
|
321
|
-
const workDir = join(tmpdir(), `
|
|
321
|
+
const workDir = join(tmpdir(), `peach-install-${Date.now()}`)
|
|
322
322
|
const downloadPath = join(workDir, target.filename)
|
|
323
323
|
|
|
324
324
|
let lastDraw = 0
|
|
@@ -347,7 +347,7 @@ examples:
|
|
|
347
347
|
console.error(
|
|
348
348
|
' network blocked the request. Check your connection and try again later.',
|
|
349
349
|
)
|
|
350
|
-
console.error(' The CLI and daemon work without the desktop app. Run `
|
|
350
|
+
console.error(' The CLI and daemon work without the desktop app. Run `peach --help`.')
|
|
351
351
|
rnxExit(1)
|
|
352
352
|
}
|
|
353
353
|
|
|
@@ -371,7 +371,7 @@ examples:
|
|
|
371
371
|
// drag rather than leaving them at a dead end. keep workDir for that.
|
|
372
372
|
if (process.platform === 'darwin') {
|
|
373
373
|
spawnSync('open', [downloadPath])
|
|
374
|
-
console.error(` Opened ${target.filename} — drag
|
|
374
|
+
console.error(` Opened ${target.filename} — drag peach to Applications to finish.`)
|
|
375
375
|
} else {
|
|
376
376
|
console.error(` Keeping the download at ${downloadPath} for manual installation.`)
|
|
377
377
|
}
|
|
@@ -380,6 +380,6 @@ examples:
|
|
|
380
380
|
|
|
381
381
|
console.log()
|
|
382
382
|
console.log(` ${bold('Ready')}`)
|
|
383
|
-
console.log('
|
|
384
|
-
console.log('
|
|
383
|
+
console.log(' peach desktop Launch the desktop app')
|
|
384
|
+
console.log(' peach open <target> Open a demo or bundle in it')
|
|
385
385
|
}
|
package/cli/commands/login.ts
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
import { rnxPublicBrand } from '../../src/public-brand'
|
|
12
12
|
import { rnxExit } from '../run-rnx'
|
|
13
13
|
|
|
14
|
-
const REMOTE_DEFAULT_ORIGIN = process.env.
|
|
14
|
+
const REMOTE_DEFAULT_ORIGIN = process.env.PEACH_AUTH_ORIGIN || 'https://contrast.dev'
|
|
15
15
|
|
|
16
16
|
type LoginResult =
|
|
17
17
|
| { ok: true; token: string; userId?: string; email?: string }
|
|
@@ -19,21 +19,21 @@ type LoginResult =
|
|
|
19
19
|
|
|
20
20
|
function resolveDefaultAuthOrigin(explicitOrigin?: string) {
|
|
21
21
|
if (explicitOrigin) return explicitOrigin
|
|
22
|
-
if (process.env.
|
|
23
|
-
if (process.env.
|
|
22
|
+
if (process.env.PEACH_AUTH_ORIGIN) return process.env.PEACH_AUTH_ORIGIN
|
|
23
|
+
if (process.env.PEACH_UPLOAD_ORIGIN) return process.env.PEACH_UPLOAD_ORIGIN
|
|
24
24
|
return REMOTE_DEFAULT_ORIGIN
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
function printHelp() {
|
|
28
28
|
console.log(`
|
|
29
|
-
|
|
29
|
+
peach login — sign in so uploads can attach to your account
|
|
30
30
|
|
|
31
31
|
usage:
|
|
32
|
-
|
|
32
|
+
peach login [--origin <url>] [--account <name-or-id>]
|
|
33
33
|
|
|
34
34
|
options:
|
|
35
35
|
--origin <url> auth host (default: ${REMOTE_DEFAULT_ORIGIN})
|
|
36
|
-
override with
|
|
36
|
+
override with PEACH_AUTH_ORIGIN env var
|
|
37
37
|
--account <name-or-id> the account remote simulators and boxes bill to.
|
|
38
38
|
one account is chosen for you; several ask.
|
|
39
39
|
-h, --help
|
|
@@ -182,7 +182,7 @@ function isLocalOrigin(origin: string): boolean {
|
|
|
182
182
|
if (hostname.endsWith('.local')) return true
|
|
183
183
|
if (hostname.endsWith('.localhost')) return true
|
|
184
184
|
// VM↔host bridge aliases — orb, docker, lima, multipass all forward the
|
|
185
|
-
// host on a well-known name (IPv4 or IPv6) so a VM-internal `
|
|
185
|
+
// host on a well-known name (IPv4 or IPv6) so a VM-internal `peach login`
|
|
186
186
|
// can still take the dev-login fast path against the host's Contrast dev
|
|
187
187
|
// server. without this the CLI falls through to a browser callback that
|
|
188
188
|
// is unreachable from a headless VM.
|
|
@@ -288,7 +288,7 @@ export async function runLogin(args: string[]) {
|
|
|
288
288
|
|
|
289
289
|
if (!token) {
|
|
290
290
|
res.end(
|
|
291
|
-
renderCallbackPage('missing token. close this tab and retry `
|
|
291
|
+
renderCallbackPage('missing token. close this tab and retry `peach login`.'),
|
|
292
292
|
)
|
|
293
293
|
finish({ ok: false, error: 'missing token' })
|
|
294
294
|
return
|
|
@@ -298,7 +298,7 @@ export async function runLogin(args: string[]) {
|
|
|
298
298
|
finish({ ok: true, token, email, userId })
|
|
299
299
|
} catch (err) {
|
|
300
300
|
res.statusCode = 500
|
|
301
|
-
res.end(renderCallbackPage('sign-in callback failed. retry `
|
|
301
|
+
res.end(renderCallbackPage('sign-in callback failed. retry `peach login`.'))
|
|
302
302
|
finish({
|
|
303
303
|
ok: false,
|
|
304
304
|
error: err instanceof Error ? err.message : 'callback failed',
|
|
@@ -310,7 +310,7 @@ export async function runLogin(args: string[]) {
|
|
|
310
310
|
finish({
|
|
311
311
|
ok: false,
|
|
312
312
|
error:
|
|
313
|
-
'timed out waiting for the browser sign-in (5 minutes). rerun `
|
|
313
|
+
'timed out waiting for the browser sign-in (5 minutes). rerun `peach login` and complete the github authorize screen if it appears.',
|
|
314
314
|
})
|
|
315
315
|
}, LOGIN_TIMEOUT_MS)
|
|
316
316
|
|
|
@@ -326,7 +326,7 @@ export async function runLogin(args: string[]) {
|
|
|
326
326
|
url.searchParams.set('port', String(address.port))
|
|
327
327
|
url.searchParams.set('contrast', origin)
|
|
328
328
|
|
|
329
|
-
console.log(' opening browser for
|
|
329
|
+
console.log(' opening browser for peach login...')
|
|
330
330
|
console.log(
|
|
331
331
|
' first time here? github will show an authorize screen. approve it to continue.',
|
|
332
332
|
)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// plain-language Maestro authoring for `
|
|
1
|
+
// plain-language Maestro authoring for `peach maestro generate`.
|
|
2
2
|
|
|
3
3
|
import { mkdtempSync, writeFileSync } from 'fs'
|
|
4
4
|
import { tmpdir } from 'os'
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
import { inspectDescribe } from './inspect/core'
|
|
20
20
|
import { resolveDefaultUploadOrigin } from './upload'
|
|
21
21
|
|
|
22
|
-
const DEFAULT_TEST_MODEL = process.env.
|
|
22
|
+
const DEFAULT_TEST_MODEL = process.env.PEACH_TEST_MODEL || 'deepseek-v4-flash'
|
|
23
23
|
const DESCRIBE_CONTEXT_LIMIT = 18_000
|
|
24
24
|
const LLM_TIMEOUT_MS = 180_000
|
|
25
25
|
|
|
@@ -96,7 +96,7 @@ async function describeCurrentSim(args: string[], promptIndex: number): Promise<
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
const RNX_TEST_SYSTEM_PROMPT = `
|
|
99
|
-
You write Maestro-compatible
|
|
99
|
+
You write Maestro-compatible peach YAML flows from a user's plain-language test goal.
|
|
100
100
|
Return only JSON, no markdown, with this exact shape:
|
|
101
101
|
{"summary":"short human-readable result goal","steps":[{"waitFor":{"text":"...","timeout":10000}}]}
|
|
102
102
|
|
|
@@ -122,7 +122,7 @@ function buildPromptRequest(prompt: string, describe: string): string {
|
|
|
122
122
|
User goal:
|
|
123
123
|
${prompt}
|
|
124
124
|
|
|
125
|
-
Current
|
|
125
|
+
Current peach visible tree:
|
|
126
126
|
${describe || '[no tree available]'}
|
|
127
127
|
|
|
128
128
|
Generate the shortest replayable flow that verifies the goal from this current state.
|
|
@@ -224,7 +224,7 @@ function parseGeneratedFlow(text: string): {
|
|
|
224
224
|
const summary =
|
|
225
225
|
typeof parsed.summary === 'string' && parsed.summary.trim()
|
|
226
226
|
? parsed.summary.trim().slice(0, 500)
|
|
227
|
-
: '
|
|
227
|
+
: 'peach generated test'
|
|
228
228
|
const rawSteps = parsed.steps
|
|
229
229
|
if (!Array.isArray(rawSteps) || rawSteps.length === 0) {
|
|
230
230
|
throw new Error('llm returned no flow steps')
|
|
@@ -291,7 +291,7 @@ export function findUnexpectedGenerateArgs(
|
|
|
291
291
|
// generate writes --billing-kind onto the flow argv itself and getFlag
|
|
292
292
|
// takes the first occurrence, so a caller's value loses to it in silence.
|
|
293
293
|
if (arg === '--billing-kind') {
|
|
294
|
-
problems.push({ arg, message: `${arg} is set by
|
|
294
|
+
problems.push({ arg, message: `${arg} is set by peach maestro generate` })
|
|
295
295
|
i += 1
|
|
296
296
|
continue
|
|
297
297
|
}
|
|
@@ -311,7 +311,7 @@ export function findUnexpectedGenerateArgs(
|
|
|
311
311
|
export async function runMaestroGenerate(args: string[]): Promise<number> {
|
|
312
312
|
const promptArg = findPrompt(args)
|
|
313
313
|
if (!promptArg) {
|
|
314
|
-
console.error(' usage:
|
|
314
|
+
console.error(' usage: peach maestro generate "test goal"')
|
|
315
315
|
return 1
|
|
316
316
|
}
|
|
317
317
|
const { prompt, index: promptIndex } = promptArg
|
|
@@ -320,12 +320,12 @@ export async function runMaestroGenerate(args: string[]): Promise<number> {
|
|
|
320
320
|
for (const problem of unexpected) {
|
|
321
321
|
console.error(` error: ${problem.message}`)
|
|
322
322
|
}
|
|
323
|
-
console.error('\n run `
|
|
323
|
+
console.error('\n run `peach maestro --help` for the flags this command accepts')
|
|
324
324
|
return 1
|
|
325
325
|
}
|
|
326
326
|
const cliAuth = resolveCliAuth()
|
|
327
327
|
if (!cliAuth || cliAuth.kind === 'github') {
|
|
328
|
-
console.error('
|
|
328
|
+
console.error(' peach maestro generate "<goal>" needs a login or PEACH_API_KEY.')
|
|
329
329
|
console.error(' API keys must include preview_upload and llm scopes.')
|
|
330
330
|
return 1
|
|
331
331
|
}
|
|
@@ -338,7 +338,7 @@ export async function runMaestroGenerate(args: string[]): Promise<number> {
|
|
|
338
338
|
console.log(' generating Maestro flow…')
|
|
339
339
|
const generated = await generateFlowJson({ prompt, describe, origin, authHeader })
|
|
340
340
|
const flow = parseGeneratedFlow(generated)
|
|
341
|
-
const tempDir = mkdtempSync(join(tmpdir(), '
|
|
341
|
+
const tempDir = mkdtempSync(join(tmpdir(), 'peach-maestro-generate-'))
|
|
342
342
|
const flowPath = join(tempDir, 'flow.yaml')
|
|
343
343
|
writeFileSync(flowPath, flow.yamlText)
|
|
344
344
|
console.log(` flow: ${flowPath}`)
|