sootsim 0.1.268 → 0.1.270

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 (155) hide show
  1. package/README.md +7 -3
  2. package/detox/index.ts +5 -2
  3. package/dist-cli/bin.js +4 -4
  4. package/dist-cli/chunks/{agent-KQSZFG6R.js → agent-4YXUPSJ2.js} +2 -2
  5. package/dist-cli/chunks/{agent-wrapper-DLDQVS7O.js → agent-wrapper-BMJPWHWK.js} +2 -2
  6. package/dist-cli/chunks/{app-fonts-6XVNNHAB.js → app-fonts-EDRH6ETC.js} +2 -2
  7. package/dist-cli/chunks/{assert-DLGUW4JS.js → assert-CRDV324D.js} +2 -2
  8. package/dist-cli/chunks/{auth-MTSJWWMS.js → auth-WYRQIJEN.js} +2 -2
  9. package/dist-cli/chunks/beta-NBANSL2S.js +2 -0
  10. package/dist-cli/chunks/{camera-MGJUBHWZ.js → camera-5TO6IVBP.js} +3 -3
  11. package/dist-cli/chunks/{chunk-LJGOZ77E.js → chunk-2J3E5TPS.js} +1 -1
  12. package/dist-cli/chunks/{chunk-GUXMUE5A.js → chunk-3VIMSXQZ.js} +2 -2
  13. package/dist-cli/chunks/{chunk-YUDUKMJV.js → chunk-3ZOF2BTJ.js} +1 -1
  14. package/dist-cli/chunks/{chunk-RCU4A7LU.js → chunk-44ISBOEK.js} +3 -3
  15. package/dist-cli/chunks/{chunk-F7DMZRQX.js → chunk-4HPWZVBS.js} +1 -1
  16. package/dist-cli/chunks/{chunk-K5ZMEBMQ.js → chunk-557IYHPC.js} +1 -1
  17. package/dist-cli/chunks/{chunk-RG6QF6DY.js → chunk-5IHDZOMR.js} +1 -1
  18. package/dist-cli/chunks/{chunk-XIBSRCKK.js → chunk-6CI73D3X.js} +2 -2
  19. package/dist-cli/chunks/chunk-6JLIPPNB.js +2 -0
  20. package/dist-cli/chunks/{chunk-YMTVQA6W.js → chunk-74HIBIJQ.js} +4 -4
  21. package/dist-cli/chunks/{chunk-6TXGR4HK.js → chunk-ABSUFSOH.js} +2 -2
  22. package/dist-cli/chunks/{chunk-NPSDN7D7.js → chunk-AG563BSO.js} +2 -2
  23. package/dist-cli/chunks/{chunk-IWJTCFAE.js → chunk-AMA3YGJ5.js} +2 -2
  24. package/dist-cli/chunks/{chunk-EG3JCOGS.js → chunk-AMVYE3F4.js} +2 -2
  25. package/dist-cli/chunks/{chunk-LOOHTTDV.js → chunk-B5IBLYEO.js} +3 -3
  26. package/dist-cli/chunks/{chunk-M2LYCMW4.js → chunk-DCJXHSIA.js} +2 -2
  27. package/dist-cli/chunks/{chunk-ITQ7WKNC.js → chunk-ERXCR7NU.js} +2 -2
  28. package/dist-cli/chunks/{chunk-KR4LGQWN.js → chunk-FCMEOOQE.js} +2 -2
  29. package/dist-cli/chunks/{chunk-YNMYUJYR.js → chunk-FHPXOPMC.js} +2 -2
  30. package/dist-cli/chunks/{chunk-V27FSRID.js → chunk-FNBFRG64.js} +1 -1
  31. package/dist-cli/chunks/{chunk-5JH5F4TM.js → chunk-GAYG7AO4.js} +1 -1
  32. package/dist-cli/chunks/chunk-GQDQO3KU.js +5 -0
  33. package/dist-cli/chunks/{chunk-JERNRAFO.js → chunk-HWGKGIWE.js} +2 -2
  34. package/dist-cli/chunks/{chunk-YLMP3AEX.js → chunk-IIXRM6BB.js} +2 -2
  35. package/dist-cli/chunks/{chunk-EPKHW3XW.js → chunk-LHMVSKKD.js} +3 -3
  36. package/dist-cli/chunks/chunk-M32JVXHU.js +5 -0
  37. package/dist-cli/chunks/{chunk-FGKDYXO3.js → chunk-M5VURHXD.js} +1 -1
  38. package/dist-cli/chunks/{chunk-6YB3URLB.js → chunk-MD24VVKT.js} +2 -2
  39. package/dist-cli/chunks/{chunk-CWC7QMVM.js → chunk-MYBY7OHL.js} +1 -1
  40. package/dist-cli/chunks/{chunk-7XWLSCXZ.js → chunk-NTO6SKS5.js} +1 -1
  41. package/dist-cli/chunks/{chunk-H2WCONSC.js → chunk-OUKH6UGN.js} +1 -1
  42. package/dist-cli/chunks/{chunk-OOVGROTR.js → chunk-PDFKRVDC.js} +1 -1
  43. package/dist-cli/chunks/{chunk-74QJWGDX.js → chunk-SDKIUJUO.js} +2 -2
  44. package/dist-cli/chunks/chunk-SLR3HWMB.js +13 -0
  45. package/dist-cli/chunks/{chunk-WUOPQL2J.js → chunk-SW5HZ5LK.js} +1 -1
  46. package/dist-cli/chunks/{chunk-WT3OYHU7.js → chunk-TIONGRTA.js} +3 -3
  47. package/dist-cli/chunks/{chunk-EH3A54PO.js → chunk-TLNGREAA.js} +2 -2
  48. package/dist-cli/chunks/{chunk-5MIRQ65V.js → chunk-TMWNOQAA.js} +1 -1
  49. package/dist-cli/chunks/{chunk-3MZJ2KVR.js → chunk-TZH4VH32.js} +3 -3
  50. package/dist-cli/chunks/{chunk-FGY5ESGU.js → chunk-UPRCATUH.js} +2 -2
  51. package/dist-cli/chunks/chunk-XTTXSDDA.js +1 -0
  52. package/dist-cli/chunks/{chunk-ZTOWO5CK.js → chunk-YKK2QUGO.js} +1 -1
  53. package/dist-cli/chunks/{chunk-SV6D5FXN.js → chunk-ZTKDHPA6.js} +2 -2
  54. package/dist-cli/chunks/chunk-ZZH2AFPJ.js +1 -0
  55. package/dist-cli/chunks/cli-version-BLKUTVJ2.js +2 -0
  56. package/dist-cli/chunks/{compat-IVBKZVGH.js → compat-IZEDAAUW.js} +3 -3
  57. package/dist-cli/chunks/{config-PQ3KBTIM.js → config-I4CXZ6M7.js} +2 -2
  58. package/dist-cli/chunks/{control-BKTYM5XP.js → control-DVF7UL5D.js} +2 -2
  59. package/dist-cli/chunks/daemon-FPKQPSSY.js +2 -0
  60. package/dist-cli/chunks/{debug-HRR2LK2J.js → debug-5X2F2WRP.js} +3 -3
  61. package/dist-cli/chunks/{desktop-466O4AQA.js → desktop-JHEYQZGF.js} +3 -3
  62. package/dist-cli/chunks/{detox-UH44KHQJ.js → detox-W64UENQG.js} +2 -2
  63. package/dist-cli/chunks/{device-FZLXTC3W.js → device-ZBSW2EHS.js} +2 -2
  64. package/dist-cli/chunks/{diagnose-RJMRI27P.js → diagnose-WER4X3P5.js} +2 -2
  65. package/dist-cli/chunks/drivers-6P53DLMM.js +2 -0
  66. package/dist-cli/chunks/{film-VL66UAM3.js → film-TIXNUTR6.js} +3 -3
  67. package/dist-cli/chunks/flow-53XFDYLL.js +2 -0
  68. package/dist-cli/chunks/help-MPYJLD7I.js +2 -0
  69. package/dist-cli/chunks/{hidden-runtime-alias-3ZAR7GCH.js → hidden-runtime-alias-R3JH3INM.js} +2 -2
  70. package/dist-cli/chunks/{home-paths-S2GRJWV3.js → home-paths-CNNARPCT.js} +2 -2
  71. package/dist-cli/chunks/inspect-JBDDYUA5.js +2 -0
  72. package/dist-cli/chunks/install-desktop-BBP7AMK4.js +2 -0
  73. package/dist-cli/chunks/{login-TR3YAEA2.js → login-6NCCZ3CZ.js} +4 -4
  74. package/dist-cli/chunks/{logout-WPY2DOYZ.js → logout-C4VKXUH4.js} +2 -2
  75. package/dist-cli/chunks/{maestro-DSG7V2BA.js → maestro-ZRGFQ3MV.js} +3 -3
  76. package/dist-cli/chunks/{maestro-generate-6KA7PCN5.js → maestro-generate-A5XZS5GC.js} +3 -3
  77. package/dist-cli/chunks/{mode-QUYGPNBW.js → mode-IFFZ55HM.js} +2 -2
  78. package/dist-cli/chunks/optional-demo-registry-TQZA65K3.js +2 -0
  79. package/dist-cli/chunks/{perf-ELBRUVVU.js → perf-44KZNTIV.js} +2 -2
  80. package/dist-cli/chunks/{record-6PDTULUN.js → record-GZLZNXYZ.js} +3 -3
  81. package/dist-cli/chunks/runtime-F4FCEPPB.js +2 -0
  82. package/dist-cli/chunks/{screenshot-command-E2A4VY6D.js → screenshot-command-GL3STSWK.js} +3 -3
  83. package/dist-cli/chunks/{screenshots-capture-TRCRHK2E.js → screenshots-capture-QSSBWHN6.js} +2 -2
  84. package/dist-cli/chunks/serve-AFK6X2Q3.js +42 -0
  85. package/dist-cli/chunks/{setup-5BHQNK2L.js → setup-DYSDNEUE.js} +3 -3
  86. package/dist-cli/chunks/{skills-NQLI6WXW.js → skills-YXWQ43PZ.js} +2 -2
  87. package/dist-cli/chunks/{storage-SKARYTYK.js → storage-C7IS5GTM.js} +2 -2
  88. package/dist-cli/chunks/store-LVF2C2XZ.js +2 -0
  89. package/dist-cli/chunks/telemetry-5V3OXY6C.js +2 -0
  90. package/dist-cli/chunks/{timeline-DYJ4GKGE.js → timeline-FDTIHQ5V.js} +2 -2
  91. package/dist-cli/chunks/{upgrade-PHUUE5QV.js → upgrade-VRQCFJEI.js} +2 -2
  92. package/dist-cli/chunks/upload-CRCPDN6G.js +2 -0
  93. package/dist-cli/chunks/{version-XQQSXS3E.js → version-MP6NKJ27.js} +2 -2
  94. package/dist-cli/chunks/web-XYPFJHKW.js +2 -0
  95. package/dist-cli/chunks/{what-happened-I2N3FFIV.js → what-happened-IM6UH24Q.js} +2 -2
  96. package/dist-lib/agent-daemon-client.cjs +1 -1
  97. package/dist-lib/agent-events.cjs +1 -1
  98. package/dist-lib/agent-identity.cjs +10 -10
  99. package/dist-lib/agent-sessions.cjs +29 -13
  100. package/dist-lib/attached-projects.cjs +33 -13
  101. package/dist-lib/auth/shared-session.cjs +1 -1
  102. package/dist-lib/backend-origin.cjs +1 -1
  103. package/dist-lib/beta.cjs +1 -1
  104. package/dist-lib/beta.mjs +1 -1
  105. package/dist-lib/bridge-constants.cjs +23 -6
  106. package/dist-lib/cli-constants.cjs +1 -1
  107. package/dist-lib/config.cjs +1 -1
  108. package/dist-lib/detox/index.cjs +6 -4
  109. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  110. package/dist-lib/home-paths.cjs +1 -1
  111. package/dist-lib/host/bridge-host.cjs +110 -54
  112. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  113. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  114. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  115. package/dist-lib/host/websocket-proxy.cjs +1 -1
  116. package/dist-lib/index.cjs +1 -1
  117. package/dist-lib/jump-to-source-babel.cjs +1 -1
  118. package/dist-lib/menu.cjs +1 -1
  119. package/dist-lib/menu.mjs +1 -1
  120. package/dist-lib/metro.cjs +1 -1
  121. package/dist-lib/profiles.cjs +1 -1
  122. package/dist-lib/render-mode.cjs +1 -1
  123. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  124. package/dist-lib/sdk.cjs +1 -1
  125. package/dist-lib/sdk.mjs +1 -1
  126. package/dist-lib/skills.cjs +220 -148
  127. package/dist-lib/vite.cjs +1 -1
  128. package/package.json +1 -1
  129. package/src/agent-daemon-client.ts +2 -2
  130. package/src/agent-identity.ts +7 -5
  131. package/src/attached-projects.ts +35 -11
  132. package/src/bridge-constants.ts +23 -4
  133. package/src/host/agent-host.ts +63 -14
  134. package/src/{agentbus-prompt.ts → team-machine-prompt.ts} +13 -20
  135. package/dist-cli/chunks/beta-7R4DRB3R.js +0 -2
  136. package/dist-cli/chunks/chunk-2LWDKYJ3.js +0 -1
  137. package/dist-cli/chunks/chunk-346C7547.js +0 -2
  138. package/dist-cli/chunks/chunk-CD2GF6PV.js +0 -5
  139. package/dist-cli/chunks/chunk-PN2LR6T4.js +0 -5
  140. package/dist-cli/chunks/chunk-Y3IYHVEX.js +0 -13
  141. package/dist-cli/chunks/chunk-ZHSXFJ7W.js +0 -1
  142. package/dist-cli/chunks/cli-version-362THKXA.js +0 -2
  143. package/dist-cli/chunks/daemon-SCTA3HTZ.js +0 -2
  144. package/dist-cli/chunks/drivers-S7D5OZQN.js +0 -2
  145. package/dist-cli/chunks/flow-IM5OXO5S.js +0 -2
  146. package/dist-cli/chunks/help-G5CN3KXU.js +0 -2
  147. package/dist-cli/chunks/inspect-WI7GXOH5.js +0 -2
  148. package/dist-cli/chunks/install-desktop-PVBWQQHY.js +0 -2
  149. package/dist-cli/chunks/optional-demo-registry-CROVHXTW.js +0 -2
  150. package/dist-cli/chunks/runtime-ITR3EUXS.js +0 -2
  151. package/dist-cli/chunks/serve-JLLSEZDN.js +0 -41
  152. package/dist-cli/chunks/store-VR5QRAYX.js +0 -2
  153. package/dist-cli/chunks/telemetry-PMYZDJGO.js +0 -2
  154. package/dist-cli/chunks/upload-OUKKXVNC.js +0 -2
  155. package/dist-cli/chunks/web-AZI3JODI.js +0 -2
