agent-device 0.17.5 → 0.17.6
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 +2 -2
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.5.apk → agent-device-android-multitouch-helper-0.17.6.apk} +0 -0
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.6.apk.sha256 +1 -0
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.5.manifest.json → agent-device-android-multitouch-helper-0.17.6.manifest.json} +4 -4
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.5.apk → agent-device-android-snapshot-helper-0.17.6.apk} +0 -0
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.6.apk.sha256 +1 -0
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.5.manifest.json → agent-device-android-snapshot-helper-0.17.6.manifest.json} +6 -6
- package/dist/src/2133.js +1 -0
- package/dist/src/2748.js +1 -0
- package/dist/src/{4012.js → 2892.js} +1 -1
- package/dist/src/2948.js +1 -0
- package/dist/src/2954.js +2 -0
- package/dist/src/{7651.js → 3006.js} +1 -1
- package/dist/src/314.js +1 -0
- package/dist/src/{8806.js → 3340.js} +5 -5
- package/dist/src/4291.js +2 -0
- package/dist/src/{7599.js → 432.js} +1 -1
- package/dist/src/4418.js +1 -0
- package/dist/src/{2403.js → 4428.js} +1 -1
- package/dist/src/4723.js +1 -0
- package/dist/src/5299.js +1 -0
- package/dist/src/{113.js → 5448.js} +1 -1
- package/dist/src/5484.js +1 -0
- package/dist/src/5628.js +1 -0
- package/dist/src/587.js +1 -0
- package/dist/src/6311.js +27 -0
- package/dist/src/6918.js +1 -0
- package/dist/src/7244.js +1 -0
- package/dist/src/7394.js +6 -0
- package/dist/src/8184.js +1 -0
- package/dist/src/8225.js +1 -0
- package/dist/src/{1974.js → 8275.js} +1 -1
- package/dist/src/8875.js +1 -0
- package/dist/src/{1352.js → 9581.js} +1 -1
- package/dist/src/9624.js +1 -0
- package/dist/src/9722.js +38 -0
- package/dist/src/9836.js +1 -0
- package/dist/src/9873.js +1 -0
- package/dist/src/9919.js +6 -0
- package/dist/src/android-adb.d.ts +3 -3
- package/dist/src/android-adb.js +1 -1
- package/dist/src/android-snapshot-helper.js +1 -1
- package/dist/src/android.js +1 -1
- package/dist/src/apple.js +1 -1
- package/dist/src/apps.js +6 -6
- package/dist/src/artifacts.js +1 -1
- package/dist/src/batch.d.ts +4 -4
- package/dist/src/batch.js +1 -1
- package/dist/src/{args.js → cli-help.js} +18 -18
- package/dist/src/cli-output.js +4 -30
- package/dist/src/cli.js +17 -17
- package/dist/src/command-surface.js +1 -1
- package/dist/src/contracts.d.ts +6 -6
- package/dist/src/contracts.js +1 -1
- package/dist/src/devices.js +1 -1
- package/dist/src/find.js +1 -1
- package/dist/src/finders.d.ts +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/generic.js +8 -14
- package/dist/src/index.d.ts +28 -25
- package/dist/src/index.js +1 -1
- package/dist/src/input-actions.js +1 -1
- package/dist/src/input-actions~1.js +1 -1
- package/dist/src/install-source.js +1 -1
- package/dist/src/interaction.js +1 -1
- package/dist/src/internal/bin.js +5 -5
- package/dist/src/internal/companion-tunnel.js +1 -1
- package/dist/src/internal/daemon.js +1 -1
- package/dist/src/internal/png-worker.js +1 -1
- package/dist/src/internal/update-check-entry.js +1 -1
- package/dist/src/io.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/linux.js +1 -1
- package/dist/src/metro.js +1 -1
- package/dist/src/notifications.js +1 -1
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-trace-recording.js +2 -2
- package/dist/src/record-trace.js +1 -1
- package/dist/src/recording-provider.js +1 -1
- package/dist/src/remote-config.d.ts +5 -5
- package/dist/src/remote-config.js +1 -1
- package/dist/src/rslib-runtime.js +1 -1
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.d.ts +1 -1
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +1 -1
- package/dist/src/session.js +7 -7
- package/dist/src/snapshot.js +2 -2
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +5 -0
- package/package.json +14 -13
- package/server.json +3 -3
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.5.apk.sha256 +0 -1
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.5.apk.sha256 +0 -1
- package/dist/src/1010.js +0 -1
- package/dist/src/123.js +0 -1
- package/dist/src/1231.js +0 -1
- package/dist/src/208.js +0 -1
- package/dist/src/221.js +0 -6
- package/dist/src/2415.js +0 -38
- package/dist/src/3675.js +0 -1
- package/dist/src/5611.js +0 -1
- package/dist/src/5827.js +0 -1
- package/dist/src/6088.js +0 -1
- package/dist/src/6133.js +0 -1
- package/dist/src/6629.js +0 -1
- package/dist/src/7556.js +0 -1
- package/dist/src/7719.js +0 -1
- package/dist/src/7847.js +0 -1
- package/dist/src/8133.js +0 -1
- package/dist/src/8656.js +0 -1
- package/dist/src/9010.js +0 -1
- package/dist/src/9471.js +0 -1
- package/dist/src/9542.js +0 -6
- package/dist/src/9616.js +0 -2
- package/dist/src/9639.js +0 -2
- package/dist/src/9671.js +0 -1
- package/dist/src/9818.js +0 -1
- package/dist/src/989.js +0 -1
- /package/dist/src/{2301.js → 4069.js} +0 -0
- /package/dist/src/{4829.js → 5560.js} +0 -0
- /package/dist/src/{4778.js → 6024.js} +0 -0
- /package/dist/src/{9152.js → 733.js} +0 -0
- /package/dist/src/{3267.js → 9612.js} +0 -0
package/dist/src/cli-output.js
CHANGED
|
@@ -1,30 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
`)}function
|
|
3
|
-
`),n.
|
|
4
|
-
|
|
5
|
-
`),n.logPath&&process.stderr.write(`Diagnostics Log: ${n.logPath}
|
|
6
|
-
`),t.showDetails&&n.details&&process.stderr.write(`${JSON.stringify(n.details,null,2)}
|
|
7
|
-
`)}function K(e){return e&&e.summaryLines.length>0?`
|
|
8
|
-
${e.summaryLines.join("\n")}`:""}function _(e){var n;let r=!0===e.baselineInitialized,i=e.summary??{},o=Q(i.additions),a=Q(i.removals),s=Q(i.unchanged),u=Y(),l=V(e),d=l.length>0?`${l.join("\n")}
|
|
9
|
-
`:"";if(r)return`${d}Baseline initialized (${s} lines).
|
|
10
|
-
`;let f=(function(e){if(0===e.length)return e;let t=e.map((e,t)=>({index:t,kind:e.kind})).filter(e=>"added"===e.kind||"removed"===e.kind).map(e=>e.index);if(0===t.length)return e;let n=Array(e.length).fill(!1);for(let r of t){let t=Math.max(0,r-1),i=Math.min(e.length-1,r+1);for(let e=t;e<=i;e+=1)n[e]=!0}return e.filter((e,t)=>n[t])})(Array.isArray(e.lines)?e.lines:[]).map(e=>{let n="string"==typeof e.text?e.text:"";if("added"===e.kind){let e=n.startsWith(" ")?`+${n}`:`+ ${n}`;return u?t("green",e):e}if("removed"===e.kind){let e=n.startsWith(" ")?`-${n}`:`- ${n}`;return u?t("red",e):e}return u?t("dim",n):n}),p=f.length>0?`${f.join("\n")}
|
|
11
|
-
`:"";if(!u)return`${d}${p}${o} additions, ${a} removals, ${s} unchanged
|
|
12
|
-
`;let c=`${(n=String(o),t("green",n))} additions, ${t("red",String(a))} removals, ${t("dim",String(s))} unchanged`;return`${d}${p}${c}
|
|
13
|
-
`}function z(e){var n,r,i,o;let a,s,u,l,d=Y(),f=!0===e.match,p=e.dimensionMismatch,c=[];return c.push(...function(e,n){if(!0===e.match){let e=n?function(e,n){return t(n,e)}("✓","green"):"✓";return[`${e} Screenshots match.`]}let r=e.dimensionMismatch,i=n?function(e,n){return t(n,e)}("✗","red"):"✗";if(r){let e=r.expected,t=r.actual;return[`${i} Screenshots have different dimensions: expected ${e?.width}x${e?.height}, got ${t?.width}x${t?.height}`]}let o=Q(e.differentPixels),a=Q(e.mismatchPercentage),s=0===a&&o>0?"<0.01":String(a),u=`${s}% pixels differ`;return[`${i} ${n?function(e,n){return t(n,e)}(u,"red"):u}`]}(e,d)),c.push(...function(e,n,r){if(n)return[];let i=[];if(e.diffPath){let n=q(e.diffPath),o=r?function(e,n){return t(n,e)}("Diff image:","dim"):"Diff image:",a=r?function(e,n){return t(n,e)}(n,"green"):n;i.push(` ${o} ${a}`)}if(e.currentOverlayPath){let n=q(e.currentOverlayPath),o=r?function(e,n){return t(n,e)}("Current overlay:","dim"):"Current overlay:",a=r?function(e,n){return t(n,e)}(n,"green"):n,s=Q(e.currentOverlayRefCount),u=s>0?` (${s} refs)`:"";i.push(` ${o} ${a}${u}`)}return i}(e,f,d)),f||p||(c.push(...(n=e,r=d,a=Q(n.differentPixels),s=Q(n.totalPixels),u=r?function(e,n){return t(n,e)}(String(a),"red"):String(a),[` ${u} different / ${s} total pixels`])),c.push(...(i=e,o=d,0===(l=function(e){let t=[];for(let n of(e.ocr?.movementClusters??[]).slice(0,2))t.push(`text movement cluster: ${function(e){let t=e.slice(0,4).map(e=>JSON.stringify(e)),n=e.length>t.length?` +${e.length-t.length} more`:"";return`${t.join(", ")}${n}`}(n.texts)} dx=${U(n.xRange)}px dy=${U(n.yRange)}px`);let n=(e.nonTextDeltas??[]).filter(e=>["icon","toggle","chevron"].includes(e.likelyKind)).slice(0,3);n.length>0&&t.push(`non-text controls: ${n.map(E).join("; ")}`);let r=(e.nonTextDeltas??[]).filter(e=>"separator"===e.likelyKind).slice(0,2);return r.length>0&&t.push(`non-text boundaries: ${r.map(E).join("; ")}`),t.slice(0,6)}(i)).length?[]:[` ${G("Hints:",o)}`,...l.map(e=>` - ${e}`)])),c.push(...function(e,t){let n=Array.isArray(e.regions)?e.regions:[];if(0===n.length)return[];let r=[` ${G("Changed regions:",t)}`];for(let e of n.slice(0,5))r.push(...function(e){let t=0===e.shareOfDiffPercentage&&e.differentPixels>0?"<0.01":String(e.shareOfDiffPercentage),n=e.rect,r=[` ${e.index}. ${e.location} x=${n.x} y=${n.y} ${n.width}x${n.height}, ${t}% of diff, change=${e.dominantChange}`],i=function(e){let t=[e.size?`size=${e.size}`:null,e.shape?`shape=${e.shape}`:null,"number"==typeof e.densityPercentage?`density=${e.densityPercentage}%`:null,e.averageBaselineColorHex&&e.averageCurrentColorHex?`avgColor=${e.averageBaselineColorHex}->${e.averageCurrentColorHex}`:null,"number"==typeof e.baselineLuminance&&"number"==typeof e.currentLuminance?`luminance=${e.baselineLuminance}->${e.currentLuminance}`:null].filter(e=>null!==e);return t.length>0?t.join(" "):null}(e);i&&r.push(` ${i}`);let o=e.currentOverlayMatches?.[0];if(o){let e=o.label?` "${o.label}"`:"";r.push(` overlaps @${o.ref}${e}, ${o.regionCoveragePercentage}% of region`)}return r}(e));return r}(e,d)),c.push(...function(e,t){let n=e.ocr?.matches??[];if(0===n.length)return[];let r=n.slice(0,8),i=[` ${G(`OCR text deltas (${e.ocr?.provider}; baselineBlocks=${e.ocr?.baselineBlocks} currentBlocks=${e.ocr?.currentBlocks}; showing ${r.length}/${n.length}; px):`,t)}`,` ${G("item | text | movePx | sizeDeltaPx | bboxBaseline | bboxCurrent | confidence | issueHint",t)}`];for(let[e,t]of r.entries()){let n=t.delta;i.push(` ${e+1} | ${JSON.stringify(t.text)} | ${J(n.x)},${J(n.y)} | ${J(n.width)},${J(n.height)} | ${W(t.baselineRect)} | ${W(t.currentRect)} | ${t.confidence} | ${t.possibleTextMetricMismatch?"ocr-bbox-size-change":"-"}`)}return i}(e,d)),c.push(...function(e,t){let n=e.nonTextDeltas??[];if(0===n.length)return[];let r=n.slice(0,8),i=[` ${G(`Non-text visual deltas (showing ${r.length}/${n.length}; px):`,t)}`,` ${G("item | region | slot | kind | bboxCurrent | nearestText",t)}`];for(let e of r)i.push(` ${e.index} | ${e.regionIndex?`r${e.regionIndex}`:"-"} | ${e.slot} | ${e.likelyKind} | ${W(e.rect)} | ${e.nearestText?JSON.stringify(e.nearestText):"-"}`);return i}(e,d))),`${c.join("\n")}
|
|
14
|
-
`}function W(e){return`x=${e.x},y=${e.y},w=${e.width},h=${e.height}`}function J(e){return e>0?`+${e}`:String(e)}function E(e){let t=e.nearestText?` near ${JSON.stringify(e.nearestText)}`:"",n=e.regionIndex?` r${e.regionIndex}`:"";return`${e.likelyKind}${t}${n}`}function U(e){return e.min===e.max?J(e.min):`${J(e.min)}..${J(e.max)}`}function q(t){let n=process.cwd(),r=e.relative(n,t);return""!==r&&(r.startsWith("..")||e.isAbsolute(r))?t:""===r?".":`.${e.sep}${r}`}function Q(e){return"number"==typeof e&&Number.isFinite(e)?e:0}function Y(){let e=process.env.FORCE_COLOR;return"string"==typeof e?"0"!==e:"string"!=typeof process.env.NO_COLOR&&!!process.stdout.isTTY}function G(e,n){return n?t("dim",e):e}function V(e){let t=e.warnings;return Array.isArray(t)?t.filter(e=>"string"==typeof e&&e.length>0):[]}function X(e,t){var n;let r="scroll-area"===(n=e.type)||"list"===n||"collection"===n||"table"===n?n:null;if(!r)return[];let i=[];if(e.node.hiddenContentAbove&&"below"!==t&&i.push(`[content above ${r} hidden]`),e.node.hiddenContentBelow&&"above"!==t&&i.push(`[content below ${r} hidden]`),0===i.length)return[];let o=" ".repeat(e.depth+1);return i.map(e=>`${o}${e}`)}let Z={debug:g(function(e){let t=[e.outPath,e.message];for(let n of(t.push(...function(e){let t=e.crash,n=[`Crash: ${t.appName??"unknown app"}${void 0===t.crashedThread?"":` thread ${t.crashedThread}`}`];for(let e of(t.bundleId&&n.push(`Bundle: ${t.bundleId}`),t.exceptionType&&n.push(`Exception: ${t.exceptionType}`),t.terminationReason&&n.push(`Termination: ${t.terminationReason}`),t.topFrames))n.push(`Frame ${e.index}: ${e.image} ${e.symbol??e.address}`);for(let e of t.findings)n.push(`Finding: ${e}`);return n}(e)),e.matchedImages))t.push(`Matched: ${n.name} ${n.uuid}${n.arch?` ${n.arch}`:""}`);for(let n of e.warnings??[])t.push(`Warning: ${n}`);return{data:e,text:t.join("\n")}})};function ee(e){let t=e.ref??"",n=e.x,r=e.y;return t&&"number"==typeof n&&"number"==typeof r?{data:e,text:`Tapped @${t} (${n}, ${r})`}:y(e)}let et={click:g(ee),press:g(ee),get:({input:e,result:t})=>{var n;let r;return r=(n={result:t,format:e.format}).result,"text"===n.format?{data:r,text:"string"==typeof r.text?r.text:""}:"attrs"===n.format?{data:r,text:JSON.stringify(r.node??{},null,2)}:y(r)},is:g(function(e){return{data:e,text:`Passed: is ${e.predicate??"assertion"}`}}),find:g(function(e){return"string"==typeof e.text?{data:e,text:e.text}:"boolean"==typeof e.found?{data:e,text:`Found: ${e.found}`}:e.node?{data:e,text:JSON.stringify(e.node,null,2)}:y(e)})};function en(e){return y(s(e))}let er={boot:g(function(e){let t=e.platform??"unknown",n=e.device??e.id??"unknown";return{data:e,text:`Boot ready: ${n} (${t})`}}),shutdown:g(function(e){let t=e.platform??"unknown",n=e.device??e.id??"unknown",r=e.shutdown,i=!!r&&"object"==typeof r&&"success"in r&&!0===r.success;return{data:e,text:`${i?"Shutdown":"Shutdown failed"}: ${n} (${t})`}}),devices:g(function(e){return{data:{devices:e.map(f)},text:e.map(ei).join("\n")}}),apps:({input:e,result:t})=>{var n;return{data:{apps:(n={result:t,appsFilter:e.appsFilter}).result},stderr:"all"===n.appsFilter?"Showing all apps, including system apps.\n":"Showing user-installed apps. Use --all to include system apps.\n",text:n.result.length>0?n.result.join("\n"):"all"===n.appsFilter?"No apps found.":"No user-installed apps found."}},session:g(function(e){if("stateDir"in e)return{data:e,text:e.stateDir};let t={sessions:e.sessions.map(o)};return{data:t,text:JSON.stringify(t,null,2)}}),open:g(function(e){let t=r(e),n=[a(t)].filter(e=>!!e);return"string"==typeof t.sessionStateDir&&n.push(`Session state: ${t.sessionStateDir}`),{data:t,text:n.join("\n")||null}}),close:g(function(e){return y(u(e))}),install:g(en),reinstall:g(en),"install-from-source":g(function(e){return y(d(e))}),prepare:m};function ei(e){let t=e.kind?` ${e.kind}`:"",n=e.target?` target=${e.target}`:"",r="boolean"==typeof e.booted?` booted=${e.booted}`:"";return`${e.name} (${e.platform}${t}${n})${r}`}let eo={logs:g(function(e){var t;return{data:e,text:"string"==typeof e.path?e.path:"",stderr:el([es(e,["active","state","backend","sizeBytes"]),(t=e,["started","stopped","marked","cleared","restarted","removedRotatedFiles"].map(e=>{var n,r;return n=e,!0===(r=t[e])?`${n}=true`:"number"==typeof r?`${n}=${r}`:""}).filter(Boolean).join(" ")||void 0),"string"==typeof e.hint?e.hint:void 0,eu(e.notes)])}}),network:g(function(e){let t=[],n="string"==typeof e.path?e.path:"";n&&t.push(n);let r=Array.isArray(e.entries)?e.entries:[];if(0===r.length)t.push("No recent HTTP(s) entries found.");else for(let e of r)t.push(...function(e){let t=x(e)??{},n="string"==typeof t.method?t.method:"HTTP",r="string"==typeof t.url?t.url:"<unknown-url>",i="number"==typeof t.status?` status=${t.status}`:"",o="string"==typeof t.timestamp?`${t.timestamp} `:"",a="number"==typeof t.durationMs?` durationMs=${t.durationMs}`:"",s=[`${o}${n} ${r}${i}${a}`];return ea(s,"headers",t.headers),ea(s,"request",t.requestBody),ea(s,"response",t.responseBody),s}(e));return{data:e,text:t.join("\n"),stderr:el([es(e,["active","state","backend","include","scannedLines","matchedLines"]),eu(e.notes)])}})};function ea(e,t,n){"string"==typeof n&&e.push(` ${t}: ${n}`)}function es(e,t){return t.map(t=>void 0!==e[t]&&null!==e[t]?`${t}=${e[t]}`:"").filter(Boolean).join(" ")||void 0}function eu(e){if(!Array.isArray(e))return;let t=e.filter(e=>"string"==typeof e&&e.length>0);return t.length>0?t.join("\n"):void 0}function el(e){return e.filter(e=>!!e).join("\n")||void 0}let ed={perf:g(function(e){return{data:e,text:function(e){var t,n,r,i;let o,a="xctrace"===(t=e).kind?function(e){var t,n,r,i,o;let a="string"==typeof e.perf?e.perf:void 0,s="string"==typeof(t=e).outPath?t.outPath:"string"==typeof t.reportPath?t.reportPath:void 0;if(a&&s&&"xctrace"===e.kind){let t;return n=s,r="string"==typeof e.mode?e.mode:"capture",i=a,o=e.template,t=[n,`Perf ${r}: ${i}`],"string"==typeof o&&t.push(`Template: ${o}`),t.join("\n")}}(t):function(e){var t;let n,r,i,o=(n=ef((t=e).action),r=ef(t.kind),i=ef(t.type),n&&r&&i?{action:n,kind:r,type:i}:void 0);if(o){let t;return`Perf ${o.action}: ${o.kind} ${o.type}${(t=ef(e.state))?` state=${t}`:""}${function(e){let t=ef(e.outPath);if(!t)return"";let n=ec(e.sizeBytes);return`
|
|
15
|
-
${t}${void 0!==n?` (${eg(n)})`:""}`}(e)}${function(e){let t=x(e.summary),n=x(t?.frameHealth);if(!n||!0!==n.available)return"";let r=ec(n.droppedFramePercent),i=ec(n.droppedFrameCount),o=ec(n.totalFrameCount);return void 0===r||void 0===i||void 0===o?"":`
|
|
16
|
-
Trace frame health: dropped ${eh(r)} (${Math.round(i)}/${Math.round(o)} frames)`}(e)}`}}(t);if(a)return a;let s=x(e.artifact);if(s)return function(e){let t="string"==typeof e.kind?e.kind:"memory";if(!1===e.available){let n="string"==typeof e.reason&&e.reason.length>0?e.reason:"not available";return`Memory artifact (${t}): unavailable - ${n}`}let n="string"==typeof e.path?e.path:void 0,r=ec(e.sizeBytes),i=void 0===r?"":` (${eg(r)})`;return n?`Memory artifact (${t}): ${n}${i}`:`Memory artifact (${t}): captured${i}`}(s);let u=x(e.metrics),l=x(u?.fps),d=(n=u,(o=[function(e){if(e?.available!==!0)return;let t=ec(e.usagePercent);return void 0!==t?`CPU ${eh(t)}`:void 0}(x(n?.cpu)),function(e){let t;if(e?.available!==!0)return;let n=ec(e.residentMemoryKb)??ec(e.totalPssKb)??ec(e.totalRssKb);return void 0!==n?`memory ${t=n/1024,`${t>=10?Math.round(t):t.toFixed(1)}MB`}`:void 0}(x(n?.memory))].filter(e=>!!e)).length>0?o.join(", "):void 0);if(!l)return ep(d,"missing frame metric");if(!1===l.available){return ep(d,"string"==typeof(r=l).reason&&r.reason.length>0?r.reason:"not available")}let f=function(e){let t=ec(e.droppedFramePercent),n=ec(e.droppedFrameCount);if(void 0!==t&&void 0!==n){var r,i,o;return[`dropped ${eh(t)}`,(r=n,void 0!==(i=ec(e.totalFrameCount))?`(${Math.round(r)}/${Math.round(i)} frames)`:`(${Math.round(r)} dropped frames)`),void 0!==(o=ec(e.sampleWindowMs))?`window ${e$(o)}`:""].filter(Boolean).join(" ")}}(l);if(!f)return ep(d,"missing dropped-frame summary");let p=[`Frame health: ${f}`],c=(Array.isArray(i=l.worstWindows)?i.filter(v):[]).flatMap(e=>{let t=function(e){let t=ec(e.startOffsetMs),n=ec(e.endOffsetMs),r=ec(e.missedDeadlineFrameCount);if(void 0===t||void 0===n||void 0===r)return;let i=ec(e.worstFrameMs),o=void 0===i?"":`, worst ${e$(i)}`;return`- +${e$(t)}-+${e$(n)}: ${Math.round(r)} missed-deadline frames${o}`}(e);return t?[t]:[]});return c.length>0&&p.push("Worst windows:",...c),p.join("\n")}(e)}})};function ef(e){return"string"==typeof e?e:void 0}function ep(e,t){return e?`Performance: ${e}`:`Frame health: unavailable - ${t}`}function ec(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function eh(e){return`${Number.isInteger(e)?e:e.toFixed(1)}%`}function e$(e){let t=Math.max(0,Math.round(e));if(t<1e3)return`${t}ms`;let n=Math.round(t/1e3);if(n<60)return`${n}s`;let r=Math.floor(n/60),i=n%60;return i>0?`${r}m ${i}s`:`${r}m`}function eg(e){if(e<1024)return`${Math.round(e)}B`;let t=e/1024;if(t<1024)return`${t>=10?Math.round(t):t.toFixed(1)}KB`;let n=t/1024;return`${n>=10?Math.round(n):n.toFixed(1)}MB`}let em={record:g(function(e){let t,n="string"==typeof e.outPath?e.outPath:"",r=Array.isArray(t=e.chunks)?t.flatMap(e=>e&&"object"==typeof e?"number"!=typeof e.index||"string"!=typeof e.path?[]:[{index:e.index,path:e.path}]:[]):[];if(r.length<=1){var i,o;let t;return{data:e,text:(i=e,t=[],(o=n)&&t.push(o),"string"==typeof i.sessionStateDir&&t.push(`Session state: ${i.sessionStateDir}`),"string"==typeof i.warning&&t.push(`Warning: ${i.warning}`),"string"==typeof i.overlayWarning&&t.push(`Overlay warning: ${i.overlayWarning}`),t.join("\n"))}}let a=["Recording chunks:"];for(let e of r)a.push(` ${e.index}: ${e.path}`);return"string"==typeof e.telemetryPath&&a.push(`Telemetry: ${e.telemetryPath}`),"string"==typeof e.warning&&a.push(`Warning: ${e.warning}`),"string"==typeof e.overlayWarning&&a.push(`Overlay warning: ${e.overlayWarning}`),{data:e,text:a.join("\n")}})},ey={appstate:g(function(e){return{data:e,text:function(e){if("ios"===e.platform){let t=[`Foreground app: ${e.appName??e.appBundleId??"unknown"}`];return e.appBundleId&&t.push(`Bundle: ${e.appBundleId}`),e.source&&t.push(`Source: ${e.source}`),t.join("\n")}if("android"===e.platform){let t=[`Foreground app: ${e.package??"unknown"}`];return e.activity&&t.push(`Activity: ${e.activity}`),t.join("\n")}return null}(e)}}),back:m,home:m,rotate:m,"app-switcher":m,keyboard:g(function(e){if("android"===e.platform&&"status"===e.action){var t;let n=[`Keyboard visible: ${!0===e.visible?"yes":"no"}`,`Input type: ${e.type??e.inputType??"unknown"}`,`Input owner: ${e.inputOwner??"unknown"}`];return e.inputMethodPackage&&n.push(`Input method: ${e.inputMethodPackage}`),e.focusedPackage&&n.push(`Focused package: ${e.focusedPackage}`),e.focusedResourceId&&n.push(`Focused resource: ${e.focusedResourceId}`),n.push(`Next action: ${(t=e.visible,"ime"===e.inputOwner?"Focused input appears to be owned by the keyboard/IME; dismiss or change the IME before retrying text entry.":!0===t?"Keyboard is visible and focused input appears app-owned; fill/type can proceed.":"Keyboard is hidden; focus an app field before type, or use fill with a concrete target.")}`),{data:e,text:n.join("\n")}}return y(e)}),clipboard:g(function(e){return"read"===e.action?{data:e,text:e.text}:y(e)})},ex={...er,snapshot:({input:e,result:t})=>{var r;let o;return{data:o=i((r={result:t,raw:e.raw,interactiveOnly:e.interactiveOnly,scope:e.scope,depth:e.depth}).result),jsonData:function(e){let{unchanged:t,...n}=e;return n}(o),stderr:r.result.snapshotDiagnostics?.warning?`${r.result.snapshotDiagnostics.warning}
|
|
17
|
-
`:void 0,text:function(e,t={}){var r,i,o,a;let s,u,d,f,p,c=e.nodes,g=Array.isArray(c)?c:[],m="string"==typeof e.backend?e.backend:void 0,y=function(e,t,n){let r;if(n.raw||!((r=e.androidSnapshot)&&"object"==typeof r&&"android-helper"===r.backend))return{nodes:t,filteredCount:0};let i=function(e){var t,n;if(0===e.length)return e;let r=new Set,i=new Map,o=new Map(e.map(e=>[e.index,e]));(function(e,t){for(let n of e)!n.rect||w(n.rect)||M(n)||j(e,n.index,t)})(e,r),function(e,t,n,r){for(let i of e){if(n.has(i.index)||i.rect||M(i))continue;let o=function(e,t,n){let r=e;for(;"number"==typeof r.parentIndex;){let e=t.get(r.parentIndex);if(!e)break;if(n(e))return e;r=e}return null}(i,t,k);o&&function(e,t,n){if(!n)return;let r=e.get(t.index)??t;e.set(t.index,{...r,hiddenContentAbove:!0===r.hiddenContentAbove||"above"===n||void 0,hiddenContentBelow:!0===r.hiddenContentBelow||"below"===n||void 0})}(r,o,function(e,t){let n=t.filter(t=>t.parentIndex===e.parentIndex&&t.rect&&w(t.rect)).map(e=>e.index);return 0===n.length?null:e.index<Math.min(...n)?"above":e.index>Math.max(...n)?"below":null}(i,e)),j(e,i.index,n)}}(e,o,r,i);for(let n of e){if(r.has(n.index)||!(!0===(t=n).hittable&&!S(t)&&t.rect&&w(t.rect)&&0===P(t).trim().length))continue;let o=function(e,t,n){let r=[],i=[],o=new Set;for(let a of e){if(n.has(a.index)||!F(a)||!C(a.rect,t.rect))continue;let e=P(a).trim().replace(/\s+/g," "),s=I(e);i.push(a.index),!e||!s||o.has(s)||(o.add(s),r.push(e))}return{label:r.join(", "),removableIndexes:i}}(N(e,n.index),n,r);if(o.label)for(let t of(i.set(n.index,{...n,...i.get(n.index),label:o.label}),o.removableIndexes))j(e,t,r)}for(let t of e){if(r.has(t.index)||!(!0===(n=t).hittable&&!S(n)&&n.rect&&w(n.rect)&&I(P(n))))continue;let i=I(P(t));if(!i)continue;let o=N(e,t.index).filter(e=>!r.has(e.index)&&function(e,t,n){if(!B(t)||!C(t.rect,e.rect))return!1;let r=I(P(t));return!!(r&&n!==r&&n.includes(r))}(t,e,i));for(let t of o.filter(F))j(e,t.index,r);let a=o.filter(e=>!F(e)),s=new Set(a.map(e=>I(P(e))).filter(e=>!!e));if(!(a.length<2)&&!(s.size<2))for(let t of a)j(e,t.index,r)}let a=new Map;for(let t of e){if(r.has(t.index)||!B(t))continue;let n=I(P(t));if(!n)continue;let o=a.get(n);if(o&&function(e,t,n){var r,i,o,a;return!n.has(e.index)&&(r=e.rect,i=t.rect,!r||!i||Math.abs(r.y+r.height/2-(i.y+i.height/2))<=Math.max(r.height,i.height,1))&&(o=e,a=t,(o.parentIndex===a.parentIndex?3>=Math.abs(o.index-a.index):o.parentIndex!==a.index&&a.parentIndex!==o.index&&1>=Math.abs((o.depth??0)-(a.depth??0))&&2>=Math.abs(o.index-a.index))||function(e,t){let n=e.parentIndex===t.index?t:t.parentIndex===e.index?e:null,r=n?.index===e.index?t:n?.index===t.index?e:null;return!!n&&!!r&&T(n,r).index===n.index}(e,t))}(o,t,r)){let s=function(e,t,n,r,i){var o,a,s;let u=T(t,n),l=u.index===t.index?n:t,d=(l.type??"").toLowerCase().includes("image")?"has image":null,f=i.get(u.index)??u,p=i.get(l.index)?.presentationHints??l.presentationHints;return i.set(u.index,{...f,presentationHints:(o=f.presentationHints,a=p,s=d,[...new Set([...Array.isArray(o)?o:[],...Array.isArray(a)?a:[],...s?[s]:[]])])}),j(e,l.index,r),i.get(u.index)??u}(e,o,t,r,i);a.set(n,s);continue}a.set(n,t)}return e.filter(e=>!r.has(e.index)).map(e=>i.get(e.index)??e)}(t);return{nodes:i,filteredCount:t.length-i.length}}(e,g,t),x=(s="string"==typeof(r=e).appName?r.appName:void 0,u="string"==typeof r.appBundleId?r.appBundleId:void 0,d=[],s&&d.push(`Page: ${s}`),u&&d.push(`App: ${u}`),d.length>0?`${d.join("\n")}
|
|
18
|
-
`:""),v=function(e,t,n,r={nodes:t,filteredCount:0}){let i=V(e);if(!e.snapshotQuality){let e=function(e,t){if(!0===t.scoped||!0===t.depthLimited||e.length>3)return null;let n=1===e.length?"node":"nodes";return`Hint: sparse accessibility snapshot returned ${e.length} ${n}; snapshot state is invalid or unavailable for this screen. Use plain screenshot, not screenshot --overlay-refs, as visual truth. If screenshot shows the Home Screen or another app, run open for this app again first. Then navigate away with coordinates if needed and retry snapshot -i on the next screen.`}(t,n);e&&i.push(e)}!n.raw&&r.filteredCount>0&&i.push(`Collapsed ${r.filteredCount} Android helper node${1===r.filteredCount?"":"s"} from the agent-facing text snapshot; use --raw or --json for the full hierarchy.`);let o=r.filteredCount>0?r.nodes:t;return!n.raw&&function(e){if(e.length<20)return!1;let t=new Map;for(let n of e){let e=(n.type??"").toLowerCase(),r=function(e){var t;let n=e.trim().replace(/\s+/g," ").toLowerCase();return!n||(t=n,/\S+@\S+\.\S+/.test(t))?null:n}(l(n));if(!r)continue;let i=`${e}|${r}`,o=t.get(i)??[];o.push(n),t.set(i,o)}let n=0;for(let e of t.values())!(e.length<=1)&&function(e){for(let r=0;r<e.length;r+=1)for(let i=r+1;i<e.length;i+=1){var t,n;if(t=e[r]?.rect,n=e[i]?.rect,!t||!n||!(t.x+t.width<=n.x+.5||n.x+n.width<=t.x+.5||t.y+t.height<=n.y+.5||n.y+n.height<=t.y+.5))return!0}return!1}(e)&&(n+=e.length);return n>=8}(o)&&i.push("Warning: possible repeated nav subtree detected."),i}(e,g,t,y),b=v.length>0?`${v.join("\n")}
|
|
19
|
-
`:"",A=t.raw?null:(f=e.unchanged)&&"object"==typeof f?"number"!=typeof f.ageMs||"number"!=typeof f.nodeCount?null:{ageMs:f.ageMs,nodeCount:f.nodeCount,interactiveOnly:!0===f.interactiveOnly||void 0,scope:"string"==typeof f.scope?f.scope:void 0}:null;if(A){let e;return`${x}${b}${e=function(e){if(e<1e3)return`${Math.round(e)}ms`;if(e<6e4)return`${(Math.round(e/100)/10).toFixed(1)}s`;let t=e/6e4;return t<60?`${(Math.round(10*t)/10).toFixed(1)}m`:`${(Math.round(t/60*10)/10).toFixed(1)}h`}((i=A).ageMs),i.scope?`Scoped snapshot unchanged for scope "${i.scope}" since previous read ${e} ago.
|
|
20
|
-
Previous refs in this scope remain valid. Use find/get/is for a targeted query, or --force-full to re-emit.`:i.interactiveOnly?`Interactive snapshot unchanged since previous read ${e} ago.
|
|
21
|
-
${i.nodeCount} visible nodes are unchanged. Previous @e refs are still valid. Use find/get/is for a targeted query, or --force-full to re-emit.`:`Snapshot unchanged since previous read ${e} ago.
|
|
22
|
-
Refs from the previous snapshot are still valid. Use --force-full to re-emit the tree, or use find/get/is for a targeted query.`}
|
|
23
|
-
`}let O=t.raw||"macos-helper"===m?null:n(y.nodes),D=!!e.truncated,L=O?.nodes??g,R=t.raw||"macos-helper"===m?null:function(e,t,n,r,i=0){let o,a=(o=e.visibility)&&"object"==typeof o&&"boolean"==typeof o.partial&&"number"==typeof o.visibleNodeCount&&"number"==typeof o.totalNodeCount&&Array.isArray(o.reasons)?{partial:o.partial,visibleNodeCount:o.visibleNodeCount,totalNodeCount:o.totalNodeCount,reasons:o.reasons.filter(e=>"string"==typeof e)}:null;if(0===i&&a)return a;let s=(t?.hiddenCount??0)+i,u=!!t&&t.nodes.some(e=>e.hiddenContentAbove||e.hiddenContentBelow);return s>0?{partial:!0,visibleNodeCount:n,totalNodeCount:Math.max(r,a?.totalNodeCount??r),reasons:[...new Set([...a?.reasons??[],"offscreen-nodes"])]}:a||(u?{partial:!0,visibleNodeCount:n,totalNodeCount:n,reasons:[]}:null)}(e,O,L.length,g.length,y.filteredCount),H=(o=g.length,a=R,p=D?" (truncated)":"",a?.partial?a.totalNodeCount>a.visibleNodeCount?`Snapshot: ${a.visibleNodeCount} visible nodes (${a.totalNodeCount} total)${p}`:`Snapshot: ${a.visibleNodeCount} visible nodes${p}`:`Snapshot: ${o} nodes${p}`);return 0===g.length?`${x}${H}
|
|
24
|
-
${b}`:t.raw?`${x}${H}
|
|
25
|
-
${b}${g.map(e=>JSON.stringify(e)).join("\n")}
|
|
26
|
-
`:t.flatten?`${x}${H}
|
|
27
|
-
${b}${h(L,{summarizeTextSurfaces:!0}).flatMap(e=>[$(e.node,0,!1,e.type,{summarizeTextSurfaces:!0}),...X({...e,depth:0})]).join("\n")}${K(O)}
|
|
28
|
-
`:`${x}${H}
|
|
29
|
-
${b}${(function(e){let t=[],n=[],r=new Map(e.map(e=>[e.node.index,e.node])),i=e=>{for(var i,o,a;n.length>0&&(!e||(i=e,o=n[n.length-1],a=r,!function(e,t,n){let r=e;for(;"number"==typeof r.parentIndex;){if(r.parentIndex===t.index)return!0;let e=n.get(r.parentIndex);if(!e)break;r=e}return!1}(i.node,o.node,a)&&i.depth<=o.depth));)t.push(...X(n.pop(),"below"))};for(let r of e)i(r),t.push(r.text),t.push(...X(r,"above")),r.node.hiddenContentBelow&&n.push(r);return i(),t})(h(L,{summarizeTextSurfaces:!0})).join("\n")}${K(O)}
|
|
30
|
-
`}(o,{raw:r.raw,flatten:r.interactiveOnly,scoped:"string"==typeof r.scope&&r.scope.trim().length>0,depthLimited:"number"==typeof r.depth})}},wait:m,alert:m,...ey,...et,...eo,...ed,...Z,...b,...em,metro:({input:e,result:t})=>{var n;return{data:(n={result:t,action:e.action}).result,text:"reload"===n.action?`Reloaded React Native apps via ${n.result.reloadUrl}`:JSON.stringify(n.result,null,2)}}};function ev(e){return ex[e.name]?.({input:e.input??{},result:e.result})}export{ev as formatCliOutput,z as formatScreenshotDiffText,_ as formatSnapshotDiffText,H as printHumanError,R as printJson};
|
|
1
|
+
import{serializeOpenResult as t,serializeSnapshotResult as e,serializeSessionListEntry as n,readCommandMessage as r,serializeDeployResult as o,serializeCloseResult as a,serializeInstallFromSourceResult as i,serializeDevice as s}from"./9873.js";import{formatSnapshotText as u}from"./6311.js";function d(t){return({result:e})=>t(e)}let p=d(l);function l(t){return{data:t,text:r(t)}}function f(t){return t&&"object"==typeof t&&!Array.isArray(t)?t:void 0}function c(t){return!!t&&"object"==typeof t&&!Array.isArray(t)}let m={batch:d(function(t){let e="number"==typeof t.total?t.total:0,n="number"==typeof t.executed?t.executed:0,o="number"==typeof t.totalDurationMs?t.totalDurationMs:void 0,a=[`Batch completed: ${n}/${e} steps${void 0!==o?` in ${o}ms`:""}`];for(let e of Array.isArray(t.results)?t.results:[]){let t=function(t){let e=f(t);if(!e)return;let n="number"==typeof e.step?e.step:void 0,o="string"==typeof e.command?e.command:"step",a=!1!==e.ok,i=function(t,e,n){var o;return e?r(f(t.data))??n:(o=f(t.error),("string"==typeof o?.message&&o.message.length>0?o.message:null)??n)}(e,a,o),s=void 0!==n?`${n}. `:"- ",u="number"==typeof e.durationMs?e.durationMs:void 0,d=void 0!==u?` (${u}ms)`:"";return`${s}${a?"OK":"FAILED"} ${i}${d}`}(e);t&&a.push(t)}return{data:t,text:a.join("\n")}})},$={debug:d(function(t){let e=[t.outPath,t.message];for(let n of(e.push(...function(t){let e=t.crash,n=[`Crash: ${e.appName??"unknown app"}${void 0===e.crashedThread?"":` thread ${e.crashedThread}`}`];for(let t of(e.bundleId&&n.push(`Bundle: ${e.bundleId}`),e.exceptionType&&n.push(`Exception: ${e.exceptionType}`),e.terminationReason&&n.push(`Termination: ${e.terminationReason}`),e.topFrames))n.push(`Frame ${t.index}: ${t.image} ${t.symbol??t.address}`);for(let t of e.findings)n.push(`Finding: ${t}`);return n}(t)),t.matchedImages))e.push(`Matched: ${n.name} ${n.uuid}${n.arch?` ${n.arch}`:""}`);for(let n of t.warnings??[])e.push(`Warning: ${n}`);return{data:t,text:e.join("\n")}})};function h(t){let e=t.ref??"",n=t.x,r=t.y;return e&&"number"==typeof n&&"number"==typeof r?{data:t,text:`Tapped @${e} (${n}, ${r})`}:l(t)}let y={click:d(h),press:d(h),get:({input:t,result:e})=>{var n;let r;return r=(n={result:e,format:t.format}).result,"text"===n.format?{data:r,text:"string"==typeof r.text?r.text:""}:"attrs"===n.format?{data:r,text:JSON.stringify(r.node??{},null,2)}:l(r)},is:d(function(t){return{data:t,text:`Passed: is ${t.predicate??"assertion"}`}}),find:d(function(t){return"string"==typeof t.text?{data:t,text:t.text}:"boolean"==typeof t.found?{data:t,text:`Found: ${t.found}`}:t.node?{data:t,text:JSON.stringify(t.node,null,2)}:l(t)})};function g(t){return l(o(t))}let v={boot:d(function(t){let e=t.platform??"unknown",n=t.device??t.id??"unknown";return{data:t,text:`Boot ready: ${n} (${e})`}}),shutdown:d(function(t){let e=t.platform??"unknown",n=t.device??t.id??"unknown",r=t.shutdown,o=!!r&&"object"==typeof r&&"success"in r&&!0===r.success;return{data:t,text:`${o?"Shutdown":"Shutdown failed"}: ${n} (${e})`}}),devices:d(function(t){return{data:{devices:t.map(s)},text:t.map(b).join("\n")}}),apps:({input:t,result:e})=>{var n;return{data:{apps:(n={result:e,appsFilter:t.appsFilter}).result},stderr:"all"===n.appsFilter?"Showing all apps, including system apps.\n":"Showing user-installed apps. Use --all to include system apps.\n",text:n.result.length>0?n.result.join("\n"):"all"===n.appsFilter?"No apps found.":"No user-installed apps found."}},session:d(function(t){if("stateDir"in t)return{data:t,text:t.stateDir};let e={sessions:t.sessions.map(n)};return{data:e,text:JSON.stringify(e,null,2)}}),open:d(function(e){let n=t(e),o=[r(n)].filter(t=>!!t);return"string"==typeof n.sessionStateDir&&o.push(`Session state: ${n.sessionStateDir}`),{data:n,text:o.join("\n")||null}}),close:d(function(t){return l(a(t))}),install:d(g),reinstall:d(g),"install-from-source":d(function(t){return l(i(t))}),prepare:p};function b(t){let e=t.kind?` ${t.kind}`:"",n=t.target?` target=${t.target}`:"",r="boolean"==typeof t.booted?` booted=${t.booted}`:"";return`${t.name} (${t.platform}${e}${n})${r}`}let x={logs:d(function(t){var e;let n="string"==typeof t.path?t.path:"";return{data:t,text:n,stderr:F([M(t,["active","state","backend","sizeBytes"]),(e=t,["started","stopped","marked","cleared","restarted","removedRotatedFiles"].map(t=>{var n,r;return n=t,!0===(r=e[t])?`${n}=true`:"number"==typeof r?`${n}=${r}`:""}).filter(Boolean).join(" ")||void 0),"string"==typeof t.hint?t.hint:void 0,k(t.notes)])}}),network:d(function(t){let e=[],n="string"==typeof t.path?t.path:"";n&&e.push(n);let r=Array.isArray(t.entries)?t.entries:[];if(0===r.length)e.push("No recent HTTP(s) entries found.");else for(let t of r)e.push(...function(t){let e=f(t)??{},n="string"==typeof e.method?e.method:"HTTP",r="string"==typeof e.url?e.url:"<unknown-url>",o="number"==typeof e.status?` status=${e.status}`:"",a="string"==typeof e.timestamp?`${e.timestamp} `:"",i="number"==typeof e.durationMs?` durationMs=${e.durationMs}`:"",s=[`${a}${n} ${r}${o}${i}`];return w(s,"headers",e.headers),w(s,"request",e.requestBody),w(s,"response",e.responseBody),s}(t));return{data:t,text:e.join("\n"),stderr:F([M(t,["active","state","backend","include","scannedLines","matchedLines"]),k(t.notes)])}})};function w(t,e,n){"string"==typeof n&&t.push(` ${e}: ${n}`)}function M(t,e){return e.map(e=>void 0!==t[e]&&null!==t[e]?`${e}=${t[e]}`:"").filter(Boolean).join(" ")||void 0}function k(t){if(!Array.isArray(t))return;let e=t.filter(t=>"string"==typeof t&&t.length>0);return e.length>0?e.join("\n"):void 0}function F(t){return t.filter(t=>!!t).join("\n")||void 0}let P={perf:d(function(t){return{data:t,text:function(t){var e,n,r,o;let a,i="xctrace"===(e=t).kind?function(t){var e,n,r,o,a;let i="string"==typeof t.perf?t.perf:void 0,s="string"==typeof(e=t).outPath?e.outPath:"string"==typeof e.reportPath?e.reportPath:void 0;if(i&&s&&"xctrace"===t.kind){let e;return n=s,r="string"==typeof t.mode?t.mode:"capture",o=i,a=t.template,e=[n,`Perf ${r}: ${o}`],"string"==typeof a&&e.push(`Template: ${a}`),e.join("\n")}}(e):function(t){var e;let n,r,o,a=(n=j((e=t).action),r=j(e.kind),o=j(e.type),n&&r&&o?{action:n,kind:r,type:o}:void 0);if(a){let e;return`Perf ${a.action}: ${a.kind} ${a.type}${(e=j(t.state))?` state=${e}`:""}${function(t){let e=j(t.outPath);if(!e)return"";let n=S(t.sizeBytes);return`
|
|
2
|
+
${e}${void 0!==n?` (${N(n)})`:""}`}(t)}${function(t){let e=f(t.summary),n=f(e?.frameHealth);if(!n||!0!==n.available)return"";let r=S(n.droppedFramePercent),o=S(n.droppedFrameCount),a=S(n.totalFrameCount);return void 0===r||void 0===o||void 0===a?"":`
|
|
3
|
+
Trace frame health: dropped ${A(r)} (${Math.round(o)}/${Math.round(a)} frames)`}(t)}`}}(e);if(i)return i;let s=f(t.artifact);if(s)return function(t){let e="string"==typeof t.kind?t.kind:"memory";if(!1===t.available){let n="string"==typeof t.reason&&t.reason.length>0?t.reason:"not available";return`Memory artifact (${e}): unavailable - ${n}`}let n="string"==typeof t.path?t.path:void 0,r=S(t.sizeBytes),o=void 0===r?"":` (${N(r)})`;return n?`Memory artifact (${e}): ${n}${o}`:`Memory artifact (${e}): captured${o}`}(s);let u=f(t.metrics),d=f(u?.fps),p=(n=u,(a=[function(t){if(t?.available!==!0)return;let e=S(t.usagePercent);return void 0!==e?`CPU ${A(e)}`:void 0}(f(n?.cpu)),function(t){let e;if(t?.available!==!0)return;let n=S(t.residentMemoryKb)??S(t.totalPssKb)??S(t.totalRssKb);return void 0!==n?`memory ${e=n/1024,`${e>=10?Math.round(e):e.toFixed(1)}MB`}`:void 0}(f(n?.memory))].filter(t=>!!t)).length>0?a.join(", "):void 0);if(!d)return B(p,"missing frame metric");if(!1===d.available){return B(p,"string"==typeof(r=d).reason&&r.reason.length>0?r.reason:"not available")}let l=function(t){let e=S(t.droppedFramePercent),n=S(t.droppedFrameCount);if(void 0!==e&&void 0!==n){var r,o,a;return[`dropped ${A(e)}`,(r=n,void 0!==(o=S(t.totalFrameCount))?`(${Math.round(r)}/${Math.round(o)} frames)`:`(${Math.round(r)} dropped frames)`),void 0!==(a=S(t.sampleWindowMs))?`window ${I(a)}`:""].filter(Boolean).join(" ")}}(d);if(!l)return B(p,"missing dropped-frame summary");let m=[`Frame health: ${l}`],$=(Array.isArray(o=d.worstWindows)?o.filter(c):[]).flatMap(t=>{let e=function(t){let e=S(t.startOffsetMs),n=S(t.endOffsetMs),r=S(t.missedDeadlineFrameCount);if(void 0===e||void 0===n||void 0===r)return;let o=S(t.worstFrameMs),a=void 0===o?"":`, worst ${I(o)}`;return`- +${I(e)}-+${I(n)}: ${Math.round(r)} missed-deadline frames${a}`}(t);return e?[e]:[]});return $.length>0&&m.push("Worst windows:",...$),m.join("\n")}(t)}})};function j(t){return"string"==typeof t?t:void 0}function B(t,e){return t?`Performance: ${t}`:`Frame health: unavailable - ${e}`}function S(t){return"number"==typeof t&&Number.isFinite(t)?t:void 0}function A(t){return`${Number.isInteger(t)?t:t.toFixed(1)}%`}function I(t){let e=Math.max(0,Math.round(t));if(e<1e3)return`${e}ms`;let n=Math.round(e/1e3);if(n<60)return`${n}s`;let r=Math.floor(n/60),o=n%60;return o>0?`${r}m ${o}s`:`${r}m`}function N(t){if(t<1024)return`${Math.round(t)}B`;let e=t/1024;if(e<1024)return`${e>=10?Math.round(e):e.toFixed(1)}KB`;let n=e/1024;return`${n>=10?Math.round(n):n.toFixed(1)}MB`}let O={record:d(function(t){let e,n="string"==typeof t.outPath?t.outPath:"",r=Array.isArray(e=t.chunks)?e.flatMap(t=>t&&"object"==typeof t?"number"!=typeof t.index||"string"!=typeof t.path?[]:[{index:t.index,path:t.path}]:[]):[];if(r.length<=1){var o,a;let e;return{data:t,text:(o=t,e=[],(a=n)&&e.push(a),"string"==typeof o.sessionStateDir&&e.push(`Session state: ${o.sessionStateDir}`),"string"==typeof o.warning&&e.push(`Warning: ${o.warning}`),"string"==typeof o.overlayWarning&&e.push(`Overlay warning: ${o.overlayWarning}`),e.join("\n"))}}let i=["Recording chunks:"];for(let t of r)i.push(` ${t.index}: ${t.path}`);return"string"==typeof t.telemetryPath&&i.push(`Telemetry: ${t.telemetryPath}`),"string"==typeof t.warning&&i.push(`Warning: ${t.warning}`),"string"==typeof t.overlayWarning&&i.push(`Overlay warning: ${t.overlayWarning}`),{data:t,text:i.join("\n")}})},T={appstate:d(function(t){return{data:t,text:function(t){if("ios"===t.platform){let e=[`Foreground app: ${t.appName??t.appBundleId??"unknown"}`];return t.appBundleId&&e.push(`Bundle: ${t.appBundleId}`),t.source&&e.push(`Source: ${t.source}`),e.join("\n")}if("android"===t.platform){let e=[`Foreground app: ${t.package??"unknown"}`];return t.activity&&e.push(`Activity: ${t.activity}`),e.join("\n")}return null}(t)}}),back:p,home:p,rotate:p,"app-switcher":p,keyboard:d(function(t){if("android"===t.platform&&"status"===t.action){var e;let n=[`Keyboard visible: ${!0===t.visible?"yes":"no"}`,`Input type: ${t.type??t.inputType??"unknown"}`,`Input owner: ${t.inputOwner??"unknown"}`];return t.inputMethodPackage&&n.push(`Input method: ${t.inputMethodPackage}`),t.focusedPackage&&n.push(`Focused package: ${t.focusedPackage}`),t.focusedResourceId&&n.push(`Focused resource: ${t.focusedResourceId}`),n.push(`Next action: ${(e=t.visible,"ime"===t.inputOwner?"Focused input appears to be owned by the keyboard/IME; dismiss or change the IME before retrying text entry.":!0===e?"Keyboard is visible and focused input appears app-owned; fill/type can proceed.":"Keyboard is hidden; focus an app field before type, or use fill with a concrete target.")}`),{data:t,text:n.join("\n")}}return l(t)}),clipboard:d(function(t){return"read"===t.action?{data:t,text:t.text}:l(t)})},D={...v,snapshot:({input:t,result:n})=>{var r;let o;return{data:o=e((r={result:n,raw:t.raw,interactiveOnly:t.interactiveOnly,scope:t.scope,depth:t.depth}).result),jsonData:function(t){let{unchanged:e,...n}=t;return n}(o),stderr:r.result.snapshotDiagnostics?.warning?`${r.result.snapshotDiagnostics.warning}
|
|
4
|
+
`:void 0,text:u(o,{raw:r.raw,flatten:r.interactiveOnly,scoped:"string"==typeof r.scope&&r.scope.trim().length>0,depthLimited:"number"==typeof r.depth})}},wait:p,alert:p,...T,...y,...x,...P,...$,...m,...O,metro:({input:t,result:e})=>{var n;return{data:(n={result:e,action:t.action}).result,text:"reload"===n.action?`Reloaded React Native apps via ${n.result.reloadUrl}`:JSON.stringify(n.result,null,2)}}};function C(t){return D[t.name]?.({input:t.input??{},result:t.result})}export{C as formatCliOutput};
|
package/dist/src/cli.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import{pathToFileURL as e}from"node:url";import t from"node:fs";import n from"node:crypto";import
|
|
2
|
-
`,{encoding:"utf8",mode:384}),t.chmodSync(e,384)}function ek(e,t){w({level:"warn",phase:"remote_connection_state_invalid",data:{session:e.session,cause:t instanceof Error?t.message:t?String(t):void 0}}),eI(e)}let eN=i.map(e=>e.key);function eU(e){let t={};for(let n of eN){let r=e[n];void 0!==r&&(t[n]=r)}return t}let eb=new Set(["connect","connection","close","disconnect","metro","session"]),eR=new Set(["open"]);async function eE(e){let t,n,{command:r,flags:o,client:s}=e;if(!o.remoteConfig)return{flags:o,runtime:e.runtime};let a=v(o.stateDir).baseDir,i=l({configPath:o.remoteConfig,cwd:process.cwd(),env:process.env}),c={...eU(i.profile),...o,remoteConfig:i.resolvedPath},d=eh({stateDir:a,session:c.session??"default"});if(d&&d.remoteConfigPath!==i.resolvedPath)throw new f("INVALID_ARGS","A different remote connection is already active for this session. Run connect --force or disconnect before using a different --remote-config.",{session:d.session,activeRemoteConfig:d.remoteConfigPath,requestedRemoteConfig:i.resolvedPath});let u=d??function(e,t){if(!e.tenant)throw new f("INVALID_ARGS","remote command requires tenant in remote config or via --tenant <id>.");if(!e.runId)throw new f("INVALID_ARGS","remote command requires runId in remote config or via --run-id <id>.");if(!e.daemonBaseUrl)throw new f("INVALID_ARGS","remote command requires daemonBaseUrl in remote config, config, env, or --daemon-base-url.");let n=new Date().toISOString();return{version:1,session:e.session??"default",remoteConfigPath:t,remoteConfigHash:ey(t),daemon:ev(e),tenant:e.tenant,runId:e.runId,leaseId:e.leaseId,leaseBackend:e.leaseBackend??ex(e),platform:e.platform,target:e.target,connectedAt:n,updatedAt:n}}(c,i.resolvedPath),m={...c,session:u.session},p=function(e,t){if(e)return eO(e,t)?e:void 0}(u.runtime,m.platform)??e.runtime,g=u,h=!d;if(w=r,!eb.has(w)){let e=u.leaseBackend??function(e,t){let n=ex(e);if(n)return n;throw new f("INVALID_ARGS",`${t} requires --platform ios|android or --lease-backend when the remote connection has not resolved a lease yet.`)}(o,r);var w,I,y,A,_,S=u,C=o,D=e;if(S.leaseBackend&&S.leaseBackend!==D)throw new f("INVALID_ARGS","Active remote connection is already bound to a different lease backend. Re-run connect --force to replace it.",{session:S.session,leaseBackend:S.leaseBackend});if(S.platform&&C.platform&&S.platform!==C.platform)throw new f("INVALID_ARGS","Active remote connection is already bound to a different platform. Re-run connect --force to replace it.",{session:S.session,platform:S.platform});if(S.target&&C.target&&S.target!==C.target)throw new f("INVALID_ARGS","Active remote connection is already bound to a different target. Re-run connect --force to replace it.",{session:S.session,target:S.target});let t=await e$(s,g,e);m.leaseId=t.leaseId,m.leaseBackend=e,m.platform=g.platform??m.platform,m.target=g.target??m.target,(g.leaseId!==t.leaseId||g.leaseBackend!==e)&&(g={...g,leaseId:t.leaseId,leaseBackend:e,platform:g.platform??o.platform,target:g.target??o.target,updatedAt:new Date().toISOString()},h=!0)}if(I=r,y=e.batchSteps,(eR.has(I)||"batch"===I&&y&&y.some(e=>{let t=e.command.trim().toLowerCase();return eR.has(t)&&void 0===e.runtime}))&&eM(m)&&(!g.leaseId&&m.leaseId&&(g={...g,leaseId:m.leaseId,leaseBackend:m.leaseBackend}),e.forceRuntimePrepare||!p||!eO(p,m.platform))){if(!g.leaseId)throw new f("INVALID_ARGS",`${r} requires a resolved remote lease before Metro runtime can be prepared.`);let e=await eP(m,s,u.remoteConfigPath,u.session,{tenantId:u.tenant,runId:u.runId,leaseId:g.leaseId});p=e.runtime;let o=(A=g.metro,_=e.cleanup,A?.projectRoot!==_?.projectRoot||A?.profileKey!==_?.profileKey||A?.consumerKey!==_?.consumerKey);t=o?g.metro:void 0,n=o?e.cleanup:void 0,g={...g,runtime:e.runtime,metro:e.cleanup,updatedAt:new Date().toISOString()},h=!0}if(h)try{ew({stateDir:a,state:g})}catch(e){throw await eT(n),e}return await eT(t),{flags:{...m,session:g.session,leaseId:g.leaseId,leaseBackend:g.leaseBackend,platform:g.platform??m.platform,target:g.target??m.target},runtime:p}}async function eP(e,t,n,r,o){if(!e.metroProjectRoot&&!e.metroPublicBaseUrl&&!e.metroProxyBaseUrl)return{};if("ios"!==e.platform&&"android"!==e.platform)throw new f("INVALID_ARGS",'Deferred Metro preparation requires platform "ios" or "android".');if(!e.metroPublicBaseUrl&&!e.metroProxyBaseUrl)throw new f("INVALID_ARGS","Deferred Metro preparation requires metroPublicBaseUrl or metroProxyBaseUrl when Metro settings are provided.");let s=await t.metro.prepare({projectRoot:e.metroProjectRoot,kind:function(e){if(void 0!==e){if("auto"===e||"react-native"===e||"expo"===e)return e;throw new f("INVALID_ARGS","metro prepare --kind must be auto, react-native, or expo")}}(e.metroKind),publicBaseUrl:e.metroPublicBaseUrl,proxyBaseUrl:e.metroProxyBaseUrl,bearerToken:e.metroBearerToken,bridgeScope:o,launchUrl:e.launchUrl,companionProfileKey:n,companionConsumerKey:r,port:e.metroPreparePort,listenHost:e.metroListenHost,statusHost:e.metroStatusHost,startupTimeoutMs:e.metroStartupTimeoutMs,probeTimeoutMs:e.metroProbeTimeoutMs,reuseExisting:!e.metroNoReuseExisting&&void 0,installDependenciesIfNeeded:!e.metroNoInstallDeps&&void 0,runtimeFilePath:e.metroRuntimeFile});return{runtime:"ios"===e.platform?s.iosRuntime:s.androidRuntime,cleanup:e.metroProxyBaseUrl?{projectRoot:s.projectRoot,profileKey:n,consumerKey:r}:void 0}}async function eT(e){if(e)try{await I(e)}catch{}}async function eL(e){try{await eg({projectRoot:process.cwd(),stateDir:e.stateDir,profileKey:e.state.remoteConfigPath,consumerKey:e.state.session})}catch{}}async function eB(e,t){if(t.leaseId)try{await e.leases.release({tenant:t.tenant,runId:t.runId,leaseId:t.leaseId,daemonBaseUrl:t.daemon?.baseUrl,daemonTransport:t.daemon?.transport,daemonServerMode:t.daemon?.serverMode})}catch{}}function ex(e){return e.leaseBackend?e.leaseBackend:"android"===e.platform?"android-instance":"ios"===e.platform?"ios-instance":void 0}function eM(e){let t=e.metroKind;return!!(e.metroPublicBaseUrl||e.metroProxyBaseUrl||e.metroProjectRoot||t)}function eO(e,t){return!e.platform||!t||"ios"!==t&&"android"!==t||e.platform===t}async function e$(e,t,n){if(t.leaseId&&t.leaseBackend===n){let r=await eG(e,t.leaseId,{tenant:t.tenant,runId:t.runId,leaseBackend:n});if(r)return r}return await e.leases.allocate({tenant:t.tenant,runId:t.runId,leaseBackend:n})}async function eG(e,t,n){try{return await e.leases.heartbeat({tenant:n.tenant,runId:n.runId,leaseId:t,leaseBackend:n.leaseBackend})}catch(e){var r;if((r=e)instanceof f&&"UNAUTHORIZED"===r.code&&(r.details?.reason==="LEASE_NOT_FOUND"||r.details?.reason==="LEASE_EXPIRED"||r.details?.reason==="LEASE_REVOKED"))return;throw e}}async function eV(e,t){let n=await e.text(),r={};if(n.trim().length>0)try{r=JSON.parse(n)}catch(n){throw new f("COMMAND_FAILED",t.invalidJsonMessage,{status:e.status},n instanceof Error?n:void 0)}if(!e.ok)throw new f("UNAUTHORIZED",t.rejectedMessage,{status:e.status,response:r});return r}async function ej(e){return await eK({command:e.command,flags:e.flags,stateDir:e.stateDir,allowInteractiveLogin:"connect"===e.command&&!e.flags.noLogin,env:e.env})}async function eK(e){let t=e.env??e.io?.env??process.env;if(!e.flags.daemonBaseUrl)return{flags:e.flags,source:"none"};if(e8(e.flags.daemonAuthToken))return{flags:e.flags,source:"flag"};if(e8(t.AGENT_DEVICE_DAEMON_AUTH_TOKEN))return{flags:e.flags,source:"env"};if(!function(e,t){if("1"===t.AGENT_DEVICE_CLOUD_AUTH||"true"===t.AGENT_DEVICE_CLOUD_AUTH||e8(t.AGENT_DEVICE_CLOUD_BASE_URL))return!0;try{let t=new URL(e).hostname.toLowerCase();return"agent-device.dev"===t||t.endsWith(".agent-device.dev")}catch{return!1}}(e.flags.daemonBaseUrl,t))return{flags:e.flags,source:"none"};let n=await ez({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io});if(n)return{flags:{...e.flags,daemonAuthToken:n.accessToken},source:"cli-session"};if(!e.allowInteractiveLogin){if(e.flags.noLogin)throw new f("UNAUTHORIZED","Remote daemon authentication is required.",{hint:"Run agent-device auth login, unset --no-login, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN."});throw eX(e.command,t)}let r=await eF({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io});return{flags:{...e.flags,daemonAuthToken:r.accessToken},source:"login"}}async function eH(e){let t=e.env??e.io?.env??process.env;if(e8(e.flags.daemonAuthToken))return{accessToken:e.flags.daemonAuthToken,cloudBaseUrl:eQ(t)};if(e8(t.AGENT_DEVICE_DAEMON_AUTH_TOKEN))return{accessToken:t.AGENT_DEVICE_DAEMON_AUTH_TOKEN,cloudBaseUrl:eQ(t)};let n=await ez({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io});if(n)return{accessToken:n.accessToken,cloudBaseUrl:n.cloudBaseUrl};if(e.flags.noLogin)throw new f("UNAUTHORIZED","Cloud connection profile authentication is required.",{hint:"Run agent-device auth login, unset --no-login, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN."});let r=await eF({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io,commandLabel:"agent-device connect"});return{accessToken:r.accessToken,cloudBaseUrl:r.session.cloudBaseUrl}}async function eF(e){let n,o,s,a=e.env??e.io?.env??process.env,i=(d=a,u=e.io,n=u?.stdinIsTTY??process.stdin.isTTY,o=u?.stdoutIsTTY??process.stdout.isTTY,"true"!==(m=d).CI&&"true"!==m.GITHUB_ACTIONS&&"true"!==m.BUILDKITE&&n&&o?(p=d).SSH_TTY||p.SSH_CONNECTION||"true"===p.CODESPACES||p.GITPOD_WORKSPACE_ID||"true"===p.REMOTE_CONTAINERS?"device-code":"local-browser":"non-interactive");if("non-interactive"===i)throw eX(e.commandLabel??"agent-device connect",a);let l=eQ(a),c=await eY({baseUrl:l,pathName:"/api/control-plane/device-auth/start",body:{client:"agent-device",tenant:e.flags.tenant,runId:e.flags.runId,daemonBaseUrl:e.flags.daemonBaseUrl,session:e.flags.session},fetchImpl:e.io?.fetch});var d,u,m,p,g,h,w=c;if(!e8(w.deviceCode)||!e8(w.userCode)||!e8(w.verificationUri))throw new f("COMMAND_FAILED","Cloud auth start returned an unusable response.");let v=c.verificationUriComplete??c.verificationUri,I="local-browser"===i?c.verificationUri:(g=c.verificationUri,h=c.userCode,(s=new URL(g)).searchParams.set("user_code",h),s.toString());"local-browser"===i?(e1(e.io,`Opening ${c.verificationUri}...
|
|
3
|
-
`),await
|
|
4
|
-
${
|
|
1
|
+
import{pathToFileURL as e}from"node:url";import t from"node:fs";import n from"node:crypto";import o from"node:path";import{resolveRemoteConfigProfile as r,resolveRemoteConfigPath as s,REMOTE_CONFIG_FIELD_SPECS as a,parseSourceValue as i,buildPrimaryEnvVarName as l}from"./4723.js";import{isClientBackedCliCommandName as c,listCliCommandNames as d}from"./2133.js";import{getCliCommandSchema as u,applyCommandDefaults as f,getCommandSchema as m}from"./9581.js";import{asAppError as p,normalizeError as g,AppError as h}from"./733.js";import{buildCommandUsageText as w,buildUsageText as v}from"./cli-help.js";import{ensureCompanionTunnel as y,stopCompanionTunnel as I}from"./8275.js";import{REACT_DEVTOOLS_COMPANION_RUN_ARG as A}from"./4069.js";import{createRequestId as _,withDiagnosticsScope as S,getDiagnosticsMeta as k,flushDiagnosticsToSessionFile as D,emitDiagnostic as C}from"./432.js";import{resolveDaemonPaths as N}from"./2892.js";import{stopMetroTunnel as b}from"./metro.js";import{runCmdStreaming as R,runCmd as U}from"./8875.js";import{formatSnapshotDiffText as E,formatScreenshotDiffText as P,printHumanError as L,printJson as T}from"./6311.js";import{parseSelectorChain as x}from"./9836.js";import{stringifyMaestroYamlDocuments as B,parseReplayScriptDetailed as M,formatMaestroPoint as O,readReplayScriptMetadata as $}from"./4428.js";import{resolveUserPath as V,expandUserHomePath as G}from"./9612.js";import{interactionCliReaders as j,observabilityCliReaders as K,parseInstallSourceConfig as F,getFlagDefinition as H,gestureCliReaders as q,reactNativeCliReaders as W,getFlagDefinitions as J,captureCliReaders as z,GLOBAL_FLAG_KEYS as Z,replayCliReaders as Y,batchCliReaders as X,appCliReaders as Q,selectorCliReaders as ee,recordingCliReaders as et,systemCliReaders as en,perfCliReaders as eo}from"./9873.js";import{isCommandName as er,metroCliReaders as es,debuggingCliReaders as ea}from"./2948.js";import{formatCliOutput as ei}from"./cli-output.js";import{runCommand as el}from"./command-surface.js";import{createLocalArtifactAdapter as ec}from"./314.js";import{localCommandPolicy as ed,createAgentDevice as eu}from"./5299.js";import{readVersion as ef}from"./7244.js";import{createAgentDeviceClient as em,sendToDaemon as ep}from"./9919.js";import{maybeRunUpgradeNotifier as eg}from"./5448.js";function eh(e,t){for(let[n,o]of Object.entries(t))void 0!==o&&(e[n]=o);return e}let ew=new Set(["config","remoteConfig","help","version","batchSteps","githubActionsArtifact"]),ev=new Set(["appsFilter","iosSimulatorDeviceSet","sessionLocked","sessionLockConflicts"]),ey=function(){let e=new Map;for(let t of J()){let n=e.get(t.key);n?n.push(t):e.set(t.key,[t])}let t=new Map;for(let e of Z)t.set(e,new Set(["*"]));for(let e of d())for(let n of u(e).allowedFlags??[]){let o=t.get(n);o&&o.has("*")||(o?o.add(e):t.set(n,new Set([e])))}return[...e.entries()].map(([e,n])=>({key:e,flagDefinitions:n,config:{enabled:!ew.has(e),key:e},env:{names:ev.has(e)?[]:[l(e)]},supportsCommand(n){let o=t.get(e);return!!o&&(!!o.has("*")||!!n&&o.has(n))}})).sort((e,t)=>e.key.localeCompare(t.key))}(),eI=new Map(ey.map(e=>[e.key,e]));function eA(e,t){return eI.get(e)?.supportsCommand(t)??!1}function e_(e){let t=e.flagDefinitions.find(e=>void 0===e.setValue);if(t)return t;let n=function(e){let t=e.flagDefinitions[0];if(!t)throw Error(`Missing flag definition for option ${e.key}`);return t}(e);if("enum"===n.type){let t=n.enumValues??e.flagDefinitions.map(e=>e.setValue).filter(e=>void 0!==e);return{...n,setValue:void 0,enumValues:t}}return n}function eS(e){let t={json:!1,help:!1,version:!1},n=null,o=[],r=[],s=!0;for(let c=0;c<e.length;c+=1){var a,i,l;let d=e[c];if(s&&"--"===d){s=!1;continue}if(!s){n?o.push(d):n=eN(d);continue}let u=d.startsWith("--"),f=d.startsWith("-")&&d.length>1;if(!u&&!f){n?o.push(d):n=eN(d);continue}let[p,g]=u?ek(d):[d,void 0];if(a=n,"-c"===p&&("snapshot"===a||"diff"===a))continue;let w=H(p);if(i=n,l=w,"react-devtools"===i&&(!l||!eA(l.key,i))){o.push(d);continue}if(!w){if(function(e,t,n){var o;if(o=n,!/^-\d+(\.\d+)?$/.test(o)||!e)return!1;let r=m(e);if(!r||r.allowsExtraPositionals)return!0;let s=r.positionalArgs??[];return 0!==s.length&&(t.length<s.length||s.some(e=>e.includes("?")))}(n,o,d)){n?o.push(d):n=d;continue}throw new h("INVALID_ARGS",`Unknown flag: ${p}`)}let v=function(e,t,n,o){if(void 0!==e.setValue){if(void 0!==n)throw new h("INVALID_ARGS",`Flag ${t} does not take a value.`);return{value:e.setValue,consumeNext:!1}}if("boolean"===e.type){if(void 0!==n)throw new h("INVALID_ARGS",`Flag ${t} does not take a value.`);return{value:!0,consumeNext:!1}}if("booleanOrString"===e.type){if(void 0!==n){if(0===n.trim().length)throw new h("INVALID_ARGS",`Flag ${t} requires a non-empty value when provided.`);return{value:n,consumeNext:!1}}return void 0===o||eC(o)||!function(e){let t=e.trim();return!(!t||/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(t))&&!!(t.startsWith("./")||t.startsWith("../")||t.startsWith("~/")||t.startsWith("/")||t.includes("/")||t.includes("\\"))}(o)?{value:!0,consumeNext:!1}:{value:o,consumeNext:!0}}let r=n??o;if(void 0===r||void 0===n&&eC(r))throw new h("INVALID_ARGS",`Flag ${t} requires a value.`);if("string"===e.type)return{value:r,consumeNext:void 0===n};if("enum"===e.type){if(!e.enumValues?.includes(r))throw new h("INVALID_ARGS",`Invalid ${eD(t)}: ${r}`);return{value:r,consumeNext:void 0===n}}let s=Number(r);if(!Number.isFinite(s)||"number"==typeof e.min&&s<e.min||"number"==typeof e.max&&s>e.max)throw new h("INVALID_ARGS",`Invalid ${eD(t)}: ${r}`);return{value:Math.floor(s),consumeNext:void 0===n}}(w,p,g,e[c+1]);v.consumeNext&&(c+=1);let y=t[w.key];if(w.multiple){let e=Array.isArray(y)?[...y,v.value]:void 0===y?[v.value]:[y,v.value];t[w.key]=e}else t[w.key]=v.value;r.push({key:w.key,token:p})}return{command:n,positionals:o,flags:t,warnings:[],providedFlags:r}}function ek(e){let t=e.indexOf("=");return -1===t?[e,void 0]:[e.slice(0,t),e.slice(t+1)]}function eD(e){return e.replace(/^-+/,"")}function eC(e){if(!e.startsWith("-")||"-"===e)return!1;let[t]=e.startsWith("--")?ek(e):[e,void 0];return void 0!==H(t)}function eN(e){return"long-press"===e?"longpress":"metrics"===e?"perf":e}let eb={slug:"react-devtools-companion",runArg:A,displayName:"React DevTools companion"};async function eR(e){return await y({...e,definition:eb,localBaseUrl:e.localBaseUrl??"http://127.0.0.1:8097",registerPath:"/api/react-devtools/companion/register",unregisterPath:"/api/react-devtools/companion/unregister",devicePort:e.devicePort??8097})}async function eU(e){return await I({...e,definition:eb})}function eE(e){var n;let o,r=eB(e);if(!t.existsSync(r))return null;try{o=JSON.parse(t.readFileSync(r,"utf8"))}catch(t){return eG(e,t),null}return!(!(n=o)||"object"!=typeof n||Array.isArray(n))&&1===n.version&&"string"==typeof n.session&&"string"==typeof n.remoteConfigPath&&"string"==typeof n.remoteConfigHash&&(void 0===n.daemon||"object"==typeof n.daemon&&null!==n.daemon&&!Array.isArray(n.daemon))&&"string"==typeof n.tenant&&"string"==typeof n.runId&&(void 0===n.leaseId||"string"==typeof n.leaseId)&&(void 0===n.leaseBackend||"string"==typeof n.leaseBackend)&&"string"==typeof n.connectedAt&&"string"==typeof n.updatedAt?o:(eG(e),null)}function eP(e){let n=eB({stateDir:e.stateDir,session:e.state.session});t.mkdirSync(o.dirname(n),{recursive:!0}),eV(n,e.state),eV(eM(e.stateDir),{session:e.state.session})}function eL(e){return{baseUrl:function(e){if(!e)return;let t=new URL(e);for(let e of(t.username="",t.password="",[...t.searchParams.keys()]))/(auth|key|password|secret|token)/i.test(e)&&t.searchParams.delete(e);return t.toString().replace(/\/+$/,"")}(e.daemonBaseUrl),transport:e.daemonTransport,serverMode:e.daemonServerMode}}function eT(e){t.rmSync(eB(e),{force:!0});let n=eM(e.stateDir);e$(e.stateDir)===e.session&&t.rmSync(n,{force:!0})}function ex(e){try{return n.createHash("sha256").update(t.readFileSync(e)).digest("hex")}catch(t){throw new h("INVALID_ARGS",`Remote config file not found: ${e}`,{cause:t instanceof Error?t.message:String(t)})}}function eB(e){return o.join(e.stateDir,"remote-connections",`${function(e){let t=e.replaceAll(/[^a-zA-Z0-9._-]/g,"_");if(!t)return"default";if(t===e)return t;let o=n.createHash("sha256").update(e).digest("hex").slice(0,8);return`${t}-${o}`}(e.session)}.json`)}function eM(e){return o.join(e,"remote-connections",".active-session.json")}function eO(e){let t=e$(e.stateDir);return t?eE({stateDir:e.stateDir,session:t}):null}function e$(e){let n=eM(e);if(t.existsSync(n))try{let e=JSON.parse(t.readFileSync(n,"utf8"));return"string"==typeof e.session?e.session:void 0}catch{return}}function eV(e,n){t.writeFileSync(e,`${JSON.stringify(n,null,2)}
|
|
2
|
+
`,{encoding:"utf8",mode:384}),t.chmodSync(e,384)}function eG(e,t){C({level:"warn",phase:"remote_connection_state_invalid",data:{session:e.session,cause:t instanceof Error?t.message:t?String(t):void 0}}),eT(e)}let ej=a.map(e=>e.key);function eK(e){let t={};for(let n of ej){let o=e[n];void 0!==o&&(t[n]=o)}return t}let eF=new Set(["connect","connection","close","disconnect","metro","session"]),eH=new Set(["open"]);async function eq(e){let t,n,{command:o,flags:s,client:a}=e;if(!s.remoteConfig)return{flags:s,runtime:e.runtime};let i=N(s.stateDir).baseDir,l=r({configPath:s.remoteConfig,cwd:process.cwd(),env:process.env}),c={...eK(l.profile),...s,remoteConfig:l.resolvedPath},d=eE({stateDir:i,session:c.session??"default"});if(d&&d.remoteConfigPath!==l.resolvedPath)throw new h("INVALID_ARGS","A different remote connection is already active for this session. Run connect --force or disconnect before using a different --remote-config.",{session:d.session,activeRemoteConfig:d.remoteConfigPath,requestedRemoteConfig:l.resolvedPath});let u=d??function(e,t){if(!e.tenant)throw new h("INVALID_ARGS","remote command requires tenant in remote config or via --tenant <id>.");if(!e.runId)throw new h("INVALID_ARGS","remote command requires runId in remote config or via --run-id <id>.");if(!e.daemonBaseUrl)throw new h("INVALID_ARGS","remote command requires daemonBaseUrl in remote config, config, env, or --daemon-base-url.");let n=new Date().toISOString();return{version:1,session:e.session??"default",remoteConfigPath:t,remoteConfigHash:ex(t),daemon:eL(e),tenant:e.tenant,runId:e.runId,leaseId:e.leaseId,leaseBackend:e.leaseBackend??eY(e),platform:e.platform,target:e.target,connectedAt:n,updatedAt:n}}(c,l.resolvedPath),f={...c,session:u.session},m=function(e,t){if(e)return eQ(e,t)?e:void 0}(u.runtime,f.platform)??e.runtime,p=u,g=!d;if(w=o,!eF.has(w)){let e=u.leaseBackend??function(e,t){let n=eY(e);if(n)return n;throw new h("INVALID_ARGS",`${t} requires --platform ios|android or --lease-backend when the remote connection has not resolved a lease yet.`)}(s,o);var w,v,y,I,A,_=u,S=s,k=e;if(_.leaseBackend&&_.leaseBackend!==k)throw new h("INVALID_ARGS","Active remote connection is already bound to a different lease backend. Re-run connect --force to replace it.",{session:_.session,leaseBackend:_.leaseBackend});if(_.platform&&S.platform&&_.platform!==S.platform)throw new h("INVALID_ARGS","Active remote connection is already bound to a different platform. Re-run connect --force to replace it.",{session:_.session,platform:_.platform});if(_.target&&S.target&&_.target!==S.target)throw new h("INVALID_ARGS","Active remote connection is already bound to a different target. Re-run connect --force to replace it.",{session:_.session,target:_.target});let t=await e0(a,p,e);f.leaseId=t.leaseId,f.leaseBackend=e,f.platform=p.platform??f.platform,f.target=p.target??f.target,(p.leaseId!==t.leaseId||p.leaseBackend!==e)&&(p={...p,leaseId:t.leaseId,leaseBackend:e,platform:p.platform??s.platform,target:p.target??s.target,updatedAt:new Date().toISOString()},g=!0)}if(v=o,y=e.batchSteps,(eH.has(v)||"batch"===v&&y&&y.some(e=>{let t=e.command.trim().toLowerCase();return eH.has(t)&&void 0===e.runtime}))&&eX(f)&&(!p.leaseId&&f.leaseId&&(p={...p,leaseId:f.leaseId,leaseBackend:f.leaseBackend}),e.forceRuntimePrepare||!m||!eQ(m,f.platform))){if(!p.leaseId)throw new h("INVALID_ARGS",`${o} requires a resolved remote lease before Metro runtime can be prepared.`);let e=await eW(f,a,u.remoteConfigPath,u.session,{tenantId:u.tenant,runId:u.runId,leaseId:p.leaseId});m=e.runtime;let r=(I=p.metro,A=e.cleanup,I?.projectRoot!==A?.projectRoot||I?.profileKey!==A?.profileKey||I?.consumerKey!==A?.consumerKey);t=r?p.metro:void 0,n=r?e.cleanup:void 0,p={...p,runtime:e.runtime,metro:e.cleanup,updatedAt:new Date().toISOString()},g=!0}if(g)try{eP({stateDir:i,state:p})}catch(e){throw await eJ(n),e}return await eJ(t),{flags:{...f,session:p.session,leaseId:p.leaseId,leaseBackend:p.leaseBackend,platform:p.platform??f.platform,target:p.target??f.target},runtime:m}}async function eW(e,t,n,o,r){if(!e.metroProjectRoot&&!e.metroPublicBaseUrl&&!e.metroProxyBaseUrl)return{};if("ios"!==e.platform&&"android"!==e.platform)throw new h("INVALID_ARGS",'Deferred Metro preparation requires platform "ios" or "android".');if(!e.metroPublicBaseUrl&&!e.metroProxyBaseUrl)throw new h("INVALID_ARGS","Deferred Metro preparation requires metroPublicBaseUrl or metroProxyBaseUrl when Metro settings are provided.");let s=await t.metro.prepare({projectRoot:e.metroProjectRoot,kind:function(e){if(void 0!==e){if("auto"===e||"react-native"===e||"expo"===e)return e;throw new h("INVALID_ARGS","metro prepare --kind must be auto, react-native, or expo")}}(e.metroKind),publicBaseUrl:e.metroPublicBaseUrl,proxyBaseUrl:e.metroProxyBaseUrl,bearerToken:e.metroBearerToken,bridgeScope:r,launchUrl:e.launchUrl,companionProfileKey:n,companionConsumerKey:o,port:e.metroPreparePort,listenHost:e.metroListenHost,statusHost:e.metroStatusHost,startupTimeoutMs:e.metroStartupTimeoutMs,probeTimeoutMs:e.metroProbeTimeoutMs,reuseExisting:!e.metroNoReuseExisting&&void 0,installDependenciesIfNeeded:!e.metroNoInstallDeps&&void 0,runtimeFilePath:e.metroRuntimeFile});return{runtime:"ios"===e.platform?s.iosRuntime:s.androidRuntime,cleanup:e.metroProxyBaseUrl?{projectRoot:s.projectRoot,profileKey:n,consumerKey:o}:void 0}}async function eJ(e){if(e)try{await b(e)}catch{}}async function ez(e){try{await eU({projectRoot:process.cwd(),stateDir:e.stateDir,profileKey:e.state.remoteConfigPath,consumerKey:e.state.session})}catch{}}async function eZ(e,t){if(t.leaseId)try{await e.leases.release({tenant:t.tenant,runId:t.runId,leaseId:t.leaseId,daemonBaseUrl:t.daemon?.baseUrl,daemonTransport:t.daemon?.transport,daemonServerMode:t.daemon?.serverMode})}catch{}}function eY(e){return e.leaseBackend?e.leaseBackend:"android"===e.platform?"android-instance":"ios"===e.platform?"ios-instance":void 0}function eX(e){let t=e.metroKind;return!!(e.metroPublicBaseUrl||e.metroProxyBaseUrl||e.metroProjectRoot||t)}function eQ(e,t){return!e.platform||!t||"ios"!==t&&"android"!==t||e.platform===t}async function e0(e,t,n){if(t.leaseId&&t.leaseBackend===n){let o=await e1(e,t.leaseId,{tenant:t.tenant,runId:t.runId,leaseBackend:n});if(o)return o}return await e.leases.allocate({tenant:t.tenant,runId:t.runId,leaseBackend:n})}async function e1(e,t,n){try{return await e.leases.heartbeat({tenant:n.tenant,runId:n.runId,leaseId:t,leaseBackend:n.leaseBackend})}catch(e){var o;if((o=e)instanceof h&&"UNAUTHORIZED"===o.code&&(o.details?.reason==="LEASE_NOT_FOUND"||o.details?.reason==="LEASE_EXPIRED"||o.details?.reason==="LEASE_REVOKED"))return;throw e}}async function e3(e,t){let n=await e.text(),o={};if(n.trim().length>0)try{o=JSON.parse(n)}catch(n){throw new h("COMMAND_FAILED",t.invalidJsonMessage,{status:e.status},n instanceof Error?n:void 0)}if(!e.ok)throw new h("UNAUTHORIZED",t.rejectedMessage,{status:e.status,response:o});return o}async function e8(e){return await e2({command:e.command,flags:e.flags,stateDir:e.stateDir,allowInteractiveLogin:"connect"===e.command&&!e.flags.noLogin,env:e.env})}async function e2(e){let t=e.env??e.io?.env??process.env;if(!e.flags.daemonBaseUrl)return{flags:e.flags,source:"none"};if(tl(e.flags.daemonAuthToken))return{flags:e.flags,source:"flag"};if(tl(t.AGENT_DEVICE_DAEMON_AUTH_TOKEN))return{flags:e.flags,source:"env"};if(!function(e,t){if("1"===t.AGENT_DEVICE_CLOUD_AUTH||"true"===t.AGENT_DEVICE_CLOUD_AUTH||tl(t.AGENT_DEVICE_CLOUD_BASE_URL))return!0;try{let t=new URL(e).hostname.toLowerCase();return"agent-device.dev"===t||t.endsWith(".agent-device.dev")}catch{return!1}}(e.flags.daemonBaseUrl,t))return{flags:e.flags,source:"none"};let n=await e7({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io});if(n)return{flags:{...e.flags,daemonAuthToken:n.accessToken},source:"cli-session"};if(!e.allowInteractiveLogin){if(e.flags.noLogin)throw new h("UNAUTHORIZED","Remote daemon authentication is required.",{hint:"Run agent-device auth login, unset --no-login, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN."});throw to(e.command,t)}let o=await e9({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io});return{flags:{...e.flags,daemonAuthToken:o.accessToken},source:"login"}}async function e4(e){let t=e.env??e.io?.env??process.env;if(tl(e.flags.daemonAuthToken))return{accessToken:e.flags.daemonAuthToken,cloudBaseUrl:tr(t)};if(tl(t.AGENT_DEVICE_DAEMON_AUTH_TOKEN))return{accessToken:t.AGENT_DEVICE_DAEMON_AUTH_TOKEN,cloudBaseUrl:tr(t)};let n=await e7({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io});if(n)return{accessToken:n.accessToken,cloudBaseUrl:n.cloudBaseUrl};if(e.flags.noLogin)throw new h("UNAUTHORIZED","Cloud connection profile authentication is required.",{hint:"Run agent-device auth login, unset --no-login, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN."});let o=await e9({stateDir:e.stateDir,flags:e.flags,env:t,io:e.io,commandLabel:"agent-device connect"});return{accessToken:o.accessToken,cloudBaseUrl:o.session.cloudBaseUrl}}async function e9(e){let n,r,s,a=e.env??e.io?.env??process.env,i=(d=a,u=e.io,n=u?.stdinIsTTY??process.stdin.isTTY,r=u?.stdoutIsTTY??process.stdout.isTTY,"true"!==(f=d).CI&&"true"!==f.GITHUB_ACTIONS&&"true"!==f.BUILDKITE&&n&&r?(m=d).SSH_TTY||m.SSH_CONNECTION||"true"===m.CODESPACES||m.GITPOD_WORKSPACE_ID||"true"===m.REMOTE_CONTAINERS?"device-code":"local-browser":"non-interactive");if("non-interactive"===i)throw to(e.commandLabel??"agent-device connect",a);let l=tr(a),c=await tn({baseUrl:l,pathName:"/api/control-plane/device-auth/start",body:{client:"agent-device",tenant:e.flags.tenant,runId:e.flags.runId,daemonBaseUrl:e.flags.daemonBaseUrl,session:e.flags.session},fetchImpl:e.io?.fetch});var d,u,f,m,p,g,w=c;if(!tl(w.deviceCode)||!tl(w.userCode)||!tl(w.verificationUri))throw new h("COMMAND_FAILED","Cloud auth start returned an unusable response.");let v=c.verificationUriComplete??c.verificationUri,y="local-browser"===i?c.verificationUri:(p=c.verificationUri,g=c.userCode,(s=new URL(p)).searchParams.set("user_code",g),s.toString());"local-browser"===i?(ta(e.io,`Opening ${c.verificationUri}...
|
|
3
|
+
`),await ts(v,e.io)):ta(e.io,`Open this URL on your machine:
|
|
4
|
+
${y}
|
|
5
5
|
|
|
6
6
|
Waiting for approval for 10 minutes...
|
|
7
|
-
`);let
|
|
8
|
-
`,{mode:384});try{t.chmodSync(n,384)}catch{}}({stateDir:e.stateDir,session:S}),{accessToken:
|
|
7
|
+
`);let I=await tt({cloudBaseUrl:l,deviceCode:c.deviceCode,expiresIn:c.expiresIn,interval:c.interval,fetchImpl:e.io?.fetch,now:e.io?.now}),A=I.cliSession?.refreshCredential??I.cliSession?.refreshToken;if(!tl(I.accessToken)||!tl(A))throw new h("UNAUTHORIZED","Device authorization did not return CLI credentials.");let _=new Date(e.io?.now?.()??Date.now()).toISOString(),S={version:1,id:I.cliSession?.id??`cli-${Date.now().toString(36)}`,cloudBaseUrl:l,workspaceId:I.cliSession?.workspaceId,accountId:I.cliSession?.accountId,name:I.cliSession?.name,refreshCredential:A,createdAt:_,expiresAt:I.cliSession?.expiresAt};return function(e){let n=e6(e.stateDir);t.mkdirSync(o.dirname(n),{recursive:!0,mode:448}),t.writeFileSync(n,`${JSON.stringify(e.session,null,2)}
|
|
8
|
+
`,{mode:384});try{t.chmodSync(n,384)}catch{}}({stateDir:e.stateDir,session:S}),{accessToken:I.accessToken,expiresAt:I.expiresAt,session:S}}function e5(e){let n=e6(e.stateDir);if(!t.existsSync(n))return null;try{let e=JSON.parse(t.readFileSync(n,"utf8"));if(1!==e.version||!tl(e.id)||!tl(e.cloudBaseUrl)||!tl(e.refreshCredential)||!tl(e.createdAt))return null;return e}catch{return null}}function e6(e){return o.join(e,"auth","cli-session.json")}async function e7(e){let t=e5({stateDir:e.stateDir});return!t||ti(t.expiresAt,e.io?.now)?null:{accessToken:(await te({session:t,flags:e.flags,env:e.env,io:e.io})).accessToken,cloudBaseUrl:tr(e.env,t.cloudBaseUrl)}}async function te(e){let t=tr(e.env,e.session.cloudBaseUrl),n=await tn({baseUrl:t,pathName:"/api/control-plane/cli-session/refresh",body:{refreshCredential:e.session.refreshCredential,tenant:e.flags.tenant,runId:e.flags.runId,daemonBaseUrl:e.flags.daemonBaseUrl,session:e.flags.session},fetchImpl:e.io?.fetch});if(tl(n.accessToken))return{accessToken:n.accessToken,expiresAt:n.expiresAt};if("revoked"===n.status||"revoked"===n.error)throw new h("UNAUTHORIZED","Stored cloud CLI session was revoked.",{hint:"Run agent-device auth login again, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN.",status:n.status,error:n.error});throw new h("UNAUTHORIZED","Failed to refresh CLI session.",{hint:"Run agent-device auth login again, or set AGENT_DEVICE_DAEMON_AUTH_TOKEN.",status:n.status,error:n.error})}async function tt(e){let t=e.now??Date.now,n=Math.min((e.expiresIn??600)*1e3,6e5),o=t()+n,r=Math.max(1e3,(e.interval??5)*1e3);for(;t()<o;){let t=await tn({baseUrl:e.cloudBaseUrl,pathName:"/api/control-plane/device-auth/poll",body:{deviceCode:e.deviceCode},fetchImpl:e.fetchImpl});if("approved"===t.status||tl(t.accessToken))return t;if("slow_down"===t.status||"slow_down"===t.error)r+=1e3;else if("authorization_pending"!==t.status&&"authorization_pending"!==t.error)throw new h("UNAUTHORIZED","Device authorization was not approved.",{status:t.status,error:t.error});await tc(r)}throw new h("TIMEOUT","Device authorization expired before approval.")}async function tn(e){let t=e.fetchImpl??fetch,n=await t(new URL(e.pathName,e.baseUrl),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e.body),signal:AbortSignal.timeout(15e3)});return await e3(n,{invalidJsonMessage:`Cloud auth endpoint returned invalid JSON (${n.status}).`,rejectedMessage:"Cloud auth endpoint rejected the request."})}function to(e,t){let n=tr(t);return new h("UNAUTHORIZED",`${e} cannot perform interactive login in CI or a non-interactive shell.`,{hint:`Create a service/API token: ${new URL("/api-keys",n).toString()} Then set AGENT_DEVICE_DAEMON_AUTH_TOKEN=adc_live_...`})}function tr(e,t){let n=e.AGENT_DEVICE_CLOUD_BASE_URL??t??"https://cloud.agent-device.dev";try{return new URL(n).toString().replace(/\/+$/,"")}catch(e){throw new h("INVALID_ARGS","Invalid AGENT_DEVICE_CLOUD_BASE_URL.",{cloudBaseUrl:n},e instanceof Error?e:void 0)}}async function ts(e,t){if(t?.openBrowser)return void await t.openBrowser(e);let n=process.platform;try{"darwin"===n?await U("open",[e],{allowFailure:!0,timeoutMs:5e3}):"win32"===n?await U("cmd",["/c","start","",e],{allowFailure:!0,timeoutMs:5e3}):await U("xdg-open",[e],{allowFailure:!0,timeoutMs:5e3})}catch{ta(t,`Open this URL on your machine:
|
|
9
9
|
${e}
|
|
10
|
-
`)}}function
|
|
11
|
-
`,{mode:384});try{t.chmodSync(i,384)}catch{}return i}({stateDir:e.stateDir,profile:
|
|
12
|
-
`))}let e9=async({flags:e,client:t})=>{var r,o,s,a;let i=v(e.stateDir).baseDir,c=e.remoteConfig?function(e){if(!e.remoteConfig)throw new f("INVALID_ARGS","connect requires --remote-config <path>.");let t=l({configPath:e.remoteConfig,cwd:process.cwd(),env:process.env});return{flags:e,remoteConfigPath:t.resolvedPath}}(e):await e4({flags:e,stateDir:i,cwd:process.cwd(),env:process.env}),d=c.flags,u=d.tenant,m=d.runId;if(!u)throw new f("INVALID_ARGS","connect requires tenant in remote config or via --tenant <id>.");if(!m)throw new f("INVALID_ARGS","connect requires runId in remote config or via --run-id <id>.");if(!d.daemonBaseUrl)throw new f("INVALID_ARGS","connect requires daemonBaseUrl in remote config, config, env, or --daemon-base-url.");let p=d.session?null:eS({stateDir:i}),g=d.session??p?.session??function(e){for(let t=0;t<8;t+=1){let t=`adc-${n.randomBytes(3).toString("hex")}`;if(!eh({stateDir:e,session:t}))return t}return`adc-${Date.now().toString(36)}-${n.randomBytes(2).toString("hex")}`}(i),h=ey(c.remoteConfigPath),w=ev(d),I=p?.session===g?p:eh({stateDir:i,session:g});if(I&&(r=I,o={flags:d,session:g,remoteConfigPath:c.remoteConfigPath,remoteConfigHash:h,desiredLeaseBackend:ex(d),daemon:w},r.remoteConfigPath!==o.remoteConfigPath||r.remoteConfigHash!==o.remoteConfigHash||r.session!==o.session||r.tenant!==o.flags.tenant||r.runId!==o.flags.runId||void 0!==o.desiredLeaseBackend&&r.leaseBackend!==o.desiredLeaseBackend||void 0!==o.flags.platform&&r.platform!==o.flags.platform||void 0!==o.flags.target&&r.target!==o.flags.target||(s=r.daemon,a=o.daemon,(s?.baseUrl??void 0)!==(a?.baseUrl??void 0)||(s?.transport??void 0)!==(a?.transport??void 0)||(s?.serverMode??void 0)!==(a?.serverMode??void 0)))&&!d.force)throw new f("INVALID_ARGS","A different remote connection is already active for this session. Re-run connect with --force to replace it.",{session:g,remoteConfig:I.remoteConfigPath});let y=new Date().toISOString(),A={version:1,session:g,remoteConfigPath:c.remoteConfigPath,remoteConfigHash:h,daemon:w,tenant:u,runId:m,leaseId:I&&!d.force?I.leaseId:void 0,leaseBackend:I&&!d.force?I.leaseBackend:ex(d),platform:d.platform??(I&&!d.force?I.platform:void 0),target:d.target??(I&&!d.force?I.target:void 0),runtime:I&&!d.force?I.runtime:void 0,metro:I&&!d.force?I.metro:void 0,connectedAt:I&&!d.force?I.connectedAt:y,updatedAt:y};ew({stateDir:i,state:A}),I&&d.force&&(await eT(I.metro),await eL({stateDir:i,state:I}),await eB(t,I));let _=tr(A),S=function(e,t){if(!t.runtime&&(eM(e)||ts(t.remoteConfigPath)))return to(t.remoteConfigPath)}(d,A);return e6(d,ta(A,S),()=>[`Connected remote session "${g}" tenant "${u}" run "${m}" ${A.leaseId?`lease ${A.leaseId}`:"lease pending"}`,_?.message,S?.message].filter(e=>!!e).join("\n")),!0},e7=async({flags:e,client:t})=>{let{session:n,stateDir:r,state:o}=tt(e);if(!o)return tn(e,n),!0;let s=o.session;try{await t.sessions.close({shutdown:e.shutdown})}catch{}await eT(o.metro),await eL({stateDir:r,state:o});let a=!1;if(o.leaseId)try{a=(await t.leases.release({tenant:o.tenant,runId:o.runId,leaseId:o.leaseId})).released}catch{}return eI({stateDir:r,session:s}),e6(e,{connected:!1,session:s,released:a},()=>`Disconnected remote session "${s}".`),!0},te=async({positionals:e,flags:t})=>{if("status"!==e[0])throw new f("INVALID_ARGS","connection accepts only: status");let{session:n,state:r}=tt(t);if(!r)return tn(t,n),!0;let o=tr(r),s=function(e){if(!e.runtime&&ts(e.remoteConfigPath))return to(e.remoteConfigPath)}(r);return e6(t,ta(r,s),()=>[`Connected remote session "${r.session}".`,`tenant=${r.tenant} runId=${r.runId} leaseId=${r.leaseId??"pending"} backend=${r.leaseBackend??"pending"}`,`remoteConfig=${r.remoteConfigPath}`,r.runtime?"metro=prepared":"metro=not-prepared",o?.message,s?.message].filter(e=>!!e).join("\n")),!0};function tt(e){let t=e.session??"default",n=v(e.stateDir).baseDir;return{session:t,stateDir:n,state:eh({stateDir:n,session:t})??(e.session?null:eS({stateDir:n}))}}function tn(e,t){e6(e,{connected:!1,session:t},()=>`No remote connection for "${t}".`)}function tr(e){if(!e.leaseId)return{status:"deferred",nextSteps:["agent-device install-from-source <artifact-url> --platform ios|android","agent-device open <app-id> --relaunch","agent-device snapshot -i","agent-device devices"],message:"Lease allocation is pending; run install-from-source, open, snapshot, or devices when ready to allocate or refresh the lease."+(void 0===e.platform&&void 0===e.leaseBackend?" Add --platform ios|android if the profile does not set a platform.":"")}}function to(e){let t=`agent-device metro prepare --remote-config ${e}`;return{status:"deferred",nextStep:t,message:`Metro runtime is not prepared yet; it will be prepared automatically on first open, or run "${t}" to inspect it before launch.`}}function ts(e){try{let t=l({configPath:e,cwd:process.cwd(),env:process.env}).profile;return!!(t.metroPublicBaseUrl||t.metroProxyBaseUrl||t.metroProjectRoot||t.metroKind)}catch{return!1}}function ta(e,t){let r=tr(e);return{connected:!0,session:e.session,tenant:e.tenant,runId:e.runId,leaseAllocated:!!e.leaseId,leaseId:e.leaseId,leaseBackend:e.leaseBackend,platform:e.platform,target:e.target,remoteConfig:e.remoteConfigPath,remoteConfigHash:e.remoteConfigHash,daemonBaseUrlFingerprint:function(e){if(e)return n.createHash("sha256").update(e).digest("hex").slice(0,12)}(e.daemon?.baseUrl),metro:e.metro?{prepared:!0,projectRoot:e.metro.projectRoot}:{prepared:!1},...r?{leasePreparation:r}:{},...t?{runtimePreparation:t}:{},connectedAt:e.connectedAt,updatedAt:e.updatedAt}}let ti=async({positionals:e,flags:n})=>{let r=e[0]??"status",o=v(n.stateDir).baseDir;if("status"===r){var s;let e,t=(e=eq({stateDir:(s={stateDir:o}).stateDir}))?{authenticated:!0,source:"cli-session",sessionId:e.id,cloudBaseUrl:e.cloudBaseUrl,workspaceId:e.workspaceId,accountId:e.accountId,name:e.name,createdAt:e.createdAt,expiresAt:e.expiresAt,expired:e3(e.expiresAt,s.now)}:{authenticated:!1,source:"none"};return e6(n,t,()=>{var e;return(e=t).authenticated?["Authenticated with cloud CLI session.",`cloud=${e.cloudBaseUrl}`,`session=${e.sessionId}`,e.workspaceId?`workspace=${e.workspaceId}`:null,e.accountId?`account=${e.accountId}`:null,e.expiresAt?`expiresAt=${e.expiresAt}`:null,e.expired?"status=expired":null].filter(e=>!!e).join("\n"):"Not authenticated."}),!0}if("login"===r){let e=await eF({stateDir:o,flags:n,commandLabel:"agent-device auth login"});return e6(n,{authenticated:!0,source:"cli-session",sessionId:e.session.id,cloudBaseUrl:e.session.cloudBaseUrl,workspaceId:e.session.workspaceId,accountId:e.session.accountId,expiresAt:e.session.expiresAt,agentTokenExpiresAt:e.expiresAt},()=>"Authenticated with cloud CLI session."),!0}if("logout"===r){let e,r=(e=eJ({stateDir:o}.stateDir),!!t.existsSync(e)&&(t.rmSync(e,{force:!0}),!0));return e6(n,{authenticated:!1,removed:r},()=>r?"Removed stored cloud CLI session.":"No stored cloud CLI session."),!0}throw new f("INVALID_ARGS","auth accepts only: status, login, logout")},tl=new Set(["id","text","label"]),tc=new Set(["enabled","selected"]),td={open:function(e){var t,n,r;let o,s,a,[i,l]=e.positionals;if(!i)return{kind:"unsupported",message:"open requires an app id or URL"};if(tI(i))return{kind:"commands",commands:[{openLink:i}]};let c=(t=e,n=i,(a=(r=t,o=r.flags?.launchArgs,s={},r.flags?.relaunch===!0&&(s.stopApp=!0),r.flags?.clearAppState===!0&&(s.clearState=!0),Array.isArray(o)&&o.length>0&&(s.launchArguments=o),Object.keys(s).length>0?s:void 0))?{launchApp:{appId:n,...a}}:"launchApp");return l&&tI(l)?{kind:"config",appId:i,commands:[c,{openLink:l}]}:l?{kind:"unsupported",message:"open with a non-URL second argument is unsupported"}:{kind:"config",appId:i,commands:[c]}},click:tu,press:tu,longpress:function(e){let[t,n]=e.positionals;if(!t)return{kind:"unsupported",message:"longpress requires a target"};let r=tp(t,n);return r?{kind:"commands",commands:[{longPressOn:r}],warnings:(function(e){let[t,n,r]=e.positionals,o=ty(t)&&ty(n)?r:n;return o&&ty(o)?[Number(o)]:[]})(e).map(tf)}:{kind:"unsupported",message:"longpress target is not Maestro-compatible"}},fill:function(e){let[t,n]=e.positionals;if(!t||void 0===n)return{kind:"unsupported",message:"fill requires a target and text"};let r=tp(t);return r?{kind:"commands",commands:[{tapOn:r},{inputText:n}],warnings:["fill exports as tapOn + inputText; Maestro may append text instead of replacing existing field contents"]}:{kind:"unsupported",message:"fill target is not Maestro-compatible"}},type:function(e){var t;let[n]=e.positionals;if(void 0===n)return{kind:"unsupported",message:"type requires text"};let r=0!==(t=n).length&&[...t].every(e=>"\b"===e)?t.length:null;return null!==r?{kind:"commands",commands:[{eraseText:r}]}:{kind:"commands",commands:[{inputText:n}]}},keyboard:function(e){let[t]=e.positionals;return"dismiss"===t?{kind:"commands",commands:["hideKeyboard"]}:"enter"===t||"return"===t?{kind:"commands",commands:[{pressKey:"Enter"}]}:{kind:"unsupported",message:`keyboard ${t??""}`.trim()}},back:()=>({kind:"commands",commands:["back"]}),wait:function(e){let[t,n]=e.positionals;if(!t)return{kind:"unsupported",message:"wait requires a target or duration"};if(ty(t))return{kind:"commands",commands:[{waitForAnimationToEnd:{timeout:Number(t)}}],warnings:["wait <ms> exports as waitForAnimationToEnd and may return before the full duration"]};if("text"===t&&n)return{kind:"commands",commands:[{extendedWaitUntil:{visible:n,timeout:tw(e,17e3)}}]};let r=tg(t);return r?{kind:"commands",commands:[{extendedWaitUntil:{visible:r,timeout:tw(e,17e3)}}]}:{kind:"unsupported",message:"wait selector is not Maestro-compatible"}},find:function(e){let[t,n,r]=e.positionals;return"text"===t&&n&&r?"exists"===r?{kind:"commands",commands:[{assertVisible:n}]}:"missing"===r||"not-exists"===r?{kind:"commands",commands:[{assertNotVisible:n}]}:{kind:"unsupported",message:`find text assertion "${r}" is unsupported`}:{kind:"unsupported",message:"only find text <query> exists|missing exports to Maestro"}},screenshot:function(e){let[t]=e.positionals;return t?{kind:"commands",commands:[{takeScreenshot:t}]}:{kind:"unsupported",message:"screenshot requires an output path"}},scroll:function(e){let[t]=e.positionals;return t&&"down"!==t?{kind:"unsupported",message:`scroll ${t} is not exported yet`}:{kind:"commands",commands:["scroll"]}},swipe:function(e){var t,n;let r,o=function(e){let[t,n,r,o,s]=e.positionals;if(ty(t)&&ty(n)&&ty(r)&&ty(o))return{start:R(t,n),end:R(r,o),...s&&ty(s)?{duration:Number(s)}:{}}}(e);if(!o)return{kind:"unsupported",message:"only coordinate swipe exports to Maestro"};let s=(t=e,Number.isInteger(r=t.flags?.count??1)&&r>=1?r:null);if(null===s)return{kind:"unsupported",message:"swipe count must be a positive integer"};let a=(n=e,n.flags?.pauseMs!==void 0?"swipe --pause-ms has no Maestro equivalent":n.flags?.pattern&&"one-way"!==n.flags.pattern?"swipe ping-pong pattern has no Maestro equivalent":void 0);return a?{kind:"unsupported",message:a}:{kind:"commands",commands:Array.from({length:s},()=>({swipe:o}))}}};function tu(e){var t,n,r,o,s;let a,i,[l,c]=e.positionals;if(!l)return{kind:"unsupported",message:`${e.command} requires a target`};let d=tp(l,c);if(!d)return{kind:"unsupported",message:"tap target is not Maestro-compatible"};let u=(a=(n=t=e,n.flags?.jitterPx!==void 0?"tap --jitter-px has no Maestro equivalent":n.flags?.clickButton&&"primary"!==n.flags.clickButton?`tap --button ${n.flags.clickButton} has no Maestro equivalent`:void 0))?{ok:!1,message:a}:{ok:!0,options:(r=t,i={},"number"==typeof r.flags?.count&&r.flags.count>1&&(i.repeat=r.flags.count),"number"==typeof r.flags?.intervalMs&&r.flags.intervalMs>0&&(i.delay=r.flags.intervalMs),i)};return u.ok?e.flags?.doubleTap===!0?{kind:"commands",commands:[{doubleTapOn:d}],warnings:tm(e,"doubleTapOn")}:"number"==typeof e.flags?.holdMs?{kind:"commands",commands:[{longPressOn:d}],warnings:[tf(e.flags.holdMs),...tm(e,"longPressOn")]}:{kind:"commands",commands:[(o=d,0===Object.keys(s=u.options).length?{tapOn:o}:"string"==typeof o?{tapOn:{text:o,...s}}:o&&"object"==typeof o&&!Array.isArray(o)?{tapOn:{...o,...s}}:{tapOn:o})]}:{kind:"unsupported",message:u.message}}function tf(e){return`long-press duration exports as Maestro longPressOn; Maestro uses its default long-press duration instead of ${e}ms`}function tm(e,t){let n=[];return"number"==typeof e.flags?.count&&e.flags.count>1&&n.push(`tap --count ${e.flags.count} is not represented by Maestro ${t}`),"number"==typeof e.flags?.intervalMs&&e.flags.intervalMs>0&&n.push(`tap --interval-ms ${e.flags.intervalMs} is not represented by Maestro ${t}`),n}function tp(e,t){return ty(e)&&ty(t)?{point:R(e,t)}:e.startsWith("@")?null:tg(e)}function tg(e){let t;try{t=N(e)}catch{return e.includes("=")||e.includes("||")?null:e}let n=function(e){if(e.length<=1)return null;let t=e.flatMap(e=>1===e.terms.length&&tl.has(e.terms[0].key)?[e.terms[0].value]:[]);if(t.length!==e.length||0===t.length)return null;let n=t[0];return"string"!=typeof n?null:t.every(e=>e===n)?n:null}(t.selectors);return null!==n?n:1!==t.selectors.length?null:function(e){let t={};for(let o of e.terms){var n,r;if(n=t,r=o,tl.has(r.key)?"string"!=typeof r.value||!!n.id||!!n.text||!!n.label||(n[r.key]=r.value,!!0):!tc.has(r.key)||"boolean"!=typeof r.value||(n[r.key]=r.value,!!0))return null}return Object.keys(t).length>0?t:null}(t.selectors[0])}function th(e,t,n,r){for(let o of t??[])e.warnings.push({line:r,action:tv(n),message:o})}function tw(e,t){let n=e.positionals.at(-1);return n&&ty(n)?Number(n):t}function tv(e){return[e.command,...e.positionals??[]].join(" ").trim()}function tI(e){return/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(e)}function ty(e){return void 0!==e&&Number.isFinite(Number(e))}let tA=async e=>{let{positionals:t}=e;return"export"!==t[0]?function({positionals:e,flags:t}){if(e.length>1)throw new f("INVALID_ARGS","replay accepts exactly one input path: replay <path>");if(void 0!==t.replayExportFormat||void 0!==t.out)throw new f("INVALID_ARGS","replay --format/--out are only supported with replay export.");return!1}(e):await t_(e)};async function t_({positionals:e,flags:n}){let o;var s,a=e,i=n;if(a.length>2)throw new f("INVALID_ARGS","replay export accepts exactly one input path: replay export <file.ad>");if(i.replayUpdate)throw new f("INVALID_ARGS","replay export does not support --update.");if(i.replayMaestro)throw new f("INVALID_ARGS","replay export reads .ad files; omit --maestro.");if(i.replayEnv?.length)throw new f("INVALID_ARGS","replay export does not evaluate --env substitutions.");let l=i.replayExportFormat??"maestro";if("maestro"!==l)throw new f("INVALID_ARGS",`Unsupported replay export format: ${l}`);let c=e[1];if(!c)throw new f("INVALID_ARGS","replay export requires an input path.");let d=P(c),u=function(e,t={}){var n,r,o,s;let a={config:(n=t.metadata,n?.env&&Object.keys(n.env).length>0?{env:n.env}:{}),warnings:[],unsupported:[]},i=[];for(let[n,o]of e.entries()){let e=t.actionLines?.[n]??n+1,s=(r=o,td[r.command]?.(r)??{kind:"unsupported",message:`${r.command} has no Maestro equivalent`});switch(s.kind){case"commands":i.push(...s.commands),th(a,s.warnings,o,e);break;case"config":(function(e,t,n,r){if(!e.config.appId){e.config.appId=t;return}e.config.appId!==t&&e.unsupported.push({line:r,action:tv(n),message:`multiple app ids cannot be represented in one Maestro config (${e.config.appId} vs ${t})`})})(a,s.appId,o,e),i.push(...s.commands),th(a,s.warnings,o,e);break;case"unsupported":a.unsupported.push({line:e,action:tv(o),message:s.message})}}if(a.unsupported.length>0)throw new f("INVALID_ARGS",`Cannot export replay to Maestro YAML: unsupported .ad action ${a.unsupported.map(e=>`line ${e.line} (${e.action}): ${e.message}`).join("; ")}.`,{unsupported:a.unsupported});return{yaml:(o=a.config,s=i,U(Object.keys(o).length>0?[o,s]:[s])),warnings:a.warnings}}((o=b(s=t.readFileSync(d,"utf8"))).actions,{actionLines:o.actionLines,metadata:E(s)}),m="string"==typeof n.out?P(n.out):void 0;for(let e of(m&&(t.mkdirSync(r.dirname(m),{recursive:!0}),t.writeFileSync(m,u.yaml)),u.warnings))process.stderr.write(`Warning: line ${e.line}: ${e.message}
|
|
13
|
-
`);return
|
|
14
|
-
`);
|
|
15
|
-
`),process.exit(0));let
|
|
16
|
-
`),process.exit(0));let t=
|
|
17
|
-
`),process.exit(1)}
|
|
18
|
-
`),process.exit(1));let{command:
|
|
10
|
+
`)}}function ta(e,t){(e?.stderr??process.stderr).write(t)}function ti(e,t){if(!e)return!1;let n=Date.parse(e);return!Number.isFinite(n)||n<=(t?.()??Date.now())}function tl(e){return"string"==typeof e&&e.trim().length>0}async function tc(e){await new Promise(t=>setTimeout(t,e))}async function td(e){let s=await e4({stateDir:e.stateDir,flags:e.flags,env:e.env,io:{env:e.env,fetch:e.fetchImpl}}),a=await tu({cloudBaseUrl:s.cloudBaseUrl,accessToken:s.accessToken,fetchImpl:e.fetchImpl}),i=function(e){try{return r(e)}catch(n){let t=p(n);throw new h("COMMAND_FAILED","Cloud connection profile returned invalid remote config.",{generatedConfigPath:e.configPath,cause:t.message},t)}}({configPath:function(e){var r;let s=function e(t){return Array.isArray(t)?t.map(e):t&&"object"==typeof t?Object.fromEntries(Object.entries(t).filter(([,e])=>void 0!==e).sort(([e],[t])=>e.localeCompare(t)).map(([t,n])=>[t,e(n)])):t}(e.profile),a=o.join(e.stateDir,"remote-connections","generated");t.mkdirSync(a,{recursive:!0,mode:448});let i=o.join(a,`cloud-${(r=s,n.createHash("sha256").update(JSON.stringify(r)).digest("hex").slice(0,16))}.json`);t.writeFileSync(i,`${JSON.stringify(s,null,2)}
|
|
11
|
+
`,{mode:384});try{t.chmodSync(i,384)}catch{}return i}({stateDir:e.stateDir,profile:a}),cwd:e.cwd,env:e.env});return{flags:{...eK(i.profile),...e.flags,remoteConfig:i.resolvedPath,daemonAuthToken:s.accessToken},remoteConfigPath:i.resolvedPath}}async function tu(e){let t=e.fetchImpl??fetch,n=await t(new URL("/api/control-plane/connection-profile",e.cloudBaseUrl),{method:"GET",headers:{authorization:`Bearer ${e.accessToken}`},signal:AbortSignal.timeout(15e3)});var o=await e3(n,{invalidJsonMessage:`Cloud connection profile endpoint returned invalid JSON (${n.status}).`,rejectedMessage:"Cloud connection profile endpoint rejected the request."});if(!o||"object"!=typeof o||Array.isArray(o))throw new h("COMMAND_FAILED","Cloud connection profile response is invalid.");let r=o.connection;if(!r||"object"!=typeof r)throw new h("COMMAND_FAILED","Cloud connection profile response is missing profile.");if(void 0!==r.remoteConfigProfile){var s=r.remoteConfigProfile;if(!s||"object"!=typeof s||Array.isArray(s))throw new h("COMMAND_FAILED","Cloud connection profile remoteConfigProfile is invalid.");if(0===Object.keys(s).length)throw new h("COMMAND_FAILED","Cloud connection profile remoteConfigProfile is empty.");return s}throw new h("COMMAND_FAILED","Cloud connection profile did not include remoteConfigProfile.")}function tf(e,t,n){var o;if(e.json)return void T({success:!0,data:t});let r=n?.();r&&(o=r,process.stdout.write(o.endsWith("\n")?o:`${o}
|
|
12
|
+
`))}let tm=async({flags:e,client:t})=>{var o,s,a,i;let l=N(e.stateDir).baseDir,c=e.remoteConfig?function(e){if(!e.remoteConfig)throw new h("INVALID_ARGS","connect requires --remote-config <path>.");let t=r({configPath:e.remoteConfig,cwd:process.cwd(),env:process.env});return{flags:e,remoteConfigPath:t.resolvedPath}}(e):await td({flags:e,stateDir:l,cwd:process.cwd(),env:process.env}),d=c.flags,u=d.tenant,f=d.runId;if(!u)throw new h("INVALID_ARGS","connect requires tenant in remote config or via --tenant <id>.");if(!f)throw new h("INVALID_ARGS","connect requires runId in remote config or via --run-id <id>.");if(!d.daemonBaseUrl)throw new h("INVALID_ARGS","connect requires daemonBaseUrl in remote config, config, env, or --daemon-base-url.");let m=d.session?null:eO({stateDir:l}),p=d.session??m?.session??function(e){for(let t=0;t<8;t+=1){let t=`adc-${n.randomBytes(3).toString("hex")}`;if(!eE({stateDir:e,session:t}))return t}return`adc-${Date.now().toString(36)}-${n.randomBytes(2).toString("hex")}`}(l),g=ex(c.remoteConfigPath),w=eL(d),v=m?.session===p?m:eE({stateDir:l,session:p});if(v&&(o=v,s={flags:d,session:p,remoteConfigPath:c.remoteConfigPath,remoteConfigHash:g,desiredLeaseBackend:eY(d),daemon:w},o.remoteConfigPath!==s.remoteConfigPath||o.remoteConfigHash!==s.remoteConfigHash||o.session!==s.session||o.tenant!==s.flags.tenant||o.runId!==s.flags.runId||void 0!==s.desiredLeaseBackend&&o.leaseBackend!==s.desiredLeaseBackend||void 0!==s.flags.platform&&o.platform!==s.flags.platform||void 0!==s.flags.target&&o.target!==s.flags.target||(a=o.daemon,i=s.daemon,(a?.baseUrl??void 0)!==(i?.baseUrl??void 0)||(a?.transport??void 0)!==(i?.transport??void 0)||(a?.serverMode??void 0)!==(i?.serverMode??void 0)))&&!d.force)throw new h("INVALID_ARGS","A different remote connection is already active for this session. Re-run connect with --force to replace it.",{session:p,remoteConfig:v.remoteConfigPath});let y=new Date().toISOString(),I={version:1,session:p,remoteConfigPath:c.remoteConfigPath,remoteConfigHash:g,daemon:w,tenant:u,runId:f,leaseId:v&&!d.force?v.leaseId:void 0,leaseBackend:v&&!d.force?v.leaseBackend:eY(d),platform:d.platform??(v&&!d.force?v.platform:void 0),target:d.target??(v&&!d.force?v.target:void 0),runtime:v&&!d.force?v.runtime:void 0,metro:v&&!d.force?v.metro:void 0,connectedAt:v&&!d.force?v.connectedAt:y,updatedAt:y};eP({stateDir:l,state:I}),v&&d.force&&(await eJ(v.metro),await ez({stateDir:l,state:v}),await eZ(t,v));let A=tv(I),_=function(e,t){if(!t.runtime&&(eX(e)||tI(t.remoteConfigPath)))return ty(t.remoteConfigPath)}(d,I);return tf(d,tA(I,_),()=>[`Connected remote session "${p}" tenant "${u}" run "${f}" ${I.leaseId?`lease ${I.leaseId}`:"lease pending"}`,A?.message,_?.message].filter(e=>!!e).join("\n")),!0},tp=async({flags:e,client:t})=>{let{session:n,stateDir:o,state:r}=th(e);if(!r)return tw(e,n),!0;let s=r.session;try{await t.sessions.close({shutdown:e.shutdown})}catch{}await eJ(r.metro),await ez({stateDir:o,state:r});let a=!1;if(r.leaseId)try{a=(await t.leases.release({tenant:r.tenant,runId:r.runId,leaseId:r.leaseId})).released}catch{}return eT({stateDir:o,session:s}),tf(e,{connected:!1,session:s,released:a},()=>`Disconnected remote session "${s}".`),!0},tg=async({positionals:e,flags:t})=>{if("status"!==e[0])throw new h("INVALID_ARGS","connection accepts only: status");let{session:n,state:o}=th(t);if(!o)return tw(t,n),!0;let r=tv(o),s=function(e){if(!e.runtime&&tI(e.remoteConfigPath))return ty(e.remoteConfigPath)}(o);return tf(t,tA(o,s),()=>[`Connected remote session "${o.session}".`,`tenant=${o.tenant} runId=${o.runId} leaseId=${o.leaseId??"pending"} backend=${o.leaseBackend??"pending"}`,`remoteConfig=${o.remoteConfigPath}`,o.runtime?"metro=prepared":"metro=not-prepared",r?.message,s?.message].filter(e=>!!e).join("\n")),!0};function th(e){let t=e.session??"default",n=N(e.stateDir).baseDir;return{session:t,stateDir:n,state:eE({stateDir:n,session:t})??(e.session?null:eO({stateDir:n}))}}function tw(e,t){tf(e,{connected:!1,session:t},()=>`No remote connection for "${t}".`)}function tv(e){if(!e.leaseId)return{status:"deferred",nextSteps:["agent-device install-from-source <artifact-url> --platform ios|android","agent-device open <app-id> --relaunch","agent-device snapshot -i","agent-device devices"],message:"Lease allocation is pending; run install-from-source, open, snapshot, or devices when ready to allocate or refresh the lease."+(void 0===e.platform&&void 0===e.leaseBackend?" Add --platform ios|android if the profile does not set a platform.":"")}}function ty(e){let t=`agent-device metro prepare --remote-config ${e}`;return{status:"deferred",nextStep:t,message:`Metro runtime is not prepared yet; it will be prepared automatically on first open, or run "${t}" to inspect it before launch.`}}function tI(e){try{let t=r({configPath:e,cwd:process.cwd(),env:process.env}).profile;return!!(t.metroPublicBaseUrl||t.metroProxyBaseUrl||t.metroProjectRoot||t.metroKind)}catch{return!1}}function tA(e,t){let o=tv(e);return{connected:!0,session:e.session,tenant:e.tenant,runId:e.runId,leaseAllocated:!!e.leaseId,leaseId:e.leaseId,leaseBackend:e.leaseBackend,platform:e.platform,target:e.target,remoteConfig:e.remoteConfigPath,remoteConfigHash:e.remoteConfigHash,daemonBaseUrlFingerprint:function(e){if(e)return n.createHash("sha256").update(e).digest("hex").slice(0,12)}(e.daemon?.baseUrl),metro:e.metro?{prepared:!0,projectRoot:e.metro.projectRoot}:{prepared:!1},...o?{leasePreparation:o}:{},...t?{runtimePreparation:t}:{},connectedAt:e.connectedAt,updatedAt:e.updatedAt}}let t_=async({positionals:e,flags:n})=>{let o=e[0]??"status",r=N(n.stateDir).baseDir;if("status"===o){var s;let e,t=(e=e5({stateDir:(s={stateDir:r}).stateDir}))?{authenticated:!0,source:"cli-session",sessionId:e.id,cloudBaseUrl:e.cloudBaseUrl,workspaceId:e.workspaceId,accountId:e.accountId,name:e.name,createdAt:e.createdAt,expiresAt:e.expiresAt,expired:ti(e.expiresAt,s.now)}:{authenticated:!1,source:"none"};return tf(n,t,()=>{var e;return(e=t).authenticated?["Authenticated with cloud CLI session.",`cloud=${e.cloudBaseUrl}`,`session=${e.sessionId}`,e.workspaceId?`workspace=${e.workspaceId}`:null,e.accountId?`account=${e.accountId}`:null,e.expiresAt?`expiresAt=${e.expiresAt}`:null,e.expired?"status=expired":null].filter(e=>!!e).join("\n"):"Not authenticated."}),!0}if("login"===o){let e=await e9({stateDir:r,flags:n,commandLabel:"agent-device auth login"});return tf(n,{authenticated:!0,source:"cli-session",sessionId:e.session.id,cloudBaseUrl:e.session.cloudBaseUrl,workspaceId:e.session.workspaceId,accountId:e.session.accountId,expiresAt:e.session.expiresAt,agentTokenExpiresAt:e.expiresAt},()=>"Authenticated with cloud CLI session."),!0}if("logout"===o){let e,o=(e=e6({stateDir:r}.stateDir),!!t.existsSync(e)&&(t.rmSync(e,{force:!0}),!0));return tf(n,{authenticated:!1,removed:o},()=>o?"Removed stored cloud CLI session.":"No stored cloud CLI session."),!0}throw new h("INVALID_ARGS","auth accepts only: status, login, logout")},tS=new Set(["id","text","label"]),tk=new Set(["enabled","selected"]),tD={open:function(e){var t,n,o;let r,s,a,[i,l]=e.positionals;if(!i)return{kind:"unsupported",message:"open requires an app id or URL"};if(tT(i))return{kind:"commands",commands:[{openLink:i}]};let c=(t=e,n=i,(a=(o=t,r=o.flags?.launchArgs,s={},o.flags?.relaunch===!0&&(s.stopApp=!0),o.flags?.clearAppState===!0&&(s.clearState=!0),Array.isArray(r)&&r.length>0&&(s.launchArguments=r),Object.keys(s).length>0?s:void 0))?{launchApp:{appId:n,...a}}:"launchApp");return l&&tT(l)?{kind:"config",appId:i,commands:[c,{openLink:l}]}:l?{kind:"unsupported",message:"open with a non-URL second argument is unsupported"}:{kind:"config",appId:i,commands:[c]}},click:tC,press:tC,longpress:function(e){let[t,n]=e.positionals;if(!t)return{kind:"unsupported",message:"longpress requires a target"};let o=tR(t,n);return o?{kind:"commands",commands:[{longPressOn:o}],warnings:(function(e){let[t,n,o]=e.positionals,r=tx(t)&&tx(n)?o:n;return r&&tx(r)?[Number(r)]:[]})(e).map(tN)}:{kind:"unsupported",message:"longpress target is not Maestro-compatible"}},fill:function(e){let[t,n]=e.positionals;if(!t||void 0===n)return{kind:"unsupported",message:"fill requires a target and text"};let o=tR(t);return o?{kind:"commands",commands:[{tapOn:o},{inputText:n}],warnings:["fill exports as tapOn + inputText; Maestro may append text instead of replacing existing field contents"]}:{kind:"unsupported",message:"fill target is not Maestro-compatible"}},type:function(e){var t;let[n]=e.positionals;if(void 0===n)return{kind:"unsupported",message:"type requires text"};let o=0!==(t=n).length&&[...t].every(e=>"\b"===e)?t.length:null;return null!==o?{kind:"commands",commands:[{eraseText:o}]}:{kind:"commands",commands:[{inputText:n}]}},keyboard:function(e){let[t]=e.positionals;return"dismiss"===t?{kind:"commands",commands:["hideKeyboard"]}:"enter"===t||"return"===t?{kind:"commands",commands:[{pressKey:"Enter"}]}:{kind:"unsupported",message:`keyboard ${t??""}`.trim()}},back:()=>({kind:"commands",commands:["back"]}),wait:function(e){let[t,n]=e.positionals;if(!t)return{kind:"unsupported",message:"wait requires a target or duration"};if(tx(t))return{kind:"commands",commands:[{waitForAnimationToEnd:{timeout:Number(t)}}],warnings:["wait <ms> exports as waitForAnimationToEnd and may return before the full duration"]};if("text"===t&&n)return{kind:"commands",commands:[{extendedWaitUntil:{visible:n,timeout:tP(e,17e3)}}]};let o=tU(t);return o?{kind:"commands",commands:[{extendedWaitUntil:{visible:o,timeout:tP(e,17e3)}}]}:{kind:"unsupported",message:"wait selector is not Maestro-compatible"}},find:function(e){let[t,n,o]=e.positionals;return"text"===t&&n&&o?"exists"===o?{kind:"commands",commands:[{assertVisible:n}]}:"missing"===o||"not-exists"===o?{kind:"commands",commands:[{assertNotVisible:n}]}:{kind:"unsupported",message:`find text assertion "${o}" is unsupported`}:{kind:"unsupported",message:"only find text <query> exists|missing exports to Maestro"}},screenshot:function(e){let[t]=e.positionals;return t?{kind:"commands",commands:[{takeScreenshot:t}]}:{kind:"unsupported",message:"screenshot requires an output path"}},scroll:function(e){let[t]=e.positionals;return t&&"down"!==t?{kind:"unsupported",message:`scroll ${t} is not exported yet`}:{kind:"commands",commands:["scroll"]}},swipe:function(e){var t,n;let o,r=function(e){let[t,n,o,r,s]=e.positionals;if(tx(t)&&tx(n)&&tx(o)&&tx(r))return{start:O(t,n),end:O(o,r),...s&&tx(s)?{duration:Number(s)}:{}}}(e);if(!r)return{kind:"unsupported",message:"only coordinate swipe exports to Maestro"};let s=(t=e,Number.isInteger(o=t.flags?.count??1)&&o>=1?o:null);if(null===s)return{kind:"unsupported",message:"swipe count must be a positive integer"};let a=(n=e,n.flags?.pauseMs!==void 0?"swipe --pause-ms has no Maestro equivalent":n.flags?.pattern&&"one-way"!==n.flags.pattern?"swipe ping-pong pattern has no Maestro equivalent":void 0);return a?{kind:"unsupported",message:a}:{kind:"commands",commands:Array.from({length:s},()=>({swipe:r}))}}};function tC(e){var t,n,o,r,s;let a,i,[l,c]=e.positionals;if(!l)return{kind:"unsupported",message:`${e.command} requires a target`};let d=tR(l,c);if(!d)return{kind:"unsupported",message:"tap target is not Maestro-compatible"};let u=(a=(n=t=e,n.flags?.jitterPx!==void 0?"tap --jitter-px has no Maestro equivalent":n.flags?.clickButton&&"primary"!==n.flags.clickButton?`tap --button ${n.flags.clickButton} has no Maestro equivalent`:void 0))?{ok:!1,message:a}:{ok:!0,options:(o=t,i={},"number"==typeof o.flags?.count&&o.flags.count>1&&(i.repeat=o.flags.count),"number"==typeof o.flags?.intervalMs&&o.flags.intervalMs>0&&(i.delay=o.flags.intervalMs),i)};return u.ok?e.flags?.doubleTap===!0?{kind:"commands",commands:[{doubleTapOn:d}],warnings:tb(e,"doubleTapOn")}:"number"==typeof e.flags?.holdMs?{kind:"commands",commands:[{longPressOn:d}],warnings:[tN(e.flags.holdMs),...tb(e,"longPressOn")]}:{kind:"commands",commands:[(r=d,0===Object.keys(s=u.options).length?{tapOn:r}:"string"==typeof r?{tapOn:{text:r,...s}}:r&&"object"==typeof r&&!Array.isArray(r)?{tapOn:{...r,...s}}:{tapOn:r})]}:{kind:"unsupported",message:u.message}}function tN(e){return`long-press duration exports as Maestro longPressOn; Maestro uses its default long-press duration instead of ${e}ms`}function tb(e,t){let n=[];return"number"==typeof e.flags?.count&&e.flags.count>1&&n.push(`tap --count ${e.flags.count} is not represented by Maestro ${t}`),"number"==typeof e.flags?.intervalMs&&e.flags.intervalMs>0&&n.push(`tap --interval-ms ${e.flags.intervalMs} is not represented by Maestro ${t}`),n}function tR(e,t){return tx(e)&&tx(t)?{point:O(e,t)}:e.startsWith("@")?null:tU(e)}function tU(e){let t;try{t=x(e)}catch{return e.includes("=")||e.includes("||")?null:e}let n=function(e){if(e.length<=1)return null;let t=e.flatMap(e=>1===e.terms.length&&tS.has(e.terms[0].key)?[e.terms[0].value]:[]);if(t.length!==e.length||0===t.length)return null;let n=t[0];return"string"!=typeof n?null:t.every(e=>e===n)?n:null}(t.selectors);return null!==n?n:1!==t.selectors.length?null:function(e){let t={};for(let r of e.terms){var n,o;if(n=t,o=r,tS.has(o.key)?"string"!=typeof o.value||!!n.id||!!n.text||!!n.label||(n[o.key]=o.value,!!0):!tk.has(o.key)||"boolean"!=typeof o.value||(n[o.key]=o.value,!!0))return null}return Object.keys(t).length>0?t:null}(t.selectors[0])}function tE(e,t,n,o){for(let r of t??[])e.warnings.push({line:o,action:tL(n),message:r})}function tP(e,t){let n=e.positionals.at(-1);return n&&tx(n)?Number(n):t}function tL(e){return[e.command,...e.positionals??[]].join(" ").trim()}function tT(e){return/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(e)}function tx(e){return void 0!==e&&Number.isFinite(Number(e))}let tB=async e=>{let{positionals:t}=e;return"export"!==t[0]?function({positionals:e,flags:t}){if(e.length>1)throw new h("INVALID_ARGS","replay accepts exactly one input path: replay <path>");if(void 0!==t.replayExportFormat||void 0!==t.out)throw new h("INVALID_ARGS","replay --format/--out are only supported with replay export.");return!1}(e):await tM(e)};async function tM({positionals:e,flags:n}){let r;var s,a=e,i=n;if(a.length>2)throw new h("INVALID_ARGS","replay export accepts exactly one input path: replay export <file.ad>");if(i.replayUpdate)throw new h("INVALID_ARGS","replay export does not support --update.");if(i.replayMaestro)throw new h("INVALID_ARGS","replay export reads .ad files; omit --maestro.");if(i.replayEnv?.length)throw new h("INVALID_ARGS","replay export does not evaluate --env substitutions.");let l=i.replayExportFormat??"maestro";if("maestro"!==l)throw new h("INVALID_ARGS",`Unsupported replay export format: ${l}`);let c=e[1];if(!c)throw new h("INVALID_ARGS","replay export requires an input path.");let d=V(c),u=function(e,t={}){var n,o,r,s;let a={config:(n=t.metadata,n?.env&&Object.keys(n.env).length>0?{env:n.env}:{}),warnings:[],unsupported:[]},i=[];for(let[n,r]of e.entries()){let e=t.actionLines?.[n]??n+1,s=(o=r,tD[o.command]?.(o)??{kind:"unsupported",message:`${o.command} has no Maestro equivalent`});switch(s.kind){case"commands":i.push(...s.commands),tE(a,s.warnings,r,e);break;case"config":(function(e,t,n,o){if(!e.config.appId){e.config.appId=t;return}e.config.appId!==t&&e.unsupported.push({line:o,action:tL(n),message:`multiple app ids cannot be represented in one Maestro config (${e.config.appId} vs ${t})`})})(a,s.appId,r,e),i.push(...s.commands),tE(a,s.warnings,r,e);break;case"unsupported":a.unsupported.push({line:e,action:tL(r),message:s.message})}}if(a.unsupported.length>0)throw new h("INVALID_ARGS",`Cannot export replay to Maestro YAML: unsupported .ad action ${a.unsupported.map(e=>`line ${e.line} (${e.action}): ${e.message}`).join("; ")}.`,{unsupported:a.unsupported});return{yaml:(r=a.config,s=i,B(Object.keys(r).length>0?[r,s]:[s])),warnings:a.warnings}}((r=M(s=t.readFileSync(d,"utf8"))).actions,{actionLines:r.actionLines,metadata:$(s)}),f="string"==typeof n.out?V(n.out):void 0;for(let e of(f&&(t.mkdirSync(o.dirname(f),{recursive:!0}),t.writeFileSync(f,u.yaml)),u.warnings))process.stderr.write(`Warning: line ${e.line}: ${e.message}
|
|
13
|
+
`);return tf(n,{format:n.replayExportFormat??"maestro",sourcePath:d,...f?{path:f}:{yaml:u.yaml},warnings:u.warnings},()=>f??u.yaml),!0}let tO={...Q,...z,...j,...q,...ee,...K,...eo,...ea,...W,...et,...Y,...en,...es,...X};async function t$(e){return(await tV(e)).result}async function tV(e){var t,n,o;let r=(t=e.command,n=e.positionals,o=e.flags,tO[t](n,o)),s=await el(e.client,e.command,r);return{result:s,cliOutput:ei({name:e.command,input:r,result:s})}}let tG={connect:tm,disconnect:tp,connection:tg,auth:t_,replay:tB,screenshot:async({positionals:e,flags:t,client:n})=>{let o=await t$({client:n,command:"screenshot",positionals:e,flags:t});return tf(t,{path:o.path,...o.overlayRefs?{overlayRefs:o.overlayRefs}:{}},()=>o.overlayRefs?`Annotated ${o.overlayRefs.length} refs onto ${o.path}`:o.path),!0},diff:async({positionals:e,flags:t,client:n})=>{var o;if("snapshot"===e[0]){let o=await t$({client:n,command:"diff",positionals:e,flags:t});return tf(t,o,()=>E(o)),!0}if("screenshot"!==e[0])return!1;let r=t.baseline;if(!r||"string"!=typeof r)throw new h("INVALID_ARGS","diff screenshot requires --baseline <path>");let s=V(r),a="string"==typeof t.out?V(t.out):void 0,i=e[1];if(e.length>2)throw new h("INVALID_ARGS","diff screenshot accepts at most one current screenshot path");let l=eu({backend:(o=n,{platform:function(e){switch(e.platform){case"android":case"linux":case"macos":return e.platform;default:return"ios"}}(t),captureScreenshot:async(e,t,n)=>{let r=await o.capture.screenshot({path:t,session:e.session,overlayRefs:n?.overlayRefs,fullscreen:n?.fullscreen,stabilize:n?.stabilize,surface:n?.surface});return{path:r.path,...r.overlayRefs?{overlayRefs:r.overlayRefs}:{}}}}),artifacts:ec(),sessions:{get:e=>({name:e}),set:()=>{}},policy:ed()}),c=await l.capture.diffScreenshot({session:t.session,baseline:{kind:"path",path:s},current:i?{kind:"path",path:V(i)}:{kind:"live"},...a?{out:{kind:"path",path:a}}:{},threshold:function(e){if(null!=e&&""!==e)return Number(e)}(t.threshold),overlayRefs:t.overlayRefs,surface:t.surface});return tf(t,c,()=>P(c)),!0}};async function tj(e){let t={...e.flags},n=tG[e.command];return!!(n&&await n({...e,flags:t}))||!!c(e.command)&&await tK({...e,command:e.command,flags:t})}async function tK(e){let{runGenericClientBackedCommand:t}=await import("./generic.js");return await t(e)}function tF(e,t,n){return n||(e.push(t),"")}async function tH(e,t,n){let{flags:o}=t,r=function(e){var t;if(!e?.metroProxyBaseUrl||"android-instance"!==(t=e.leaseBackend)&&"ios-instance"!==t)return null;let n=[],o={serverBaseUrl:tF(n,"metroProxyBaseUrl",e.metroProxyBaseUrl),bearerToken:tF(n,"metroBearerToken",e.metroBearerToken),tenantId:tF(n,"tenant",e.tenant),runId:tF(n,"runId",e.runId),leaseId:tF(n,"leaseId",e.leaseId)};if(n.length>0)throw new h("INVALID_ARGS",`react-devtools remote bridge requires ${n.join(", ")}.`,{missing:n});return o}(o);if(!r)return n();let s=t.stateDir??process.cwd(),a=t.session??o?.session??"default",i=o?.remoteConfig??`${r.tenantId}:${r.runId}:${r.leaseId}`;if("stop"===e[0])try{return await n()}finally{await eU({projectRoot:t.cwd??process.cwd(),stateDir:s,profileKey:i,consumerKey:a})}return await eR({projectRoot:t.cwd??process.cwd(),stateDir:s,serverBaseUrl:r.serverBaseUrl,bearerToken:r.bearerToken,bridgeScope:{tenantId:r.tenantId,runId:r.runId,leaseId:r.leaseId},session:a,profileKey:i,consumerKey:a,env:t.env??process.env}),await n()}async function tq(e,t={}){let n=t.cwd??process.cwd(),o=t.env??process.env,r=await tH(e,t,async()=>(await R("npm",["exec","--yes","--package","agent-react-devtools@0.4.0","--","agent-react-devtools",...e],{cwd:n,env:o,allowFailure:!0,onStdoutChunk:e=>{process.stdout.write(e)},onStderrChunk:e=>{process.stderr.write(e)}})).exitCode);var s,a=t.flags;return 0!==r&&"wait"===(s=e)[0]&&s.includes("--connected")&&"ios-instance"===a?.leaseBackend&&process.stderr.write("Hint: Remote iOS React DevTools connects during JavaScript startup.\nIf the app was already open before `agent-device react-devtools start`, relaunch it with `agent-device open <bundle-id> --platform ios --relaunch`, then retry `agent-device react-devtools wait --connected`.\n"),r}function tW(e,t={}){let n=tJ(t),o={...e};return n.defaultPlatform&&void 0===o.platform&&(o.platform=n.defaultPlatform),o}function tJ(e){var t,n,o,r;let s,a=e.env??process.env,i=e.inheritedPlatform??e.configuredPlatform??function(e){if(void 0===e)return;let t=e.trim().toLowerCase();if(t){if("ios"===t||"android"===t||"apple"===t)return t;throw new h("INVALID_ARGS",`Invalid AGENT_DEVICE_PLATFORM: ${e}. Use ios, android, or apple.`)}}(a.AGENT_DEVICE_PLATFORM),l="string"==typeof(t=e.configuredSession??a.AGENT_DEVICE_SESSION)&&t.trim().length>0;return{defaultPlatform:i,lockPolicy:(n=e.policyOverrides,o=a,r=l,(s=n?.sessionLock??n?.sessionLockConflicts??function(e){if(void 0===e)return;let t=e.trim().toLowerCase();if(t){if("reject"===t||"strip"===t)return t;throw new h("INVALID_ARGS",`Invalid session lock mode: ${e}. Use reject or strip.`)}}(o.AGENT_DEVICE_SESSION_LOCK))||(n?.sessionLocked===!0||r?"reject":void 0))}}let tz={sendToDaemon:ep},tZ=new Set(["launchUrl","kind","metroBearerToken","metroKind","metroListenHost","metroNoInstallDeps","metroNoReuseExisting","metroPreparePort","metroProbeTimeoutMs","metroProjectRoot","metroProxyBaseUrl","metroPublicBaseUrl","metroRuntimeFile","metroStartupTimeoutMs","metroStatusHost"]),tY=new Set(["connect","connection","close","disconnect","metro","session"]);async function tX(e,n=tz){let a=_(),l=ef(),c=function(e){try{let t=eS(e);return tQ(t.command??"",t.providedFlags)}catch{return e.includes("--debug")||e.includes("-v")||e.includes("--verbose")}}(e),d=e.includes("--json"),u=function(e){for(let t=0;t<e.length;t+=1){let n=e[t];if(n.startsWith("--session=")){let e=n.slice(10).trim();return e.length>0?e:null}if("--session"===n){let n=e[t+1]?.trim();if(n&&!n.startsWith("-"))return n;break}}return null}(e)??process.env.AGENT_DEVICE_SESSION??"default";await S({session:u,requestId:a,command:e[0],debug:c},async()=>{var u,m,y,I,A,_,S,b,R,U,E,P,x,B,M,O,$;let j,K,H,q,W,J,z;try{let n,s,a,l,c,d,p,g;u={cwd:process.cwd(),env:process.env},n=eS(e),s=u?.env??process.env,a=u?.cwd??process.cwd(),I=n.command,l=null!==I&&(m={remoteConfig:n.flags.remoteConfig,cwd:a,env:s}).remoteConfig?{...eK(r({configPath:m.remoteConfig,cwd:m.cwd,env:m.env}).profile),remoteConfig:m.remoteConfig}:{},p=eh((c=(y={command:n.command,cwd:a,cliFlags:n.flags,env:s}).env??process.env,d=eh({},function(e){let n={};for(let o of e)eh(n,function(e,n){let o,r;if(!t.existsSync(e)){if(n)throw new h("INVALID_ARGS",`Config file not found: ${e}`);return{}}try{o=t.readFileSync(e,"utf8")}catch(t){throw new h("INVALID_ARGS",`Failed to read config file: ${e}`,{cause:t instanceof Error?t.message:String(t)})}try{r=JSON.parse(o)}catch(t){throw new h("INVALID_ARGS",`Invalid JSON in config file: ${e}`,{cause:t instanceof Error?t.message:String(t)})}if(!r||"object"!=typeof r||Array.isArray(r))throw new h("INVALID_ARGS",`Config file must contain a JSON object: ${e}`);return function(e,t){let n={};for(let[o,r]of Object.entries(e)){if("installSource"===o){n.installSource=F(r,t);continue}let e=eI.get(o);if(!e)throw new h("INVALID_ARGS",`Unknown config key "${o}" in ${t}.`);if(!e.config.enabled)throw new h("INVALID_ARGS",`Unsupported config key "${o}" in ${t}.`);n[o]=i(e_(e),r,t,o)}return n}(r,`config file ${e}`)}(o.path,o.required));return n}((A=y.cwd,_=y.cliFlags.config,S=c,(g=_??S.AGENT_DEVICE_CONFIG)?[{path:(b=g,R=A,U=S,V(b,{cwd:R,env:U})),required:!0}]:[{path:(E=S,o.join(G("~",{env:E}),".agent-device","config.json")),required:!1},{path:o.resolve(A,"agent-device.json"),required:!1}]))),eh(d,function(e,t){var n,o,r;let s={};for(let a of ey.filter(e=>e.config.enabled&&e.supportsCommand(t))){if("installSource"===a.key)continue;let t=a.env.names.map(t=>({name:t,value:e[t]})).find(e=>"string"==typeof e.value&&e.value.trim().length>0);t&&(s[a.key]=(n=t.value,o=`environment variable ${t.name}`,r=t.name,i(e_(a),n,o,r)))}return s}(c,y.command))),l),j={...function(e,t){let n=t?.strictFlags??!0,o=[...e.warnings],r=eh({json:!1,help:!1,version:!1},t?.defaultFlags??{});eh(r,e.flags);let s=e.providedFlags.filter(t=>!eA(t.key,e.command));if(s.length>0){var a,i;let t=s.map(e=>e.token),l=(a=e.command,i=t,a?1===i.length?`Flag ${i[0]} is not supported for command ${a}.`:`Flags ${i.join(", ")} are not supported for command ${a}.`:1===i.length?`Flag ${i[0]} requires a command that supports it.`:`Flags ${i.join(", ")} require a command that supports them.`);if(n)throw new h("INVALID_ARGS",l);for(let e of(o.push(l),s))delete r[e.key]}for(let t of Object.keys(r))void 0!==r[t]&&(eA(t,e.command)||delete r[t]);if(function(e){if("back"===e.command&&!(new Set(e.providedFlags.filter(e=>"backMode"===e.key).map(e=>e.token)).size<=1))throw new h("INVALID_ARGS","back accepts only one explicit mode flag: use either --in-app or --system.")}(e),f(e.command,r),"batch"===e.command&&1!=+!!r.steps+ +!!r.stepsFile)throw new h("INVALID_ARGS","batch requires exactly one step source: --steps or --steps-file.");return function(e){if(e.flags.help)return e;if("snapshot"===e.command&&e.flags.snapshotDiff){let{snapshotDiff:t,...n}=e.flags;return{command:"diff",positionals:["snapshot",...e.positionals],flags:n,warnings:e.warnings}}return e}({command:e.command,positionals:e.positionals,flags:r,warnings:o})}(n,{strictFlags:u?.strictFlags,defaultFlags:p}),providedFlags:n.providedFlags}}catch(t){C({level:"error",phase:"cli_parse_failed",data:{error:t instanceof Error?t.message:String(t)}});let e=g(t,{diagnosticId:k().diagnosticId,logPath:D({force:!0})??void 0});d?T({success:!1,error:e}):L(e,{showDetails:c}),process.exit(1);return}for(let e of j.warnings)process.stderr.write(`Warning: ${e}
|
|
14
|
+
`);j.flags.version&&(process.stdout.write(`${l}
|
|
15
|
+
`),process.exit(0));let Z="help"===j.command,Y=j.flags.help;if(Z||Y){Z&&j.positionals.length>1&&(L(new h("INVALID_ARGS","help accepts at most one command.")),process.exit(1));let e=Z?j.positionals[0]:j.command;e||(process.stdout.write(`${v()}
|
|
16
|
+
`),process.exit(0));let t=w(eN(e));t&&(process.stdout.write(t),process.exit(0)),L(new h("INVALID_ARGS",`Unknown command: ${e}`)),process.stdout.write(`${v()}
|
|
17
|
+
`),process.exit(1)}j.command||(process.stdout.write(`${v()}
|
|
18
|
+
`),process.exit(1));let{command:X,positionals:Q}=j,ee=tQ(X,j.providedFlags),et=new Set(j.providedFlags.map(e=>e.key));try{H=(K=tJ({policyOverrides:j.flags,configuredPlatform:j.flags.platform,configuredSession:j.flags.session})).lockPolicy?{...j.flags}:tW(j.flags,{policyOverrides:j.flags,configuredPlatform:j.flags.platform,configuredSession:j.flags.session}),q=N(H.stateDir),W=H.session??"default",P={command:X,explicitFlagKeys:et,stateDir:q.baseDir,session:W,remoteConfig:H.remoteConfig,hasResolvedSession:void 0!==H.session},z=(J="connect"===P.command||"connection"===P.command?null:function(e){let t=e.validateRemoteConfigHash??!0,n=e.remoteConfig?s({configPath:e.remoteConfig,cwd:e.cwd,env:e.env}):void 0,o=eE(e)??(e.allowActiveFallback?eO({stateDir:e.stateDir}):null);if(!o||n&&o.remoteConfigPath!==n)return null;if(t&&ex(o.remoteConfigPath)!==o.remoteConfigHash)throw new h("INVALID_ARGS","Active remote connection config changed. Run agent-device connect --force to refresh it.",{remoteConfig:o.remoteConfigPath});let a=function(e,t){try{return r({configPath:e.remoteConfigPath,cwd:t.cwd,env:t.env}).profile}catch(e){if(!1===t.validateRemoteConfigHash)return{};throw e}}(o,e);return{runtime:o.runtime,flags:{...a,remoteConfig:o.remoteConfigPath,daemonBaseUrl:o.daemon?.baseUrl??a.daemonBaseUrl,daemonTransport:o.daemon?.transport??a.daemonTransport,daemonServerMode:o.daemon?.serverMode??a.daemonServerMode,tenant:o.tenant,sessionIsolation:"tenant",runId:o.runId,leaseId:o.leaseId,leaseBackend:o.leaseBackend,session:o.session,platform:o.platform??a.platform,target:o.target??a.target}}}({stateDir:P.stateDir,session:P.session,remoteConfig:P.remoteConfig,cwd:process.cwd(),env:process.env,allowActiveFallback:!P.explicitFlagKeys.has("session")&&(!P.remoteConfig||"disconnect"===P.command||!P.hasResolvedSession),validateRemoteConfigHash:"disconnect"!==P.command}))?function(e,t,n){let o={...e};for(let[e,r]of Object.entries(t))void 0!==r&&(n.has(e)||(o[e]=r));return o}(H,J.flags,et):H}catch(t){let e=g(p(t),{diagnosticId:k().diagnosticId,logPath:D({force:!0})??void 0});j.flags.json?T({success:!1,error:e}):L(e,{showDetails:ee}),process.exit(1);return}let en=null;try{let e;if("react-devtools"===X){let e=await tq(Q,{flags:z,stateDir:q.baseDir,session:z.session??W,cwd:process.cwd(),env:process.env});process.exit(e);return}eg({command:X,currentVersion:l,stateDir:q.baseDir,flags:z});let o=J?.runtime,r=(e,t)=>({session:e.session,requestId:a,stateDir:e.stateDir,daemonBaseUrl:e.daemonBaseUrl,daemonAuthToken:e.daemonAuthToken,daemonTransport:e.daemonTransport,daemonServerMode:e.daemonServerMode,tenant:e.tenant,sessionIsolation:e.sessionIsolation,runId:e.runId,leaseId:e.leaseId,leaseBackend:e.leaseBackend,runtime:t,lockPolicy:K.lockPolicy,lockPlatform:K.defaultPlatform,cwd:process.cwd(),debug:ee});if("batch"===X){if(Q.length>0)throw new h("INVALID_ARGS","batch does not accept positional arguments.");e=function(e){let n,o,r,s="";if(e.steps)s=e.steps;else if(e.stepsFile)try{s=t.readFileSync(e.stepsFile,"utf8")}catch(n){let t=n instanceof Error?n.message:String(n);throw new h("INVALID_ARGS",`Failed to read --steps-file ${e.stepsFile}: ${t}`)}var a,i=s;try{r=JSON.parse(i)}catch{throw new h("INVALID_ARGS","Batch steps must be valid JSON.")}if(!Array.isArray(r)||0===r.length)throw new h("INVALID_ARGS","Batch steps must be a non-empty JSON array.");return a=r,n=!1,o=a.map((e,t)=>{var o,r,s,a,i,l;let c;if(o=e,null!==o&&"object"==typeof o&&!Array.isArray(o)&&"input"in o&&!("positionals"in o)&&!("flags"in o))return e;let d=function(e,t){if(!e||"object"!=typeof e||Array.isArray(e))throw new h("INVALID_ARGS",`Invalid batch step ${t}.`);var n=e,o=t;let r=Object.keys(n).filter(e=>!["command","positionals","flags","runtime"].includes(e));if(r.length>0)throw new h("INVALID_ARGS",`Batch step ${o} has unknown legacy field(s): ${r.join(", ")}.`);let s=function(e,t){let n="string"==typeof e?e.trim().toLowerCase():"";if(!n)throw new h("INVALID_ARGS",`Batch step ${t} requires command.`);if(er(n))return n;throw new h("INVALID_ARGS",`Batch step ${t} command is not available through command batch: ${String(e)}`)}(e.command,t),a=function(e,t){if(void 0!==e){if(!Array.isArray(e)||e.some(e=>"string"!=typeof e))throw new h("INVALID_ARGS",`Batch step ${t} positionals must contain only strings.`);return e}}(e.positionals,t),i=function(e,t){if(void 0!==e){if(!e||"object"!=typeof e||Array.isArray(e))throw new h("INVALID_ARGS",`Batch step ${t} flags must be an object.`);return e}}(e.flags,t);return{command:s,...void 0===a?{}:{positionals:a},...void 0===i?{}:{flags:i},...void 0===e.runtime?{}:{runtime:e.runtime}}}(e,t+1);return n=!0,c=(s=(r=d).command,a=r.positionals??[],l=r.flags,i={json:!1,help:!1,version:!1,...l},tO[s](a,i)),{command:r.command,input:c,...void 0===r.runtime?{}:{runtime:r.runtime}}}),n&&process.stderr.write('Warning: batch steps using positionals/flags are deprecated and will be removed in the next major version. Use {"command":"...","input":{...}} steps instead.\n'),o}(H)}if(x=X,"auth"!==x&&"connection"!==x&&(z=(await e8({command:X,flags:z,stateDir:q.baseDir,env:process.env})).flags),z.remoteConfig&&(B=X,!tY.has(B))){let t=em(r(z,o),{transport:n.sendToDaemon}),s=await eq({command:X,flags:z,client:t,runtime:o,batchSteps:e,forceRuntimePrepare:function(e){for(let t of tZ)if(e.has(t))return!0;return!1}(et)});z=s.flags,o=s.runtime}M={command:X,flags:z,runtime:o,explicitFlagKeys:et,hadConnectionDefaults:!!J},!("open"===M.command&&!M.runtime&&!M.flags.bundleUrl&&!M.flags.metroHost&&!M.flags.metroPort&&!M.flags.remoteConfig&&!M.hadConnectionDefaults&&((O=M.explicitFlagKeys).has("daemonBaseUrl")||O.has("daemonTransport")||O.has("tenant")||O.has("sessionIsolation")||O.has("runId")||O.has("leaseId")||O.has("leaseBackend")))||process.stderr.write("Warning: open is using explicit remote daemon or tenant flags without saved Metro runtime hints. React Native apps may launch without bundle/runtime hints; prefer connect --remote-config <path> first or pass --remote-config <path> on this command.\n");let s=z.daemonBaseUrl;en=!ee||z.json||s?null:function(e){try{let n=t.existsSync(e)?t.statSync(e).size:0,o=!1,r=setInterval(()=>{if(!o&&t.existsSync(e))try{let o=t.statSync(e);if(o.size<n&&(n=0),o.size<=n)return;let r=t.openSync(e,"r");try{let e=Buffer.alloc(o.size-n);t.readSync(r,e,0,e.length,n),n=o.size,e.length>0&&process.stdout.write(e.toString("utf8"))}finally{t.closeSync(r)}}catch{}},200);return()=>{o=!0,clearInterval(r)}}catch{return null}}(q.logPath);let i=em(r(z,o),{transport:function(e){let{command:t,flags:n,transport:o}=e;return"test"!==t||n.json?o:async e=>await o({...e,meta:{...e.meta,requestProgress:"replay-test"}})}({command:X,flags:z,transport:n.sendToDaemon})});if("batch"===X){if(!e)throw new h("INVALID_ARGS","batch requires --steps or --steps-file.");let t=e.map((e,t)=>({...e,input:K.lockPolicy&&void 0===H.platform?{...e.input}:tW(e.input,{policyOverrides:z,configuredPlatform:z.platform,configuredSession:z.session,inheritedPlatform:z.platform})}));if(await tj({command:X,positionals:Q,flags:{...z,batchSteps:t},client:i,debug:ee}))return}else if("runtime"===X)throw new h("INVALID_ARGS","runtime command was removed. Use connect --remote-config <path> for remote runs, or metro prepare --remote-config <path> for inspection.");else if(await tj({command:X,positionals:Q,flags:z,client:i,debug:ee}))return;throw new h("INVALID_ARGS",`Unknown command: ${X}`)}catch(o){let e=p(o),n=g(e,{diagnosticId:k().diagnosticId,logPath:D({force:!0})??void 0});if("close"===X&&"COMMAND_FAILED"===($=e).code&&($.details?.kind==="daemon_startup_failed"||$.message.toLowerCase().includes("failed to start daemon")&&("string"==typeof $.details?.infoPath||"string"==typeof $.details?.lockPath))){z.json&&T({success:!0,data:{closed:"session",source:"no-daemon"}});return}if(z.json)T({success:!1,error:n});else if(L(n,{showDetails:ee}),ee)try{let e=q.logPath;if(t.existsSync(e)){let n=t.readFileSync(e,"utf8").split("\n"),o=n.slice(Math.max(0,n.length-200)).join("\n");o.trim().length>0&&process.stderr.write(`
|
|
19
19
|
[daemon log]
|
|
20
|
-
${
|
|
21
|
-
`)}}catch{}
|
|
20
|
+
${o}
|
|
21
|
+
`)}}catch{}en&&en(),process.exit(1)}finally{en&&en()}})}function tQ(e,t){return t.some(t=>"verbose"===t.key&&("--debug"===t.token||"-v"===t.token||"test"!==e))}e(process.argv[1]??"").href===import.meta.url&&tX(process.argv.slice(2)).catch(e=>{L(g(p(e)),{showDetails:!0}),process.exit(1)});export{tX as runCli,tV as runCliCommandWithOutput,tf as writeCommandOutput};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{interactionCommandDefinitions as _,batchCommandDefinition as n}from"./
|
|
1
|
+
import{interactionCommandDefinitions as _,batchCommandDefinition as n}from"./9873.js";import{clientCommandDefinitions as r}from"./2948.js";let a=new Map([..._,...r,n].map(_=>[_.name,_]));async function m(_,n,r){var m;return await (m=n,a.get(m)).invoke(_,r)}export{m as runCommand};
|
package/dist/src/contracts.d.ts
CHANGED
|
@@ -2,11 +2,11 @@ export declare type AppErrorCode = KnownAppErrorCode | (string & {});
|
|
|
2
2
|
|
|
3
3
|
export declare function centerOfRect(rect: Rect): Point;
|
|
4
4
|
|
|
5
|
-
export declare const DAEMON_LOCK_POLICIES: readonly [
|
|
5
|
+
export declare const DAEMON_LOCK_POLICIES: readonly ['reject', 'strip'];
|
|
6
6
|
|
|
7
|
-
export declare const DAEMON_SERVER_MODES: readonly [
|
|
7
|
+
export declare const DAEMON_SERVER_MODES: readonly ['socket', 'http', 'dual'];
|
|
8
8
|
|
|
9
|
-
export declare const DAEMON_TRANSPORT_PREFERENCES: readonly [
|
|
9
|
+
export declare const DAEMON_TRANSPORT_PREFERENCES: readonly ['auto', 'socket', 'http'];
|
|
10
10
|
|
|
11
11
|
export declare type DaemonArtifact = {
|
|
12
12
|
field: string;
|
|
@@ -166,7 +166,7 @@ export declare const jsonRpcRequestSchema: RuntimeSchema<JsonRpcRequestEnvelope<
|
|
|
166
166
|
|
|
167
167
|
declare type KnownAppErrorCode = 'INVALID_ARGS' | 'DEVICE_NOT_FOUND' | 'DEVICE_IN_USE' | 'TOOL_MISSING' | 'APP_NOT_INSTALLED' | 'UNSUPPORTED_PLATFORM' | 'UNSUPPORTED_OPERATION' | 'NOT_IMPLEMENTED' | 'COMMAND_FAILED' | 'SESSION_NOT_FOUND' | 'UNAUTHORIZED' | 'AMBIGUOUS_MATCH' | 'UNKNOWN';
|
|
168
168
|
|
|
169
|
-
export declare const LEASE_BACKENDS: readonly [
|
|
169
|
+
export declare const LEASE_BACKENDS: readonly ['ios-simulator', 'ios-instance', 'android-instance'];
|
|
170
170
|
|
|
171
171
|
export declare type LeaseAllocatePayload = {
|
|
172
172
|
token?: string;
|
|
@@ -205,7 +205,7 @@ export declare type LeaseReleasePayload = {
|
|
|
205
205
|
|
|
206
206
|
export declare const leaseReleaseSchema: RuntimeSchema<LeaseReleasePayload>;
|
|
207
207
|
|
|
208
|
-
export declare const NETWORK_INCLUDE_MODES: readonly [
|
|
208
|
+
export declare const NETWORK_INCLUDE_MODES: readonly ['summary', 'headers', 'body', 'all'];
|
|
209
209
|
|
|
210
210
|
export declare type NetworkIncludeMode = (typeof NETWORK_INCLUDE_MODES)[number];
|
|
211
211
|
|
|
@@ -270,7 +270,7 @@ declare type RuntimeSchema<T> = {
|
|
|
270
270
|
parse(input: unknown): T;
|
|
271
271
|
};
|
|
272
272
|
|
|
273
|
-
export declare const SESSION_ISOLATION_MODES: readonly [
|
|
273
|
+
export declare const SESSION_ISOLATION_MODES: readonly ['none', 'tenant'];
|
|
274
274
|
|
|
275
275
|
export declare type SessionIsolationMode = (typeof SESSION_ISOLATION_MODES)[number];
|
|
276
276
|
|
package/dist/src/contracts.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{DAEMON_LOCK_POLICIES,DAEMON_SERVER_MODES,DAEMON_TRANSPORT_PREFERENCES,LEASE_BACKENDS,NETWORK_INCLUDE_MODES,SESSION_ISOLATION_MODES,centerOfRect,daemonCommandRequestSchema,daemonRuntimeSchema,jsonRpcRequestSchema,leaseAllocateSchema,leaseHeartbeatSchema,leaseReleaseSchema}from"./
|
|
1
|
+
export{DAEMON_LOCK_POLICIES,DAEMON_SERVER_MODES,DAEMON_TRANSPORT_PREFERENCES,LEASE_BACKENDS,NETWORK_INCLUDE_MODES,SESSION_ISOLATION_MODES,centerOfRect,daemonCommandRequestSchema,daemonRuntimeSchema,jsonRpcRequestSchema,leaseAllocateSchema,leaseHeartbeatSchema,leaseReleaseSchema}from"./4291.js";export{defaultHintForCode,normalizeError}from"./733.js";
|