sootsim 0.0.1
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 +197 -0
- package/dist-cli/bin.js +29 -0
- package/dist-cli/chunks/bridge-host-2EY7Z4AO.js +2 -0
- package/dist-cli/chunks/chunk-3C3ZH7PP.js +4 -0
- package/dist-cli/chunks/chunk-3R4ZZESY.js +119 -0
- package/dist-cli/chunks/chunk-64TOMNZX.js +37 -0
- package/dist-cli/chunks/chunk-74XPLOV4.js +2 -0
- package/dist-cli/chunks/chunk-7LMDCMSI.js +8 -0
- package/dist-cli/chunks/chunk-7X6OPSRD.js +2 -0
- package/dist-cli/chunks/chunk-A2CZQIWO.js +1 -0
- package/dist-cli/chunks/chunk-CKZ376AY.js +322 -0
- package/dist-cli/chunks/chunk-E522F5JW.js +2 -0
- package/dist-cli/chunks/chunk-E5UBZEYR.js +2 -0
- package/dist-cli/chunks/chunk-G5MR66EB.js +180 -0
- package/dist-cli/chunks/chunk-GPVPHE2B.js +3 -0
- package/dist-cli/chunks/chunk-HOIHCO7S.js +3 -0
- package/dist-cli/chunks/chunk-J2S3OCWA.js +69 -0
- package/dist-cli/chunks/chunk-JSF5LPNT.js +176 -0
- package/dist-cli/chunks/chunk-KQWZZ56P.js +2 -0
- package/dist-cli/chunks/chunk-KSACMDXK.js +3 -0
- package/dist-cli/chunks/chunk-KSB6MSZ4.js +34 -0
- package/dist-cli/chunks/chunk-KXYKAYYB.js +51 -0
- package/dist-cli/chunks/chunk-MBFP2LVH.js +3 -0
- package/dist-cli/chunks/chunk-MPSZ5EWF.js +16 -0
- package/dist-cli/chunks/chunk-OROM7DZI.js +2 -0
- package/dist-cli/chunks/chunk-PWXPA745.js +3 -0
- package/dist-cli/chunks/chunk-QOBRRY5X.js +4 -0
- package/dist-cli/chunks/chunk-X2U72K7X.js +1 -0
- package/dist-cli/chunks/chunk-YCETS3B3.js +2 -0
- package/dist-cli/chunks/compat-MRN2ORY5.js +33 -0
- package/dist-cli/chunks/config-CO5IYWUY.js +45 -0
- package/dist-cli/chunks/control-Y7TKKB6D.js +2 -0
- package/dist-cli/chunks/daemon-G4XVRFHM.js +49 -0
- package/dist-cli/chunks/debug-ZNSZTWT6.js +182 -0
- package/dist-cli/chunks/detox-JEGYNTYV.js +49 -0
- package/dist-cli/chunks/dev-ZUKCZQEX.js +25 -0
- package/dist-cli/chunks/dev-checkout-IEZVVTCN.js +2 -0
- package/dist-cli/chunks/device-BS34FAFM.js +16 -0
- package/dist-cli/chunks/drivers-46PFFIDF.js +2 -0
- package/dist-cli/chunks/electron-P2KOPX2S.js +15 -0
- package/dist-cli/chunks/flow-VVOF6UNC.js +2 -0
- package/dist-cli/chunks/hints-7Z656W4H.js +2 -0
- package/dist-cli/chunks/inspect-NAHXP2M5.js +1042 -0
- package/dist-cli/chunks/install-EPUJX4AT.js +67 -0
- package/dist-cli/chunks/install-desktop-PYIZIH67.js +19 -0
- package/dist-cli/chunks/login-Z5Z54HUJ.js +26 -0
- package/dist-cli/chunks/logout-T2QDYGCB.js +2 -0
- package/dist-cli/chunks/maestro-4AXTS7OE.js +75 -0
- package/dist-cli/chunks/preview-NMGWHWMX.js +17 -0
- package/dist-cli/chunks/profile-6RGJA4FR.js +22 -0
- package/dist-cli/chunks/record-IE27Z2GA.js +37 -0
- package/dist-cli/chunks/screenshot-R3GCCSCI.js +26 -0
- package/dist-cli/chunks/screenshot-mode-SZQDNGYE.js +17 -0
- package/dist-cli/chunks/screenshots-4UQJE4NC.js +70 -0
- package/dist-cli/chunks/server-AN2G5KO4.js +21 -0
- package/dist-cli/chunks/skills-2PPKPL4B.js +10 -0
- package/dist-cli/chunks/store-PU5ES4YQ.js +2 -0
- package/dist-cli/chunks/test-5LFKOQ4M.js +31 -0
- package/dist-cli/chunks/upload-BYNPC54C.js +2 -0
- package/dist-cli/chunks/vite-plugin-5AEUUBKP.js +9 -0
- package/dist-cli/chunks/whoami-H6FW34JS.js +2 -0
- package/package.json +56 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/*! sootsim v0.0.1 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{g as u}from"./chunk-YCETS3B3.js";var S=52,l=18,h=42,w=96,g=54,$=1.5,y="inset 0 0 0 0.5px #000, inset 0 0 0 2px #757575, inset 0 0 0 5px #212121",x=1;function L(e){let t=u(e),r=t.scale,o=!t.dynamicIsland&&t.homeIndicatorHeight===0&&t.cornerRadius===0,n=t.width,i=t.height,a=o?t.width+l*2:t.width+28,d=o?t.height+h+w:t.height+28,c=9.5,b=x,p=a+c*2,m=d+x*2,f=c+(o?l:14),B=o?h:14,v=o?S:t.cornerRadius+14,H=[{side:"right",top:t.hardwareButtons.lock.top,height:t.hardwareButtons.lock.height,width:t.hardwareButtons.width},{side:"left",top:t.hardwareButtons.ringToggle.top,height:t.hardwareButtons.ringToggle.height,width:t.hardwareButtons.width},{side:"left",top:t.hardwareButtons.volumeUp.top,height:t.hardwareButtons.volumeUp.height,width:t.hardwareButtons.width},{side:"left",top:t.hardwareButtons.volumeDown.top,height:t.hardwareButtons.volumeDown.height,width:t.hardwareButtons.width}];return{model:e,renderScale:r,outerWidth:Math.round(p*r),outerHeight:Math.round(m*r),logicalOuterWidth:p,logicalOuterHeight:m,logicalFrameWidth:a,logicalFrameHeight:d,logicalFrameLeft:c,logicalFrameTop:b,logicalScreenWidth:n,logicalScreenHeight:i,logicalScreenLeft:f,logicalScreenTop:B,logicalScreenRadius:o?0:t.cornerRadius,logicalFrameRadius:v,frameBackground:o?"linear-gradient(180deg, #1b1c20 0%, #0f1012 42%, #050608 100%)":"#000000",frameOutline:o?"0 0 0 1px #1f2125":"0 0 0 1px #333",metallicRingShadow:o?null:y,buttons:H,legacyHomeButton:o?{top:h+t.height+(w-g)/2,left:t.width/2-g/2+l,size:g,ring:$}:null,showHomeIndicator:t.homeIndicatorHeight>0,logicalHomeIndicatorStripHeight:t.homeIndicatorHeight}}function E(e){let t=e.side==="right",r=t?"inset(-3px -3px -3px 0)":"inset(-3px 0 -3px -3px)";return`
|
|
3
|
+
<div
|
|
4
|
+
aria-hidden="true"
|
|
5
|
+
style="
|
|
6
|
+
position:absolute;
|
|
7
|
+
${t?`right:-${e.width}px;`:`left:-${e.width}px;`}
|
|
8
|
+
top:${e.top}px;
|
|
9
|
+
width:${e.width}px;
|
|
10
|
+
height:${e.height}px;
|
|
11
|
+
background-color:#212121;
|
|
12
|
+
border-top-left-radius:${t?0:1.5}px;
|
|
13
|
+
border-bottom-left-radius:${t?0:1.5}px;
|
|
14
|
+
border-top-right-radius:${t?1.5:0}px;
|
|
15
|
+
border-bottom-right-radius:${t?1.5:0}px;
|
|
16
|
+
box-shadow:
|
|
17
|
+
inset 0 0.5px 0 #616161,
|
|
18
|
+
inset 0 -0.5px 0 #3F3F3F,
|
|
19
|
+
${t?"inset -0.5px 0 0 #3F3F3F,":"inset 0.5px 0 0 #3F3F3F,"}
|
|
20
|
+
0 0 0 0.5px #676767,
|
|
21
|
+
0 0 0 1.5px #000;
|
|
22
|
+
clip-path:${r};
|
|
23
|
+
pointer-events:none;
|
|
24
|
+
z-index:2;
|
|
25
|
+
"
|
|
26
|
+
></div>
|
|
27
|
+
`}function T(e,t){let r=e.buttons.map(E).join(""),o=e.metallicRingShadow?`
|
|
28
|
+
<div
|
|
29
|
+
aria-hidden="true"
|
|
30
|
+
style="
|
|
31
|
+
position:absolute;
|
|
32
|
+
inset:0;
|
|
33
|
+
border-radius:${e.logicalFrameRadius}px;
|
|
34
|
+
box-shadow:${e.metallicRingShadow};
|
|
35
|
+
pointer-events:none;
|
|
36
|
+
z-index:10;
|
|
37
|
+
"
|
|
38
|
+
></div>
|
|
39
|
+
`:"",n=e.legacyHomeButton?`
|
|
40
|
+
<div
|
|
41
|
+
aria-hidden="true"
|
|
42
|
+
style="
|
|
43
|
+
position:absolute;
|
|
44
|
+
top:${e.legacyHomeButton.top}px;
|
|
45
|
+
left:${e.legacyHomeButton.left}px;
|
|
46
|
+
width:${e.legacyHomeButton.size}px;
|
|
47
|
+
height:${e.legacyHomeButton.size}px;
|
|
48
|
+
border-radius:50%;
|
|
49
|
+
background:
|
|
50
|
+
radial-gradient(circle at 35% 32%, rgba(62,64,68,0.35) 0%, rgba(17,18,20,0.98) 72%, rgba(8,9,11,1) 100%);
|
|
51
|
+
box-shadow:
|
|
52
|
+
inset 0 0 0 1px rgba(255,255,255,0.06),
|
|
53
|
+
inset 0 0 0 ${e.legacyHomeButton.ring}px rgba(184,192,204,0.45),
|
|
54
|
+
0 0 0 1px rgba(0,0,0,0.5);
|
|
55
|
+
z-index:3;
|
|
56
|
+
pointer-events:none;
|
|
57
|
+
display:flex;
|
|
58
|
+
align-items:center;
|
|
59
|
+
justify-content:center;
|
|
60
|
+
"
|
|
61
|
+
>
|
|
62
|
+
<div
|
|
63
|
+
style="
|
|
64
|
+
width:16px;
|
|
65
|
+
height:16px;
|
|
66
|
+
border-radius:4px;
|
|
67
|
+
box-shadow:inset 0 0 0 1.5px rgba(188,194,202,0.5);
|
|
68
|
+
"
|
|
69
|
+
></div>
|
|
70
|
+
</div>
|
|
71
|
+
`:"",i=e.showHomeIndicator?`
|
|
72
|
+
<div
|
|
73
|
+
aria-hidden="true"
|
|
74
|
+
style="
|
|
75
|
+
position:absolute;
|
|
76
|
+
left:0;
|
|
77
|
+
right:0;
|
|
78
|
+
bottom:4px;
|
|
79
|
+
height:${e.logicalHomeIndicatorStripHeight}px;
|
|
80
|
+
display:flex;
|
|
81
|
+
align-items:center;
|
|
82
|
+
justify-content:center;
|
|
83
|
+
pointer-events:none;
|
|
84
|
+
z-index:10;
|
|
85
|
+
"
|
|
86
|
+
>
|
|
87
|
+
<div
|
|
88
|
+
style="
|
|
89
|
+
width:134px;
|
|
90
|
+
height:5px;
|
|
91
|
+
border-radius:2.5px;
|
|
92
|
+
background-color:rgb(150, 150, 150);
|
|
93
|
+
opacity:0.5;
|
|
94
|
+
"
|
|
95
|
+
></div>
|
|
96
|
+
</div>
|
|
97
|
+
`:"";return`<!doctype html>
|
|
98
|
+
<html>
|
|
99
|
+
<head>
|
|
100
|
+
<meta charset="utf-8" />
|
|
101
|
+
<style>
|
|
102
|
+
html, body {
|
|
103
|
+
margin: 0;
|
|
104
|
+
width: ${e.outerWidth}px;
|
|
105
|
+
height: ${e.outerHeight}px;
|
|
106
|
+
background: transparent;
|
|
107
|
+
}
|
|
108
|
+
body {
|
|
109
|
+
overflow: hidden;
|
|
110
|
+
}
|
|
111
|
+
img {
|
|
112
|
+
display: block;
|
|
113
|
+
width: 100%;
|
|
114
|
+
height: 100%;
|
|
115
|
+
}
|
|
116
|
+
</style>
|
|
117
|
+
</head>
|
|
118
|
+
<body>
|
|
119
|
+
<div
|
|
120
|
+
id="frame-export-root"
|
|
121
|
+
style="
|
|
122
|
+
position:relative;
|
|
123
|
+
width:${e.outerWidth}px;
|
|
124
|
+
height:${e.outerHeight}px;
|
|
125
|
+
overflow:hidden;
|
|
126
|
+
background:transparent;
|
|
127
|
+
"
|
|
128
|
+
>
|
|
129
|
+
<div
|
|
130
|
+
id="frame-scale-layer"
|
|
131
|
+
style="
|
|
132
|
+
position:absolute;
|
|
133
|
+
top:0;
|
|
134
|
+
left:0;
|
|
135
|
+
width:${e.logicalOuterWidth}px;
|
|
136
|
+
height:${e.logicalOuterHeight}px;
|
|
137
|
+
transform:scale(${e.renderScale});
|
|
138
|
+
transform-origin:top left;
|
|
139
|
+
overflow:visible;
|
|
140
|
+
"
|
|
141
|
+
>
|
|
142
|
+
<div
|
|
143
|
+
id="frame"
|
|
144
|
+
style="
|
|
145
|
+
position:absolute;
|
|
146
|
+
top:${e.logicalFrameTop}px;
|
|
147
|
+
left:${e.logicalFrameLeft}px;
|
|
148
|
+
width:${e.logicalFrameWidth}px;
|
|
149
|
+
height:${e.logicalFrameHeight}px;
|
|
150
|
+
border-radius:${e.logicalFrameRadius}px;
|
|
151
|
+
box-sizing:border-box;
|
|
152
|
+
overflow:visible;
|
|
153
|
+
background:${e.frameBackground};
|
|
154
|
+
box-shadow:${e.frameOutline};
|
|
155
|
+
"
|
|
156
|
+
>
|
|
157
|
+
${r}
|
|
158
|
+
${o}
|
|
159
|
+
${n}
|
|
160
|
+
<div
|
|
161
|
+
id="screen"
|
|
162
|
+
style="
|
|
163
|
+
position:absolute;
|
|
164
|
+
top:${e.logicalScreenTop}px;
|
|
165
|
+
left:${e.logicalScreenLeft-e.logicalFrameLeft}px;
|
|
166
|
+
width:${e.logicalScreenWidth}px;
|
|
167
|
+
height:${e.logicalScreenHeight}px;
|
|
168
|
+
border-radius:${e.logicalScreenRadius}px;
|
|
169
|
+
overflow:hidden;
|
|
170
|
+
background:#000;
|
|
171
|
+
"
|
|
172
|
+
>
|
|
173
|
+
<img src="${t}" alt="" />
|
|
174
|
+
${i}
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
177
|
+
</div>
|
|
178
|
+
</div>
|
|
179
|
+
</body>
|
|
180
|
+
</html>`}async function D(e,t){let{chromium:r}=await import("playwright"),o=await r.launch({headless:!0});try{let n=await _(o);try{return await n.compose(e,t)}finally{await n.close()}}finally{await o.close()}}async function _(e){let t=new Map;async function r(o){let n=t.get(o);if(n)return n;let i=L(o),a=await e.newContext({viewport:{width:i.outerWidth,height:i.outerHeight},deviceScaleFactor:1}),d=await a.newPage(),c={layout:i,context:a,page:d};return t.set(o,c),c}return{async compose(o,n){let i=await r(n),a=`data:image/png;base64,${o.toString("base64")}`;return await i.page.setContent(T(i.layout,a),{waitUntil:"load"}),await i.page.waitForTimeout(20),await i.page.screenshot({type:"png",clip:{x:0,y:0,width:i.layout.outerWidth,height:i.layout.outerHeight},omitBackground:!0})},async close(){for(let o of t.values())await o.context.close();t.clear()}}}export{D as a,_ as b};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/*! sootsim v0.0.1 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{c as m}from"./chunk-3C3ZH7PP.js";import{existsSync as S,mkdirSync as h,readFileSync as b,writeFileSync as H,rmSync as w}from"fs";import{tmpdir as d}from"os";import{dirname as v,join as p}from"path";var y=new Map;function i(e,r){y.set(e,r)}var a=1;function s(){return p(d(),`sootsim-cli-hints-${m()}.json`)}function l(){return p(d(),"sootsim-cli-hints-global.json")}function u(e){if(!S(e))return{version:a,shown:{}};try{let r=JSON.parse(b(e,"utf8"));return r?.version!==a||!r?.shown?{version:a,shown:{}}:r}catch{return{version:a,shown:{}}}}function f(e,r){try{h(v(e),{recursive:!0}),H(e,JSON.stringify(r)+`
|
|
3
|
+
`)}catch{}}function F(){let e=(process.env.SOOTSIM_HINTS||"").toLowerCase();return e==="off"||e==="0"||e==="false"?"off":e==="always"||e==="verbose"?"always":"normal"}function x(e,r){let o=F();if(o==="off")return!1;if(o==="always"||r==="always")return!0;let t=Date.now();if(r==="once-per-session"){let n=u(s());return n.shown[e]?!1:(n.shown[e]=t,f(s(),n),!0)}if(r==="once-ever"){let n=u(l());return n.shown[e]?!1:(n.shown[e]=t,f(l(),n),!0)}if(typeof r=="object"&&"cooldownMs"in r){let n=u(s()),c=n.shown[e]??0;return t-c<r.cooldownMs?!1:(n.shown[e]=t,f(s(),n),!0)}return!0}function M(e,...r){let o=y.get(e);if(!o)return process.env.SOOTSIM_HINTS_DEBUG&&console.error(` [hints] no hint registered for id "${e}"`),!1;if(!x(e,o.frequency))return!1;let t=o.render(...r);if(t==null)return!1;let n=Array.isArray(t)?t:[t],c=o.stream==="error"?console.error:console.log;for(let g of n)c(` hint: ${g}`);return!0}function O(){w(s(),{force:!0})}function k(){w(l(),{force:!0})}function T(){return Array.from(y.entries()).map(([e,r])=>({id:e,frequency:r.frequency}))}i("app-still-loading",{frequency:{cooldownMs:6e4},render:e=>`app may still be loading (${e} nodes). run \`sootsim wait ready\` first.`});i("wait-selector-for-missing-testid",{frequency:"once-per-session",render:e=>`sootsim wait selector ${e}`,stream:"error"});i("prefer-cli-over-eval",{frequency:"once-per-session",render:e=>e.length?["try the CLI shortcut instead:",...e.map(r=>` ${r}`)]:null,stream:"error"});i("describe-use-filters",{frequency:"once-per-session",render:()=>["describe output is long. narrow it with:"," sootsim describe --only '*Bottom Sheet*'"," sootsim describe --testid-like 'swap-*'"," sootsim describe --subtree <testID>"]});i("subtree-root-not-found",{frequency:"always",render:e=>`no node with testID/id "${e}" \u2014 try \`sootsim find --testid ${e}\` to discover available ids.`,stream:"error"});export{M as a,O as b,k as c,T as d};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/*! sootsim v0.0.1 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
import{b as P}from"./chunk-KSB6MSZ4.js";import{a as V}from"./chunk-OROM7DZI.js";import{a as K,b,c as $,d as y}from"./chunk-MPSZ5EWF.js";import{d as E,e as p,f as A}from"./chunk-3C3ZH7PP.js";import{a as T}from"./chunk-E5UBZEYR.js";import{b as J}from"./chunk-74XPLOV4.js";import{a as j,b as q}from"./chunk-MBFP2LVH.js";import ge from"node:fs";import we from"node:os";import D from"node:path";var W="sootsimConfig";function C(t){return!!t&&Object.keys(t).length>0}function ie(t){return t?C(t.modules)||C(t.turboModules)||C(t.env)||C(t.settings)||C(t.initialState):!1}function R(t,o){let e=new URL(t);return ie(o)?e.searchParams.set(W,JSON.stringify(o)):e.searchParams.delete(W),e.toString()}var U="/node_modules/one/metro-entry.bundle?platform=ios&dev=true&minify=false",k="/index.bundle?platform=ios&dev=true&hot=true&minify=false",ae=new Set(["localhost","127.0.0.1","0.0.0.0","::1"]);function G(t){return new Error(`could not resolve a native bundle for ${t}. pass an explicit bundle URL or open Connect and choose the app there.`)}function ce(t,o){return t?.includes("/one/metro-entry.bundle")?"one":typeof o=="string"&&o?"expo":"unknown"}function le(t){return t.replace(/^\[|\]$/g,"").toLowerCase()}function Q(t){return ae.has(le(t))}function Y(t,o,e){return`${t}//${o}:${e}`}function ue(t){if(typeof window>"u")return!1;try{let o=new URL(t);return Q(o.hostname)&&o.origin!==window.location.origin}catch{return!1}}async function B(t,o){return ue(t)?fetch(`/__fetch-proxy?url=${encodeURIComponent(t)}`,o):fetch(t,o)}function de(t){return t==="https:"?443:80}function me(t){let o=t.pathname||"/";return(o==="/"||o==="")&&!t.search&&!t.hash}async function fe(t){try{return(await B(`${t}${U}`,{method:"HEAD"})).ok}catch{return!1}}async function X(t,o){let e=t.replace(/\/+$/,"");try{let n=await B(`${e}/`,{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){let a=ce(i,s.sdkVersion);return{bundleUrl:a==="one"&&await fe(e)?`${e}${U}`:i||`${e}${k}`,port:o,framework:a,projectName:s.name}}}}catch{}try{if((await B(`${e}${U}`,{method:"HEAD"})).ok)return{bundleUrl:`${e}${U}`,port:o,framework:"one"}}catch{}try{if((await B(`${e}${k}`,{method:"HEAD"})).ok)return{bundleUrl:`${e}${k}`,port:o,framework:"metro"}}catch{}try{let n=await B(`${e}/status`);if(n.ok&&(await n.text()).includes("packager-status:running"))return{bundleUrl:`${e}${k}`,port:o,framework:"metro"}}catch{}return null}async function pe(t){return X(Y("http:","localhost",t),t)}async function Z(t){let o=t.trim();if(/^\d+$/.test(o)){let a=parseInt(o,10),c=await pe(a);if(c)return c;throw G(`localhost:${a}`)}let e=o.startsWith("http")?o:`http://${o}`,n;try{n=new URL(e)}catch{throw new Error(`could not parse "${t}". 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):de(r),i=Y(r,n.hostname,s);if(Q(n.hostname)&&me(n)){let a=await X(i,s);if(a)return a;throw G(i)}return{bundleUrl:n.toString(),port:s,framework:"unknown"}}var he={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 M(t){return new Promise(o=>setTimeout(o,t))}function oe(t){return t.trim()}function F(t){try{let o=new URL(t),e=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")||o.pathname==="/__soot"||o.pathname==="/__soot/"||e==="/rn"||/^\/rn\/[^/]+$/i.test(e)||/^\/app\/[^/]+$/i.test(e)||e==="/__soot/rn"||/^\/__soot\/rn\/[^/]+$/i.test(e)||/^\/__soot\/app\/[^/]+$/i.test(e)}catch{return!1}}async function Fe(t){let o=oe(t);return(await Z(o)).bundleUrl}function ne(t){let o=t.replace(/\/+$/,"")||"/";return o==="/__soot"||o.startsWith("/__soot/")?"/__soot":""}function be(t,o){let e=oe(t),n=new URL(o),r=ne(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(e)?n.pathname=`${r}/rn/${e}`:(n.pathname=`${r}/rn`,n.searchParams.set("open",e)),n.toString()}function $e(t){return t.startsWith("~/")?D.join(we.homedir(),t.slice(2)):D.isAbsolute(t)?t:D.resolve(process.cwd(),t)}function ye(t){let o={};for(let e=0;e<t.length;e++){if(t[e]!=="--replace")continue;let n=t[e+1];n||(console.error(" sootsim open: --replace expects <module>=<file>"),process.exit(1));let r=n.indexOf("=");(r<=0||r===n.length-1)&&(console.error(" sootsim open: --replace expects <module>=<file>"),process.exit(1));let s=n.slice(0,r).trim(),i=$e(n.slice(r+1).trim());ge.existsSync(i)||(console.error(` sootsim open: replacement file not found: ${i}`),process.exit(1)),o[s]={file:i},e++}return Object.keys(o).length>0?{modules:o}:void 0}async function v(t,o=T){if(!t)return new URL(o).toString();if(F(t))return new URL(t).toString();let e=he[t.toLowerCase()];if(e){let n=new URL(o),r=ne(n.pathname);return n.pathname=`${r}${e}`,n.toString()}return be(t,o)}function ee(t,o){let e=t?.url||t?.origin||o;try{let n=new URL(e);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.toString()}catch{return o}}async function Se(t,o,e){let n=new URL(await v(t,o));return n.searchParams.set("inspectOpen",e),n.toString()}async function Ce(t,o,e,n={}){let r=n.attempts??30,s=n.intervalMs??500,i=n.minNodeCount??10;for(let a=0;a<r;a++){let c=$(t,{commandTimeoutMs:o,browserId:e});try{let u=await c.send({type:"evaluate",code:"(async () => (await window.__sootsimTest?.getNodeCount()) || 0)()"});if(typeof u=="number"&&u>i)return{bridge:c,count:u}}catch{}c.close(),await M(s)}return null}function Be(t){if(!t)return"unknown";try{let o=new URL(t);if(o.searchParams.has("bundle")){let e=o.searchParams.get("bundle")||"";try{let n=new URL(e),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")?"embedded sootsim":`${o.host}${o.pathname}${o.search}`}catch{return t}}function xe(t,o){if(t.length===0){console.log(" no browser tabs connected");return}console.log(` connected browser tabs (${t.length}):
|
|
3
|
+
`);for(let e of t){let n=e.lockedBy&&e.lockExpiresAt?`locked by ${e.lockedBy} (${Math.max(0,Math.round((e.lockExpiresAt-Date.now())/1e3))}s)`:"",r=[e.isPrimary?"primary":"",e.id===o?"selected":"",e.readyState,e.attachedCliCount&&e.attachedCliCount>0?"in use":"",e.userFocused?"focused":"",n].filter(Boolean);if(console.log(` ${e.id}${r.length?` [${r.join(", ")}]`:""}`),console.log(` loaded: ${Be(e.url)}`),e.url?console.log(` url: ${e.url}`):e.origin&&console.log(` origin: ${e.origin}`),e.title&&console.log(` title: ${e.title}`),console.log(` connected: ${new Date(e.connectedAt).toISOString()}`),e.lastActiveAt&&e.lastActiveAt>0){let s=Math.round((Date.now()-e.lastActiveAt)/1e3),i=s<60?`${s}s ago`:s<3600?`${Math.round(s/60)}m ago`:`${Math.round(s/3600)}h ago`;console.log(` last active: ${i}`)}}}async function te(t,o,e,n={}){let r=n.attempts??30,s=n.intervalMs??500;for(let i=0;i<r;i++){let a=$(t,{commandTimeoutMs:o});try{let u=(await a.listBrowsers()).find(e);if(u)return u}catch{}finally{a.close()}await M(s)}return null}async function Pe(t,o,e,n={}){let r=n.attempts??20,s=n.intervalMs??250;for(let i=0;i<r;i++){let a=$(t,{commandTimeoutMs:o});try{let u=(await a.listBrowsers()).find(g=>g.id===e);if(!u||u.readyState!=="open")return!0}catch{return!0}finally{a.close()}await M(s)}return!1}function I(t,o){if(o){let r=t.find(s=>s.id===o);if(!r)throw new Error(`no browser connected with id ${o}`);return r}let e=t.find(r=>r.isPrimary&&r.readyState==="open");if(e)return e;let n=t.find(r=>r.readyState==="open");if(n)return n;throw new Error("no browser connected")}function N(t,o,e){console.log(` ${e==="current session"?"loaded":"opened"}: ${t} [${e}]`),console.log(` active session: ${o.id}`),console.log(JSON.stringify({id:o.id,url:o.url},null,2))}async function He(t,o={}){let e=b(t,{port:o.port,commandTimeoutMs:o.timeoutMs}),n=y(e);try{let r=await n.listBrowsers();xe(r,e.browserId)}finally{n.close()}}async function ze(t,o={}){let e=b(t,{port:o.port,commandTimeoutMs:o.timeoutMs,stripBooleanFlags:["--new"],stripValueFlags:["--base-url","--replace"]}),n=t.includes("--new"),r=ye(t);n&&e.browserIdSource==="flag"&&(console.error(" sootsim open: --new cannot be combined with --session/--id"),process.exit(1));let s=e.positional[0]||"",i=t.find((l,w)=>t[w-1]==="--base-url")||T,a=t.includes("--base-url"),c=E();if(!n&&(e.browserIdSource==="flag"||e.browserIdSource==="saved"&&!!c)){let l=y(e),w=e.browserId?` --session ${e.browserId}`:"",f=!1;try{let d=null;try{let m=await l.listBrowsers();if(e.browserIdSource==="saved"?(d=m.find(h=>h.id===c&&h.readyState==="open"),d||A()):d=I(m,e.browserId),!d)if(e.browserIdSource==="saved")f=!0;else throw new Error("no browser connected");if(!f&&d){let h=a||F(s)?i:ee(d,i),x=await v(s,R(h,r));l.send({type:"evaluate",browserId:d.id,code:`window.location.href = ${JSON.stringify(x)}`}).catch(()=>{})}}catch(m){console.error(` open failed: ${m instanceof Error?m.message:String(m)}`),await P(l,{errorsCommand:`sootsim get errors 5${w}`,warningsCommand:`sootsim get warnings 5${w}`,requestsCommand:`sootsim get requests 5${w}`}),process.exit(1)}if(!f&&d){await M(1500);let m=await Ce(e.wsPort,e.commandTimeoutMs,d.id);m||(console.error(" timed out waiting for current session to load target"),process.exit(1)),m.bridge.close(),p(d.id);let h=a||F(s)?i:ee(d,i),x=await v(s,R(h,r));N(x,{...d,url:x},"current session");return}}finally{l.close()}}let g=R(i,r),se=await v(s,g),H=`cli-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`,S=await Se(s,g,H),z=l=>l.url?.includes(`inspectOpen=${H}`)??!1,O=!1,_=!1;try{let l=$(e.wsPort,{commandTimeoutMs:2e3});try{await l.listBrowsers(),O=!0}finally{l.close()}}catch{}if(O)try{let l=$(e.wsPort,{commandTimeoutMs:3e3});try{await l.openUrl(S),_=!0}finally{l.close()}}catch{}if(!_){let l=j();if(l)try{if((await q(S,l)).launched){let f=await te(e.wsPort,e.commandTimeoutMs,z,{attempts:20,intervalMs:500});if(f){p(f.id),N(S,f,"desktop companion");return}}}catch{}if(await V(S),!O){console.log(` opened: ${se}`),J(e.wsPort);return}}let L=await te(e.wsPort,e.commandTimeoutMs,z,{attempts:30,intervalMs:500});L||(console.error(" timed out waiting for opened tab to connect"),process.exit(1)),p(L.id),N(S,L,_?"bridge":"direct open")}async function re(t,o={}){let e=b(t,{port:o.port,commandTimeoutMs:o.timeoutMs}),n=y(e),r=e.browserId?` --session ${e.browserId}`:"";try{try{let s=await n.listBrowsers(),i=I(s,e.positional[0]||e.browserId);await n.focusBrowser(i.id),p(i.id),console.log(` using: ${i.id}`)}catch(s){console.error(` use failed: ${s instanceof Error?s.message:String(s)}`),await P(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()}}async function je(t,o={}){await re(t,o)}async function qe(t,o={}){await re(t,o)}async function Je(t,o={}){let e=b(t,{port:o.port,commandTimeoutMs:o.timeoutMs,stripBooleanFlags:["--force"]}),n=t.includes("--force"),r=y(e);try{try{let s=await r.listBrowsers(),i=I(s,e.positional[0]||e.browserId),a=n&&i.lockedBy&&i.lockedByKind!=="user-active"?i.lockedBy:null,c=await r.claim(i.id,{force:n});p(i.id);let u=Math.max(0,Math.round((c.lockExpiresAt-Date.now())/1e3)),g=c.bootedCount>0?` (booted ${c.bootedCount})`:"";console.log(` claimed: ${c.browserId} [${u}s]${g}`),a&&console.log(` took over from: ${a}`)}catch(s){if(s instanceof K){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 session"),process.exit(1)}console.error(` claim failed: ${s instanceof Error?s.message:String(s)}`),process.exit(1)}}finally{r.close()}}async function Ke(t,o={}){let e=b(t,{port:o.port,commandTimeoutMs:o.timeoutMs}),n=y(e),r=e.browserId?` --session ${e.browserId}`:"";try{try{let s=await n.listBrowsers(),i=I(s,e.positional[0]||e.browserId),a=s.find(u=>u.id!==i.id&&u.readyState==="open");if(await n.closeBrowser(i.id),!await Pe(e.wsPort,e.commandTimeoutMs,i.id)){console.log(` close requested: ${i.id} (still connected)`);return}E()===i.id&&(a?p(a.id):A()),console.log(` closed: ${i.id}`)}catch(s){console.error(` close failed: ${s instanceof Error?s.message:String(s)}`),await P(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{R as a,Fe as b,v as c,Se as d,Be as e,xe as f,te as g,He as h,ze as i,je as j,qe as k,Je as l,Ke as m};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/*! sootsim v0.0.1 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
function t(_){return`(async () => {
|
|
3
|
+
const __t = window.__sootsimTest
|
|
4
|
+
if (!__t) throw new Error('__sootsimTest not available')
|
|
5
|
+
const __id = ${JSON.stringify(_.id||"")}
|
|
6
|
+
const __text = ${JSON.stringify(_.text||"")}
|
|
7
|
+
let __node = null
|
|
8
|
+
if (__id) {
|
|
9
|
+
__node = (__t.findByTestId && await __t.findByTestId(__id)) ||
|
|
10
|
+
(__t.findById && await __t.findById(__id)) || null
|
|
11
|
+
} else if (__text) {
|
|
12
|
+
__node = __t.findByText ? await __t.findByText(__text) : null
|
|
13
|
+
}
|
|
14
|
+
if (!__node) return null
|
|
15
|
+
const __pos = __node.absolutePosition || { x: __node.layout?.x || 0, y: __node.layout?.y || 0 }
|
|
16
|
+
const __layout = __node.layout || {}
|
|
17
|
+
return {
|
|
18
|
+
x: __pos.x,
|
|
19
|
+
y: __pos.y,
|
|
20
|
+
w: __layout.width || 1,
|
|
21
|
+
h: __layout.height || 1,
|
|
22
|
+
}
|
|
23
|
+
})()`}function e(_){return`(async () => {
|
|
24
|
+
const __rect = ${JSON.stringify(_)}
|
|
25
|
+
const __screenshot = window.__sootsimScreenshot
|
|
26
|
+
if (typeof __screenshot !== 'function') {
|
|
27
|
+
throw new Error('screenshot bridge not installed')
|
|
28
|
+
}
|
|
29
|
+
const __dataUrl = await __screenshot({ crop: __rect })
|
|
30
|
+
const __img = await new Promise((res, rej) => {
|
|
31
|
+
const img = new Image()
|
|
32
|
+
img.onload = () => res(img)
|
|
33
|
+
img.onerror = () => rej(new Error('failed to decode cropped screenshot'))
|
|
34
|
+
img.src = __dataUrl
|
|
35
|
+
})
|
|
36
|
+
const __w = __img.naturalWidth
|
|
37
|
+
const __h = __img.naturalHeight
|
|
38
|
+
const __canvas = document.createElement('canvas')
|
|
39
|
+
__canvas.width = __w
|
|
40
|
+
__canvas.height = __h
|
|
41
|
+
const __ctx = __canvas.getContext('2d')
|
|
42
|
+
if (!__ctx) throw new Error('could not acquire 2d context')
|
|
43
|
+
__ctx.drawImage(__img, 0, 0)
|
|
44
|
+
const __data = __ctx.getImageData(0, 0, __w, __h).data
|
|
45
|
+
const __n = __data.length / 4
|
|
46
|
+
let __r = 0, __g = 0, __b = 0, __a = 0
|
|
47
|
+
for (let __i = 0; __i < __data.length; __i += 4) {
|
|
48
|
+
__r += __data[__i]
|
|
49
|
+
__g += __data[__i + 1]
|
|
50
|
+
__b += __data[__i + 2]
|
|
51
|
+
__a += __data[__i + 3]
|
|
52
|
+
}
|
|
53
|
+
const __round = (v) => Math.round(v / __n)
|
|
54
|
+
const __rr = __round(__r), __gg = __round(__g), __bb = __round(__b), __aa = __round(__a)
|
|
55
|
+
const __hex =
|
|
56
|
+
'#' +
|
|
57
|
+
[__rr, __gg, __bb]
|
|
58
|
+
.map((v) => v.toString(16).padStart(2, '0'))
|
|
59
|
+
.join('')
|
|
60
|
+
const __dpr = window.devicePixelRatio || 1
|
|
61
|
+
return {
|
|
62
|
+
r: __rr, g: __gg, b: __bb, a: __aa,
|
|
63
|
+
hex: __hex,
|
|
64
|
+
samples: __n,
|
|
65
|
+
rect: { x: __rect.x, y: __rect.y, w: __rect.w, h: __rect.h },
|
|
66
|
+
deviceWidth: __w / __dpr,
|
|
67
|
+
deviceHeight: __h / __dpr,
|
|
68
|
+
}
|
|
69
|
+
})()`}export{t as a,e as b};
|