@unotest/mobile 0.1.0 → 0.8.0
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/.claude/skills/write-e2e-test.md +373 -261
- package/CHANGELOG.md +468 -0
- package/README.md +11 -4
- package/bin/mcp.js +66 -8
- package/dist/mcp/server.js +2262 -408
- package/dist/runner/cli.js +1237 -181
- package/dist/runner/doctor.js +11 -12
- package/dist/runner/init.js +114 -59
- package/dist/runner/install.js +1967 -0
- package/package.json +10 -3
- package/dist/mcp/server.js.map +0 -1
- package/dist/runner/cli.js.map +0 -1
- package/dist/runner/doctor.js.map +0 -1
- package/dist/runner/init.js.map +0 -1
package/dist/mcp/server.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/fixtures/db/pg-client.ts","../../src/fixtures/db/mysql-client.ts","../../src/fixtures/db/sqlite-client.ts","../../src/mcp/server.ts","../../src/config/env.ts","../../src/driver/wda/appium-wda-binary-provider.ts","../../src/driver/ios-utils.ts","../../src/driver/simctl/adapter.ts","../../src/driver/wda/session.ts","../../src/driver/wda/http-client.ts","../../src/driver/wda/probe.ts","../../src/driver/wda/runner.ts","../../src/driver/wda/tree-parser.ts","../../src/driver/wda/index.ts","../../src/driver/factory.ts","../../src/inspection/action-differ.ts","../../src/inspection/failure-explainer.ts","../../src/inspection/screenshot-annotator.ts","../../src/inspection/selector-resolver.ts","../../src/inspection/tree-inspector.ts","../../vendor/dsl/parser/lib/array-value.ts","../../vendor/dsl/parser/lib/number-value.ts","../../vendor/dsl/parser/lib/functions.ts","../../vendor/dsl/parser/lib/object-value.ts","../../vendor/dsl/parser/lib/string-value.ts","../../vendor/dsl/parser/lib/user-define-function.ts","../../vendor/dsl/parser/lib/variables.ts","../../vendor/dsl/parser/ast/array-access-expression.ts","../../vendor/dsl/parser/ast/array-assignment-statement.ts","../../vendor/dsl/parser/ast/array-expression.ts","../../vendor/dsl/parser/ast/assignment-statement.ts","../../vendor/dsl/parser/ast/binary-expression.ts","../../vendor/dsl/parser/ast/block-statement.ts","../../vendor/dsl/parser/ast/break-statement.ts","../../vendor/dsl/parser/ast/conditional-expression.ts","../../vendor/dsl/parser/ast/continue-statement.ts","../../vendor/dsl/parser/ast/do-while-statement.ts","../../vendor/dsl/parser/ast/for-statement.ts","../../vendor/dsl/parser/ast/function-define-statement.ts","../../vendor/dsl/parser/ast/function-statement.ts","../../vendor/dsl/parser/ast/functional-expression.ts","../../vendor/dsl/parser/ast/if-statement.ts","../../vendor/dsl/parser/ast/increment-expression.ts","../../vendor/dsl/parser/ast/increment-statement.ts","../../vendor/dsl/parser/ast/meta-block-statement.ts","../../vendor/dsl/parser/ast/object-expression.ts","../../vendor/dsl/parser/ast/print-statement.ts","../../vendor/dsl/parser/ast/return-statement.ts","../../vendor/dsl/parser/ast/unary-expression.ts","../../vendor/dsl/parser/token-type.ts","../../vendor/dsl/parser/ast/value-expression.ts","../../vendor/dsl/parser/lib/undefined-value.ts","../../vendor/dsl/parser/ast/var-statement.ts","../../vendor/dsl/parser/ast/variable-expression.ts","../../vendor/dsl/parser/ast/while-statement.ts","../../src/dsl/return-signal.ts","../../src/dsl/user-function-resolver.ts","../../src/dsl/ast-executor.ts","../../src/dsl/linter.ts","../../src/dsl/function-registry.ts","../../src/dsl/functions/asserts.ts","../../src/dsl/functions/data.ts","../../src/dsl/functions/device.ts","../../src/dsl/functions/selectors.ts","../../src/dsl/functions/time.ts","../../src/dsl/functions/ui.ts","../../src/dsl/functions/index.ts","../../src/dsl/test-runtime-manager.ts","../../src/runner/fs-scenario-repository.ts","../../vendor/dsl/parser/token.ts","../../vendor/dsl/parser/tools.ts","../../vendor/dsl/parser/lexer.ts","../../vendor/dsl/parser/parser.ts","../../src/runner/scenario-loader.ts","../../src/runner/helper-repository.ts","../../src/mcp/session-recorder.ts","../../src/fixtures/db.ts","../../src/fixtures/api.ts","../../src/fixtures/shell.ts","../../src/composition-root.ts","../../src/util/log.ts","../../src/mcp/tools/legacy.tool.ts","../../src/mcp/tools/base.tool.ts","../../src/mcp/tools/selector-param.ts","../../src/mcp/tools/resolve-selector.tool.ts","../../src/mcp/tools/debugger.tool.ts","../../src/dsl/variable-scope.ts","../../src/dsl/runtime.ts","../../src/mcp/tools/index.ts"],"sourcesContent":["// Postgres driver. Lazy-imports the `pg` peer-dep at create() time so users\n// without Postgres don't pay the dep cost.\n\nimport type { Pool } from \"pg\";\n\nimport type { DbClient, DbExecResult } from \"./types.ts\";\n\nexport async function create(databaseUrl: string): Promise<DbClient> {\n const pgMod = await import(\"pg\").catch(() => {\n throw new Error(\n `'pg' driver requested by DATABASE_URL but the 'pg' package is not installed. ` +\n `Run: pnpm add -D pg @types/pg`,\n );\n });\n const PoolCtor = (pgMod.default?.Pool ?? (pgMod as unknown as { Pool: typeof Pool }).Pool) as typeof Pool;\n const pool: Pool = new PoolCtor({ connectionString: databaseUrl });\n\n let closed = false;\n\n return {\n async query<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<T[]> {\n const result = await pool.query<T extends Record<string, unknown> ? T : Record<string, unknown>>(\n sql,\n params as unknown[],\n );\n return (result.rows ?? []) as T[];\n },\n\n async exec(sql: string, params?: unknown[]): Promise<DbExecResult> {\n const result = await pool.query(sql, params as unknown[]);\n return {\n rowCount: result.rowCount ?? 0,\n rows: (result.rows ?? []) as unknown[],\n };\n },\n\n async close(): Promise<void> {\n if (closed) return;\n closed = true;\n await pool.end();\n },\n };\n}\n","// MySQL driver. Lazy-imports `mysql2/promise` at create() time.\n//\n// mysql2 result shape differs for reads vs writes:\n// SELECT → [rowsArray, fieldsMeta]\n// INSERT/UPDATE/DELETE → [ResultSetHeader, fieldsMeta]\n//\n// We normalize via heuristic: leading SQL keyword. The keyword check is the\n// ONLY place we parse SQL in our codebase, and it's strictly local to this\n// driver impl.\n\nimport type { Pool, ResultSetHeader, RowDataPacket } from \"mysql2/promise\";\n\nimport type { DbClient, DbExecResult } from \"./types.ts\";\n\n// mysql2 typing constrains values to a primitive subset. Our DSL params are\n// already string|number|boolean|null (validated by toSqlParam in data.ts),\n// so a single cast at the driver boundary is safe — no SQL interpolation.\ntype MysqlValue = string | number | boolean | null | Buffer | Date;\n\nfunction isWriteSql(sql: string): boolean {\n const m = sql.trimStart().match(/^([a-z]+)/i);\n if (!m) return false;\n const verb = m[1]!.toUpperCase();\n return (\n verb === \"INSERT\" ||\n verb === \"UPDATE\" ||\n verb === \"DELETE\" ||\n verb === \"REPLACE\" ||\n verb === \"CREATE\" ||\n verb === \"DROP\" ||\n verb === \"ALTER\" ||\n verb === \"TRUNCATE\"\n );\n}\n\nexport async function create(databaseUrl: string): Promise<DbClient> {\n const mod = await import(\"mysql2/promise\").catch(() => {\n throw new Error(\n `'mysql' driver requested by DATABASE_URL but the 'mysql2' package is not installed. ` +\n `Run: pnpm add -D mysql2`,\n );\n });\n const pool: Pool = mod.createPool(databaseUrl);\n\n let closed = false;\n\n return {\n async query<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<T[]> {\n const [rows] = await pool.execute<RowDataPacket[]>(sql, (params ?? []) as MysqlValue[]);\n return rows as unknown as T[];\n },\n\n async exec(sql: string, params?: unknown[]): Promise<DbExecResult> {\n if (isWriteSql(sql)) {\n const [header] = await pool.execute<ResultSetHeader>(sql, (params ?? []) as MysqlValue[]);\n return { rowCount: header.affectedRows, rows: [] };\n }\n const [rows] = await pool.execute<RowDataPacket[]>(sql, (params ?? []) as MysqlValue[]);\n return { rowCount: rows.length, rows: rows as unknown as unknown[] };\n },\n\n async close(): Promise<void> {\n if (closed) return;\n closed = true;\n await pool.end();\n },\n };\n}\n","// SQLite driver via better-sqlite3 (sync underlying API, wrapped in\n// Promise.resolve to match the async DbClient contract).\n//\n// better-sqlite3 chooses between Statement.all() (returns rows) and\n// Statement.run() (returns { changes, lastInsertRowid }) — we pick based on\n// SQL leading verb + presence of RETURNING. This is the ONLY place we parse\n// SQL in our codebase; localized to driver impl.\n//\n// URL forms:\n// sqlite:./relative.db\n// sqlite:///absolute/path.db\n// sqlite::memory:\n\nimport type { Database as DatabaseType, Statement } from \"better-sqlite3\";\n\nimport type { DbClient, DbExecResult } from \"./types.ts\";\n\nfunction parseSqlitePath(databaseUrl: string): string {\n // `sqlite::memory:` → \":memory:\"\n if (databaseUrl === \"sqlite::memory:\" || databaseUrl === \"sqlite://memory\") return \":memory:\";\n\n // `sqlite:///abs/path` → /abs/path\n if (databaseUrl.startsWith(\"sqlite:///\")) return \"/\" + databaseUrl.slice(\"sqlite:///\".length);\n\n // `sqlite://relative/...` or `sqlite:./rel` or `sqlite:rel` — strip scheme.\n if (databaseUrl.startsWith(\"sqlite://\")) return databaseUrl.slice(\"sqlite://\".length);\n if (databaseUrl.startsWith(\"sqlite:\")) return databaseUrl.slice(\"sqlite:\".length);\n\n // `file:` fallback\n if (databaseUrl.startsWith(\"file://\")) return databaseUrl.slice(\"file://\".length);\n if (databaseUrl.startsWith(\"file:\")) return databaseUrl.slice(\"file:\".length);\n\n return databaseUrl;\n}\n\nexport async function create(databaseUrl: string): Promise<DbClient> {\n const mod = await import(\"better-sqlite3\").catch(() => {\n throw new Error(\n `'sqlite' driver requested by DATABASE_URL but the 'better-sqlite3' package is not installed. ` +\n `Run: pnpm add -D better-sqlite3 @types/better-sqlite3`,\n );\n });\n const Database = (mod.default ?? mod) as unknown as new (path: string) => DatabaseType;\n const path = parseSqlitePath(databaseUrl);\n const db = new Database(path);\n\n let closed = false;\n\n function prep(sql: string): Statement {\n return db.prepare(sql);\n }\n\n return {\n async query<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<T[]> {\n const stmt = prep(sql);\n const rows = stmt.all(...((params ?? []) as unknown[])) as T[];\n return rows;\n },\n\n async exec(sql: string, params?: unknown[]): Promise<DbExecResult> {\n const stmt = prep(sql);\n // better-sqlite3 exposes `statement.reader` — true iff the statement\n // produces rows (SELECT / RETURNING / pragma queries). Use that for\n // dispatch rather than parsing SQL.\n const isReader = (stmt as unknown as { reader?: boolean }).reader === true;\n if (isReader) {\n const rows = stmt.all(...((params ?? []) as unknown[])) as unknown[];\n return { rowCount: rows.length, rows };\n }\n const info = stmt.run(...((params ?? []) as unknown[]));\n return { rowCount: Number(info.changes ?? 0), rows: [] };\n },\n\n async close(): Promise<void> {\n if (closed) return;\n closed = true;\n db.close();\n },\n };\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\n\nimport { buildApp } from \"../composition-root.ts\";\nimport type { Logger } from \"../util/log.ts\";\nimport { createLogger } from \"../util/log.ts\";\nimport { registerAllTools } from \"./tools/index.ts\";\n\nexport async function startMcpServer(): Promise<void> {\n // Stdio MCP transport — never write logs to stdout (it's the protocol channel).\n const stderrLogger: Logger = {\n info: (m, ...r) => console.error(\"[mcp]\", m, ...r),\n warn: (m, ...r) => console.error(\"[mcp] warn\", m, ...r),\n error: (m, ...r) => console.error(\"[mcp] error\", m, ...r),\n debug: (m, ...r) => {\n if (process.env.E2E_DEBUG) console.error(\"[mcp] debug\", m, ...r);\n },\n step: (m, ...r) => console.error(\"[mcp] →\", m, ...r),\n child: (sub: string) => createLogger(`mcp/${sub}`),\n };\n\n const services = await buildApp({ logger: stderrLogger });\n\n // Graceful shutdown — drain DB pool / file handles before process exit.\n // Errors during close() are logged but never block exit.\n const shutdown = async (signal: string): Promise<void> => {\n services.logger.info(`[mcp] received ${signal}, closing services...`);\n try {\n await services.close();\n } catch (e) {\n services.logger.error(`[mcp] close() failed: ${(e as Error).message}`);\n }\n process.exit(0);\n };\n process.once(\"SIGINT\", () => { void shutdown(\"SIGINT\"); });\n process.once(\"SIGTERM\", () => { void shutdown(\"SIGTERM\"); });\n\n const server = new McpServer({\n name: \"unotest-mobile\",\n version: \"0.0.0\",\n });\n\n registerAllTools(server, services);\n\n const transport = new StdioServerTransport();\n transport.onclose = () => { void shutdown(\"transport.onclose\"); };\n await server.connect(transport);\n services.logger.info(\n `unotest-mobile MCP server up on stdio (session log: ${services.sessionRecorder.getPath()})`,\n );\n}\n\nif (import.meta.url === `file://${process.argv[1]}`) {\n startMcpServer().catch((e) => {\n console.error(\"[mcp] fatal:\", e);\n process.exit(1);\n });\n}\n","import { config as loadDotenv } from \"dotenv\";\nimport { z } from \"zod\";\n\nexport const ENV_FILE_PATH = \"unotest/.env\";\n\nlet loaded = false;\nfunction ensureLoaded(): void {\n if (loaded) return;\n loadDotenv({ path: ENV_FILE_PATH });\n loaded = true;\n}\n\nconst EnvSchema = z.object({\n APP_BUNDLE_ID: z.string().min(1),\n APP_URL_SCHEME: z.string().min(1),\n INVITE_DEEPLINK_PREFIX: z.string().min(1),\n API_BASE_URL: z.string().url(),\n // PROJECT_ROOT — optional default cwd for the `shell(...)` DSL primitive.\n // When unset, shell commands run from process.cwd(). Set to the absolute\n // path of the project-under-test when its CLI must be invoked from a\n // specific directory (e.g. monorepo root for `pnpm --filter ...`).\n PROJECT_ROOT: z.string().optional(),\n // DATABASE_URL — connection string for native pg/mysql/sqlite client\n // (Stage 0 plugin DbClient). Format examples:\n // postgresql://user:pass@host:5432/dbname\n // mysql://user:pass@host:3306/dbname\n // sqlite:./e2e.db\n // sqlite::memory:\n DATABASE_URL: z.string().min(1),\n SIM_A_NAME: z.string().min(1),\n SIM_B_NAME: z.string().min(1),\n SIM_POOL: z.string().default(\"A,B\"),\n METRO_URL: z.string().url(),\n // Expo dev-client builds show a \"Development Servers\" launcher after a clean\n // launch (clearState wipes the remembered Metro URL). When true, the driver\n // auto-opens `exp+<APP_URL_SCHEME>://expo-development-client/?url=<METRO_URL>`\n // after `app_launch clean: true` to bypass the launcher.\n EXPO_DEV_CLIENT: z\n .string()\n .optional()\n .transform((v) => v === \"true\" || v === \"1\"),\n SESSION_LOG_PATH: z.string().default(\"sessions/current.jsonl\"),\n ARTIFACTS_DIR: z.string().default(\"artifacts\"),\n // WDA per-slot port mapping (D-13 parallel multi-device). Stored as a\n // comma-separated `slot=port` list, e.g. \"A=8100,B=8101\". Each slot present\n // in SIM_POOL needs a port.\n WDA_PORTS: z.string().default(\"A=8100,B=8101\"),\n // Implicit auto-wait on selector-bearing actions (D-18).\n WDA_DEFAULT_ACTION_WAIT_MS: z\n .string()\n .default(\"2000\")\n .transform((v) => Number.parseInt(v, 10)),\n WDA_DEFAULT_WAITFOR_TIMEOUT_MS: z\n .string()\n .default(\"10000\")\n .transform((v) => Number.parseInt(v, 10)),\n // TTL for paused-failed runtimes before auto-abort (D-17). Default 30 min.\n PAUSED_RUNTIME_TTL_MS: z\n .string()\n .default(\"1800000\")\n .transform((v) => Number.parseInt(v, 10)),\n});\n\nexport type EnvConfig = z.infer<typeof EnvSchema> & {\n simPool: string[];\n simBySlot: Record<string, string>;\n wdaPortBySlot: Record<string, number>;\n defaultActionWaitMs: number;\n defaultWaitForTimeoutMs: number;\n pausedRuntimeTtlMs: number;\n};\n\nlet cached: EnvConfig | null = null;\n\nexport function loadEnv(): EnvConfig {\n if (cached) return cached;\n ensureLoaded();\n const parsed = EnvSchema.safeParse(process.env);\n if (!parsed.success) {\n const issues = parsed.error.issues.map((i) => ` - ${i.path.join(\".\")}: ${i.message}`).join(\"\\n\");\n throw new Error(\n `Invalid environment. Copy unotest/.env.example to unotest/.env and fill required values.\\n${issues}`,\n );\n }\n const raw = parsed.data;\n const simPool = raw.SIM_POOL.split(\",\").map((s) => s.trim()).filter(Boolean);\n const simBySlot: Record<string, string> = {};\n for (const slot of simPool) {\n const key = `SIM_${slot}_NAME` as const;\n const value = (process.env as Record<string, string | undefined>)[key];\n if (!value) {\n throw new Error(\n `SIM_POOL lists slot \"${slot}\" but ${key} is not set in unotest/.env`,\n );\n }\n simBySlot[slot] = value;\n }\n const wdaPortBySlot: Record<string, number> = {};\n for (const entry of raw.WDA_PORTS.split(\",\").map((s) => s.trim()).filter(Boolean)) {\n const [slot, portStr] = entry.split(\"=\").map((s) => s.trim());\n if (!slot || !portStr) {\n throw new Error(`Invalid WDA_PORTS entry \"${entry}\". Expected \"slot=port\"`);\n }\n const port = Number.parseInt(portStr, 10);\n if (!Number.isFinite(port) || port <= 0) {\n throw new Error(`Invalid WDA_PORTS port \"${portStr}\" for slot \"${slot}\"`);\n }\n wdaPortBySlot[slot] = port;\n }\n for (const slot of simPool) {\n if (wdaPortBySlot[slot] == null) {\n throw new Error(\n `SIM_POOL includes slot \"${slot}\" but WDA_PORTS has no entry for it. ` +\n `Add \"${slot}=<port>\" to WDA_PORTS in unotest/.env.`,\n );\n }\n }\n\n cached = {\n ...raw,\n simPool,\n simBySlot,\n wdaPortBySlot,\n defaultActionWaitMs: raw.WDA_DEFAULT_ACTION_WAIT_MS,\n defaultWaitForTimeoutMs: raw.WDA_DEFAULT_WAITFOR_TIMEOUT_MS,\n pausedRuntimeTtlMs: raw.PAUSED_RUNTIME_TTL_MS,\n };\n return cached;\n}\n","// On-demand `xcodebuild build-for-testing` of WDA from the\n// `appium-webdriveragent` npm package, with on-disk cache keyed by the package\n// version (D-3, D-11).\n//\n// Why this lives behind BinaryProvider: the rest of the code must not know\n// about Xcode, Apple developer tooling, or cache layout. Phase-N replacements\n// (prebuilt download / corporate-distributed bundle) drop in by implementing\n// the same interface.\n\nimport { execFile } from \"node:child_process\";\nimport { existsSync, mkdirSync, readFileSync, readdirSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { promisify } from \"node:util\";\n\nimport type { Logger } from \"../../util/log.ts\";\nimport type { BinaryProvider, WdaArtifacts } from \"./binary-provider.ts\";\n\nconst exec = promisify(execFile);\n\nexport interface AppiumWdaBinaryProviderDeps {\n logger: Logger;\n cacheDir?: string; // default ~/.cache/unotest/mobile/wda\n // Overrideable for tests (avoid touching real filesystem / xcodebuild).\n resolveSourceDir?: () => string;\n resolveSourceVersion?: () => string;\n runXcodebuild?: (args: string[], cwd: string) => Promise<void>;\n}\n\nexport class AppiumWdaBinaryProvider implements BinaryProvider {\n private readonly logger: Logger;\n private readonly cacheRoot: string;\n private cached: WdaArtifacts | null = null;\n private readonly resolveSourceDir: () => string;\n private readonly resolveSourceVersion: () => string;\n private readonly runXcodebuild: (args: string[], cwd: string) => Promise<void>;\n\n constructor(deps: AppiumWdaBinaryProviderDeps) {\n this.logger = deps.logger;\n this.cacheRoot = deps.cacheDir ?? join(homedir(), \".cache\", \"unotest\", \"mobile\", \"wda\");\n this.resolveSourceDir = deps.resolveSourceDir ?? defaultResolveSourceDir;\n this.resolveSourceVersion = deps.resolveSourceVersion ?? (() => readSourceVersion(this.resolveSourceDir()));\n this.runXcodebuild = deps.runXcodebuild ?? defaultRunXcodebuild;\n }\n\n async getWdaAppPath(): Promise<string> {\n return (await this.getArtifacts()).appPath;\n }\n\n async getArtifacts(): Promise<WdaArtifacts> {\n if (this.cached && existsSync(this.cached.appPath) && existsSync(this.cached.xctestrunPath)) {\n return this.cached;\n }\n\n const sourceDir = this.resolveSourceDir();\n const version = this.resolveSourceVersion();\n const versionedCache = join(this.cacheRoot, version);\n const productsDir = join(versionedCache, \"Build\", \"Products\");\n const builtAppPath = join(productsDir, \"Debug-iphonesimulator\", \"WebDriverAgentRunner-Runner.app\");\n\n if (existsSync(builtAppPath)) {\n const xctestrun = locateXctestrun(productsDir);\n if (xctestrun) {\n this.logger.debug(`wda cache hit: ${builtAppPath}`);\n this.cached = { appPath: builtAppPath, derivedDataPath: versionedCache, xctestrunPath: xctestrun };\n return this.cached;\n }\n }\n\n this.logger.info(`Building WDA (version ${version}) — first time, expect 5-15 min…`);\n mkdirSync(versionedCache, { recursive: true });\n const projectPath = join(sourceDir, \"WebDriverAgent.xcodeproj\");\n if (!existsSync(projectPath)) {\n throw new Error(\n `appium-webdriveragent: WebDriverAgent.xcodeproj not found at ${projectPath}. ` +\n `Reinstall: pnpm add appium-webdriveragent`,\n );\n }\n\n await this.runXcodebuild(\n [\n \"build-for-testing\",\n \"-project\",\n projectPath,\n \"-scheme\",\n \"WebDriverAgentRunner\",\n \"-destination\",\n \"generic/platform=iOS Simulator\",\n \"-derivedDataPath\",\n versionedCache,\n \"CODE_SIGNING_ALLOWED=NO\",\n ],\n sourceDir,\n );\n\n if (!existsSync(builtAppPath)) {\n throw new Error(\n `xcodebuild succeeded but expected output not found: ${builtAppPath}\\n` +\n `Inspect ${productsDir}/ for what was produced.`,\n );\n }\n\n const xctestrun = locateXctestrun(productsDir);\n if (!xctestrun) {\n throw new Error(\n `xcodebuild succeeded but no .xctestrun file found in ${productsDir}. ` +\n `Cache may be corrupt — try \\`rm -rf ${versionedCache}\\` and re-run.`,\n );\n }\n\n this.cached = { appPath: builtAppPath, derivedDataPath: versionedCache, xctestrunPath: xctestrun };\n return this.cached;\n }\n}\n\n// ---- defaults ------------------------------------------------------------\n\nfunction locateXctestrun(productsDir: string): string | null {\n if (!existsSync(productsDir)) return null;\n // xcodebuild emits one .xctestrun file per build; name varies by SDK/arch\n // (e.g. `WebDriverAgentRunner_iphonesimulator17.5-arm64.xctestrun`).\n const entries = readdirSync(productsDir).filter((f) => f.endsWith(\".xctestrun\"));\n if (entries.length === 0) return null;\n // Multiple shouldn't happen for our single-scheme build; if it does, pick\n // the lexically-last (newest SDK).\n entries.sort();\n return join(productsDir, entries[entries.length - 1]!);\n}\n\nfunction defaultResolveSourceDir(): string {\n // Resolve via Node's module system rather than `../../../node_modules` path\n // math: under bundle (`dist/runner/cli.js`) the relative depth differs from\n // source (`src/driver/wda/`), and a hardcoded ladder silently lands in the\n // wrong directory. createRequire walks up from the caller's actual location\n // and finds the package wherever the package manager put it (own\n // node_modules, hoisted, linked, etc.).\n const require = createRequire(import.meta.url);\n return dirname(require.resolve(\"appium-webdriveragent/package.json\"));\n}\n\nfunction readSourceVersion(sourceDir: string): string {\n const pkg = JSON.parse(readFileSync(join(sourceDir, \"package.json\"), \"utf8\")) as { version?: string };\n if (!pkg.version) throw new Error(`appium-webdriveragent package.json has no version`);\n return pkg.version;\n}\n\nasync function defaultRunXcodebuild(args: string[], cwd: string): Promise<void> {\n // Wide timeout — clean xcodebuild on a cold M-series box clocks ~3-7min, on\n // intel up to 15. We surface the timeout as a clear error rather than hang\n // indefinitely.\n const FIFTEEN_MIN = 15 * 60 * 1000;\n try {\n await exec(\"xcodebuild\", args, { cwd, maxBuffer: 32 * 1024 * 1024, timeout: FIFTEEN_MIN });\n } catch (e: unknown) {\n const err = e as { stdout?: string; stderr?: string; message?: string };\n const detail = [err.stderr, err.stdout, err.message].filter(Boolean).join(\"\\n\").slice(-2000);\n throw new Error(`xcodebuild failed:\\n${detail}`);\n }\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst exec = promisify(execFile);\n\nexport interface SimInfo {\n name: string;\n udid: string;\n state: \"Booted\" | \"Shutdown\" | string;\n runtime: string;\n}\n\ninterface SimctlListJson {\n devices: Record<string, Array<{ name: string; udid: string; state: string; isAvailable?: boolean }>>;\n}\n\nexport async function listSimulators(): Promise<SimInfo[]> {\n const { stdout } = await exec(\"xcrun\", [\"simctl\", \"list\", \"-j\", \"devices\"]);\n const parsed = JSON.parse(stdout) as SimctlListJson;\n const out: SimInfo[] = [];\n for (const [runtime, list] of Object.entries(parsed.devices)) {\n for (const d of list) {\n if (d.isAvailable === false) continue;\n out.push({ name: d.name, udid: d.udid, state: d.state, runtime });\n }\n }\n return out;\n}\n\nexport async function resolveSimByName(name: string): Promise<SimInfo> {\n const all = await listSimulators();\n const matches = all.filter((s) => s.name === name);\n if (matches.length === 0) {\n const available = all.map((s) => s.name).join(\", \") || \"(none)\";\n throw new Error(`Sim \"${name}\" not found. Available: ${available}`);\n }\n const booted = matches.find((s) => s.state === \"Booted\");\n return booted ?? matches[0]!;\n}\n\nexport async function bootSim(udid: string): Promise<void> {\n try {\n await exec(\"xcrun\", [\"simctl\", \"boot\", udid]);\n } catch (e: unknown) {\n const msg = (e as { stderr?: string }).stderr ?? String(e);\n if (msg.includes(\"Booted\") || msg.includes(\"current state: Booted\")) return;\n throw e;\n }\n}\n\nexport async function shutdownSim(udid: string): Promise<void> {\n try {\n await exec(\"xcrun\", [\"simctl\", \"shutdown\", udid]);\n } catch {\n /* ignore — already off */\n }\n}\n\nexport async function openUrl(udid: string, url: string): Promise<void> {\n await exec(\"xcrun\", [\"simctl\", \"openurl\", udid, url]);\n}\n\nexport async function screenshotPng(udid: string): Promise<Buffer> {\n // Pipe to stdout, capture buffer.\n const { stdout } = await exec(\"xcrun\", [\"simctl\", \"io\", udid, \"screenshot\", \"--type=png\", \"-\"], {\n encoding: \"buffer\",\n maxBuffer: 32 * 1024 * 1024,\n });\n return stdout as unknown as Buffer;\n}\n\nexport async function terminateApp(udid: string, bundleId: string): Promise<void> {\n try {\n await exec(\"xcrun\", [\"simctl\", \"terminate\", udid, bundleId]);\n } catch {\n /* not running */\n }\n}\n\nexport async function launchApp(\n udid: string,\n bundleId: string,\n args: string[] = [],\n): Promise<void> {\n await exec(\"xcrun\", [\"simctl\", \"launch\", udid, bundleId, ...args]);\n}\n\nexport async function uninstallApp(udid: string, bundleId: string): Promise<void> {\n try {\n await exec(\"xcrun\", [\"simctl\", \"uninstall\", udid, bundleId]);\n } catch {\n /* not installed */\n }\n}\n\nexport async function installApp(udid: string, appPath: string): Promise<void> {\n await exec(\"xcrun\", [\"simctl\", \"install\", udid, appPath]);\n}\n\n/**\n * Forces an English-only software keyboard on the sim. Maestro's `inputText`\n * sends Unicode chars to whichever keyboard is currently focused; on a sim\n * configured with Russian (or any non-English) layout, ASCII chars like `-`\n * and digits can be dropped or remapped, producing truncated/mangled input\n * (observed: \"e2e-pass-1234\" → \"•••••••\", 7 chars instead of 13). Applied\n * once per sim per harness process.\n */\nexport async function ensureEnglishKeyboard(udid: string): Promise<void> {\n await exec(\"xcrun\", [\n \"simctl\",\n \"spawn\",\n udid,\n \"defaults\",\n \"write\",\n \"-g\",\n \"AppleKeyboards\",\n \"-array\",\n \"en_US@sw=QWERTY;hw=Automatic\",\n ]);\n await exec(\"xcrun\", [\"simctl\", \"spawn\", udid, \"defaults\", \"write\", \"-g\", \"AppleLanguages\", \"-array\", \"en\"]);\n await exec(\"xcrun\", [\"simctl\", \"spawn\", udid, \"defaults\", \"write\", \"-g\", \"AppleLocale\", \"en_US\"]);\n}\n\n","// SimctlAdapter — DI-wrapped surface over `xcrun simctl`.\n//\n// The legacy `src/driver/ios-utils.ts` is a flat namespace of free functions.\n// This adapter wraps them so consumers depend on a class they can mock,\n// matching the rest of the architecture (composition root, AppServices, slices).\n//\n// ios-utils.ts itself stays — MaestroDriver still calls it directly until\n// Phase 3 retires Maestro. Both pathways coexist.\n\nimport {\n bootSim,\n installApp,\n launchApp,\n openUrl,\n resolveSimByName,\n screenshotPng,\n shutdownSim,\n terminateApp,\n uninstallApp,\n type SimInfo,\n} from \"../ios-utils.ts\";\n\nexport class SimctlAdapter {\n async resolveByName(name: string): Promise<SimInfo> {\n return resolveSimByName(name);\n }\n\n async boot(udid: string): Promise<void> {\n return bootSim(udid);\n }\n\n async shutdown(udid: string): Promise<void> {\n return shutdownSim(udid);\n }\n\n async install(udid: string, appPath: string): Promise<void> {\n return installApp(udid, appPath);\n }\n\n async uninstall(udid: string, bundleId: string): Promise<void> {\n return uninstallApp(udid, bundleId);\n }\n\n async launch(udid: string, bundleId: string, args?: string[]): Promise<void> {\n return launchApp(udid, bundleId, args);\n }\n\n async terminate(udid: string, bundleId: string): Promise<void> {\n return terminateApp(udid, bundleId);\n }\n\n async openUrl(udid: string, url: string): Promise<void> {\n return openUrl(udid, url);\n }\n\n async screenshot(udid: string): Promise<Buffer> {\n return screenshotPng(udid);\n }\n}\n","// One WDA session per device slot (D-13 parallel multi-device).\n//\n// Lifecycle:\n// 1. Caller picks slot → boots sim via SimctlAdapter.\n// 2. WdaSession installs (idempotent) and launches the WDA runner app on\n// that sim — WDA listens on a slot-specific port from `EnvConfig.wdaPortBySlot`.\n// 3. POST /session → captures sessionId, ready for commands.\n// 4. On teardown: DELETE /session/{id}. Sim left running (D-17 paused-failure\n// preservation; explicit caller decides when to shutdown).\n//\n// **Port locking is per-slot, not global**: coach and athlete each get their\n// own WDA process and own session. This is what makes the multi-device\n// scenario parallel.\n\nimport { setTimeout as delay } from \"node:timers/promises\";\n\nimport type { Logger } from \"../../util/log.ts\";\nimport type { BinaryProvider } from \"./binary-provider.ts\";\nimport { WdaHttpClient, type FetchFn } from \"./http-client.ts\";\nimport { tryProbeWda } from \"./probe.ts\";\nimport { WdaRunner } from \"./runner.ts\";\nimport type { SimctlAdapter } from \"../simctl/adapter.ts\";\nimport type { DeviceHandle, DeviceSlot } from \"../interfaces.ts\";\n\nexport interface WdaRunnerHandle {\n stop(): Promise<void>;\n}\n\nexport interface WdaSessionDeps {\n slot: DeviceSlot;\n handle: DeviceHandle;\n port: number;\n bundleId: string;\n logger: Logger;\n binaryProvider: BinaryProvider;\n simctl: SimctlAdapter;\n // Overrideable for tests.\n fetchFn?: FetchFn;\n readyTimeoutMs?: number;\n /**\n * Spawn the WDA runner XCTest under xcodebuild on the given sim+port.\n * Returns a handle whose `stop()` kills the xcodebuild child process.\n * Default impl uses `WdaRunner` (xcodebuild test-without-building);\n * tests inject a no-op.\n */\n startWdaRunner?: (\n handle: DeviceHandle,\n port: number,\n binaryProvider: BinaryProvider,\n simctl: SimctlAdapter,\n logger: Logger,\n ) => Promise<WdaRunnerHandle>;\n}\n\nexport class WdaSession {\n readonly client: WdaHttpClient;\n private sessionId: string | null = null;\n private runnerHandle: WdaRunnerHandle | null = null;\n private readonly deps: WdaSessionDeps;\n\n constructor(deps: WdaSessionDeps) {\n this.deps = deps;\n this.client = new WdaHttpClient({\n baseUrl: `http://127.0.0.1:${deps.port}`,\n ...(deps.fetchFn ? { fetchFn: deps.fetchFn } : {}),\n });\n }\n\n getSessionId(): string {\n if (!this.sessionId) throw new Error(`WdaSession[${this.deps.slot}] not started — call start() first`);\n return this.sessionId;\n }\n\n async start(): Promise<void> {\n if (this.sessionId) return;\n const starter = this.deps.startWdaRunner ?? defaultStartWdaRunner;\n this.runnerHandle = await starter(\n this.deps.handle,\n this.deps.port,\n this.deps.binaryProvider,\n this.deps.simctl,\n this.deps.logger,\n );\n // Anything between runner-spawned and session-id-captured can throw\n // (port unreachable, xctestrun mismatch, WDA returns 4xx). On failure the\n // xcodebuild child stays alive holding the port and the underlying\n // XCTest process on the sim — kill it before re-throwing so the next\n // start() attempt has a clean slot.\n try {\n await this.waitUntilReady(this.deps.readyTimeoutMs ?? 90_000);\n const created = await this.client.createSession({\n platformName: \"iOS\",\n \"appium:automationName\": \"XCUITest\",\n \"appium:bundleId\": this.deps.bundleId,\n \"appium:udid\": this.deps.handle.udid,\n });\n this.sessionId = created.sessionId ?? created.value.sessionId;\n this.deps.logger.debug(`wda session started: ${this.deps.slot} (${this.sessionId})`);\n } catch (e) {\n if (this.runnerHandle) {\n try {\n await this.runnerHandle.stop();\n } catch (stopErr) {\n this.deps.logger.warn(\n `WdaRunner cleanup after failed start failed for ${this.deps.slot}: ${(stopErr as Error).message}`,\n );\n }\n this.runnerHandle = null;\n }\n throw e;\n }\n }\n\n async stop(): Promise<void> {\n if (this.sessionId) {\n try {\n await this.client.deleteSession(this.sessionId);\n } catch (e) {\n this.deps.logger.warn(`wda deleteSession failed for ${this.deps.slot}: ${(e as Error).message}`);\n } finally {\n this.sessionId = null;\n }\n }\n if (this.runnerHandle) {\n try {\n await this.runnerHandle.stop();\n } catch (e) {\n this.deps.logger.warn(`WdaRunner stop failed for ${this.deps.slot}: ${(e as Error).message}`);\n } finally {\n this.runnerHandle = null;\n }\n }\n }\n\n private async waitUntilReady(timeoutMs: number): Promise<void> {\n const deadline = Date.now() + timeoutMs;\n let lastErr: unknown;\n while (Date.now() < deadline) {\n try {\n const s = await this.client.status();\n if (s.value.ready) return;\n } catch (e) {\n lastErr = e;\n }\n await delay(500);\n }\n throw new Error(\n `WDA on port ${this.deps.port} not ready within ${timeoutMs}ms` +\n (lastErr ? `: ${(lastErr as Error).message}` : \"\"),\n );\n }\n}\n\n// Real WDA runner spawn — `xcodebuild test-without-building` against the\n// xctestrun produced by AppiumWdaBinaryProvider. Returns a handle whose\n// `stop()` kills the child (which takes the sim's XCTest process down too).\n//\n// Reuse-first: if a healthy WDA already answers on the port (CLI of a\n// previous run exited without tearing down, leaving xcodebuild orphaned —\n// xcodebuild keeps the WDA HTTP server alive), reuse it instead of racing\n// a second runner onto the same port. `stop` becomes a no-op because we\n// did not start the runner and must not kill someone else's process.\nasync function defaultStartWdaRunner(\n handle: DeviceHandle,\n port: number,\n binaryProvider: BinaryProvider,\n simctl: SimctlAdapter,\n logger: Logger,\n): Promise<WdaRunnerHandle> {\n const probe = await tryProbeWda(port, 1500);\n if (probe?.ready) {\n logger.debug(\n `reusing existing WDA on port ${port}${probe.build ? ` (build ${probe.build})` : \"\"}`,\n );\n return { stop: async () => {} };\n }\n\n // Ensure sim is booted before we ask XCTest to run on it.\n await simctl.boot(handle.udid);\n const artifacts = await binaryProvider.getArtifacts();\n const runner = new WdaRunner({ logger: logger.child(\"xcb\") });\n runner.start({ udid: handle.udid, port, artifacts });\n return {\n stop: () => runner.stop(),\n };\n}\n","// Typed HTTP client to a single WDA session. Stateless wrt sessionId — caller\n// (WdaSession) supplies it. Thin: only what WdaDriver needs.\n//\n// Injectable `fetchFn` for unit tests (no live WDA).\n\nimport type {\n WdaDragRequest,\n WdaElementHandle,\n WdaFindElementsRequest,\n WdaFindElementsResponse,\n WdaScreenshotResponse,\n WdaSessionCreated,\n WdaSetElementValueRequest,\n WdaSourceResponse,\n WdaStatusResponse,\n WdaTapRequest,\n WdaTypeRequest,\n WdaWindowSize,\n} from \"./types.ts\";\n\nexport type FetchFn = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;\n\nexport interface WdaHttpClientDeps {\n baseUrl: string; // e.g. http://127.0.0.1:8100\n fetchFn?: FetchFn; // injection hook for tests\n}\n\nexport class WdaHttpClient {\n private readonly baseUrl: string;\n private readonly fetchFn: FetchFn;\n\n constructor(deps: WdaHttpClientDeps) {\n this.baseUrl = deps.baseUrl.replace(/\\/+$/, \"\");\n this.fetchFn = deps.fetchFn ?? ((url, init) => fetch(url, init));\n }\n\n async status(): Promise<WdaStatusResponse> {\n return this.get<WdaStatusResponse>(\"/status\");\n }\n\n async createSession(capabilities: Record<string, unknown>): Promise<WdaSessionCreated> {\n return this.post<WdaSessionCreated>(\"/session\", {\n capabilities: { alwaysMatch: capabilities, firstMatch: [{}] },\n });\n }\n\n async deleteSession(sessionId: string): Promise<void> {\n await this.delete(`/session/${encodeURIComponent(sessionId)}`);\n }\n\n async source(sessionId: string): Promise<WdaSourceResponse> {\n return this.get<WdaSourceResponse>(`/session/${encodeURIComponent(sessionId)}/source?format=json`);\n }\n\n async screenshot(sessionId: string): Promise<Buffer> {\n const resp = await this.get<WdaScreenshotResponse>(`/session/${encodeURIComponent(sessionId)}/screenshot`);\n return Buffer.from(resp.value, \"base64\");\n }\n\n async windowSize(sessionId: string): Promise<WdaWindowSize> {\n return this.get<WdaWindowSize>(`/session/${encodeURIComponent(sessionId)}/window/size`);\n }\n\n async tap(sessionId: string, req: WdaTapRequest): Promise<void> {\n // WDA 12.x dropped `/wda/tap/0` (legacy coordinate-tap). Use the W3C\n // Actions API instead — supported by every WDA from ~5.x onward and\n // future-proof.\n await this.post(`/session/${encodeURIComponent(sessionId)}/actions`, {\n actions: [\n {\n type: \"pointer\",\n id: \"finger1\",\n parameters: { pointerType: \"touch\" },\n actions: [\n { type: \"pointerMove\", duration: 0, x: req.x, y: req.y },\n { type: \"pointerDown\", button: 0 },\n { type: \"pause\", duration: 100 },\n { type: \"pointerUp\", button: 0 },\n ],\n },\n ],\n });\n }\n\n async drag(sessionId: string, req: WdaDragRequest): Promise<void> {\n await this.post(`/session/${encodeURIComponent(sessionId)}/wda/dragfromtoforduration`, {\n ...req,\n duration: req.duration ?? 0.4,\n });\n }\n\n async typeText(sessionId: string, req: WdaTypeRequest): Promise<void> {\n // `/wda/keys` sends keys to whichever element has keyboard focus. Used\n // ONLY for focus-less key events (enter/escape) where there's no target\n // element. Text input goes through `setElementValue` to avoid the\n // focus-switch race where `[FBKeyboard typeText:]` doesn't wait for the\n // keyboard to settle and the first 1-2 chars get reordered.\n await this.post(`/session/${encodeURIComponent(sessionId)}/wda/keys`, req);\n }\n\n async findElements(sessionId: string, req: WdaFindElementsRequest): Promise<string[]> {\n const resp = await this.post<WdaFindElementsResponse>(\n `/session/${encodeURIComponent(sessionId)}/elements`,\n req,\n );\n return resp.value.map(extractElementId);\n }\n\n async setElementValue(\n sessionId: string,\n elementId: string,\n req: WdaSetElementValueRequest,\n ): Promise<void> {\n // Backed by `[XCUIElement typeText:]` — internally `waitForKeyboard`'s\n // and types into a specific element rather than into whichever element\n // currently has keyboard focus.\n await this.post(\n `/session/${encodeURIComponent(sessionId)}/element/${encodeURIComponent(elementId)}/value`,\n req,\n );\n }\n\n async pressKey(sessionId: string, name: string): Promise<void> {\n // Home/lock — via PressButton endpoint. Back/enter/escape are translated\n // by WdaDriver into specific endpoints (return key via /wda/keys \"\\n\",\n // back is iOS-meaningless so we no-op upstream).\n await this.post(`/session/${encodeURIComponent(sessionId)}/wda/pressButton`, { name });\n }\n\n async openUrl(sessionId: string, url: string): Promise<void> {\n await this.post(`/session/${encodeURIComponent(sessionId)}/url`, { url });\n }\n\n // ---- internals ---------------------------------------------------------\n\n private async get<T>(path: string): Promise<T> {\n return this.request<T>(\"GET\", path);\n }\n\n private async post<T = void>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(\"POST\", path, body);\n }\n\n private async delete(path: string): Promise<void> {\n await this.request<unknown>(\"DELETE\", path);\n }\n\n private async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const init: RequestInit = {\n method,\n headers: { \"Content-Type\": \"application/json\" },\n };\n if (body !== undefined) init.body = JSON.stringify(body);\n const resp = await this.fetchFn(`${this.baseUrl}${path}`, init);\n if (!resp.ok) {\n const text = await resp.text().catch(() => \"<no body>\");\n throw new Error(`WDA ${method} ${path} failed: HTTP ${resp.status} — ${text.slice(0, 500)}`);\n }\n if (resp.status === 204) return undefined as T;\n return (await resp.json()) as T;\n }\n}\n\nfunction extractElementId(h: WdaElementHandle): string {\n const id = h[\"element-6066-11e4-a52e-4f735466cecf\"] ?? h.ELEMENT;\n if (!id) {\n throw new Error(`WDA element handle missing id: ${JSON.stringify(h)}`);\n }\n return id;\n}\n","// Cheap reachability + readiness check for an existing WDA on a port.\n//\n// Used by `defaultStartWdaRunner` to decide between cold-start (xcodebuild\n// test, 5-15 min on first run) and reuse of an already-running WDA (e.g.\n// runner orphaned by a previous CLI process that exited without teardown).\n\nimport type { FetchFn } from \"./http-client.ts\";\nimport type { WdaStatusResponse } from \"./types.ts\";\n\nexport interface WdaProbeResult {\n ready: boolean;\n build?: string;\n}\n\nexport async function tryProbeWda(\n port: number,\n timeoutMs: number,\n fetchFn: FetchFn = (input, init) => fetch(input, init),\n): Promise<WdaProbeResult | null> {\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), timeoutMs);\n try {\n const res = await fetchFn(`http://127.0.0.1:${port}/status`, { signal: ctrl.signal });\n if (!res.ok) return null;\n const body = (await res.json()) as Partial<WdaStatusResponse>;\n const value = body?.value;\n if (!value || typeof value.ready !== \"boolean\") return null;\n return value.build?.version\n ? { ready: value.ready, build: value.build.version }\n : { ready: value.ready };\n } catch {\n return null;\n } finally {\n clearTimeout(timer);\n }\n}\n","// WdaRunner — owns the `xcodebuild test-without-building` child process that\n// runs the WebDriverAgent XCTest bundle on a specific simulator.\n//\n// Lifecycle:\n// start(udid, port, artifacts) → spawn xcodebuild with USE_PORT=<port>\n// stop() → kill the child (sim XCTest dies with it)\n//\n// Why xcodebuild test-without-building instead of `simctl spawn xctest`:\n// XCTest bundles need an `.xctestrun` plist that wires up framework search\n// paths, test host bundles, and environment. xcodebuild reads the plist and\n// does the right thing; rolling our own would replicate a hundred lines of\n// Apple-internal lookups and break on every Xcode minor.\n\nimport { spawn, type ChildProcess } from \"node:child_process\";\n\nimport type { Logger } from \"../../util/log.ts\";\nimport type { WdaArtifacts } from \"./binary-provider.ts\";\n\nexport interface WdaRunnerStartOptions {\n udid: string;\n port: number;\n artifacts: WdaArtifacts;\n}\n\nexport class WdaRunner {\n private child: ChildProcess | null = null;\n private readonly logger: Logger;\n\n constructor(deps: { logger: Logger }) {\n this.logger = deps.logger;\n }\n\n start(opts: WdaRunnerStartOptions): void {\n if (this.child) {\n throw new Error(`WdaRunner already started (pid ${this.child.pid})`);\n }\n const args = [\n \"test-without-building\",\n \"-xctestrun\",\n opts.artifacts.xctestrunPath,\n \"-destination\",\n `platform=iOS Simulator,id=${opts.udid}`,\n \"-derivedDataPath\",\n opts.artifacts.derivedDataPath,\n ];\n this.logger.debug(`spawning xcodebuild ${args.join(\" \")}`);\n this.child = spawn(\"xcodebuild\", args, {\n env: {\n ...process.env,\n // WDA reads USE_PORT at startup to bind the HTTP server. This is THE\n // mechanism by which two slots run on different ports (D-13).\n USE_PORT: String(opts.port),\n },\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n this.child.on(\"exit\", (code, signal) => {\n this.logger.debug(`xcodebuild exited code=${code} signal=${signal ?? \"(none)\"}`);\n this.child = null;\n });\n // Capture xcodebuild output for debug (WDA prints \"ServerURLHere\" line\n // when ready; useful in trace-mode failure analysis). We do not gate\n // start() on this — readiness is observed via WDA's own /status endpoint\n // by WdaSession.\n if (this.child.stdout) {\n this.child.stdout.on(\"data\", (chunk: Buffer) => {\n if (process.env.E2E_DEBUG) {\n process.stderr.write(`[wda:${opts.port}] ${chunk}`);\n }\n });\n }\n if (this.child.stderr) {\n this.child.stderr.on(\"data\", (chunk: Buffer) => {\n if (process.env.E2E_DEBUG) {\n process.stderr.write(`[wda:${opts.port}:err] ${chunk}`);\n }\n });\n }\n }\n\n async stop(): Promise<void> {\n if (!this.child) return;\n const child = this.child;\n return new Promise<void>((resolve) => {\n child.once(\"exit\", () => resolve());\n try {\n child.kill(\"SIGTERM\");\n } catch (e) {\n this.logger.warn(`WdaRunner.stop: kill SIGTERM failed: ${(e as Error).message}`);\n resolve();\n }\n // Forced kill if xcodebuild does not exit within 5s.\n setTimeout(() => {\n if (this.child) {\n try {\n child.kill(\"SIGKILL\");\n } catch {\n /* already dead */\n }\n }\n }, 5_000);\n });\n }\n\n isRunning(): boolean {\n return this.child !== null;\n }\n}\n","// Convert WDA's XCUIElement-rooted source dump into our `A11yNode`.\n//\n// D-16: XCUIElement attribute → A11yNode mapping\n// name / value → A11yNode.text (priority `name`, fallback `value`)\n// label → A11yNode.label\n// name === label (Apple often duplicates) → write to BOTH fields so\n// getByText('X') AND getByLabel('X') both match.\n// Empty / whitespace-only strings are normalized to `undefined` to avoid\n// false-positive matches against the empty selector.\n\nimport type { A11yNode, Bounds } from \"../../inspection/types.ts\";\nimport type { WdaSourceNode } from \"./types.ts\";\n\nexport function parseWdaSource(root: WdaSourceNode): A11yNode {\n return mapNode(root);\n}\n\nfunction mapNode(raw: WdaSourceNode): A11yNode {\n const name = nonEmpty(raw.name);\n const label = nonEmpty(raw.label);\n const value = nonEmpty(typeof raw.value === \"string\" ? raw.value : raw.value != null ? String(raw.value) : undefined);\n\n // D-16 mapping\n const text = name ?? value;\n const labelOut = label;\n // If name and label are identical, label is already covered by text; still\n // set label to satisfy getByLabel('X') without an extra branch.\n // (Same string in two fields — no harm; resolver treats them as equal keys.)\n\n const out: A11yNode = { children: (raw.children ?? []).map(mapNode) };\n // iOS XCUI `name` IS the accessibilityIdentifier — same value RN exposes as\n // `testID` prop. We populate `testId` from name too, so getByTestId works\n // out of the box on instrumented apps. (D-16 says name → text; we add\n // name → testId on top, since one XCUI attribute legitimately serves both:\n // for instrumented components it's a stable id, for plain text it's the\n // visible string. The resolver matches whichever the author asked for.)\n if (name) out.testId = name;\n if (text) out.text = text;\n if (labelOut) out.label = labelOut;\n if (raw.type) out.role = raw.type;\n const bounds = parseRect(raw.rect);\n if (bounds) out.bounds = bounds;\n const enabled = parseBool(raw.isEnabled);\n if (enabled !== undefined) out.enabled = enabled;\n const focused = parseBool(raw.hasFocus);\n if (focused !== undefined) out.focused = focused;\n return out;\n}\n\nfunction nonEmpty(s: string | null | undefined): string | undefined {\n if (s == null) return undefined;\n const trimmed = s.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction parseRect(r: WdaSourceNode[\"rect\"]): Bounds | undefined {\n if (!r) return undefined;\n if ([r.x, r.y, r.width, r.height].some((n) => typeof n !== \"number\" || !Number.isFinite(n))) return undefined;\n return { x: r.x, y: r.y, width: r.width, height: r.height };\n}\n\nfunction parseBool(b: string | boolean | undefined): boolean | undefined {\n if (b === undefined || b === null) return undefined;\n if (typeof b === \"boolean\") return b;\n // WDA serializes booleans as strings like \"1\"/\"0\" or \"true\"/\"false\".\n const v = b.toLowerCase().trim();\n if (v === \"1\" || v === \"true\") return true;\n if (v === \"0\" || v === \"false\") return false;\n return undefined;\n}\n","// WdaDriver — pure-TS implementation of `Driver` via HTTP to WebDriverAgent.\n//\n// Responsibilities per ISP split:\n// - DeviceController: simctl-backed sim lifecycle + app install/launch.\n// - UiDriver: resolve selector against a11y tree → coordinate tap/drag/keys.\n// - InspectionDriver: a11y tree dump + screenshot via WDA.\n// - ContextController: native-only stub (D-9), WebView arrives later.\n//\n// Selector resolution in this phase is **deliberately minimal** — first-match\n// by testId/text/label, no NearMisses, no `near`/`ordinal`. Phase 4 swaps in\n// the real SelectorResolver. The Driver interface here doesn't change.\n\nimport type { Logger } from \"../../util/log.ts\";\nimport type { A11yNode, A11yTreeOptions, Bounds } from \"../../inspection/types.ts\";\nimport type { Selector } from \"../../inspection/selector.ts\";\nimport type {\n ContextController,\n ContextInfo,\n DeviceController,\n DeviceHandle,\n DeviceSlot,\n Driver,\n InspectionDriver,\n UiDriver,\n} from \"../interfaces.ts\";\nimport { SimctlAdapter } from \"../simctl/adapter.ts\";\nimport type { BinaryProvider } from \"./binary-provider.ts\";\nimport { WdaSession } from \"./session.ts\";\nimport { parseWdaSource } from \"./tree-parser.ts\";\n\nexport interface WdaDriverDeps {\n logger: Logger;\n simBySlot: Record<string, string>;\n appBundleId: string;\n wdaPortBySlot: Record<string, number>;\n binaryProvider: BinaryProvider;\n simctl?: SimctlAdapter;\n // Hook for tests to substitute the session factory entirely.\n sessionFactory?: (slot: DeviceSlot, handle: DeviceHandle, port: number) => WdaSession;\n}\n\nexport class WdaDriver implements DeviceController, UiDriver, InspectionDriver, ContextController {\n private readonly handles = new Map<DeviceSlot, DeviceHandle>();\n private readonly sessions = new Map<DeviceSlot, WdaSession>();\n private readonly simctl: SimctlAdapter;\n private static readonly NATIVE_CONTEXT: ContextInfo = { id: \"native\", type: \"native\" };\n\n constructor(private readonly deps: WdaDriverDeps) {\n this.simctl = deps.simctl ?? new SimctlAdapter();\n }\n\n // ---- DeviceController --------------------------------------------------\n\n async resolve(slot: DeviceSlot): Promise<DeviceHandle> {\n const cached = this.handles.get(slot);\n if (cached) return cached;\n const name = this.deps.simBySlot[slot];\n if (!name) {\n throw new Error(\n `Unknown device slot \"${slot}\". Known: ${Object.keys(this.deps.simBySlot).join(\",\")}`,\n );\n }\n const info = await this.simctl.resolveByName(name);\n const handle: DeviceHandle = { slot, name: info.name, udid: info.udid };\n this.handles.set(slot, handle);\n return handle;\n }\n\n async boot(slot: DeviceSlot): Promise<DeviceHandle> {\n const h = await this.resolve(slot);\n await this.simctl.boot(h.udid);\n return h;\n }\n\n async shutdown(slot: DeviceSlot): Promise<void> {\n const session = this.sessions.get(slot);\n if (session) {\n await session.stop();\n this.sessions.delete(slot);\n }\n const h = await this.resolve(slot);\n await this.simctl.shutdown(h.udid);\n }\n\n async installApp(slot: DeviceSlot, appPath: string): Promise<void> {\n const h = await this.boot(slot);\n await this.simctl.install(h.udid, appPath);\n }\n\n async appLaunch(slot: DeviceSlot, opts: { bundleId?: string; clean?: boolean }): Promise<void> {\n const h = await this.boot(slot);\n const bundleId = opts.bundleId ?? this.deps.appBundleId;\n if (opts.clean) {\n // Drop in-memory app state by terminating the running process; the next\n // launch starts the app from cold. We do NOT uninstall — that would\n // remove the dev-client/IPA itself, and we have no reinstall path in\n // scenario execution. (Full data reset belongs to a separate driver\n // op once we add simctl privacy/keychain reset — out of MVP scope.)\n await this.simctl.terminate(h.udid, bundleId);\n }\n await this.simctl.launch(h.udid, bundleId);\n }\n\n async openDeeplink(slot: DeviceSlot, url: string): Promise<void> {\n const h = await this.boot(slot);\n await this.simctl.openUrl(h.udid, url);\n }\n\n // ---- UiDriver ----------------------------------------------------------\n\n async tap(slot: DeviceSlot, selector: Selector): Promise<void> {\n const session = await this.getSession(slot);\n const bounds = await this.resolveBounds(slot, selector);\n const { cx, cy } = center(bounds);\n await session.client.tap(session.getSessionId(), { x: cx, y: cy });\n }\n\n async type(slot: DeviceSlot, selector: Selector, text: string): Promise<void> {\n // Element-scoped typing via `POST /element/{id}/value`. Backed by\n // `[XCUIElement typeText:]`, which `waitForKeyboard`'s internally and\n // types into a specific element. We deliberately avoid the older\n // tap-to-focus + `/wda/keys` (= `[FBKeyboard typeText:]`) flow: on\n // focus-switch between two text inputs that path drops/reorders the\n // first 1-2 chars because the keyboard hasn't finished animating in.\n const session = await this.getSession(slot);\n const elementId = await this.resolveElementId(slot, selector);\n await session.client.setElementValue(session.getSessionId(), elementId, {\n value: Array.from(text),\n });\n }\n\n async swipe(\n slot: DeviceSlot,\n direction: \"up\" | \"down\" | \"left\" | \"right\",\n from?: Selector,\n ): Promise<void> {\n const session = await this.getSession(slot);\n const size = await session.client.windowSize(session.getSessionId());\n const w = size.value.width;\n const h = size.value.height;\n\n let fromX: number, fromY: number;\n if (from) {\n const b = await this.resolveBounds(slot, from);\n const c = center(b);\n fromX = c.cx;\n fromY = c.cy;\n } else {\n fromX = w / 2;\n fromY = h / 2;\n }\n\n const dist = Math.min(w, h) * 0.4;\n const toX = direction === \"left\" ? fromX - dist : direction === \"right\" ? fromX + dist : fromX;\n const toY = direction === \"up\" ? fromY - dist : direction === \"down\" ? fromY + dist : fromY;\n\n await session.client.drag(session.getSessionId(), { fromX, fromY, toX, toY, duration: 0.3 });\n }\n\n async pressKey(slot: DeviceSlot, key: \"back\" | \"home\" | \"enter\" | \"escape\"): Promise<void> {\n const session = await this.getSession(slot);\n if (key === \"home\") {\n await session.client.pressKey(session.getSessionId(), \"home\");\n return;\n }\n if (key === \"enter\") {\n // Send return key through the keyboard endpoint.\n await session.client.typeText(session.getSessionId(), { value: [\"\\n\"] });\n return;\n }\n if (key === \"escape\") {\n await session.client.typeText(session.getSessionId(), { value: [\"\u001b\"] });\n return;\n }\n // 'back' has no iOS-native equivalent; nav back is a UI gesture handled by\n // app-specific swipe-from-edge or a back button. Document this loudly.\n throw new Error(`pressKey('back') is not supported on iOS — use swipe-back or app-specific control`);\n }\n\n async waitFor(\n slot: DeviceSlot,\n selector: Selector,\n opts: { timeoutMs?: number; optional?: boolean } = {},\n ): Promise<boolean> {\n const timeoutMs = opts.timeoutMs ?? 10_000;\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n const tree = await this.a11yTree(slot);\n const found = findFirstMatch(tree, selector);\n if (found) return true;\n await new Promise((r) => setTimeout(r, 300));\n }\n if (opts.optional) return false;\n throw new Error(`waitFor timed out after ${timeoutMs}ms on slot \"${slot}\": ${selectorPretty(selector)}`);\n }\n\n // ---- InspectionDriver --------------------------------------------------\n\n async screenshot(slot: DeviceSlot): Promise<Buffer> {\n const session = await this.getSession(slot);\n return session.client.screenshot(session.getSessionId());\n }\n\n async a11yTree(slot: DeviceSlot, _opts: A11yTreeOptions = {}): Promise<A11yNode> {\n const session = await this.getSession(slot);\n const resp = await session.client.source(session.getSessionId());\n return parseWdaSource(resp.value);\n }\n\n // ---- ContextController stub (D-9) --------------------------------------\n\n async listContexts(_slot: DeviceSlot): Promise<ContextInfo[]> {\n return [WdaDriver.NATIVE_CONTEXT];\n }\n\n async setContext(_slot: DeviceSlot, contextId: string): Promise<void> {\n if (contextId !== \"native\") {\n throw new Error(`WdaDriver.setContext: only 'native' is supported in MVP (got '${contextId}')`);\n }\n }\n\n async getCurrentContext(_slot: DeviceSlot): Promise<ContextInfo> {\n return WdaDriver.NATIVE_CONTEXT;\n }\n\n // ---- internals ---------------------------------------------------------\n\n private async getSession(slot: DeviceSlot): Promise<WdaSession> {\n const existing = this.sessions.get(slot);\n if (existing) return existing;\n const handle = await this.boot(slot);\n const port = this.deps.wdaPortBySlot[slot];\n if (port == null) {\n throw new Error(\n `No WDA port configured for slot \"${slot}\". Set EnvConfig.wdaPortBySlot or add WDA_PORT_${slot} to .env.`,\n );\n }\n const session = this.deps.sessionFactory\n ? this.deps.sessionFactory(slot, handle, port)\n : new WdaSession({\n slot,\n handle,\n port,\n bundleId: this.deps.appBundleId,\n logger: this.deps.logger.child(`wda:${slot}`),\n binaryProvider: this.deps.binaryProvider,\n simctl: this.simctl,\n });\n await session.start();\n this.sessions.set(slot, session);\n return session;\n }\n\n private async resolveBounds(slot: DeviceSlot, selector: Selector): Promise<Bounds> {\n const tree = await this.a11yTree(slot);\n const node = findFirstMatch(tree, selector);\n if (!node) {\n throw new Error(`Selector did not match on slot \"${slot}\": ${selectorPretty(selector)}`);\n }\n if (!node.bounds) {\n throw new Error(`Matched node has no bounds (cannot tap): ${selectorPretty(selector)}`);\n }\n return node.bounds;\n }\n\n private async resolveElementId(slot: DeviceSlot, selector: Selector): Promise<string> {\n if (selector.near) {\n throw new Error(\n `type(): near() selectors are not supported — use getByTestId/getByLabel/getByText.`,\n );\n }\n if (selector.pointPercent) {\n throw new Error(`type(): pointPercent selectors are not supported.`);\n }\n const predicate = buildPredicate(selector);\n if (!predicate) {\n throw new Error(\n `type(): selector must specify testId/text/label: ${selectorPretty(selector)}`,\n );\n }\n const session = await this.getSession(slot);\n const ids = await session.client.findElements(session.getSessionId(), {\n using: \"predicate string\",\n value: predicate,\n });\n if (ids.length === 0) {\n throw new Error(\n `type(): no element matched ${selectorPretty(selector)} (predicate: ${predicate})`,\n );\n }\n const idx = selector.ordinal ?? 0;\n if (idx >= ids.length) {\n throw new Error(\n `type(): ordinal=${idx} out of range (${ids.length} matches) for ${selectorPretty(selector)}`,\n );\n }\n return ids[idx]!;\n }\n}\n\n// Minimal first-match resolver. Phase 4 replaces with full SelectorResolver\n// (NearMisses, near(), ordinal()). For Phase 2 we keep this inline so the\n// driver is self-sufficient.\nexport function findFirstMatch(root: A11yNode, sel: Selector): A11yNode | undefined {\n const matches = (n: A11yNode): boolean => {\n if (sel.testId && n.testId !== sel.testId) return false;\n if (sel.text && n.text !== sel.text && n.label !== sel.text) return false;\n if (sel.label && n.label !== sel.label && n.text !== sel.label) return false;\n return Boolean(sel.testId || sel.text || sel.label);\n };\n if (matches(root)) return root;\n for (const c of root.children) {\n const found = findFirstMatch(c, sel);\n if (found) return found;\n }\n return undefined;\n}\n\nfunction center(b: Bounds): { cx: number; cy: number } {\n return { cx: b.x + b.width / 2, cy: b.y + b.height / 2 };\n}\n\n// NSPredicate string for WDA `findElements`. Combines testId/text/label\n// clauses with AND so multi-attribute selectors narrow down correctly.\n// iOS `accessibilityIdentifier` (= RN `testID`) is exposed by WDA as `name`.\nfunction buildPredicate(s: Selector): string | undefined {\n const esc = (v: string) => v.replace(/\\\\/g, \"\\\\\\\\\").replace(/'/g, \"\\\\'\");\n const clauses: string[] = [];\n if (s.testId) clauses.push(`name == '${esc(s.testId)}'`);\n if (s.text) clauses.push(`(label == '${esc(s.text)}' OR value == '${esc(s.text)}')`);\n if (s.label && s.label !== s.text) clauses.push(`label == '${esc(s.label)}'`);\n return clauses.length ? clauses.join(\" AND \") : undefined;\n}\n\nfunction selectorPretty(s: Selector): string {\n const parts: string[] = [];\n if (s.testId) parts.push(`testId=${JSON.stringify(s.testId)}`);\n if (s.text) parts.push(`text=${JSON.stringify(s.text)}`);\n if (s.label) parts.push(`label=${JSON.stringify(s.label)}`);\n if (s.ordinal !== undefined) parts.push(`ordinal=${s.ordinal}`);\n if (s.near) parts.push(`near=…`);\n return `{${parts.join(\", \")}}`;\n}\n","import type { EnvConfig } from \"../config/env.ts\";\nimport type { Logger } from \"../util/log.ts\";\nimport type { Driver } from \"./interfaces.ts\";\nimport { AppiumWdaBinaryProvider } from \"./wda/appium-wda-binary-provider.ts\";\nimport type { BinaryProvider } from \"./wda/binary-provider.ts\";\nimport { WdaDriver } from \"./wda/index.ts\";\n\nexport interface DriverConfig {\n env: EnvConfig;\n logger: Logger;\n engine?: \"wda\";\n // For tests: substitute the WDA binary provider (e.g. with a prebuilt path).\n binaryProvider?: BinaryProvider;\n}\n\nexport function createDriver(cfg: DriverConfig): Driver {\n const engine = cfg.engine ?? \"wda\";\n switch (engine) {\n case \"wda\": {\n const binaryProvider =\n cfg.binaryProvider ?? new AppiumWdaBinaryProvider({ logger: cfg.logger.child(\"wda-binary\") });\n return new WdaDriver({\n logger: cfg.logger.child(\"wda\"),\n simBySlot: cfg.env.simBySlot,\n wdaPortBySlot: cfg.env.wdaPortBySlot,\n appBundleId: cfg.env.APP_BUNDLE_ID,\n binaryProvider,\n });\n }\n default: {\n const exhaustive: never = engine;\n throw new Error(`unsupported driver engine: ${exhaustive as string}`);\n }\n }\n}\n","// ActionDiffer — `{ before, after }` → \"what changed on screen?\".\n//\n// Used by MCP `tap`/`type`/`waitFor` tools to attach a structured changelog\n// to each successful action. The LLM uses this to verify intent without a\n// second a11y_tree round-trip.\n//\n// Identity for diffing: a node is \"the same\" between trees if its **path**\n// (testId stack from root, with fallbacks to text/label/role) matches.\n// We do not rely on object identity — trees come from separate parses.\n\nimport type { A11yNode } from \"./types.ts\";\n\nexport interface TreeChange {\n path: string; // e.g. \"Window>List>Cell[2]>Button[login-btn]\"\n field?: keyof A11yNode; // for `changed`, which field flipped\n before?: unknown;\n after?: unknown;\n node: A11yNode; // post-action snapshot (or pre, for \"removed\")\n}\n\nexport interface TreeDiff {\n added: TreeChange[];\n removed: TreeChange[];\n changed: TreeChange[];\n}\n\nexport class ActionDiffer {\n diff(before: A11yNode, after: A11yNode): TreeDiff {\n const beforeMap = indexByPath(before);\n const afterMap = indexByPath(after);\n\n const out: TreeDiff = { added: [], removed: [], changed: [] };\n\n for (const [path, b] of beforeMap) {\n const a = afterMap.get(path);\n if (!a) {\n out.removed.push({ path, node: b });\n continue;\n }\n const fieldChanges = diffFields(b, a);\n for (const fc of fieldChanges) {\n out.changed.push({ path, ...fc, node: a });\n }\n }\n for (const [path, a] of afterMap) {\n if (!beforeMap.has(path)) {\n out.added.push({ path, node: a });\n }\n }\n return out;\n }\n}\n\nfunction indexByPath(root: A11yNode): Map<string, A11yNode> {\n const out = new Map<string, A11yNode>();\n walk(root, \"\", out);\n return out;\n}\n\nfunction walk(n: A11yNode, parentPath: string, out: Map<string, A11yNode>): void {\n const key = nodeKey(n);\n const path = parentPath ? `${parentPath}>${key}` : key;\n // Disambiguate same-key siblings by index suffix:\n let unique = path;\n let i = 1;\n while (out.has(unique)) {\n unique = `${path}#${i++}`;\n }\n out.set(unique, n);\n for (const c of n.children) walk(c, unique, out);\n}\n\nfunction nodeKey(n: A11yNode): string {\n if (n.testId) return `[${n.testId}]`;\n if (n.text) return `\"${truncate(n.text)}\"`;\n if (n.label) return `(${truncate(n.label)})`;\n if (n.role) return n.role;\n return \"*\";\n}\n\nfunction truncate(s: string, max = 24): string {\n if (s.length <= max) return s;\n return s.slice(0, max - 1) + \"…\";\n}\n\nfunction diffFields(b: A11yNode, a: A11yNode): Array<Pick<TreeChange, \"field\" | \"before\" | \"after\">> {\n const out: Array<Pick<TreeChange, \"field\" | \"before\" | \"after\">> = [];\n const fields: Array<keyof A11yNode> = [\"text\", \"label\", \"testId\", \"role\", \"enabled\", \"focused\"];\n for (const f of fields) {\n if (b[f] !== a[f]) out.push({ field: f, before: b[f], after: a[f] });\n }\n return out;\n}\n","// FailureExplainer — packs a Driver/Resolver throw into a structured payload\n// that an LLM can act on without a separate diagnostic round-trip.\n//\n// Output shape is stable across all failure paths (resolve / drive / timeout)\n// so MCP-tool consumers only marshal one schema.\n\nimport type { A11yNode } from \"./types.ts\";\nimport type { NearMiss, Selector } from \"./selector.ts\";\n\nexport interface ExplainedFailure {\n code: FailureCode;\n message: string;\n context: {\n slot?: string;\n selector?: Selector;\n candidates?: NearMiss[];\n screenshotPath?: string;\n treePath?: string;\n [k: string]: unknown;\n };\n}\n\nexport type FailureCode =\n | \"selector_not_found\"\n | \"selector_ambiguous\"\n | \"timeout\"\n | \"driver_error\"\n | \"session_not_ready\"\n | \"unknown\";\n\nexport class FailureExplainer {\n fromResolverFailure(opts: {\n slot: string;\n selector: Selector;\n reason: string;\n candidates: NearMiss[];\n screenshotPath?: string;\n treePath?: string;\n }): ExplainedFailure {\n const code: FailureCode = /ambiguous|ordinal/i.test(opts.reason)\n ? \"selector_ambiguous\"\n : \"selector_not_found\";\n return {\n code,\n message: opts.reason,\n context: {\n slot: opts.slot,\n selector: opts.selector,\n candidates: opts.candidates,\n ...(opts.screenshotPath ? { screenshotPath: opts.screenshotPath } : {}),\n ...(opts.treePath ? { treePath: opts.treePath } : {}),\n },\n };\n }\n\n fromTimeout(opts: { slot: string; selector: Selector; timeoutMs: number }): ExplainedFailure {\n return {\n code: \"timeout\",\n message: `waitFor timed out after ${opts.timeoutMs}ms`,\n context: { slot: opts.slot, selector: opts.selector, timeoutMs: opts.timeoutMs },\n };\n }\n\n fromDriverError(opts: { slot?: string; error: Error; selector?: Selector }): ExplainedFailure {\n const code = /not ready|status|session/i.test(opts.error.message) ? \"session_not_ready\" : \"driver_error\";\n return {\n code,\n message: opts.error.message,\n context: {\n ...(opts.slot ? { slot: opts.slot } : {}),\n ...(opts.selector ? { selector: opts.selector } : {}),\n },\n };\n }\n\n /**\n * Serialize to a single-line summary + structured details, suitable for\n * embedding in MCP-tool error responses.\n */\n format(f: ExplainedFailure): string {\n const lines: string[] = [`[${f.code}] ${f.message}`];\n if (f.context.slot) lines.push(` on slot: ${f.context.slot}`);\n if (f.context.selector) lines.push(` selector: ${JSON.stringify(f.context.selector)}`);\n if (f.context.candidates && f.context.candidates.length > 0) {\n lines.push(` candidates (top ${f.context.candidates.length}):`);\n for (const c of f.context.candidates) {\n lines.push(` - score ${c.score.toFixed(2)} ${describeNode(c.node)} — ${c.reason}`);\n }\n }\n if (f.context.screenshotPath) lines.push(` screenshot: ${f.context.screenshotPath}`);\n if (f.context.treePath) lines.push(` tree: ${f.context.treePath}`);\n return lines.join(\"\\n\");\n }\n}\n\nfunction describeNode(n: A11yNode): string {\n const parts: string[] = [];\n if (n.testId) parts.push(`testId=\"${n.testId}\"`);\n if (n.text) parts.push(`text=\"${n.text}\"`);\n if (n.label) parts.push(`label=\"${n.label}\"`);\n if (n.role) parts.push(`role=${n.role}`);\n return parts.length > 0 ? `{${parts.join(\", \")}}` : `{*unidentified*}`;\n}\n","// ScreenshotAnnotator — overlay bounds + indices onto a PNG.\n//\n// D-14: sharp + SVG composite. We never touch a Canvas API; the SVG is a\n// plain string we build in memory and feed to `sharp.composite()`.\n//\n// The annotated PNG goes into failure artifacts and into MCP responses so\n// the LLM sees rectangles around candidates instead of just JSON node names.\n\nimport sharp from \"sharp\";\n\nimport type { A11yNode, Bounds } from \"./types.ts\";\n\nexport interface AnnotationTarget {\n bounds: Bounds;\n label?: string; // e.g. \"0\", \"1\", \"2\" for top-3 NearMisses\n color?: string; // e.g. \"#ff3333\" — defaults to red\n}\n\nexport class ScreenshotAnnotator {\n /**\n * Returns a PNG buffer with rectangles + numeric labels overlaid on top of\n * the input screenshot. Coordinates are in points (matching A11yNode.bounds\n * coming from WDA) — we re-scale to the screenshot's actual pixel size.\n */\n async annotate(screenshot: Buffer, targets: AnnotationTarget[]): Promise<Buffer> {\n if (targets.length === 0) return screenshot;\n const meta = await sharp(screenshot).metadata();\n const w = meta.width ?? 0;\n const h = meta.height ?? 0;\n if (w === 0 || h === 0) return screenshot;\n\n // WDA usually returns screenshots at @2x or @3x relative to the point\n // coordinate space. Caller can pass already-pixel bounds; we don't know\n // the ratio here without context. Draw bounds as-is — caller scales if\n // needed. (TreeInspector + WdaDriver bounds match the screenshot already\n // on simulator: bounds and screenshot pixel-equivalent.)\n const svg = buildOverlaySvg(w, h, targets);\n return sharp(screenshot)\n .composite([{ input: Buffer.from(svg), top: 0, left: 0 }])\n .png()\n .toBuffer();\n }\n\n /**\n * Convenience: annotate from A11yNodes (extract bounds + auto-number labels).\n */\n async annotateNodes(screenshot: Buffer, nodes: A11yNode[], color = \"#ff3333\"): Promise<Buffer> {\n const targets: AnnotationTarget[] = nodes\n .filter((n): n is A11yNode & { bounds: Bounds } => n.bounds !== undefined)\n .map((n, idx) => ({ bounds: n.bounds, label: String(idx), color }));\n return this.annotate(screenshot, targets);\n }\n}\n\nfunction buildOverlaySvg(width: number, height: number, targets: AnnotationTarget[]): string {\n const elems = targets\n .map((t) => {\n const c = t.color ?? \"#ff3333\";\n const lbl = t.label ?? \"\";\n const x = t.bounds.x;\n const y = t.bounds.y;\n const w = t.bounds.width;\n const h = t.bounds.height;\n return `\n <rect x=\"${x}\" y=\"${y}\" width=\"${w}\" height=\"${h}\" fill=\"none\" stroke=\"${c}\" stroke-width=\"3\" />\n <rect x=\"${x}\" y=\"${y - 22}\" width=\"${Math.max(20, lbl.length * 12 + 8)}\" height=\"22\" fill=\"${c}\" />\n <text x=\"${x + 5}\" y=\"${y - 6}\" fill=\"#fff\" font-family=\"Helvetica\" font-size=\"16\" font-weight=\"bold\">${escapeXml(lbl)}</text>`;\n })\n .join(\"\\n\");\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${width}\" height=\"${height}\">${elems}</svg>`;\n}\n\nfunction escapeXml(s: string): string {\n return s\n .replaceAll(\"&\", \"&\")\n .replaceAll(\"<\", \"<\")\n .replaceAll(\">\", \">\")\n .replaceAll('\"', \""\")\n .replaceAll(\"'\", \"'\");\n}\n","// SelectorResolver — the heart of AI-first error recovery.\n//\n// Given a Selector + a parsed a11y tree, return either:\n// - the matched A11yNode (exact), OR\n// - up to 3 NearMisses with structured reasons (so the LLM can pick one).\n//\n// D-16: testId / text / label are equal-citizens. No priority among them; the\n// \"closer match\" wins by string distance. Custom buttons-without-testID get\n// the same treatment as instrumented buttons.\n//\n// `ordinal` and `near` (D-10) are modifiers, applied AFTER the primary match\n// reduces the candidate set.\n\nimport type { A11yNode, Bounds } from \"./types.ts\";\nimport type { NearMiss, Selector } from \"./selector.ts\";\n\nexport interface ResolveSuccess {\n ok: true;\n node: A11yNode;\n}\n\nexport interface ResolveFailure {\n ok: false;\n reason: string;\n candidates: NearMiss[];\n}\n\nexport type ResolveResult = ResolveSuccess | ResolveFailure;\n\nexport class SelectorResolver {\n resolve(root: A11yNode, sel: Selector): ResolveResult {\n if (!sel.testId && !sel.text && !sel.label && !sel.pointPercent) {\n return { ok: false, reason: \"Selector empty (no testId/text/label/pointPercent)\", candidates: [] };\n }\n\n const all: A11yNode[] = [];\n collectAll(root, all);\n\n let exact = all.filter((n) => matchesExact(n, sel));\n\n // `near` filter — keep only candidates within maxDistancePx of the anchor\n // and (when multiple satisfy the constraint) keep the closest. With\n // maxDistancePx undefined, near() acts as a disambiguator: always picks\n // the single nearest candidate.\n if (sel.near) {\n const anchorRes = this.resolve(root, sel.near.anchor);\n if (!anchorRes.ok) {\n return {\n ok: false,\n reason: `near() anchor did not resolve: ${anchorRes.reason}`,\n candidates: [],\n };\n }\n const anchorCenter = boundsCenter(anchorRes.node.bounds);\n if (!anchorCenter) {\n return { ok: false, reason: \"near() anchor has no bounds\", candidates: [] };\n }\n const ranked = exact\n .map((n) => ({ n, dist: dist(boundsCenter(n.bounds), anchorCenter) }))\n .filter((x) => x.dist !== Infinity)\n .filter((x) => sel.near!.maxDistancePx === undefined || x.dist <= sel.near!.maxDistancePx!)\n .sort((a, b) => a.dist - b.dist);\n // Keep only the closest one when maxDistancePx is unbounded.\n // (If maxDistancePx is set, ranked already filtered to in-range only —\n // still narrow to closest so the resolver returns success on single match.)\n exact = ranked.length > 0 ? [ranked[0]!.n] : [];\n }\n\n if (sel.ordinal !== undefined) {\n const picked = exact[sel.ordinal];\n return picked\n ? { ok: true, node: picked }\n : {\n ok: false,\n reason: `ordinal ${sel.ordinal} out of range (found ${exact.length} match${exact.length === 1 ? \"\" : \"es\"})`,\n candidates: top3FromMatches(exact),\n };\n }\n\n if (exact.length === 1) {\n return { ok: true, node: exact[0]! };\n }\n\n if (exact.length > 1) {\n return {\n ok: false,\n reason: `${exact.length} elements match selector — add ordinal(n) or near(anchor) to disambiguate`,\n candidates: top3FromMatches(exact),\n };\n }\n\n // No exact match: build top-3 NearMisses from the whole tree.\n return {\n ok: false,\n reason: \"No element matched\",\n candidates: top3NearMisses(all, sel),\n };\n }\n}\n\n// ---- internals -----------------------------------------------------------\n\nfunction collectAll(n: A11yNode, out: A11yNode[]): void {\n out.push(n);\n for (const c of n.children) collectAll(c, out);\n}\n\nfunction matchesExact(n: A11yNode, sel: Selector): boolean {\n if (sel.testId !== undefined) {\n if (n.testId !== sel.testId) return false;\n }\n if (sel.text !== undefined) {\n // text matches against `text` OR `label` (D-16 first-class).\n if (n.text !== sel.text && n.label !== sel.text) return false;\n }\n if (sel.label !== undefined) {\n if (n.label !== sel.label && n.text !== sel.label) return false;\n }\n // At least one of testId/text/label must have been specified (checked at entry).\n return true;\n}\n\nfunction top3FromMatches(matches: A11yNode[]): NearMiss[] {\n return matches.slice(0, 3).map((n) => ({\n node: n,\n score: 1,\n reason: \"ambiguous match\",\n }));\n}\n\nfunction top3NearMisses(all: A11yNode[], sel: Selector): NearMiss[] {\n const scored: NearMiss[] = [];\n for (const n of all) {\n const s = scoreNearMiss(n, sel);\n if (s) scored.push(s);\n }\n return scored.sort((a, b) => b.score - a.score).slice(0, 3);\n}\n\nfunction scoreNearMiss(n: A11yNode, sel: Selector): NearMiss | null {\n const reasons: string[] = [];\n let best = 0;\n\n if (sel.testId !== undefined && n.testId) {\n const s = stringSim(sel.testId, n.testId);\n if (s > 0.4) {\n reasons.push(`testId close: \"${n.testId}\" vs \"${sel.testId}\" (sim ${s.toFixed(2)})`);\n best = Math.max(best, s);\n }\n }\n if (sel.text !== undefined) {\n for (const haystack of [n.text, n.label]) {\n if (haystack) {\n const s = stringSim(sel.text, haystack);\n if (s > 0.4) {\n reasons.push(`text close: \"${haystack}\" vs \"${sel.text}\" (sim ${s.toFixed(2)})`);\n best = Math.max(best, s);\n }\n }\n }\n }\n if (sel.label !== undefined) {\n for (const haystack of [n.label, n.text]) {\n if (haystack) {\n const s = stringSim(sel.label, haystack);\n if (s > 0.4) {\n reasons.push(`label close: \"${haystack}\" vs \"${sel.label}\" (sim ${s.toFixed(2)})`);\n best = Math.max(best, s);\n }\n }\n }\n }\n\n if (best === 0) return null;\n return { node: n, score: best, reason: reasons.join(\"; \") };\n}\n\n// Cheap similarity: 1 - normalized Levenshtein distance.\n// Good enough for ranking near misses; not a search engine.\nfunction stringSim(a: string, b: string): number {\n if (a === b) return 1;\n const maxLen = Math.max(a.length, b.length);\n if (maxLen === 0) return 1;\n const d = levenshtein(a, b);\n return 1 - d / maxLen;\n}\n\nfunction levenshtein(a: string, b: string): number {\n const m = a.length;\n const n = b.length;\n if (m === 0) return n;\n if (n === 0) return m;\n const prev = new Array<number>(n + 1);\n for (let j = 0; j <= n; j++) prev[j] = j;\n for (let i = 1; i <= m; i++) {\n let prevDiag = prev[0]!;\n prev[0] = i;\n for (let j = 1; j <= n; j++) {\n const tmp = prev[j]!;\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n prev[j] = Math.min(prev[j]! + 1, prev[j - 1]! + 1, prevDiag + cost);\n prevDiag = tmp;\n }\n }\n return prev[n]!;\n}\n\nfunction boundsCenter(b: Bounds | undefined): { x: number; y: number } | undefined {\n if (!b) return undefined;\n return { x: b.x + b.width / 2, y: b.y + b.height / 2 };\n}\n\nfunction dist(a: { x: number; y: number } | undefined, b: { x: number; y: number } | undefined): number {\n if (!a || !b) return Infinity;\n const dx = a.x - b.x;\n const dy = a.y - b.y;\n return Math.sqrt(dx * dx + dy * dy);\n}\n","// TreeInspector — turns a raw a11y tree from any Driver into something an\n// LLM can scan in seconds rather than minutes.\n//\n// Three responsibilities, deliberately kept in one class so MCP tools don't\n// have to wire three services for the common path:\n// 1. compactTree(root) — drop layout-only wrappers, strip noise attrs.\n// 2. indexDuplicates(root) — add `@N` suffix to testIds that occur more\n// than once, so selectors resolve unambiguously.\n// 3. nodePath(root, target) — stable string path through the kept tree,\n// for \"where in the screen is this?\" answers.\n//\n// D-16: nodes with only `text` or only `label` (no testId) are KEPT. They are\n// not layout wrappers; they are real targets for `getByText`/`getByLabel`.\n\nimport type { A11yNode, A11yTreeMode } from \"./types.ts\";\n\n// ---- compaction ----------------------------------------------------------\n\nconst INTERACTIVE_ROLE_HINTS = [\n \"button\",\n \"textfield\",\n \"securefield\",\n \"secureinput\",\n \"input\",\n \"link\",\n \"switch\",\n \"slider\",\n \"picker\",\n \"checkbox\",\n \"tab\",\n \"menuitem\",\n];\n\nfunction isInteractiveRole(role: string | undefined): boolean {\n if (!role) return false;\n const r = role.toLowerCase();\n return INTERACTIVE_ROLE_HINTS.some((hint) => r.includes(hint));\n}\n\nfunction isNoise(n: A11yNode): boolean {\n // D-16: a node is \"noise\" only if it has NO identifying attributes AND\n // is not interactive. The instant any of testId/text/label exist, the node\n // becomes a real selectable target and must be preserved.\n return !n.testId && !n.text && !n.label && !isInteractiveRole(n.role);\n}\n\nfunction stripAttrs(n: A11yNode, children: A11yNode[]): A11yNode {\n const out: A11yNode = { children };\n if (n.testId) out.testId = n.testId;\n if (n.text) out.text = n.text;\n if (n.label) out.label = n.label;\n if (isInteractiveRole(n.role)) out.role = n.role;\n return out;\n}\n\ninterface CompactResult {\n totalSeen: number;\n kept: A11yNode[];\n}\n\nfunction compactSubtree(n: A11yNode): CompactResult {\n let totalSeen = 1;\n const newChildren: A11yNode[] = [];\n for (const c of n.children) {\n const r = compactSubtree(c);\n totalSeen += r.totalSeen;\n newChildren.push(...r.kept);\n }\n if (isNoise(n)) {\n return { totalSeen, kept: newChildren };\n }\n return { totalSeen, kept: [stripAttrs(n, newChildren)] };\n}\n\nfunction countNodes(n: A11yNode): number {\n let total = 1;\n for (const c of n.children) total += countNodes(c);\n return total;\n}\n\n// ---- duplicate-indexing -------------------------------------------------\n\nfunction collectTestIds(n: A11yNode, counts: Map<string, number>): void {\n if (n.testId) counts.set(n.testId, (counts.get(n.testId) ?? 0) + 1);\n for (const c of n.children) collectTestIds(c, counts);\n}\n\nfunction applyIndex(n: A11yNode, counts: Map<string, number>, running: Map<string, number>): void {\n if (n.testId && (counts.get(n.testId) ?? 0) > 1) {\n const idx = running.get(n.testId) ?? 0;\n running.set(n.testId, idx + 1);\n n.testId = `${n.testId}@${idx}`;\n }\n for (const c of n.children) applyIndex(c, counts, running);\n}\n\n/**\n * Mutates `tree` in place: duplicated testIds get `@N` suffix in DFS order.\n * After indexing, no two visible nodes share a testId.\n * Use AFTER compaction (testIds dropped during compaction won't get @N).\n */\nexport function indexDuplicates(tree: A11yNode): A11yNode {\n const counts = new Map<string, number>();\n collectTestIds(tree, counts);\n applyIndex(tree, counts, new Map());\n return tree;\n}\n\n// ---- main compact entry -------------------------------------------------\n\nexport class TreeInspector {\n /**\n * D-16-aware compaction:\n * - drop wrappers with no identifying signal,\n * - strip layout-only attributes (bounds, enabled, focused, non-interactive role),\n * - keep text-only and label-only leaves,\n * - report `_meta` at the root.\n */\n compactTree(root: A11yNode): A11yNode {\n const result = compactSubtree(root);\n const out: A11yNode = result.kept.length === 1 ? result.kept[0]! : { children: result.kept };\n const shown = countNodes(out);\n out._meta = { totalNodes: result.totalSeen, shown, mode: \"compact\" };\n return out;\n }\n\n /**\n * Convenience: compact + index duplicates. The shape most MCP-tools want.\n */\n compactWithIds(root: A11yNode): A11yNode {\n return indexDuplicates(this.compactTree(root));\n }\n\n /**\n * Annotate the raw tree as `full` (carries _meta for symmetry, no shape\n * changes). Useful for MCP tools whose only choice is compact vs full.\n */\n withMode(root: A11yNode, mode: A11yTreeMode): A11yNode {\n if (mode === \"compact\") return this.compactWithIds(root);\n const total = countNodes(root);\n return { ...root, _meta: { totalNodes: total, shown: total, mode: \"full\" } };\n }\n\n /**\n * DFS path from root to `target`, encoded as \"child-index/child-index/...\".\n * Returns null if target is not part of the tree (by reference equality).\n */\n nodePath(root: A11yNode, target: A11yNode): string | null {\n if (root === target) return \"\";\n for (let i = 0; i < root.children.length; i++) {\n const child = root.children[i]!;\n const sub = this.nodePath(child, target);\n if (sub !== null) return sub.length === 0 ? String(i) : `${i}/${sub}`;\n }\n return null;\n }\n}\n","import { Value } from './value';\n\nexport class ArrayValue implements Value {\n private readonly elements: Value[];\n\n constructor(sizeOrElements: number | Value[] | ArrayValue) {\n if (typeof sizeOrElements === 'number') {\n this.elements = new Array(sizeOrElements).fill(undefined as any);\n } else if (Array.isArray(sizeOrElements)) {\n // Клонируем массив (но НЕ значения)\n this.elements = [...sizeOrElements];\n } else {\n // Клонируем другой ArrayValue\n this.elements = [...sizeOrElements.elements];\n }\n }\n\n get(index: number): Value {\n return this.elements[index];\n }\n\n set(index: number, value: Value): void {\n this.elements[index] = value;\n }\n\n asNumber(): number {\n throw new Error('Cannot cast array to number');\n }\n\n clone(): ArrayValue {\n // Глубокое копирование элементов\n return new ArrayValue(this.elements.map((e) => e.clone()));\n }\n\n asString(): string {\n return `[${this.elements.map((e) => e.asString()).join(', ')}]`;\n }\n\n toString(): string {\n return this.asString();\n }\n}\n","import { Value } from './value';\n\nexport class NumberValue implements Value {\n static ZERO = new NumberValue(0);\n public readonly value: number;\n\n constructor(value: number | boolean) {\n if (typeof value === 'boolean') {\n this.value = value ? 1 : 0;\n } else {\n this.value = value;\n }\n }\n\n clone(): Value {\n return new NumberValue(this.value);\n }\n\n asNumber(): number {\n return this.value;\n }\n\n asString(): string {\n return this.value.toString();\n }\n\n toString(): string {\n return this.asString();\n }\n}\n","import { Func } from './func';\nimport { NumberValue } from './number-value';\nimport { Value } from './value';\n\nexport class Functions {\n private static readonly functions: Map<string, Func> = new Map([\n // prettier-ignore\n ['cos', {execute(...args: Value[]): Value {if (args.length !== 1) {throw new Error('One argument expected');}return new NumberValue(Math.cos(args[0].asNumber()));}}],\n // prettier-ignore\n ['echo', {execute(...args: Value[]): Value {for (const arg of args) {console.log(arg.asString());}return NumberValue.ZERO;}}],\n // prettier-ignore\n ['highlightBlock', {execute(...args: Value[]): Value {return NumberValue.ZERO;}}],\n // prettier-ignore\n ['setPage', {execute(...args: Value[]): Value {return NumberValue.ZERO;}}],\n // prettier-ignore\n ['afterBlock', {execute(...args: Value[]): Value {return NumberValue.ZERO;}}],\n // prettier-ignore\n ['open', {execute(...args: Value[]): Value {return NumberValue.ZERO;}}],\n // prettier-ignore\n ['String', {execute(...args: Value[]): Value {return NumberValue.ZERO;}}],\n ]);\n\n public static isExists(key: string): boolean {\n return this.functions.has(key);\n }\n\n public static get(key: string): Func {\n const f = this.functions.get(key);\n if (!f) {\n throw new TypeError(`Unknown function: ${key}`);\n }\n return f;\n }\n\n public static set(name: string, value: Func): void {\n this.functions.set(name, value);\n }\n}\n","import { Value } from './value';\n\nexport class ObjectValue implements Value {\n private readonly properties: Map<string, Value>;\n\n constructor(properties: Map<string, Value> = new Map()) {\n this.properties = properties;\n }\n\n get(key: string): Value | undefined {\n return this.properties.get(key);\n }\n\n set(key: string, value: Value): void {\n this.properties.set(key, value);\n }\n\n asNumber(): number {\n return this.properties.size;\n }\n\n asString(): string {\n const entries = Array.from(this.properties.entries())\n .map(([key, value]) => `${key}: ${value.asString()}`)\n .join(', ');\n return `{${entries}}`;\n }\n\n clone(): Value {\n const clonedProperties = new Map<string, Value>();\n this.properties.forEach((value, key) => {\n clonedProperties.set(key, value.clone());\n });\n return new ObjectValue(clonedProperties);\n }\n\n getProperties(): Map<string, Value> {\n return this.properties;\n }\n}\n","import { Value } from './value';\n\nexport class StringValue implements Value {\n private readonly value: string;\n\n constructor(value: string) {\n this.value = value;\n }\n\n clone(): Value {\n return new StringValue(this.value);\n }\n asNumber(): number {\n try {\n return parseFloat(this.value);\n } catch (error) {\n return 0;\n }\n }\n\n asString(): string {\n return this.value;\n }\n\n toString(): string {\n return this.asString();\n }\n}\n","import { ReturnStatement, Statement } from '../ast';\nimport { Func } from './func';\nimport { NumberValue } from './number-value';\nimport { Value } from './value';\n\nexport class UserDefineFunction implements Func {\n private readonly argNames: string[];\n private readonly body: Statement;\n constructor(argNames: string[], body: Statement) {\n this.argNames = argNames;\n this.body = body;\n }\n\n public getArgsCount() {\n return this.argNames.length;\n }\n\n getArgsName(index: number): string {\n if (index < 0 || index >= this.argNames.length) {\n return '';\n }\n return this.argNames[index];\n }\n execute(...args: Value[]): Value {\n try {\n this.body.execute();\n return NumberValue.ZERO;\n } catch (e) {\n if (e instanceof ReturnStatement) {\n return e.getResult();\n }\n throw e;\n }\n }\n}\n","import { NumberValue } from './number-value';\nimport { Value } from './value';\n\nexport class Variables {\n private static stack: Map<string, Value>[] = [];\n private static variables: Map<string, Value> = new Map([\n ['PI', new NumberValue(Math.PI)],\n ['E', new NumberValue(Math.E)],\n ]);\n\n public static push(): void {\n const clone = new Map<string, Value>([]);\n for (const [key, value] of this.variables.entries()) {\n clone.set(key, value);\n }\n this.stack.push(clone);\n }\n\n public static pop(): void {\n const v = this.stack.pop();\n if (!v) {\n throw new Error('Variables stack undefined');\n }\n this.variables = v;\n }\n\n public static isExists(key: string): boolean {\n return this.variables.has(key);\n }\n\n public static get(key: string): Value {\n return this.variables.get(key) || NumberValue.ZERO;\n }\n\n public static set(name: string, value: Value): void {\n this.variables.set(name, value);\n }\n}\n","import { ArrayValue, Value, Variables } from '../lib';\nimport { Token } from '../token';\nimport { Expression } from './expression';\n\nexport class ArrayAccessExpression implements Expression {\n private readonly variable: string;\n private readonly indexes: Expression[];\n public readonly token: Token;\n\n constructor(variable: string, indexes: Expression[], token: Token) {\n this.variable = variable;\n this.indexes = indexes;\n this.token = token;\n }\n\n eval(): Value {\n const i = this.lastIndex();\n const arr = this.getArray();\n return arr.get(i);\n }\n\n public lastIndex() {\n return this.index(this.indexes.length - 1);\n }\n\n index(index: number) {\n return this.indexes[index].eval().asNumber();\n }\n\n public getArray() {\n let arr: ArrayValue = this.consumeArray(Variables.get(this.variable));\n const last: number = this.indexes.length - 1;\n for (let i = 0; i < last; i++) {\n arr = this.consumeArray(arr.get(this.index(i)));\n }\n return arr;\n }\n\n private consumeArray(value: Value): ArrayValue {\n if (value instanceof ArrayValue) {\n return value as ArrayValue;\n }\n throw new Error('Array expected');\n }\n\n toString() {\n return `${this.variable + this.indexes}`;\n }\n}\n","import { Token } from '../token';\nimport { ArrayAccessExpression } from './array-access-expression';\nimport { Expression } from './expression';\nimport { Statement } from './statement';\n\nexport class ArrayAssignmentStatement implements Statement {\n private readonly array: ArrayAccessExpression;\n private readonly expression: Expression;\n public readonly token: Token;\n constructor(array: ArrayAccessExpression, expression: Expression, token: Token) {\n this.array = array;\n this.expression = expression;\n this.token = token;\n }\n execute() {\n this.array.getArray().set(this.array.lastIndex(), this.expression.eval());\n }\n\n toString() {\n return `${this.array} = ${this.expression}`;\n }\n}\n","import { ArrayValue, Value } from '../lib';\nimport { Token } from '../token';\nimport { Expression } from './expression';\n\nexport class ArrayExpression implements Expression {\n public readonly elements: Expression[];\n public readonly token: Token;\n\n constructor(argument: Expression[], token: Token) {\n this.elements = argument;\n this.token = token;\n }\n\n eval(): Value {\n const values = this.elements.map((el) => el.eval());\n return new ArrayValue(values);\n }\n\n toString() {\n return `${this.elements.toString()}`;\n }\n}\n","import { Variables } from '../lib/variables';\nimport { Token } from '../token';\nimport { Expression } from './expression';\nimport { Statement } from './statement';\n\nexport class AssignmentStatement implements Statement {\n variable: string;\n expression: Expression;\n public readonly token: Token;\n constructor(variable: string, expression: Expression, token: Token) {\n this.variable = variable;\n this.expression = expression;\n this.token = token;\n }\n execute() {\n const result = this.expression.eval();\n Variables.set(this.variable, result);\n }\n\n toString() {\n return `${this.variable} = ${this.expression}`;\n }\n}\n","import { ArrayValue, NumberValue, StringValue, Value } from '../lib';\nimport { Token } from '../token';\nimport { Expression } from './expression';\n\nexport class BinaryExpression implements Expression {\n public readonly expr1: Expression;\n public readonly expr2: Expression;\n public readonly operation: string;\n public readonly token: Token;\n\n constructor(operator: string, expr1: Expression, expr2: Expression, token: Token) {\n this.expr1 = expr1;\n this.expr2 = expr2;\n this.operation = operator;\n this.token = token;\n }\n\n eval(): Value {\n const value1 = this.expr1.eval();\n if (value1 instanceof StringValue || value1 instanceof ArrayValue) {\n const string1 = value1.asString();\n const string2 = this.expr2.eval().asString();\n switch (this.operation) {\n case '+':\n return new StringValue(string1 + string2);\n default:\n throw new Error('Unrecognized operator for string value');\n }\n }\n\n const number1 = this.expr1.eval().asNumber();\n const number2 = this.expr2.eval().asNumber();\n switch (this.operation) {\n case '-':\n return new NumberValue(number1 - number2);\n case '+':\n return new NumberValue(number1 + number2);\n case '/':\n return new NumberValue(number1 / number2);\n case '*':\n default:\n return new NumberValue(number1 * number2);\n }\n }\n\n toString() {\n return `${this.expr1} ${this.operation} ${this.expr2}`;\n }\n}\n","import { Token } from '../token';\nimport { Statement } from './statement';\n\nexport class BlockStatement implements Statement {\n public readonly statements: Statement[] = [];\n public readonly token: Token;\n constructor(token: Token) {\n this.token = token;\n }\n\n add(statement: Statement) {\n this.statements.push(statement);\n }\n execute() {\n for (const statement of this.statements) {\n statement.execute();\n }\n }\n\n toString() {\n return `${this.statements.join('\\n')}`;\n }\n}\n","import { Token } from '../token';\nimport { Statement } from './statement';\n\nexport class BreakStatement extends Error implements Statement {\n public readonly token: Token;\n constructor(token: Token) {\n super('BreakStatement');\n this.token = token;\n }\n execute() {\n throw this;\n }\n\n override toString() {\n return `break`;\n }\n}\n","import { NumberValue, StringValue, Value } from '../lib';\nimport { Token } from '../token';\nimport { Expression } from './expression';\n\nexport enum Operator {\n PLUS = '+',\n MINUS = '-',\n MULTIPLY = '*',\n DIVIDE = '/',\n\n EQ = '==',\n NEQ = '!=',\n\n LT = '<',\n LTE = '<=',\n GT = '>',\n GTE = '>=',\n\n AND = '&&',\n OR = '||',\n}\nexport function getOperatorName(value: Operator) {\n for (const [key, val] of Object.entries(Operator)) {\n if (val === value) {\n return key;\n }\n }\n return 'EQ';\n}\n\nexport class ConditionalExpression implements Expression {\n public readonly expr1: Expression;\n public readonly expr2: Expression;\n public readonly operation: Operator;\n public readonly token: Token;\n\n constructor(operator: Operator, expr1: Expression, expr2: Expression, token: Token) {\n this.expr1 = expr1;\n this.expr2 = expr2;\n this.operation = operator;\n this.token = token;\n }\n\n eval(): Value {\n const value1 = this.expr1.eval();\n const value2 = this.expr2.eval();\n\n let number1: number;\n let number2: number;\n if (value1 instanceof StringValue) {\n number1 = number1 = value1.asString().localeCompare(value2.asString());\n number2 = 0;\n } else {\n number1 = this.expr1.eval().asNumber();\n number2 = this.expr2.eval().asNumber();\n }\n\n let result;\n switch (this.operation) {\n case Operator.LT:\n result = number1 < number2;\n break;\n case Operator.LTE:\n result = number1 <= number2;\n break;\n case Operator.GT:\n result = number1 > number2;\n break;\n case Operator.GTE:\n result = number1 >= number2;\n break;\n case Operator.NEQ:\n result = number1 != number2;\n break;\n case Operator.AND:\n result = number1 != 0 && number2 != 0;\n break;\n case Operator.OR:\n result = number1 != 0 || number2 != 0;\n break;\n case Operator.EQ:\n default:\n result = number1 === number2;\n }\n return new NumberValue(result);\n }\n\n toString() {\n return `${this.expr1} ${this.operation} ${this.expr2}`;\n }\n}\n","import { Token } from '../token';\nimport { Statement } from './statement';\n\nexport class ContinueStatement extends Error implements Statement {\n public readonly token: Token;\n constructor(token: Token) {\n super('ContinueStatement');\n this.token = token;\n }\n execute() {\n throw this;\n }\n\n override toString() {\n return `continue`;\n }\n}\n","import { Token } from '../token';\nimport { BreakStatement } from './break-statement';\nimport { ContinueStatement } from './continue-statement';\nimport { Expression } from './expression';\nimport { Statement } from './statement';\n\nexport class DoWhileStatement implements Statement {\n private readonly condition: Expression;\n private readonly statement: Statement;\n public readonly token: Token;\n\n constructor(expression: Expression, statement: Statement, token: Token) {\n this.condition = expression;\n this.statement = statement;\n this.token = token;\n }\n\n execute() {\n do {\n try {\n this.statement.execute();\n } catch (e) {\n if (e instanceof BreakStatement) {\n break;\n } else if (e instanceof ContinueStatement) {\n // continue;\n } else {\n throw e;\n }\n }\n } while (this.condition.eval().asNumber() != 0);\n }\n\n toString() {\n return `do {\\n${this.statement}\\n}\\nwhile (${this.condition})\\n`;\n }\n}\n","import { Token } from '../token';\nimport { BreakStatement } from './break-statement';\nimport { ContinueStatement } from './continue-statement';\nimport { Expression } from './expression';\nimport { Statement } from './statement';\n\nexport class ForStatement implements Statement {\n public readonly initialization: Statement;\n public readonly termination: Expression;\n public readonly increment: Statement;\n public readonly block: Statement;\n public readonly token: Token;\n\n constructor(\n initialization: Statement,\n termination: Expression,\n increment: Statement,\n block: Statement,\n token: Token,\n ) {\n this.initialization = initialization;\n this.termination = termination;\n this.increment = increment;\n this.block = block;\n this.token = token;\n }\n\n execute() {\n for (this.initialization.execute(); this.termination.eval().asNumber() != 0; this.increment.execute()) {\n try {\n this.block.execute();\n } catch (e) {\n if (e instanceof BreakStatement) {\n break;\n } else if (e instanceof ContinueStatement) {\n // continue;\n } else {\n throw e;\n }\n }\n }\n }\n\n toString() {\n return `for (${this.initialization}; ${this.termination}; ${this.increment})\\n{\\n${this.block}\\n}`;\n }\n}\n","import { Functions } from '../lib';\nimport { UserDefineFunction } from '../lib/user-define-function';\nimport { Token } from '../token';\nimport { Statement } from './statement';\n\nexport class FunctionDefineStatement implements Statement {\n public readonly name: string;\n public readonly argNames: string[];\n public readonly body: Statement;\n public readonly token: Token;\n constructor(name: string, argNames: string[], body: Statement, token: Token) {\n this.name = name;\n this.argNames = argNames;\n this.body = body;\n this.token = token;\n }\n execute() {\n Functions.set(this.name, new UserDefineFunction(this.argNames, this.body));\n }\n\n toString() {\n const argsString = this.argNames.map((arg) => arg.toString()).join(', ');\n return `function ${this.name}(${argsString})`;\n }\n}\n","import { Token } from '../token';\nimport { FunctionalExpression } from './functional-expression';\nimport { Statement } from './statement';\n\nexport class FunctionStatement implements Statement {\n functionalExpression: FunctionalExpression;\n public readonly token: Token;\n constructor(func: FunctionalExpression, token: Token) {\n this.functionalExpression = func;\n this.token = token;\n }\n execute() {\n this.functionalExpression.eval();\n }\n\n toString() {\n return `${this.functionalExpression.toString()}`;\n }\n}\n","import { Functions, UserDefineFunction, Value, Variables } from '../lib';\nimport { Token } from '../token';\nimport { Expression } from './expression';\n\nexport class FunctionalExpression implements Expression {\n public readonly name: string;\n public readonly arguments: Expression[];\n public readonly token: Token;\n\n constructor(name: string, argument: Expression[], token: Token) {\n this.name = name;\n this.arguments = argument;\n this.token = token;\n }\n\n addArgument(argument: Expression) {\n return this.arguments.push(argument);\n }\n\n eval(): Value {\n const values: Value[] = this.arguments.map((v) => v.eval());\n const size = values.length;\n\n const func = Functions.get(this.name);\n if (func instanceof UserDefineFunction) {\n const userFunction = func as UserDefineFunction;\n if (values.length !== userFunction.getArgsCount()) {\n throw new Error(`Invalid argument count for function ${this.name}: expected ${size}`);\n }\n Variables.push();\n for (let i = 0; i < size; i++) {\n Variables.set(userFunction.getArgsName(i), values[i]);\n }\n const result = userFunction.execute(...values);\n Variables.pop();\n return result;\n }\n\n return func.execute(...values);\n }\n\n toString() {\n const argsString = this.arguments.map((arg) => arg.toString()).join(', ');\n return `${this.name}(${argsString})`;\n }\n}\n","import { Token } from '../token';\nimport { Expression } from './expression';\nimport { Statement } from './statement';\n\nexport class IfStatement implements Statement {\n public readonly expression: Expression;\n public readonly ifStatement: Statement;\n public readonly elseStatement: Statement | null;\n public readonly token: Token;\n\n constructor(expression: Expression, ifStatement: Statement, elseStatement: Statement | null, token: Token) {\n this.expression = expression;\n this.ifStatement = ifStatement;\n this.elseStatement = elseStatement;\n this.token = token;\n }\n\n execute() {\n const result = this.expression.eval().asNumber();\n if (result != 0) {\n this.ifStatement.execute();\n } else if (this.elseStatement != null) {\n this.elseStatement.execute();\n }\n }\n\n toString() {\n let result = `if ${this.expression} ${this.ifStatement}`;\n if (this.elseStatement != null) {\n result += ` else ${this.elseStatement}`;\n }\n return result.toString();\n }\n}\n","import { NumberValue } from '../lib/number-value';\nimport { Value } from '../lib/value';\nimport { Variables } from '../lib/variables';\nimport { Token } from '../token';\nimport { Expression } from './expression';\nimport { VariableExpression } from './variable-expression';\n\nexport enum IncrementType {\n PREFIX_INCREMENT, // ++i\n PREFIX_DECREMENT, // --i\n POSTFIX_INCREMENT, // i++\n POSTFIX_DECREMENT, // i--\n}\n\nexport class IncrementExpression implements Expression {\n private variable: VariableExpression;\n private readonly type: IncrementType;\n public readonly token: Token;\n\n constructor(variable: VariableExpression, type: IncrementType, token: Token) {\n this.variable = variable;\n this.type = type;\n this.token = token;\n }\n\n eval(): Value {\n const varName = this.variable.getName();\n const currentValue = Variables.get(varName);\n\n if (!(currentValue instanceof NumberValue)) {\n throw new Error(`Cannot increment/decrement non-numeric value`);\n }\n\n const currentNumber = currentValue.asNumber();\n let newNumber: number;\n\n switch (this.type) {\n case IncrementType.PREFIX_INCREMENT:\n newNumber = currentNumber + 1;\n Variables.set(varName, new NumberValue(newNumber));\n return new NumberValue(newNumber);\n\n case IncrementType.PREFIX_DECREMENT:\n newNumber = currentNumber - 1;\n Variables.set(varName, new NumberValue(newNumber));\n return new NumberValue(newNumber);\n\n case IncrementType.POSTFIX_INCREMENT:\n Variables.set(varName, new NumberValue(currentNumber + 1));\n return new NumberValue(currentNumber);\n\n case IncrementType.POSTFIX_DECREMENT:\n Variables.set(varName, new NumberValue(currentNumber - 1));\n return new NumberValue(currentNumber);\n }\n }\n}\n","import { Token } from '../token';\nimport { IncrementExpression } from './increment-expression';\nimport { Statement } from './statement';\n\nexport class IncrementStatement implements Statement {\n private expression: IncrementExpression;\n public readonly token: Token;\n\n constructor(expression: IncrementExpression, token: Token) {\n this.expression = expression;\n this.token = token;\n }\n\n execute(): void {\n this.expression.eval();\n }\n}\n","import { Token } from '../token';\nimport { Statement } from './statement';\n\nexport class MetaBlockStatement implements Statement {\n public readonly name: string;\n public readonly argNames: string[];\n public readonly body: Statement;\n public readonly token: Token;\n constructor(name: string, argNames: string[], body: Statement, token: Token) {\n this.name = name;\n this.argNames = argNames;\n this.body = body;\n this.token = token;\n }\n execute() {\n // just decorator\n }\n\n toString() {\n const argsString = this.argNames.map((arg) => arg.toString()).join(', ');\n return `//@${this.name}(${argsString})\\n${this.body}\\n//@end-${this.name}`;\n }\n}\n","import { ObjectValue, Value } from '../lib';\nimport { Token } from '../token';\nimport { Expression } from './expression';\n\nexport class ObjectExpression implements Expression {\n public readonly properties: Map<string, Expression>;\n public readonly token: Token;\n\n constructor(properties: Map<string, Expression> = new Map(), token: Token) {\n this.properties = properties;\n this.token = token;\n }\n\n eval(): Value {\n const evaluatedProperties = new Map<string, Value>();\n this.properties.forEach((expression, key) => {\n evaluatedProperties.set(key, expression.eval());\n });\n return new ObjectValue(evaluatedProperties);\n }\n\n toString() {\n const entries = Array.from(this.properties.entries())\n .map(([key, value]) => `${key}: ${value.toString()}`)\n .join(', ');\n return `{${entries}}`;\n }\n}\n","import { Token } from '../token';\nimport { Expression } from './expression';\nimport { Statement } from './statement';\n\nexport class PrintStatement implements Statement {\n public readonly expression: Expression;\n public readonly token: Token;\n constructor(expression: Expression, token: Token) {\n this.expression = expression;\n this.token = token;\n }\n execute() {\n const result = this.expression.eval().asString();\n console.log(`${result}`);\n }\n\n toString() {\n return `print ${this.expression}`;\n }\n}\n","import { Value } from '../lib';\nimport { Token } from '../token';\nimport { Expression } from './expression';\nimport { Statement } from './statement';\n\nexport class ReturnStatement extends Error implements Statement {\n private readonly expression: Expression;\n private result?: Value;\n public readonly token: Token;\n constructor(expression: Expression, token: Token) {\n super('ContinueStatement');\n this.expression = expression;\n this.token = token;\n }\n\n public getResult(): Value {\n if (!this.result) {\n throw new Error('Not execute ReturnStatement');\n }\n return this.result;\n }\n execute() {\n this.result = this.expression.eval();\n throw this;\n }\n\n override toString() {\n return `return`;\n }\n}\n","import { NumberValue, Value } from '../lib';\nimport { Token } from '../token';\nimport { Expression } from './expression';\n\nexport class UnaryExpression implements Expression {\n private readonly expr1: Expression;\n private readonly operation: string;\n public readonly token: Token;\n\n constructor(operator: string, expr1: Expression, token: Token) {\n this.operation = operator;\n this.expr1 = expr1;\n this.token = token;\n }\n\n eval(): Value {\n switch (this.operation) {\n case '-':\n return new NumberValue(-this.expr1.eval().asNumber());\n case '+':\n default:\n return new NumberValue(this.expr1.eval().asNumber());\n }\n }\n\n toString() {\n return `${this.operation}${this.expr1}`;\n }\n}\n","export enum TokenType {\n NUMBER,\n WORD,\n TEXT,\n\n VAR,\n\n // keyword\n PRINT,\n IF,\n ELSE,\n WHILE,\n FOR,\n DO,\n BREAK,\n CONTINUE,\n FUNCTION,\n RETURN,\n\n PLUS,\n PLUSPLUS,\n MINUS,\n MINUSMINUS,\n STAR,\n SLASH,\n EQ,\n EQEQ,\n EXCL,\n EXCLEQ,\n LT,\n LTEQ,\n GT,\n GTEQ,\n\n BAR, // |\n BARBAR, // ||\n AMP, // &\n AMPAMP, // &&\n\n LPAREN, // (\n RPAREN, // )\n LBRACE, // {\n RBRACE, // }\n LBRACKET, // [\n RBRACKET, // ]\n COMMA, // ,\n COLON, // :\n SEMICOLON, // ;\n\n META_BLOCK,\n CLOSE_META_BLOCK,\n\n EOF,\n}\n","import { NumberValue, StringValue, Value } from '../lib';\nimport { Token } from '../token';\nimport { TokenType } from '../token-type';\nimport { Expression } from './expression';\n\nexport class ValueExpression implements Expression {\n public readonly value: Value;\n public readonly token: Token;\n\n constructor(value: string, token: Token) {\n this.token = token;\n\n if (token.getType() === TokenType.NUMBER) {\n this.value = new NumberValue(parseFloat(value));\n return;\n }\n if (token.getType() === TokenType.TEXT) {\n this.value = new StringValue(value);\n return;\n }\n\n throw new Error(`Unrecognized value. ${token}`);\n }\n\n eval(): Value {\n return this.value;\n }\n\n toString() {\n return `${this.value.asString()}`;\n }\n}\n","import { Value } from './value';\n\nexport class UndefinedValue implements Value {\n static UNDEFINED = new UndefinedValue();\n\n clone(): Value {\n return UndefinedValue.UNDEFINED;\n }\n\n asNumber(): number {\n return NaN;\n }\n\n asString(): string {\n return 'undefined';\n }\n\n toString(): string {\n return this.asString();\n }\n}\n","import { UndefinedValue } from '../lib/undefined-value';\nimport { Variables } from '../lib/variables';\nimport { Token } from '../token';\nimport { Expression } from './expression';\nimport { Statement } from './statement';\n\nexport interface VarDeclarator {\n name: string;\n init: Expression | null;\n}\n\nexport class VarStatement implements Statement {\n declarators: VarDeclarator[];\n public readonly token: Token;\n\n constructor(declarators: VarDeclarator[], token: Token) {\n this.declarators = declarators;\n this.token = token;\n }\n\n execute() {\n for (const declarator of this.declarators) {\n if (declarator.init) {\n const value = declarator.init.eval();\n Variables.set(declarator.name, value);\n } else {\n Variables.set(declarator.name, UndefinedValue.UNDEFINED);\n }\n }\n }\n\n toString() {\n const decls = this.declarators.map((d) => (d.init ? `${d.name} = ${d.init}` : d.name)).join(', ');\n return `var ${decls}`;\n }\n}\n","import { Value, Variables } from '../lib';\nimport { Token } from '../token';\nimport { Expression } from './expression';\n\nexport class VariableExpression implements Expression {\n public readonly name: string;\n public readonly token: Token;\n\n constructor(name: string, token: Token) {\n this.name = name;\n this.token = token;\n }\n\n eval(): Value {\n if (!Variables.isExists(this.name)) {\n throw new Error(`Constant ${this.name} does not exist!`);\n }\n return Variables.get(this.name);\n }\n\n getName(): string {\n return this.name;\n }\n\n toString() {\n return `${this.name}`;\n }\n}\n","import { Token } from '../token';\nimport { BreakStatement } from './break-statement';\nimport { ContinueStatement } from './continue-statement';\nimport { Expression } from './expression';\nimport { Statement } from './statement';\n\nexport class WhileStatement implements Statement {\n private readonly condition: Expression;\n private readonly statement: Statement;\n public readonly token: Token;\n\n constructor(expression: Expression, statement: Statement, token: Token) {\n this.condition = expression;\n this.statement = statement;\n this.token = token;\n }\n\n execute() {\n while (this.condition.eval().asNumber() != 0) {\n try {\n this.statement.execute();\n } catch (e) {\n if (e instanceof BreakStatement) {\n break;\n } else if (e instanceof ContinueStatement) {\n // continue;\n } else {\n throw e;\n }\n }\n }\n }\n\n toString() {\n return `while (${this.condition})\\n{\\n${this.statement}\\n}`;\n }\n}\n","// ReturnSignal — typed exception used as internal control-flow for `return`\n// statements inside user-defined functions.\n//\n// Thrown by the executor when it visits a `ReturnStatement` node, caught\n// strictly at the user-function call boundary (callUserFunction in\n// ast-executor.ts). Must NEVER escape to user-facing error paths — if it\n// does, the linter (E2) was supposed to catch a stray return in a\n// test_/flow_ body. Linter is the contract; this is the runtime guard.\n\nimport type { DslValue } from \"./runtime.ts\";\n\nexport class ReturnSignal extends Error {\n constructor(public readonly value: DslValue | undefined) {\n super(\"ReturnSignal\");\n this.name = \"ReturnSignal\";\n }\n}\n","// UserFunctionResolver — map from DSL function name to its parsed\n// FunctionDefineStatement AST node.\n//\n// Populated at executor pre-pass: scan all top-level FunctionDefineStatements\n// across the entry scenario + helper files, register them here. Looked up\n// by FunctionalExpression eval before falling back to FunctionRegistry\n// (built-ins).\n//\n// Conflicts (duplicate name across files, or user-defined shadowing a\n// built-in) are caught by the linter (E8), not silently allowed here.\n\nimport { FunctionDefineStatement } from \"../../vendor/dsl/parser/ast/index.ts\";\n\nexport class UserFunctionResolver {\n private readonly fns = new Map<string, FunctionDefineStatement>();\n\n register(fnDef: FunctionDefineStatement, source?: string): void {\n if (this.fns.has(fnDef.name)) {\n const existing = this.fns.get(fnDef.name)!;\n const existingTok = (existing.token as { getLine?: () => number } | undefined)?.getLine?.();\n throw new Error(\n `Duplicate user function \"${fnDef.name}\"` +\n (existingTok ? ` (already defined at line ${existingTok}${source ? ` in ${source}` : \"\"})` : \"\"),\n );\n }\n this.fns.set(fnDef.name, fnDef);\n }\n\n get(name: string): FunctionDefineStatement | undefined {\n return this.fns.get(name);\n }\n\n has(name: string): boolean {\n return this.fns.has(name);\n }\n\n names(): string[] {\n return [...this.fns.keys()].sort();\n }\n}\n","// AstExecutor — async-generator that walks the vendor/dsl AST.\n//\n// D-17: each top-level statement is a yield-point. The runner pumps `.next()`:\n// - auto-mode: pump in a tight loop until the generator returns.\n// - step-mode: pump one statement, then await caller command.\n// - on throw: if `pauseOnFailure`, emit `paused: 'failure'` and remain\n// suspended on the failed node (consumer can call .next() to retry, or\n// .return() to abort).\n//\n// Stage 1 (user-defined functions):\n// - Pre-pass at run() scans top-level FunctionDefineStatements (entry +\n// helpers) and registers them in UserFunctionResolver.\n// - evalExpression is an async-generator so user-function calls inside\n// expression context propagate body step-events upward.\n// - callUserFunction: enterCall (maxCallDepth budget), pushScope, bind\n// args, runBlock body, catch ReturnSignal → return value, popScope,\n// exitCall.\n//\n// D-4 subset (strict):\n// Statements: FunctionDefineStatement, BlockStatement, AssignmentStatement,\n// IfStatement, FunctionStatement, ReturnStatement (helpers only)\n// Expressions: ValueExpression, VariableExpression, FunctionalExpression,\n// BinaryExpression, ArrayExpression\n// Anything else → UnsupportedAstNodeError (line/col preserved from token).\n\nimport {\n AssignmentStatement,\n ArrayExpression,\n BinaryExpression,\n BlockStatement,\n ForStatement,\n FunctionDefineStatement,\n FunctionStatement,\n FunctionalExpression,\n IfStatement,\n ReturnStatement,\n type Statement,\n type Expression,\n ValueExpression,\n VariableExpression,\n VarStatement,\n WhileStatement,\n} from \"../../vendor/dsl/parser/ast/index.ts\";\nimport { NumberValue, StringValue } from \"../../vendor/dsl/parser/lib/index.ts\";\nimport type { ExecutionEvent, ExecutionError, RunOptions, RunResult } from \"./execution-events.ts\";\nimport type { FunctionRegistry } from \"./function-registry.ts\";\nimport type { TestRuntime, DslValue } from \"./runtime.ts\";\nimport { ReturnSignal } from \"./return-signal.ts\";\nimport { UserFunctionResolver } from \"./user-function-resolver.ts\";\n\nexport class UnsupportedAstNodeError extends Error {\n constructor(nodeType: string, line: number, col: number) {\n super(`Unsupported AST node \"${nodeType}\" at ${line}:${col} — not allowed by MVP DSL subset (D-4)`);\n this.name = \"UnsupportedAstNodeError\";\n }\n}\n\nconst DEFAULT_MAX_CALL_DEPTH = 32;\n\nfunction isBlockMappable(name: string): boolean {\n return name.startsWith(\"test_\") || name.startsWith(\"flow_\");\n}\n\nexport class AstExecutor {\n constructor(private readonly registry: FunctionRegistry) {}\n\n /**\n * Run the test function `testName` from the parsed AST `program`.\n *\n * @param program entry scenario AST\n * @param testName name of the entry test_/flow_ function\n * @param runtime per-run state container\n * @param opts execution options (budgets, mode)\n * @param helpers optional helper-file ASTs (Stage 2); their top-level\n * FunctionDefineStatements are registered alongside\n * the entry's helpers in the user-function resolver\n */\n async *run(\n program: BlockStatement,\n testName: string,\n runtime: TestRuntime,\n opts: RunOptions,\n helpers?: BlockStatement[],\n ): AsyncGenerator<ExecutionEvent, RunResult> {\n const start = Date.now();\n let stepsExecuted = 0;\n\n // Pre-pass: register all top-level FunctionDefineStatements from entry +\n // helpers into a fresh per-run resolver. Per-run so concurrent runtimes\n // never see each other's helper namespaces.\n const userFns = new UserFunctionResolver();\n const programs: BlockStatement[] = [program, ...(helpers ?? [])];\n for (const p of programs) {\n for (const stmt of p.statements) {\n if (stmt instanceof FunctionDefineStatement) {\n userFns.register(stmt);\n }\n }\n }\n\n // Find the requested entry function.\n const entry = userFns.get(testName);\n if (!entry) {\n const error: ExecutionError = {\n message: `Test function \"${testName}\" not found in scenario AST`,\n };\n return { outcome: \"failed\", stepsExecuted, durationMs: Date.now() - start, error };\n }\n if (!(entry.body instanceof BlockStatement)) {\n const error: ExecutionError = {\n message: `Test \"${testName}\" body is not a BlockStatement (got ${(entry.body as { constructor: { name: string } }).constructor.name})`,\n };\n return { outcome: \"failed\", stepsExecuted, durationMs: Date.now() - start, error };\n }\n if (!isBlockMappable(testName)) {\n // Defensive: only test_/flow_ are valid entry points. Linter normally\n // refuses to run a non-test entry, but if a frontend calls run() with\n // an arbitrary name we surface a clear error.\n const error: ExecutionError = {\n message: `Entry function \"${testName}\" must start with test_ or flow_`,\n };\n return { outcome: \"failed\", stepsExecuted, durationMs: Date.now() - start, error };\n }\n\n const getSteps = () => stepsExecuted;\n const setSteps = (n: number) => {\n stepsExecuted = n;\n };\n\n // callStack: helper-fn names from outermost to innermost the executor is\n // currently inside. Entry test/flow body itself is NOT pushed — its\n // step-events ship with empty callStack to signal \"top-level\".\n const callStack: string[] = [];\n\n try {\n // Entry-body execution is plain runBlock — entry is itself a top-level\n // function; we do NOT route through callUserFunction (which would push\n // a scope and count enterCall). Vars in test/flow body live in the\n // root scope; recursion happens only via helper calls.\n yield* this.runBlock(entry.body, runtime, opts, getSteps, setSteps, start, userFns, callStack);\n return { outcome: \"completed\", stepsExecuted, durationMs: Date.now() - start };\n } catch (e: unknown) {\n const error = toExecutionError(e);\n return { outcome: \"failed\", stepsExecuted, durationMs: Date.now() - start, error };\n }\n }\n\n // ---- internals ---------------------------------------------------------\n\n private async *runBlock(\n block: BlockStatement,\n runtime: TestRuntime,\n opts: RunOptions,\n getSteps: () => number,\n setSteps: (n: number) => void,\n runStartMs: number,\n userFns: UserFunctionResolver,\n callStack: string[],\n ): AsyncGenerator<ExecutionEvent, void> {\n for (const stmt of block.statements) {\n yield* this.runStatement(stmt, runtime, opts, getSteps, setSteps, runStartMs, userFns, callStack);\n }\n }\n\n private async *runStatement(\n stmt: Statement,\n runtime: TestRuntime,\n opts: RunOptions,\n getSteps: () => number,\n setSteps: (n: number) => void,\n runStartMs: number,\n userFns: UserFunctionResolver,\n callStack: string[],\n ): AsyncGenerator<ExecutionEvent, void> {\n const { line, col } = locationOf(stmt);\n // Snapshot the stack at emit time — consumers see the call context as it\n // was when this step started, even if helpers push/pop concurrently.\n const stackSnap = callStack.length === 0 ? undefined : [...callStack];\n yield { kind: \"step-start\", node: stmt, line, col, callStack: stackSnap };\n\n let attempted = false;\n while (true) {\n this.checkBudgets(opts, getSteps(), runStartMs);\n\n try {\n yield* this.execStatement(stmt, runtime, opts, getSteps, setSteps, runStartMs, userFns, callStack);\n setSteps(getSteps() + 1);\n yield { kind: \"step-end\", node: stmt, line, col, ok: true, callStack: stackSnap };\n if (opts.mode === \"step\") yield { kind: \"paused\", reason: \"step\", line, col };\n return;\n } catch (e: unknown) {\n // ReturnSignal bubbles through runStatement to callUserFunction —\n // do NOT yield step-end:failure or pause for it. It's control flow.\n if (e instanceof ReturnSignal) throw e;\n\n const error = toExecutionError(e);\n yield { kind: \"step-end\", node: stmt, line, col, ok: false, error, callStack: stackSnap };\n\n if (!opts.pauseOnFailure) throw e;\n\n yield { kind: \"paused\", reason: \"failure\", line, col };\n attempted = true;\n if (attempted) continue;\n return;\n }\n }\n }\n\n private async *execStatement(\n stmt: Statement,\n runtime: TestRuntime,\n opts: RunOptions,\n getSteps: () => number,\n setSteps: (n: number) => void,\n runStartMs: number,\n userFns: UserFunctionResolver,\n callStack: string[],\n ): AsyncGenerator<ExecutionEvent, void> {\n if (stmt instanceof BlockStatement) {\n // Inline blocks (e.g. `if` bodies) execute their children through the\n // full runStatement path so step-events flow normally.\n yield* this.runBlock(stmt, runtime, opts, getSteps, setSteps, runStartMs, userFns, callStack);\n return;\n }\n\n if (stmt instanceof AssignmentStatement) {\n const value = yield* this.evalExpression(stmt.expression, runtime, opts, getSteps, setSteps, runStartMs, userFns, callStack);\n runtime.setVar(stmt.variable, value as DslValue);\n return;\n }\n\n if (stmt instanceof FunctionStatement) {\n yield* this.evalExpression(\n stmt.functionalExpression,\n runtime,\n opts,\n getSteps,\n setSteps,\n runStartMs,\n userFns,\n callStack,\n );\n return;\n }\n\n if (stmt instanceof IfStatement) {\n const cond = yield* this.evalExpression(stmt.expression, runtime, opts, getSteps, setSteps, runStartMs, userFns, callStack);\n if (isTruthy(cond)) {\n yield* this.execStatement(stmt.ifStatement, runtime, opts, getSteps, setSteps, runStartMs, userFns, callStack);\n } else if (stmt.elseStatement) {\n yield* this.execStatement(stmt.elseStatement, runtime, opts, getSteps, setSteps, runStartMs, userFns, callStack);\n }\n return;\n }\n\n if (stmt instanceof ReturnStatement) {\n // Vendor's ReturnStatement has `private readonly expression: Expression`.\n // Runtime JS doesn't enforce private — cast at the boundary.\n const expr = (stmt as unknown as { expression: Expression }).expression;\n const value = yield* this.evalExpression(expr, runtime, opts, getSteps, setSteps, runStartMs, userFns, callStack);\n throw new ReturnSignal(value as DslValue);\n }\n\n if (stmt instanceof FunctionDefineStatement) {\n const { line, col } = locationOf(stmt);\n throw new UnsupportedAstNodeError(\"nested FunctionDefineStatement\", line, col);\n }\n\n if (stmt instanceof VarStatement) {\n const { line, col } = locationOf(stmt);\n throw new UnsupportedAstNodeError(\"VarStatement (use bare assignment instead)\", line, col);\n }\n\n if (stmt instanceof ForStatement || stmt instanceof WhileStatement) {\n const { line, col } = locationOf(stmt);\n throw new UnsupportedAstNodeError(\n stmt instanceof ForStatement ? \"ForStatement\" : \"WhileStatement\",\n line,\n col,\n );\n }\n\n const { line, col } = locationOf(stmt);\n throw new UnsupportedAstNodeError(stmt.constructor.name, line, col);\n }\n\n private async *evalExpression(\n expr: Expression,\n runtime: TestRuntime,\n opts: RunOptions,\n getSteps: () => number,\n setSteps: (n: number) => void,\n runStartMs: number,\n userFns: UserFunctionResolver,\n callStack: string[],\n ): AsyncGenerator<ExecutionEvent, unknown> {\n if (expr instanceof ValueExpression) {\n const v = expr.value;\n // Dispatch via instanceof, never constructor.name — esbuild renames\n // class identifiers under bundle (`class _NumberValue {}`), so string\n // comparison would silently break only in the published artifact.\n if (v instanceof StringValue) return v.asString();\n if (v instanceof NumberValue) return v.asNumber();\n const { line, col } = locationOf(expr);\n throw new UnsupportedAstNodeError(\n `ValueExpression payload ${v.constructor.name}`,\n line,\n col,\n );\n }\n\n if (expr instanceof VariableExpression) {\n if (expr.name === \"true\") return true;\n if (expr.name === \"false\") return false;\n if (expr.name === \"null\") return null;\n return runtime.getVar(expr.name);\n }\n\n if (expr instanceof FunctionalExpression) {\n const args: unknown[] = [];\n for (const a of expr.arguments) {\n const v = yield* this.evalExpression(a, runtime, opts, getSteps, setSteps, runStartMs, userFns, callStack);\n args.push(v);\n }\n\n // User-defined function call?\n const userFn = userFns.get(expr.name);\n if (userFn) {\n return yield* this.callUserFunction(\n userFn,\n args as DslValue[],\n runtime,\n opts,\n getSteps,\n setSteps,\n runStartMs,\n userFns,\n callStack,\n );\n }\n\n // Built-in.\n const fn = this.registry.get(expr.name);\n if (!fn) {\n const { line, col } = locationOf(expr);\n throw new Error(`Unknown DSL function \"${expr.name}\" at ${line}:${col}`);\n }\n return await fn.invoke(runtime, ...args);\n }\n\n if (expr instanceof BinaryExpression) {\n const l = yield* this.evalExpression(expr.expr1, runtime, opts, getSteps, setSteps, runStartMs, userFns, callStack);\n const r = yield* this.evalExpression(expr.expr2, runtime, opts, getSteps, setSteps, runStartMs, userFns, callStack);\n return applyBinaryOp(expr.operation, l, r);\n }\n\n if (expr instanceof ArrayExpression) {\n const out: unknown[] = [];\n for (const e of expr.elements) {\n const v = yield* this.evalExpression(e, runtime, opts, getSteps, setSteps, runStartMs, userFns, callStack);\n out.push(v);\n }\n return out;\n }\n\n const { line, col } = locationOf(expr);\n throw new UnsupportedAstNodeError(`expression ${expr.constructor.name}`, line, col);\n }\n\n /**\n * Invoke a user-defined function. enterCall (maxCallDepth budget), pushScope,\n * bind args, runBlock body, catch ReturnSignal → return value, popScope,\n * exitCall. NOTE: does NOT increment stepsExecuted on the call itself —\n * `stepsExecuted == count of emitted step-events`, invariant preserved.\n */\n private async *callUserFunction(\n fnDef: FunctionDefineStatement,\n args: DslValue[],\n runtime: TestRuntime,\n opts: RunOptions,\n getSteps: () => number,\n setSteps: (n: number) => void,\n runStartMs: number,\n userFns: UserFunctionResolver,\n callStack: string[],\n ): AsyncGenerator<ExecutionEvent, unknown> {\n runtime.enterCall(opts.maxCallDepth ?? DEFAULT_MAX_CALL_DEPTH);\n callStack.push(fnDef.name);\n try {\n runtime.pushScope();\n try {\n for (let i = 0; i < fnDef.argNames.length; i++) {\n runtime.setVar(fnDef.argNames[i]!, args[i] ?? null);\n }\n if (!(fnDef.body instanceof BlockStatement)) {\n throw new Error(`User function \"${fnDef.name}\" body is not a BlockStatement`);\n }\n try {\n yield* this.runBlock(fnDef.body, runtime, opts, getSteps, setSteps, runStartMs, userFns, callStack);\n return null; // implicit `return null` if body had no explicit return\n } catch (e) {\n if (e instanceof ReturnSignal) return e.value ?? null;\n throw e;\n }\n } finally {\n runtime.popScope();\n }\n } finally {\n callStack.pop();\n runtime.exitCall();\n }\n }\n\n private checkBudgets(opts: RunOptions, steps: number, runStartMs: number): void {\n if (opts.maxSteps !== undefined && steps >= opts.maxSteps) {\n throw new Error(`maxSteps budget (${opts.maxSteps}) exhausted`);\n }\n if (opts.maxDurationMs !== undefined && Date.now() - runStartMs >= opts.maxDurationMs) {\n throw new Error(`maxDurationMs budget (${opts.maxDurationMs}ms) exhausted`);\n }\n }\n}\n\n// ---- helpers -------------------------------------------------------------\n\nfunction locationOf(node: Statement | Expression): { line: number; col: number } {\n const tok = (node as { token?: { getLine?: () => number; getColumn?: () => number } }).token;\n if (!tok) return { line: 0, col: 0 };\n return {\n line: tok.getLine ? tok.getLine() : 0,\n col: tok.getColumn ? tok.getColumn() : 0,\n };\n}\n\nfunction isTruthy(v: unknown): boolean {\n if (typeof v === \"number\") return v !== 0;\n if (typeof v === \"boolean\") return v;\n if (typeof v === \"string\") return v.length > 0;\n return v != null;\n}\n\nfunction applyBinaryOp(op: string, l: unknown, r: unknown): unknown {\n const ln = typeof l === \"number\" ? l : Number(l);\n const rn = typeof r === \"number\" ? r : Number(r);\n switch (op) {\n case \"+\":\n if (typeof l === \"string\" || typeof r === \"string\") return String(l) + String(r);\n return ln + rn;\n case \"-\":\n return ln - rn;\n case \"*\":\n return ln * rn;\n case \"/\":\n return ln / rn;\n case \"==\":\n return l === r || (Number.isFinite(ln) && Number.isFinite(rn) && ln === rn);\n case \"!=\":\n return !(l === r || (Number.isFinite(ln) && Number.isFinite(rn) && ln === rn));\n case \"<\":\n return ln < rn;\n case \"<=\":\n return ln <= rn;\n case \">\":\n return ln > rn;\n case \">=\":\n return ln >= rn;\n case \"&&\":\n return Boolean(l) && Boolean(r);\n case \"||\":\n return Boolean(l) || Boolean(r);\n default:\n throw new Error(`Unsupported binary operator \"${op}\"`);\n }\n}\n\nfunction toExecutionError(e: unknown): ExecutionError {\n if (e instanceof Error) {\n return { message: e.message, stack: e.stack ?? \"\" };\n }\n return { message: String(e) };\n}\n","// DslLinter — static validation of a parsed scenario AST.\n//\n// MVP approach: pragmatic. We do NOT lean on vendor's\n// `validateBlocklyCompatibility` because its FUNCTION_CONTRACT_REGISTRY is\n// fully web-oriented (click/fill/getByRole/...) and would flag every mobile\n// function as \"unknown\". The portable parts (shape-rules, JSON-as-string\n// rule) reapply here as small visitor checks.\n//\n// Rule catalogue:\n// E1 Unknown function (not in FunctionRegistry, not in userFunctionNames).\n// E2 Forbidden AST node type (D-4 subset: for/while/var/print/break/\n// continue/increment/object/index access/conditional/unary).\n// `return` is legal ONLY inside non-test/non-flow user functions\n// (helpers); illegal in test_*/flow_* bodies.\n// E3 setDevice() with unknown slot.\n// E4 JSON-string args of apiCall do not parse.\n// W5 assert* called before first UI action.\n// E7 test_*/flow_* function missing 3-comment Blockly header.\n// E8 Duplicate user-function name (cross-file or shadowing built-in).\n\nimport {\n AssignmentStatement,\n ArrayAccessExpression,\n ArrayAssignmentStatement,\n ArrayExpression,\n BinaryExpression,\n BlockStatement,\n BreakStatement,\n ConditionalExpression,\n ContinueStatement,\n DoWhileStatement,\n ForStatement,\n FunctionDefineStatement,\n FunctionStatement,\n FunctionalExpression,\n IfStatement,\n IncrementExpression,\n IncrementStatement,\n MetaBlockStatement,\n ObjectExpression,\n PrintStatement,\n ReturnStatement,\n type Statement,\n type Expression,\n UnaryExpression,\n ValueExpression,\n VarStatement,\n VariableExpression,\n WhileStatement,\n} from \"../../vendor/dsl/parser/ast/index.ts\";\n\nimport type { FunctionRegistry } from \"./function-registry.ts\";\nimport type { HelperSource } from \"../runner/helper-repository.ts\";\nimport type { UserFunctionOrigin } from \"../runner/scenario-loader.ts\";\n\nexport type DiagnosticSeverity = \"error\" | \"warning\";\n\nexport interface Diagnostic {\n severity: DiagnosticSeverity;\n code: string; // \"E1\", \"W5\", ...\n message: string;\n line: number;\n col: number;\n /** When set, identifies the source file (e.g. \"_helpers/auth.js\").\n * Production callers print this prefix; unit tests can ignore. */\n source?: string;\n}\n\nexport interface DslLinterDeps {\n registry: FunctionRegistry;\n /** Known device slots (from EnvConfig.simBySlot keys). */\n knownSlots: string[];\n}\n\nexport interface LintOptions {\n /** Names of all top-level user-defined functions visible to this AST —\n * union of entry + helpers. Used to suppress E1 \"Unknown function\". */\n userFunctionNames?: Set<string>;\n}\n\nconst ASSERT_PREFIX = \"assert\";\nconst UI_CALL_NAMES = new Set([\"tap\", \"type\", \"swipe\", \"pressKey\", \"waitFor\", \"appLaunch\", \"openDeeplink\"]);\n\nexport class DslLinter {\n constructor(private readonly deps: DslLinterDeps) {}\n\n /**\n * Lint a parsed scenario AST.\n *\n * @param ast entry-scenario AST\n * @param source raw source — when present enables E7 header check\n * @param options cross-cutting context (user-function names, etc.)\n */\n lint(ast: BlockStatement, source?: string, options: LintOptions = {}): Diagnostic[] {\n const diags: Diagnostic[] = [];\n const lines = source !== undefined ? source.split(\"\\n\") : null;\n const userFns = options.userFunctionNames ?? new Set<string>();\n\n for (const stmt of ast.statements) {\n if (stmt instanceof FunctionDefineStatement && isBlockMappable(stmt.name)) {\n if (lines !== null) this.checkBlocklyHeader(stmt, lines, diags);\n this.lintFunctionBody(stmt, diags, userFns, /*allowReturn*/ false);\n } else if (stmt instanceof FunctionDefineStatement) {\n // Helper function declared inline in scenario file — return allowed,\n // header NOT required.\n this.lintFunctionBody(stmt, diags, userFns, /*allowReturn*/ true);\n } else if (stmt instanceof MetaBlockStatement) {\n // Allowed at top level without further checks.\n } else {\n diags.push(diag(\"error\", \"E2\", `Only function definitions allowed at top level (got ${stmt.constructor.name})`, stmt));\n }\n }\n return diags;\n }\n\n /**\n * Cross-file E8 check — duplicate user-function names + shadowing\n * built-ins. Run ONCE per scenario load (not per file) using the\n * full origin list from ScenarioLoader.userFunctionOrigins.\n *\n * Each diagnostic is anchored to a specific origin (with path/line/col),\n * so production callers print \"_helpers/seed.js:12:1 [E8] ...\".\n */\n lintCrossFile(origins: UserFunctionOrigin[]): Diagnostic[] {\n const diags: Diagnostic[] = [];\n const byName = new Map<string, UserFunctionOrigin[]>();\n for (const o of origins) {\n const list = byName.get(o.name) ?? [];\n list.push(o);\n byName.set(o.name, list);\n }\n for (const [name, list] of byName) {\n if (this.deps.registry.has(name)) {\n // Built-in shadowing — flag every origin so user sees both places.\n for (const o of list) {\n diags.push({\n severity: \"error\",\n code: \"E8\",\n message: `User function \"${name}\" shadows a built-in DSL function. Rename it.`,\n line: o.line,\n col: o.col,\n source: o.source,\n });\n }\n continue;\n }\n if (list.length > 1) {\n // True duplicate. Anchor every occurrence so user sees all sites.\n const where = list.map((o) => `${o.source}:${o.line}`).join(\", \");\n for (const o of list) {\n diags.push({\n severity: \"error\",\n code: \"E8\",\n message: `Duplicate user function \"${name}\". Defined at: ${where}`,\n line: o.line,\n col: o.col,\n source: o.source,\n });\n }\n }\n }\n return diags;\n }\n\n /**\n * Lint a helper file. Same rules as scenario, but:\n * - No E7 header check (helpers aren't block-mappable)\n * - `return` allowed in any function body\n * - All diagnostics tagged with helper.path\n */\n lintHelper(helper: HelperSource, options: LintOptions = {}): Diagnostic[] {\n const diags: Diagnostic[] = [];\n const userFns = options.userFunctionNames ?? new Set<string>();\n\n for (const stmt of helper.ast.statements) {\n if (stmt instanceof FunctionDefineStatement) {\n if (isBlockMappable(stmt.name)) {\n // test_*/flow_* in a helper file — unusual but possible.\n // Treat as scenario-class: return forbidden.\n this.lintFunctionBody(stmt, diags, userFns, /*allowReturn*/ false);\n } else {\n this.lintFunctionBody(stmt, diags, userFns, /*allowReturn*/ true);\n }\n } else if (stmt instanceof MetaBlockStatement) {\n // ok\n } else {\n diags.push(diag(\"error\", \"E2\", `Only function definitions allowed at top level (got ${stmt.constructor.name})`, stmt));\n }\n }\n // Tag every diagnostic with the helper's path so production callers\n // can print \"_helpers/auth.js:LINE:COL\".\n return diags.map((d) => ({ ...d, source: helper.path }));\n }\n\n // ---- internals --------------------------------------------------------\n\n private checkBlocklyHeader(\n fn: FunctionDefineStatement,\n lines: string[],\n diags: Diagnostic[],\n ): void {\n const fnLine = (fn.token as { getLine?: () => number } | undefined)?.getLine?.() ?? 0;\n if (fnLine <= 3) {\n diags.push(diag(\"error\", \"E7\", `${fn.name}: missing 3-comment Blockly header (// id-<slug>, // <name>, // #<color>) immediately above the function definition`, fn));\n return;\n }\n const idLine = lines[fnLine - 4];\n const nameLine = lines[fnLine - 3];\n const colorLine = lines[fnLine - 2];\n const allComments = [idLine, nameLine, colorLine].every(\n (l) => typeof l === \"string\" && l.trimStart().startsWith(\"//\"),\n );\n if (!allComments) {\n diags.push(diag(\"error\", \"E7\", `${fn.name}: 3 comment lines must immediately precede the function (// id-<slug>, // <name>, // #<color>) — no blank line in between`, fn));\n }\n }\n\n private lintFunctionBody(\n fn: FunctionDefineStatement,\n diags: Diagnostic[],\n userFns: Set<string>,\n allowReturn: boolean,\n ): void {\n if (!(fn.body instanceof BlockStatement)) {\n diags.push(diag(\"error\", \"E2\", `Function \"${fn.name}\" body must be a block`, fn));\n return;\n }\n let firstUiSeen = false;\n let firstAssertSeen = false;\n const recordCall = (name: string) => {\n if (UI_CALL_NAMES.has(name)) firstUiSeen = true;\n if (name.startsWith(ASSERT_PREFIX)) firstAssertSeen = true;\n };\n for (const stmt of fn.body.statements) {\n this.checkStatement(stmt, diags, recordCall, () => firstUiSeen, userFns, allowReturn);\n }\n // firstAssertSeen unused for now — kept for symmetry with prior W5.\n void firstAssertSeen;\n }\n\n private checkStatement(\n stmt: Statement,\n diags: Diagnostic[],\n recordCall: (name: string) => void,\n isFirstUiSeen: () => boolean,\n userFns: Set<string>,\n allowReturn: boolean,\n ): void {\n if (stmt instanceof ReturnStatement) {\n if (!allowReturn) {\n diags.push(diag(\"error\", \"E2\", `'return' is not allowed inside test_*/flow_* function bodies (only in helpers)`, stmt));\n return;\n }\n // Recurse into the return expression to validate it.\n const expr = (stmt as unknown as { expression?: Expression }).expression;\n if (expr) this.checkExpression(expr, diags, recordCall, isFirstUiSeen, userFns, allowReturn);\n return;\n }\n\n if (this.isForbiddenStatement(stmt)) {\n diags.push(diag(\"error\", \"E2\", `Forbidden statement type \"${stmt.constructor.name}\" (D-4 subset)`, stmt));\n return;\n }\n\n if (stmt instanceof AssignmentStatement) {\n this.checkExpression(stmt.expression, diags, recordCall, isFirstUiSeen, userFns, allowReturn);\n return;\n }\n\n if (stmt instanceof FunctionStatement) {\n this.checkCall(stmt.functionalExpression, diags, recordCall, isFirstUiSeen, userFns, allowReturn);\n return;\n }\n\n if (stmt instanceof IfStatement) {\n this.checkExpression(stmt.expression, diags, recordCall, isFirstUiSeen, userFns, allowReturn);\n this.checkStatement(stmt.ifStatement, diags, recordCall, isFirstUiSeen, userFns, allowReturn);\n if (stmt.elseStatement) this.checkStatement(stmt.elseStatement, diags, recordCall, isFirstUiSeen, userFns, allowReturn);\n return;\n }\n\n if (stmt instanceof BlockStatement) {\n for (const s of stmt.statements) this.checkStatement(s, diags, recordCall, isFirstUiSeen, userFns, allowReturn);\n return;\n }\n\n if (stmt instanceof FunctionDefineStatement) {\n diags.push(diag(\"error\", \"E2\", \"Nested function definitions are not allowed\", stmt));\n return;\n }\n\n if (stmt instanceof MetaBlockStatement) return;\n\n diags.push(diag(\"error\", \"E2\", `Unsupported statement \"${stmt.constructor.name}\"`, stmt));\n }\n\n private checkExpression(\n expr: Expression,\n diags: Diagnostic[],\n recordCall: (name: string) => void,\n isFirstUiSeen: () => boolean,\n userFns: Set<string>,\n allowReturn: boolean,\n ): void {\n if (expr instanceof FunctionalExpression) {\n this.checkCall(expr, diags, recordCall, isFirstUiSeen, userFns, allowReturn);\n return;\n }\n if (expr instanceof BinaryExpression) {\n this.checkExpression(expr.expr1, diags, recordCall, isFirstUiSeen, userFns, allowReturn);\n this.checkExpression(expr.expr2, diags, recordCall, isFirstUiSeen, userFns, allowReturn);\n return;\n }\n if (expr instanceof ArrayExpression) {\n for (const e of expr.elements) this.checkExpression(e, diags, recordCall, isFirstUiSeen, userFns, allowReturn);\n return;\n }\n if (expr instanceof ValueExpression || expr instanceof VariableExpression) return;\n if (this.isForbiddenExpression(expr)) {\n diags.push(diag(\"error\", \"E2\", `Forbidden expression \"${expr.constructor.name}\" (D-4 subset)`, expr));\n return;\n }\n diags.push(diag(\"error\", \"E2\", `Unsupported expression \"${expr.constructor.name}\"`, expr));\n }\n\n private checkCall(\n call: FunctionalExpression,\n diags: Diagnostic[],\n recordCall: (name: string) => void,\n isFirstUiSeen: () => boolean,\n userFns: Set<string>,\n allowReturn: boolean,\n ): void {\n const name = call.name;\n\n // E1 unless name is built-in OR a user-defined function.\n if (!this.deps.registry.has(name) && !userFns.has(name)) {\n diags.push(diag(\"error\", \"E1\", `Unknown DSL function \"${name}\"`, call));\n }\n\n // setDevice slot check.\n if (name === \"setDevice\" && call.arguments.length > 0) {\n const arg0 = call.arguments[0];\n if (arg0 instanceof ValueExpression) {\n const val = (arg0.value as { asString?: () => string }).asString?.call(arg0.value);\n if (typeof val === \"string\" && !this.deps.knownSlots.includes(val)) {\n diags.push(\n diag(\"error\", \"E3\", `setDevice(\"${val}\"): unknown slot. Known: ${this.deps.knownSlots.join(\", \") || \"(none)\"}`, call),\n );\n }\n }\n }\n\n // JSON-as-string for apiCall body (arg 2).\n if (name === \"apiCall\" && call.arguments.length > 0) {\n const jsonArgIdx = 2;\n const jsonArg = call.arguments[jsonArgIdx];\n if (jsonArg instanceof ValueExpression) {\n const val = (jsonArg.value as { asString?: () => string }).asString?.call(jsonArg.value);\n if (typeof val === \"string\") {\n try {\n JSON.parse(val);\n } catch (e) {\n diags.push(\n diag(\"error\", \"E4\", `${name}: arg ${jsonArgIdx} is not valid JSON — ${(e as Error).message}`, call),\n );\n }\n }\n }\n }\n\n // Flow-order warnings (only meaningful for built-ins).\n if (name.startsWith(ASSERT_PREFIX) && !isFirstUiSeen()) {\n diags.push(diag(\"warning\", \"W5\", `${name}() called before any UI action — typo or wrong order?`, call));\n }\n\n recordCall(name);\n\n for (const arg of call.arguments) {\n this.checkExpression(arg, diags, recordCall, isFirstUiSeen, userFns, allowReturn);\n }\n }\n\n private isForbiddenStatement(stmt: Statement): boolean {\n return (\n stmt instanceof ForStatement ||\n stmt instanceof WhileStatement ||\n stmt instanceof DoWhileStatement ||\n stmt instanceof VarStatement ||\n stmt instanceof PrintStatement ||\n stmt instanceof BreakStatement ||\n stmt instanceof ContinueStatement ||\n stmt instanceof IncrementStatement ||\n stmt instanceof ArrayAssignmentStatement\n );\n }\n\n private isForbiddenExpression(expr: Expression): boolean {\n return (\n expr instanceof IncrementExpression ||\n expr instanceof UnaryExpression ||\n expr instanceof ConditionalExpression ||\n expr instanceof ObjectExpression ||\n expr instanceof ArrayAccessExpression\n );\n }\n}\n\nfunction isBlockMappable(name: string): boolean {\n return name.startsWith(\"test_\") || name.startsWith(\"flow_\");\n}\n\nfunction diag(severity: DiagnosticSeverity, code: string, message: string, node: { token?: { getLine?: () => number; getColumn?: () => number } }): Diagnostic {\n const tok = node.token;\n return {\n severity,\n code,\n message,\n line: tok?.getLine ? tok.getLine() : 0,\n col: tok?.getColumn ? tok.getColumn() : 0,\n };\n}\n","// FunctionRegistry — the mobile DSL allowlist.\n//\n// Two purposes layered in one registry:\n// 1. Runtime dispatch: name → TS implementation (`invoke`).\n// 2. Static signature (`argTypes`, `returnType`) for the linter and (later)\n// the Blockly mobile-generators.\n//\n// We deliberately keep argTypes loose (string / number / boolean / selector /\n// any) — strict shape-checking happens inside each function via small zod\n// schemas where it earns its keep. The registry's job is \"exists / matches\n// arity\", not \"validates content\".\n\nimport type { TestRuntime, DslValue } from \"./runtime.ts\";\nimport type { Selector } from \"../inspection/selector.ts\";\n\nexport type DslArgType = \"string\" | \"number\" | \"boolean\" | \"selector\" | \"any\";\nexport type DslReturnType = \"void\" | \"string\" | \"number\" | \"boolean\" | \"selector\" | \"any\";\n\n// Selectors flow through the executor as `DslValue | Selector`. For typing\n// purposes we widen to `unknown` and let each implementation narrow.\nexport type DslArg = DslValue | Selector | unknown;\n\nexport interface DslFunction {\n name: string;\n argTypes: DslArgType[];\n returnType: DslReturnType;\n /** Some functions tolerate a trailing optional arg (e.g. waitFor timeoutMs). */\n minArgs?: number;\n /**\n * Implementation. The runtime is passed first; args follow in declaration\n * order. May return a primitive, a Selector object, or a Promise of either.\n */\n invoke(runtime: TestRuntime, ...args: DslArg[]): Promise<DslValue | Selector | void> | DslValue | Selector | void;\n}\n\nexport class FunctionRegistry {\n private readonly map = new Map<string, DslFunction>();\n\n register(fn: DslFunction): void {\n if (this.map.has(fn.name)) {\n throw new Error(`Duplicate DSL function: ${fn.name}`);\n }\n this.map.set(fn.name, fn);\n }\n\n has(name: string): boolean {\n return this.map.has(name);\n }\n\n get(name: string): DslFunction | undefined {\n return this.map.get(name);\n }\n\n names(): string[] {\n return [...this.map.keys()].sort();\n }\n}\n","// Assertion DSL functions.\n\nimport type { Selector } from \"../../inspection/selector.ts\";\nimport type { TestRuntime } from \"../runtime.ts\";\nimport type { DslFunction } from \"../function-registry.ts\";\n\nfunction asSelector(x: unknown, fn: string, idx: number): Selector {\n if (typeof x !== \"object\" || x === null) {\n throw new Error(`${fn}(): arg ${idx} must be a Selector. Got ${typeof x}.`);\n }\n return x as Selector;\n}\n\nfunction asNumber(x: unknown, fn: string, idx: number): number {\n if (typeof x !== \"number\") throw new Error(`${fn}(): arg ${idx} must be a number. Got ${typeof x}.`);\n return x;\n}\n\nexport const assertEqual: DslFunction = {\n name: \"assertEqual\",\n argTypes: [\"any\", \"any\"],\n returnType: \"void\",\n invoke: (_runtime, actual, expected) => {\n if (actual !== expected) {\n throw new Error(\n `assertEqual failed: actual ${JSON.stringify(actual)} !== expected ${JSON.stringify(expected)}`,\n );\n }\n },\n};\n\nexport const assertVisible: DslFunction = {\n name: \"assertVisible\",\n argTypes: [\"selector\"],\n returnType: \"void\",\n invoke: async (runtime, selectorArg) => {\n const selector = asSelector(selectorArg, \"assertVisible\", 0);\n const tree = await runtime.driver.a11yTree(runtime.currentDeviceSlot);\n const r = runtime.selectorResolver.resolve(tree, selector);\n if (!r.ok) {\n throw new Error(\n `assertVisible failed: ${r.reason}\\n selector: ${JSON.stringify(selector)}\\n candidates: ${JSON.stringify(r.candidates).slice(0, 600)}`,\n );\n }\n },\n};\n\nexport const assertCount: DslFunction = {\n name: \"assertCount\",\n argTypes: [\"selector\", \"number\"],\n returnType: \"void\",\n invoke: async (runtime, selectorArg, expectedArg) => {\n const selector = asSelector(selectorArg, \"assertCount\", 0);\n const expected = asNumber(expectedArg, \"assertCount\", 1);\n const tree = await runtime.driver.a11yTree(runtime.currentDeviceSlot);\n // Count via repeated ordinal probing — keep increasing ordinal until miss.\n let count = 0;\n while (true) {\n const probe = { ...selector, ordinal: count };\n const r = runtime.selectorResolver.resolve(tree, probe);\n if (!r.ok) break;\n count++;\n if (count > 1000) {\n throw new Error(`assertCount: aborting after 1000 — selector too broad`);\n }\n }\n if (count !== expected) {\n throw new Error(\n `assertCount failed: ${JSON.stringify(selector)} matched ${count} time(s), expected ${expected}`,\n );\n }\n },\n};\n\n/**\n * assertEnabled / assertDisabled — read `enabled` attribute from the RAW a11y\n * tree (driver.a11yTree), NOT from TreeInspector.compactTree (which strips it).\n */\nasync function assertEnabledState(\n runtime: TestRuntime,\n selectorArg: unknown,\n expected: boolean,\n fnName: string,\n): Promise<void> {\n const selector = asSelector(selectorArg, fnName, 0);\n const tree = await runtime.driver.a11yTree(runtime.currentDeviceSlot);\n const r = runtime.selectorResolver.resolve(tree, selector);\n if (!r.ok) {\n throw new Error(\n `${fnName} failed: selector did not match. ${r.reason}\\n selector: ${JSON.stringify(selector)}`,\n );\n }\n const node = r.node as { enabled?: boolean };\n if (node.enabled === undefined) {\n throw new Error(\n `${fnName} failed: matched node does not report 'enabled' (likely a non-interactive widget or RN-side accessibility gap). ` +\n `Selector: ${JSON.stringify(selector)}`,\n );\n }\n if (node.enabled !== expected) {\n throw new Error(\n `${fnName} failed: node.enabled=${node.enabled}, expected ${expected}. Selector: ${JSON.stringify(selector)}`,\n );\n }\n}\n\nexport const assertEnabled: DslFunction = {\n name: \"assertEnabled\",\n argTypes: [\"selector\"],\n returnType: \"void\",\n invoke: async (runtime, selectorArg) => {\n await assertEnabledState(runtime, selectorArg, true, \"assertEnabled\");\n },\n};\n\nexport const assertDisabled: DslFunction = {\n name: \"assertDisabled\",\n argTypes: [\"selector\"],\n returnType: \"void\",\n invoke: async (runtime, selectorArg) => {\n await assertEnabledState(runtime, selectorArg, false, \"assertDisabled\");\n },\n};\n\nexport const ASSERT_FUNCTIONS: DslFunction[] = [\n assertEqual,\n assertVisible,\n assertCount,\n assertEnabled,\n assertDisabled,\n];\n","// Data-layer DSL functions — universal primitives:\n// - dbQuery / dbExec — parameterized SQL via DbClient (pg/mysql/sqlite)\n// - apiCall — HTTP via ApiClient\n// - shell — execFile-style spawn (no shell interpolation)\n//\n// Project-specific seeding (e.g. UnoPeak's `pnpm db:create-user`) belongs in\n// `unotest/e2e/_helpers/seed.js`, NOT in core. dbSeed/dbWipe removed in Stage 3.\n\nimport type { DslFunction, DslArg } from \"../function-registry.ts\";\n\nfunction asString(x: unknown, fn: string, idx: number): string {\n if (typeof x !== \"string\") throw new Error(`${fn}(): arg ${idx} must be a string. Got ${typeof x}.`);\n return x;\n}\n\n/**\n * Coerce a DSL value to a SQL parameter. DSL primitives are string|number|\n * boolean|null; the driver lib serializes them appropriately at the protocol\n * level (no string interpolation).\n */\nfunction toSqlParam(v: DslArg): unknown {\n if (v === null || v === undefined) return null;\n if (typeof v === \"string\" || typeof v === \"number\" || typeof v === \"boolean\") return v;\n throw new Error(`dbQuery/dbExec arg type unsupported: ${typeof v}`);\n}\n\nexport const dbQuery: DslFunction = {\n name: \"dbQuery\",\n argTypes: [\"string\"],\n returnType: \"string\",\n invoke: async (runtime, sqlArg, ...rest) => {\n const sql = asString(sqlArg, \"dbQuery\", 0);\n const params = rest.map((a, i) => {\n try {\n return toSqlParam(a);\n } catch (e) {\n throw new Error(`dbQuery: arg ${i + 1} ${(e as Error).message}`);\n }\n });\n runtime.logger.debug(`dbQuery ${sql.slice(0, 200)} params=${JSON.stringify(params).slice(0, 200)}`);\n const rows = await runtime.db.query<Record<string, unknown>>(sql, params);\n if (rows.length === 0) return \"\";\n const firstKey = Object.keys(rows[0]!)[0];\n if (!firstKey) return \"\";\n const cell = rows[0]![firstKey];\n return cell == null ? \"\" : String(cell);\n },\n};\n\nexport const dbExec: DslFunction = {\n name: \"dbExec\",\n argTypes: [\"string\"],\n returnType: \"string\",\n invoke: async (runtime, sqlArg, ...rest) => {\n const sql = asString(sqlArg, \"dbExec\", 0);\n const params = rest.map((a, i) => {\n try {\n return toSqlParam(a);\n } catch (e) {\n throw new Error(`dbExec: arg ${i + 1} ${(e as Error).message}`);\n }\n });\n runtime.logger.debug(`dbExec ${sql.slice(0, 200)} params=${JSON.stringify(params).slice(0, 200)}`);\n const result = await runtime.db.exec(sql, params);\n if (result.rows.length === 0) return \"\";\n const firstRow = result.rows[0] as Record<string, unknown>;\n const firstKey = Object.keys(firstRow)[0];\n if (!firstKey) return \"\";\n const cell = firstRow[firstKey];\n return cell == null ? \"\" : String(cell);\n },\n};\n\nexport const shell: DslFunction = {\n name: \"shell\",\n argTypes: [\"string\"],\n returnType: \"string\",\n invoke: async (runtime, cmdArg, ...rest) => {\n const cmd = asString(cmdArg, \"shell\", 0);\n const args: string[] = rest.map((a, i) => {\n // Coerce primitives to string. Arrays not supported in MVP (variadic only).\n if (a === null || a === undefined) return \"\";\n if (typeof a === \"string\") return a;\n if (typeof a === \"number\" || typeof a === \"boolean\") return String(a);\n throw new Error(`shell: arg ${i + 1} must be string|number|boolean|null. Got ${typeof a}.`);\n });\n runtime.logger.debug(`shell ${cmd} ${args.join(\" \")}`);\n const result = await runtime.shell.exec(cmd, args);\n return result.stdout;\n },\n};\n\nexport const apiCall: DslFunction = {\n name: \"apiCall\",\n argTypes: [\"string\", \"string\", \"string\"],\n returnType: \"string\",\n minArgs: 2,\n invoke: async (runtime, methodArg, pathArg, bodyArg) => {\n const method = asString(methodArg, \"apiCall\", 0).toUpperCase();\n const path = asString(pathArg, \"apiCall\", 1);\n if (method !== \"GET\" && method !== \"POST\" && method !== \"PUT\" && method !== \"PATCH\" && method !== \"DELETE\") {\n throw new Error(`apiCall(): unsupported method \"${method}\"`);\n }\n let body: unknown;\n if (bodyArg !== undefined) {\n const bodyJson = asString(bodyArg, \"apiCall\", 2);\n try {\n body = JSON.parse(bodyJson);\n } catch (e) {\n throw new Error(`apiCall(): body arg must be valid JSON. ${(e as Error).message}`);\n }\n }\n runtime.logger.debug(`apiCall ${method} ${path}`);\n const opts: { method: typeof method; path: string; body?: unknown } = { method, path };\n if (body !== undefined) opts.body = body;\n const resp = await runtime.api.call(opts);\n if (!resp.ok) {\n throw new Error(`apiCall ${method} ${path} → HTTP ${resp.status}: ${resp.raw.slice(0, 500)}`);\n }\n return resp.raw;\n },\n};\n\nexport const DATA_FUNCTIONS: DslFunction[] = [dbQuery, dbExec, apiCall, shell];\n","// Device DSL functions — multi-device coordination and app lifecycle.\n\nimport type { TestRuntime } from \"../runtime.ts\";\nimport type { DslFunction } from \"../function-registry.ts\";\n\nfunction asString(x: unknown, fn: string, idx: number): string {\n if (typeof x !== \"string\") throw new Error(`${fn}(): arg ${idx} must be a string. Got ${typeof x}.`);\n return x;\n}\n\nfunction asBoolean(x: unknown, fn: string, idx: number): boolean {\n if (typeof x !== \"boolean\") throw new Error(`${fn}(): arg ${idx} must be a boolean. Got ${typeof x}.`);\n return x;\n}\n\nexport const setDevice: DslFunction = {\n name: \"setDevice\",\n argTypes: [\"string\"],\n returnType: \"void\",\n invoke: (runtime, slotArg) => {\n const slot = asString(slotArg, \"setDevice\", 0);\n runtime.setCurrentDeviceSlot(slot);\n },\n};\n\nexport const appLaunch: DslFunction = {\n name: \"appLaunch\",\n argTypes: [\"boolean\"],\n returnType: \"void\",\n minArgs: 0,\n invoke: async (runtime, cleanArg) => {\n const clean = cleanArg !== undefined ? asBoolean(cleanArg, \"appLaunch\", 0) : false;\n await runtime.driver.appLaunch(runtime.currentDeviceSlot, { clean });\n },\n};\n\nexport const openDeeplink: DslFunction = {\n name: \"openDeeplink\",\n argTypes: [\"string\"],\n returnType: \"void\",\n invoke: async (runtime, urlArg) => {\n const url = asString(urlArg, \"openDeeplink\", 0);\n await runtime.driver.openDeeplink(runtime.currentDeviceSlot, url);\n },\n};\n\nexport const DEVICE_FUNCTIONS: DslFunction[] = [setDevice, appLaunch, openDeeplink];\n","// Selector-constructor DSL functions. Pure — no driver/HTTP side effects.\n// Each returns a frozen Selector value that the AstExecutor passes downstream.\n//\n// D-10: ordinal/near are modifiers — they take a target Selector and return a\n// new Selector with the extra constraint set.\n\nimport type { Selector } from \"../../inspection/selector.ts\";\nimport type { DslFunction } from \"../function-registry.ts\";\n\nfunction assertSelector(x: unknown, fnName: string, argIndex: number): Selector {\n if (typeof x !== \"object\" || x === null) {\n throw new Error(\n `${fnName}(): arg ${argIndex} must be a Selector (from getByTestId/getByText/getByLabel/ordinal/near). Got ${typeof x}.`,\n );\n }\n return x as Selector;\n}\n\nfunction assertString(x: unknown, fnName: string, argIndex: number): string {\n if (typeof x !== \"string\") {\n throw new Error(`${fnName}(): arg ${argIndex} must be a string. Got ${typeof x}.`);\n }\n return x;\n}\n\nfunction assertNumber(x: unknown, fnName: string, argIndex: number): number {\n if (typeof x !== \"number\") {\n throw new Error(`${fnName}(): arg ${argIndex} must be a number. Got ${typeof x}.`);\n }\n return x;\n}\n\nexport const getByTestId: DslFunction = {\n name: \"getByTestId\",\n argTypes: [\"string\"],\n returnType: \"selector\",\n invoke: (_rt, testId) => {\n return { testId: assertString(testId, \"getByTestId\", 0) };\n },\n};\n\nexport const getByText: DslFunction = {\n name: \"getByText\",\n argTypes: [\"string\"],\n returnType: \"selector\",\n invoke: (_rt, text) => {\n return { text: assertString(text, \"getByText\", 0) };\n },\n};\n\nexport const getByLabel: DslFunction = {\n name: \"getByLabel\",\n argTypes: [\"string\"],\n returnType: \"selector\",\n invoke: (_rt, label) => {\n return { label: assertString(label, \"getByLabel\", 0) };\n },\n};\n\nexport const ordinal: DslFunction = {\n name: \"ordinal\",\n argTypes: [\"selector\", \"number\"],\n returnType: \"selector\",\n invoke: (_rt, target, n) => {\n return { ...assertSelector(target, \"ordinal\", 0), ordinal: assertNumber(n, \"ordinal\", 1) };\n },\n};\n\nexport const near: DslFunction = {\n name: \"near\",\n argTypes: [\"selector\", \"selector\", \"number\"],\n returnType: \"selector\",\n minArgs: 2,\n invoke: (_rt, target, anchor, maxDist) => {\n const t = assertSelector(target, \"near\", 0);\n const a = assertSelector(anchor, \"near\", 1);\n const near: { anchor: Selector; maxDistancePx?: number } = { anchor: a };\n if (maxDist !== undefined) near.maxDistancePx = assertNumber(maxDist, \"near\", 2);\n return { ...t, near };\n },\n};\n\nexport const SELECTOR_FUNCTIONS: DslFunction[] = [getByTestId, getByText, getByLabel, ordinal, near];\n","// Time DSL primitives — deterministic time access for scenarios.\n//\n// Scenarios needing \"today's workout\" / \"future workout\" date-sensitivity\n// can't hardcode strings — they go stale daily. These primitives expose\n// current time / date arithmetic without leaking native Date/object types\n// into the DSL (which is primitives-only).\n//\n// All functions read time via TestRuntime.now() (injected; defaults to Date.now)\n// — keeps tests deterministic via dependency injection at the runtime level.\n\nimport type { TestRuntime } from \"../runtime.ts\";\nimport type { DslFunction } from \"../function-registry.ts\";\n\nfunction pad2(n: number): string {\n return n < 10 ? `0${n}` : String(n);\n}\n\nfunction isoDate(ms: number): string {\n const d = new Date(ms);\n return `${d.getUTCFullYear()}-${pad2(d.getUTCMonth() + 1)}-${pad2(d.getUTCDate())}`;\n}\n\nexport const todayFn: DslFunction = {\n name: \"today\",\n argTypes: [],\n returnType: \"string\",\n invoke: (runtime) => isoDate(runtime.now()),\n};\n\nexport const daysFromNow: DslFunction = {\n name: \"daysFromNow\",\n argTypes: [\"number\"],\n returnType: \"string\",\n invoke: (runtime, nArg) => {\n if (typeof nArg !== \"number\" || !Number.isFinite(nArg)) {\n throw new Error(`daysFromNow(): arg 0 must be a finite number. Got ${nArg}.`);\n }\n const dayMs = 24 * 60 * 60 * 1000;\n return isoDate(runtime.now() + Math.trunc(nArg) * dayMs);\n },\n};\n\nexport const nowMs: DslFunction = {\n name: \"nowMs\",\n argTypes: [],\n returnType: \"number\",\n invoke: (runtime) => runtime.now(),\n};\n\nexport const TIME_FUNCTIONS: DslFunction[] = [todayFn, daysFromNow, nowMs];\n","// UI DSL functions — actual driver calls.\n//\n// D-18: tap / type / waitFor poll the selector until `defaultActionWaitMs`\n// before throwing. `swipe` polls only when a `fromSelector` is supplied.\n// `pressKey` and `pause` have no selector — they execute immediately.\n\nimport { setTimeout as wait } from \"node:timers/promises\";\n\nimport type { Selector } from \"../../inspection/selector.ts\";\nimport type { TestRuntime } from \"../runtime.ts\";\nimport type { DslFunction } from \"../function-registry.ts\";\n\nfunction asSelector(x: unknown, fn: string, idx: number): Selector {\n if (typeof x !== \"object\" || x === null) {\n throw new Error(`${fn}(): arg ${idx} must be a Selector (use getByTestId/Text/Label). Got ${typeof x}.`);\n }\n return x as Selector;\n}\n\nfunction asString(x: unknown, fn: string, idx: number): string {\n if (typeof x !== \"string\") throw new Error(`${fn}(): arg ${idx} must be a string. Got ${typeof x}.`);\n return x;\n}\n\nfunction asNumber(x: unknown, fn: string, idx: number): number {\n if (typeof x !== \"number\") throw new Error(`${fn}(): arg ${idx} must be a number. Got ${typeof x}.`);\n return x;\n}\n\nasync function pollUntilFound(\n runtime: TestRuntime,\n selector: Selector,\n timeoutMs: number,\n): Promise<void> {\n const deadline = Date.now() + timeoutMs;\n let lastFailure: { reason: string; candidates: unknown[] } | null = null;\n while (Date.now() < deadline) {\n const tree = await runtime.driver.a11yTree(runtime.currentDeviceSlot);\n const r = runtime.selectorResolver.resolve(tree, selector);\n if (r.ok) return;\n lastFailure = { reason: r.reason, candidates: r.candidates };\n await wait(150);\n }\n throw new Error(\n `Selector not found within ${timeoutMs}ms on slot \"${runtime.currentDeviceSlot}\": ${JSON.stringify(selector)}\\n` +\n ` reason: ${lastFailure?.reason ?? \"unknown\"}\\n` +\n ` candidates: ${JSON.stringify(lastFailure?.candidates ?? [], null, 2).slice(0, 600)}`,\n );\n}\n\nexport const tap: DslFunction = {\n name: \"tap\",\n argTypes: [\"selector\"],\n returnType: \"void\",\n invoke: async (runtime, selectorArg) => {\n const selector = asSelector(selectorArg, \"tap\", 0);\n await pollUntilFound(runtime, selector, runtime.envConfig.defaultActionWaitMs);\n await runtime.driver.tap(runtime.currentDeviceSlot, selector);\n },\n};\n\nexport const type_: DslFunction = {\n name: \"type\",\n argTypes: [\"selector\", \"string\"],\n returnType: \"void\",\n invoke: async (runtime, selectorArg, textArg) => {\n const selector = asSelector(selectorArg, \"type\", 0);\n const text = asString(textArg, \"type\", 1);\n await pollUntilFound(runtime, selector, runtime.envConfig.defaultActionWaitMs);\n await runtime.driver.type(runtime.currentDeviceSlot, selector, text);\n },\n};\n\nexport const swipe: DslFunction = {\n name: \"swipe\",\n argTypes: [\"string\", \"selector\"],\n returnType: \"void\",\n minArgs: 1,\n invoke: async (runtime, directionArg, fromArg) => {\n const direction = asString(directionArg, \"swipe\", 0);\n if (direction !== \"up\" && direction !== \"down\" && direction !== \"left\" && direction !== \"right\") {\n throw new Error(`swipe(): direction must be 'up'|'down'|'left'|'right'. Got \"${direction}\".`);\n }\n let from: Selector | undefined;\n if (fromArg !== undefined) {\n from = asSelector(fromArg, \"swipe\", 1);\n await pollUntilFound(runtime, from, runtime.envConfig.defaultActionWaitMs);\n }\n await runtime.driver.swipe(runtime.currentDeviceSlot, direction, from);\n },\n};\n\nexport const pressKey: DslFunction = {\n name: \"pressKey\",\n argTypes: [\"string\"],\n returnType: \"void\",\n invoke: async (runtime, keyArg) => {\n const key = asString(keyArg, \"pressKey\", 0);\n if (key !== \"back\" && key !== \"home\" && key !== \"enter\" && key !== \"escape\") {\n throw new Error(`pressKey(): key must be 'back'|'home'|'enter'|'escape'. Got \"${key}\".`);\n }\n await runtime.driver.pressKey(runtime.currentDeviceSlot, key);\n },\n};\n\nexport const waitFor: DslFunction = {\n name: \"waitFor\",\n argTypes: [\"selector\", \"number\"],\n returnType: \"void\",\n minArgs: 1,\n invoke: async (runtime, selectorArg, timeoutMsArg) => {\n const selector = asSelector(selectorArg, \"waitFor\", 0);\n const timeoutMs = timeoutMsArg === undefined\n ? runtime.envConfig.defaultWaitForTimeoutMs\n : asNumber(timeoutMsArg, \"waitFor\", 1);\n await pollUntilFound(runtime, selector, timeoutMs);\n },\n};\n\nexport const pause: DslFunction = {\n name: \"pause\",\n argTypes: [\"number\"],\n returnType: \"void\",\n invoke: async (_runtime, msArg) => {\n const ms = asNumber(msArg, \"pause\", 0);\n await wait(ms);\n },\n};\n\nexport const UI_FUNCTIONS: DslFunction[] = [tap, type_, swipe, pressKey, waitFor, pause];\n","// Centralized registration of the entire mobile DSL surface.\n//\n// Composition root imports `buildDefaultRegistry` and stores the result in\n// AppServices.functionRegistry. New functions land by appending to a category\n// file (or creating a new one) and adding the export to the array below.\n\nimport { FunctionRegistry, type DslFunction } from \"../function-registry.ts\";\nimport { ASSERT_FUNCTIONS } from \"./asserts.ts\";\nimport { DATA_FUNCTIONS } from \"./data.ts\";\nimport { DEVICE_FUNCTIONS } from \"./device.ts\";\nimport { SELECTOR_FUNCTIONS } from \"./selectors.ts\";\nimport { TIME_FUNCTIONS } from \"./time.ts\";\nimport { UI_FUNCTIONS } from \"./ui.ts\";\n\nexport const ALL_DSL_FUNCTIONS: DslFunction[] = [\n ...DEVICE_FUNCTIONS,\n ...UI_FUNCTIONS,\n ...SELECTOR_FUNCTIONS,\n ...DATA_FUNCTIONS,\n ...ASSERT_FUNCTIONS,\n ...TIME_FUNCTIONS,\n];\n\nexport function buildDefaultRegistry(): FunctionRegistry {\n const reg = new FunctionRegistry();\n for (const fn of ALL_DSL_FUNCTIONS) reg.register(fn);\n return reg;\n}\n","// TestRuntimeManager — registry of active and paused TestRuntimes.\n//\n// Single-process semantics:\n// - CLI runner: starts one ephemeral runtime, aborts on exit.\n// - MCP debugger: may keep several paused-failed runtimes alive for inspection.\n//\n// D-17 TTL: each runtime that transitions into `paused-failure` arms a timer\n// (default `EnvConfig.pausedRuntimeTtlMs`, 30 min). Any `step` / `resume` /\n// `inspect` call resets it. Expiry → auto-`abort` with a log entry.\n\nimport type {\n ExecutionEvent,\n RunOptions,\n RunResult,\n} from \"./execution-events.ts\";\nimport type { TestRuntime } from \"./runtime.ts\";\nimport type { Logger } from \"../util/log.ts\";\n\nexport type RuntimeState =\n | \"starting\"\n | \"running\"\n | \"paused-step\"\n | \"paused-failure\"\n | \"completed\"\n | \"failed\"\n | \"aborted\";\n\nexport interface ActiveRuntime {\n id: string;\n scenarioName: string;\n testFn: string;\n testRuntime: TestRuntime;\n generator: AsyncGenerator<ExecutionEvent, RunResult>;\n state: RuntimeState;\n lastEvent: ExecutionEvent | null;\n /**\n * The most recent failure event (step-end with ok=false). Distinct from\n * `lastEvent` because the immediately-following `paused` event would\n * otherwise overwrite it — inspect_runtime needs both: state context\n * (paused) AND why (the error).\n */\n lastFailure: { node: unknown; line: number; col: number; error: { message: string; stack?: string; details?: unknown } } | null;\n lastResult: RunResult | null;\n createdAt: number;\n /** Active TTL timer (only when state is paused-failure). */\n ttlTimer: NodeJS.Timeout | null;\n}\n\nexport interface RuntimeSummary {\n id: string;\n scenarioName: string;\n testFn: string;\n state: RuntimeState;\n createdAt: number;\n}\n\nexport interface RuntimeSnapshot {\n id: string;\n scenarioName: string;\n testFn: string;\n state: RuntimeState;\n vars: Record<string, unknown>;\n currentDeviceSlot: string | null;\n lastEvent: ExecutionEvent | null;\n lastFailure: ActiveRuntime[\"lastFailure\"];\n lastResult: RunResult | null;\n}\n\nexport interface TestRuntimeManagerDeps {\n logger: Logger;\n ttlMs: number;\n // Override for tests — bypass real timers.\n setTimeoutFn?: (cb: () => void, ms: number) => NodeJS.Timeout;\n clearTimeoutFn?: (t: NodeJS.Timeout) => void;\n // Hook called by the manager when ttl expires (or when abort runs).\n // Default: invoke testRuntime.driver.shutdown for each slot, ignore errors.\n onAbort?: (runtime: ActiveRuntime) => Promise<void>;\n}\n\nexport class TestRuntimeManager {\n private readonly runtimes = new Map<string, ActiveRuntime>();\n private nextId = 1;\n\n constructor(private readonly deps: TestRuntimeManagerDeps) {}\n\n /**\n * Register a freshly-built runtime + generator. State starts at \"running\"\n * (caller is responsible for kicking off pumping with `pump()` below).\n */\n register(opts: {\n scenarioName: string;\n testFn: string;\n testRuntime: TestRuntime;\n generator: AsyncGenerator<ExecutionEvent, RunResult>;\n runOptions: RunOptions;\n }): string {\n const id = `r-${this.nextId++}-${Date.now().toString(36)}`;\n const active: ActiveRuntime = {\n id,\n scenarioName: opts.scenarioName,\n testFn: opts.testFn,\n testRuntime: opts.testRuntime,\n generator: opts.generator,\n state: \"starting\",\n lastEvent: null,\n lastFailure: null,\n lastResult: null,\n createdAt: Date.now(),\n ttlTimer: null,\n };\n this.runtimes.set(id, active);\n return id;\n }\n\n /**\n * Pump the generator until it either yields `paused` or returns. The caller\n * decides what to do next (continue, abort, or expose to MCP). This loop\n * is what makes the auto vs step distinction work — the generator decides\n * when to yield `paused`; we just keep pumping in auto.\n */\n async pump(id: string): Promise<ExecutionEvent | RunResult> {\n const active = this.requireActive(id);\n // Always clear the TTL before transitioning into running. resetTtl()\n // re-arms when state is still paused-failure, which would race against\n // an in-flight resume. armTtl() runs again only if the generator yields\n // a fresh `paused: 'failure'`.\n this.clearTtl(active);\n active.state = \"running\";\n\n while (true) {\n const r = await active.generator.next();\n if (r.done) {\n active.lastResult = r.value;\n active.state = r.value.outcome === \"completed\" ? \"completed\" : \"failed\";\n return r.value;\n }\n active.lastEvent = r.value;\n // Capture the failure detail BEFORE the paused event overwrites context.\n if (r.value.kind === \"step-end\" && r.value.ok === false) {\n active.lastFailure = {\n node: r.value.node,\n line: r.value.line,\n col: r.value.col,\n error: {\n message: r.value.error.message,\n ...(r.value.error.stack ? { stack: r.value.error.stack } : {}),\n ...(r.value.error.details !== undefined ? { details: r.value.error.details } : {}),\n },\n };\n }\n if (r.value.kind === \"paused\") {\n if (r.value.reason === \"failure\") {\n active.state = \"paused-failure\";\n this.armTtl(active);\n } else {\n active.state = \"paused-step\";\n }\n return r.value;\n }\n }\n }\n\n async step(id: string): Promise<ExecutionEvent | RunResult> {\n return this.pump(id);\n }\n\n /**\n * Resume after failure (re-executes failed statement; D-17 Resume semantics)\n * or after step (advances one statement, then re-pauses if mode=step).\n */\n async resume(id: string): Promise<ExecutionEvent | RunResult> {\n return this.pump(id);\n }\n\n async abort(id: string): Promise<void> {\n const active = this.runtimes.get(id);\n if (!active) return;\n this.clearTtl(active);\n try {\n await active.generator.return({\n outcome: \"aborted\",\n stepsExecuted: 0,\n durationMs: Date.now() - active.createdAt,\n });\n } catch (e) {\n this.deps.logger.warn(`runtime ${id}: generator.return threw: ${(e as Error).message}`);\n }\n active.state = \"aborted\";\n if (this.deps.onAbort) {\n try {\n await this.deps.onAbort(active);\n } catch (e) {\n this.deps.logger.warn(`runtime ${id}: onAbort hook threw: ${(e as Error).message}`);\n }\n }\n this.runtimes.delete(id);\n }\n\n inspect(id: string): RuntimeSnapshot {\n const active = this.requireActive(id);\n // Inspect is read-only and may target a paused-failure runtime; only\n // re-arm the TTL when the runtime is actually idle in that state.\n if (active.state === \"paused-failure\") this.armTtl(active);\n let currentDeviceSlot: string | null = null;\n try {\n currentDeviceSlot = active.testRuntime.currentDeviceSlot;\n } catch {\n currentDeviceSlot = null;\n }\n return {\n id: active.id,\n scenarioName: active.scenarioName,\n testFn: active.testFn,\n state: active.state,\n vars: active.testRuntime.snapshotVars(),\n currentDeviceSlot,\n lastEvent: active.lastEvent,\n lastFailure: active.lastFailure,\n lastResult: active.lastResult,\n };\n }\n\n list(): RuntimeSummary[] {\n return [...this.runtimes.values()].map((r) => ({\n id: r.id,\n scenarioName: r.scenarioName,\n testFn: r.testFn,\n state: r.state,\n createdAt: r.createdAt,\n }));\n }\n\n // ---- TTL ---------------------------------------------------------------\n\n private armTtl(active: ActiveRuntime): void {\n this.clearTtl(active);\n const set = this.deps.setTimeoutFn ?? ((cb, ms) => setTimeout(cb, ms));\n active.ttlTimer = set(() => {\n this.deps.logger.warn(\n `runtime ${active.id} expired after ${Math.round(this.deps.ttlMs / 60_000)}m idle in paused-failure — auto-aborting`,\n );\n void this.abort(active.id);\n }, this.deps.ttlMs);\n }\n\n private resetTtl(active: ActiveRuntime): void {\n if (active.state === \"paused-failure\" && active.ttlTimer) {\n this.armTtl(active);\n } else {\n this.clearTtl(active);\n }\n }\n\n private clearTtl(active: ActiveRuntime): void {\n if (!active.ttlTimer) return;\n const clear = this.deps.clearTimeoutFn ?? clearTimeout;\n clear(active.ttlTimer);\n active.ttlTimer = null;\n }\n\n private requireActive(id: string): ActiveRuntime {\n const a = this.runtimes.get(id);\n if (!a) throw new Error(`Runtime \"${id}\" not found (already aborted or never started)`);\n return a;\n }\n}\n","// Filesystem-backed ScenarioRepository — unotest/e2e/**/*.js on disk.\n//\n// Convention: file `unotest/e2e/<path>/<name>.js` → scenario id \"<path>/<name>\"\n// (path separators preserved). Files / dirs starting with `_` are excluded\n// (those are helpers handled by HelperRepository).\n//\n// The DSL parser is the ScenarioLoader's job, not the repository's; this\n// layer is pure I/O.\n\nimport { readFileSync } from \"node:fs\";\nimport { readdir } from \"node:fs/promises\";\nimport { resolve, join, sep } from \"node:path\";\n\nimport type { ScenarioRepository, ScenarioSource } from \"./scenario-repository.ts\";\n\nexport interface FileSystemScenarioRepositoryDeps {\n /** Absolute path to the scenarios root. */\n scenariosDir: string;\n}\n\nexport class FileSystemScenarioRepository implements ScenarioRepository {\n private readonly scenariosDir: string;\n\n constructor(deps: FileSystemScenarioRepositoryDeps) {\n this.scenariosDir = resolve(deps.scenariosDir);\n }\n\n async list(): Promise<string[]> {\n const out: string[] = [];\n await this.walk(this.scenariosDir, \"\", out);\n return out.sort();\n }\n\n private async walk(dir: string, relPrefix: string, out: string[]): Promise<void> {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n // Skip helper directories (`_helpers/`, `_archive/`, etc.) and dotfiles.\n if (entry.name.startsWith(\"_\") || entry.name.startsWith(\".\")) continue;\n const abs = join(dir, entry.name);\n const rel = relPrefix === \"\" ? entry.name : `${relPrefix}/${entry.name}`;\n if (entry.isDirectory()) {\n await this.walk(abs, rel, out);\n } else if (entry.isFile() && entry.name.endsWith(\".js\")) {\n out.push(rel.slice(0, -\".js\".length));\n }\n }\n }\n\n async load(name: string): Promise<ScenarioSource> {\n if (name.includes(\"..\") || name.startsWith(\"/\") || name.includes(\"\\\\\")) {\n throw new Error(`Invalid scenario name \"${name}\"`);\n }\n // Convert forward-slash scenario id to filesystem path.\n const relPath = name.split(\"/\").join(sep) + \".js\";\n const path = join(this.scenariosDir, relPath);\n const source = readFileSync(path, \"utf8\");\n return { name, source };\n }\n}\n","import { TokenType } from './token-type';\n\nexport class Token {\n private readonly text: string;\n private readonly type: TokenType;\n private readonly column: number;\n private readonly line: number;\n\n constructor(tokenType: TokenType, text: string, column: number, line: number) {\n this.type = tokenType;\n this.text = text;\n this.column = column;\n this.line = line;\n }\n\n getText() {\n return this.text;\n }\n\n getType() {\n return this.type;\n }\n\n getLine() {\n return this.line;\n }\n\n getColumn() {\n return this.column;\n }\n\n // Переопределение метода toString\n toString(): string {\n return `Token(type: ${TokenType[this.type]}, text: \"${this.text}\", line: ${this.line}, column: ${this.column})`;\n }\n}\n","export function isNumber(char: string): boolean {\n // Check if the entire string is a valid number\n // parseInt/parseFloat will parse partial strings (e.g., \"2025-01-01\" -> 2025)\n // So we need to be more strict\n const num = Number(char);\n return !isNaN(num) && char.trim() === num.toString();\n}\n\nexport function isLetter(char: string): boolean {\n return /^[a-zA-Zа-яА-ЯёЁ]$/.test(char);\n}\n\nexport function isLetterOrDigit(char: string): boolean {\n return /^[a-zA-Zа-яА-ЯёЁ0-9]$/.test(char);\n}\n\nexport function isLetterInWord(char: string): boolean {\n return /^[a-zA-Zа-яА-ЯёЁ0-9_$]$/.test(char);\n}\n","import { Token } from './token';\nimport { TokenType } from './token-type';\nimport { isLetter, isLetterInWord, isNumber } from './tools';\n\nexport class Lexer {\n private OPERATOR_CHARS = '+-*/(){}[]=<>!&|,:;';\n\n private readonly OPERATORS: Map<string, TokenType> = new Map([\n ['+', TokenType.PLUS],\n ['++', TokenType.PLUSPLUS],\n ['-', TokenType.MINUS],\n ['--', TokenType.MINUSMINUS],\n ['*', TokenType.STAR],\n ['/', TokenType.SLASH],\n ['(', TokenType.LPAREN],\n [')', TokenType.RPAREN],\n ['{', TokenType.LBRACE],\n ['}', TokenType.RBRACE],\n ['[', TokenType.LBRACKET],\n [']', TokenType.RBRACKET],\n ['=', TokenType.EQ],\n ['<', TokenType.LT],\n ['>', TokenType.GT],\n [',', TokenType.COMMA],\n [':', TokenType.COLON],\n [';', TokenType.SEMICOLON],\n\n ['!', TokenType.EXCL],\n ['&', TokenType.AMP],\n ['|', TokenType.BAR],\n\n ['==', TokenType.EQEQ],\n ['!=', TokenType.EXCLEQ],\n ['<=', TokenType.LTEQ],\n ['>=', TokenType.GTEQ],\n\n ['&&', TokenType.AMPAMP],\n ['||', TokenType.BARBAR],\n ]);\n\n private input: string;\n private readonly length: number;\n private tokens: Token[] = [];\n private pos = 0;\n private column = 1;\n private line = 1;\n\n constructor(input: string) {\n this.input = input;\n this.length = input.length;\n }\n\n tokenize(): Token[] {\n while (this.pos < this.length) {\n const current = this.peek(0);\n if (isNumber(current)) {\n this.tokenizeNumber();\n } else if (isLetter(current)) {\n this.tokenizeWord();\n } else if (current === '\"' || current === \"'\") {\n this.tokenizeText(current);\n } else if (this.peekGroup(3) === '//@') {\n this.tokenizeMetaWord();\n } else if (this.OPERATOR_CHARS.indexOf(current) !== -1) {\n this.tokenizeOperator();\n } else {\n this.next();\n }\n }\n return this.tokens;\n }\n\n private next(): string {\n const currentChar = this.input.charAt(this.pos);\n this.pos++;\n if (currentChar == '\\n') {\n this.line++;\n this.column = 1;\n } else {\n this.column++;\n }\n return this.peek(0);\n }\n\n private peek(relativePosition: number): string {\n const position = this.pos + relativePosition;\n if (position >= this.length) {\n return '\\0';\n }\n return this.input.charAt(position);\n }\n\n private peekGroup(count: number) {\n const buffer = [];\n for (let i = 0; i < count; i++) {\n buffer.push(this.peek(i));\n }\n return buffer.join('');\n }\n\n private addToken(type: TokenType, text: string, column: number, line: number) {\n this.tokens.push(new Token(type, text, column - 1, line));\n }\n\n private tokenizeNumber() {\n const column = this.column;\n const line = this.line;\n const buffer = [];\n let current = this.peek(0);\n while (current !== '\\0') {\n if (current == '.') {\n if (buffer.indexOf('.') !== -1) {\n throw new Error('Invalid float number');\n }\n } else if (!isNumber(current)) {\n break;\n }\n buffer.push(current);\n current = this.next();\n }\n this.addToken(TokenType.NUMBER, buffer.join(''), column, line);\n }\n\n private consumeWord() {\n const buffer = [];\n let current = this.peek(0);\n while (current !== '\\0') {\n if (!isLetterInWord(current)) {\n break;\n }\n buffer.push(current);\n current = this.next();\n }\n return buffer.join('');\n }\n\n private tokenizeMetaWord() {\n const column = this.column;\n const line = this.line;\n // SKIP //@\n this.next();\n this.next();\n this.next();\n const word = this.consumeWord();\n if (word.startsWith('end')) {\n this.addToken(TokenType.CLOSE_META_BLOCK, word, column, line);\n } else {\n this.addToken(TokenType.META_BLOCK, word, column, line);\n }\n }\n\n private tokenizeWord() {\n const column = this.column;\n const line = this.line;\n const word = this.consumeWord();\n\n switch (word) {\n case 'var':\n this.addToken(TokenType.VAR, '', column, line);\n break;\n case 'print':\n this.addToken(TokenType.PRINT, '', column, line);\n break;\n case 'if':\n this.addToken(TokenType.IF, '', column, line);\n break;\n case 'else':\n this.addToken(TokenType.ELSE, '', column, line);\n break;\n case 'for':\n this.addToken(TokenType.FOR, '', column, line);\n break;\n case 'while':\n this.addToken(TokenType.WHILE, '', column, line);\n break;\n case 'do':\n this.addToken(TokenType.DO, '', column, line);\n break;\n case 'break':\n this.addToken(TokenType.BREAK, '', column, line);\n break;\n case 'continue':\n this.addToken(TokenType.CONTINUE, '', column, line);\n break;\n case 'function':\n this.addToken(TokenType.FUNCTION, '', column, line);\n break;\n case 'return':\n this.addToken(TokenType.RETURN, '', column, line);\n break;\n default:\n this.addToken(TokenType.WORD, word, column, line);\n }\n }\n\n private tokenizeText(char: string) {\n this.next(); // SKIP \"\n\n const column = this.column;\n const line = this.line;\n\n const buffer = [];\n let current = this.peek(0);\n while (current !== '\\0') {\n if (current == '\\\\') {\n current = this.next();\n switch (current) {\n case char:\n current = this.next();\n buffer.push(char);\n continue;\n case 'n':\n current = this.next();\n buffer.push('\\n');\n continue;\n case 't':\n current = this.next();\n buffer.push('\\t');\n continue;\n }\n buffer.push('\\\\');\n continue;\n }\n if (current == char) {\n break;\n }\n buffer.push(current);\n current = this.next();\n }\n if (current === '\\0') {\n throw new Error('Missing close quote in string literal');\n }\n this.next();\n const text = buffer.join('');\n this.addToken(TokenType.TEXT, text, column, line);\n }\n\n private tokenizeComment() {\n let current = this.peek(0);\n while ('\\r\\n\\0'.indexOf(current) == -1) {\n current = this.next();\n // console.log(\"read comment\", current);\n }\n }\n\n private tokenizeMultilineComment() {\n let current = this.peek(0);\n while (current != '\\0') {\n if (current == '*' && this.peek(1) == '/') break;\n current = this.next();\n }\n if (current == '\\0') throw new Error('Missing close tag in comment');\n this.next(); // *\n this.next(); // /\n }\n\n private tokenizeOperator() {\n let current = this.peek(0);\n if (current == '/') {\n if (this.peek(1) == '/') {\n this.next();\n this.next();\n this.tokenizeComment();\n return;\n } else if (this.peek(1) == '*') {\n this.next();\n this.next();\n this.tokenizeMultilineComment();\n return;\n }\n }\n const buffer: string[] = [];\n while (current !== '\\0') {\n const text = buffer.join('');\n const column = this.column;\n const line = this.line;\n if (!this.OPERATORS.has(text + current) && text != '') {\n const type = this.OPERATORS.get(text);\n if (!type) {\n throw new Error(`Invalid tokenizeOperator ${text}`);\n }\n this.addToken(type, '', column, line);\n return;\n }\n buffer.push(current);\n current = this.next();\n }\n const text = buffer.join('');\n if (text !== '') {\n const type = this.OPERATORS.get(text);\n if (type) {\n this.addToken(type, '', this.column, this.line);\n return;\n }\n }\n throw new Error('Invalid tokenizeOperator: unexpected end of input');\n }\n}\n","import {\n ArrayAccessExpression,\n ArrayAssignmentStatement,\n ArrayExpression,\n AssignmentStatement,\n BinaryExpression,\n BlockStatement,\n BreakStatement,\n ConditionalExpression,\n ContinueStatement,\n DoWhileStatement,\n Expression,\n ForStatement,\n FunctionDefineStatement,\n FunctionStatement,\n FunctionalExpression,\n IfStatement,\n IncrementExpression,\n IncrementStatement,\n IncrementType,\n MetaBlockStatement,\n ObjectExpression,\n Operator,\n PrintStatement,\n ReturnStatement,\n Statement,\n UnaryExpression,\n ValueExpression,\n VarDeclarator,\n VarStatement,\n VariableExpression,\n WhileStatement,\n} from './ast';\nimport { Token } from './token';\nimport { TokenType } from './token-type';\n\nexport class Parser {\n private EOF = new Token(TokenType.EOF, '', -1, -1);\n private readonly tokens: Token[] = [];\n private pos = 0;\n private readonly size: number;\n\n constructor(tokens: Token[]) {\n this.tokens = tokens;\n this.size = tokens.length;\n }\n\n parse(): BlockStatement {\n const current = this.get(0);\n const result = new BlockStatement(current);\n while (!this.match(TokenType.EOF)) {\n result.add(this.statement());\n // Опционально пропускаем точку с запятой\n this.match(TokenType.SEMICOLON);\n }\n return result;\n }\n\n private statementOrBlock(): Statement {\n if (this.get(0).getType() === TokenType.LBRACE) {\n return this.block();\n }\n return this.statement();\n }\n\n private blockMetaBlock(name: string): Statement {\n const current = this.get(0);\n const block = new BlockStatement(current);\n // this.consume(TokenType.LBRACE);\n while (!this.match(TokenType.CLOSE_META_BLOCK)) {\n block.add(this.statement());\n // Опционально пропускаем точку с запятой\n this.match(TokenType.SEMICOLON);\n }\n return block;\n // const block = new BlockStatement();\n //\n // // let current = this.get(0);\n //\n // // while (current.getType() !== TokenType.CLOSE_META_BLOCK && current.getText() !== `end_${name}`) {\n // while (current.getType() !== TokenType.CLOSE_META_BLOCK && current.getText() !== `end_${name}`) {\n // block.add(this.statement());\n // // Опционально пропускаем точку с запятой\n // this.match(TokenType.SEMICOLON);\n // // current = this.get(0);\n // }\n // // this.consume(TokenType.META_BLOCK);\n // return block;\n }\n\n private metaBlock(): MetaBlockStatement {\n const current = this.get(0);\n\n const name = this.consume(TokenType.META_BLOCK).getText();\n this.consume(TokenType.LPAREN);\n const argNames = [];\n while (!this.match(TokenType.RPAREN)) {\n argNames.push(this.consume(TokenType.TEXT).getText());\n this.match(TokenType.COMMA);\n }\n const body = this.blockMetaBlock(name);\n return new MetaBlockStatement(name, argNames, body, current);\n }\n\n private block(): Statement {\n const current = this.get(0);\n const block = new BlockStatement(current);\n this.consume(TokenType.LBRACE);\n while (!this.match(TokenType.RBRACE)) {\n block.add(this.statement());\n // Опционально пропускаем точку с запятой\n this.match(TokenType.SEMICOLON);\n }\n return block;\n }\n\n private statement(): Statement {\n const current = this.get(0);\n if (this.match(TokenType.VAR)) {\n return this.varStatement(current);\n }\n if (this.match(TokenType.PRINT)) {\n return new PrintStatement(this.expression(), current);\n }\n if (this.match(TokenType.IF)) {\n return this.ifElse(current);\n }\n if (this.match(TokenType.WHILE)) {\n return this.whileStatement(current);\n }\n if (this.match(TokenType.DO)) {\n return this.doWhileStatement(current);\n }\n if (this.match(TokenType.BREAK)) {\n return new BreakStatement(current);\n }\n if (this.match(TokenType.CONTINUE)) {\n return new ContinueStatement(current);\n }\n if (this.match(TokenType.RETURN)) {\n return new ReturnStatement(this.expression(), current);\n }\n if (this.match(TokenType.FOR)) {\n return this.forStatement(current);\n }\n if (this.match(TokenType.FUNCTION)) {\n return this.functionDefine(current);\n }\n if (this.lookMatch(0, TokenType.META_BLOCK)) {\n return this.metaBlock();\n }\n if (this.lookMatch(0, TokenType.WORD) && this.lookMatch(1, TokenType.LPAREN)) {\n return new FunctionStatement(this.functionExpression(current), current);\n }\n // Проверяем префиксные ++ и -- как statements\n if (this.match(TokenType.PLUSPLUS)) {\n const variable = new VariableExpression(this.consume(TokenType.WORD).getText(), current);\n return new IncrementStatement(\n new IncrementExpression(variable, IncrementType.PREFIX_INCREMENT, current),\n current,\n );\n }\n if (this.match(TokenType.MINUSMINUS)) {\n const variable = new VariableExpression(this.consume(TokenType.WORD).getText(), current);\n return new IncrementStatement(\n new IncrementExpression(variable, IncrementType.PREFIX_DECREMENT, current),\n current,\n );\n }\n // Проверяем постфиксные ++ и -- как statements\n if (\n this.lookMatch(0, TokenType.WORD) &&\n (this.lookMatch(1, TokenType.PLUSPLUS) || this.lookMatch(1, TokenType.MINUSMINUS))\n ) {\n const varToken = this.consume(TokenType.WORD);\n const varName = varToken.getText();\n if (this.match(TokenType.PLUSPLUS)) {\n throw new Error(\n `Postfix increment '${varName}++' is not supported. ` +\n `Use '${varName} = ${varName} + 1' instead. ` +\n `${varToken.toString()}`,\n );\n } else if (this.match(TokenType.MINUSMINUS)) {\n throw new Error(\n `Postfix decrement '${varName}--' is not supported. ` +\n `Use '${varName} = ${varName} - 1' instead. ` +\n `${varToken.toString()}`,\n );\n }\n }\n return this.assignmentStatement();\n }\n\n private static readonly RESERVED_WORDS = new Set([\n 'true',\n 'false',\n 'null',\n 'undefined',\n 'let',\n 'const',\n 'class',\n 'new',\n 'delete',\n 'typeof',\n 'instanceof',\n 'in',\n 'of',\n 'import',\n 'export',\n 'default',\n 'extends',\n 'super',\n 'this',\n 'void',\n 'throw',\n 'try',\n 'catch',\n 'finally',\n 'switch',\n 'case',\n 'with',\n 'debugger',\n 'yield',\n 'await',\n ]);\n\n private varStatement(token: Token): Statement {\n const declarators: VarDeclarator[] = [];\n\n do {\n const nameToken = this.consume(TokenType.WORD);\n const name = nameToken.getText();\n if (Parser.RESERVED_WORDS.has(name)) {\n throw new Error(\n `Variable name '${name}' is a reserved JavaScript keyword. ` +\n `Use a different name. ${nameToken.toString()}`,\n );\n }\n let init: Expression | null = null;\n\n if (this.match(TokenType.EQ)) {\n init = this.expression();\n }\n\n declarators.push({ name, init });\n } while (this.match(TokenType.COMMA));\n\n return new VarStatement(declarators, token);\n }\n\n private assignmentStatement(): Statement {\n const current = this.get(0);\n if (this.lookMatch(0, TokenType.WORD) && this.lookMatch(1, TokenType.EQ)) {\n // variable = expression\n const variable = this.consume(TokenType.WORD).getText();\n this.consume(TokenType.EQ);\n return new AssignmentStatement(variable, this.expression(), current);\n }\n if (this.lookMatch(0, TokenType.WORD) && this.lookMatch(1, TokenType.LBRACKET)) {\n // variable[index] = expression\n const array = this.elementExpression(current);\n this.consume(TokenType.EQ);\n return new ArrayAssignmentStatement(array, this.expression(), current);\n }\n throw new Error(`Unknown statement ${this.get(0)}`);\n }\n\n private ifElse(token: Token): Statement {\n const condition = this.expression();\n const ifStatement = this.statementOrBlock();\n\n let elseStatement: Statement | null;\n if (this.match(TokenType.ELSE)) {\n elseStatement = this.statementOrBlock();\n } else {\n elseStatement = null;\n }\n return new IfStatement(condition, ifStatement, elseStatement, token);\n }\n\n private doWhileStatement(token: Token): Statement {\n const statement = this.statementOrBlock();\n this.consume(TokenType.WHILE);\n const condition = this.expression();\n\n return new DoWhileStatement(condition, statement, token);\n }\n\n private whileStatement(token: Token): Statement {\n const condition = this.expression();\n const statement = this.statementOrBlock();\n return new WhileStatement(condition, statement, token);\n }\n\n private forStatement(token: Token): Statement {\n this.consume(TokenType.LPAREN);\n\n // Инициализация может быть только обычным присваиванием (var не поддерживается конвертером)\n let initialization: Statement;\n if (this.match(TokenType.VAR)) {\n throw new Error(\n `'var' in for-loop initialization is not supported by the Blockly converter. ` +\n `Use plain assignment: 'for (k = 1; k <= N; k = k + 1)'. ` +\n `${this.get(-1).toString()}`,\n );\n } else {\n initialization = this.assignmentStatement();\n }\n\n this.consume(TokenType.SEMICOLON);\n const termination = this.expression();\n this.consume(TokenType.SEMICOLON);\n const increment = this.statement();\n this.consume(TokenType.RPAREN);\n const block = this.statementOrBlock();\n return new ForStatement(initialization, termination, increment, block, token);\n }\n\n private functionDefine(token: Token): FunctionDefineStatement {\n const name = this.consume(TokenType.WORD).getText();\n this.consume(TokenType.LPAREN);\n const argNames = [];\n while (!this.match(TokenType.RPAREN)) {\n argNames.push(this.consume(TokenType.WORD).getText());\n this.match(TokenType.COMMA);\n }\n const body = this.statementOrBlock();\n return new FunctionDefineStatement(name, argNames, body, token);\n }\n\n private functionExpression(token: Token): FunctionalExpression {\n const name = this.consume(TokenType.WORD).getText();\n this.consume(TokenType.LPAREN);\n const func = new FunctionalExpression(name, [], token);\n while (!this.match(TokenType.RPAREN)) {\n func.addArgument(this.expression());\n this.match(TokenType.COMMA);\n }\n return func;\n }\n\n private elementExpression(token: Token): ArrayAccessExpression {\n // variable[index] || variable[index][index2][index3]\n const variable = this.consume(TokenType.WORD).getText();\n const indexes = [];\n do {\n this.consume(TokenType.LBRACKET);\n indexes.push(this.expression());\n this.consume(TokenType.RBRACKET);\n } while (this.lookMatch(0, TokenType.LBRACKET));\n return new ArrayAccessExpression(variable, indexes, token);\n }\n\n private arrayExpression(token: Token): Expression {\n // [1, 3, 4 + 4]\n this.consume(TokenType.LBRACKET);\n const elements: Expression[] = [];\n while (!this.match(TokenType.RBRACKET)) {\n elements.push(this.expression());\n this.match(TokenType.COMMA);\n }\n // this.consume(TokenType.RBRACKET);\n return new ArrayExpression(elements, token);\n }\n\n private objectExpression(token: Token): Expression {\n // {key: value, key2: value2}\n this.consume(TokenType.LBRACE);\n const properties = new Map<string, Expression>();\n\n while (!this.match(TokenType.RBRACE)) {\n // Получаем ключ - может быть WORD или TEXT (строка в кавычках)\n let key: string;\n if (this.lookMatch(0, TokenType.WORD)) {\n key = this.consume(TokenType.WORD).getText();\n } else if (this.lookMatch(0, TokenType.TEXT)) {\n key = this.consume(TokenType.TEXT).getText();\n } else {\n throw new Error('Expected property key (word or string)');\n }\n\n this.consume(TokenType.COLON);\n const value = this.expression();\n properties.set(key, value);\n\n // Опционально пропускаем запятую\n this.match(TokenType.COMMA);\n }\n\n return new ObjectExpression(properties, token);\n }\n\n private expression(): Expression {\n return this.logicalOr();\n }\n\n private logicalOr(): Expression {\n let result = this.logicalAnd();\n\n while (this.match(TokenType.BARBAR)) {\n const current = this.get(0);\n result = new ConditionalExpression(Operator.OR, result, this.logicalAnd(), current);\n }\n\n return result;\n }\n private logicalAnd(): Expression {\n let result = this.equality();\n\n while (this.match(TokenType.AMPAMP)) {\n const current = this.get(0);\n result = new ConditionalExpression(Operator.AND, result, this.equality(), current);\n }\n\n return result;\n }\n\n private equality(): Expression {\n const current = this.get(0);\n const result = this.conditional();\n\n if (this.match(TokenType.EQEQ)) {\n return new ConditionalExpression(Operator.EQ, result, this.conditional(), current);\n }\n if (this.match(TokenType.EXCLEQ)) {\n return new ConditionalExpression(Operator.NEQ, result, this.conditional(), current);\n }\n return result;\n }\n\n private conditional(): Expression {\n let result = this.additive();\n while (\n this.lookMatch(0, TokenType.LT) ||\n this.lookMatch(0, TokenType.LTEQ) ||\n this.lookMatch(0, TokenType.GT) ||\n this.lookMatch(0, TokenType.GTEQ)\n ) {\n const current = this.get(0);\n if (this.match(TokenType.LT)) {\n result = new ConditionalExpression(Operator.LT, result, this.additive(), current);\n continue;\n }\n if (this.match(TokenType.LTEQ)) {\n result = new ConditionalExpression(Operator.LTE, result, this.additive(), current);\n continue;\n }\n if (this.match(TokenType.GT)) {\n result = new ConditionalExpression(Operator.GT, result, this.additive(), current);\n continue;\n }\n if (this.match(TokenType.GTEQ)) {\n result = new ConditionalExpression(Operator.GTE, result, this.additive(), current);\n continue;\n }\n }\n return result;\n }\n\n private additive(): Expression {\n let result = this.multiplicate();\n while (this.lookMatch(0, TokenType.PLUS) || this.lookMatch(0, TokenType.MINUS)) {\n if (this.match(TokenType.PLUS)) {\n const opToken = this.get(-1);\n result = new BinaryExpression('+', result, this.multiplicate(), opToken);\n continue;\n }\n this.consume(TokenType.MINUS);\n const opToken = this.get(-1);\n result = new BinaryExpression('-', result, this.multiplicate(), opToken);\n }\n return result;\n }\n\n private multiplicate(): Expression {\n let result = this.unary();\n while (this.lookMatch(0, TokenType.STAR) || this.lookMatch(0, TokenType.SLASH)) {\n if (this.match(TokenType.STAR)) {\n const opToken = this.get(-1);\n result = new BinaryExpression('*', result, this.unary(), opToken);\n continue;\n }\n this.consume(TokenType.SLASH);\n const opToken = this.get(-1);\n result = new BinaryExpression('/', result, this.unary(), opToken);\n }\n return result;\n }\n\n private unary(): Expression {\n const current = this.get(0);\n if (this.match(TokenType.MINUS)) {\n return new UnaryExpression('-', this.primary(), current);\n }\n if (this.match(TokenType.PLUSPLUS)) {\n const variable = new VariableExpression(this.consume(TokenType.WORD).getText(), current);\n return new IncrementExpression(variable, IncrementType.PREFIX_INCREMENT, current);\n }\n if (this.match(TokenType.MINUSMINUS)) {\n const variable = new VariableExpression(this.consume(TokenType.WORD).getText(), current);\n return new IncrementExpression(variable, IncrementType.PREFIX_DECREMENT, current);\n }\n return this.primary();\n }\n\n private primary(): Expression {\n const current = this.get(0);\n if (this.match(TokenType.NUMBER)) {\n return new ValueExpression(current.getText(), current);\n }\n if (this.lookMatch(0, TokenType.WORD) && this.lookMatch(1, TokenType.LPAREN)) {\n return this.functionExpression(current);\n }\n if (this.lookMatch(0, TokenType.WORD) && this.lookMatch(1, TokenType.LBRACKET)) {\n return this.elementExpression(current);\n }\n if (this.lookMatch(0, TokenType.LBRACKET)) {\n return this.arrayExpression(current);\n }\n if (this.lookMatch(0, TokenType.LBRACE)) {\n return this.objectExpression(current);\n }\n if (this.match(TokenType.WORD)) {\n const variable = new VariableExpression(current.getText(), current);\n // Проверяем постфиксные операторы\n if (this.match(TokenType.PLUSPLUS)) {\n throw new Error(\n `Postfix increment '${current.getText()}++' is not supported. ` +\n `Use '${current.getText()} = ${current.getText()} + 1' instead. ` +\n `${current.toString()}`,\n );\n }\n if (this.match(TokenType.MINUSMINUS)) {\n throw new Error(\n `Postfix decrement '${current.getText()}--' is not supported. ` +\n `Use '${current.getText()} = ${current.getText()} - 1' instead. ` +\n `${current.toString()}`,\n );\n }\n return variable;\n }\n if (this.match(TokenType.TEXT)) {\n return new ValueExpression(current.getText(), current);\n }\n if (this.match(TokenType.LPAREN)) {\n const result = this.expression();\n this.match(TokenType.RPAREN);\n return result;\n }\n throw new Error(`Invalid token ${current}`);\n }\n\n private consume(type: TokenType): Token {\n const current = this.get(0);\n if (type != current.getType()) {\n throw new Error(`Token ${current} doesn't match token type ${TokenType[type]}`);\n }\n this.pos++;\n return current;\n }\n private match(type: TokenType): boolean {\n const current = this.get(0);\n if (type != current.getType()) {\n return false;\n }\n this.pos++;\n return true;\n }\n\n private lookMatch(pos: number, type: TokenType): boolean {\n return this.get(pos).getType() == type;\n }\n\n private get(relativePosition: number): Token {\n const position = this.pos + relativePosition;\n if (position >= this.size) {\n return this.EOF;\n }\n return this.tokens[position];\n }\n}\n","// ScenarioLoader — repository → parsed AST + helpers.\n// Pure orchestration: pulls source via ScenarioRepository, runs vendor/dsl\n// Lexer+Parser, returns the BlockStatement root. Also loads helpers via\n// HelperRepository so the linter and executor see the same namespace.\n\nimport { Lexer } from \"../../vendor/dsl/parser/lexer.ts\";\nimport { Parser } from \"../../vendor/dsl/parser/parser.ts\";\nimport {\n type BlockStatement,\n FunctionDefineStatement,\n} from \"../../vendor/dsl/parser/ast/index.ts\";\n\nimport type { ScenarioRepository, ScenarioSource } from \"./scenario-repository.ts\";\nimport type { HelperRepository, HelperSource } from \"./helper-repository.ts\";\n\n/** Per-name location of a user-function definition. Used by the linter to\n * emit E8 duplicate diagnostics with a precise path/line/col pointer. */\nexport interface UserFunctionOrigin {\n name: string;\n /** Source path (scenario name or helper relative path). */\n source: string;\n line: number;\n col: number;\n}\n\nexport interface LoadedScenario {\n source: ScenarioSource;\n ast: BlockStatement;\n /** Helper-file ASTs (Stage 2) — top-level FunctionDefineStatements merged\n * into one user-function namespace at lint/run time. */\n helpers: HelperSource[];\n /** Names of all top-level user-defined functions visible at lint time —\n * union of entry + helpers (deduplicated). */\n userFunctionNames: Set<string>;\n /** All FunctionDefineStatement origins across entry + helpers, NOT\n * deduplicated. Two entries with the same name = a duplicate the linter\n * must flag as E8. */\n userFunctionOrigins: UserFunctionOrigin[];\n}\n\nexport class ScenarioLoader {\n constructor(\n private readonly repo: ScenarioRepository,\n private readonly helpers: HelperRepository,\n ) {}\n\n async load(name: string): Promise<LoadedScenario> {\n const source = await this.repo.load(name);\n const tokens = new Lexer(source.source).tokenize();\n const ast = new Parser(tokens).parse();\n const helpers = await this.helpers.loadAll();\n\n const userFunctionOrigins: UserFunctionOrigin[] = [];\n collectOrigins(ast, name, userFunctionOrigins);\n for (const h of helpers) {\n collectOrigins(h.ast, h.path, userFunctionOrigins);\n }\n const userFunctionNames = new Set(userFunctionOrigins.map((o) => o.name));\n\n return { source, ast, helpers, userFunctionNames, userFunctionOrigins };\n }\n}\n\n/**\n * Compute the expected entry function name for a scenario id.\n *\n * Convention: `unotest/e2e/<path>/<basename>.js` → `test_<basename_snake>`.\n * Directory segments do NOT enter the function name — only the basename.\n * So `workouts/athlete-runs-todays-workout` → `test_athlete_runs_todays_workout`.\n */\nexport function resolveEntryFunctionName(scenarioName: string, prefix: \"test\" | \"flow\" = \"test\"): string {\n const lastSlash = scenarioName.lastIndexOf(\"/\");\n const basename = lastSlash >= 0 ? scenarioName.slice(lastSlash + 1) : scenarioName;\n return `${prefix}_${basename.replaceAll(\"-\", \"_\")}`;\n}\n\nfunction collectOrigins(\n program: BlockStatement,\n sourcePath: string,\n out: UserFunctionOrigin[],\n): void {\n for (const stmt of program.statements) {\n if (stmt instanceof FunctionDefineStatement) {\n const tok = (stmt.token as { getLine?: () => number; getColumn?: () => number } | undefined);\n out.push({\n name: stmt.name,\n source: sourcePath,\n line: tok?.getLine?.() ?? 0,\n col: tok?.getColumn?.() ?? 0,\n });\n }\n }\n}\n","// HelperRepository — loads project-level DSL helpers from\n// unotest/e2e/_helpers/**/*.js, parses each into a BlockStatement AST. The\n// executor pre-pass merges these helpers' top-level FunctionDefineStatements\n// with the entry scenario's top-level user functions into a single\n// UserFunctionResolver.\n//\n// Convention `_helpers/` (with leading underscore) is fixed — mirrors\n// established OSS conventions (Jekyll `_partials`, Next.js `_app.tsx`).\n// No declarative `useHelpers(...)` import syntax in MVP: all helper files\n// are visible to every scenario. If selective loading becomes a felt need,\n// it lands as an explicit, non-magical AST-level directive later.\n\nimport { readdir, readFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join, relative } from \"node:path\";\n\nimport { Lexer } from \"../../vendor/dsl/parser/lexer.ts\";\nimport { Parser } from \"../../vendor/dsl/parser/parser.ts\";\nimport type { BlockStatement } from \"../../vendor/dsl/parser/ast/index.ts\";\n\nexport interface HelperSource {\n /** Path relative to scenariosDir (e.g. \"_helpers/auth.js\"). For diagnostics. */\n path: string;\n /** Absolute path on disk. */\n absolutePath: string;\n /** Raw source as written by the author. */\n source: string;\n /** Parsed AST. */\n ast: BlockStatement;\n}\n\nexport interface HelperRepository {\n loadAll(): Promise<HelperSource[]>;\n}\n\nexport interface FileSystemHelperRepositoryDeps {\n scenariosDir: string;\n}\n\nexport class FileSystemHelperRepository implements HelperRepository {\n private readonly helpersDir: string;\n private readonly scenariosDir: string;\n\n constructor(deps: FileSystemHelperRepositoryDeps) {\n this.scenariosDir = deps.scenariosDir;\n this.helpersDir = join(deps.scenariosDir, \"_helpers\");\n }\n\n async loadAll(): Promise<HelperSource[]> {\n if (!existsSync(this.helpersDir)) return [];\n const files = await collectJsFiles(this.helpersDir);\n const out: HelperSource[] = [];\n for (const absolutePath of files) {\n const source = await readFile(absolutePath, \"utf8\");\n const tokens = new Lexer(source).tokenize();\n const ast = new Parser(tokens).parse();\n out.push({\n path: relative(this.scenariosDir, absolutePath),\n absolutePath,\n source,\n ast,\n });\n }\n return out;\n }\n}\n\nasync function collectJsFiles(dir: string): Promise<string[]> {\n const entries = await readdir(dir, { withFileTypes: true });\n const result: string[] = [];\n for (const entry of entries) {\n const abs = join(dir, entry.name);\n if (entry.isDirectory()) {\n result.push(...(await collectJsFiles(abs)));\n } else if (entry.isFile() && entry.name.endsWith(\".js\")) {\n result.push(abs);\n }\n }\n return result.sort();\n}\n","import { appendFileSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\n\nexport interface SessionAction {\n ts: string;\n tool: string;\n args: unknown;\n result?: \"ok\" | \"error\";\n error?: string;\n}\n\nexport class SessionRecorder {\n private readonly path: string;\n\n constructor(path: string) {\n this.path = resolve(process.cwd(), path);\n mkdirSync(dirname(this.path), { recursive: true });\n }\n\n record(action: Omit<SessionAction, \"ts\">): void {\n const entry: SessionAction = { ts: new Date().toISOString(), ...action };\n appendFileSync(this.path, JSON.stringify(entry) + \"\\n\");\n }\n\n reset(): void {\n writeFileSync(this.path, \"\");\n }\n\n getPath(): string {\n return this.path;\n }\n}\n","// DbClient facade — dispatches by DATABASE_URL.protocol to a per-driver impl.\n//\n// Drivers are peer-deps (optional) and lazy-imported in their per-file\n// modules. This file knows the URL scheme → driver-module mapping; it does\n// NOT import any driver type or runtime symbol.\n\nimport type { DbClient } from \"./db/types.ts\";\n\nexport type { DbClient, DbExecResult } from \"./db/types.ts\";\n\nexport async function createDbClient(databaseUrl: string): Promise<DbClient> {\n let protocol: string;\n try {\n protocol = new URL(databaseUrl).protocol;\n } catch {\n // sqlite::memory: is not a valid URL — handle as a special case.\n if (databaseUrl === \"sqlite::memory:\" || databaseUrl.startsWith(\"sqlite:\")) {\n protocol = \"sqlite:\";\n } else {\n throw new Error(`DATABASE_URL not a valid URL: ${databaseUrl}`);\n }\n }\n\n switch (protocol) {\n case \"postgresql:\":\n case \"postgres:\":\n return (await import(\"./db/pg-client.ts\")).create(databaseUrl);\n case \"mysql:\":\n case \"mysql2:\":\n return (await import(\"./db/mysql-client.ts\")).create(databaseUrl);\n case \"sqlite:\":\n case \"file:\":\n return (await import(\"./db/sqlite-client.ts\")).create(databaseUrl);\n default:\n throw new Error(\n `Unsupported DATABASE_URL scheme: \"${protocol}\". Supported: postgresql://, mysql://, sqlite://, file://`,\n );\n }\n}\n","import type { Logger } from \"../util/log.ts\";\n\nexport interface ApiCallOpts {\n method: \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n path: string;\n body?: unknown;\n token?: string;\n}\n\nexport interface ApiResponse<T = unknown> {\n status: number;\n ok: boolean;\n data: T;\n raw: string;\n}\n\nexport interface ApiClient {\n call<T = unknown>(opts: ApiCallOpts): Promise<ApiResponse<T>>;\n login(email: string, password: string): Promise<{ token: string; user: { id: string; email: string } }>;\n}\n\nexport function createApiClient(baseUrl: string, logger: Logger): ApiClient {\n const base = baseUrl.replace(/\\/$/, \"\");\n async function call<T>(opts: ApiCallOpts): Promise<ApiResponse<T>> {\n const url = `${base}${opts.path.startsWith(\"/\") ? \"\" : \"/\"}${opts.path}`;\n const headers: Record<string, string> = { \"content-type\": \"application/json\" };\n if (opts.token) headers[\"authorization\"] = `Bearer ${opts.token}`;\n logger.debug(`api ${opts.method} ${url}`);\n const res = await fetch(url, {\n method: opts.method,\n headers,\n body: opts.body === undefined ? undefined : JSON.stringify(opts.body),\n });\n const raw = await res.text();\n let data: unknown = raw;\n try {\n data = raw ? JSON.parse(raw) : null;\n } catch {\n /* keep raw */\n }\n return { status: res.status, ok: res.ok, data: data as T, raw };\n }\n\n async function login(email: string, password: string) {\n // UnoPeak login path verification: see init.md \"Implementation notes\".\n const res = await call<{ token?: string; accessToken?: string; user?: { id: string; email: string } }>({\n method: \"POST\",\n path: \"/auth/login\",\n body: { email, password },\n });\n if (!res.ok) {\n throw new Error(`login failed for ${email}: HTTP ${res.status} — ${res.raw.slice(0, 200)}`);\n }\n const token = res.data?.token ?? res.data?.accessToken;\n const user = res.data?.user;\n if (!token || !user) {\n throw new Error(\n `login response missing token/user for ${email}: ${res.raw.slice(0, 200)}`,\n );\n }\n return { token, user };\n }\n\n return { call, login };\n}\n","// ShellExecutor — execFile-style spawn без shell-interpretation.\n//\n// Args передаются массивом и попадают в child_process через argv напрямую —\n// никаких \\\" / | / $ / ; не интерпретируются shell'ом. Это блокирует\n// случайные shell-injection при подстановке test-args.\n//\n// Если кому-то реально нужны shell-pipes — пусть пишет `shell(\"sh\", \"-c\", \"...\")`\n// явно. Default — безопасно.\n\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nimport type { Logger } from \"../util/log.ts\";\n\nconst exec = promisify(execFile);\n\nexport interface ShellExecResult {\n stdout: string;\n stderr: string;\n exitCode: number;\n}\n\nexport interface ShellExecOptions {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n /** Hard cap on combined stdout buffer. Default 32MB. */\n maxBuffer?: number;\n /** Timeout (ms). Default 60_000. */\n timeoutMs?: number;\n}\n\nexport interface ShellExecutor {\n exec(cmd: string, args: string[], opts?: ShellExecOptions): Promise<ShellExecResult>;\n}\n\nexport interface NodeShellExecutorDeps {\n logger: Logger;\n /** Default cwd if call site doesn't pass one. */\n defaultCwd?: string;\n}\n\nexport class ShellExecError extends Error {\n constructor(\n public readonly cmd: string,\n public readonly args: string[],\n public readonly exitCode: number,\n public readonly stdout: string,\n public readonly stderr: string,\n ) {\n super(\n `shell(${cmd} ${args.join(\" \")}) exited ${exitCode}\\n` +\n `stderr: ${stderr.slice(-2000)}\\n` +\n `stdout: ${stdout.slice(-500)}`,\n );\n this.name = \"ShellExecError\";\n }\n}\n\nexport class NodeShellExecutor implements ShellExecutor {\n private readonly logger: Logger;\n private readonly defaultCwd: string | undefined;\n\n constructor(deps: NodeShellExecutorDeps) {\n this.logger = deps.logger;\n this.defaultCwd = deps.defaultCwd;\n }\n\n async exec(cmd: string, args: string[], opts: ShellExecOptions = {}): Promise<ShellExecResult> {\n const cwd = opts.cwd ?? this.defaultCwd;\n const maxBuffer = opts.maxBuffer ?? 32 * 1024 * 1024;\n const timeout = opts.timeoutMs ?? 60_000;\n\n this.logger.debug(`shell: ${cmd} ${args.join(\" \")} (cwd=${cwd ?? process.cwd()})`);\n\n try {\n const result = await exec(cmd, args, {\n cwd,\n env: opts.env,\n maxBuffer,\n timeout,\n });\n return { stdout: result.stdout, stderr: result.stderr, exitCode: 0 };\n } catch (e: unknown) {\n const err = e as { code?: number; stdout?: string; stderr?: string; message?: string };\n const exitCode = typeof err.code === \"number\" ? err.code : 1;\n throw new ShellExecError(cmd, args, exitCode, err.stdout ?? \"\", err.stderr ?? err.message ?? \"\");\n }\n }\n}\n","// Composition root — the **only** place the dependency graph is wired.\n//\n// Frontends (MCP server, CLI runner, future Electron IPC) MUST call\n// `await buildApp(...)` and consume `AppServices` through DI. They MUST NOT\n// `import` concrete classes (MaestroDriver, WdaDriver, ...).\n//\n// This is the seam at which the Electron migration becomes mechanical: the\n// engine is one `buildApp` call, and you can swap the EnvConfig source\n// (process.env → Electron settings) without touching downstream services.\n//\n// Forward-extension policy: new services land in `AppServices` and are wired\n// here. Domain slices live in `src/mcp/tools/services.interface.ts` (or\n// inline) and pick from `AppServices` via `Pick<>`, following the testoid5\n// pattern.\n//\n// Stage 0 changes:\n// - `buildApp` is async (multi-DB plugin uses `await import(...)`)\n// - `AppServices.close()` graceful teardown for db/etc.\n// - `shell` (ShellExecutor) added to services + TestRuntime\n// - `db` now via multi-driver plugin: pg/mysql/sqlite by DATABASE_URL\n\nimport type { EnvConfig } from \"./config/env.ts\";\nimport { loadEnv } from \"./config/env.ts\";\nimport type { Driver } from \"./driver/interfaces.ts\";\nimport { createDriver } from \"./driver/factory.ts\";\nimport { ActionDiffer } from \"./inspection/action-differ.ts\";\nimport { FailureExplainer } from \"./inspection/failure-explainer.ts\";\nimport { ScreenshotAnnotator } from \"./inspection/screenshot-annotator.ts\";\nimport { SelectorResolver } from \"./inspection/selector-resolver.ts\";\nimport { TreeInspector } from \"./inspection/tree-inspector.ts\";\nimport { AstExecutor } from \"./dsl/ast-executor.ts\";\nimport { DslLinter } from \"./dsl/linter.ts\";\nimport type { FunctionRegistry } from \"./dsl/function-registry.ts\";\nimport { buildDefaultRegistry } from \"./dsl/functions/index.ts\";\nimport { TestRuntimeManager } from \"./dsl/test-runtime-manager.ts\";\nimport { FileSystemScenarioRepository } from \"./runner/fs-scenario-repository.ts\";\nimport type { ScenarioRepository } from \"./runner/scenario-repository.ts\";\nimport { ScenarioLoader } from \"./runner/scenario-loader.ts\";\nimport { FileSystemHelperRepository, type HelperRepository } from \"./runner/helper-repository.ts\";\nimport { SessionRecorder } from \"./mcp/session-recorder.ts\";\nimport { createDbClient, type DbClient } from \"./fixtures/db.ts\";\nimport { createApiClient, type ApiClient } from \"./fixtures/api.ts\";\nimport { NodeShellExecutor, type ShellExecutor } from \"./fixtures/shell.ts\";\nimport { resolve } from \"node:path\";\nimport type { Logger } from \"./util/log.ts\";\nimport { createLogger } from \"./util/log.ts\";\n\nexport interface AppServices {\n envConfig: EnvConfig;\n logger: Logger;\n driver: Driver;\n treeInspector: TreeInspector;\n selectorResolver: SelectorResolver;\n screenshotAnnotator: ScreenshotAnnotator;\n actionDiffer: ActionDiffer;\n failureExplainer: FailureExplainer;\n functionRegistry: FunctionRegistry;\n astExecutor: AstExecutor;\n dslLinter: DslLinter;\n testRuntimeManager: TestRuntimeManager;\n scenarioRepository: ScenarioRepository;\n helperRepository: HelperRepository;\n scenarioLoader: ScenarioLoader;\n sessionRecorder: SessionRecorder;\n db: DbClient;\n api: ApiClient;\n shell: ShellExecutor;\n /** Graceful shutdown — closes pool / file handles. Idempotent. Errors\n * logged but not re-thrown (must not mask test failures in finally blocks). */\n close(): Promise<void>;\n}\n\nexport interface BuildAppOptions {\n // Optional overrides for testing / Electron embedding.\n envConfig?: EnvConfig;\n logger?: Logger;\n engine?: \"wda\";\n scenarioRepository?: ScenarioRepository;\n helperRepository?: HelperRepository;\n /** Path to scenarios dir. Default: <cwd>/unotest/e2e (consumer-project\n * layout). Override for embedded/Electron use or non-standard locations. */\n scenariosDir?: string;\n /** Override for tests — when set, use this DbClient instead of constructing one\n * from DATABASE_URL. */\n db?: DbClient;\n /** Override for tests — when set, use this ShellExecutor instead of the default. */\n shell?: ShellExecutor;\n}\n\nexport async function buildApp(opts: BuildAppOptions = {}): Promise<AppServices> {\n const envConfig = opts.envConfig ?? loadEnv();\n const logger = opts.logger ?? createLogger();\n const driver = createDriver({\n env: envConfig,\n logger,\n ...(opts.engine ? { engine: opts.engine } : {}),\n });\n const functionRegistry = buildDefaultRegistry();\n const astExecutor = new AstExecutor(functionRegistry);\n const dslLinter = new DslLinter({\n registry: functionRegistry,\n knownSlots: Object.keys(envConfig.simBySlot),\n });\n const testRuntimeManager = new TestRuntimeManager({\n logger: logger.child(\"rt-mgr\"),\n ttlMs: envConfig.pausedRuntimeTtlMs,\n onAbort: async (active) => {\n const slots = [...active.testRuntime.usedSlots];\n if (slots.length === 0) return;\n logger.child(\"rt-mgr\").debug(`abort ${active.id}: tearing down slots ${slots.join(\",\")}`);\n await Promise.allSettled(slots.map((slot) => active.testRuntime.driver.shutdown(slot)));\n },\n });\n const scenariosDirAbs = resolve(opts.scenariosDir ?? \"unotest/e2e\");\n const scenarioRepository =\n opts.scenarioRepository ??\n new FileSystemScenarioRepository({ scenariosDir: scenariosDirAbs });\n const helperRepository =\n opts.helperRepository ?? new FileSystemHelperRepository({ scenariosDir: scenariosDirAbs });\n const scenarioLoader = new ScenarioLoader(scenarioRepository, helperRepository);\n\n const sessionRecorder = new SessionRecorder(envConfig.SESSION_LOG_PATH);\n\n const db = opts.db ?? (await createDbClient(envConfig.DATABASE_URL));\n const api = createApiClient(envConfig.API_BASE_URL, logger.child(\"api\"));\n const shell = opts.shell ?? new NodeShellExecutor({\n logger: logger.child(\"shell\"),\n defaultCwd: envConfig.PROJECT_ROOT ?? process.cwd(),\n });\n\n const closeableLogger = logger.child(\"close\");\n let closed = false;\n\n return {\n envConfig,\n logger,\n driver,\n treeInspector: new TreeInspector(),\n selectorResolver: new SelectorResolver(),\n screenshotAnnotator: new ScreenshotAnnotator(),\n actionDiffer: new ActionDiffer(),\n failureExplainer: new FailureExplainer(),\n functionRegistry,\n astExecutor,\n dslLinter,\n testRuntimeManager,\n scenarioRepository,\n helperRepository,\n scenarioLoader,\n sessionRecorder,\n db,\n api,\n shell,\n async close() {\n if (closed) return;\n closed = true;\n try {\n await db.close();\n } catch (e) {\n closeableLogger.warn(`db.close() failed: ${(e as Error).message}`);\n }\n },\n };\n}\n","// SGR sequences only — never cursor-movement (`\\x1b[A`/`\\x1b[K`/etc), which\n// would mangle scrollback when output goes to a file or non-VT100 terminal.\n// Each painted span is wrapped with `\\x1b[0m` reset; spans must not be\n// nested (the inner reset would terminate the outer style).\nconst SGR = {\n reset: \"\\x1b[0m\",\n dim: \"\\x1b[2m\",\n bold: \"\\x1b[1m\",\n red: \"\\x1b[31m\",\n green: \"\\x1b[32m\",\n yellow: \"\\x1b[33m\",\n blue: \"\\x1b[34m\",\n magenta: \"\\x1b[35m\",\n cyan: \"\\x1b[36m\",\n boldCyan: \"\\x1b[1;36m\",\n} as const;\n\nexport type ColorName = Exclude<keyof typeof SGR, \"reset\">;\n\n// De-facto NO_COLOR standard (https://no-color.org) — any non-empty value\n// disables colors. FORCE_COLOR forces them on even when stdout isn't a TTY\n// (useful for tools that capture stdout but want ANSI preserved).\nexport function colorsEnabled(): boolean {\n if (process.env.NO_COLOR) return false;\n if (process.env.FORCE_COLOR) return true;\n return Boolean(process.stdout.isTTY);\n}\n\nexport function paint(color: ColorName, s: string): string {\n if (!colorsEnabled()) return s;\n return `${SGR[color]}${s}${SGR.reset}`;\n}\n\nexport interface Logger {\n info(msg: string, ...rest: unknown[]): void;\n warn(msg: string, ...rest: unknown[]): void;\n error(msg: string, ...rest: unknown[]): void;\n debug(msg: string, ...rest: unknown[]): void;\n step(msg: string, ...rest: unknown[]): void;\n child(prefix: string): Logger;\n}\n\nexport function createLogger(prefix = \"\"): Logger {\n const p = prefix ? `${paint(\"dim\", `[${prefix}]`)} ` : \"\";\n return {\n info: (m, ...r) => console.log(`${p}${m}`, ...r),\n warn: (m, ...r) => console.warn(`${p}${paint(\"yellow\", \"warn\")} ${m}`, ...r),\n error: (m, ...r) => console.error(`${p}${paint(\"red\", \"error\")} ${m}`, ...r),\n debug: (m, ...r) => {\n if (process.env.E2E_DEBUG) console.log(`${p}${paint(\"dim\", \"debug\")} ${m}`, ...r);\n },\n step: (m, ...r) => console.log(`${p}${paint(\"cyan\", \"→\")} ${m}`, ...r),\n child: (sub: string) => createLogger(prefix ? `${prefix}/${sub}` : sub),\n };\n}\n","// The 11 \"legacy\" MCP tools (devices_list, screenshot, a11y_tree, tap, type,\n// press_key, swipe, open_deeplink, app_launch, wait_for, session_reset) ported\n// from registerXxx(server, deps) free-functions to BaseTool classes.\n//\n// Co-located in one file because each is small and they share three identical\n// imports. The conventional one-tool-per-file split was useful when the\n// original 11 each had bespoke try/catch + recorder wiring; with BaseTool's\n// `tracked()` helper most are ~10 lines.\n\nimport { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\n\nimport { BaseTool } from \"./base.tool.ts\";\nimport { SelectorParam, SelectorParamOptional } from \"./selector-param.ts\";\nimport type { AppServices } from \"../../composition-root.ts\";\nimport { listSimulators } from \"../../driver/ios-utils.ts\";\n\ntype DeviceSlice = Pick<AppServices, \"driver\" | \"envConfig\" | \"sessionRecorder\">;\ntype DeviceListSlice = Pick<AppServices, \"envConfig\" | \"sessionRecorder\">;\ntype SessionSlice = Pick<AppServices, \"sessionRecorder\">;\n\n// ---------------------------------------------------------------------------\n\nexport class DevicesListTool extends BaseTool<DeviceListSlice> {\n register(server: McpServer): void {\n server.registerTool(\n \"devices_list\",\n {\n title: \"List simulators\",\n description: \"Lists iOS simulators with state. Annotates each slot from .env (A/B → SIM_X_NAME).\",\n inputSchema: {},\n },\n async () =>\n this.tracked(\"devices_list\", {}, async () => {\n const sims = await listSimulators();\n const byName = new Map(sims.map((s) => [s.name, s]));\n const slots = Object.entries(this.services.envConfig.simBySlot).map(([slot, name]) => {\n const info = byName.get(name);\n return {\n slot,\n name,\n state: info?.state ?? \"Missing\",\n udid: info?.udid ?? null,\n runtime: info?.runtime ?? null,\n };\n });\n return this.okJson({\n slots,\n all: sims.map((s) => ({ name: s.name, state: s.state, udid: s.udid, runtime: s.runtime })),\n });\n }),\n );\n }\n}\n\n// ---------------------------------------------------------------------------\n\nexport class ScreenshotTool extends BaseTool<DeviceSlice> {\n register(server: McpServer): void {\n server.registerTool(\n \"screenshot\",\n {\n title: \"Screenshot\",\n description:\n \"Returns a PNG screenshot of the device as MCP image content (inline base64). Does not write to disk.\",\n inputSchema: { device: z.string().describe(\"device slot, e.g. 'A'\") },\n },\n async ({ device }) =>\n this.tracked(\"screenshot\", { device }, async () => {\n const buf = await this.services.driver.screenshot(device);\n return {\n content: [\n { type: \"image\" as const, data: buf.toString(\"base64\"), mimeType: \"image/png\" },\n ],\n };\n }),\n );\n }\n}\n\n// ---------------------------------------------------------------------------\n\ntype A11yTreeSlice = Pick<AppServices, \"driver\" | \"treeInspector\" | \"sessionRecorder\">;\n\nexport class A11yTreeTool extends BaseTool<A11yTreeSlice> {\n register(server: McpServer): void {\n server.registerTool(\n \"a11y_tree\",\n {\n title: \"Accessibility tree\",\n description:\n \"Returns the accessibility hierarchy. mode='compact' (default) drops layout-only nodes (no testId/text/label and no interactive role), strips bounds/enabled/focused/non-interactive role, indexes duplicate testIds with @N suffix, and includes _meta at the root. mode='full' returns the raw tree.\",\n inputSchema: {\n device: z.string(),\n mode: z.enum([\"compact\", \"full\"]).optional(),\n },\n },\n async ({ device, mode }) => {\n const m = mode ?? \"compact\";\n return this.tracked(\"a11y_tree\", { device, mode: m }, async () => {\n const raw = await this.services.driver.a11yTree(device);\n const out = this.services.treeInspector.withMode(raw, m);\n return this.okJson(out);\n });\n },\n );\n }\n}\n\n// ---------------------------------------------------------------------------\n\nexport class TapTool extends BaseTool<DeviceSlice> {\n register(server: McpServer): void {\n server.registerTool(\n \"tap\",\n {\n title: \"Tap\",\n description: \"Tap on a selector (testId | text | label | ordinal | pointPercent).\",\n inputSchema: { device: z.string(), selector: SelectorParam },\n },\n async ({ device, selector }) =>\n this.tracked(\"tap\", { device, selector }, async () => {\n await this.services.driver.tap(device, selector);\n return this.ok(`tap ok on ${device}`);\n }),\n );\n }\n}\n\n// ---------------------------------------------------------------------------\n\nexport class TypeTool extends BaseTool<DeviceSlice> {\n register(server: McpServer): void {\n server.registerTool(\n \"type\",\n {\n title: \"Type text\",\n description: \"Tap the input by selector and type text.\",\n inputSchema: { device: z.string(), selector: SelectorParam, text: z.string() },\n },\n async ({ device, selector, text }) =>\n this.tracked(\"type\", { device, selector, text }, async () => {\n await this.services.driver.type(device, selector, text);\n return this.ok(`type ok on ${device}`);\n }),\n );\n }\n}\n\n// ---------------------------------------------------------------------------\n\nexport class PressKeyTool extends BaseTool<DeviceSlice> {\n register(server: McpServer): void {\n server.registerTool(\n \"press_key\",\n {\n title: \"Press key\",\n description: \"Press a system key: back | home | enter | escape. (iOS has no native back; the tool will surface a clear error.)\",\n inputSchema: {\n device: z.string(),\n key: z.enum([\"back\", \"home\", \"enter\", \"escape\"]),\n },\n },\n async ({ device, key }) =>\n this.tracked(\"press_key\", { device, key }, async () => {\n await this.services.driver.pressKey(device, key);\n return this.ok(`pressKey ${key} on ${device}`);\n }),\n );\n }\n}\n\n// ---------------------------------------------------------------------------\n\nexport class SwipeTool extends BaseTool<DeviceSlice> {\n register(server: McpServer): void {\n server.registerTool(\n \"swipe\",\n {\n title: \"Swipe\",\n description: \"Swipe in a direction, optionally anchored at a selector.\",\n inputSchema: {\n device: z.string(),\n direction: z.enum([\"up\", \"down\", \"left\", \"right\"]),\n from: SelectorParamOptional,\n },\n },\n async ({ device, direction, from }) =>\n this.tracked(\"swipe\", { device, direction, from }, async () => {\n await this.services.driver.swipe(device, direction, from);\n return this.ok(`swipe ${direction} on ${device}`);\n }),\n );\n }\n}\n\n// ---------------------------------------------------------------------------\n\nexport class OpenDeeplinkTool extends BaseTool<DeviceSlice> {\n register(server: McpServer): void {\n server.registerTool(\n \"open_deeplink\",\n {\n title: \"Open deep link\",\n description: \"Open a URL on the device (custom URL scheme / universal link).\",\n inputSchema: { device: z.string(), url: z.string() },\n },\n async ({ device, url }) =>\n this.tracked(\"open_deeplink\", { device, url }, async () => {\n await this.services.driver.openDeeplink(device, url);\n return this.ok(`open_deeplink on ${device}: ${url}`);\n }),\n );\n }\n}\n\n// ---------------------------------------------------------------------------\n\nexport class AppLaunchTool extends BaseTool<DeviceSlice> {\n register(server: McpServer): void {\n server.registerTool(\n \"app_launch\",\n {\n title: \"Launch app\",\n description: \"Launch the app under test; clean=true terminates the running process and starts cold (D-3 fix: no uninstall — preserves the dev-client).\",\n inputSchema: {\n device: z.string(),\n bundleId: z.string().optional(),\n clean: z.boolean().optional(),\n },\n },\n async ({ device, bundleId, clean }) =>\n this.tracked(\"app_launch\", { device, bundleId, clean }, async () => {\n const opts: { bundleId?: string; clean?: boolean } = {};\n if (bundleId !== undefined) opts.bundleId = bundleId;\n if (clean !== undefined) opts.clean = clean;\n await this.services.driver.appLaunch(device, opts);\n return this.ok(`app_launch on ${device}${clean ? \" (clean)\" : \"\"}`);\n }),\n );\n }\n}\n\n// ---------------------------------------------------------------------------\n\nexport class WaitForTool extends BaseTool<DeviceSlice> {\n register(server: McpServer): void {\n server.registerTool(\n \"wait_for\",\n {\n title: \"Wait for selector\",\n description: \"Poll the a11y tree until a selector becomes visible.\",\n inputSchema: {\n device: z.string(),\n selector: SelectorParam,\n timeoutMs: z.number().int().positive().optional(),\n optional: z.boolean().optional(),\n },\n },\n async ({ device, selector, timeoutMs, optional }) =>\n this.tracked(\"wait_for\", { device, selector, timeoutMs, optional }, async () => {\n const opts: { timeoutMs?: number; optional?: boolean } = {};\n if (timeoutMs !== undefined) opts.timeoutMs = timeoutMs;\n if (optional !== undefined) opts.optional = optional;\n const visible = await this.services.driver.waitFor(device, selector, opts);\n return this.ok(`wait_for ${visible ? \"visible\" : \"absent\"} on ${device}`);\n }),\n );\n }\n}\n\n// ---------------------------------------------------------------------------\n\nexport class SessionResetTool extends BaseTool<SessionSlice> {\n register(server: McpServer): void {\n server.registerTool(\n \"session_reset\",\n {\n title: \"Reset session log\",\n description: \"Truncate the MCP session log (session.jsonl).\",\n inputSchema: {},\n },\n async () => {\n this.services.sessionRecorder.reset();\n return this.ok(`session log reset: ${this.services.sessionRecorder.getPath()}`);\n },\n );\n }\n}\n","// BaseTool — pattern lifted from testoid5/apps/unotest/src/modules/mcp.\n//\n// Each tool extends this class, declares its services slice via the type\n// parameter, and registers itself against an MCP server. The class itself is\n// minimal — it exists to:\n// 1. Enforce ISP: getServices<Slice>() returns a narrowed AppServices.\n// 2. Centralize the wrapping convention (try/catch → tool error result).\n//\n// New tools land by `class FooTool extends BaseTool<FooSlice> { register(...) }`.\n\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\n\nimport type { AppServices } from \"../../composition-root.ts\";\n\nexport type Slice<K extends keyof AppServices> = Pick<AppServices, K>;\n\nexport abstract class BaseTool<S extends Partial<AppServices>> {\n protected readonly services: S;\n\n constructor(services: S) {\n this.services = services;\n }\n\n /** Each tool registers itself against the MCP server. */\n abstract register(server: McpServer): void;\n\n protected ok(text: string) {\n return { content: [{ type: \"text\" as const, text }] };\n }\n\n protected okJson(obj: unknown) {\n return this.ok(JSON.stringify(obj, null, 2));\n }\n\n protected fail(text: string): { isError: true; content: [{ type: \"text\"; text: string }] } {\n return { isError: true, content: [{ type: \"text\" as const, text }] };\n }\n\n protected failJson(obj: unknown) {\n return this.fail(JSON.stringify(obj, null, 2));\n }\n\n /**\n * Wrap a tool invocation so any thrown Error becomes a structured failure\n * response rather than crashing the MCP server.\n */\n protected async safe<T>(fn: () => Promise<T>): Promise<T | { isError: true; content: [{ type: \"text\"; text: string }] }> {\n try {\n return await fn();\n } catch (e: unknown) {\n return this.fail(e instanceof Error ? e.message : String(e));\n }\n }\n\n /**\n * Wrap `fn` with session-log recording AND error→fail conversion. The\n * recorder lives on AppServices (Phase 8 addition); slices that include it\n * get tracking for free, slices that don't simply skip recording.\n *\n * Use this from concrete tool `register` callbacks — the convention saves\n * 4-5 lines of boilerplate per tool.\n */\n protected async tracked<T>(\n toolName: string,\n args: unknown,\n fn: () => Promise<T>,\n ): Promise<T | { isError: true; content: [{ type: \"text\"; text: string }] }> {\n const recorder = (this.services as { sessionRecorder?: { record: (entry: { tool: string; args: unknown; result: \"ok\" | \"error\"; error?: string }) => void } })\n .sessionRecorder;\n try {\n const out = await fn();\n if (recorder) recorder.record({ tool: toolName, args, result: \"ok\" });\n return out;\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n if (recorder) recorder.record({ tool: toolName, args, result: \"error\", error: msg });\n return this.fail(msg);\n }\n }\n}\n","// Zod schema for the MCP `selector` parameter. Lives in its own module so the\n// 11 tools that take a selector can share one schema without depending on a\n// \"_shared\" grab-bag.\n//\n// D-10 + D-16: selector accepts testId / text / label / ordinal. Older\n// `pointPercent` escape hatch is preserved for backwards-compat with the few\n// JSON scenarios that may still reference it; new code uses near()/ordinal()\n// instead.\n\nimport { z } from \"zod\";\n\nexport const SelectorShape = {\n testId: z.string().optional(),\n text: z.string().optional(),\n label: z.string().optional(),\n ordinal: z.number().int().nonnegative().optional(),\n pointPercent: z\n .object({\n x: z.number().min(0).max(1),\n y: z.number().min(0).max(1),\n })\n .optional(),\n} as const;\n\n// Some MCP clients (Claude Code among them, observed empirically) serialize\n// nested-object tool params as a JSON string instead of an object. Accept\n// both — preprocess parses string → object, then the normal zod schema\n// validates shape.\nfunction coerceJsonObject(v: unknown): unknown {\n if (typeof v !== \"string\") return v;\n try {\n return JSON.parse(v);\n } catch {\n return v; // let zod surface the real shape error\n }\n}\n\nexport const SelectorParam = z.preprocess(\n coerceJsonObject,\n z.object(SelectorShape).refine(\n (s) => Boolean(s.testId || s.text || s.label || s.pointPercent),\n { message: \"selector requires one of testId/text/label/pointPercent\" },\n ),\n);\n\nexport const SelectorParamOptional = z.preprocess(coerceJsonObject, z.object(SelectorShape).optional());\n","// New in Phase 6 — AI-first failure-recovery tool.\n//\n// Given a Selector, returns either the matched node OR up to 3 near-misses\n// with reasons. Removes the need for Claude to round-trip a11y_tree + diff\n// when a `tap` fails.\n\nimport { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\n\nimport { BaseTool } from \"./base.tool.ts\";\nimport type { SelectorResolverSlice } from \"./services.interface.ts\";\n\nconst SelectorInput = z.preprocess(\n (v) => (typeof v === \"string\" ? safeJsonParse(v) : v),\n z.object({\n testId: z.string().optional(),\n text: z.string().optional(),\n label: z.string().optional(),\n ordinal: z.number().int().nonnegative().optional(),\n }),\n);\n\nfunction safeJsonParse(s: string): unknown {\n try {\n return JSON.parse(s);\n } catch {\n return s;\n }\n}\n\nexport class ResolveSelectorTool extends BaseTool<SelectorResolverSlice> {\n register(server: McpServer): void {\n server.registerTool(\n \"resolve_selector\",\n {\n title: \"Resolve selector against current screen\",\n description:\n \"Returns either the matched A11yNode or up to 3 near-misses (with score + reason). Use this when a tap/type fails to understand which element is actually on screen. Selector shape: {testId?, text?, label?, ordinal?}.\",\n inputSchema: {\n device: z.string(),\n selector: SelectorInput,\n },\n },\n async ({ device, selector }) =>\n this.safe(async () => {\n const tree = await this.services.driver.a11yTree(device);\n const r = this.services.selectorResolver.resolve(tree, selector);\n if (r.ok) {\n return this.okJson({\n status: \"found\",\n node: r.node,\n });\n }\n return this.okJson({\n status: \"miss\",\n reason: r.reason,\n candidates: r.candidates.map((c) => ({\n node: c.node,\n score: c.score,\n reason: c.reason,\n })),\n });\n }),\n );\n }\n}\n","// 6 debugger tools (D-17) consolidated in one module — they share the\n// DebuggerSlice and a common run-id arg shape, so co-locating them keeps the\n// surface readable.\n\nimport { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\n\nimport { BaseTool } from \"./base.tool.ts\";\nimport type { DebuggerSlice } from \"./services.interface.ts\";\nimport { TestRuntime } from \"../../dsl/runtime.ts\";\nimport { resolveEntryFunctionName } from \"../../runner/scenario-loader.ts\";\nimport { randomUUID } from \"node:crypto\";\n\nexport class RunTestTool extends BaseTool<DebuggerSlice> {\n register(server: McpServer): void {\n server.registerTool(\n \"run_test\",\n {\n title: \"Run a DSL scenario (with optional step/pause modes)\",\n description:\n \"Loads unotest/e2e/<name>.js, parses + lints, then runs the function 'test_<name>' through AstExecutor. mode='auto' runs to completion or failure; mode='step' pauses after every statement. pauseOnFailure (default true) keeps simulators and WDA sessions alive on error so they can be inspected.\",\n inputSchema: {\n name: z.string(),\n mode: z.enum([\"auto\", \"step\"]).optional(),\n pauseOnFailure: z.boolean().optional(),\n maxSteps: z.number().int().positive().optional(),\n maxDurationMs: z.number().int().positive().optional(),\n },\n },\n async ({ name, mode, pauseOnFailure, maxSteps, maxDurationMs }) =>\n this.safe(async () => {\n const { scenarioLoader, dslLinter, astExecutor, testRuntimeManager, envConfig, logger, driver, selectorResolver, treeInspector, failureExplainer, screenshotAnnotator, actionDiffer, db, api, shell } = this.services;\n\n const loaded = await scenarioLoader.load(name);\n const entryDiags = dslLinter.lint(loaded.ast, loaded.source.source, {\n userFunctionNames: loaded.userFunctionNames,\n });\n const helperDiags = loaded.helpers.flatMap((h) =>\n dslLinter.lintHelper(h, { userFunctionNames: loaded.userFunctionNames }),\n );\n const crossDiags = dslLinter.lintCrossFile(loaded.userFunctionOrigins);\n const diags = [...entryDiags, ...helperDiags, ...crossDiags];\n const errors = diags.filter((d) => d.severity === \"error\");\n if (errors.length > 0) {\n return this.failJson({ status: \"lint_failed\", errors, warnings: diags.filter((d) => d.severity === \"warning\") });\n }\n\n // Entry function name follows the basename of the scenario id —\n // directory segments are stripped (e.g. workouts/foo → test_foo).\n const testFn = resolveEntryFunctionName(name);\n if (!loaded.userFunctionNames.has(testFn)) {\n return this.failJson({\n status: \"entry_not_found\",\n message: `Entry function \"${testFn}\" not found in ${name}.js. ` +\n `Convention: unotest/e2e/${name}.js → function ${testFn}().`,\n });\n }\n\n const runId = `e2e-${randomUUID().slice(0, 8)}`;\n const runtime = new TestRuntime({\n runId,\n envConfig,\n logger: logger.child(runId),\n driver,\n selectorResolver,\n treeInspector,\n failureExplainer,\n screenshotAnnotator,\n actionDiffer,\n artifactsDir: envConfig.ARTIFACTS_DIR,\n db,\n api,\n shell,\n });\n\n const runOptions = {\n mode: mode ?? \"auto\" as const,\n pauseOnFailure: pauseOnFailure ?? true,\n ...(maxSteps !== undefined ? { maxSteps } : {}),\n ...(maxDurationMs !== undefined ? { maxDurationMs } : {}),\n };\n const generator = astExecutor.run(\n loaded.ast,\n testFn,\n runtime,\n runOptions,\n loaded.helpers.map((h) => h.ast),\n );\n\n const runtimeId = testRuntimeManager.register({\n scenarioName: name,\n testFn,\n testRuntime: runtime,\n generator,\n runOptions,\n });\n\n const next = await testRuntimeManager.pump(runtimeId);\n return this.okJson({ status: \"started\", runtimeId, next });\n }),\n );\n }\n}\n\nexport class StepTool extends BaseTool<DebuggerSlice> {\n register(server: McpServer): void {\n server.registerTool(\n \"step\",\n {\n title: \"Advance one statement in a paused runtime\",\n description: \"After paused-step or paused-failure, advances the executor by one statement. On failure-retry: re-runs the failed statement.\",\n inputSchema: { runtimeId: z.string() },\n },\n async ({ runtimeId }) =>\n this.safe(async () => {\n const next = await this.services.testRuntimeManager.step(runtimeId);\n return this.okJson({ next });\n }),\n );\n }\n}\n\nexport class ResumeTool extends BaseTool<DebuggerSlice> {\n register(server: McpServer): void {\n server.registerTool(\n \"resume\",\n {\n title: \"Resume a paused runtime back to auto-execution\",\n description: \"After paused-failure: re-executes the failed statement (D-17 Resume semantics) and continues until completion or next failure. After paused-step: advances and continues.\",\n inputSchema: { runtimeId: z.string() },\n },\n async ({ runtimeId }) =>\n this.safe(async () => {\n const next = await this.services.testRuntimeManager.resume(runtimeId);\n return this.okJson({ next });\n }),\n );\n }\n}\n\nexport class InspectRuntimeTool extends BaseTool<DebuggerSlice> {\n register(server: McpServer): void {\n server.registerTool(\n \"inspect_runtime\",\n {\n title: \"Snapshot of a paused runtime\",\n description: \"Returns vars, current device, last event, last result for the given runtimeId. Resets the TTL timer.\",\n inputSchema: { runtimeId: z.string() },\n },\n async ({ runtimeId }) =>\n this.safe(async () => {\n return this.okJson(this.services.testRuntimeManager.inspect(runtimeId));\n }),\n );\n }\n}\n\nexport class AbortRuntimeTool extends BaseTool<DebuggerSlice> {\n register(server: McpServer): void {\n server.registerTool(\n \"abort_runtime\",\n {\n title: \"Tear down a runtime (sessions + sims)\",\n description: \"Cleanly stops the generator and runs onAbort cleanup. After this call the runtime is forgotten.\",\n inputSchema: { runtimeId: z.string() },\n },\n async ({ runtimeId }) =>\n this.safe(async () => {\n await this.services.testRuntimeManager.abort(runtimeId);\n return this.okJson({ status: \"aborted\", runtimeId });\n }),\n );\n }\n}\n\nexport class ListRuntimesTool extends BaseTool<DebuggerSlice> {\n register(server: McpServer): void {\n server.registerTool(\n \"list_runtimes\",\n {\n title: \"List active and paused runtimes\",\n description: \"Useful when several tests have been kicked off — find the one that failed and is awaiting inspection.\",\n inputSchema: {},\n },\n async () =>\n this.safe(async () => {\n return this.okJson({ runtimes: this.services.testRuntimeManager.list() });\n }),\n );\n }\n}\n","// VariableScope — snapshot push/pop scoping for DSL variables.\n//\n// Semantics modeled on ownlang Variables.java (lesson-10):\n// - push() saves a shallow copy of the current scope onto a stack\n// - pop() restores the saved scope (mutations during the pushed frame\n// are discarded)\n// - reads see the current frame only\n//\n// Use case: user-function call boundary. caller pushes before binding\n// args + running body; pops on return. Helper-internal var mutations don't\n// leak back to caller. Return values flow through ReturnSignal, not vars.\n\nimport type { DslValue } from \"./runtime.ts\";\n\nexport class VariableScope {\n private stack: Map<string, DslValue>[] = [];\n private current = new Map<string, DslValue>();\n\n push(): void {\n this.stack.push(new Map(this.current));\n }\n\n pop(): void {\n const popped = this.stack.pop();\n if (popped === undefined) throw new Error(\"VariableScope.pop(): underflow (more pops than pushes)\");\n this.current = popped;\n }\n\n get(name: string): DslValue | undefined {\n return this.current.get(name);\n }\n\n has(name: string): boolean {\n return this.current.has(name);\n }\n\n set(name: string, value: DslValue): void {\n this.current.set(name, value);\n }\n\n toObject(): Record<string, DslValue> {\n return Object.fromEntries(this.current.entries());\n }\n\n /** Depth of the push-stack. 0 at construction; +1 per push, -1 per pop. */\n depth(): number {\n return this.stack.length;\n }\n}\n","// TestRuntime — per-test state isolated from any other concurrent test.\n//\n// What lives here:\n// - `vars`: assignment store (DSL `x = dbQuery(...)` writes here).\n// - `currentDeviceSlot`: the slot picked by the most recent `setDevice(...)`.\n// - `runId`: unique id propagated to artifact paths and DB fixture prefixes.\n// - injected services: driver/inspection/logger — so DSL functions never\n// reach into module-level globals.\n//\n// Reach-through: DSL functions get a Runtime via the FunctionRegistry's\n// `invoke(ctx, ...)` call, NOT via module imports. This makes parallel runtimes\n// (two paused-failed tests being inspected by Claude at the same time) trivial.\n\nimport type { Logger } from \"../util/log.ts\";\nimport type { Driver } from \"../driver/interfaces.ts\";\nimport type { EnvConfig } from \"../config/env.ts\";\nimport type { SelectorResolver } from \"../inspection/selector-resolver.ts\";\nimport type { TreeInspector } from \"../inspection/tree-inspector.ts\";\nimport type { FailureExplainer } from \"../inspection/failure-explainer.ts\";\nimport type { ScreenshotAnnotator } from \"../inspection/screenshot-annotator.ts\";\nimport type { ActionDiffer } from \"../inspection/action-differ.ts\";\nimport type { DbClient } from \"../fixtures/db.ts\";\nimport type { ApiClient } from \"../fixtures/api.ts\";\nimport type { ShellExecutor } from \"../fixtures/shell.ts\";\nimport { VariableScope } from \"./variable-scope.ts\";\n\nexport type DslValue = string | number | boolean | null;\n\nexport interface TestRuntimeDeps {\n runId: string;\n envConfig: EnvConfig;\n logger: Logger;\n driver: Driver;\n selectorResolver: SelectorResolver;\n treeInspector: TreeInspector;\n failureExplainer: FailureExplainer;\n screenshotAnnotator: ScreenshotAnnotator;\n actionDiffer: ActionDiffer;\n artifactsDir: string;\n db: DbClient;\n api: ApiClient;\n shell: ShellExecutor;\n /** Injectable clock — defaults to Date.now. Tests pass a fake. */\n nowFn?: () => number;\n}\n\nexport class TestRuntime {\n readonly runId: string;\n readonly envConfig: EnvConfig;\n readonly logger: Logger;\n readonly driver: Driver;\n readonly selectorResolver: SelectorResolver;\n readonly treeInspector: TreeInspector;\n readonly failureExplainer: FailureExplainer;\n readonly screenshotAnnotator: ScreenshotAnnotator;\n readonly actionDiffer: ActionDiffer;\n readonly artifactsDir: string;\n readonly db: DbClient;\n readonly api: ApiClient;\n readonly shell: ShellExecutor;\n private readonly nowFn: () => number;\n private readonly scope = new VariableScope();\n private _currentDeviceSlot: string | null = null;\n // Every slot ever set via setDevice() during this runtime. Used by\n // TestRuntimeManager.onAbort to know which sims/sessions to tear down —\n // multi-device scenarios touch more than one slot, single-slot ones touch one.\n private readonly _usedSlots = new Set<string>();\n // User-function call depth — guarded by RunOptions.maxCallDepth. Lives here\n // (per-runtime), not on the executor singleton, to avoid cross-run leakage.\n private _callDepth = 0;\n\n constructor(deps: TestRuntimeDeps) {\n this.runId = deps.runId;\n this.envConfig = deps.envConfig;\n this.logger = deps.logger;\n this.driver = deps.driver;\n this.selectorResolver = deps.selectorResolver;\n this.treeInspector = deps.treeInspector;\n this.failureExplainer = deps.failureExplainer;\n this.screenshotAnnotator = deps.screenshotAnnotator;\n this.actionDiffer = deps.actionDiffer;\n this.artifactsDir = deps.artifactsDir;\n this.db = deps.db;\n this.api = deps.api;\n this.shell = deps.shell;\n this.nowFn = deps.nowFn ?? Date.now;\n }\n\n /** Current epoch ms — injectable for deterministic tests. */\n now(): number {\n return this.nowFn();\n }\n\n /** Variable scope stack — push/pop on user-function call boundaries. */\n pushScope(): void {\n this.scope.push();\n }\n popScope(): void {\n this.scope.pop();\n }\n\n /** User-function call depth — separate budget from maxSteps. */\n enterCall(maxCallDepth: number): void {\n if (this._callDepth >= maxCallDepth) {\n throw new Error(`maxCallDepth budget (${maxCallDepth}) exhausted`);\n }\n this._callDepth++;\n }\n exitCall(): void {\n if (this._callDepth <= 0) throw new Error(\"callDepth underflow\");\n this._callDepth--;\n }\n get callDepth(): number {\n return this._callDepth;\n }\n\n setVar(name: string, value: DslValue): void {\n this.scope.set(name, value);\n }\n\n getVar(name: string): DslValue {\n if (!this.scope.has(name)) {\n throw new Error(`Variable \"${name}\" is not defined`);\n }\n return this.scope.get(name)!;\n }\n\n hasVar(name: string): boolean {\n return this.scope.has(name);\n }\n\n /** Returns a snapshot for `inspect_runtime` MCP tool. */\n snapshotVars(): Record<string, DslValue> {\n return this.scope.toObject();\n }\n\n get currentDeviceSlot(): string {\n if (!this._currentDeviceSlot) {\n throw new Error(\n `No device selected. Call setDevice('coach' | 'athlete' | ...) before UI actions.`,\n );\n }\n return this._currentDeviceSlot;\n }\n\n setCurrentDeviceSlot(slot: string): void {\n if (!this.envConfig.simBySlot[slot]) {\n const known = Object.keys(this.envConfig.simBySlot).join(\", \") || \"(none)\";\n throw new Error(`Unknown device slot \"${slot}\". Known: ${known}`);\n }\n this._currentDeviceSlot = slot;\n this._usedSlots.add(slot);\n }\n\n /** Slots that were ever activated via setDevice() during this runtime. */\n get usedSlots(): ReadonlySet<string> {\n return this._usedSlots;\n }\n}\n","// MCP tool registration — single entry point. Every tool is a class extending\n// BaseTool with a narrow services slice (Pick<AppServices, ...>); composition\n// root wires them through here.\n//\n// Phase 8 review fix #4: legacy `registerXxx(server, deps)` functions and\n// `_shared.ts` are GONE. All 18 tools (11 legacy + resolve_selector + 6\n// debugger) live under BaseTool now.\n\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\n\nimport type { AppServices } from \"../../composition-root.ts\";\n\nimport {\n A11yTreeTool,\n AppLaunchTool,\n DevicesListTool,\n OpenDeeplinkTool,\n PressKeyTool,\n ScreenshotTool,\n SessionResetTool,\n SwipeTool,\n TapTool,\n TypeTool,\n WaitForTool,\n} from \"./legacy.tool.ts\";\nimport { ResolveSelectorTool } from \"./resolve-selector.tool.ts\";\nimport {\n AbortRuntimeTool,\n InspectRuntimeTool,\n ListRuntimesTool,\n ResumeTool,\n RunTestTool,\n StepTool,\n} from \"./debugger.tool.ts\";\n\nexport function registerAllTools(server: McpServer, services: AppServices): void {\n // 11 legacy tools, now under BaseTool.\n new DevicesListTool({ envConfig: services.envConfig, sessionRecorder: services.sessionRecorder }).register(server);\n new ScreenshotTool({ driver: services.driver, envConfig: services.envConfig, sessionRecorder: services.sessionRecorder }).register(server);\n new A11yTreeTool({ driver: services.driver, treeInspector: services.treeInspector, sessionRecorder: services.sessionRecorder }).register(server);\n new TapTool({ driver: services.driver, envConfig: services.envConfig, sessionRecorder: services.sessionRecorder }).register(server);\n new TypeTool({ driver: services.driver, envConfig: services.envConfig, sessionRecorder: services.sessionRecorder }).register(server);\n new PressKeyTool({ driver: services.driver, envConfig: services.envConfig, sessionRecorder: services.sessionRecorder }).register(server);\n new SwipeTool({ driver: services.driver, envConfig: services.envConfig, sessionRecorder: services.sessionRecorder }).register(server);\n new OpenDeeplinkTool({ driver: services.driver, envConfig: services.envConfig, sessionRecorder: services.sessionRecorder }).register(server);\n new AppLaunchTool({ driver: services.driver, envConfig: services.envConfig, sessionRecorder: services.sessionRecorder }).register(server);\n new WaitForTool({ driver: services.driver, envConfig: services.envConfig, sessionRecorder: services.sessionRecorder }).register(server);\n new SessionResetTool({ sessionRecorder: services.sessionRecorder }).register(server);\n\n // AI-first tools (Phase 6).\n new ResolveSelectorTool({\n driver: services.driver,\n selectorResolver: services.selectorResolver,\n treeInspector: services.treeInspector,\n screenshotAnnotator: services.screenshotAnnotator,\n failureExplainer: services.failureExplainer,\n logger: services.logger,\n }).register(server);\n\n const dbgServices = {\n testRuntimeManager: services.testRuntimeManager,\n scenarioLoader: services.scenarioLoader,\n dslLinter: services.dslLinter,\n astExecutor: services.astExecutor,\n envConfig: services.envConfig,\n logger: services.logger,\n driver: services.driver,\n selectorResolver: services.selectorResolver,\n treeInspector: services.treeInspector,\n screenshotAnnotator: services.screenshotAnnotator,\n actionDiffer: services.actionDiffer,\n failureExplainer: services.failureExplainer,\n db: services.db,\n api: services.api,\n shell: services.shell,\n };\n new RunTestTool(dbgServices).register(server);\n new StepTool(dbgServices).register(server);\n new ResumeTool(dbgServices).register(server);\n new InspectRuntimeTool(dbgServices).register(server);\n new AbortRuntimeTool(dbgServices).register(server);\n new ListRuntimesTool(dbgServices).register(server);\n}\n"],"mappings":"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","names":["create","create","xctestrun","require","execFile","promisify","exec","promisify","execFile","resolve","cached","dist","TokenType","line","col","isBlockMappable","asString","near","asSelector","asString","asNumber","readFileSync","join","join","readFileSync","text","opToken","readdir","existsSync","join","join","existsSync","readdir","mkdirSync","dirname","resolve","resolve","mkdirSync","dirname","execFile","promisify","exec","promisify","execFile","resolve","resolve","shell","z","z","z","z","z","z","z","z","shell","loaded"]}
|