{"version":3,"file":"platform.mjs","sources":["../../src/platform.ts"],"sourcesContent":["import type { Agent } from '@midscene/core/agent';\nimport type {\n  MidsceneRecorderEvent,\n  MidsceneRecorderEventType,\n  MidsceneRecorderSourceKind,\n} from '@midscene/shared/recorder';\nimport type { LaunchPlaygroundOptions } from './launcher';\nimport type { AgentFactory } from './types';\n\nexport type PlaygroundPreviewKind =\n  | 'none'\n  | 'screenshot'\n  | 'mjpeg'\n  | 'scrcpy'\n  | 'custom';\n\nexport interface PlaygroundPreviewCapability {\n  kind: PlaygroundPreviewKind;\n  label?: string;\n  live?: boolean;\n}\n\nexport interface PlaygroundPreviewDescriptor {\n  kind: PlaygroundPreviewKind;\n  title?: string;\n  capabilities?: PlaygroundPreviewCapability[];\n  screenshotPath?: string;\n  mjpegPath?: string;\n  custom?: Record<string, unknown>;\n}\n\nexport interface PlaygroundSessionTarget {\n  id: string;\n  label: string;\n  description?: string;\n  status?: string;\n  isDefault?: boolean;\n  metadata?: Record<string, unknown>;\n}\n\nexport interface PlaygroundSessionFieldOption {\n  label: string;\n  value: string | number | boolean;\n  description?: string;\n}\n\nexport interface PlaygroundPlatformRegistration {\n  id: string;\n  label: string;\n  description?: string;\n  unavailableReason?: string;\n  supportsStandalone?: boolean;\n  metadata?: Record<string, unknown>;\n}\n\nexport interface PlaygroundPlatformSelectorConfig {\n  fieldKey: string;\n  variant?: 'cards' | 'select';\n}\n\nexport interface PlaygroundSessionField {\n  key: string;\n  label: string;\n  type: 'text' | 'number' | 'select';\n  required?: boolean;\n  defaultValue?: string | number | boolean;\n  options?: PlaygroundSessionFieldOption[];\n  placeholder?: string;\n  description?: string;\n}\n\nexport interface PlaygroundSessionNotice {\n  type: 'info' | 'warning' | 'error';\n  message: string;\n  description?: string;\n}\n\nexport interface PlaygroundSessionSetup {\n  title?: string;\n  description?: string;\n  primaryActionLabel?: string;\n  autoSubmitWhenReady?: boolean;\n  fields: PlaygroundSessionField[];\n  targets?: PlaygroundSessionTarget[];\n  platformRegistry?: PlaygroundPlatformRegistration[];\n  platformSelector?: PlaygroundPlatformSelectorConfig;\n  notice?: PlaygroundSessionNotice;\n}\n\nexport interface PlaygroundExecutionHooks {\n  beforeExecute?: () => void | Promise<void>;\n  afterExecute?: () => void | Promise<void>;\n}\n\nexport interface PlaygroundSidecar {\n  id: string;\n  start(): void | Promise<void>;\n  stop?(): void | Promise<void>;\n}\n\nexport type PlaygroundRecorderSourceKind = MidsceneRecorderSourceKind;\n\nexport type PlaygroundRecorderEventType = MidsceneRecorderEventType;\n\nexport type PlaygroundRecorderEvent = MidsceneRecorderEvent;\n\nexport interface PlaygroundRecorderCapabilitiesResult {\n  supported: boolean;\n  source: PlaygroundRecorderSourceKind;\n  platformId?: string;\n  error?: string;\n}\n\nexport interface PlaygroundRecorderStartResult {\n  ok: boolean;\n  supported?: boolean;\n  source?: PlaygroundRecorderSourceKind;\n  platformId?: string;\n  error?: string;\n}\n\nexport interface PlaygroundRecorderEventsResult {\n  events: PlaygroundRecorderEvent[];\n  nextIndex: number;\n}\n\nexport interface PlaygroundRecorderDescribeTrace {\n  traceId: string;\n  eventHashId?: string;\n  eventType?: string;\n  actionType?: string;\n  eventSummary?: {\n    hashId?: string;\n    mergedHashIds?: string[];\n    type?: string;\n    source?: string;\n    actionType?: string;\n    timestamp?: number;\n    url?: string;\n    title?: string;\n    valueLength?: number;\n    rawPayloadSummary?: Record<string, unknown>;\n    elementRect?: {\n      left?: number;\n      top?: number;\n      width?: number;\n      height?: number;\n      x?: number;\n      y?: number;\n    };\n    pageInfo?: { width: number; height: number };\n  };\n  status: 'ready' | 'failed' | 'skipped';\n  error?: string;\n  startedAt: string;\n  durationMs: number;\n  modelCallDurationMs?: number;\n  point?: [number, number];\n  pageInfo?: { width: number; height: number };\n  screenshotBytes?: number;\n  screenshotRef?: {\n    path: string;\n    sha256: string;\n    bytes: number;\n    mimeType?: string;\n  };\n  annotatedScreenshotRef?: {\n    path: string;\n    sha256: string;\n    bytes: number;\n    mimeType?: string;\n  };\n  screenshotAnnotation?: {\n    inputPoint?: {\n      logical: [number, number];\n      screenshot: [number, number];\n    };\n    sourceTargetRect?: {\n      left: number;\n      top: number;\n      width: number;\n      height: number;\n    };\n    locateRect?: {\n      left: number;\n      top: number;\n      width: number;\n      height: number;\n    };\n    centerDelta?: {\n      x: number;\n      y: number;\n      distance: number;\n    };\n    distanceOutsideRect?: {\n      x: number;\n      y: number;\n      distance: number;\n    };\n  };\n  screenshotPersistError?: string;\n  annotatedScreenshotPersistError?: string;\n  elementDescription?: string;\n  verifyPrompt?: boolean;\n  verifyPassed?: boolean;\n  centerDistance?: number;\n  verifyResult?: {\n    pass?: boolean;\n    rect?: {\n      left: number;\n      top: number;\n      width: number;\n      height: number;\n    };\n    center?: [number, number];\n    centerDistance?: number;\n    includedInRect?: boolean;\n  };\n}\n\nexport interface PlaygroundRecorderDescribeResult {\n  ok: boolean;\n  event?: PlaygroundRecorderEvent;\n  trace?: PlaygroundRecorderDescribeTrace;\n  error?: string;\n}\n\nexport interface PlaygroundSessionState {\n  connected: boolean;\n  displayName?: string;\n  metadata?: Record<string, unknown>;\n  setupState?: 'required' | 'ready' | 'blocked';\n  setupBlockingReason?: string;\n}\n\nexport interface PlaygroundSessionNavigationEvent {\n  url: string;\n  timestamp?: number;\n}\n\nexport type PlaygroundSessionNavigationSubscriber = (\n  listener: (event: PlaygroundSessionNavigationEvent) => void,\n) => () => void;\n\nexport interface PlaygroundCreatedSession {\n  agent?: Agent;\n  agentFactory?: AgentFactory;\n  preview?: PlaygroundPreviewDescriptor;\n  metadata?: Record<string, unknown>;\n  displayName?: string;\n  platformId?: string;\n  title?: string;\n  platformDescription?: string;\n  executionHooks?: PlaygroundExecutionHooks;\n  sidecars?: PlaygroundSidecar[];\n  subscribeNavigationEvents?: PlaygroundSessionNavigationSubscriber;\n}\n\nexport interface PlaygroundSessionManager {\n  getSetupSchema?(\n    input?: Record<string, unknown>,\n  ): Promise<PlaygroundSessionSetup>;\n  listTargets?(): Promise<PlaygroundSessionTarget[]>;\n  createSession(\n    input?: Record<string, unknown>,\n  ): Promise<PlaygroundCreatedSession>;\n  destroySession?(session?: PlaygroundSessionState): Promise<void>;\n}\n\nexport interface PreparedPlaygroundPlatform {\n  platformId: string;\n  title: string;\n  description?: string;\n  agent?: Agent;\n  agentFactory?: AgentFactory;\n  sessionManager?: PlaygroundSessionManager;\n  executionHooks?: PlaygroundExecutionHooks;\n  launchOptions?: LaunchPlaygroundOptions;\n  preview?: PlaygroundPreviewDescriptor;\n  metadata?: Record<string, unknown>;\n  sidecars?: PlaygroundSidecar[];\n}\n\nexport interface PlaygroundPlatformDescriptor<TOptions = void> {\n  id: string;\n  title: string;\n  description?: string;\n  prepare(options: TOptions): Promise<PreparedPlaygroundPlatform>;\n}\n\nexport function definePlaygroundPlatform<TOptions>(\n  descriptor: PlaygroundPlatformDescriptor<TOptions>,\n): PlaygroundPlatformDescriptor<TOptions> {\n  return descriptor;\n}\n\nexport function createScreenshotPreviewDescriptor(\n  overrides: Partial<PlaygroundPreviewDescriptor> = {},\n): PlaygroundPreviewDescriptor {\n  return {\n    kind: 'screenshot',\n    screenshotPath: '/screenshot',\n    capabilities: [\n      {\n        kind: 'screenshot',\n        label: 'Screenshot polling',\n        live: false,\n      },\n    ],\n    ...overrides,\n  };\n}\n\nexport function createMjpegPreviewDescriptor(\n  overrides: Partial<PlaygroundPreviewDescriptor> = {},\n): PlaygroundPreviewDescriptor {\n  return {\n    kind: 'mjpeg',\n    screenshotPath: '/screenshot',\n    mjpegPath: '/mjpeg',\n    capabilities: [\n      {\n        kind: 'mjpeg',\n        label: 'MJPEG streaming',\n        live: true,\n      },\n      {\n        kind: 'screenshot',\n        label: 'Screenshot fallback',\n        live: false,\n      },\n    ],\n    ...overrides,\n  };\n}\n\nexport function createScrcpyPreviewDescriptor(\n  custom: Record<string, unknown> = {},\n  overrides: Partial<PlaygroundPreviewDescriptor> = {},\n): PlaygroundPreviewDescriptor {\n  return {\n    kind: 'scrcpy',\n    screenshotPath: '/screenshot',\n    capabilities: [\n      {\n        kind: 'scrcpy',\n        label: 'scrcpy streaming',\n        live: true,\n      },\n      {\n        kind: 'screenshot',\n        label: 'Screenshot fallback',\n        live: false,\n      },\n    ],\n    custom,\n    ...overrides,\n  };\n}\n\nexport function resolvePreparedLaunchOptions(\n  prepared: PreparedPlaygroundPlatform,\n  overrides: LaunchPlaygroundOptions = {},\n): LaunchPlaygroundOptions {\n  return {\n    ...(prepared.launchOptions || {}),\n    ...overrides,\n  };\n}\n"],"names":["definePlaygroundPlatform","descriptor","createScreenshotPreviewDescriptor","overrides","createMjpegPreviewDescriptor","createScrcpyPreviewDescriptor","custom","resolvePreparedLaunchOptions","prepared"],"mappings":"AAkSO,SAASA,yBACdC,UAAkD;IAElD,OAAOA;AACT;AAEO,SAASC,kCACdC,YAAkD,CAAC,CAAC;IAEpD,OAAO;QACL,MAAM;QACN,gBAAgB;QAChB,cAAc;YACZ;gBACE,MAAM;gBACN,OAAO;gBACP,MAAM;YACR;SACD;QACD,GAAGA,SAAS;IACd;AACF;AAEO,SAASC,6BACdD,YAAkD,CAAC,CAAC;IAEpD,OAAO;QACL,MAAM;QACN,gBAAgB;QAChB,WAAW;QACX,cAAc;YACZ;gBACE,MAAM;gBACN,OAAO;gBACP,MAAM;YACR;YACA;gBACE,MAAM;gBACN,OAAO;gBACP,MAAM;YACR;SACD;QACD,GAAGA,SAAS;IACd;AACF;AAEO,SAASE,8BACdC,SAAkC,CAAC,CAAC,EACpCH,YAAkD,CAAC,CAAC;IAEpD,OAAO;QACL,MAAM;QACN,gBAAgB;QAChB,cAAc;YACZ;gBACE,MAAM;gBACN,OAAO;gBACP,MAAM;YACR;YACA;gBACE,MAAM;gBACN,OAAO;gBACP,MAAM;YACR;SACD;QACDG;QACA,GAAGH,SAAS;IACd;AACF;AAEO,SAASI,6BACdC,QAAoC,EACpCL,YAAqC,CAAC,CAAC;IAEvC,OAAO;QACL,GAAIK,SAAS,aAAa,IAAI,CAAC,CAAC;QAChC,GAAGL,SAAS;IACd;AACF"}