@@ -5,26 +5,47 @@ import type { ResolveTargetDeviceOptions } from '../core/dispatch-resolve.ts';
55import type { MaestroProgram } from '../compat/maestro/program-ir.ts' ;
66import { appleSimulatorAppTargetForOpenTarget } from './open-device-selection.ts' ;
77import { SessionStore } from './session-store.ts' ;
8+ import type { CommandFlags } from '../core/dispatch.ts' ;
89import type { DaemonRequest , SessionAction } from './types.ts' ;
910
11+ export type ReplayTargetDeviceResolution = {
12+ flags : CommandFlags ;
13+ options : ResolveTargetDeviceOptions | undefined ;
14+ } ;
15+
1016/**
1117 * Finds the first static app target a fresh replay will open. Request binding
1218 * uses this before any replay action can cache an unqualified device choice.
1319 */
14- export function buildReplayTargetDeviceResolutionOptions (
20+ export function buildReplayTargetDeviceResolution (
1521 req : DaemonRequest ,
16- ) : ResolveTargetDeviceOptions | undefined {
22+ ) : ReplayTargetDeviceResolution | undefined {
1723 if ( req . command !== 'replay' || req . flags ?. replayFrom !== undefined ) return undefined ;
1824 const filePath = req . positionals ?. [ 0 ] ;
1925 if ( ! filePath ) return undefined ;
2026
2127 try {
2228 const resolved = SessionStore . expandHome ( filePath , req . meta ?. cwd ) ;
2329 const source = fs . readFileSync ( resolved , 'utf8' ) ;
24- const appTarget = isMaestroReplay ( req , resolved )
25- ? readMaestroReplayAppTarget ( parseMaestroProgram ( source , { sourcePath : resolved } ) )
26- : readScriptReplayAppTarget ( parseReplayInput ( source , req . flags ) . actions ) ;
27- return appTargetResolutionOptions ( appTarget ) ;
30+ if ( isMaestroReplay ( req , resolved ) ) {
31+ return {
32+ flags : req . flags ?? { } ,
33+ options : buildMaestroReplayTargetDeviceResolutionOptions (
34+ parseMaestroProgram ( source , { sourcePath : resolved } ) ,
35+ req . flags ?. platform ,
36+ ) ,
37+ } ;
38+ }
39+ const parsed = parseReplayInput ( source , req . flags ) ;
40+ const selection = readScriptReplaySelection ( parsed . actions ) ;
41+ if ( ! selection . appTarget ) return undefined ;
42+ const scriptFlags = buildReplayScriptPlatformFlags ( req . flags , parsed . actions ) ;
43+ const platform = scriptFlags . platform ?? parsed . metadata . platform ;
44+ return {
45+ flags :
46+ platform && scriptFlags . platform === undefined ? { ...scriptFlags , platform } : scriptFlags ,
47+ options : platform === 'ios' ? appTargetResolutionOptions ( selection . appTarget ) : undefined ,
48+ } ;
2849 } catch {
2950 // Parsing and validation stay in the replay handler. Lock binding is only
3051 // advisory, so an unreadable/invalid plan must not mask its real error.
@@ -34,7 +55,9 @@ export function buildReplayTargetDeviceResolutionOptions(
3455
3556export function buildMaestroReplayTargetDeviceResolutionOptions (
3657 program : MaestroProgram ,
58+ platform : CommandFlags [ 'platform' ] | undefined ,
3759) : ResolveTargetDeviceOptions {
60+ if ( platform !== 'ios' ) return { } ;
3861 const appTarget = readMaestroReplayAppTarget ( program ) ;
3962 return appTargetResolutionOptions ( appTarget ) ?? { } ;
4063}
@@ -46,9 +69,34 @@ function isMaestroReplay(req: DaemonRequest, filePath: string): boolean {
4669 ) ;
4770}
4871
49- function readScriptReplayAppTarget ( actions : SessionAction [ ] ) : string | undefined {
50- const target = actions . find ( ( action ) => action . command === 'open' ) ?. positionals ?. [ 0 ] ;
51- return isStaticAppTarget ( target ) ? target : undefined ;
72+ function readScriptReplaySelection ( actions : SessionAction [ ] ) : {
73+ appTarget : string | undefined ;
74+ platform : CommandFlags [ 'platform' ] | undefined ;
75+ } {
76+ let platform : CommandFlags [ 'platform' ] | undefined ;
77+ for ( const action of actions ) {
78+ if ( action . command === 'runtime' && action . flags . platform ) {
79+ platform = action . flags . platform ;
80+ continue ;
81+ }
82+ if ( action . command !== 'open' ) continue ;
83+ platform = action . runtime ?. platform ?? platform ;
84+ const target = action . positionals ?. [ 0 ] ;
85+ if ( isStaticAppTarget ( target ) ) return { appTarget : target , platform } ;
86+ }
87+ return { appTarget : undefined , platform } ;
88+ }
89+
90+ /** Applies a platform configured before the first static app open to replay dispatch. */
91+ export function buildReplayScriptPlatformFlags (
92+ flags : CommandFlags | undefined ,
93+ actions : SessionAction [ ] ,
94+ ) : CommandFlags {
95+ const selection = readScriptReplaySelection ( actions ) ;
96+ if ( flags ?. platform !== undefined || ! selection . appTarget || ! selection . platform ) {
97+ return flags ?? { } ;
98+ }
99+ return { ...flags , platform : selection . platform } ;
52100}
53101
54102function readMaestroReplayAppTarget ( program : MaestroProgram ) : string | undefined {
0 commit comments