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.
- package/README.md +7 -3
- package/detox/index.ts +5 -2
- package/dist-cli/bin.js +4 -4
- package/dist-cli/chunks/{agent-KQSZFG6R.js → agent-4YXUPSJ2.js} +2 -2
- package/dist-cli/chunks/{agent-wrapper-DLDQVS7O.js → agent-wrapper-BMJPWHWK.js} +2 -2
- package/dist-cli/chunks/{app-fonts-6XVNNHAB.js → app-fonts-EDRH6ETC.js} +2 -2
- package/dist-cli/chunks/{assert-DLGUW4JS.js → assert-CRDV324D.js} +2 -2
- package/dist-cli/chunks/{auth-MTSJWWMS.js → auth-WYRQIJEN.js} +2 -2
- package/dist-cli/chunks/beta-NBANSL2S.js +2 -0
- package/dist-cli/chunks/{camera-MGJUBHWZ.js → camera-5TO6IVBP.js} +3 -3
- package/dist-cli/chunks/{chunk-LJGOZ77E.js → chunk-2J3E5TPS.js} +1 -1
- package/dist-cli/chunks/{chunk-GUXMUE5A.js → chunk-3VIMSXQZ.js} +2 -2
- package/dist-cli/chunks/{chunk-YUDUKMJV.js → chunk-3ZOF2BTJ.js} +1 -1
- package/dist-cli/chunks/{chunk-RCU4A7LU.js → chunk-44ISBOEK.js} +3 -3
- package/dist-cli/chunks/{chunk-F7DMZRQX.js → chunk-4HPWZVBS.js} +1 -1
- package/dist-cli/chunks/{chunk-K5ZMEBMQ.js → chunk-557IYHPC.js} +1 -1
- package/dist-cli/chunks/{chunk-RG6QF6DY.js → chunk-5IHDZOMR.js} +1 -1
- package/dist-cli/chunks/{chunk-XIBSRCKK.js → chunk-6CI73D3X.js} +2 -2
- package/dist-cli/chunks/chunk-6JLIPPNB.js +2 -0
- package/dist-cli/chunks/{chunk-YMTVQA6W.js → chunk-74HIBIJQ.js} +4 -4
- package/dist-cli/chunks/{chunk-6TXGR4HK.js → chunk-ABSUFSOH.js} +2 -2
- package/dist-cli/chunks/{chunk-NPSDN7D7.js → chunk-AG563BSO.js} +2 -2
- package/dist-cli/chunks/{chunk-IWJTCFAE.js → chunk-AMA3YGJ5.js} +2 -2
- package/dist-cli/chunks/{chunk-EG3JCOGS.js → chunk-AMVYE3F4.js} +2 -2
- package/dist-cli/chunks/{chunk-LOOHTTDV.js → chunk-B5IBLYEO.js} +3 -3
- package/dist-cli/chunks/{chunk-M2LYCMW4.js → chunk-DCJXHSIA.js} +2 -2
- package/dist-cli/chunks/{chunk-ITQ7WKNC.js → chunk-ERXCR7NU.js} +2 -2
- package/dist-cli/chunks/{chunk-KR4LGQWN.js → chunk-FCMEOOQE.js} +2 -2
- package/dist-cli/chunks/{chunk-YNMYUJYR.js → chunk-FHPXOPMC.js} +2 -2
- package/dist-cli/chunks/{chunk-V27FSRID.js → chunk-FNBFRG64.js} +1 -1
- package/dist-cli/chunks/{chunk-5JH5F4TM.js → chunk-GAYG7AO4.js} +1 -1
- package/dist-cli/chunks/chunk-GQDQO3KU.js +5 -0
- package/dist-cli/chunks/{chunk-JERNRAFO.js → chunk-HWGKGIWE.js} +2 -2
- package/dist-cli/chunks/{chunk-YLMP3AEX.js → chunk-IIXRM6BB.js} +2 -2
- package/dist-cli/chunks/{chunk-EPKHW3XW.js → chunk-LHMVSKKD.js} +3 -3
- package/dist-cli/chunks/chunk-M32JVXHU.js +5 -0
- package/dist-cli/chunks/{chunk-FGKDYXO3.js → chunk-M5VURHXD.js} +1 -1
- package/dist-cli/chunks/{chunk-6YB3URLB.js → chunk-MD24VVKT.js} +2 -2
- package/dist-cli/chunks/{chunk-CWC7QMVM.js → chunk-MYBY7OHL.js} +1 -1
- package/dist-cli/chunks/{chunk-7XWLSCXZ.js → chunk-NTO6SKS5.js} +1 -1
- package/dist-cli/chunks/{chunk-H2WCONSC.js → chunk-OUKH6UGN.js} +1 -1
- package/dist-cli/chunks/{chunk-OOVGROTR.js → chunk-PDFKRVDC.js} +1 -1
- package/dist-cli/chunks/{chunk-74QJWGDX.js → chunk-SDKIUJUO.js} +2 -2
- package/dist-cli/chunks/chunk-SLR3HWMB.js +13 -0
- package/dist-cli/chunks/{chunk-WUOPQL2J.js → chunk-SW5HZ5LK.js} +1 -1
- package/dist-cli/chunks/{chunk-WT3OYHU7.js → chunk-TIONGRTA.js} +3 -3
- package/dist-cli/chunks/{chunk-EH3A54PO.js → chunk-TLNGREAA.js} +2 -2
- package/dist-cli/chunks/{chunk-5MIRQ65V.js → chunk-TMWNOQAA.js} +1 -1
- package/dist-cli/chunks/{chunk-3MZJ2KVR.js → chunk-TZH4VH32.js} +3 -3
- package/dist-cli/chunks/{chunk-FGY5ESGU.js → chunk-UPRCATUH.js} +2 -2
- package/dist-cli/chunks/chunk-XTTXSDDA.js +1 -0
- package/dist-cli/chunks/{chunk-ZTOWO5CK.js → chunk-YKK2QUGO.js} +1 -1
- package/dist-cli/chunks/{chunk-SV6D5FXN.js → chunk-ZTKDHPA6.js} +2 -2
- package/dist-cli/chunks/chunk-ZZH2AFPJ.js +1 -0
- package/dist-cli/chunks/cli-version-BLKUTVJ2.js +2 -0
- package/dist-cli/chunks/{compat-IVBKZVGH.js → compat-IZEDAAUW.js} +3 -3
- package/dist-cli/chunks/{config-PQ3KBTIM.js → config-I4CXZ6M7.js} +2 -2
- package/dist-cli/chunks/{control-BKTYM5XP.js → control-DVF7UL5D.js} +2 -2
- package/dist-cli/chunks/daemon-FPKQPSSY.js +2 -0
- package/dist-cli/chunks/{debug-HRR2LK2J.js → debug-5X2F2WRP.js} +3 -3
- package/dist-cli/chunks/{desktop-466O4AQA.js → desktop-JHEYQZGF.js} +3 -3
- package/dist-cli/chunks/{detox-UH44KHQJ.js → detox-W64UENQG.js} +2 -2
- package/dist-cli/chunks/{device-FZLXTC3W.js → device-ZBSW2EHS.js} +2 -2
- package/dist-cli/chunks/{diagnose-RJMRI27P.js → diagnose-WER4X3P5.js} +2 -2
- package/dist-cli/chunks/drivers-6P53DLMM.js +2 -0
- package/dist-cli/chunks/{film-VL66UAM3.js → film-TIXNUTR6.js} +3 -3
- package/dist-cli/chunks/flow-53XFDYLL.js +2 -0
- package/dist-cli/chunks/help-MPYJLD7I.js +2 -0
- package/dist-cli/chunks/{hidden-runtime-alias-3ZAR7GCH.js → hidden-runtime-alias-R3JH3INM.js} +2 -2
- package/dist-cli/chunks/{home-paths-S2GRJWV3.js → home-paths-CNNARPCT.js} +2 -2
- package/dist-cli/chunks/inspect-JBDDYUA5.js +2 -0
- package/dist-cli/chunks/install-desktop-BBP7AMK4.js +2 -0
- package/dist-cli/chunks/{login-TR3YAEA2.js → login-6NCCZ3CZ.js} +4 -4
- package/dist-cli/chunks/{logout-WPY2DOYZ.js → logout-C4VKXUH4.js} +2 -2
- package/dist-cli/chunks/{maestro-DSG7V2BA.js → maestro-ZRGFQ3MV.js} +3 -3
- package/dist-cli/chunks/{maestro-generate-6KA7PCN5.js → maestro-generate-A5XZS5GC.js} +3 -3
- package/dist-cli/chunks/{mode-QUYGPNBW.js → mode-IFFZ55HM.js} +2 -2
- package/dist-cli/chunks/optional-demo-registry-TQZA65K3.js +2 -0
- package/dist-cli/chunks/{perf-ELBRUVVU.js → perf-44KZNTIV.js} +2 -2
- package/dist-cli/chunks/{record-6PDTULUN.js → record-GZLZNXYZ.js} +3 -3
- package/dist-cli/chunks/runtime-F4FCEPPB.js +2 -0
- package/dist-cli/chunks/{screenshot-command-E2A4VY6D.js → screenshot-command-GL3STSWK.js} +3 -3
- package/dist-cli/chunks/{screenshots-capture-TRCRHK2E.js → screenshots-capture-QSSBWHN6.js} +2 -2
- package/dist-cli/chunks/serve-AFK6X2Q3.js +42 -0
- package/dist-cli/chunks/{setup-5BHQNK2L.js → setup-DYSDNEUE.js} +3 -3
- package/dist-cli/chunks/{skills-NQLI6WXW.js → skills-YXWQ43PZ.js} +2 -2
- package/dist-cli/chunks/{storage-SKARYTYK.js → storage-C7IS5GTM.js} +2 -2
- package/dist-cli/chunks/store-LVF2C2XZ.js +2 -0
- package/dist-cli/chunks/telemetry-5V3OXY6C.js +2 -0
- package/dist-cli/chunks/{timeline-DYJ4GKGE.js → timeline-FDTIHQ5V.js} +2 -2
- package/dist-cli/chunks/{upgrade-PHUUE5QV.js → upgrade-VRQCFJEI.js} +2 -2
- package/dist-cli/chunks/upload-CRCPDN6G.js +2 -0
- package/dist-cli/chunks/{version-XQQSXS3E.js → version-MP6NKJ27.js} +2 -2
- package/dist-cli/chunks/web-XYPFJHKW.js +2 -0
- package/dist-cli/chunks/{what-happened-I2N3FFIV.js → what-happened-IM6UH24Q.js} +2 -2
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +10 -10
- package/dist-lib/agent-sessions.cjs +29 -13
- package/dist-lib/attached-projects.cjs +33 -13
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +23 -6
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +6 -4
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +110 -54
- package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +1 -1
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/menu.cjs +1 -1
- package/dist-lib/menu.mjs +1 -1
- package/dist-lib/metro.cjs +1 -1
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/render-mode.cjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
- package/dist-lib/sdk.cjs +1 -1
- package/dist-lib/sdk.mjs +1 -1
- package/dist-lib/skills.cjs +220 -148
- package/dist-lib/vite.cjs +1 -1
- package/package.json +1 -1
- package/src/agent-daemon-client.ts +2 -2
- package/src/agent-identity.ts +7 -5
- package/src/attached-projects.ts +35 -11
- package/src/bridge-constants.ts +23 -4
- package/src/host/agent-host.ts +63 -14
- package/src/{agentbus-prompt.ts → team-machine-prompt.ts} +13 -20
- package/dist-cli/chunks/beta-7R4DRB3R.js +0 -2
- package/dist-cli/chunks/chunk-2LWDKYJ3.js +0 -1
- package/dist-cli/chunks/chunk-346C7547.js +0 -2
- package/dist-cli/chunks/chunk-CD2GF6PV.js +0 -5
- package/dist-cli/chunks/chunk-PN2LR6T4.js +0 -5
- package/dist-cli/chunks/chunk-Y3IYHVEX.js +0 -13
- package/dist-cli/chunks/chunk-ZHSXFJ7W.js +0 -1
- package/dist-cli/chunks/cli-version-362THKXA.js +0 -2
- package/dist-cli/chunks/daemon-SCTA3HTZ.js +0 -2
- package/dist-cli/chunks/drivers-S7D5OZQN.js +0 -2
- package/dist-cli/chunks/flow-IM5OXO5S.js +0 -2
- package/dist-cli/chunks/help-G5CN3KXU.js +0 -2
- package/dist-cli/chunks/inspect-WI7GXOH5.js +0 -2
- package/dist-cli/chunks/install-desktop-PVBWQQHY.js +0 -2
- package/dist-cli/chunks/optional-demo-registry-CROVHXTW.js +0 -2
- package/dist-cli/chunks/runtime-ITR3EUXS.js +0 -2
- package/dist-cli/chunks/serve-JLLSEZDN.js +0 -41
- package/dist-cli/chunks/store-VR5QRAYX.js +0 -2
- package/dist-cli/chunks/telemetry-PMYZDJGO.js +0 -2
- package/dist-cli/chunks/upload-OUKKXVNC.js +0 -2
- package/dist-cli/chunks/web-AZI3JODI.js +0 -2
package/dist-lib/vite.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
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
|
@@ -168,8 +168,8 @@ export class AgentDaemonClient {
|
|
|
168
168
|
async sendClaimedPrompt(
|
|
169
169
|
simId: string,
|
|
170
170
|
prompt: AgentPromptEnvelope,
|
|
171
|
-
): Promise<{ ok: true; routed: '
|
|
172
|
-
return this.send<{ ok: true; routed: '
|
|
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,
|
package/src/agent-identity.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
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
|
|
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 (!
|
|
17
|
+
if (!TEAM_MACHINE_SESSION_RE.test(sessionId)) return null
|
|
16
18
|
return sessionId
|
|
17
19
|
}
|
|
18
20
|
|
|
19
|
-
export function
|
|
20
|
-
return
|
|
21
|
+
export function isValidTeamMachineSessionId(sessionId: string): boolean {
|
|
22
|
+
return TEAM_MACHINE_SESSION_RE.test(sessionId)
|
|
21
23
|
}
|
package/src/attached-projects.ts
CHANGED
|
@@ -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
|
|
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
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
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)
|
package/src/bridge-constants.ts
CHANGED
|
@@ -106,20 +106,39 @@ export function resolveSootsimBridgePortForRuntimeLocation(
|
|
|
106
106
|
return resolveSootsimBridgePortForHttpPort({ httpPort, baseHttpPort })
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
export function
|
|
110
|
-
|
|
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
|
|
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',
|
|
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.
|
package/src/host/agent-host.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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: '
|
|
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 =
|
|
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
|
|
266
|
+
await sendPromptToTeamMachineSession({
|
|
254
267
|
sessionId,
|
|
255
268
|
prompt: this.normalizePromptEnvelope(msg),
|
|
256
269
|
})
|
|
257
|
-
return { ok: true, routed: '
|
|
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
|
-
|
|
534
|
-
|
|
535
|
-
if (
|
|
536
|
-
|
|
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
|
-
|
|
7
|
-
|
|
3
|
+
isValidTeamMachineSessionId,
|
|
4
|
+
teamMachineSessionIdFromCliIdentity,
|
|
8
5
|
} from './agent-identity.ts'
|
|
9
6
|
import type { AgentPromptEnvelope } from './agent-prompt.ts'
|
|
10
7
|
|
|
11
|
-
export {
|
|
8
|
+
export { teamMachineSessionIdFromCliIdentity } from './agent-identity.ts'
|
|
12
9
|
|
|
13
|
-
export function
|
|
10
|
+
export function formatTeamMachinePromptText(prompt: AgentPromptEnvelope): string {
|
|
14
11
|
return typeof prompt.text === 'string' ? prompt.text.trim() : ''
|
|
15
12
|
}
|
|
16
13
|
|
|
17
|
-
function
|
|
14
|
+
function resolveTeamMachineCommand(explicit?: string): string {
|
|
18
15
|
const fromArg = explicit?.trim()
|
|
19
16
|
if (fromArg) return fromArg
|
|
20
|
-
|
|
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
|
|
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 (!
|
|
35
|
-
throw new Error(`invalid
|
|
27
|
+
if (!isValidTeamMachineSessionId(sessionId)) {
|
|
28
|
+
throw new Error(`invalid Team Machine session id: ${sessionId || '<empty>'}`)
|
|
36
29
|
}
|
|
37
|
-
const text =
|
|
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 =
|
|
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(`
|
|
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
|
-
`
|
|
68
|
+
`tm send exited with ${signal ? `signal ${signal}` : `code ${code ?? 'unknown'}`}`,
|
|
76
69
|
),
|
|
77
70
|
)
|
|
78
71
|
})
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/*! sootsim v0.1.268 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
@@ -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,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-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};
|