peachsim 0.1.527 → 0.1.571

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/README.md +28 -28
  2. package/cli/app-fonts.ts +1 -1
  3. package/cli/app-splash.ts +1 -1
  4. package/cli/bin.ts +1 -1
  5. package/cli/bridge-diagnostics.ts +1 -1
  6. package/cli/bridge-flow-runner.ts +72 -12
  7. package/cli/cloud-client.ts +273 -6
  8. package/cli/cloud-dispatch.ts +23 -2
  9. package/cli/cloud-session.ts +60 -4
  10. package/cli/cloud-test-result-files.ts +97 -0
  11. package/cli/cloud-test-tunnel.ts +354 -0
  12. package/cli/commands/box/bundle-plane.ts +2 -2
  13. package/cli/commands/box/checkout-plane.ts +1 -1
  14. package/cli/commands/box/rnx-command.ts +2 -2
  15. package/cli/commands/box/search-command.ts +2 -2
  16. package/cli/commands/box.ts +8 -8
  17. package/cli/commands/compat.ts +1 -1
  18. package/cli/commands/control.ts +22 -3
  19. package/cli/commands/detox.ts +1 -1
  20. package/cli/commands/device.ts +1 -1
  21. package/cli/commands/diagnose.ts +1 -1
  22. package/cli/commands/film.ts +1 -1
  23. package/cli/commands/flow.ts +60 -3
  24. package/cli/commands/inspect/actions.ts +1 -1
  25. package/cli/commands/inspect/core.ts +6 -7
  26. package/cli/commands/inspect/find.ts +2 -1
  27. package/cli/commands/inspect/resolve-target.ts +5 -3
  28. package/cli/commands/inspect/shared.ts +1 -1
  29. package/cli/commands/inspect/wait-event.ts +1 -1
  30. package/cli/commands/inspect/wait-selector.ts +15 -4
  31. package/cli/commands/inspect.ts +19 -14
  32. package/cli/commands/maestro.ts +582 -69
  33. package/cli/commands/permissions.ts +1 -1
  34. package/cli/commands/platform.ts +205 -8
  35. package/cli/commands/preview.ts +2 -2
  36. package/cli/commands/record.ts +2 -2
  37. package/cli/commands/report-issue.ts +2 -2
  38. package/cli/commands/screenshot-layers.ts +1 -1
  39. package/cli/commands/screenshot.ts +1 -1
  40. package/cli/commands/setup.ts +2 -2
  41. package/cli/commands/test.ts +600 -117
  42. package/cli/commands/three-mode.ts +1 -1
  43. package/cli/commands/upload.ts +5 -5
  44. package/cli/commands/what-happened.ts +1 -1
  45. package/cli/desktop-companion.ts +3 -3
  46. package/cli/drivers/playwright-sim-host.ts +2 -2
  47. package/cli/flow-file.ts +7 -0
  48. package/cli/flow-live-status.ts +65 -8
  49. package/cli/help-core.ts +3 -3
  50. package/cli/hidden-runtime-alias.ts +1 -1
  51. package/cli/maestro-report.ts +180 -0
  52. package/cli/main.ts +1 -1
  53. package/cli/outbound-endpoints.ts +187 -136
  54. package/cli/parse-args.ts +1 -1
  55. package/cli/registry.ts +1 -1
  56. package/cli/resolve-assets.ts +1 -1
  57. package/cli/run-registry.ts +10 -1
  58. package/cli/send-to-box.ts +4 -4
  59. package/cli/ws-bridge.ts +3 -5
  60. package/detox/expectations.ts +1 -1
  61. package/detox/gestures.ts +2 -2
  62. package/detox/index.ts +71 -29
  63. package/detox/jest-preset.cjs +5 -5
  64. package/detox/jest-setup-after-env.cjs +1 -1
  65. package/dist-lib/agent-daemon-client.cjs +2 -2
  66. package/dist-lib/agent-events.cjs +1 -1
  67. package/dist-lib/agent-identity.cjs +1 -1
  68. package/dist-lib/agent-sessions.cjs +2 -2
  69. package/dist-lib/attached-projects.cjs +2 -2
  70. package/dist-lib/auth/shared-session.cjs +1 -1
  71. package/dist-lib/backend-origin.cjs +1 -1
  72. package/dist-lib/beta.cjs +1 -1
  73. package/dist-lib/beta.mjs +1 -1
  74. package/dist-lib/bridge-constants.cjs +1 -1
  75. package/dist-lib/bridge-contract-input.cjs +1 -1
  76. package/dist-lib/bridge-contract-input.mjs +1 -1
  77. package/dist-lib/bridge-contract.cjs +1 -1
  78. package/dist-lib/bridge-contract.mjs +1 -1
  79. package/dist-lib/capture-contract.cjs +94 -3
  80. package/dist-lib/capture-contract.mjs +93 -3
  81. package/dist-lib/cli-constants.cjs +1 -1
  82. package/dist-lib/cloud-contract.cjs +1 -1
  83. package/dist-lib/cloud-contract.mjs +1 -1
  84. package/dist-lib/cloud-test-args.cjs +116 -0
  85. package/dist-lib/cloud-test-args.mjs +86 -0
  86. package/dist-lib/cloud.cjs +2 -2
  87. package/dist-lib/cloud.mjs +2 -2
  88. package/dist-lib/config.cjs +1 -1
  89. package/dist-lib/detox/index.cjs +106 -25
  90. package/dist-lib/detox/jest-preset.cjs +5 -5
  91. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  92. package/dist-lib/home-paths.cjs +1 -1
  93. package/dist-lib/host/bridge-host.cjs +150 -65
  94. package/dist-lib/host/fetch-proxy-handler.cjs +28 -2
  95. package/dist-lib/host/fetch-proxy-overrides.cjs +33 -3
  96. package/dist-lib/host/fetch-proxy-overrides.mjs +30 -2
  97. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  98. package/dist-lib/host/websocket-proxy.cjs +1 -1
  99. package/dist-lib/index.cjs +224 -41
  100. package/dist-lib/jump-to-source-babel.cjs +1 -1
  101. package/dist-lib/jump-to-source-native.cjs +1 -1
  102. package/dist-lib/menu.cjs +2 -2
  103. package/dist-lib/menu.mjs +2 -2
  104. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  105. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  106. package/dist-lib/metro-production-bundle.cjs +3 -3
  107. package/dist-lib/metro-production-bundle.mjs +3 -3
  108. package/dist-lib/metro.cjs +8 -8
  109. package/dist-lib/profiles.cjs +1 -1
  110. package/dist-lib/public-brand.cjs +2 -2
  111. package/dist-lib/react-native-host-modules.cjs +1 -1
  112. package/dist-lib/react-native-host-modules.mjs +1 -1
  113. package/dist-lib/render-mode.cjs +1 -1
  114. package/dist-lib/scripts/dev-server-scanner.cjs +31 -15
  115. package/dist-lib/sdk.cjs +3 -2
  116. package/dist-lib/sdk.mjs +3 -2
  117. package/dist-lib/skills.cjs +478 -266
  118. package/dist-lib/swift-compile.cjs +372 -0
  119. package/dist-lib/swift-compile.mjs +339 -0
  120. package/dist-lib/swift-package.cjs +78 -0
  121. package/dist-lib/swift-package.mjs +52 -0
  122. package/dist-lib/swift-submit.cjs +1 -1
  123. package/dist-lib/swift-submit.mjs +1 -1
  124. package/dist-lib/swift.cjs +583 -16
  125. package/dist-lib/vite.cjs +483 -150
  126. package/package.json +30 -9
  127. package/scripts/dev-server-scanner.ts +41 -14
  128. package/scripts/optional-demo-registry.ts +3 -3
  129. package/skills/contrast/SKILL.md +9 -9
  130. package/skills/rnx-debug/SKILL.md +14 -4
  131. package/skills/rnx-perf/SKILL.md +5 -5
  132. package/skills/rnx-setup/SKILL.md +11 -11
  133. package/skills/rnx-test/SKILL.md +14 -14
  134. package/skills/rnx-visual/SKILL.md +6 -6
  135. package/src/agent-sessions.ts +3 -3
  136. package/src/attached-projects.ts +1 -1
  137. package/src/bridge-contract-input.ts +1 -1
  138. package/src/bridge-contract.ts +23 -5
  139. package/src/capture-contract.ts +145 -3
  140. package/src/cloud-test-args.ts +100 -0
  141. package/src/config.ts +2 -2
  142. package/src/connect.ts +2 -2
  143. package/src/home-paths.ts +3 -3
  144. package/src/host/bridge-host.ts +2 -2
  145. package/src/host/fetch-proxy-handler.ts +4 -3
  146. package/src/host/fetch-proxy-overrides.ts +41 -0
  147. package/src/host/plane-host.ts +2 -2
  148. package/src/index.ts +3 -0
  149. package/src/metro-plugin.ts +4 -4
  150. package/src/metro-production-bundle.ts +2 -2
  151. package/src/native-seam-manifest.ts +6 -6
  152. package/src/public-brand.ts +1 -1
  153. package/src/rolldown-plugin-swift.ts +16 -12
  154. package/src/runtime-assets.ts +8 -6
  155. package/src/screenshots/frame-compose.ts +24 -56
  156. package/src/screenshots/org-deck.ts +1 -1
  157. package/src/screenshots/registry.ts +4 -4
  158. package/src/screenshots/schema.ts +1 -1
  159. package/src/sdk.ts +2 -2
  160. package/src/settings-bundle.ts +1 -1
  161. package/src/sim-client.ts +2 -4
  162. package/src/skills/builtin/compat-check.ts +1 -1
  163. package/src/swift-compile.ts +359 -0
  164. package/src/swift-package.ts +69 -0
  165. package/src/swift-submit.ts +3 -2
  166. package/src/vite-plugin-one.ts +1 -1
  167. package/src/vite-plugin-swift.ts +114 -113
  168. package/src/vite-plugin.ts +30 -17
  169. package/src/worklets-babel.ts +2 -2