package/dist-lib/vite.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! sootsim v0.1.268 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! sootsim v0.1.270 | (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,6 +1,6 @@
1
1
  {
2
2
  "name": "sootsim",
3
- "version": "0.1.268",
3
+ "version": "0.1.270",
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",
@@ -168,8 +168,8 @@ export class AgentDaemonClient {
168
168
  async sendClaimedPrompt(
169
169
  simId: string,
170
170
  prompt: AgentPromptEnvelope,
171
- ): Promise<{ ok: true; routed: 'agentbus'; sessionId: string }> {
172
- return this.send<{ ok: true; routed: 'agentbus'; sessionId: string }>(
171
+ ): Promise<{ ok: true; routed: 'team-machine'; sessionId: string }> {
172
+ return this.send<{ ok: true; routed: 'team-machine'; sessionId: string }>(
173
173
  'agent:send-claimed-prompt',
174
174
  {
175
175
  simId,
@@ -1,4 +1,4 @@
1
- const AGENTBUS_SESSION_RE = /^[A-Za-z0-9._:-]{1,160}$/
1
+ const TEAM_MACHINE_SESSION_RE = /^[A-Za-z0-9._:-]{1,160}$/
2
2
 
3
3
  export function agentSessionIdFromCliIdentity(identity: string | null): string | null {
4
4
  if (!identity) return null
@@ -9,13 +9,15 @@ export function agentSessionIdFromCliIdentity(identity: string | null): string |
9
9
  return source === 'SOOTSIM_CLI_IDENTITY' && value ? value : null
10
10
  }
11
11
 
12
- export function agentbusSessionIdFromCliIdentity(identity: string | null): string | null {
12
+ export function teamMachineSessionIdFromCliIdentity(
13
+ identity: string | null,
14
+ ): string | null {
13
15
  if (!identity?.startsWith('AGENTBUS_SESSION:')) return null
14
16
  const sessionId = identity.slice('AGENTBUS_SESSION:'.length).trim()
15
- if (!AGENTBUS_SESSION_RE.test(sessionId)) return null
17
+ if (!TEAM_MACHINE_SESSION_RE.test(sessionId)) return null
16
18
  return sessionId
17
19
  }
18
20
 
19
- export function isValidAgentbusSessionId(sessionId: string): boolean {
20
- return AGENTBUS_SESSION_RE.test(sessionId)
21
+ export function isValidTeamMachineSessionId(sessionId: string): boolean {
22
+ return TEAM_MACHINE_SESSION_RE.test(sessionId)
21
23
  }
@@ -406,22 +406,46 @@ export function listSessions(projectId?: string): AgentSession[] {
406
406
  return projectId ? all.filter((s) => s.projectId === projectId) : all
407
407
  }
408
408
 
409
- export function updateSessionStatus(id: string, patch: Partial<AgentSession>): void {
409
+ export function applySessionStatusPatch(
410
+ existing: AgentSession,
411
+ patch: Partial<AgentSession>,
412
+ now = Date.now(),
413
+ ): AgentSession {
414
+ return {
415
+ ...existing,
416
+ ...patch,
417
+ id: existing.id,
418
+ projectId: existing.projectId,
419
+ createdAt: existing.createdAt,
420
+ lastSeenAt: now,
421
+ }
422
+ }
423
+
424
+ export function updateSessionStatuses(
425
+ updates: ReadonlyArray<{ id: string; patch: Partial<AgentSession> }>,
426
+ ): void {
427
+ if (updates.length === 0) return
410
428
  mutateStore((store) => {
411
- const existing = store.agentSessions.find((s) => s.id === id)
412
- if (!existing) return
413
- const idx = store.agentSessions.indexOf(existing)
414
- store.agentSessions[idx] = {
415
- ...existing,
416
- ...patch,
417
- id: existing.id,
418
- projectId: existing.projectId,
419
- createdAt: existing.createdAt,
420
- lastSeenAt: Date.now(),
429
+ const now = Date.now()
430
+ const indexById = new Map(
431
+ store.agentSessions.map((session, index) => [session.id, index]),
432
+ )
433
+ for (const { id, patch } of updates) {
434
+ const idx = indexById.get(id)
435
+ if (idx === undefined) continue
436
+ store.agentSessions[idx] = applySessionStatusPatch(
437
+ store.agentSessions[idx]!,
438
+ patch,
439
+ now,
440
+ )
421
441
  }
422
442
  })
423
443
  }
424
444
 
445
+ export function updateSessionStatus(id: string, patch: Partial<AgentSession>): void {
446
+ updateSessionStatuses([{ id, patch }])
447
+ }
448
+
425
449
  export function deleteSession(id: string): void {
426
450
  mutateStore((store) => {
427
451
  store.agentSessions = store.agentSessions.filter((s) => s.id !== id)
@@ -106,20 +106,39 @@ export function resolveSootsimBridgePortForRuntimeLocation(
106
106
  return resolveSootsimBridgePortForHttpPort({ httpPort, baseHttpPort })
107
107
  }
108
108
 
109
- export function resolveSootsimBridgeWebSocketUrl(input: {
110
- bridgePort: number
109
+ export function resolveSootsimWebSocketProxyUrl(input: {
110
+ targetUrl: string
111
111
  href: string
112
112
  }): string {
113
113
  const pageUrl = parseHrefUrl(input.href)
114
114
  if (!pageUrl || (pageUrl.protocol !== 'http:' && pageUrl.protocol !== 'https:')) {
115
- throw new Error(`invalid SootSim browser bridge page URL: ${input.href}`)
115
+ throw new Error(`invalid SootSim websocket proxy page URL: ${input.href}`)
116
+ }
117
+ let targetUrl: URL
118
+ try {
119
+ targetUrl = new URL(input.targetUrl)
120
+ } catch {
121
+ throw new Error(`invalid SootSim websocket proxy target URL: ${input.targetUrl}`)
122
+ }
123
+ if (targetUrl.protocol !== 'ws:' && targetUrl.protocol !== 'wss:') {
124
+ throw new Error(`invalid SootSim websocket proxy target URL: ${input.targetUrl}`)
116
125
  }
117
126
  const proxyUrl = new URL('/__websocket-proxy', pageUrl)
118
127
  proxyUrl.protocol = pageUrl.protocol === 'https:' ? 'wss:' : 'ws:'
119
- proxyUrl.searchParams.set('url', `ws://localhost:${input.bridgePort}`)
128
+ proxyUrl.searchParams.set('url', input.targetUrl)
120
129
  return proxyUrl.href
121
130
  }
122
131
 
132
+ export function resolveSootsimBridgeWebSocketUrl(input: {
133
+ bridgePort: number
134
+ href: string
135
+ }): string {
136
+ return resolveSootsimWebSocketProxyUrl({
137
+ targetUrl: `ws://localhost:${input.bridgePort}`,
138
+ href: input.href,
139
+ })
140
+ }
141
+
123
142
  // private websocket close code used when the daemon intentionally closes a
124
143
  // sim. browser clients treat it as terminal and skip their normal reconnect
125
144
  // loop; playwright-owned sims use it to close their hosting context.
@@ -28,10 +28,6 @@ import {
28
28
  transcriptPath,
29
29
  type Provider,
30
30
  } from '../agent-sessions.ts'
31
- import {
32
- agentbusSessionIdFromCliIdentity,
33
- sendPromptToAgentbusSession,
34
- } from '../agentbus-prompt.ts'
35
31
  import {
36
32
  deleteProject,
37
33
  findProjectById,
@@ -41,17 +37,23 @@ import {
41
37
  listSessions,
42
38
  recordTurnTelemetry,
43
39
  seedFromDemoAppRegistry,
44
- updateSessionStatus,
40
+ applySessionStatusPatch,
41
+ updateSessionStatuses,
45
42
  upsertProject,
46
43
  type AgentSession,
47
44
  type AttachedProject,
48
45
  } from '../attached-projects.ts'
46
+ import {
47
+ sendPromptToTeamMachineSession,
48
+ teamMachineSessionIdFromCliIdentity,
49
+ } from '../team-machine-prompt.ts'
49
50
  import type { AgentEvent } from '../agent-events.ts'
50
51
  import type { AgentPromptEnvelope } from '../agent-prompt.ts'
51
52
  import type { WebSocket } from 'ws'
52
53
 
53
54
  // ws.readyState constant — avoid importing the module just for this enum.
54
55
  const WS_OPEN = 1
56
+ const SESSION_STATUS_PERSIST_DELAY_MS = 25
55
57
 
56
58
  interface FanoutSubscription {
57
59
  unsubscribe: () => void
@@ -69,7 +71,7 @@ export interface AgentHostOptions {
69
71
  * right thing. */
70
72
  getExcludePorts?: () => number[]
71
73
  /** returns the active CLI lease for a sim. used only for prompt routing to
72
- * an external agentbus-wrapped agent that claimed the tab. */
74
+ * an external Team Machine agent that claimed the tab. */
73
75
  resolveCliLease?: (simId: string) => AgentCliLeaseSnapshot | null
74
76
  }
75
77
 
@@ -113,6 +115,12 @@ export class AgentHost {
113
115
  // in-memory count so session status stays `working` until that backlog
114
116
  // truly drains.
115
117
  private pendingTurns = new Map<string, number>()
118
+ // status fan-out is realtime state. keep the current value in memory and
119
+ // batch its durable store write so an fsync cannot delay the websocket event
120
+ // it describes. close() flushes the final batch synchronously.
121
+ private pendingSessionStates = new Map<string, AgentSession>()
122
+ private pendingSessionPatches = new Map<string, Partial<AgentSession>>()
123
+ private sessionStatusPersistTimer: ReturnType<typeof setTimeout> | null = null
116
124
  private opts: AgentHostOptions
117
125
 
118
126
  constructor(opts: AgentHostOptions = {}) {
@@ -168,6 +176,11 @@ export class AgentHost {
168
176
  /** terminate every subscription and drop every socket reference. called
169
177
  * by the bridge host during shutdown. */
170
178
  close(): void {
179
+ if (this.sessionStatusPersistTimer) {
180
+ clearTimeout(this.sessionStatusPersistTimer)
181
+ this.sessionStatusPersistTimer = null
182
+ }
183
+ this.flushSessionStatuses()
171
184
  for (const sub of this.subscriptions.values()) {
172
185
  try {
173
186
  sub.unsubscribe()
@@ -232,7 +245,7 @@ export class AgentHost {
232
245
 
233
246
  private async sendClaimedPrompt(msg: any): Promise<{
234
247
  ok: true
235
- routed: 'agentbus'
248
+ routed: 'team-machine'
236
249
  sessionId: string
237
250
  }> {
238
251
  const simId = typeof msg.simId === 'string' ? msg.simId.trim() : ''
@@ -243,18 +256,18 @@ export class AgentHost {
243
256
  if (!lease || lease.kind !== 'cli' || lease.expiresAt <= Date.now()) {
244
257
  throw new AgentSessionError('NO_CLAIM', `sim ${simId} has no active CLI claim`)
245
258
  }
246
- const sessionId = agentbusSessionIdFromCliIdentity(lease.cliIdentityKey)
259
+ const sessionId = teamMachineSessionIdFromCliIdentity(lease.cliIdentityKey)
247
260
  if (!sessionId) {
248
261
  throw new AgentSessionError(
249
262
  'UNSUPPORTED_CLAIM',
250
263
  `sim ${simId} is claimed by a CLI identity that is not promptable`,
251
264
  )
252
265
  }
253
- await sendPromptToAgentbusSession({
266
+ await sendPromptToTeamMachineSession({
254
267
  sessionId,
255
268
  prompt: this.normalizePromptEnvelope(msg),
256
269
  })
257
- return { ok: true, routed: 'agentbus', sessionId }
270
+ return { ok: true, routed: 'team-machine', sessionId }
258
271
  }
259
272
 
260
273
  private async doStartSession(input: {
@@ -530,10 +543,46 @@ export class AgentHost {
530
543
  }
531
544
 
532
545
  private patchSession(sessionId: string, patch: Partial<AgentSession>): void {
533
- updateSessionStatus(sessionId, patch)
534
- const updated = findSessionById(sessionId)
535
- if (updated) {
536
- this.broadcastSessionStatus(updated)
546
+ const existing =
547
+ this.pendingSessionStates.get(sessionId) ?? findSessionById(sessionId)
548
+ if (!existing) return
549
+ const updated = applySessionStatusPatch(existing, patch)
550
+ this.pendingSessionStates.set(sessionId, updated)
551
+ this.pendingSessionPatches.set(sessionId, {
552
+ ...this.pendingSessionPatches.get(sessionId),
553
+ ...patch,
554
+ })
555
+ this.broadcastSessionStatus(updated)
556
+ if (this.sessionStatusPersistTimer) return
557
+ this.sessionStatusPersistTimer = setTimeout(() => {
558
+ this.sessionStatusPersistTimer = null
559
+ this.flushSessionStatuses()
560
+ }, SESSION_STATUS_PERSIST_DELAY_MS)
561
+ }
562
+
563
+ private flushSessionStatuses(): void {
564
+ if (this.pendingSessionPatches.size === 0) return
565
+ const pendingStates = this.pendingSessionStates
566
+ const pendingPatches = this.pendingSessionPatches
567
+ this.pendingSessionStates = new Map()
568
+ this.pendingSessionPatches = new Map()
569
+ try {
570
+ updateSessionStatuses([...pendingPatches].map(([id, patch]) => ({ id, patch })))
571
+ } catch (error) {
572
+ for (const [id, session] of pendingStates) {
573
+ if (!this.pendingSessionStates.has(id)) {
574
+ this.pendingSessionStates.set(id, session)
575
+ }
576
+ }
577
+ for (const [id, patch] of pendingPatches) {
578
+ this.pendingSessionPatches.set(id, {
579
+ ...patch,
580
+ ...this.pendingSessionPatches.get(id),
581
+ })
582
+ }
583
+ process.stderr.write(
584
+ `[sootsim-agent] session status persistence failed: ${error instanceof Error ? error.message : String(error)}\n`,
585
+ )
537
586
  }
538
587
  }
539
588
 
@@ -1,45 +1,38 @@
1
1
  import { spawn } from 'node:child_process'
2
- import fs from 'node:fs'
3
- import os from 'node:os'
4
- import path from 'node:path'
5
2
  import {
6
- agentbusSessionIdFromCliIdentity,
7
- isValidAgentbusSessionId,
3
+ isValidTeamMachineSessionId,
4
+ teamMachineSessionIdFromCliIdentity,
8
5
  } from './agent-identity.ts'
9
6
  import type { AgentPromptEnvelope } from './agent-prompt.ts'
10
7
 
11
- export { agentbusSessionIdFromCliIdentity } from './agent-identity.ts'
8
+ export { teamMachineSessionIdFromCliIdentity } from './agent-identity.ts'
12
9
 
13
- export function formatAgentbusPromptText(prompt: AgentPromptEnvelope): string {
10
+ export function formatTeamMachinePromptText(prompt: AgentPromptEnvelope): string {
14
11
  return typeof prompt.text === 'string' ? prompt.text.trim() : ''
15
12
  }
16
13
 
17
- function resolveAgentbusCommand(explicit?: string): string {
14
+ function resolveTeamMachineCommand(explicit?: string): string {
18
15
  const fromArg = explicit?.trim()
19
16
  if (fromArg) return fromArg
20
- const fromEnv = process.env.AGENTBUS_COMMAND?.trim()
21
- if (fromEnv) return fromEnv
22
- const localBin = path.join(os.homedir(), '.local', 'bin', 'agentbus')
23
- if (fs.existsSync(localBin)) return localBin
24
- return 'agentbus'
17
+ return 'tm'
25
18
  }
26
19
 
27
- export async function sendPromptToAgentbusSession(input: {
20
+ export async function sendPromptToTeamMachineSession(input: {
28
21
  sessionId: string
29
22
  prompt: AgentPromptEnvelope
30
23
  command?: string
31
24
  timeoutMs?: number
32
25
  }): Promise<void> {
33
26
  const sessionId = input.sessionId.trim()
34
- if (!isValidAgentbusSessionId(sessionId)) {
35
- throw new Error(`invalid agentbus session id: ${sessionId || '<empty>'}`)
27
+ if (!isValidTeamMachineSessionId(sessionId)) {
28
+ throw new Error(`invalid Team Machine session id: ${sessionId || '<empty>'}`)
36
29
  }
37
- const text = formatAgentbusPromptText(input.prompt)
30
+ const text = formatTeamMachinePromptText(input.prompt)
38
31
  if (!text) {
39
32
  throw new Error('prompt text is empty')
40
33
  }
41
34
 
42
- const command = resolveAgentbusCommand(input.command)
35
+ const command = resolveTeamMachineCommand(input.command)
43
36
  const timeoutMs = input.timeoutMs ?? 15_000
44
37
  await new Promise<void>((resolve, reject) => {
45
38
  const child = spawn(command, ['send', sessionId, text], {
@@ -51,7 +44,7 @@ export async function sendPromptToAgentbusSession(input: {
51
44
  try {
52
45
  child.kill('SIGTERM')
53
46
  } catch {}
54
- reject(new Error(`agentbus send timed out after ${Math.round(timeoutMs / 1000)}s`))
47
+ reject(new Error(`tm send timed out after ${Math.round(timeoutMs / 1000)}s`))
55
48
  }, timeoutMs)
56
49
 
57
50
  child.stderr?.setEncoding('utf8')
@@ -72,7 +65,7 @@ export async function sendPromptToAgentbusSession(input: {
72
65
  reject(
73
66
  new Error(
74
67
  detail ||
75
- `agentbus send exited with ${signal ? `signal ${signal}` : `code ${code ?? 'unknown'}`}`,
68
+ `tm send exited with ${signal ? `signal ${signal}` : `code ${code ?? 'unknown'}`}`,
76
69
  ),
77
70
  )
78
71
  })
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.268 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a,b,c,d}from"./chunk-YUDUKMJV.js";import"./chunk-RG6QF6DY.js";export{d as BETA_ASK_HEADLINE,b as BETA_LABEL,c as BETA_TAGLINE,a as IS_BETA};
@@ -1 +0,0 @@
1
- /*! sootsim v0.1.268 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.268 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- var t=4001,r="sootsim close";var n="http://localhost:5173/";export{t as a,r as b,n as c};
@@ -1,5 +0,0 @@
1
- /*! sootsim v0.1.268 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as R}from"./chunk-WUOPQL2J.js";import{o as D}from"./chunk-K5ZMEBMQ.js";import{a as T}from"./chunk-RG6QF6DY.js";function Y(e){if(!e||typeof e!="object")return!1;let t=e;return typeof t.type=="string"&&typeof t.ts=="number"}function I(e){let t=e.trim();if(!t)return null;try{let r=JSON.parse(t);return Y(r)?r:null}catch{return null}}import{randomBytes as G,createHash as q}from"node:crypto";import m from"node:fs";import h from"node:path";var N=null;function _(){if(N)return N;let e=process.env.SOOTSIM_USER_DATA_DIR;return e||D()}function y(){return _()}function U(){return h.join(_(),"attached-projects.json")}function $(){return{version:1,attachedProjects:[],previewAttachments:[],agentSessions:[]}}function S(){let e=U(),t;try{t=m.readFileSync(e,"utf8")}catch(r){if(r.code==="ENOENT")return $();throw r}try{let r=JSON.parse(t);if(!r||typeof r!="object")throw new Error("not an object");return{version:1,attachedProjects:Array.isArray(r.attachedProjects)?r.attachedProjects:[],previewAttachments:Array.isArray(r.previewAttachments)?r.previewAttachments:[],agentSessions:Array.isArray(r.agentSessions)?r.agentSessions:[]}}catch(r){let n=`${e}.corrupt-${Date.now()}`;try{m.renameSync(e,n),console.warn(`[sootsim] attached-projects.json was unparseable; quarantined to ${n}. original error: ${r.message}`)}catch{}return $()}}function X(e){let t=U();m.mkdirSync(h.dirname(t),{recursive:!0});let r=`${t}.tmp-${process.pid}-${Date.now()}`,n=m.openSync(r,"w",384);try{m.writeFileSync(n,JSON.stringify(e,null,2)),m.fsyncSync(n)}finally{m.closeSync(n)}m.renameSync(r,t)}function w(e){let t=S();return e(t),X(t),t}function B(e){return q("sha256").update(h.resolve(e)).digest("hex").slice(0,16)}function K(){return`s_${G(10).toString("hex")}`}function ge(e){let t=h.resolve(e.cwd),r=B(t),n;return w(o=>{let s=o.attachedProjects.find(c=>c.id===r);if(s){let c={...s,...e,id:r,cwd:t,sourceRoots:e.sourceRoots??s.sourceRoots,knownBundleUrls:e.knownBundleUrls??s.knownBundleUrls,pinnedSourceResolutions:e.pinnedSourceResolutions??s.pinnedSourceResolutions,telemetry:e.telemetry??s.telemetry,updatedAt:Date.now(),createdAt:s.createdAt},g=o.attachedProjects.indexOf(s);o.attachedProjects[g]=c,n=c;return}let a=Date.now(),d={id:r,name:e.name??h.basename(t),cwd:t,repoRoot:e.repoRoot,sourceRoots:e.sourceRoots??[t],framework:e.framework??"unknown",bundleId:e.bundleId,knownBundleUrls:e.knownBundleUrls??[],preferredProvider:e.preferredProvider??"codex",preferredTransport:e.preferredTransport??"tmux",editorOpenCommand:e.editorOpenCommand,moshiWebhookToken:e.moshiWebhookToken,pinnedSourceResolutions:e.pinnedSourceResolutions??{},isolateDiscovery:e.isolateDiscovery,git:e.git,telemetry:e.telemetry??{lastOpened:0,runsCompleted:0},createdAt:a,updatedAt:a};o.attachedProjects.push(d),n=d}),n}function F(e){return S().attachedProjects.find(t=>t.id===e)??null}function he(){return S().attachedProjects}var Q=336*60*60*1e3;function ye(e,t={}){w(r=>{let n=r.attachedProjects.find(s=>s.id===e);if(!n)return;let o=t.ts??Date.now();if(n.telemetry.runsCompleted=(n.telemetry.runsCompleted??0)+1,typeof t.usd=="number"&&Number.isFinite(t.usd)&&t.usd>=0){let s=n.telemetry.costHistory??[],a=o-Q,d=s.filter(c=>c.ts>=a);d.push({ts:o,usd:t.usd}),n.telemetry.costHistory=d}n.updatedAt=o})}function Se(e,t=Date.now()){let r=t-6048e5,n=e.telemetry.costHistory??[],o=0;for(let s of n)s.ts>=r&&(o+=s.usd);return o}function we(e){w(t=>{t.attachedProjects=t.attachedProjects.filter(r=>r.id!==e),t.agentSessions=t.agentSessions.filter(r=>r.projectId!==e),t.previewAttachments=t.previewAttachments.filter(r=>r.projectId!==e)})}function M(e){let t;return w(r=>{if(e.id){let a=r.agentSessions.find(d=>d.id===e.id);if(a){let d={...a,...e,lastSeenAt:Date.now()},c=r.agentSessions.indexOf(a);r.agentSessions[c]=d,t=d;return}}let n=r.attachedProjects.find(a=>a.id===e.projectId);if(!n)throw new Error(`upsertSession: no AttachedProject with id=${e.projectId}`);let o=Date.now(),s={id:e.id??K(),projectId:e.projectId,provider:e.provider,transport:e.transport??n.preferredTransport,cwd:e.cwd??n.cwd,claudeSessionUuid:e.claudeSessionUuid,tmuxSessionName:e.tmuxSessionName,wrapperPid:e.wrapperPid,status:e.status??"idle",needsAttention:e.needsAttention??!1,lastPrompt:e.lastPrompt,lastSummary:e.lastSummary,lastTurnFiles:e.lastTurnFiles,currentlyEditing:e.currentlyEditing,lastSeenAt:o,createdAt:o};r.agentSessions.push(s),t=s}),t}function k(e){return S().agentSessions.find(t=>t.id===e)??null}function C(e){let t=S().agentSessions;return e?t.filter(r=>r.projectId===e):t}function v(e,t){w(r=>{let n=r.agentSessions.find(s=>s.id===e);if(!n)return;let o=r.agentSessions.indexOf(n);r.agentSessions[o]={...n,...t,id:n.id,projectId:n.projectId,createdAt:n.createdAt,lastSeenAt:Date.now()}})}async function ve(){if(S().attachedProjects.length>0)return;let{loadOptionalDemoApps:t}=await import("./optional-demo-registry-CROVHXTW.js"),r=await t();r.length!==0&&w(n=>{for(let o of r){if(!m.existsSync(o.dir))continue;let s=h.resolve(o.dir),a=B(s);if(n.attachedProjects.some(c=>c.id===a))continue;let d=Date.now();n.attachedProjects.push({id:a,name:o.label,cwd:s,sourceRoots:[s],framework:o.framework,knownBundleUrls:[`http://localhost:${o.preferredPort}/index.bundle`],preferredProvider:"codex",preferredTransport:"tmux",pinnedSourceResolutions:{},telemetry:{lastOpened:0,runsCompleted:0},createdAt:d,updatedAt:d})}})}import{spawn as V,spawnSync as z}from"node:child_process";import{randomUUID as Z}from"node:crypto";import i,{constants as f}from"node:fs";import u from"node:path";import ee from"node:readline";function b(e){return u.join(y(),"sessions",e)}function W(e){return u.join(b(e),"prompt.in")}function J(e){return u.join(b(e),"events.out")}function te(e){return u.join(y(),"transcripts",`${e}.log`)}function O(e,t){if(!e)return!1;try{process.kill(e,0)}catch{return!1}return!(t&&!i.existsSync(b(t)))}function re(){if(process.env.SOOTSIM_BIN)return{cmd:process.env.SOOTSIM_BIN,prefixArgs:[]};if(process.versions.electron){let n=process.resourcesPath;if(n){let o=[u.join(n,"bin","sootsim"),u.join(n,"bin",`sootsim-${process.platform}-${process.arch}`)];for(let s of o)if(i.existsSync(s))return{cmd:s,prefixArgs:[]}}}let e=ne();if(e)return e;let t=process.argv[0],r=process.argv[1];if(r&&/\.(ts|tsx|mjs|cjs|js)$/.test(r))return{cmd:t,prefixArgs:[r]};if(!r||r.includes("/.bin/"))throw new Error("sootsim CLI not found. set SOOTSIM_BIN to the path of the sootsim binary, or build the workspace CLI via `bun run --cwd packages/sootsim build:cli`.");return{cmd:t,prefixArgs:[]}}function ne(){try{let e=se();if(!e)return null;let t=`sootsim-${process.platform}-${process.arch}`,r=u.join(e,"dist-bin",t);if(i.existsSync(r))return{cmd:r,prefixArgs:[]};let n=u.join(e,"dist-cli","bin.js");if(i.existsSync(n)){try{let o=u.join(e,"cli","commands","agent-wrapper.ts");if(i.existsSync(o)){let s=i.statSync(o).mtimeMs;i.statSync(n).mtimeMs<s&&console.warn("[sootsim] dist-cli/bin.js is older than agent-wrapper.ts \u2014 rebuild with `bun run --cwd packages/sootsim build:cli`.")}}catch{}return{cmd:process.execPath,prefixArgs:[n]}}return null}catch{return null}}function se(){try{let r=T.resolve("sootsim/package.json");return u.dirname(r)}catch{}let e=oe();if(!e)return null;let t=u.dirname(e);for(let r=0;r<8;r++){let n=u.join(t,"package.json");try{if(i.existsSync(n)&&JSON.parse(i.readFileSync(n,"utf8")).name==="sootsim")return t}catch{}let o=u.dirname(t);if(o===t)break;t=o}return null}function oe(){try{let e=import.meta.url;return!e||!e.startsWith("file://")?null:decodeURIComponent(e.slice(7))}catch{return null}}async function ie(e,t,r){let n=u.join(y(),"locks");i.mkdirSync(n,{recursive:!0});try{i.chmodSync(n,448)}catch{}let o=u.join(n,`start-${e}-${t}.lock`),s=Date.now()+4e3,a=null;for(;a===null;)try{a=i.openSync(o,f.O_WRONLY|f.O_CREAT|f.O_EXCL,384)}catch(d){if(d.code!=="EEXIST")throw d;try{let c=Number(i.readFileSync(o,"utf8").trim());if(c&&!ce(c)){i.unlinkSync(o);continue}}catch{}if(Date.now()>s)throw new Error(`another start is in progress for project=${e} provider=${t} (lock: ${o})`);await new Promise(c=>setTimeout(c,50))}try{return i.writeFileSync(a,String(process.pid)),await r()}finally{try{i.closeSync(a)}catch{}try{i.unlinkSync(o)}catch{}}}function ce(e){try{return process.kill(e,0),!0}catch{return!1}}function L(e){let t=u.dirname(e);i.mkdirSync(t,{recursive:!0});try{i.chmodSync(t,448)}catch{}if(i.existsSync(e))try{if(i.statSync(e).isFIFO()){try{i.chmodSync(e,384)}catch{}return}i.unlinkSync(e)}catch{i.unlinkSync(e)}let r=z("mkfifo",["-m","600",e]);if(r.status!==0)throw new Error(`mkfifo(${e}) failed: ${r.stderr?.toString().trim()||"unknown error"}`)}var l=class extends Error{code;constructor(t,r){super(r),this.code=t}};async function Te(e){let t=F(e.projectId);if(!t)throw new l("NO_PROJECT",`no project with id=${e.projectId}`);let r=e.provider||t.preferredProvider||"codex";return ie(t.id,r,async()=>{let n=C(t.id).find(p=>p.provider===r&&p.status!=="ended"&&O(p.wrapperPid,p.id));if(n)throw new l("ALREADY_RUNNING",`session already running for project=${t.id} provider=${r} (session ${n.id}, pid ${n.wrapperPid}). end it first with \`sootsim agent end <sessionId>\`.`);let o=r==="claude"?Z():void 0,s=M({projectId:t.id,provider:r,transport:"pty",cwd:t.cwd,status:"idle",claudeSessionUuid:o}),a=W(s.id),d=J(s.id),c=te(s.id);L(a),L(d);let g=u.dirname(c);i.mkdirSync(g,{recursive:!0});try{i.chmodSync(g,448)}catch{}let{cmd:A,prefixArgs:H}=re(),x=[...H,"agent-wrapper","--session-id",s.id,"--project-id",t.id,"--provider",r,"--cwd",t.cwd,"--prompt-in",a,"--events-out",d,"--transcript",c];e.codexBin&&x.push("--codex-bin",e.codexBin),e.claudeBin&&x.push("--claude-bin",e.claudeBin),e.freshThread&&x.push("--fresh-thread"),o&&x.push("--claude-session-uuid",o);let P=V(A,x,{detached:!0,stdio:"ignore",env:{...process.env,SOOTSIM_USER_DATA_DIR:y()}});P.unref();let E=e.readyTimeoutMs??6e3,j=await ae(d,p=>p.type==="ready"||p.type==="error",E);if(!j||j.type==="error"){if(P.pid)try{process.kill(P.pid,"SIGTERM")}catch{}try{i.rmSync(b(s.id),{recursive:!0,force:!0})}catch{}v(s.id,{status:"ended"});let p=j&&j.type==="error"?j.message:`no ready event within ${E}ms`;throw new l("WRAPPER_FAILED",p)}return v(s.id,{wrapperPid:P.pid,status:"idle"}),{session:k(s.id),wrapperPid:P.pid}})}async function De(e,t){let r=k(e);if(!r)throw new l("NO_SESSION",`no session with id=${e}`);if(!O(r.wrapperPid,e))throw v(e,{status:"ended"}),new l("NOT_ALIVE",`session wrapper is not alive (pid=${r.wrapperPid}). start a new session.`);let n=W(e);if(!i.existsSync(n))throw new l("NO_FIFO",`prompt FIFO missing: ${n}`);let o=i.openSync(n,f.O_WRONLY);try{let s=R(t);if(!s)throw new l("EMPTY_PROMPT","prompt text is empty");i.writeSync(o,s+`
3
- `)}finally{i.closeSync(o)}v(e,{lastPrompt:t.displayText??t.text,status:"working"})}async function Re(e){let t=k(e);if(!t)throw new l("NO_SESSION",`no session with id=${e}`);if(O(t.wrapperPid,e))try{process.kill(t.wrapperPid,"SIGTERM")}catch{}let r=b(e),n=y();if(r.startsWith(n))try{i.rmSync(r,{recursive:!0,force:!0})}catch{}v(e,{status:"ended",wrapperPid:void 0})}function Ne(e,t){let r=J(e);if(!i.existsSync(r))throw new l("NO_FIFO",`events FIFO missing: ${r}`);let n=i.openSync(r,f.O_RDWR),o=i.createReadStream("",{fd:n,autoClose:!0}),s=ee.createInterface({input:o,crlfDelay:1/0});s.on("line",d=>{let c=I(d);c&&t(c)});let a=!1;return()=>{if(!a){a=!0;try{i.writeSync(n,`
4
- `)}catch{}try{s.close()}catch{}try{o.destroy()}catch{}}}}async function ae(e,t,r){let n=i.openSync(e,f.O_RDWR|f.O_NONBLOCK),o=Buffer.alloc(8192),s="",a=Date.now()+r;try{for(;Date.now()<a;){let d=0;try{d=i.readSync(n,o,0,o.length,null)}catch(c){if(c.code!=="EAGAIN")throw c;d=0}if(d>0){s+=o.subarray(0,d).toString("utf8");let c;for(;(c=s.indexOf(`
5
- `))>=0;){let g=s.slice(0,c);s=s.slice(c+1);let A=I(g);if(A&&t(A))return A}}else await new Promise(c=>setTimeout(c,30))}return null}finally{i.closeSync(n)}}export{I as a,y as b,ge as c,F as d,he as e,ye as f,Se as g,we as h,k as i,C as j,v as k,ve as l,b as m,W as n,J as o,te as p,O as q,re as r,l as s,Te as t,De as u,Re as v,Ne as w};
@@ -1,5 +0,0 @@
1
- /*! sootsim v0.1.268 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{execFileSync as h,spawn as g}from"child_process";import{existsSync as s,readdirSync as k}from"fs";import{dirname as m,join as l,resolve as a}from"path";import{fileURLToPath as v}from"url";var c;function p(){if(c!==void 0)return c;try{c=m(v(import.meta.resolve("sootsim-engine/package.json")))}catch{c=null}return c}var I="dev.sootsim.simulator";function x(){let n=p();if(!n)return null;let e=l(n,"dist-electron/main.cjs");if(!s(e))return null;let i=D(n);return i?{path:i,platform:process.platform,kind:"dev-electron",engineDir:n}:null}function b(){let n=p();return n?s(l(n,"src-electron/main.ts")):!1}function D(n){let e=n;for(let i=0;i<6;i++){let t=l(e,"node_modules/.bin/electron");if(s(t))return t;let r=m(e);if(r===e)break;e=r}return null}function C(){let n=p(),i=["/Applications/sootsim.app",a(process.env.HOME||"","Applications/sootsim.app"),...n?[a(n,"app/sootsim.app")]:[]].find(t=>s(t));if(i)return{path:i,platform:"darwin",kind:"mac-app"};try{let t=h("mdfind",[`kMDItemCFBundleIdentifier == "${I}"`],{encoding:"utf8",timeout:3e3}).trim();if(t)return{path:t.split(`
3
- `)[0],platform:"darwin",kind:"mac-app"}}catch{}return null}function f(n){if(!s(n))return null;let e=k(n).filter(i=>i.startsWith("sootsim")&&i.endsWith(".AppImage")).sort().reverse()[0];return e?l(n,e):null}function w(){let n=p(),i=[a(process.env.HOME||"","Applications/sootsim.AppImage"),a(process.env.HOME||"",".local/bin/sootsim.AppImage"),"/opt/sootsim/sootsim.AppImage","/opt/sootsim/sootsim",...n?[a(n,"app/sootsim.AppImage"),a(n,"release/linux-unpacked/sootsim")]:[]].find(r=>s(r));if(i)return{path:i,platform:"linux",kind:i.endsWith(".AppImage")?"linux-appimage":"linux-binary"};let t=n?f(a(n,"app"))||f(a(n,"release")):null;return t?{path:t,platform:"linux",kind:"linux-appimage"}:null}function A(){let n=x();if(n)return n;if(b()){let e=p(),i=l(e,"dist-electron/main.cjs");return s(i)?console.error(` no node_modules/.bin/electron found near ${e}. run \`bun install\`.`):console.error(` dist-electron/main.cjs missing in ${e}.
4
- run: bun run --cwd packages/sootsim-engine build:electron-main
5
- (or keep it fresh with: bun run watch:sootsim:electron-main)`),null}return process.platform==="darwin"?C():process.platform==="linux"?w():null}async function d(n,e,i={}){let t=i.inheritStdio?["ignore","inherit","inherit"]:"ignore";await new Promise((r,o)=>{let u=g(n,e,{detached:!0,stdio:t});u.once("error",o),u.once("spawn",()=>{u.unref(),r()})})}async function O(n,e=A(),i={}){if(!e)return{launched:!1};let t=[];if(i.device&&t.push(`--device=${i.device}`),i.profileId&&t.push(`--profile=${i.profileId}`),i.ephemeralProfile&&t.push("--ephemeral-profile"),e.kind==="mac-app"){let o=["-g","-a",e.path];return n&&o.push(L(n,i)),t.length>0&&o.push("--args",...t),await d("open",o),{launched:!0,via:"mac-app",target:e.path}}if(e.kind==="dev-electron"){let o=["--no-sandbox",e.engineDir||p()];return n&&o.push(n),t.length>0&&o.push(...t),await d(e.path,o,{inheritStdio:!0}),{launched:!0,via:"dev-electron",target:e.path}}let r=[];return n&&r.push(n),t.length>0&&r.push(...t),await d(e.path,r),{launched:!0,via:e.kind,target:e.path}}function L(n,e){if(!e.profileId&&!e.ephemeralProfile)return n;let i=new URL("sootsim://dev");return i.searchParams.set("url",n),e.profileId&&i.searchParams.set("profile",e.profileId),e.ephemeralProfile&&i.searchParams.set("ephemeral","1"),i.toString()}export{A as a,O as b};
@@ -1,13 +0,0 @@
1
- /*! sootsim v0.1.268 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a as K,b as ne,c as re,d as xe,e as ke,g as P,h as Pe}from"./chunk-YNMYUJYR.js";import{b as Ie,l as ce}from"./chunk-EPKHW3XW.js";import{a as O,b as ae}from"./chunk-PN2LR6T4.js";import{a as Me,b as Te}from"./chunk-CWC7QMVM.js";import{a as Ce,b as se,c as Ee}from"./chunk-7XWLSCXZ.js";import{d as le}from"./chunk-LJGOZ77E.js";import{m as R}from"./chunk-KR4LGQWN.js";import{m as _e,o as Ue}from"./chunk-FGKDYXO3.js";import{a as Re,b as Oe,c as ie,e as Be,f as De,g as E,h as v,i as M}from"./chunk-ITQ7WKNC.js";import{e as _,f as b,g as U}from"./chunk-YMTVQA6W.js";import{H as Se,K as te,M as j,l as ve}from"./chunk-K5ZMEBMQ.js";import{b as oe,d as $e}from"./chunk-OOVGROTR.js";import{spawn as je,spawnSync as Ke}from"node:child_process";import L from"node:fs";import ut from"node:os";import T from"node:path";import{WebSocket as pt}from"ws";function Le(e){return new Error(`could not resolve a native bundle for ${e}. pass an explicit bundle URL or open Connect and choose the app there.`)}function st(e,o){return e?.includes("/one/metro-entry.bundle")?"one":typeof o=="string"&&o?"expo":"unknown"}function Ne(e,o,t){return`${e}//${o}:${t}`}function it(e){if(typeof window>"u")return!1;try{let o=new URL(e);return P(o.hostname)&&P(window.location.hostname)&&o.origin!==window.location.origin}catch{return!1}}async function Ae(e,o){let t={...o,cache:o?.cache??"no-store"};return it(e)?fetch(`/__fetch-proxy?url=${encodeURIComponent(e)}`,t):fetch(e,t)}function at(e){return e==="https:"?443:80}function lt(e){let o=e.pathname||"/";return(o==="/"||o==="")&&!e.search&&!e.hash}async function ct(e){try{let o=await fetch("/__server-scan",{cache:"no-store"});if(!o.ok||!(o.headers.get("content-type")||"").toLowerCase().includes("json"))return null;let t=await o.json();if(!Array.isArray(t))return null;let n=t.find(r=>!!r&&typeof r=="object"&&r.port===e&&typeof r.bundleUrl=="string");return n?{bundleUrl:re(n.bundleUrl),port:e,framework:typeof n.framework=="string"?n.framework:"unknown",projectName:typeof n.projectName=="string"?n.projectName:void 0}:null}catch{return null}}async function Fe(e,o){let t=e.replace(/\/+$/,"");try{if(P(new URL(t).hostname)){let n=await ct(o);if(n)return n}}catch{}try{let n=await Ae(`${t}/`,{headers:{"expo-platform":"ios"}});if(n.ok){let r=await n.json(),s=r?.extra?.expoClient||r?.extra||{},i=typeof r?.launchAsset?.url=="string"?r.launchAsset.url:void 0;if(i||s.name)return{bundleUrl:re(i||`${t}${ne}`),port:o,framework:st(i,s.sdkVersion),projectName:s.name}}}catch{}try{let n=await Ae(`${t}/status`);if(n.ok&&(await n.text()).includes("packager-status:running"))return{bundleUrl:`${t}${ne}`,port:o,framework:"metro"}}catch{}return null}async function dt(e){return Fe(Ne("http:","localhost",e),e)}async function He(e){let o=e.trim();if(/^\d+$/.test(o)){let a=parseInt(o,10),l=await dt(a);if(l)return l;throw Le(`localhost:${a}`)}let t=o.startsWith("http")?o:`http://${o}`,n;try{n=new URL(t)}catch{throw new Error(`could not parse "${e}". pass a dev-server port, a dev-server base URL, or a full bundle URL.`)}let r=n.protocol||"http:",s=n.port?parseInt(n.port,10):at(r),i=Ne(r,n.hostname,s);if(lt(n)){let a=await Fe(i,s);if(a)return a;throw Le(i)}return{bundleUrl:n.toString(),port:s,framework:"unknown"}}function io(){console.error(" no sootsim desktop companion found."),console.error(""),console.error(" install the desktop app:"),console.error(" sootsim desktop install"),console.error(""),console.error(" or run setup to install the background daemon:"),console.error(" sootsim setup"),console.error("")}function We(e){let o=O();if(console.log(` note: no sootsim bridge detected on port ${e}`),o){console.log(" launch the installed companion with:"),console.log(" sootsim desktop");return}console.log(""),console.log(" run `sootsim setup` to install the background daemon,"),console.log(" or run `sootsim serve` in another shell for a foreground bridge.")}function mt(e){console.error(""),console.error(` no sim is connected to the sootsim bridge on port ${e}.`),console.error(""),console.error(" start your app dev server, then open it in sootsim:"),console.error(" npx expo start --localhost --port 8081"),console.error(" sootsim open 8081"),console.error(""),console.error(" then inspect the live app:"),console.error(" sootsim describe")}async function ao(e,o,t){let n=[];try{n=await e.listSims()}catch{}if(console.error(""),n.length===0){mt(o);return}console.error(` no sim with id "${t}" is connected to the bridge on port ${o}.`),console.error(""),console.error(" connected sims:");for(let r of n){let s=[r.isPrimary?"primary":null,r.readyState,r.userVisible===!1?"hidden":r.userVisible===!0?"visible":null,r.userFocused?"focused":null].filter(Boolean).join(", ");console.error(` ${r.id} (${s})`)}console.error(""),console.error(" pass a valid --sim id, or run `sootsim list` to see all sessions.")}var ft=12e4,qe=100,ht=5e3,ze=1e4,gt={rn:"/rn",connectrn:"/rn","connect-rn":"/rn",clock:"/app/clock","native-ui":"/app/native-ui",tamagui:"/app/tamagui",settings:"/app/settings",photos:"/app/photos",camera:"/app/camera"};function $(e){return new Promise(o=>setTimeout(o,e))}function Ve(e){let o=process.env[e]?.trim();if(!o)return null;let t=Number(o);return Number.isInteger(t)&&t>0?t:null}function wt(){let e=Ve("SOOTSIM_DRIVER_CONNECT_TIMEOUT_MS")??Ve("SOOTSIM_PW_CONNECT_TIMEOUT_MS")??ft;return{timeoutMs:e,hostTimeoutMs:e+ht,intervalMs:qe,attempts:Math.max(1,Math.ceil(e/qe))}}function bt(e){return e==="chromium"||e==="electron"||e==="playwright"||e==="system"}function yt(e,o){return e.includes("--headless")?!0:e.includes("--headed")?!1:o==="playwright"&&process.platform==="linux"&&!process.env.DISPLAY&&!process.env.WAYLAND_DISPLAY?(console.error(" no display detected \u2192 running playwright headless (override with --headed)"),!0):!1}function V(e){return e.trim()}var Ye=/^[A-Za-z][A-Za-z0-9+.-]*:/;function vt(e){let o=e.trim();if(!o)throw new Error("expected <url-or-route>");return Ye.test(o)||o.startsWith("/")?o:`/${o}`}function St(e){return e!==null&&typeof e=="object"}function $t(e){let o=e.trim();return o?o.startsWith("/")?!0:Ye.test(o)?!/^https?:\/\//i.test(o):!1:!1}async function xt(e){if(await q(e,250))return e;let o=te();if(o&&j(o)&&await q(o.bridgePort,500))return o.bridgePort;if(o&&j(o))throw new Error(`sootsim bridge lockfile is fresh (port ${o.bridgePort}) but the bridge is not reachable. run \`sootsim daemon restart\` or \`sootsim daemon uninstall\`.`);await kt();let t=It(["serve","--quiet","--port",String(e)]),n=null;t.once("exit",(s,i)=>{n=String(s??i??"unknown")}),t.unref();let r=Date.now()+ze;for(;Date.now()<r;){let s=te();if(s&&j(s)&&await q(s.bridgePort,250))return console.error(` started local bridge on port ${s.bridgePort}; run \`sootsim setup\` to install the background daemon`),s.bridgePort;if(await q(e,250))return console.error(` started local bridge on port ${e}; run \`sootsim setup\` to install the background daemon`),e;if(n)throw new Error(`sootsim bridge exited before becoming ready (exit ${n})`);await $(150)}throw new Error(`sootsim bridge did not start within ${Math.round(ze/1e3)}s`)}async function kt(){let e=Se();if(e&&L.existsSync(ve(e)))return;console.error(" installing sootsim engine runtime...");let{runRuntime:o}=await import("./runtime-ITR3EUXS.js");await o(["install"],{})}function It(e){let o=process.argv[1];return o&&L.existsSync(o)?je(process.execPath,[o,...e],{detached:!0,stdio:"ignore",env:process.env}):je("sootsim",e,{detached:!0,stdio:"ignore",env:process.env})}function q(e,o){return new Promise(t=>{let n=new pt(`ws://127.0.0.1:${e}`,{handshakeTimeout:o}),r=!1,s=i=>{if(!r){r=!0;try{n.close()}catch{}t(i)}};n.once("open",()=>s(!0)),n.once("error",()=>s(!1)),setTimeout(()=>s(!1),o)})}function ue(e){try{let o=new URL(e),t=o.pathname.replace(/\/+$/,"")||"/";return o.searchParams.has("open")||o.searchParams.has("port")||o.searchParams.has("bundle")||o.searchParams.has("demo")||o.pathname.includes("/sootsim/index.html")||t==="/sootsim"||o.pathname==="/__soot"||o.pathname==="/__soot/"||t==="/rn"||/^\/rn\/[^/]+$/i.test(t)||/^\/app\/[^/]+$/i.test(t)||t==="/__soot/rn"||/^\/__soot\/rn\/[^/]+$/i.test(t)||/^\/__soot\/app\/[^/]+$/i.test(t)}catch{return!1}}function Pt(e){try{let o=new URL(e,"http://sootsim.local");if(o.origin!=="http://sootsim.local")return!1;let t=o.pathname.replace(/\/+$/,"")||"/";return t==="/rn"||/^\/rn\/[^/]+$/i.test(t)||/^\/app\/[^/]+$/i.test(t)||t==="/__soot/rn"||/^\/__soot\/rn\/[^/]+$/i.test(t)||/^\/__soot\/app\/[^/]+$/i.test(t)}catch{return!1}}function Ct(e,o){let t=new URL(e,"http://sootsim.local"),n=new URL(o),r=G(n.pathname),s=t.pathname.startsWith("/__soot/")?t.pathname.slice(7):t.pathname;return n.pathname=`${r}${s}`,n.search=t.search,n.hash=t.hash,n.toString()}function Et(e){try{let o=new URL(e).pathname.replace(/\/+$/,"")||"/";return/^\/preview\/[^/]+$/.test(o)||/^\/build\/.+/.test(o)}catch{return!1}}async function Oo(e){let o=V(e);return(await Ze(o)).bundleUrl}function Mt(e){try{let o=new URL(e.startsWith("http")?e:`http://${e}`),t=o.pathname||"/";if(t!=="/"&&t!==""||o.search||o.hash||!P(o.hostname))return null;let n=o.port?Number(o.port):o.protocol==="https:"?443:80;return Number.isFinite(n)&&n>0?n:null}catch{return null}}async function Ze(e){let o=V(e),t=/^\d+$/.test(o)?Number(o):Mt(o);if(t&&t>0){let n=await ke(t);if(n)return{bundleUrl:n.bundleUrl,port:n.port,framework:n.framework,projectName:n.projectName}}return He(o)}function G(e){let o=e.replace(/\/+$/,"")||"/";return o==="/__soot"||o.startsWith("/__soot/")?"/__soot":""}function Tt(e,o){let t=V(e),n=new URL(o),r=G(n.pathname);return n.pathname=`${r}/rn`,n.searchParams.delete("bundle"),n.searchParams.delete("demo"),n.searchParams.delete("app"),n.searchParams.delete("open"),n.searchParams.delete("port"),/^\d+$/.test(t)?n.pathname=`${r}/rn/${t}`:(n.pathname=`${r}/rn`,n.searchParams.set("open",t)),n.toString()}function _t(e){let o=V(e);return/^\d+$/.test(o)||/^https?:\/\//i.test(o)?!0:/^(localhost|127\.0\.0\.1|\[::1\]|[^/]+\.localhost):\d+(?:\/.*)?$/i.test(o)}async function Ut(e,o,t={}){let n=await Ze(e),r=new URL(o),s=G(r.pathname);r.pathname=`${s}/rn`,r.searchParams.delete("open"),r.searchParams.delete("port"),r.searchParams.delete("demo"),r.searchParams.delete("app");let i=t.hot===void 0?n.bundleUrl:xe(n.bundleUrl,t.hot);return r.searchParams.set("bundle",i),r.toString()}function Rt(e){return e.startsWith("~/")?T.join(ut.homedir(),e.slice(2)):T.isAbsolute(e)?e:T.resolve(process.cwd(),e)}function Ot(e){let o={},t={};for(let r=0;r<e.length;r++){if(e[r]==="--replace"){let s=e[r+1];s||(console.error(" sootsim open: --replace expects <module>=<file>"),process.exit(1));let i=s.indexOf("=");(i<=0||i===s.length-1)&&(console.error(" sootsim open: --replace expects <module>=<file>"),process.exit(1));let a=s.slice(0,i).trim(),l=Rt(s.slice(i+1).trim());L.existsSync(l)||(console.error(` sootsim open: replacement file not found: ${l}`),process.exit(1)),o[a]={file:l},r++;continue}if(e[r]==="--remap"){let s=e[r+1],i=s?s.indexOf("="):-1;(!s||i<=0||i===s.length-1)&&(console.error(" sootsim open: --remap expects <host:port>=<host:port>"),process.exit(1)),t[s.slice(0,i).trim()]=s.slice(i+1).trim(),r++;continue}}let n={};return Object.keys(o).length>0&&(n.modules=o),Object.keys(t).length>0&&(n.network={remap:t}),n.modules||n.network?n:void 0}function Xe(){return Re().shellBaseUrl}async function Bt(e){try{let o=new URL(e),t=o.searchParams.get("bundle")||"";if(!t)return e;let n=process.env.CONTRAST_REPO_DIR||await se(t)||void 0,r=Ce({bundleUrl:t,repoDir:n});if(r.length===0)return e;let s=await Dt(r);return s.length===0?e:(o.searchParams.set("appFonts",Ee(s)),o.toString())}catch{return e}}async function Dt(e){let o=await Promise.all(e.map(async n=>{let r=new AbortController,s=setTimeout(()=>r.abort(),1500);try{let i=await fetch(n.url,{method:"HEAD",signal:r.signal});return i.status>=200&&i.status<400?n:null}catch{return null}finally{clearTimeout(s)}})),t=[];for(let n of o)n!==null&&t.push(n);return t}async function Lt(e,o,t={}){if(!e)return new URL(o).toString();if(ue(e))return new URL(e).toString();if(Pt(e))return Ct(e,o);let n=gt[e.toLowerCase()];if(n){let r=new URL(o),s=G(r.pathname);return r.pathname=`${s}${n}`,r.toString()}return _t(e)?Ut(e,o,t):Tt(e,o)}async function At(e){try{let o=new URL(e),t=o.searchParams.get("bundle")||"";if(!t)return e;let n=process.env.CONTRAST_REPO_DIR||await se(t)||void 0,r=Me({bundleUrl:t,repoDir:n});return!r||r.imageUrl&&!await Nt(r.imageUrl)?e:(o.searchParams.set("appSplash",Te(r)),o.toString())}catch{return e}}async function Nt(e){let o=new AbortController,t=setTimeout(()=>o.abort(),1500);try{let n=await fetch(e,{method:"HEAD",signal:o.signal});return n.status>=200&&n.status<400}catch{return!1}finally{clearTimeout(t)}}async function z(e,o=Xe(),t={}){let n=await Lt(e,o,t),r=await At(await Bt(n));if(!t.device)return r;let s=new URL(r);return s.searchParams.set("device",t.device),s.toString()}function Ge(e,o){let t=e?.url||e?.origin||o;try{let n=new URL(t);return n.searchParams.delete("bundle"),n.searchParams.delete("demo"),n.searchParams.delete("app"),n.searchParams.delete("open"),n.searchParams.delete("port"),n.searchParams.delete("inspectOpen"),n.searchParams.delete("appFonts"),n.searchParams.delete("appSplash"),n.toString()}catch{return o}}async function Ft(e,o,t,n={}){let r=new URL(await z(e,o,n));return r.searchParams.set("inspectOpen",t),r.toString()}async function Ht(e,o,t,n={}){let r=n.attempts??30,s=n.intervalMs??500,i=n.minNodeCount??10;for(let a=0;a<r;a++){let l=v(e,{commandTimeoutMs:o,simId:t,simIdSource:"flag"});try{let d=await l.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount()) || 0)()"});if(typeof d=="number"&&d>i)return{bridge:l,count:d}}catch{}l.close(),await $(s)}return null}function Wt(e){if(!e)return null;try{let o=new URL(e);if(o.searchParams.has("bundle")){let t=o.searchParams.get("bundle")||"";try{let n=new URL(t),r=n.pathname.length>36?`...${n.pathname.slice(-36)}`:n.pathname;return`bundle ${n.host}${r}`}catch{return"bundle"}}return o.searchParams.has("port")?`connect :${o.searchParams.get("port")||""}`:o.searchParams.has("open")?`connect ${o.searchParams.get("open")||""}`:o.searchParams.has("demo")?`demo ${o.searchParams.get("demo")||"default"}`:o.pathname.includes("/sootsim/index.html")||o.pathname==="/sootsim/"||o.pathname==="/sootsim"?"embedded sootsim":null}catch{return null}}function jt(e){let o=e.indexOf(":");if(o<=0)return e.length>24?`${e.slice(0,21)}\u2026`:e;let t=e.slice(0,o),n=e.slice(o+1),r=n.length>12?`${n.slice(0,8)}\u2026`:n;return t==="AGENTBUS_SESSION"||t==="CLAUDE_CODE_SESSION_ID"||t==="CODEX_THREAD_ID"?`agent ${r}`:`${t} ${r}`}function Bo(e,o){if(e.length===0){console.log(" no sims connected");return}console.log(` connected sims (${e.length}):
3
- `);for(let t of e){let n=t.lockedBy&&t.lockExpiresAt?`locked by ${jt(t.lockedBy)} (${Math.max(0,Math.round((t.lockExpiresAt-Date.now())/1e3))}s)`:"",r=[t.isPrimary?"primary":"",t.id===o?"selected":"",t.readyState,t.userVisible===!1?"hidden":t.userVisible===!0?"visible":"",t.attachedCliCount&&t.attachedCliCount>0?"in use":"",t.userFocused?"focused":"",n].filter(Boolean);console.log(` ${t.id}${r.length?` [${r.join(", ")}]`:""}`);let s=Wt(t.url);if(s)console.log(` loaded: ${s}`);else if(t.url){let a=t.url.length>96?`${t.url.slice(0,93)}\u2026`:t.url;console.log(` url: ${a}`)}else t.origin&&console.log(` origin: ${t.origin}`);let i=Kt(t);i&&console.log(` engine: ${i}`),t.title&&console.log(` title: ${t.title}`),t.visibilityState&&t.visibilityState!=="visible"&&console.log(` visibility: ${t.visibilityState}`),console.log(` connected: ${Je(Date.now()-t.connectedAt)}`),t.lastActiveAt&&t.lastActiveAt>0&&console.log(` last active: ${Je(Date.now()-t.lastActiveAt)}`)}}function Kt(e){let o=e.url||e.origin||"";if(!o)return null;try{let t=new URL(o).port;return t==="5173"?"dev \u2014 local source (:5173)":t==="3000"?"Contrast app embedded (:3000)":Pe()?`dev \u2014 local build (:${t||"?"})`:`runtime \u2014 published engine (:${t||"?"})`}catch{return null}}function Je(e){let o=Math.max(0,Math.round(e/1e3));return o<60?`${o}s ago`:o<3600?`${Math.round(o/60)}m ago`:o<86400?`${Math.round(o/3600)}h ago`:`${Math.round(o/86400)}d ago`}async function de(e,o,t,n={}){let r=n.attempts??30,s=n.intervalMs??500;for(let i=0;i<r;i++){let a=v(e,{commandTimeoutMs:o});try{let d=(await a.listSims()).find(t);if(d)return d}catch{}finally{a.close()}await $(s)}return null}async function qt(e,o,t,n,r={}){let s=r.attempts??30,i=r.intervalMs??500,a=!!n&&Number.isInteger(n)&&n>1,l=()=>a&&n!==void 0&&!pe(n);for(let d=0;d<s;d++){if(l())return{kind:"host-exit"};let m=v(e,{commandTimeoutMs:o});try{let g=(await m.listSims()).find(t);if(g)return l()?{kind:"host-exit"}:{kind:"match",sim:g}}catch{}finally{m.close()}if(l())return{kind:"host-exit"};await $(i)}return{kind:"timeout"}}async function zt(e,o,t,n={}){let r=n.attempts??20,s=n.intervalMs??250;for(let i=0;i<r;i++){let a=v(e,{commandTimeoutMs:o});try{let d=(await a.listSims()).find(m=>m.id===t);if(!d||d.readyState!=="open")return!0}catch{return!0}finally{a.close()}await $(s)}return!1}function Vt(e){let o=e.meta;if(!o||o.sootsimHostDriver!=="playwright")return null;let t=Number(o.sootsimHostPid);return!Number.isInteger(t)||t<=1||t===process.pid?null:t}function Gt(e){if(!e.connectAckFile)return!1;try{return L.writeFileSync(e.connectAckFile,`${JSON.stringify({connectedAt:Date.now(),pid:e.pid??null})}
4
- `,{flag:"w"}),!0}catch{return!1}}function Qe(e){if(e.diagnosticLogPath)try{let o=L.readFileSync(e.diagnosticLogPath,"utf8").trim();if(!o){console.error(` ${T.basename(e.diagnosticLogPath)} was empty`);return}let t=o.length>4e3?`\u2026
5
- ${o.slice(-4e3)}`:o;console.error(` ${T.basename(e.diagnosticLogPath)}:`),console.error(t)}catch(o){let t=o instanceof Error?o.message:String(o);console.error(` failed to read ${T.basename(e.diagnosticLogPath)}: ${t}`)}}function pe(e){try{return process.kill(e,0),!0}catch(o){return o?.code==="EPERM"}}async function Jt(e,o=2500){let t=Date.now()+o;for(;Date.now()<t;){if(!pe(e))return!0;await $(100)}return!pe(e)}function Qt(e){let o=Ke("ps",["-o","command=","-p",String(e)],{encoding:"utf8",stdio:["ignore","pipe","pipe"]}),t=Ke("ps",["eww","-o","command=","-p",String(e)],{encoding:"utf8",stdio:["ignore","pipe","pipe"]});if(o.status!==0||t.status!==0)return!1;let n=(o.stdout||"").trimEnd(),r=(t.stdout||"").trimEnd();return(r.startsWith(n)?r.slice(n.length):r).includes("SOOTSIM_PW_URL=")}async function me(e,o){let t=new Set(o),n=new Set;for(let r of e){if(!t.has(r.id))continue;let s=Vt(r);s&&n.add(s)}for(let r of n){if(!Qt(r)){console.log(` skipped pid ${r}: not a sootsim playwright host (stale sim record)`);continue}try{process.kill(r,"SIGTERM")}catch{}if(await Jt(r)){console.log(` closed playwright host process ${r}`);continue}try{process.kill(r,"SIGKILL"),console.log(` force-closed playwright host process ${r}`)}catch{}}}function J(e,o){if(o){let r=o.trim(),s=e.find(i=>i.id===r);if(!s)throw new Error(`no sim connected with id ${r}`);return s}let t=e.find(r=>r.isPrimary&&r.readyState==="open");if(t)return t;let n=e.find(r=>r.readyState==="open");if(n)return n;throw new Error("no sim connected")}function B(e,o,t){console.log(` ${t==="current sim"?"loaded":"opened"}: ${e} [${t}]`),console.log(` current sim: ${o.id}`),console.log(JSON.stringify({simId:o.id,url:o.url},null,2))}async function D(e,o,t){if(t.includes("--no-describe"))return;let n=process.env.SOOTSIM_QUIET_TARGET_NOTICE;process.env.SOOTSIM_QUIET_TARGET_NOTICE="1";try{await Yt(e,o,{stableMs:150,maxMs:400});let r=v(e,{commandTimeoutMs:3e3,simId:o,cliLabel:"open --describe",simIdSource:"flag"});try{let s=null;try{s=await r.send({type:"evaluate",code:_e})}catch{}if(s&&!(s.flag===!0&&!s.loadingText&&Ue(s))){let m=s.loadingText?`still showing "${s.loadingText}"`:s.flag!==!0?"guest ready event has not fired":s.targets<=0?"no visible app content is inspectable yet":"app tree is still stabilizing";console.log(` app still loading: ${m} (nodes: ${s.nodes}, targets: ${s.targets})`),console.log(" before interacting, run: sootsim wait ready --max-ms 120000")}let a=`(async () => {
6
- const t = window.__sootsimTest
7
- const ms = window.SootSim?.bridges?.mainShell
8
- if (!t) return null
9
- let shell = null
10
- try { shell = ms?.getState ? await ms.getState() : null } catch {}
11
- const tree = await t.dumpTree(12, ${JSON.stringify({describe:!0,verbose:!1,filter:""})})
12
- return { tree, shell }
13
- })()`,l=await r.send({type:"evaluate",code:a});if(!l?.tree)return;if(console.log(""),l.shell?.state){let d=[`state=${l.shell.state}`,l.shell.activeApp?`app=${l.shell.activeApp}`:null].filter(Boolean);console.log(` shell: ${d.join(" ")}`)}console.log(l.tree)}finally{r.close()}}catch{}finally{n===void 0?delete process.env.SOOTSIM_QUIET_TARGET_NOTICE:process.env.SOOTSIM_QUIET_TARGET_NOTICE=n}}async function Yt(e,o,t){let n=Date.now()+t.maxMs,r="(async () => (await window.__sootsimTest?.getNodeCount?.()) || 0)()",s=v(e,{commandTimeoutMs:2e3,simId:o,simIdSource:"flag"});try{let i=-1,a=0;for(;Date.now()<n;){let l=-1;try{let d=await s.send({type:"evaluate",code:r});typeof d=="number"&&(l=d)}catch{}if(l>=0&&l===i){if(Date.now()-a>=t.stableMs)return}else i=l,a=Date.now();await $(50)}}finally{s.close()}}async function Zt(e,o={}){let t=E(e,{port:o.port,commandTimeoutMs:o.timeoutMs});t.positional.length!==1&&(console.error(" sootsim open: expected exactly one <url-or-route>"),console.error(" examples: sootsim open /settings | sootsim open myapp://settings"),process.exit(1));let n;try{n=vt(t.positional[0]??"")}catch(i){console.error(` sootsim open: ${i instanceof Error?i.message:String(i)}`),process.exit(1)}let r=M(t),s=t.simId?` --sim ${t.simId}`:"";try{let i=await r.send({type:"call",path:"SootSim.bridges.test.openDeepLink",args:[n]});if(St(i)&&i.ok===!1)throw new Error(typeof i.error=="string"?i.error:"deep-link dispatch failed");console.log(` opened deep link: ${n}`)}catch(i){console.error(` link failed: ${i instanceof Error?i.message:String(i)}`),await R(r,{errorsCommand:`sootsim get errors 5${s}`,warningsCommand:`sootsim get warnings 5${s}`,requestsCommand:`sootsim get requests 5${s}`}),process.exit(1)}finally{r.close()}}async function Do(e,o={}){let t=E(e,{port:o.port,commandTimeoutMs:o.timeoutMs,stripBooleanFlags:["--new","--headless","--headed","--ephemeral","--hot","--no-hmr","--no-describe"],stripValueFlags:["--base-url","--replace","--driver","--profile","--cdp-port","--browser","--device"]}),n=e.find((c,p)=>e[p-1]==="--profile"),r=e.includes("--ephemeral"),s=e.find((c,p)=>e[p-1]==="--cdp-port"),i=s?Number(s):void 0;s&&(!Number.isFinite(i)||i<=0)&&(console.error(` sootsim open: --cdp-port must be a positive port number, got "${s}"`),process.exit(1)),n&&r&&(console.error(" sootsim open: --profile cannot be combined with --ephemeral"),process.exit(1));let a=n?Ie(n).id:void 0,l=!!a||r,d=e.includes("--new")||l,m=Ot(e);d&&t.simIdSource==="flag"&&(console.error(" sootsim open: --new, --profile, and --ephemeral cannot be combined with --sim"),process.exit(1));let u=t.positional[0]||"";if($t(u)){d&&(console.error(" sootsim open: deep links target the current app; remove --new, --profile, or --ephemeral"),process.exit(1)),await Zt(e,o);return}if(Et(u)){let c=(()=>{try{return P(new URL(u).hostname)}catch{return!1}})();console.log(" that\u2019s a SootSim preview/build link \u2014 a full player page, not a driveable sim."),console.log(" opening it in your browser for viewing\u2026");try{await le(u,{background:!1})}catch(p){console.error(` could not launch a browser: ${p instanceof Error?p.message:String(p)}`),console.error(` open it yourself: ${u}`),process.exit(1)}console.log(c?" to drive it under the CLI, point `sootsim open` at the app\u2019s dev port instead (e.g. `sootsim open 8081`).":" the CLI can\u2019t drive a remote preview (the engine only attaches to the local bridge from localhost). to drive the app, run it locally and `sootsim open <port>`.");return}let g=e.find((c,p)=>e[p-1]==="--base-url"),Q=o.port!==void 0||e.some(c=>c==="--port"||c==="-p"||c.startsWith("--port="));if(g&&!Q){let c=ie(g);c&&(t.wsPort=c)}t.wsPort=await xt(t.wsPort);let y=e.find((c,p)=>e[p-1]==="--driver")||"",tt=yt(e,y);i&&y!=="playwright"&&(console.error(" sootsim open: --cdp-port is only honored by the playwright driver \u2014 add `--driver playwright`"),process.exit(1));let x=e.find((c,p)=>e[p-1]==="--browser");x&&y!=="playwright"&&(console.error(" sootsim open: --browser is only honored by the playwright driver \u2014 add `--driver playwright`"),process.exit(1));let A=x==="chromium"||x==="webkit"||x==="firefox"?x:void 0;x&&!A&&(console.error(` sootsim open: --browser must be chromium, webkit, or firefox \u2014 got "${x}"`),process.exit(1)),i&&A&&A!=="chromium"&&(console.error(" sootsim open: --cdp-port requires the chromium engine"),process.exit(1));let fe=e.includes("--hot"),he=e.includes("--no-hmr");fe&&he&&(console.error(" sootsim open: --hot and --no-hmr cannot be combined"),process.exit(1));let ot=fe?!0:he?!1:y!=="playwright",k=e.find((c,p)=>e[p-1]==="--device");k&&!(k in oe)&&(console.error(` sootsim open: unknown device "${k}"`),console.error(` known devices: ${$e().join(", ")}`),process.exit(1));let Y=k?oe[k]:void 0,N={hot:ot,device:k},nt=Oe(t.wsPort),I=g||nt?.shellBaseUrl||Xe(),ge=e.includes("--base-url");Be(t.wsPort,I);let we=_();if(!y&&!d&&(t.simIdSource==="flag"||t.simIdSource==="saved"&&!!we)){let c=M(t),p=t.simId?` --sim ${t.simId}`:"",f=!1;try{let h=null;try{let w=await c.listSims();if(t.simIdSource==="saved"?(h=w.find(C=>C.id===we&&C.readyState==="open")??null,h||U()):h=J(w,t.simId),!h)if(t.simIdSource==="saved")f=!0;else throw new Error("no sim connected");if(!f&&h){let C=ge||ue(u)?I:Ge(h,I),W=await z(u,K(C,m),N);c.send({type:"evaluate",simId:h.id,code:`window.location.href = ${JSON.stringify(W)}`}).catch(()=>{})}}catch(w){console.error(` open failed: ${w instanceof Error?w.message:String(w)}`),await R(c,{errorsCommand:`sootsim get errors 5${p}`,warningsCommand:`sootsim get warnings 5${p}`,requestsCommand:`sootsim get requests 5${p}`}),process.exit(1)}if(!f&&h){await $(1500);let w=await Ht(t.wsPort,t.commandTimeoutMs,h.id);w||(console.error(" timed out waiting for current sim to load target"),process.exit(1)),w.bridge.close(),b(h.id);let C=ge||ue(u)?I:Ge(h,I),W=await z(u,K(C,m),N);B(W,{...h,url:W},"current sim"),await D(t.wsPort,h.id,e);return}}finally{c.close()}}let be=K(I,m),rt=await z(u,be,N),ye=`cli-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`,S=await Ft(u,be,ye,N),Z={newWindow:!0},F=c=>c.url?.includes(`inspectOpen=${ye}`)??!1;if(y){bt(y)||(console.error(` unknown driver "${y}" \u2014 run \`sootsim list --drivers\``),process.exit(1));let c=ce(y);c||(console.error(` unknown driver "${y}" \u2014 run \`sootsim list --drivers\``),process.exit(1));let p=wt(),f=await c.launch({url:S,bridgePort:ie(I)??t.wsPort,headless:tt,newWindow:Z.newWindow,profileId:a,ephemeralProfile:r,cdpPort:i,browser:A,device:k,viewport:Y?{width:Y.width+120,height:Y.height+60}:void 0,connectTimeoutMs:p.hostTimeoutMs});f.launched||(console.error(` ${c.name} driver: ${f.message}`),process.exit(1));let h=await qt(t.wsPort,t.commandTimeoutMs,F,f.pid,{attempts:p.attempts,intervalMs:p.intervalMs});if(h.kind==="host-exit"&&(Qe(f),console.error(` ${c.name} host crashed \u2014 sim is no longer attached`),process.exit(1)),h.kind==="timeout"){if(f.pid)try{process.kill(f.pid,"SIGTERM"),console.error(` closed ${c.name} host process ${f.pid}`)}catch{}Qe(f),console.error(` timed out after ${p.timeoutMs}ms waiting for opened sim to connect`),process.exit(1)}let w=h.sim;b(w.id),Gt(f),B(S,w,`${c.name} driver`),await D(t.wsPort,w.id,e);return}if(l){let c=O();c||(console.error(" profiles require electron or playwright; install the desktop companion or use `--driver playwright`"),process.exit(1));try{(await ae(S,c,{profileId:a,ephemeralProfile:r})).launched||(console.error(" desktop companion failed to start"),process.exit(1))}catch(f){console.error(` desktop companion failed: ${f instanceof Error?f.message:String(f)}`),process.exit(1)}let p=await de(t.wsPort,t.commandTimeoutMs,F,{attempts:40,intervalMs:500});p||(console.error(" timed out waiting for profiled sim to connect"),process.exit(1)),b(p.id),B(S,p,"desktop companion"),await D(t.wsPort,p.id,e);return}let X=!1,ee=!1;try{let c=v(t.wsPort,{commandTimeoutMs:2e3});try{await c.listSims(),X=!0}finally{c.close()}}catch{}if(X)try{let c=v(t.wsPort,{commandTimeoutMs:3e3});try{await c.openUrl(S,Z),ee=!0}finally{c.close()}}catch{}if(!ee){let c=O();if(c)try{if((await ae(S,c)).launched){let f=await de(t.wsPort,t.commandTimeoutMs,F,{attempts:20,intervalMs:500});if(f){b(f.id),B(S,f,"desktop companion"),await D(t.wsPort,f.id,e);return}}}catch{}try{await le(S,Z)}catch(p){console.error(` open failed: ${p instanceof Error?p.message:String(p)}`),ce("playwright")?.availability().available?console.error(" no system browser found \u2014 retry with `sootsim open \u2026 --driver playwright` for a headless sim."):console.error(" run `sootsim list --drivers` to see available drivers."),process.exit(1)}if(!X){console.log(` opened: ${rt}`),We(t.wsPort);return}}let H=await de(t.wsPort,t.commandTimeoutMs,F,{attempts:30,intervalMs:500});H||(console.error(" timed out waiting for opened sim to connect"),process.exit(1)),b(H.id),B(S,H,ee?"bridge":"direct shell open"),await D(t.wsPort,H.id,e)}async function et(e,o={}){let t=E(e,{port:o.port,commandTimeoutMs:o.timeoutMs,stripBooleanFlags:["--force"]}),n=e.includes("--force"),r=M(t),s=t.simId?` --sim ${t.simId}`:"";try{try{let i=await r.listSims(),a=J(i,t.positional[0]||t.simId);if(a.lockedBy&&a.lockExpiresAt&&a.lockExpiresAt>Date.now()){let l=Math.max(0,Math.round((a.lockExpiresAt-Date.now())/1e3));a.lockedByKind==="user-active"&&(console.error(` refused: ${a.id} is locked by the active user (${l}s) \u2014 that's a live human tab`),console.error(" run `sootsim open --new` for a fresh investigation sim"),process.exit(1)),n||(console.error(` refused: ${a.id} is leased by ${a.lockedBy} (${l}s)`),console.error(` \`sootsim use ${a.id} --force\` to take it, or \`sootsim open --new\` for a fresh sim`),process.exit(1))}await r.focusSim(a.id),b(a.id),console.log(` using: ${a.id}`)}catch(i){console.error(` use failed: ${i instanceof Error?i.message:String(i)}`),await R(r,{errorsCommand:`sootsim get errors 5${s}`,warningsCommand:`sootsim get warnings 5${s}`,requestsCommand:`sootsim get requests 5${s}`}),process.exit(1)}}finally{r.close()}}async function Lo(e,o={}){await et(e,o)}async function Ao(e,o={}){await et(e,o)}async function No(e,o={}){let t=E(e,{port:o.port,commandTimeoutMs:o.timeoutMs,stripBooleanFlags:["--force"]}),n=e.includes("--force"),r=M(t);try{try{let s=await r.listSims(),i=J(s,t.positional[0]||t.simId),a=n&&i.lockedBy&&i.lockedByKind!=="user-active"?i.lockedBy:null,l=await r.claim(i.id,{force:n});b(i.id);let d=Math.max(0,Math.round((l.lockExpiresAt-Date.now())/1e3)),m=l.bootedCount>0?` (booted ${l.bootedCount})`:"";console.log(` claimed: ${l.simId} [${d}s]${m}`),a&&console.log(` took over from: ${a}`)}catch(s){if(s instanceof De){let i=Math.max(0,Math.round(s.lock.expiresInMs/1e3));console.error(` claim failed: locked by ${s.lock.by} for ${i}s more`),console.error(" use --force to take it, or `sootsim open --new` for a fresh sim"),process.exit(1)}console.error(` claim failed: ${s instanceof Error?s.message:String(s)}`),process.exit(1)}}finally{r.close()}}async function Xt(e,o,t,n){if(n.length===0)return{closed:[],remaining:[]};await Promise.all(n.map(s=>e.closeSim(s).catch(()=>{})));let r=new Set(n);for(let s=0;s<40;s++){let i=[];try{let a=v(o,{commandTimeoutMs:t});try{i=(await a.listSims()).filter(d=>r.has(d.id)&&d.readyState==="open").map(d=>d.id)}finally{a.close()}}catch{i=[]}if(i.length===0)return{closed:[...r],remaining:[]};if(s===39)return{closed:[...r].filter(a=>!i.includes(a)),remaining:i};await $(250)}return{closed:[...r],remaining:[]}}function eo(e,o){let t=e.filter(u=>u.readyState==="open"),n=t.map(u=>u.id),r=o.explicitKeepId?.trim()||"",s=o.savedKeepId?.trim()||"",i=s?t.some(u=>u.id===s):!1,a=s&&!i?s:null,l=null,d=null,m=null;if(o.closeOthers)if(r){let u=t.find(g=>g.id===r);u?l=u.id:d=r}else if(s&&i)l=s;else{let u=t.find(g=>g.isPrimary)??t[0]??null;u&&(l=u.id,s&&!i&&(m=u.id))}return{openIds:n,keepId:l,targets:d?[]:n.filter(u=>u!==l),staleSavedId:a,missingExplicitKeepId:d,fallbackKeepId:m}}async function Fo(e,o={}){let t=E(e,{port:o.port,commandTimeoutMs:o.timeoutMs,stripBooleanFlags:["--all","--others"]}),n=M(t),r=t.simId?` --sim ${t.simId}`:"",s=e.includes("--all"),i=e.includes("--others");if(s||i){try{let a=await n.listSims(),l=_(),d=t.positional[0]||(t.simIdSource==="flag"?t.simId:void 0),m=eo(a,{closeOthers:i,explicitKeepId:d,savedKeepId:l});if(m.staleSavedId&&U(),m.fallbackKeepId&&(b(m.fallbackKeepId),console.log(` saved sim ${m.staleSavedId} is gone \u2014 keeping primary ${m.fallbackKeepId}`)),m.missingExplicitKeepId&&(console.error(` close failed: keep sim ${m.missingExplicitKeepId} is not connected; not closing other sims`),process.exit(1)),m.targets.length===0){console.log(m.keepId?` nothing to close \u2014 only the kept sim ${m.keepId} is connected`:m.staleSavedId?` nothing to close \u2014 no sims connected (cleared stale current sim ${m.staleSavedId})`:" nothing to close \u2014 no sims connected");return}let u=await Xt(n,t.wsPort,t.commandTimeoutMs,m.targets);await me(a,m.targets);let g=_();g&&u.closed.includes(g)&&(m.keepId?b(m.keepId):U());let Q=` closed ${u.closed.length} sim(s)${m.keepId?` (kept ${m.keepId})`:""}`;console.log(Q),u.remaining.length>0&&(console.error(` close failed: still connected: ${u.remaining.join(", ")}`),process.exit(1))}catch(a){console.error(` close failed: ${a instanceof Error?a.message:String(a)}`),process.exit(1)}finally{n.close()}return}try{try{let a=await n.listSims(),l=J(a,t.positional[0]||t.simId),d=a.find(u=>u.id!==l.id&&u.readyState==="open");await n.closeSim(l.id),await zt(t.wsPort,t.commandTimeoutMs,l.id)||(await me(a,[l.id]),console.error(` close failed: ${l.id} is still connected`),process.exit(1)),await me(a,[l.id]),_()===l.id&&(d?b(d.id):U()),console.log(` closed: ${l.id}`)}catch(a){console.error(` close failed: ${a instanceof Error?a.message:String(a)}`),await R(n,{errorsCommand:`sootsim get errors 5${r}`,warningsCommand:`sootsim get warnings 5${r}`,requestsCommand:`sootsim get requests 5${r}`}),process.exit(1)}}finally{n.close()}}export{io as a,mt as b,ao as c,wt as d,vt as e,Oo as f,Xe as g,z as h,Ft as i,Wt as j,Bo as k,de as l,qt as m,Vt as n,Gt as o,me as p,Zt as q,Do as r,Lo as s,Ao as t,No as u,Xt as v,eo as w,Fo as x};
@@ -1 +0,0 @@
1
- /*! sootsim v0.1.268 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.268 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a}from"./chunk-F7DMZRQX.js";import"./chunk-RG6QF6DY.js";export{a as getCliVersion};
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.268 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a,b,c,d,e}from"./chunk-YLMP3AEX.js";import"./chunk-EH3A54PO.js";import"./chunk-GUXMUE5A.js";import"./chunk-SV6D5FXN.js";import"./chunk-EG3JCOGS.js";import"./chunk-M2LYCMW4.js";import"./chunk-XIBSRCKK.js";import"./chunk-346C7547.js";import"./chunk-YMTVQA6W.js";import"./chunk-ZTOWO5CK.js";import"./chunk-K5ZMEBMQ.js";import"./chunk-F7DMZRQX.js";import"./chunk-YUDUKMJV.js";import"./chunk-OOVGROTR.js";import"./chunk-RG6QF6DY.js";export{c as daemonInstall,b as getDaemonServiceStatus,a as runDaemon,d as teardownDaemonService,e as teardownSootsimHome};
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.268 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import"./chunk-2LWDKYJ3.js";import{f as a,g as b,h as c,i as d,j as e,k as f,l as g,m as h,n as i}from"./chunk-EPKHW3XW.js";import"./chunk-PN2LR6T4.js";import"./chunk-LJGOZ77E.js";import"./chunk-YMTVQA6W.js";import"./chunk-K5ZMEBMQ.js";import"./chunk-RG6QF6DY.js";export{e as ALL_DRIVERS,i as buildDriverListRows,a as chromiumDriver,b as electronDriver,f as getAllDrivers,g as getDriver,c as playwrightDriver,h as resolveDriver,d as systemDriver};
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.268 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{c,d,e,f,g,h}from"./chunk-WT3OYHU7.js";import"./chunk-IWJTCFAE.js";import"./chunk-5JH5F4TM.js";import{c as a,d as b}from"./chunk-LOOHTTDV.js";import"./chunk-74QJWGDX.js";import"./chunk-JERNRAFO.js";import"./chunk-6TXGR4HK.js";import"./chunk-Y3IYHVEX.js";import"./chunk-YNMYUJYR.js";import"./chunk-ZHSXFJ7W.js";import"./chunk-EPKHW3XW.js";import"./chunk-PN2LR6T4.js";import"./chunk-CWC7QMVM.js";import"./chunk-7XWLSCXZ.js";import"./chunk-LJGOZ77E.js";import"./chunk-V27FSRID.js";import"./chunk-KR4LGQWN.js";import"./chunk-FGKDYXO3.js";import"./chunk-ITQ7WKNC.js";import"./chunk-H2WCONSC.js";import"./chunk-EH3A54PO.js";import"./chunk-GUXMUE5A.js";import"./chunk-M2LYCMW4.js";import"./chunk-XIBSRCKK.js";import"./chunk-346C7547.js";import"./chunk-YMTVQA6W.js";import"./chunk-ZTOWO5CK.js";import"./chunk-K5ZMEBMQ.js";import"./chunk-FGY5ESGU.js";import"./chunk-OOVGROTR.js";import"./chunk-RG6QF6DY.js";export{e as discoverSootsimUrl,c as getLastFlowPreviewUploadResult,d as getLastFlowTraceSteps,g as hoistLeadingSimFlag,a as parseFlowFile,f as runFlowPlayback,h as runMaestroAuthoring,b as validateFlowFile};
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.268 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a,b,c}from"./chunk-SV6D5FXN.js";import"./chunk-EG3JCOGS.js";import"./chunk-M2LYCMW4.js";import"./chunk-XIBSRCKK.js";import"./chunk-346C7547.js";import"./chunk-YMTVQA6W.js";import"./chunk-ZTOWO5CK.js";import"./chunk-K5ZMEBMQ.js";import"./chunk-F7DMZRQX.js";import"./chunk-YUDUKMJV.js";import"./chunk-OOVGROTR.js";import"./chunk-RG6QF6DY.js";export{c as printCommandHelp,b as printGroupHelp,a as printHelp};
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.268 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{j as a,k as b}from"./chunk-LOOHTTDV.js";import"./chunk-74QJWGDX.js";import"./chunk-Y3IYHVEX.js";import"./chunk-YNMYUJYR.js";import"./chunk-ZHSXFJ7W.js";import"./chunk-EPKHW3XW.js";import"./chunk-PN2LR6T4.js";import"./chunk-CWC7QMVM.js";import"./chunk-7XWLSCXZ.js";import"./chunk-LJGOZ77E.js";import"./chunk-V27FSRID.js";import"./chunk-KR4LGQWN.js";import"./chunk-FGKDYXO3.js";import"./chunk-ITQ7WKNC.js";import"./chunk-H2WCONSC.js";import"./chunk-M2LYCMW4.js";import"./chunk-XIBSRCKK.js";import"./chunk-346C7547.js";import"./chunk-YMTVQA6W.js";import"./chunk-ZTOWO5CK.js";import"./chunk-K5ZMEBMQ.js";import"./chunk-FGY5ESGU.js";import"./chunk-OOVGROTR.js";import"./chunk-RG6QF6DY.js";export{a as printShellPerfReport,b as runInspect};
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.268 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a}from"./chunk-3MZJ2KVR.js";import"./chunk-PN2LR6T4.js";import"./chunk-5MIRQ65V.js";import"./chunk-RG6QF6DY.js";export{a as runInstallDesktop};
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.268 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a,b,c}from"./chunk-V27FSRID.js";import"./chunk-RG6QF6DY.js";export{c as __withOptionalDemoAppsForTests,a as loadOptionalDemoApps,b as optionalDemoAppsSync};
@@ -1,2 +0,0 @@
1
- /*! sootsim v0.1.268 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import{a}from"./chunk-RCU4A7LU.js";import"./chunk-NPSDN7D7.js";import"./chunk-ITQ7WKNC.js";import"./chunk-346C7547.js";import"./chunk-YMTVQA6W.js";import"./chunk-K5ZMEBMQ.js";import"./chunk-RG6QF6DY.js";export{a as runRuntime};