rnxsim 0.1.313 → 0.1.315
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 +11 -10
- package/README.md +5 -0
- package/cli/app-config.ts +65 -0
- package/cli/app-fonts.ts +408 -0
- package/cli/app-project.ts +231 -0
- package/cli/app-splash.ts +185 -0
- package/cli/app-state-reset.ts +24 -0
- package/cli/auth.ts +155 -0
- package/cli/bin.ts +594 -0
- package/cli/bridge-diagnostics.ts +226 -0
- package/cli/bridge-flow-runner.ts +2830 -0
- package/cli/browser-evals.ts +96 -0
- package/cli/commands/agent-wrapper.ts +986 -0
- package/cli/commands/agent.ts +423 -0
- package/cli/commands/app-fonts.ts +98 -0
- package/cli/commands/assert.ts +541 -0
- package/cli/commands/auth.ts +59 -0
- package/cli/commands/camera.ts +266 -0
- package/cli/commands/cleanup.ts +169 -0
- package/cli/commands/compat.ts +87 -0
- package/cli/commands/config.ts +32 -0
- package/cli/commands/control.ts +2142 -0
- package/cli/commands/cpu-profile.ts +269 -0
- package/cli/commands/daemon-mac-app.ts +169 -0
- package/cli/commands/daemon.ts +874 -0
- package/cli/commands/debug.ts +719 -0
- package/cli/commands/desktop.ts +39 -0
- package/cli/commands/detect.ts +197 -0
- package/cli/commands/detox.ts +385 -0
- package/cli/commands/device.ts +133 -0
- package/cli/commands/diagnose.ts +589 -0
- package/cli/commands/electron.ts +95 -0
- package/cli/commands/film.ts +379 -0
- package/cli/commands/flow.ts +1124 -0
- package/cli/commands/inspect/actions.ts +622 -0
- package/cli/commands/inspect/core.ts +2405 -0
- package/cli/commands/inspect/count.ts +17 -0
- package/cli/commands/inspect/describe.ts +192 -0
- package/cli/commands/inspect/env.ts +23 -0
- package/cli/commands/inspect/find.ts +171 -0
- package/cli/commands/inspect/get-layout.ts +39 -0
- package/cli/commands/inspect/keyboard.ts +52 -0
- package/cli/commands/inspect/list.ts +58 -0
- package/cli/commands/inspect/memory.ts +215 -0
- package/cli/commands/inspect/redaction.ts +39 -0
- package/cli/commands/inspect/resolve-target.ts +82 -0
- package/cli/commands/inspect/screens.ts +78 -0
- package/cli/commands/inspect/settle.ts +22 -0
- package/cli/commands/inspect/settling.ts +158 -0
- package/cli/commands/inspect/shared.ts +353 -0
- package/cli/commands/inspect/sleep.ts +14 -0
- package/cli/commands/inspect/tree.ts +32 -0
- package/cli/commands/inspect/url.ts +17 -0
- package/cli/commands/inspect/wait-event.ts +210 -0
- package/cli/commands/inspect/wait-idle.ts +24 -0
- package/cli/commands/inspect/wait-ready.ts +74 -0
- package/cli/commands/inspect/wait-selector.ts +54 -0
- package/cli/commands/inspect/wait.ts +31 -0
- package/cli/commands/inspect.ts +4519 -0
- package/cli/commands/install-desktop.ts +351 -0
- package/cli/commands/login.ts +331 -0
- package/cli/commands/logout.ts +31 -0
- package/cli/commands/maestro-generate.ts +361 -0
- package/cli/commands/maestro.ts +453 -0
- package/cli/commands/mode.ts +57 -0
- package/cli/commands/no-bridge-hint.ts +80 -0
- package/cli/commands/perf.ts +66 -0
- package/cli/commands/permissions.ts +203 -0
- package/cli/commands/profile.ts +108 -0
- package/cli/commands/react.ts +353 -0
- package/cli/commands/record.ts +1434 -0
- package/cli/commands/report-issue.ts +305 -0
- package/cli/commands/reset.ts +85 -0
- package/cli/commands/runtime.ts +351 -0
- package/cli/commands/screenshot-command.ts +106 -0
- package/cli/commands/screenshot-layers.ts +143 -0
- package/cli/commands/screenshot-mode.ts +37 -0
- package/cli/commands/screenshot.ts +488 -0
- package/cli/commands/screenshots-capture.ts +607 -0
- package/cli/commands/screenshots.ts +127 -0
- package/cli/commands/serve.ts +168 -0
- package/cli/commands/setup.ts +545 -0
- package/cli/commands/shell-boolean-mode.ts +81 -0
- package/cli/commands/skills.ts +467 -0
- package/cli/commands/slides.ts +361 -0
- package/cli/commands/state.ts +87 -0
- package/cli/commands/storage.ts +58 -0
- package/cli/commands/telemetry.ts +54 -0
- package/cli/commands/three-mode.ts +763 -0
- package/cli/commands/timeline.ts +122 -0
- package/cli/commands/upgrade.ts +208 -0
- package/cli/commands/upload.ts +1225 -0
- package/cli/commands/version.ts +54 -0
- package/cli/commands/what-happened.ts +327 -0
- package/cli/current-sim.ts +204 -0
- package/cli/desktop-companion.ts +300 -0
- package/cli/drivers/electron.ts +70 -0
- package/cli/drivers/index.ts +20 -0
- package/cli/drivers/playwright-provisioning.ts +180 -0
- package/cli/drivers/playwright.ts +698 -0
- package/cli/drivers/registry.ts +65 -0
- package/cli/drivers/types.ts +102 -0
- package/cli/flow-file.ts +142 -0
- package/cli/flow-live-status.ts +120 -0
- package/cli/flow-session.ts +187 -0
- package/cli/help.ts +80 -0
- package/cli/hidden-runtime-alias.ts +19 -0
- package/cli/hints.ts +216 -0
- package/cli/inspect-notice-state.ts +114 -0
- package/cli/maestro-js.ts +334 -0
- package/cli/open-url.ts +8 -0
- package/cli/parent-pid.ts +204 -0
- package/cli/parse-args.ts +211 -0
- package/cli/prompt.ts +51 -0
- package/cli/recording-access.ts +107 -0
- package/cli/registry.ts +1 -0
- package/cli/resolve-assets.ts +63 -0
- package/cli/run-registry.ts +226 -0
- package/cli/runtime-notes.ts +66 -0
- package/cli/runtime-summary.ts +25 -0
- package/cli/setup-repository.ts +187 -0
- package/cli/telemetry.ts +187 -0
- package/cli/ws-bridge.ts +798 -0
- package/dist-cli/bin.js +5 -5
- package/dist-cli/chunks/{agent-XZ2KTPCU.js → agent-CBU2WDKV.js} +2 -2
- package/dist-cli/chunks/{agent-wrapper-JJYYW2WH.js → agent-wrapper-UNB4R27L.js} +2 -2
- package/dist-cli/chunks/{app-fonts-IXRNQG6B.js → app-fonts-YMLRF3JD.js} +2 -2
- package/dist-cli/chunks/{assert-54T5SK5F.js → assert-5N6HUCL5.js} +2 -2
- package/dist-cli/chunks/{auth-FI5UDI45.js → auth-BHDR3A6G.js} +2 -2
- package/dist-cli/chunks/{beta-JV6UKADW.js → beta-LWUVCPYK.js} +2 -2
- package/dist-cli/chunks/camera-CNO6B2JZ.js +33 -0
- package/dist-cli/chunks/{chunk-ZMJD5GEC.js → chunk-25VCR44B.js} +1 -1
- package/dist-cli/chunks/{chunk-WUSWBCWA.js → chunk-26CSIR76.js} +8 -9
- package/dist-cli/chunks/{chunk-WINYQ44O.js → chunk-26WMWUH4.js} +1 -1
- package/dist-cli/chunks/{chunk-BTWORNNG.js → chunk-2JZ53D4A.js} +1 -1
- package/dist-cli/chunks/{chunk-DCEMHR2Y.js → chunk-2POODCTW.js} +2 -2
- package/dist-cli/chunks/{chunk-5TEF3ET3.js → chunk-4LTBK3ZN.js} +2 -2
- package/dist-cli/chunks/{chunk-NMF2ZMZQ.js → chunk-54MIRTFE.js} +4 -4
- package/dist-cli/chunks/{chunk-WEXDAC74.js → chunk-56H6EVO4.js} +2 -2
- package/dist-cli/chunks/{chunk-F5ZRSS3C.js → chunk-657SQG4D.js} +1 -1
- package/dist-cli/chunks/{chunk-IJ5CAZZC.js → chunk-6ZMRJPKI.js} +1 -1
- package/dist-cli/chunks/{chunk-W6K4EFPH.js → chunk-AOGGOC4V.js} +2 -2
- package/dist-cli/chunks/chunk-BPCDO7ST.js +15 -0
- package/dist-cli/chunks/{chunk-D4FFVGI5.js → chunk-C5O5CTXJ.js} +1 -1
- package/dist-cli/chunks/{chunk-RTN5C5RL.js → chunk-CMM64PPR.js} +1 -1
- package/dist-cli/chunks/{chunk-BBULZ7CG.js → chunk-D3M36D7O.js} +62 -87
- package/dist-cli/chunks/{chunk-5DHC6KHQ.js → chunk-DNCNFZ7V.js} +1 -1
- package/dist-cli/chunks/{chunk-YIFT42WN.js → chunk-FNTTIR2P.js} +2 -2
- package/dist-cli/chunks/chunk-H362IX2I.js +4 -0
- package/dist-cli/chunks/{chunk-IJO63TDP.js → chunk-J6HMTUZH.js} +2 -2
- package/dist-cli/chunks/{chunk-RSZWCKNT.js → chunk-JZ6VTZ5B.js} +3 -3
- package/dist-cli/chunks/{chunk-MJRLLB4R.js → chunk-KQSJVNFE.js} +4 -4
- package/dist-cli/chunks/chunk-L4JZKVCC.js +6 -0
- package/dist-cli/chunks/{chunk-VFCMSYZK.js → chunk-LP2BTEJ6.js} +2 -2
- package/dist-cli/chunks/{chunk-2YR5BGA5.js → chunk-LT6UC7I3.js} +2 -2
- package/dist-cli/chunks/{chunk-OVFJFXUD.js → chunk-MCKQH4AM.js} +2 -2
- package/dist-cli/chunks/{chunk-TZFFR3SD.js → chunk-MF7WUHQ3.js} +2 -2
- package/dist-cli/chunks/{chunk-46EUUFJ5.js → chunk-MSSY4EEZ.js} +1 -1
- package/dist-cli/chunks/{chunk-WMIIKMGK.js → chunk-N5ZCYP5F.js} +2 -2
- package/dist-cli/chunks/{chunk-3NV2NCNX.js → chunk-NCKAD3V7.js} +2 -2
- package/dist-cli/chunks/{chunk-VNQEB4L7.js → chunk-O2KRHVTU.js} +2 -2
- package/dist-cli/chunks/{chunk-OZSSI4WN.js → chunk-OF2HTH25.js} +2 -2
- package/dist-cli/chunks/{chunk-GGRX24GF.js → chunk-OXS2IWO2.js} +2 -2
- package/dist-cli/chunks/{chunk-WWZIXIRD.js → chunk-PVL7XSPN.js} +1 -1
- package/dist-cli/chunks/{chunk-DZS6WPUI.js → chunk-PVPAP3TV.js} +1 -1
- package/dist-cli/chunks/{chunk-5YJCOWCH.js → chunk-PXNAZYGV.js} +1 -1
- package/dist-cli/chunks/chunk-QR3HTFRB.js +5 -0
- package/dist-cli/chunks/{chunk-5TPRP5QT.js → chunk-QR7MWAWE.js} +1 -1
- package/dist-cli/chunks/chunk-RJIEZ2NY.js +4 -0
- package/dist-cli/chunks/{chunk-UC6U3MML.js → chunk-RVM4EZ4E.js} +2 -2
- package/dist-cli/chunks/{chunk-2D2UPBBR.js → chunk-SZKSFMWS.js} +1 -1
- package/dist-cli/chunks/{chunk-7GN3LVWB.js → chunk-TEL7G234.js} +2 -2
- package/dist-cli/chunks/{chunk-GASE6UBA.js → chunk-U2HNIHBY.js} +1 -1
- package/dist-cli/chunks/chunk-UROXJVY3.js +27 -0
- package/dist-cli/chunks/{chunk-HI5TFJWN.js → chunk-WM32MGTJ.js} +2 -2
- package/dist-cli/chunks/{chunk-VZXWHRUZ.js → chunk-WMZ7NJAO.js} +89 -133
- package/dist-cli/chunks/{chunk-XEVZYVIW.js → chunk-WUXCH6WN.js} +10 -9
- package/dist-cli/chunks/chunk-XOXGC3EH.js +9 -0
- package/dist-cli/chunks/chunk-XSSHENNY.js +4 -0
- package/dist-cli/chunks/{chunk-OHAZNXLK.js → chunk-XZ6O67AR.js} +1 -1
- package/dist-cli/chunks/{chunk-QKDWYITG.js → chunk-Y2MWQKOS.js} +3 -3
- package/dist-cli/chunks/{chunk-YDGQTMQL.js → chunk-YY24QI25.js} +1 -1
- package/dist-cli/chunks/{chunk-WF3T4SVI.js → chunk-ZWX6DDIS.js} +2 -2
- package/dist-cli/chunks/{cleanup-P27PA6JI.js → cleanup-F3NUJ3SL.js} +2 -2
- package/dist-cli/chunks/cli-version-XIW6O3FG.js +4 -0
- package/dist-cli/chunks/{compat-ZD65FED3.js → compat-AX2SEPTH.js} +2 -2
- package/dist-cli/chunks/{config-XMJRNM2A.js → config-4QQO5JVU.js} +2 -2
- package/dist-cli/chunks/{control-KMIQT3QP.js → control-OCKKSOWA.js} +2 -2
- package/dist-cli/chunks/daemon-N5VLMYKQ.js +4 -0
- package/dist-cli/chunks/{debug-PT4HOP7N.js → debug-T6MWVEVX.js} +5 -5
- package/dist-cli/chunks/{desktop-S3FG72AK.js → desktop-NCW7R7CB.js} +3 -3
- package/dist-cli/chunks/{detox-B3D4IFCN.js → detox-G6GITO2X.js} +2 -2
- package/dist-cli/chunks/{device-XBNDSB2R.js → device-7BTEJCTH.js} +2 -2
- package/dist-cli/chunks/{diagnose-HMQXJE5N.js → diagnose-SC5LACE3.js} +2 -2
- package/dist-cli/chunks/{disk-cleanup-BLCZ5BSZ.js → disk-cleanup-KK56QQZA.js} +2 -2
- package/dist-cli/chunks/drivers-NPGVBWMG.js +4 -0
- package/dist-cli/chunks/{film-BJGTBYZB.js → film-WGYEHGIA.js} +3 -3
- package/dist-cli/chunks/flow-KQBIBM3N.js +4 -0
- package/dist-cli/chunks/help-G7CAKI65.js +4 -0
- package/dist-cli/chunks/{hidden-runtime-alias-ANOYADHM.js → hidden-runtime-alias-CWTZWH3L.js} +2 -2
- package/dist-cli/chunks/home-paths-EBT4XHAS.js +4 -0
- package/dist-cli/chunks/inspect-CCPZXVDU.js +4 -0
- package/dist-cli/chunks/install-desktop-NZ3VGTQZ.js +4 -0
- package/dist-cli/chunks/{login-FJ737MWG.js → login-GSYOTGVQ.js} +4 -4
- package/dist-cli/chunks/{logout-ZCNMMHMY.js → logout-JPRIR7YK.js} +2 -2
- package/dist-cli/chunks/{maestro-SZTNKLDF.js → maestro-LXKDNO5M.js} +3 -3
- package/dist-cli/chunks/{maestro-generate-DCFAIZ4H.js → maestro-generate-5ZIKOU53.js} +3 -3
- package/dist-cli/chunks/{mode-GRMQCRXR.js → mode-N3QHXCES.js} +2 -2
- package/dist-cli/chunks/{optional-demo-registry-W36EWFFB.js → optional-demo-registry-XDH6X24N.js} +2 -2
- package/dist-cli/chunks/{perf-QYBAAUZG.js → perf-VOPL26FM.js} +2 -2
- package/dist-cli/chunks/{permissions-3QCQ6VF4.js → permissions-CZFKM4UD.js} +2 -2
- package/dist-cli/chunks/{record-QPPC2S4E.js → record-FODSOGMA.js} +3 -3
- package/dist-cli/chunks/{report-issue-7NMFP4HK.js → report-issue-FBPCZKOV.js} +2 -2
- package/dist-cli/chunks/reset-3H35GFO3.js +4 -0
- package/dist-cli/chunks/runtime-4OVFRXV5.js +4 -0
- package/dist-cli/chunks/{screenshot-command-67AECJFB.js → screenshot-command-7S3FYVO7.js} +7 -7
- package/dist-cli/chunks/{screenshot-layers-ASWBYPJL.js → screenshot-layers-CDYHPNC3.js} +3 -3
- package/dist-cli/chunks/{screenshots-capture-PXA3HFQK.js → screenshots-capture-EBIIY2YU.js} +2 -2
- package/dist-cli/chunks/serve-NELNSCZP.js +44 -0
- package/dist-cli/chunks/{setup-7DWPMRSB.js → setup-DF5ZDDIV.js} +2 -2
- package/dist-cli/chunks/{skills-S3Y22TUA.js → skills-E2QZF6WZ.js} +2 -2
- package/dist-cli/chunks/state-MBZDKZ7U.js +14 -0
- package/dist-cli/chunks/{storage-XUIMJWAJ.js → storage-J5BMNVXM.js} +6 -6
- package/dist-cli/chunks/store-U3DXC7HH.js +4 -0
- package/dist-cli/chunks/telemetry-XIPJVT5E.js +4 -0
- package/dist-cli/chunks/{timeline-TMPLQPSP.js → timeline-MC6N5BHY.js} +2 -2
- package/dist-cli/chunks/{upgrade-7HDSIM7K.js → upgrade-7UTU53DH.js} +2 -2
- package/dist-cli/chunks/upload-2M2KOTYI.js +4 -0
- package/dist-cli/chunks/version-VNACNYQK.js +6 -0
- package/dist-cli/chunks/{web-DG3WBYD3.js → web-MGJ2TUKR.js} +2 -2
- package/dist-cli/chunks/{what-happened-XFVUTZR7.js → what-happened-7DLKH3OD.js} +3 -3
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +1 -1
- package/dist-lib/agent-sessions.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- 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 +1 -1
- package/dist-lib/bridge-contract.cjs +20 -0
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +1 -1
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +67 -28
- package/dist-lib/host/bridge-host.cjs +140 -12
- 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/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +2815 -40
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/menu.cjs +1 -1
- package/dist-lib/menu.mjs +1 -1
- package/dist-lib/metro.cjs +1 -1
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +1 -1
- package/dist-lib/render-mode.cjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
- package/dist-lib/sdk.cjs +2549 -2061
- package/dist-lib/sdk.mjs +2543 -2061
- package/dist-lib/skills.cjs +480 -280
- package/dist-lib/vite.cjs +1 -1
- package/package.json +8 -2
- package/src/bridge-constants.ts +3 -4
- package/src/bridge-contract.ts +251 -0
- package/src/connect.ts +83 -0
- package/src/disk-cleanup.ts +30 -0
- package/src/home-paths.ts +81 -38
- package/src/host/bridge-host.ts +134 -6
- package/src/index.ts +27 -1
- package/src/sdk.ts +8 -0
- package/src/sim-client.ts +660 -0
- package/dist-cli/chunks/camera-VL73YIKP.js +0 -22
- package/dist-cli/chunks/chunk-4NPPOV2N.js +0 -5
- package/dist-cli/chunks/chunk-FSUYIVJ6.js +0 -9
- package/dist-cli/chunks/chunk-G2WW6L2C.js +0 -23
- package/dist-cli/chunks/chunk-KTHV3RUS.js +0 -26
- package/dist-cli/chunks/chunk-LF2ZVT7O.js +0 -6
- package/dist-cli/chunks/chunk-NFK7T35W.js +0 -4
- package/dist-cli/chunks/chunk-TIVZIMMW.js +0 -4
- package/dist-cli/chunks/cli-version-WWLPBDQ7.js +0 -4
- package/dist-cli/chunks/daemon-G2ME7NLB.js +0 -4
- package/dist-cli/chunks/drivers-LDECZGP2.js +0 -4
- package/dist-cli/chunks/flow-UEQNVTU7.js +0 -4
- package/dist-cli/chunks/help-T5FYSVGB.js +0 -4
- package/dist-cli/chunks/home-paths-GT3LFNOR.js +0 -4
- package/dist-cli/chunks/inspect-ZA6XF5LD.js +0 -4
- package/dist-cli/chunks/install-desktop-TIMUDHPL.js +0 -4
- package/dist-cli/chunks/runtime-XOAXMSTU.js +0 -4
- package/dist-cli/chunks/serve-BI2NBAXG.js +0 -44
- package/dist-cli/chunks/store-JTHEJLAZ.js +0 -4
- package/dist-cli/chunks/telemetry-ZYJGD2DB.js +0 -4
- package/dist-cli/chunks/upload-GMSZPWM6.js +0 -4
- package/dist-cli/chunks/version-HOCHZ37L.js +0 -6
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
// sootsim report-issue — submit an explicitly approved compatibility report.
|
|
2
|
+
|
|
3
|
+
import { existsSync, readFileSync } from 'node:fs'
|
|
4
|
+
import { resolve } from 'node:path'
|
|
5
|
+
import { getCliVersion } from '../../src/cli-version'
|
|
6
|
+
import { readActiveRuntime } from '../../src/home-paths'
|
|
7
|
+
import { authHeaderValue, resolveCliAuth } from '../auth'
|
|
8
|
+
import { confirm } from '../prompt'
|
|
9
|
+
import type { ScanResult } from '@sootsim/compat/web'
|
|
10
|
+
|
|
11
|
+
const DEFAULT_REPORT_ORIGIN = 'https://contrast.dev'
|
|
12
|
+
const MAX_DESCRIPTION_LENGTH = 8_000
|
|
13
|
+
|
|
14
|
+
type PackageManifest = {
|
|
15
|
+
name?: string
|
|
16
|
+
dependencies?: Record<string, string>
|
|
17
|
+
devDependencies?: Record<string, string>
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type ReportIssueOptions = {
|
|
21
|
+
appDir: string
|
|
22
|
+
description: string
|
|
23
|
+
dryRun: boolean
|
|
24
|
+
yes: boolean
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type ReportIssuePayload = {
|
|
28
|
+
note: string
|
|
29
|
+
timestamp: string
|
|
30
|
+
sootsim_version: string | null
|
|
31
|
+
cli_version: string
|
|
32
|
+
bundle: {
|
|
33
|
+
activeApp: { appName: string } | null
|
|
34
|
+
reportSource: 'cli'
|
|
35
|
+
runtimeVersion: string | null
|
|
36
|
+
cliVersion: string
|
|
37
|
+
platform: NodeJS.Platform
|
|
38
|
+
arch: string
|
|
39
|
+
compatibility: ScanResult | null
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export type ReportIssueDependencies = {
|
|
44
|
+
request: (url: string, init: RequestInit) => Promise<Response>
|
|
45
|
+
confirmSubmission: (message: string, defaultYes: boolean) => Promise<boolean>
|
|
46
|
+
isInteractive: boolean
|
|
47
|
+
now: () => Date
|
|
48
|
+
stdout: (message: string) => void
|
|
49
|
+
stderr: (message: string) => void
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function defaultDependencies(): ReportIssueDependencies {
|
|
53
|
+
return {
|
|
54
|
+
request: (url, init) => fetch(url, init),
|
|
55
|
+
confirmSubmission: confirm,
|
|
56
|
+
isInteractive: process.stdin.isTTY === true,
|
|
57
|
+
now: () => new Date(),
|
|
58
|
+
stdout: (message) => process.stdout.write(message),
|
|
59
|
+
stderr: (message) => process.stderr.write(message),
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function getFlagValue(args: string[], flag: string): string | null {
|
|
64
|
+
const index = args.indexOf(flag)
|
|
65
|
+
if (index === -1) return null
|
|
66
|
+
const value = args[index + 1]
|
|
67
|
+
if (!value || value.startsWith('-')) {
|
|
68
|
+
throw new Error(`${flag} requires a value`)
|
|
69
|
+
}
|
|
70
|
+
return value
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function parseReportIssueOptions(
|
|
74
|
+
args: string[],
|
|
75
|
+
cwd = process.cwd(),
|
|
76
|
+
): ReportIssueOptions {
|
|
77
|
+
const app = getFlagValue(args, '--app')
|
|
78
|
+
const consumed = new Set<number>()
|
|
79
|
+
const appIndex = args.indexOf('--app')
|
|
80
|
+
if (appIndex !== -1) {
|
|
81
|
+
consumed.add(appIndex)
|
|
82
|
+
consumed.add(appIndex + 1)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const descriptionParts: string[] = []
|
|
86
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
87
|
+
if (consumed.has(index)) continue
|
|
88
|
+
const arg = args[index]
|
|
89
|
+
if (arg === '--yes' || arg === '-y' || arg === '--dry-run') continue
|
|
90
|
+
if (arg.startsWith('-')) throw new Error(`unknown flag: ${arg}`)
|
|
91
|
+
descriptionParts.push(arg)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const description = descriptionParts.join(' ').trim()
|
|
95
|
+
if (!description) {
|
|
96
|
+
throw new Error('describe the missing or broken compatibility behavior')
|
|
97
|
+
}
|
|
98
|
+
if (description.length > MAX_DESCRIPTION_LENGTH) {
|
|
99
|
+
throw new Error(
|
|
100
|
+
`description is too long (maximum ${MAX_DESCRIPTION_LENGTH} characters)`,
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
appDir: resolve(cwd, app ?? '.'),
|
|
106
|
+
description,
|
|
107
|
+
dryRun: args.includes('--dry-run'),
|
|
108
|
+
yes: args.includes('--yes') || args.includes('-y'),
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function readStringRecord(value: unknown): Record<string, string> | undefined {
|
|
113
|
+
if (!value || typeof value !== 'object') return undefined
|
|
114
|
+
const output: Record<string, string> = {}
|
|
115
|
+
for (const key of Object.keys(value)) {
|
|
116
|
+
const next = Object.getOwnPropertyDescriptor(value, key)?.value
|
|
117
|
+
if (typeof next === 'string') output[key] = next
|
|
118
|
+
}
|
|
119
|
+
return output
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function readManifest(appDir: string): PackageManifest | null {
|
|
123
|
+
const path = resolve(appDir, 'package.json')
|
|
124
|
+
if (!existsSync(path)) return null
|
|
125
|
+
|
|
126
|
+
let parsed: unknown
|
|
127
|
+
try {
|
|
128
|
+
parsed = JSON.parse(readFileSync(path, 'utf8'))
|
|
129
|
+
} catch {
|
|
130
|
+
throw new Error(`could not parse ${path}`)
|
|
131
|
+
}
|
|
132
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
133
|
+
throw new Error(`${path} must contain a JSON object`)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const name = Object.getOwnPropertyDescriptor(parsed, 'name')?.value
|
|
137
|
+
const dependencies = Object.getOwnPropertyDescriptor(parsed, 'dependencies')?.value
|
|
138
|
+
const devDependencies = Object.getOwnPropertyDescriptor(
|
|
139
|
+
parsed,
|
|
140
|
+
'devDependencies',
|
|
141
|
+
)?.value
|
|
142
|
+
const dependencyRecord = readStringRecord(dependencies)
|
|
143
|
+
const devDependencyRecord = readStringRecord(devDependencies)
|
|
144
|
+
return {
|
|
145
|
+
...(typeof name === 'string' ? { name } : {}),
|
|
146
|
+
...(dependencyRecord ? { dependencies: dependencyRecord } : {}),
|
|
147
|
+
...(devDependencyRecord ? { devDependencies: devDependencyRecord } : {}),
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export async function createReportIssuePayload(
|
|
152
|
+
options: Pick<ReportIssueOptions, 'appDir' | 'description'>,
|
|
153
|
+
now = new Date(),
|
|
154
|
+
): Promise<ReportIssuePayload> {
|
|
155
|
+
const manifest = readManifest(options.appDir)
|
|
156
|
+
const compatibility = manifest
|
|
157
|
+
? (await import('@sootsim/compat/web')).scanDeps(manifest)
|
|
158
|
+
: null
|
|
159
|
+
const cliVersion = getCliVersion()
|
|
160
|
+
const runtimeVersion = readActiveRuntime()
|
|
161
|
+
|
|
162
|
+
return {
|
|
163
|
+
note: options.description,
|
|
164
|
+
timestamp: now.toISOString(),
|
|
165
|
+
sootsim_version: runtimeVersion,
|
|
166
|
+
cli_version: cliVersion,
|
|
167
|
+
bundle: {
|
|
168
|
+
activeApp:
|
|
169
|
+
compatibility && compatibility.projectName !== 'unknown'
|
|
170
|
+
? { appName: compatibility.projectName }
|
|
171
|
+
: null,
|
|
172
|
+
reportSource: 'cli',
|
|
173
|
+
runtimeVersion,
|
|
174
|
+
cliVersion,
|
|
175
|
+
platform: process.platform,
|
|
176
|
+
arch: process.arch,
|
|
177
|
+
compatibility,
|
|
178
|
+
},
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function reportEndpoint(): { url: string; authorization: string | null } {
|
|
183
|
+
const auth = resolveCliAuth()
|
|
184
|
+
const origin =
|
|
185
|
+
auth?.kind === 'session' ? auth.origin.replace(/\/+$/, '') : DEFAULT_REPORT_ORIGIN
|
|
186
|
+
const authorization = auth && auth.kind !== 'github' ? authHeaderValue(auth) : null
|
|
187
|
+
return {
|
|
188
|
+
url: `${origin}/api/sootsim/report-issue`,
|
|
189
|
+
authorization,
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function compatibilitySummary(scan: ScanResult | null): string {
|
|
194
|
+
if (!scan) return 'no package.json found; no compatibility scan attached'
|
|
195
|
+
const attention = scan.packages.filter(
|
|
196
|
+
(item) => item.status !== 'full' && item.status !== 'not-relevant',
|
|
197
|
+
).length
|
|
198
|
+
return `${scan.packages.length} React Native ecosystem packages, ${attention} needing attention`
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function readResponseId(value: unknown): string | null {
|
|
202
|
+
if (!value || typeof value !== 'object') return null
|
|
203
|
+
const id = Object.getOwnPropertyDescriptor(value, 'id')?.value
|
|
204
|
+
return typeof id === 'string' && id ? id : null
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export async function runReportIssue(
|
|
208
|
+
args: string[],
|
|
209
|
+
dependencies: ReportIssueDependencies = defaultDependencies(),
|
|
210
|
+
): Promise<number> {
|
|
211
|
+
let options: ReportIssueOptions
|
|
212
|
+
try {
|
|
213
|
+
options = parseReportIssueOptions(args)
|
|
214
|
+
} catch (error) {
|
|
215
|
+
dependencies.stderr(
|
|
216
|
+
` ${error instanceof Error ? error.message : String(error)}\n` +
|
|
217
|
+
` usage: rnxsim report-issue [--app <dir>] [--dry-run] [--yes] "<description>"\n`,
|
|
218
|
+
)
|
|
219
|
+
return 1
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (!existsSync(options.appDir)) {
|
|
223
|
+
dependencies.stderr(` directory not found: ${options.appDir}\n`)
|
|
224
|
+
return 1
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
let payload: ReportIssuePayload
|
|
228
|
+
try {
|
|
229
|
+
payload = await createReportIssuePayload(options, dependencies.now())
|
|
230
|
+
} catch (error) {
|
|
231
|
+
dependencies.stderr(
|
|
232
|
+
` could not prepare the issue report: ${
|
|
233
|
+
error instanceof Error ? error.message : String(error)
|
|
234
|
+
}\n`,
|
|
235
|
+
)
|
|
236
|
+
return 1
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
dependencies.stdout(
|
|
240
|
+
`\n rnxsim issue report preview\n\n` +
|
|
241
|
+
` description: ${payload.note}\n` +
|
|
242
|
+
` compatibility: ${compatibilitySummary(payload.bundle.compatibility)}\n` +
|
|
243
|
+
` environment: CLI ${payload.bundle.cliVersion}, runtime ${
|
|
244
|
+
payload.bundle.runtimeVersion ?? 'not installed'
|
|
245
|
+
}, ${payload.bundle.platform}/${payload.bundle.arch}\n\n` +
|
|
246
|
+
` Includes only the description, compatibility scan, and the version/platform details above.\n` +
|
|
247
|
+
` It does not include source files, environment variables, terminal output, logs, screenshots, or app data.\n`,
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
if (options.dryRun) {
|
|
251
|
+
dependencies.stdout(`\n dry run: nothing was sent.\n`)
|
|
252
|
+
return 0
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (!options.yes) {
|
|
256
|
+
if (!dependencies.isInteractive) {
|
|
257
|
+
dependencies.stderr(
|
|
258
|
+
`\n not sent: ask the user for explicit approval, then rerun with --yes.\n`,
|
|
259
|
+
)
|
|
260
|
+
return 2
|
|
261
|
+
}
|
|
262
|
+
const approved = await dependencies.confirmSubmission(
|
|
263
|
+
'send this compatibility report to the rnx team?',
|
|
264
|
+
false,
|
|
265
|
+
)
|
|
266
|
+
if (!approved) {
|
|
267
|
+
dependencies.stdout(`\n not sent.\n`)
|
|
268
|
+
return 2
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const endpoint = reportEndpoint()
|
|
273
|
+
const headers: Record<string, string> = { 'content-type': 'application/json' }
|
|
274
|
+
if (endpoint.authorization) headers.authorization = endpoint.authorization
|
|
275
|
+
|
|
276
|
+
let response: Response
|
|
277
|
+
try {
|
|
278
|
+
response = await dependencies.request(endpoint.url, {
|
|
279
|
+
method: 'POST',
|
|
280
|
+
headers,
|
|
281
|
+
body: JSON.stringify(payload),
|
|
282
|
+
signal: AbortSignal.timeout(15_000),
|
|
283
|
+
})
|
|
284
|
+
} catch (error) {
|
|
285
|
+
dependencies.stderr(
|
|
286
|
+
` report failed: ${error instanceof Error ? error.message : String(error)}\n`,
|
|
287
|
+
)
|
|
288
|
+
return 1
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
if (!response.ok) {
|
|
292
|
+
const detail = (await response.text().catch(() => '')).slice(0, 240)
|
|
293
|
+
dependencies.stderr(
|
|
294
|
+
` report failed: ${response.status} ${response.statusText}${
|
|
295
|
+
detail ? ` — ${detail}` : ''
|
|
296
|
+
}\n`,
|
|
297
|
+
)
|
|
298
|
+
return 1
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
const parsed: unknown = await response.json().catch(() => null)
|
|
302
|
+
const id = readResponseId(parsed)
|
|
303
|
+
dependencies.stdout(id ? `\n sent. Report id: ${id}\n` : `\n sent. Thank you.\n`)
|
|
304
|
+
return 0
|
|
305
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { printBridgeFailureDiagnostics } from '../bridge-diagnostics'
|
|
2
|
+
import { createBridgeFromParsed, parseBridgeCliArgs } from '../ws-bridge'
|
|
3
|
+
import type { ResetResult } from '../../src/bridge-contract'
|
|
4
|
+
|
|
5
|
+
function isResetResult(value: unknown): value is ResetResult {
|
|
6
|
+
if (!value || typeof value !== 'object') return false
|
|
7
|
+
const strategy = Reflect.get(value, 'strategy')
|
|
8
|
+
return (
|
|
9
|
+
typeof Reflect.get(value, 'ok') === 'boolean' &&
|
|
10
|
+
(strategy === 'data' || strategy === 'full') &&
|
|
11
|
+
Array.isArray(Reflect.get(value, 'cleared')) &&
|
|
12
|
+
typeof Reflect.get(value, 'relaunched') === 'boolean'
|
|
13
|
+
)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function printHelp(): void {
|
|
17
|
+
console.log(`
|
|
18
|
+
rnxsim reset - clear the current guest app and relaunch it
|
|
19
|
+
|
|
20
|
+
usage:
|
|
21
|
+
rnxsim reset [--full] [--json] [--sim <id>]
|
|
22
|
+
|
|
23
|
+
options:
|
|
24
|
+
--full also clear keychain, user defaults, and permissions
|
|
25
|
+
--json print the structured reset result
|
|
26
|
+
--sim <id> target a specific sim
|
|
27
|
+
--port <p> WS bridge port
|
|
28
|
+
`)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export async function runReset(
|
|
32
|
+
args: string[],
|
|
33
|
+
opts: { port?: number } = {},
|
|
34
|
+
): Promise<number> {
|
|
35
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
36
|
+
printHelp()
|
|
37
|
+
return 0
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const parsed = parseBridgeCliArgs(args, {
|
|
41
|
+
port: opts.port,
|
|
42
|
+
stripBooleanFlags: ['--full', '--json'],
|
|
43
|
+
})
|
|
44
|
+
if (parsed.positional.length > 0) {
|
|
45
|
+
console.error(` unexpected reset argument: ${parsed.positional[0]}`)
|
|
46
|
+
return 1
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const bridge = createBridgeFromParsed(parsed)
|
|
50
|
+
try {
|
|
51
|
+
const value: unknown = await bridge.send({
|
|
52
|
+
type: 'reset',
|
|
53
|
+
resetOptions: { strategy: args.includes('--full') ? 'full' : 'data' },
|
|
54
|
+
})
|
|
55
|
+
if (!isResetResult(value)) {
|
|
56
|
+
throw new Error('reset bridge returned an invalid result')
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (args.includes('--json')) {
|
|
60
|
+
console.log(JSON.stringify(value))
|
|
61
|
+
} else {
|
|
62
|
+
console.log(` ${value.strategy} reset ${value.ok ? 'complete' : 'failed'}`)
|
|
63
|
+
console.log(
|
|
64
|
+
value.cleared.length > 0
|
|
65
|
+
? ` cleared: ${value.cleared.join(', ')}`
|
|
66
|
+
: ' cleared: none',
|
|
67
|
+
)
|
|
68
|
+
for (const skipped of value.skipped ?? []) {
|
|
69
|
+
console.log(` skipped ${skipped.store}: ${skipped.reason}`)
|
|
70
|
+
}
|
|
71
|
+
console.log(` app: ${value.relaunched ? 'relaunched' : 'not relaunched'}`)
|
|
72
|
+
console.log(
|
|
73
|
+
` worker: ${value.workerReloaded ? 'restarted' : 'preserved in place'}`,
|
|
74
|
+
)
|
|
75
|
+
if (value.error) console.error(` error: ${value.error}`)
|
|
76
|
+
}
|
|
77
|
+
return value.ok ? 0 : 1
|
|
78
|
+
} catch (error) {
|
|
79
|
+
console.error(` reset failed: ${error instanceof Error ? error.message : error}`)
|
|
80
|
+
await printBridgeFailureDiagnostics(bridge)
|
|
81
|
+
return 1
|
|
82
|
+
} finally {
|
|
83
|
+
bridge.close()
|
|
84
|
+
}
|
|
85
|
+
}
|