@@ -15,6 +15,7 @@ import {
15
15
  HEADLESS_TENANT_FETCH_HUNG_MARKER,
16
16
  PUBLIC_NO_NETWORK_MARKER,
17
17
  type SemanticWaitResult,
18
+ type WsBridgeCommand,
18
19
  } from '../../../src/bridge-contract'
19
20
  export {
20
21
  readyProbeHasContent,
@@ -33,8 +34,8 @@ import type {
33
34
  SootSimTimelineQuery,
34
35
  SootSimTimelineQueryResult,
35
36
  SootSimTimelineSummary,
36
- } from '@rnx/globals'
37
- import type { KeyboardLayoutSnapshot } from 'sootsim-engine/render-worker/native-ui-protocol'
37
+ } from '@peach/globals'
38
+ import type { KeyboardLayoutSnapshot } from 'peach-engine/render-worker/native-ui-protocol'
38
39
 
39
40
  // resolve a `--max-ms <n>` flag, tolerating the spellings agents and humans
40
41
  // actually type (`--maxMs`, `--maxms`, `--max_ms`). a silently-ignored
@@ -56,10 +57,7 @@ export function resolveMaxMsFlag(args: string[], fallbackMs: number): number {
56
57
  // rnx instance.
57
58
  export interface InspectBridge {
58
59
  readonly plane?: 'local' | 'cloud'
59
- send(
60
- cmd: { type: string; [k: string]: any },
61
- opts?: { timeoutMs?: number },
62
- ): Promise<any>
60
+ send(cmd: WsBridgeCommand, opts?: { timeoutMs?: number }): Promise<any>
63
61
  }
64
62
 
65
63
  const INSPECT_PICK_COMMANDS = new Set([
@@ -1151,13 +1149,14 @@ export async function inspectWaitSelector(
1151
1149
  opts: { gone?: boolean; structural?: boolean } = {},
1152
1150
  ): Promise<{ found: boolean; node?: SimSemanticNode; elapsed: number }> {
1153
1151
  const gone = opts.gone === true
1152
+ const cleanId = testId.replace(/^#/, '')
1154
1153
  const result: SemanticWaitResult = await bridge.send(
1155
1154
  {
1156
1155
  type: 'waitFor',
1157
1156
  waitForOptions: {
1158
1157
  condition: {
1159
1158
  type: gone ? 'absent' : opts.structural === true ? 'mounted' : 'present',
1160
- selector: { testID: testId },
1159
+ selector: { testID: cleanId },
1161
1160
  },
1162
1161
  timeoutMs,
1163
1162
  },
@@ -23,7 +23,8 @@ export async function runFindSubcommand(opts: {
23
23
  }
24
24
  const hasFlag = (name: string): boolean => effectiveArgs.includes(name)
25
25
 
26
- const testId = findFlag('--testid') || findFlag('--test-id')
26
+ const rawTestId = findFlag('--testid') || findFlag('--test-id')
27
+ const testId = rawTestId ? rawTestId.replace(/^#/, '') : null
27
28
  const role = findFlag('--role')
28
29
  const typeFlag = findFlag('--type')
29
30
  const textFlag = findFlag('--text')
@@ -14,14 +14,16 @@ export function readTargetFlag(
14
14
  positional?: string[],
15
15
  ): { mode: 'testid' | 'text'; value: string } | null {
16
16
  const tid = args.indexOf('--testid')
17
- if (tid >= 0 && args[tid + 1]) return { mode: 'testid', value: args[tid + 1] }
17
+ if (tid >= 0 && args[tid + 1])
18
+ return { mode: 'testid', value: args[tid + 1].replace(/^#/, '') }
18
19
  const alt = args.indexOf('--test-id')
19
- if (alt >= 0 && args[alt + 1]) return { mode: 'testid', value: args[alt + 1] }
20
+ if (alt >= 0 && args[alt + 1])
21
+ return { mode: 'testid', value: args[alt + 1].replace(/^#/, '') }
20
22
  const text = args.indexOf('--text')
21
23
  if (text >= 0 && args[text + 1]) return { mode: 'text', value: args[text + 1] }
22
24
  const bare = positional?.[1]
23
25
  if (bare && !bare.startsWith('-') && !Number.isFinite(Number(bare))) {
24
- return { mode: 'testid', value: bare }
26
+ return { mode: 'testid', value: bare.replace(/^#/, '') }
25
27
  }
26
28
  return null
27
29
  }
@@ -12,7 +12,7 @@ import {
12
12
  type WsBridge,
13
13
  } from '../../ws-bridge'
14
14
  import { getShellState, inspectWaitReady, isShellCommandUnavailable } from './core'
15
- import type { SootSimScreenTransitionWaitResult } from '@rnx/globals'
15
+ import type { SootSimScreenTransitionWaitResult } from '@peach/globals'
16
16
 
17
17
  // shell-state helpers live in the transport-agnostic kernel module so the CLI
18
18
  // and the in-browser agent share one implementation. re-exported here so
@@ -26,7 +26,7 @@ import type {
26
26
  SootSimTimelineEvent,
27
27
  SootSimTimelineQuery,
28
28
  SootSimTimelineQueryResult,
29
- } from '@rnx/globals'
29
+ } from '@peach/globals'
30
30
 
31
31
  interface WaitEventOptions {
32
32
  bridge: WsBridge
@@ -16,16 +16,27 @@ export async function runWaitSelectorSubcommand(opts: {
16
16
  inspectUsage: (name: string, tail: string) => string
17
17
  }): Promise<void> {
18
18
  const { bridge, args, positional, inspectUsage } = opts
19
- const testId = positional[1]
20
- if (!testId) {
19
+ const rawTestId = positional[1]
20
+ if (!rawTestId) {
21
21
  console.error(
22
- inspectUsage('selector', '<testid> [--max-ms 5000] [--gone] [--structural]'),
22
+ inspectUsage(
23
+ 'selector',
24
+ '<testid> [--max-ms 5000 | --timeout 5000] [--gone] [--structural]',
25
+ ),
23
26
  )
24
27
  rnxExit(1)
25
28
  }
29
+ const testId = rawTestId.replace(/^#/, '')
30
+ // the wait budget. `--max-ms` names it, and `--timeout` (the global
31
+ // per-command budget) means the same thing for a command whose whole job is
32
+ // to wait — without this it parsed away and the wait silently stayed at 5s,
33
+ // reporting a false timeout.
26
34
  const maxMsIdx = args.indexOf('--max-ms')
35
+ const budgetIdx = maxMsIdx >= 0 ? maxMsIdx : args.indexOf('--timeout')
27
36
  const timeoutMs =
28
- maxMsIdx >= 0 && args[maxMsIdx + 1] ? Math.max(100, Number(args[maxMsIdx + 1])) : 5000
37
+ budgetIdx >= 0 && args[budgetIdx + 1]
38
+ ? Math.max(100, Number(args[budgetIdx + 1]))
39
+ : 5000
29
40
  const gone = args.includes('--gone')
30
41
  const structural = args.includes('--structural')
31
42
 
@@ -1,8 +1,8 @@
1
1
  // rnx inspect — dump node tree, accessibility info, query nodes
2
2
  // connects to the rnx WS bridge (no Playwright)
3
3
 
4
- import { getCliInspectVerbMeta } from '@rnx/skills/cli'
5
- import { renderCliCommandHelp, renderCliGroupHelp } from '@rnx/skills/cli/renderers'
4
+ import { getCliInspectVerbMeta } from '@peach/skills/cli'
5
+ import { renderCliCommandHelp, renderCliGroupHelp } from '@peach/skills/cli/renderers'
6
6
  import { DEFAULT_SOOTSIM_BRIDGE_PORT } from '../../src/bridge-constants'
7
7
  import { DEFAULT_SOOTSIM_SHELL_URL } from '../../src/cli-constants'
8
8
  import { resetGuestAppStateEval } from '../app-state-reset'
@@ -103,10 +103,11 @@ import { runWaitSelectorSubcommand } from './inspect/wait-selector'
103
103
  import { printMissingSimHint, printUnknownSimHint } from './no-bridge-hint'
104
104
  import type { PerformResult, PerformStep } from '../../src/bridge-contract'
105
105
  import type {
106
+ SootSimReplayTarget,
106
107
  SootSimRequestEntry,
107
108
  SootSimScreenTransitionWaitResult,
108
109
  SootSimScrollPerformanceTrace,
109
- } from '@rnx/globals'
110
+ } from '@peach/globals'
110
111
 
111
112
  interface InspectOptions extends BridgeTransportOption {
112
113
  port?: number
@@ -116,7 +117,7 @@ interface InspectOptions extends BridgeTransportOption {
116
117
  }
117
118
 
118
119
  // shape of entries in the shared observability store — mirrors
119
- // packages/sootsim-engine/src/observability/types.ts NetworkEntry. duplicated
120
+ // packages/peach-engine/src/observability/types.ts NetworkEntry. duplicated
120
121
  // here so this command doesn't cross-import from engine internals.
121
122
  interface NetworkEntryPayload {
122
123
  id: string
@@ -1145,7 +1146,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
1145
1146
  ` usage: ${inspectCommand(name)}${tail ? ` ${tail}` : ''}`
1146
1147
 
1147
1148
  if (!subcommand || args.includes('--help') || args.includes('-h')) {
1148
- // all help output comes from the registry in packages/rnx-skills
1149
+ // all help output comes from the registry in packages/peach-skills
1149
1150
  // so `rnx do --help`, `rnx get --help`, the website docs, and
1150
1151
  // the Contrast skill markdown stay in lock-step. a drift check in
1151
1152
  // test/sootsimCliRegistry.test.ts fails CI if a verb lands without a
@@ -2615,7 +2616,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2615
2616
  ? keyboardState.focusedInput.text
2616
2617
  : ''
2617
2618
  for (let i = 0; i < existingText.length; i++) {
2618
- await bridge.send({ type: 'keyboard', action: 'press', key: 'delete' })
2619
+ await bridge.send({ type: 'keyboard', action: 'press', text: 'delete' })
2619
2620
  }
2620
2621
  await bridge.send({ type: 'keyboard', action: 'type', text })
2621
2622
  const secureTextEntry =
@@ -2742,8 +2743,12 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2742
2743
  console.error(inspectUsage('keycode', '<code> [<code> ...]'))
2743
2744
  rnxExit(1)
2744
2745
  }
2745
- const keys = codes.map((code) => ({ code, key: keyCodeToVisualKey(code) }))
2746
- const unsupported = keys.filter((entry) => !entry.key)
2746
+ const mapped = codes.map((code) => ({ code, key: keyCodeToVisualKey(code) }))
2747
+ const unsupported = mapped.filter((entry) => !entry.key)
2748
+ const keys = mapped.filter(
2749
+ (entry): entry is { code: string; key: string } =>
2750
+ typeof entry.key === 'string',
2751
+ )
2747
2752
  if (unsupported.length > 0) {
2748
2753
  console.error(
2749
2754
  ` unsupported keycode(s): ${unsupported.map((entry) => entry.code).join(', ')}`,
@@ -2836,11 +2841,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
2836
2841
  let x = Number(positional[1])
2837
2842
  let y = Number(positional[2])
2838
2843
  const target = readTargetFlag(args, positional)
2839
- let resolvedTarget: {
2840
- testID?: string | null
2841
- text?: string | null
2842
- type?: string | null
2843
- } | null = null
2844
+ let resolvedTarget: SootSimReplayTarget | undefined
2844
2845
  if (target) {
2845
2846
  const resolved = await resolveTargetCoords(bridge, target)
2846
2847
  if (!resolved) {
@@ -3896,6 +3897,7 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3896
3897
 
3897
3898
  options:
3898
3899
  --limit <n> maximum samples retained per layer (default 6000)
3900
+ --press-testid <id> trace pointer → tree → paint for one target
3899
3901
  --json emit every per-frame sample on stop
3900
3902
 
3901
3903
  examples:
@@ -3915,12 +3917,15 @@ export async function runInspect(args: string[], opts: InspectOptions) {
3915
3917
  console.error(' error: --limit must be a number of at least 120')
3916
3918
  rnxExit(1)
3917
3919
  }
3920
+ const pressTestID = effectiveArgs.find(
3921
+ (_, index) => effectiveArgs[index - 1] === '--press-testid',
3922
+ )
3918
3923
  const result = await bridge.send({
3919
3924
  type: 'evaluate',
3920
3925
  code: `(async () => {
3921
3926
  const perf = window.SootSim?.bridges?.scrollPerf
3922
3927
  if (!perf) return { error: 'scroll performance profile unavailable' }
3923
- await perf.start(${Math.floor(parsedLimit)})
3928
+ await perf.start(${Math.floor(parsedLimit)}, ${JSON.stringify(pressTestID)})
3924
3929
  return { started: true }
3925
3930
  })()`,
3926
3931
  })