sootsim 0.1.292 → 0.1.294

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 (172) hide show
  1. package/detox/expectations.ts +4 -3
  2. package/detox/index.ts +2 -4
  3. package/dist-cli/bin.js +7 -5
  4. package/dist-cli/chunks/{agent-JEONFLYE.js → agent-GDFF6G7N.js} +4 -2
  5. package/dist-cli/chunks/{agent-wrapper-YR2IKZVN.js → agent-wrapper-ZUKQUOD2.js} +4 -2
  6. package/dist-cli/chunks/{app-fonts-A2R5ZIVW.js → app-fonts-IMYBO6AQ.js} +4 -2
  7. package/dist-cli/chunks/{assert-S27WE34T.js → assert-GXOGZUKO.js} +4 -2
  8. package/dist-cli/chunks/{auth-CY3SOCMK.js → auth-P7FAKLHQ.js} +4 -2
  9. package/dist-cli/chunks/beta-RXT5RU3A.js +4 -0
  10. package/dist-cli/chunks/{camera-VXTZ3M2P.js → camera-RNVAC4IO.js} +4 -2
  11. package/dist-cli/chunks/{chunk-637NGQFS.js → chunk-24BJFJFB.js} +26 -24
  12. package/dist-cli/chunks/{chunk-LNSMUJOI.js → chunk-2M7OZ6Y4.js} +4 -2
  13. package/dist-cli/chunks/chunk-37ZXWXM3.js +4 -0
  14. package/dist-cli/chunks/{chunk-KBCJX4FK.js → chunk-3F2GAJ4Z.js} +3 -1
  15. package/dist-cli/chunks/{chunk-OYOZGYYP.js → chunk-4Z4URZOG.js} +4 -2
  16. package/dist-cli/chunks/{chunk-5V6UBIAU.js → chunk-5S3GPTX7.js} +4 -2
  17. package/dist-cli/chunks/chunk-6YN3IAWJ.js +4 -0
  18. package/dist-cli/chunks/{chunk-AN5IVTX2.js → chunk-7HVMAGDK.js} +4 -2
  19. package/dist-cli/chunks/{chunk-ITSO4QXQ.js → chunk-7Q77LTPT.js} +7 -5
  20. package/dist-cli/chunks/{chunk-3JRVWPIU.js → chunk-AFLGWOX3.js} +18 -16
  21. package/dist-cli/chunks/{chunk-YS5MI4DR.js → chunk-AMKQUZA2.js} +3 -1
  22. package/dist-cli/chunks/{chunk-BPR2XKYR.js → chunk-AO65WEF7.js} +3 -1
  23. package/dist-cli/chunks/{chunk-AT2MKEM7.js → chunk-BBVBMGTT.js} +5 -3
  24. package/dist-cli/chunks/{chunk-4DSOSKTJ.js → chunk-BXO2PTNM.js} +4 -2
  25. package/dist-cli/chunks/{chunk-2OPIAGET.js → chunk-CTMPC5DN.js} +4 -2
  26. package/dist-cli/chunks/chunk-D2R7PDN5.js +4 -0
  27. package/dist-cli/chunks/{chunk-JYU5SGXS.js → chunk-DI55E6CS.js} +4 -2
  28. package/dist-cli/chunks/chunk-DUHBRW7J.js +4 -0
  29. package/dist-cli/chunks/chunk-EXTV6NWM.js +74 -0
  30. package/dist-cli/chunks/{chunk-RTA3PINK.js → chunk-FNCSUHUR.js} +3 -1
  31. package/dist-cli/chunks/{chunk-GNK6RVZH.js → chunk-FSRRJGYC.js} +4 -2
  32. package/dist-cli/chunks/{chunk-Z3ZSAYR5.js → chunk-I233T2T4.js} +4 -2
  33. package/dist-cli/chunks/{chunk-2ZTEZVBF.js → chunk-ISJ4ACWL.js} +28 -26
  34. package/dist-cli/chunks/chunk-JFWEDISV.js +120 -0
  35. package/dist-cli/chunks/chunk-JGGXQHXH.js +10 -0
  36. package/dist-cli/chunks/chunk-JUOQ4ZPA.js +7 -0
  37. package/dist-cli/chunks/{chunk-YRA3KKIU.js → chunk-K53YCAQM.js} +3 -1
  38. package/dist-cli/chunks/{chunk-25BLPY4A.js → chunk-KWIURH7N.js} +4 -2
  39. package/dist-cli/chunks/{chunk-3LJBLFEN.js → chunk-N4MT5KEB.js} +5 -3
  40. package/dist-cli/chunks/{chunk-QZGHTJTR.js → chunk-O6I5ZGMY.js} +3 -1
  41. package/dist-cli/chunks/chunk-OKSGM6IG.js +4 -0
  42. package/dist-cli/chunks/chunk-OYYQQBKP.js +3 -0
  43. package/dist-cli/chunks/{chunk-YGGYK2JC.js → chunk-PSOUSJSZ.js} +3 -1
  44. package/dist-cli/chunks/{chunk-Z3USOIFO.js → chunk-PZTKQG6H.js} +4 -2
  45. package/dist-cli/chunks/{chunk-MXIMWWHX.js → chunk-RWUNC66S.js} +4 -2
  46. package/dist-cli/chunks/{chunk-FOJ6PLJY.js → chunk-SLMUW2WU.js} +4 -2
  47. package/dist-cli/chunks/chunk-SPQKJDIK.js +4 -0
  48. package/dist-cli/chunks/{chunk-MFF7EOC3.js → chunk-V2MYTL4C.js} +4 -2
  49. package/dist-cli/chunks/{chunk-JX3BGKKO.js → chunk-VVVORIQI.js} +3 -1
  50. package/dist-cli/chunks/chunk-VXGCZUX4.js +5 -0
  51. package/dist-cli/chunks/chunk-W44PDEQH.js +4 -0
  52. package/dist-cli/chunks/{chunk-WRYUC7SI.js → chunk-WQL3BLFD.js} +3 -1
  53. package/dist-cli/chunks/{chunk-JDKUI77I.js → chunk-WYRLRNIP.js} +4 -2
  54. package/dist-cli/chunks/chunk-XYFP466E.js +12 -0
  55. package/dist-cli/chunks/chunk-ZFMJFX27.js +4 -0
  56. package/dist-cli/chunks/{chunk-RYKAXP3I.js → chunk-ZUX5PIGI.js} +3 -1
  57. package/dist-cli/chunks/{cleanup-HA7KH7UX.js → cleanup-74SKOD2P.js} +4 -2
  58. package/dist-cli/chunks/cli-version-2JGMYL4O.js +4 -0
  59. package/dist-cli/chunks/{compat-ZGFJDYQK.js → compat-ME6HXEEU.js} +5 -3
  60. package/dist-cli/chunks/{config-Y7ECMHD7.js → config-PM67EWT3.js} +4 -2
  61. package/dist-cli/chunks/control-HV7GZXAH.js +4 -0
  62. package/dist-cli/chunks/daemon-LKRHF5OK.js +4 -0
  63. package/dist-cli/chunks/{debug-QQXOPDRB.js → debug-XUGWZLIW.js} +5 -3
  64. package/dist-cli/chunks/{desktop-I4H5RYXR.js → desktop-IO5HPX5Z.js} +5 -3
  65. package/dist-cli/chunks/{detox-4PZM3L5X.js → detox-E42OEJJZ.js} +4 -2
  66. package/dist-cli/chunks/{device-7RBJHWOK.js → device-XA67L2EB.js} +4 -2
  67. package/dist-cli/chunks/{diagnose-VTHQZZUH.js → diagnose-36FD6ECF.js} +4 -2
  68. package/dist-cli/chunks/disk-cleanup-DDCFGFWK.js +4 -0
  69. package/dist-cli/chunks/drivers-C2SH3DWS.js +4 -0
  70. package/dist-cli/chunks/{film-ORXXZQLV.js → film-XARTGFIZ.js} +11 -24
  71. package/dist-cli/chunks/flow-E64G5LF3.js +4 -0
  72. package/dist-cli/chunks/help-4ZSRG4F4.js +4 -0
  73. package/dist-cli/chunks/{hidden-runtime-alias-NKU6KMED.js → hidden-runtime-alias-T4ZALBE2.js} +4 -2
  74. package/dist-cli/chunks/{home-paths-ZQNFMCJT.js → home-paths-5L7N2FLS.js} +4 -2
  75. package/dist-cli/chunks/inspect-U2SV25ER.js +4 -0
  76. package/dist-cli/chunks/install-desktop-LTGVT7ID.js +4 -0
  77. package/dist-cli/chunks/{login-WSEJPYO5.js → login-GF6WVVER.js} +6 -4
  78. package/dist-cli/chunks/logout-6F6UKUNI.js +4 -0
  79. package/dist-cli/chunks/{maestro-VNHC7VCY.js → maestro-FMPKHEMX.js} +13 -11
  80. package/dist-cli/chunks/{maestro-generate-UXQ5CSQQ.js → maestro-generate-QGPGNXI6.js} +5 -3
  81. package/dist-cli/chunks/{mode-TAWHH4KY.js → mode-JSNMAHDZ.js} +4 -2
  82. package/dist-cli/chunks/optional-demo-registry-K4VERLJV.js +4 -0
  83. package/dist-cli/chunks/{perf-7MB6JVO2.js → perf-PO7ARUTG.js} +4 -2
  84. package/dist-cli/chunks/permissions-XI2QUAEZ.js +13 -0
  85. package/dist-cli/chunks/{record-B27J7UAA.js → record-4CJCJAFD.js} +5 -3
  86. package/dist-cli/chunks/runtime-SN2RWDES.js +4 -0
  87. package/dist-cli/chunks/{screenshot-command-SBOYWN5Y.js → screenshot-command-NDVULWMZ.js} +5 -3
  88. package/dist-cli/chunks/{screenshots-capture-YPO27U4Q.js → screenshots-capture-Q7UTXF3V.js} +4 -2
  89. package/dist-cli/chunks/{serve-6XIKRRFE.js → serve-UEUIBHCK.js} +4 -2
  90. package/dist-cli/chunks/{setup-KE2ZIKBX.js → setup-ZEEWYK4B.js} +5 -3
  91. package/dist-cli/chunks/{skills-PFVZURZR.js → skills-NFG6VAO5.js} +4 -2
  92. package/dist-cli/chunks/{storage-WIKXL2DP.js → storage-POWCOUCQ.js} +4 -2
  93. package/dist-cli/chunks/store-BJK7V7FL.js +4 -0
  94. package/dist-cli/chunks/telemetry-EJP5EW7K.js +4 -0
  95. package/dist-cli/chunks/{timeline-6QZ4ETR3.js → timeline-MNHZCVAL.js} +4 -2
  96. package/dist-cli/chunks/{upgrade-VUF4MTIC.js → upgrade-X57SIG7L.js} +4 -2
  97. package/dist-cli/chunks/upload-JABM3ITZ.js +4 -0
  98. package/dist-cli/chunks/{version-5QONKRGH.js → version-V4IKIDX7.js} +4 -2
  99. package/dist-cli/chunks/web-F5CLF34I.js +4 -0
  100. package/dist-cli/chunks/{what-happened-MYETIVUB.js → what-happened-H74HHGRK.js} +4 -2
  101. package/dist-lib/agent-daemon-client.cjs +1 -1
  102. package/dist-lib/agent-events.cjs +1 -1
  103. package/dist-lib/agent-identity.cjs +3 -3
  104. package/dist-lib/agent-sessions.cjs +1 -1
  105. package/dist-lib/attached-projects.cjs +1 -1
  106. package/dist-lib/auth/shared-session.cjs +1 -1
  107. package/dist-lib/backend-origin.cjs +1 -1
  108. package/dist-lib/beta.cjs +1 -1
  109. package/dist-lib/beta.mjs +1 -1
  110. package/dist-lib/bridge-constants.cjs +1 -1
  111. package/dist-lib/cli-constants.cjs +1 -1
  112. package/dist-lib/config.cjs +1 -1
  113. package/dist-lib/detox/index.cjs +5 -4
  114. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  115. package/dist-lib/home-paths.cjs +1 -1
  116. package/dist-lib/host/bridge-host.cjs +413 -68
  117. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  118. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  119. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  120. package/dist-lib/host/websocket-proxy.cjs +1 -1
  121. package/dist-lib/index.cjs +1 -1
  122. package/dist-lib/jump-to-source-babel.cjs +1 -1
  123. package/dist-lib/menu.cjs +75 -4
  124. package/dist-lib/menu.mjs +72 -4
  125. package/dist-lib/metro.cjs +1 -1
  126. package/dist-lib/profiles.cjs +1 -1
  127. package/dist-lib/render-mode.cjs +1 -1
  128. package/dist-lib/scripts/dev-server-scanner.cjs +354 -2
  129. package/dist-lib/sdk.cjs +5 -2
  130. package/dist-lib/sdk.mjs +4 -2
  131. package/dist-lib/skills.cjs +767 -272
  132. package/dist-lib/vite.cjs +1 -1
  133. package/package.json +7 -1
  134. package/scripts/dev-server-scanner.ts +27 -1
  135. package/scripts/postinstall.cjs +11 -2
  136. package/skills/contrast/SKILL.md +1 -0
  137. package/src/agent-identity.ts +2 -2
  138. package/src/menu.ts +83 -4
  139. package/src/settings-bundle.ts +439 -0
  140. package/src/vite-plugin.ts +102 -2
  141. package/dist-cli/chunks/beta-LXTSQC5F.js +0 -2
  142. package/dist-cli/chunks/chunk-2S6PCP7Q.js +0 -8
  143. package/dist-cli/chunks/chunk-34JU3Y6V.js +0 -118
  144. package/dist-cli/chunks/chunk-6JTRQCRD.js +0 -2
  145. package/dist-cli/chunks/chunk-AE2V5YSY.js +0 -72
  146. package/dist-cli/chunks/chunk-D4UFVQZ7.js +0 -5
  147. package/dist-cli/chunks/chunk-GH5IVTEH.js +0 -2
  148. package/dist-cli/chunks/chunk-I6LKLLP5.js +0 -2
  149. package/dist-cli/chunks/chunk-J5XOFF7C.js +0 -1
  150. package/dist-cli/chunks/chunk-JVCPDNHG.js +0 -2
  151. package/dist-cli/chunks/chunk-LDANZSMQ.js +0 -2
  152. package/dist-cli/chunks/chunk-MWPVLUE4.js +0 -2
  153. package/dist-cli/chunks/chunk-SFXJGGYK.js +0 -5
  154. package/dist-cli/chunks/chunk-T5F7EAKY.js +0 -2
  155. package/dist-cli/chunks/chunk-U42EWZZX.js +0 -2
  156. package/dist-cli/chunks/chunk-ZK2ECNH3.js +0 -2
  157. package/dist-cli/chunks/cli-version-H4A6RWGG.js +0 -2
  158. package/dist-cli/chunks/control-ZMSUHFS6.js +0 -2
  159. package/dist-cli/chunks/daemon-KUZGYUC5.js +0 -2
  160. package/dist-cli/chunks/disk-cleanup-FSW4J2ZZ.js +0 -2
  161. package/dist-cli/chunks/drivers-ZCDNP2VP.js +0 -2
  162. package/dist-cli/chunks/flow-GXK7MFAS.js +0 -2
  163. package/dist-cli/chunks/help-6MTAEVY6.js +0 -2
  164. package/dist-cli/chunks/inspect-TRR5AXJJ.js +0 -2
  165. package/dist-cli/chunks/install-desktop-H4VCPRLA.js +0 -2
  166. package/dist-cli/chunks/logout-NRGYAXYA.js +0 -2
  167. package/dist-cli/chunks/optional-demo-registry-RFZZISD6.js +0 -2
  168. package/dist-cli/chunks/runtime-WT7GEBL6.js +0 -2
  169. package/dist-cli/chunks/store-SHY2R3KN.js +0 -2
  170. package/dist-cli/chunks/telemetry-JISXG5P6.js +0 -2
  171. package/dist-cli/chunks/upload-SFFK5MJ6.js +0 -2
  172. package/dist-cli/chunks/web-DRQ3SAD4.js +0 -2
package/dist-lib/vite.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.292 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.294 | (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;
package/package.json CHANGED
@@ -1,9 +1,14 @@
1
1
  {
2
2
  "name": "sootsim",
3
- "version": "0.1.292",
3
+ "version": "0.1.294",
4
4
  "description": "sootsim CLI + vite/metro plugins + skills registry. bridge client for driving the proprietary sootsim-engine over WebSocket.",
5
5
  "author": "Tamagui LLC",
6
6
  "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/sootbean/soot.git",
10
+ "directory": "packages/sootsim"
11
+ },
7
12
  "type": "module",
8
13
  "publishConfig": {
9
14
  "access": "public"
@@ -163,6 +168,7 @@
163
168
  "preuninstall": "node ./scripts/preuninstall.cjs"
164
169
  },
165
170
  "dependencies": {
171
+ "@expo/plist": "^0.5.4",
166
172
  "ws": "^8.18.0"
167
173
  },
168
174
  "peerDependencies": {
@@ -17,10 +17,15 @@ import { exec } from 'child_process'
17
17
  import http from 'http'
18
18
  import net from 'net'
19
19
  import { promisify } from 'util'
20
+ import type { AppSettingsSpecifier } from '@sootsim/globals'
20
21
 
21
22
  const execP = promisify(exec)
22
23
  import { applySootSimConfigToUrl } from '../src/config.ts'
23
24
  import { normalizeNativeDevBundleUrl } from '../src/native-dev-bundle-url.ts'
25
+ import {
26
+ __resetAppSettingsBundleCacheForTests,
27
+ readAppSettingsBundle,
28
+ } from '../src/settings-bundle.ts'
24
29
  import { loadOptionalDemoApps, optionalDemoAppsSync } from './optional-demo-registry.ts'
25
30
 
26
31
  // pre-warm the optional internal demo registry once at module load. in-repo
@@ -41,6 +46,8 @@ export interface DiscoveredServer {
41
46
  iconUrl?: string
42
47
  iconPath?: string
43
48
  bundleId?: string
49
+ settingsBundle?: readonly AppSettingsSpecifier[]
50
+ settingsStorageScopeUrl?: string
44
51
  patched?: boolean
45
52
  /** absolute cwd of the owning node/bun process — resolved from `lsof -d cwd`
46
53
  * when the scanner can see the pid. used to auto-attach the project for
@@ -709,8 +716,25 @@ export function __resetScannerCache() {
709
716
  knownOne.clear()
710
717
  enrichmentCache.clear()
711
718
  enrichmentInFlight.clear()
719
+ __resetAppSettingsBundleCacheForTests()
712
720
  }
713
721
 
722
+ async function attachAppSettingsBundle(
723
+ result: DiscoveredServer,
724
+ projectRoot: string,
725
+ ): Promise<void> {
726
+ const settingsBundle = await readAppSettingsBundle(projectRoot)
727
+ if (settingsBundle) {
728
+ result.settingsBundle = settingsBundle
729
+ result.settingsStorageScopeUrl = result.bundleUrl
730
+ } else {
731
+ delete result.settingsBundle
732
+ delete result.settingsStorageScopeUrl
733
+ }
734
+ }
735
+
736
+ export const __attachAppSettingsBundleForTests = attachAppSettingsBundle
737
+
714
738
  export async function scanDevServers(
715
739
  opts: ScanOptions = {},
716
740
  ): Promise<DiscoveredServer[]> {
@@ -796,7 +820,9 @@ export async function scanDevServers(
796
820
  if (!pid) return
797
821
  result.pid = pid
798
822
  const cwd = await resolveProcessCwd(pid)
799
- if (cwd) result.cwd = cwd
823
+ if (!cwd) return
824
+ result.cwd = cwd
825
+ await attachAppSettingsBundle(result, cwd)
800
826
  }),
801
827
  )
802
828
  // evict stale cwd cache entries for pids no longer listening
@@ -42,13 +42,22 @@ if (existingActiveRuntime) {
42
42
  process.exit(0)
43
43
  }
44
44
 
45
+ const RUNTIME_INSTALL_TIMEOUT_MS = 60_000
46
+
45
47
  const bin = path.join(__dirname, '..', 'dist-cli', 'bin.js')
46
48
  const res = spawnSync(process.execPath, [bin, 'runtime', 'install'], {
47
49
  stdio: 'inherit',
48
- timeout: 60_000,
50
+ timeout: RUNTIME_INSTALL_TIMEOUT_MS,
49
51
  })
50
52
 
51
- if (res.status !== 0) {
53
+ if (res.error && res.error.code === 'ETIMEDOUT') {
54
+ // the runtime tarball is ~48MB; on a slow link it does not finish inside the
55
+ // npm-install budget above. say that plainly instead of implying we chose to
56
+ // defer — the user has to run the install themselves for it to complete.
57
+ console.log(
58
+ `sootsim: runtime download did not finish within ${RUNTIME_INSTALL_TIMEOUT_MS / 1000}s, so npm install could return — run \`sootsim upgrade\` to finish it`,
59
+ )
60
+ } else if (res.status !== 0) {
52
61
  console.log('sootsim: runtime install deferred to first run')
53
62
  }
54
63
  process.exit(0)
@@ -25,6 +25,7 @@ automation, inspecting the render tree, and managing sims.
25
25
  | `sootsim record` | capture the live sim as webm/mp4/gif, or sample N png frames (--frames) |
26
26
  | `sootsim film` | record a flow on the flat canvas, replay it on the 3d device stage under a camera cinematic, save a clip |
27
27
  | `sootsim storage` | manage guest app storage and launch profiles |
28
+ | `sootsim permissions` | inspect and change simulated operating-system permissions |
28
29
  | `sootsim perf` | CPU, React render, shell frame, and scroll-layer profiling |
29
30
  | `sootsim describe` | curated human-readable UI summary (default inspection tool) |
30
31
  | `sootsim find` | locate nodes by text / testID / role / type / predicate |
@@ -12,8 +12,8 @@ export function agentSessionIdFromCliIdentity(identity: string | null): string |
12
12
  export function teamMachineSessionIdFromCliIdentity(
13
13
  identity: string | null,
14
14
  ): string | null {
15
- if (!identity?.startsWith('AGENTBUS_SESSION:')) return null
16
- const sessionId = identity.slice('AGENTBUS_SESSION:'.length).trim()
15
+ if (!identity?.startsWith('TM_SESSION:')) return null
16
+ const sessionId = identity.slice('TM_SESSION:'.length).trim()
17
17
  if (!TEAM_MACHINE_SESSION_RE.test(sessionId)) return null
18
18
  return sessionId
19
19
  }
package/src/menu.ts CHANGED
@@ -7,6 +7,26 @@ export const SOOTSIM_SHELL_COMMAND_NAME = 'sootsim:shell-command'
7
7
  export type SootSimMenuPlatform = 'browser' | 'electron'
8
8
  export type SootSimScaleMode = 'physical' | 'point' | 'pixel' | 'fit'
9
9
 
10
+ // ambient glow strength. one setting with three states rather than an on/off
11
+ // pair plus a separate strength: every host that carries the preference (the
12
+ // menus, the persisted setting, the ?ambientGlow= boot seed, the live
13
+ // set-ambient-glow push, electron's shared config) then carries exactly one
14
+ // value and cannot end up half-configured.
15
+ export type SootSimAmbientGlowLevel = 'off' | 'soft' | 'full'
16
+ export const SOOTSIM_AMBIENT_GLOW_LEVELS = ['off', 'soft', 'full'] as const
17
+
18
+ export function isSootSimAmbientGlowLevel(
19
+ value: unknown,
20
+ ): value is SootSimAmbientGlowLevel {
21
+ return value === 'off' || value === 'soft' || value === 'full'
22
+ }
23
+
24
+ export const SOOTSIM_AMBIENT_GLOW_LABELS: Record<SootSimAmbientGlowLevel, string> = {
25
+ off: 'Off',
26
+ soft: 'Soft',
27
+ full: 'Full',
28
+ }
29
+
10
30
  export type SootSimMenuItemDef =
11
31
  | { type: 'separator' }
12
32
  | {
@@ -35,8 +55,10 @@ export type SootSimMenuDef = {
35
55
  export interface SootSimMenuState {
36
56
  currentDevice: string
37
57
  showBezels: boolean
38
- showTopBar: boolean
58
+ showMenuBar: boolean
39
59
  showRail: boolean
60
+ solidWindow: boolean
61
+ ambientGlow: SootSimAmbientGlowLevel
40
62
  screenshotMode: boolean
41
63
  threeMode: boolean
42
64
  inspectMode: boolean
@@ -73,6 +95,7 @@ export interface SootSimShortcutDocSection {
73
95
  export type MenuItemDef = SootSimMenuItemDef
74
96
  export type MenuDef = SootSimMenuDef
75
97
  export type MenuState = SootSimMenuState
98
+ export type AmbientGlowLevel = SootSimAmbientGlowLevel
76
99
  export type ShortcutPlatform = SootSimMenuPlatform
77
100
  export type MenuShortcutEntry = SootSimMenuShortcutEntry
78
101
  export type ShortcutDocEntry = SootSimShortcutDocEntry
@@ -108,6 +131,36 @@ function appMenu(): SootSimMenuDef {
108
131
  shortcutLabel: 'settings',
109
132
  showInShortcutDocs: true,
110
133
  },
134
+ {
135
+ label: 'Settings Pages',
136
+ items: [
137
+ {
138
+ label: 'Accessibility',
139
+ action: 'open-settings-page',
140
+ actionPayload: 'accessibility',
141
+ },
142
+ {
143
+ label: 'Display & Text Size',
144
+ action: 'open-settings-page',
145
+ actionPayload: 'display-and-text-size',
146
+ },
147
+ {
148
+ label: 'Notifications',
149
+ action: 'open-settings-page',
150
+ actionPayload: 'notifications',
151
+ },
152
+ {
153
+ label: 'Apps',
154
+ action: 'open-settings-page',
155
+ actionPayload: 'apps',
156
+ },
157
+ {
158
+ label: 'Privacy & Security',
159
+ action: 'open-settings-page',
160
+ actionPayload: 'privacy',
161
+ },
162
+ ],
163
+ },
111
164
  { type: 'separator' },
112
165
  {
113
166
  label: 'Hide SootSim',
@@ -336,10 +389,11 @@ function windowMenu(state: SootSimMenuState): SootSimMenuDef {
336
389
  action: 'toggle-bezels',
337
390
  },
338
391
  {
339
- label: 'Show Top Bar',
392
+ label: 'Show Menu Bar',
340
393
  type: 'checkbox',
341
- checked: state.showTopBar,
342
- action: 'toggle-topbar',
394
+ checked: state.showMenuBar,
395
+ action: 'toggle-menubar',
396
+ hiddenIn: 'electron',
343
397
  },
344
398
  {
345
399
  label: 'Show Rail',
@@ -348,6 +402,31 @@ function windowMenu(state: SootSimMenuState): SootSimMenuDef {
348
402
  action: 'toggle-rail',
349
403
  hiddenIn: 'electron',
350
404
  },
405
+ {
406
+ // desktop only. the device window is frameless and transparent, which
407
+ // is right for a phone floating on the desktop and wrong for the
408
+ // full-window modes; this pins the solid style on all the time. 3d
409
+ // mode switches to it on its own either way.
410
+ label: 'Solid Window',
411
+ type: 'checkbox',
412
+ checked: state.solidWindow,
413
+ action: 'toggle-solid-window',
414
+ hiddenIn: 'browser',
415
+ },
416
+ {
417
+ // browser only: the wash needs several glow radii of stage around the
418
+ // device to fade out in, and electron's transparent window is sized to
419
+ // the device, so there it can only paint a clipped rectangle.
420
+ label: 'Ambient Glow',
421
+ hiddenIn: 'electron',
422
+ items: SOOTSIM_AMBIENT_GLOW_LEVELS.map((level) => ({
423
+ label: SOOTSIM_AMBIENT_GLOW_LABELS[level],
424
+ type: 'radio' as const,
425
+ checked: state.ambientGlow === level,
426
+ action: 'set-ambient-glow',
427
+ actionPayload: level,
428
+ })),
429
+ },
351
430
  {
352
431
  label: 'Screenshot',
353
432
  type: 'checkbox',