@refrainai/cli 0.4.1 → 0.4.3
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/dist/{ai-model-FM6GWCID.js → ai-model-DP5PKGM6.js} +2 -2
- package/dist/{chunk-IGFCYKHC.js → chunk-5CKPPEYP.js} +262 -305
- package/dist/chunk-5CKPPEYP.js.map +1 -0
- package/dist/{chunk-7UCVPKD4.js → chunk-6FGCPMBU.js} +34 -74
- package/dist/chunk-6FGCPMBU.js.map +1 -0
- package/dist/{chunk-2BVDAJZT.js → chunk-A5X2VF5G.js} +9 -6
- package/dist/chunk-A5X2VF5G.js.map +1 -0
- package/dist/{chunk-H47NWH7N.js → chunk-AOCGSFRM.js} +611 -73
- package/dist/chunk-AOCGSFRM.js.map +1 -0
- package/dist/{chunk-CLYJHKPY.js → chunk-CMWLFQXD.js} +43 -42
- package/dist/chunk-CMWLFQXD.js.map +1 -0
- package/dist/chunk-GC7I5SGK.js +1146 -0
- package/dist/chunk-GC7I5SGK.js.map +1 -0
- package/dist/{chunk-WEYR56ZN.js → chunk-HHRHHFSK.js} +4 -4
- package/dist/chunk-IGJNT457.js +30 -0
- package/dist/chunk-IGJNT457.js.map +1 -0
- package/dist/{chunk-UGPXCQY3.js → chunk-KFNW4XR2.js} +13 -4
- package/dist/chunk-KFNW4XR2.js.map +1 -0
- package/dist/{chunk-RT664YIO.js → chunk-LZDZGI4M.js} +3 -1
- package/dist/chunk-LZDZGI4M.js.map +1 -0
- package/dist/{chunk-RYIJPYM3.js → chunk-MYITSQYV.js} +25 -8
- package/dist/chunk-MYITSQYV.js.map +1 -0
- package/dist/chunk-NRKZJVPE.js +74 -0
- package/dist/chunk-NRKZJVPE.js.map +1 -0
- package/dist/chunk-RBZK7T76.js +349 -0
- package/dist/chunk-RBZK7T76.js.map +1 -0
- package/dist/{chunk-HQDXLWAY.js → chunk-SDV3X5UN.js} +2 -2
- package/dist/{chunk-Z33FCOTZ.js → chunk-VVXNFUPL.js} +4 -2
- package/dist/chunk-VVXNFUPL.js.map +1 -0
- package/dist/chunk-YTVEYQGA.js +64 -0
- package/dist/chunk-YTVEYQGA.js.map +1 -0
- package/dist/{chunk-DJVUITRB.js → chunk-ZEBQWBEU.js} +898 -1135
- package/dist/chunk-ZEBQWBEU.js.map +1 -0
- package/dist/cli.js +5 -5
- package/dist/{compose-MTSIJY5D.js → compose-AVX5RU67.js} +9 -7
- package/dist/{compose-MTSIJY5D.js.map → compose-AVX5RU67.js.map} +1 -1
- package/dist/extraction-prompt-VDCKIFLB.js +17 -0
- package/dist/extraction-prompt-VDCKIFLB.js.map +1 -0
- package/dist/{fix-runbook-ZSBOTLC2.js → fix-runbook-6L5ZMA5G.js} +12 -10
- package/dist/{fix-runbook-ZSBOTLC2.js.map → fix-runbook-6L5ZMA5G.js.map} +1 -1
- package/dist/prompts-AGUYYIOM.js +13 -0
- package/dist/runbook-builder-2ZLE2AEO.js +11 -0
- package/dist/{runbook-data-helpers-KRR2SH76.js → runbook-data-helpers-5UAO65TZ.js} +3 -3
- package/dist/{runbook-executor-K7T6RJWJ.js → runbook-executor-OJXJTN6A.js} +41 -444
- package/dist/runbook-executor-OJXJTN6A.js.map +1 -0
- package/dist/{runbook-generator-MPXJBQ5N.js → runbook-generator-UIHWBEYC.js} +61 -136
- package/dist/runbook-generator-UIHWBEYC.js.map +1 -0
- package/dist/{runbook-schema-3T6TP3JJ.js → runbook-schema-X7DW725O.js} +2 -2
- package/dist/runbook-store-S24PXIHD.js +11 -0
- package/dist/{schema-5G6UQSPT.js → schema-XFSD5EWN.js} +2 -2
- package/dist/{server-AG3LXQBI.js → server-MULT5ZWG.js} +1176 -128
- package/dist/server-MULT5ZWG.js.map +1 -0
- package/dist/{tenant-ai-config-QPFEJUVJ.js → tenant-ai-config-4NHKRW7O.js} +4 -4
- package/dist/tenant-ai-config-4NHKRW7O.js.map +1 -0
- package/dist/yaml-patcher-GOCLYKZZ.js +18 -0
- package/dist/yaml-patcher-GOCLYKZZ.js.map +1 -0
- package/package.json +3 -2
- package/dist/chunk-2BVDAJZT.js.map +0 -1
- package/dist/chunk-7UCVPKD4.js.map +0 -1
- package/dist/chunk-CLYJHKPY.js.map +0 -1
- package/dist/chunk-DJVUITRB.js.map +0 -1
- package/dist/chunk-H47NWH7N.js.map +0 -1
- package/dist/chunk-IGFCYKHC.js.map +0 -1
- package/dist/chunk-RT664YIO.js.map +0 -1
- package/dist/chunk-RYIJPYM3.js.map +0 -1
- package/dist/chunk-UGPXCQY3.js.map +0 -1
- package/dist/chunk-VPK2MQAZ.js +0 -589
- package/dist/chunk-VPK2MQAZ.js.map +0 -1
- package/dist/chunk-Z33FCOTZ.js.map +0 -1
- package/dist/runbook-executor-K7T6RJWJ.js.map +0 -1
- package/dist/runbook-generator-MPXJBQ5N.js.map +0 -1
- package/dist/runbook-store-G5GUOWRR.js +0 -11
- package/dist/server-AG3LXQBI.js.map +0 -1
- package/dist/yaml-patcher-VGUS2JGH.js +0 -15
- /package/dist/{ai-model-FM6GWCID.js.map → ai-model-DP5PKGM6.js.map} +0 -0
- /package/dist/{chunk-WEYR56ZN.js.map → chunk-HHRHHFSK.js.map} +0 -0
- /package/dist/{chunk-HQDXLWAY.js.map → chunk-SDV3X5UN.js.map} +0 -0
- /package/dist/{runbook-data-helpers-KRR2SH76.js.map → prompts-AGUYYIOM.js.map} +0 -0
- /package/dist/{runbook-schema-3T6TP3JJ.js.map → runbook-builder-2ZLE2AEO.js.map} +0 -0
- /package/dist/{runbook-store-G5GUOWRR.js.map → runbook-data-helpers-5UAO65TZ.js.map} +0 -0
- /package/dist/{schema-5G6UQSPT.js.map → runbook-schema-X7DW725O.js.map} +0 -0
- /package/dist/{tenant-ai-config-QPFEJUVJ.js.map → runbook-store-S24PXIHD.js.map} +0 -0
- /package/dist/{yaml-patcher-VGUS2JGH.js.map → schema-XFSD5EWN.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/runbook-executor/types.ts","../../../src/plan/errors.ts","../../../src/plan/key-kind.ts","../../../src/plan/debug-token.ts","../../../src/plan/key-cache.ts","../../../src/plan/key-validator.ts","../../../src/plan/index.ts","../../../src/harness/selector-cache.ts","../../../src/runbook-executor/executor.ts","../../../src/harness/selector-resolver.ts","../../../src/harness/failure-registry.ts","../../../src/harness/goal-agent.ts","../../../src/harness/vision-resolver.ts","../../../src/harness/action-validator.ts","../../../src/harness/deterministic-resolver.ts","../../../src/harness/confirmation.ts","../../../src/runbook-executor/confirmation.ts","../../../src/context/capture-handler.ts","../../../src/context/expression-evaluator.ts","../../../src/context/snapshot-cache.ts","../../../src/context/context-chunker.ts","../../../src/runbook-executor/input-collector.ts","../../../src/runbook-executor/execution-planner.ts","../../../src/context/runtime-store.ts","../../../src/messaging/chat-bot.ts","../../../src/messaging/config.ts","../../../src/runbook-executor/self-heal-analyzer.ts","../../../src/messaging/cards.ts"],"sourcesContent":["/**\n * runbook-executor 型定義\n *\n * シリアライズ型(YAML ↔ メモリ)は Zod スキーマから推論。\n * ランタイム専用型(実行結果、設定等)は interface で定義。\n */\n\nimport type { SecretsData } from \"../cli/secrets-loader\";\nimport type { AIModelConfig } from \"../harness/ai-model\";\nimport type { Plan } from \"../plan\";\nimport type { z } from \"zod\";\nimport type {\n ActionTypeSchema,\n RiskLevelSchema,\n VariableSourceSchema,\n CaptureStrategySchema,\n SelectorSchema,\n StepCaptureSchema,\n LoopDefinitionSchema,\n VariableDefinitionSchema,\n DataSourceConfigSchema,\n StepActionSchema,\n ParsedStepSchema,\n ParsedRunbookSchema,\n AggregateOperationSchema,\n MemoryOperationSchema,\n BranchDefinitionShape,\n} from \"../schemas/runbook-schema\";\n\n// ── Zod スキーマから推論した型 ──\n\nexport type Selector = z.infer<typeof SelectorSchema>;\nexport type ActionType = z.infer<typeof ActionTypeSchema>;\nexport type RiskLevel = z.infer<typeof RiskLevelSchema>;\nexport type VariableSource = z.infer<typeof VariableSourceSchema>;\nexport type CaptureStrategy = z.infer<typeof CaptureStrategySchema>;\nexport type StepCapture = z.infer<typeof StepCaptureSchema>;\nexport type LoopDefinition = z.infer<typeof LoopDefinitionSchema>;\nexport type VariableDefinition = z.infer<typeof VariableDefinitionSchema>;\nexport type DataSourceConfig = z.infer<typeof DataSourceConfigSchema>;\nexport type AggregateOperation = z.infer<typeof AggregateOperationSchema>;\nexport type MemoryOperation = z.infer<typeof MemoryOperationSchema>;\nexport type StepAction = z.infer<typeof StepActionSchema>;\nexport type ParsedStep = z.infer<typeof ParsedStepSchema>;\nexport type ParsedRunbook = z.infer<typeof ParsedRunbookSchema>;\nexport type BranchDefinition = BranchDefinitionShape;\n\n// ── エラー分類 ──\n\nexport type {\n FailureCategory,\n ClassificationContext,\n} from \"../harness/error-classifier\";\nexport { classifyFailure, getRecoveryHint } from \"../harness/error-classifier\";\n\n// ── ランタイム専用型 ──\n\nexport interface ResolvedVariables {\n values: Map<string, string>;\n sensitiveKeys: Set<string>;\n}\n\nexport interface ExecutionStrategy {\n /** セレクタ解決のリトライ上限 */\n maxRetries: number;\n /** attempt 1〜N のスナップショット変化待機タイムアウト (ms) */\n changeTimeouts: number[];\n /** 最終リトライ前の sleep (ms) */\n finalRetryStabilizeMs: number;\n /** 最終リトライの DOM stability 待機 (ms) */\n domStabilityMs: number;\n}\n\nexport interface ExecutorConfig {\n runbookPath: string;\n headless: boolean;\n stepDelay?: number;\n screenshotDir?: string;\n contextMarkdown: string;\n skipConfirmation: boolean;\n /** CSV/JSON データファイルパス */\n dataFilePath?: string;\n /** secrets JSON から読み込んだ秘密情報 */\n secrets?: SecretsData;\n /** バッチ時にブラウザセッションを再利用するか (default: true) */\n reuseSession?: boolean;\n /** デバッグログ出力先ファイルパス */\n debugLogPath?: string;\n /** --debug フラグ: コンソールにデバッグ情報を出力 */\n debugConsole?: boolean;\n /** 承認モード (default: \"web\") */\n approvalMode?: \"web\" | \"slack\" | \"teams\" | \"discord\";\n /** 完了通知モード (default: undefined = 通知なし) */\n notifyMode?: \"slack\" | \"teams\" | \"discord\";\n /** Webhook コールバックポート (default: 3100) */\n callbackPort?: number;\n /** 承認タイムアウト (ms) (default: 300000) */\n approvalTimeoutMs?: number;\n /** リトライ戦略の上書き(debug モード等で使用) */\n executionStrategy?: ExecutionStrategy;\n /** リトライ警告閾値(この回数以上リトライしたステップを警告対象にする) */\n retryWarningThreshold?: number;\n /** セレクタキャッシュを有効にするか (default: plan で許可されていれば true) */\n enableSelectorCache?: boolean;\n /** Agent Fallback を有効にするか (default: plan で許可されていれば true) */\n enableAgentFallback?: boolean;\n /** Vision Fallback を有効にするか (default: plan で許可されていれば true) */\n enableVisionFallback?: boolean;\n /** ダウンロード・出力ファイルの保存先ディレクトリ */\n outputDir?: string;\n /** ダウンロードしたCSVファイルを結合するか (default: false) */\n mergeDownloads?: boolean;\n /** 自動修正モード(探索強度を上げ、失敗分析・修正提案を行う) */\n selfHeal?: boolean;\n /** リトライ上限(selfHealモード時, default: 5) */\n maxRetries?: number;\n /** --report: 成功時にもレポートファイルを出力する */\n forceReport: boolean;\n /** 動画録画の出力先ディレクトリ */\n videoDir?: string;\n /** AIモデル設定 */\n aiModelConfig: AIModelConfig;\n /** プラン(ティア・制限・機能ゲート) */\n plan?: Plan;\n /** API キー */\n apiKey?: string;\n /** バリデーション API サーバー URL(opaque キー用) */\n apiServerUrl?: string;\n /** キャッシュを無視してバリデーション API に再問い合わせする */\n refreshKey?: boolean;\n /** ステルスモード(bot検出回避パッチ適用) */\n stealth?: boolean;\n /** プロキシ URL (e.g. http://user:pass@host:port) */\n proxy?: string;\n /** Skill 名リスト(YAML metadata or --skill CLI から取得) */\n skills?: string[];\n}\n\nexport type StepStatus = \"success\" | \"failed\" | \"skipped\";\n\nexport interface StepExecutionResult {\n ordinal: number;\n description: string;\n status: StepStatus;\n durationMs: number;\n error?: string;\n /** キャプチャされた値 */\n capturedValues?: Record<string, string>;\n /** 条件評価によりスキップされた */\n conditionSkipped?: boolean;\n /** ループ実行回数 */\n loopIterations?: number;\n /** ループ内サブステップの結果(イテレーションごと) */\n subStepResults?: StepExecutionResult[][];\n /** ブランチマッチ結果(マッチした case の match 値、または \"default\") */\n branchMatch?: string;\n /** forEach で処理したアイテム数 */\n forEachItemCount?: number;\n /** セレクタ解決のリトライ回数(0 = リトライなし) */\n retryCount?: number;\n /** リトライの詳細情報(debug 分析用) */\n retryDetails?: StepRetryDetail[];\n /** エラー分類カテゴリ */\n failureCategory?: import(\"../harness/error-classifier\").FailureCategory;\n /** 実行されたアクションタイプ(レポート・アサーション用) */\n actionType?: string;\n /** extract アクションで取得したデータ */\n extractedData?: string;\n /** download アクションでダウンロードしたファイルパス */\n downloadedFile?: string;\n /** export アクションで出力したファイルパス */\n exportedFile?: string;\n /** 失敗時のフル診断情報 */\n diagnostics?: StepDiagnostics;\n\n // ── テレメトリ用フィールド ──\n\n /** セレクタ解決に成功した方法 */\n resolveMethod?: \"cache\" | \"deterministic\" | \"ai\" | \"scroll\" | \"vision\" | \"agent\" | null;\n /** 決定論的リゾルバのマッチタイプ */\n deterministicMatchType?: string;\n /** 決定論的リゾルバの信頼度 (0-1) */\n deterministicConfidence?: number;\n /** 使用されたコンテキストチャンク数 */\n contextChunksUsed?: number;\n /** FailureRegistry からヒント注入有無 */\n failureHintsProvided?: boolean;\n /** ワーキングメモリの推定トークン数 */\n workingMemoryTokens?: number;\n /** スナップショット内の要素数 */\n snapshotElementCount?: number;\n}\n\nexport interface StepRetryDetail {\n attempt: number;\n snapshotChanged: boolean;\n snapshotElementCount: number;\n failureReason: string;\n aiReasoning?: string;\n /** AI に送ったプロンプト(セレクタ解決用) */\n aiPrompt?: string;\n /** AI のレスポンス全文 */\n aiResponse?: string;\n /** リトライ時のスナップショットプレビュー(先頭 N 文字) */\n snapshotPreview?: string;\n}\n\n/** 失敗ステップに付帯するフル診断情報 */\nexport interface StepDiagnostics {\n /** 最終スナップショットのプレビュー */\n lastSnapshotPreview?: string;\n /** 失敗履歴(各試行の理由) */\n failureHistory?: string[];\n /** 最終AIレスポンス全文 */\n lastAiResponseText?: string;\n /** エラー分類のリカバリヒント */\n recoveryHint?: string;\n /** 決定論的セレクタ解決の試行結果 */\n deterministicResolveResult?: string;\n /** Vision Fallback の分析結果 */\n visionFallbackResult?: {\n annotationCount: number;\n reasoning: string;\n success: boolean;\n };\n /** Agent Fallback の分析結果 */\n agentFallbackResult?: {\n strategy: string;\n analysis: string;\n reasoning: string;\n success: boolean;\n };\n /** バリデーション警告 */\n validationWarnings?: string[];\n /** バリデーションエラー */\n validationErrors?: string[];\n /** 使用した実行戦略 */\n executionStrategy?: {\n maxRetries: number;\n changeTimeouts: number[];\n finalRetryStabilizeMs: number;\n domStabilityMs: number;\n };\n /** ステップのアクション定義(早期リターンエラー時の診断用) */\n stepAction?: {\n type: string;\n selector?: Record<string, unknown>;\n value?: string;\n url?: string;\n };\n /** ステップの対象URL */\n stepUrl?: string;\n}\n\nexport interface ExecutionReport {\n runbookTitle: string;\n startUrl: string;\n totalSteps: number;\n executed: number;\n succeeded: number;\n failed: number;\n skipped: number;\n aborted: boolean;\n steps: StepExecutionResult[];\n totalDurationMs: number;\n /** メモリコレクション一覧(名前 → アイテム数) */\n memoryCollections?: Record<string, number>;\n /** ダウンロードしたファイルパス一覧 */\n downloadedFiles?: string[];\n /** 動画録画の出力先パス一覧 */\n videoPaths?: string[];\n /** AI メトリクスサマリー */\n aiMetrics?: import(\"../harness/ai-metrics\").AIMetricsSummary;\n}\n\nexport interface BatchExecutionReport {\n runbookTitle: string;\n totalRows: number;\n succeeded: number;\n failed: number;\n rows: { rowIndex: number; rowLabel: string; report: ExecutionReport }[];\n totalDurationMs: number;\n}\n\n// ── 自動修正モード ──\n\n/** self-heal モード時の共通デフォルト値 */\nexport const SELF_HEAL_DEFAULTS = {\n enableSelectorCache: true,\n enableAgentFallback: true,\n enableVisionFallback: true,\n maxRetries: 5,\n retryWarningThreshold: 3,\n} as const;\n\n/**\n * Partial な ExecutorConfig に共通デフォルト + self-heal 展開を適用する(破壊的更新)。\n * ユーザーが明示指定した値は上書きしない(??= による null/undefined ガード)。\n */\nexport function applyExecutorDefaults(\n config: Partial<ExecutorConfig> & { selfHeal?: boolean },\n): void {\n if (config.selfHeal) {\n config.enableSelectorCache ??= SELF_HEAL_DEFAULTS.enableSelectorCache;\n config.enableAgentFallback ??= SELF_HEAL_DEFAULTS.enableAgentFallback;\n config.enableVisionFallback ??= SELF_HEAL_DEFAULTS.enableVisionFallback;\n config.maxRetries ??= SELF_HEAL_DEFAULTS.maxRetries;\n config.retryWarningThreshold ??= SELF_HEAL_DEFAULTS.retryWarningThreshold;\n config.executionStrategy ??= buildSelfHealStrategy(config.maxRetries);\n config.skipConfirmation ??= true;\n }\n}\n\n/**\n * 自動修正モード用のアグレッシブなリトライ戦略を構築する。\n * 変化待機タイムアウトを maxRetries - 1 個分生成(最終は DOM 安定化フェーズ)\n */\nexport function buildSelfHealStrategy(maxRetries: number): ExecutionStrategy {\n const changeTimeoutCount = Math.max(maxRetries - 1, 0);\n const changeTimeouts: number[] = [];\n for (let i = 0; i < changeTimeoutCount; i++) {\n changeTimeouts.push(8000 + i * 2000); // 8s, 10s, 12s, 14s, ...\n }\n return {\n maxRetries,\n changeTimeouts,\n finalRetryStabilizeMs: 5000,\n domStabilityMs: 8000,\n };\n}\n\n// ── Debug レポート(定義は self-heal-types.ts) ──\n\nexport type { DebugReport, DebugStepWarning, DebugSuggestion } from \"./self-heal-types\";\n","/**\n * plan/errors --- プラン制限・機能ゲートのエラー型\n */\n\n/** 制限超過の種別 */\nexport type LimitType = \"hard\" | \"quota_exceeded\" | \"timeout\";\n\n/** ステップ数・バッチ行数などの数値制限超過 */\nexport class PlanLimitError extends Error {\n /** 制限種別(デフォルト: \"hard\") */\n readonly limitType: LimitType;\n\n constructor(message: string, limitType: LimitType = \"hard\") {\n super(message);\n this.name = \"PlanLimitError\";\n this.limitType = limitType;\n }\n}\n\n/** 月間クォータ超過(PlanLimitError のサブクラス) */\nexport class QuotaExceededError extends PlanLimitError {\n /** 現在の使用量 */\n readonly currentUsage: number;\n /** 制限値 */\n readonly limit: number;\n /** 超過したメトリクス名(例: \"monthlyJobs\", \"monthlySteps\") */\n readonly metric: string;\n\n constructor(message: string, currentUsage: number, limit: number, metric: string) {\n super(message, \"quota_exceeded\");\n this.name = \"QuotaExceededError\";\n this.currentUsage = currentUsage;\n this.limit = limit;\n this.metric = metric;\n }\n}\n\n/** ゲート対象機能の利用試行 */\nexport class PlanFeatureError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"PlanFeatureError\";\n }\n}\n","/**\n * plan/key-kind --- API キー種別判定\n *\n * rfn_ = opaque(本番用、サーバーバリデーション)\n * rfnd- = debug(閉域網 PoC 用、オフライン Enterprise)\n */\n\nexport type ApiKeyKind = \"opaque\" | \"debug\";\n\n/**\n * API キー文字列からキー種別を判定する。\n * 不明なプレフィックスの場合は undefined を返す。\n */\nexport function detectKeyKind(key: string): ApiKeyKind | undefined {\n if (key.startsWith(\"rfn_\")) return \"opaque\";\n if (key.startsWith(\"rfnd-\")) return \"debug\";\n return undefined;\n}\n","/**\n * plan/debug-token --- デバッグトークン生成・検証\n *\n * Ed25519 署名 + AES-256-GCM 暗号化のハイブリッド設計。\n * お客様にシークレットを渡さず、公開鍵のみでオフライン検証を実現する。\n *\n * 暗号方式:\n * - Ed25519 秘密鍵: サーバー側のみ(トークン署名)\n * - Ed25519 公開鍵: バイナリ埋め込み(トークン検証)\n * - AES-256 鍵: SHA-256(公開鍵) から自動導出(ペイロード暗号化)\n */\n\nimport {\n createHash,\n createCipheriv,\n createDecipheriv,\n randomBytes,\n sign,\n verify,\n createPublicKey,\n createPrivateKey,\n} from \"node:crypto\";\n\n// ── 定数 ──\n\n/** デバッグトークンのプレフィックス */\nconst DEBUG_PREFIX = \"rfnd-\";\n\n/** AES-GCM の IV サイズ(12 bytes) */\nconst IV_SIZE = 12;\n\n/** AES-GCM の AuthTag サイズ(16 bytes) */\nconst AUTH_TAG_SIZE = 16;\n\n/** Ed25519 署名サイズ(64 bytes) */\nconst SIGNATURE_SIZE = 64;\n\n/**\n * Ed25519 公開鍵(バイナリ埋め込み)。\n * サーバー側で生成した秘密鍵のペアとなる公開鍵。\n * 本番環境では実際の鍵ペアに差し替えること。\n *\n * 開発用ダミー鍵: `crypto.generateKeyPairSync('ed25519')` で生成。\n */\nconst EMBEDDED_PUBLIC_KEY_PEM = `-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEADummyDevPublicKeyForDevelopmentOnly00000000000=\n-----END PUBLIC KEY-----`;\n\n// ── 型定義 ──\n\n/** デバッグトークンのペイロード */\nexport interface DebugTokenPayload {\n /** テナント ID */\n tid: string;\n /** 発行時刻(Unix seconds) */\n iat: number;\n}\n\n/** デバッグトークン検証結果 */\nexport interface VerifiedDebugToken {\n /** テナント ID */\n tenantId: string;\n /** 発行時刻 */\n issuedAt: Date;\n}\n\n// ── 内部ヘルパー ──\n\n/**\n * 公開鍵から AES-256 鍵を導出する。\n * SHA-256(rawPublicKey) → 32 bytes。\n */\nfunction deriveAesKey(publicKeyPem: string): Buffer {\n const publicKey = createPublicKey(publicKeyPem);\n const rawKey = publicKey.export({ type: \"spki\", format: \"der\" });\n return createHash(\"sha256\").update(rawKey).digest();\n}\n\n// ── 生成(サーバー側のみ) ──\n\n/**\n * デバッグトークンを生成する。\n * Ed25519 秘密鍵が必要(サーバー環境変数 or 開発用)。\n *\n * @param tenantId - テナント ID\n * @param privateKeyPem - Ed25519 秘密鍵(PEM 形式)\n * @param publicKeyPem - Ed25519 公開鍵(PEM 形式、AES 鍵導出に使用)\n * @returns デバッグトークン文字列(rfnd-xxx 形式)\n */\nexport function generateDebugToken(\n tenantId: string,\n privateKeyPem: string,\n publicKeyPem: string,\n): string {\n if (!tenantId) {\n throw new Error(\"tenantId is required\");\n }\n\n const payload: DebugTokenPayload = {\n tid: tenantId,\n iat: Math.floor(Date.now() / 1000),\n };\n\n // 1. ペイロードを JSON 化\n const payloadBytes = Buffer.from(JSON.stringify(payload), \"utf-8\");\n\n // 2. Ed25519 署名\n const privateKey = createPrivateKey(privateKeyPem);\n const signature = sign(null, payloadBytes, privateKey);\n if (signature.length !== SIGNATURE_SIZE) {\n throw new Error(`Unexpected Ed25519 signature size: ${signature.length}`);\n }\n\n // 3. payload + signature を結合\n const plaintext = Buffer.concat([payloadBytes, signature]);\n\n // 4. AES-256-GCM 暗号化\n const aesKey = deriveAesKey(publicKeyPem);\n const iv = randomBytes(IV_SIZE);\n const cipher = createCipheriv(\"aes-256-gcm\", aesKey, iv);\n const encrypted = Buffer.concat([cipher.update(plaintext), cipher.final()]);\n const authTag = cipher.getAuthTag();\n\n // 5. iv + encrypted + authTag → base64url\n const combined = Buffer.concat([iv, encrypted, authTag]);\n return `${DEBUG_PREFIX}${combined.toString(\"base64url\")}`;\n}\n\n// ── 検証(CLI/SDK、完全オフライン) ──\n\n/**\n * デバッグトークンを検証する。\n * 埋め込み公開鍵のみで検証可能(シークレット不要)。\n *\n * @param token - デバッグトークン文字列(rfnd-xxx 形式)\n * @param publicKeyPemOverride - テスト用公開鍵上書き(省略時は埋め込み公開鍵)\n * @returns 検証結果。無効な場合は undefined\n */\nexport function verifyDebugToken(\n token: string,\n publicKeyPemOverride?: string,\n): VerifiedDebugToken | undefined {\n if (!token.startsWith(DEBUG_PREFIX)) return undefined;\n\n const publicKeyPem = publicKeyPemOverride ?? getDebugPublicKey();\n\n try {\n // 1. strip prefix → base64url decode\n const combined = Buffer.from(token.slice(DEBUG_PREFIX.length), \"base64url\");\n\n // 最小サイズチェック: IV(12) + 最小暗号文(1) + AuthTag(16) = 29\n if (combined.length < IV_SIZE + 1 + AUTH_TAG_SIZE) return undefined;\n\n // 2. 分離: iv | encrypted | authTag\n const iv = combined.subarray(0, IV_SIZE);\n const authTag = combined.subarray(combined.length - AUTH_TAG_SIZE);\n const encrypted = combined.subarray(IV_SIZE, combined.length - AUTH_TAG_SIZE);\n\n // 3. AES-256-GCM 復号\n const aesKey = deriveAesKey(publicKeyPem);\n const decipher = createDecipheriv(\"aes-256-gcm\", aesKey, iv);\n decipher.setAuthTag(authTag);\n const plaintext = Buffer.concat([decipher.update(encrypted), decipher.final()]);\n\n // 4. 分離: payload | signature(64B)\n if (plaintext.length <= SIGNATURE_SIZE) return undefined;\n const payloadBytes = plaintext.subarray(0, plaintext.length - SIGNATURE_SIZE);\n const signature = plaintext.subarray(plaintext.length - SIGNATURE_SIZE);\n\n // 5. Ed25519 検証\n const publicKey = createPublicKey(publicKeyPem);\n const valid = verify(null, payloadBytes, publicKey, signature);\n if (!valid) return undefined;\n\n // 6. ペイロードパース\n const payload = JSON.parse(payloadBytes.toString(\"utf-8\")) as Record<string, unknown>;\n if (typeof payload.tid !== \"string\" || !payload.tid) return undefined;\n if (typeof payload.iat !== \"number\") return undefined;\n\n return {\n tenantId: payload.tid,\n issuedAt: new Date((payload.iat as number) * 1000),\n };\n } catch {\n return undefined;\n }\n}\n\n/**\n * Ed25519 秘密鍵を環境変数から取得する。\n * サーバー側のデバッグトークン生成時のみ使用。\n */\nexport function getDebugSigningKey(): string | undefined {\n return process.env.REFRAIN_DEBUG_SIGNING_KEY;\n}\n\n/**\n * デバッグ公開鍵を返す。\n * 環境変数 `REFRAIN_DEBUG_PUBLIC_KEY` が設定されていればそちらを優先し、\n * 未設定の場合はハードコード定数(開発用ダミー鍵)にフォールバックする。\n */\nexport function getDebugPublicKey(): string {\n return process.env.REFRAIN_DEBUG_PUBLIC_KEY ?? EMBEDDED_PUBLIC_KEY_PEM;\n}\n","/**\n * plan/key-cache --- opaque キーのローカルキャッシュ\n *\n * 保存先: ~/.config/refrain/key-cache.json\n * キーの SHA-256 ハッシュ → { tier, tenantId, limits, features, expiresAt }\n * TTL: サーバー expiresAt(デフォルト 24h)\n */\n\nimport { createHash } from \"node:crypto\";\nimport { readFile, writeFile, mkdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport type { PlanTier, PlanLimits, PlanFeatures } from \"./index\";\n\n// ── 型定義 ──\n\nexport interface CachedKeyData {\n tier: PlanTier;\n tenantId: string;\n limits: PlanLimits;\n features: PlanFeatures;\n expiresAt: string; // ISO 8601\n}\n\ninterface CacheFile {\n version: 1;\n entries: Record<string, CachedKeyData>;\n}\n\n// ── 定数 ──\n\nconst CONFIG_DIR = join(homedir(), \".config\", \"refrain\");\nconst CACHE_FILE = join(CONFIG_DIR, \"key-cache.json\");\n\n// ── キャッシュ操作 ──\n\n/** キーの SHA-256 ハッシュ(キャッシュキー) */\nfunction hashKey(apiKey: string): string {\n return createHash(\"sha256\").update(apiKey).digest(\"hex\");\n}\n\n/**\n * キャッシュファイルを読み込む。\n * ファイルが存在しない場合や不正な場合は空のキャッシュを返す。\n */\nasync function loadCacheFile(): Promise<CacheFile> {\n try {\n const data = await readFile(CACHE_FILE, \"utf-8\");\n const parsed = JSON.parse(data) as CacheFile;\n if (parsed.version === 1 && parsed.entries) return parsed;\n return { version: 1, entries: {} };\n } catch {\n return { version: 1, entries: {} };\n }\n}\n\n/**\n * キャッシュファイルに書き込む。\n */\nasync function saveCacheFile(cache: CacheFile): Promise<void> {\n await mkdir(CONFIG_DIR, { recursive: true });\n await writeFile(CACHE_FILE, JSON.stringify(cache, null, 2), \"utf-8\");\n}\n\n/**\n * キャッシュからキーデータを取得する。\n *\n * @param apiKey - API キー文字列\n * @param allowExpired - true の場合、期限切れキャッシュも返す(オフラインフォールバック用)\n * @returns キャッシュデータ。キャッシュミスの場合は undefined\n */\nexport async function getCachedKey(\n apiKey: string,\n allowExpired = false,\n): Promise<CachedKeyData | undefined> {\n const cache = await loadCacheFile();\n const hash = hashKey(apiKey);\n const entry = cache.entries[hash];\n if (!entry) return undefined;\n\n const now = new Date();\n const expires = new Date(entry.expiresAt);\n if (!allowExpired && expires <= now) {\n // 期限切れ → キャッシュから削除\n delete cache.entries[hash];\n await saveCacheFile(cache);\n return undefined;\n }\n\n return entry;\n}\n\n/**\n * キャッシュにキーデータを保存する。\n */\nexport async function setCachedKey(\n apiKey: string,\n data: CachedKeyData,\n): Promise<void> {\n const cache = await loadCacheFile();\n const hash = hashKey(apiKey);\n cache.entries[hash] = data;\n await saveCacheFile(cache);\n}\n\n/**\n * キャッシュからキーデータを削除する。\n */\nexport async function removeCachedKey(apiKey: string): Promise<void> {\n const cache = await loadCacheFile();\n const hash = hashKey(apiKey);\n delete cache.entries[hash];\n await saveCacheFile(cache);\n}\n\n/**\n * キャッシュを全削除する。\n */\nexport async function clearCache(): Promise<void> {\n await saveCacheFile({ version: 1, entries: {} });\n}\n","/**\n * plan/key-validator --- バリデーション API クライアント\n *\n * opaque キーをサーバーに送信して Plan 情報を取得する。\n * レスポンスをローカルキャッシュに保存し、オフライン時はキャッシュを使用する。\n */\n\nimport { getCachedKey, setCachedKey, type CachedKeyData } from \"./key-cache\";\nimport {\n COMMUNITY_PLAN,\n TIER_TO_PLAN,\n type Plan,\n type PlanTier,\n} from \"./index\";\n\n// ── 定数 ──\n\nconst DEFAULT_SERVER_URL = \"https://api.therefrain.ai\";\n\n// ── 型定義 ──\n\ninterface ValidateKeyResponse {\n valid: boolean;\n tier?: PlanTier;\n tenantId?: string;\n limits?: Plan[\"limits\"];\n features?: Plan[\"features\"];\n expiresAt?: string;\n error?: string;\n}\n\n// ── バリデーション API ──\n\n/**\n * opaque キーをバリデーション API で検証し、Plan を返す。\n * キャッシュ → API → キャッシュ保存のフローで動作する。\n *\n * @param apiKey - opaque API キー(rfn_xxx 形式)\n * @param serverUrl - API サーバー URL(省略時はデフォルト)\n * @param forceRefresh - true の場合、キャッシュを無視して API に問い合わせる\n * @returns 解決された Plan\n */\nexport async function validateOpaqueKey(\n apiKey: string,\n serverUrl?: string,\n forceRefresh = false,\n): Promise<Plan> {\n // 1. キャッシュ確認(forceRefresh でなければ)\n if (!forceRefresh) {\n const cached = await getCachedKey(apiKey);\n if (cached) {\n return planFromCachedData(cached);\n }\n }\n\n // 2. バリデーション API に問い合わせ\n const baseUrl = serverUrl ?? process.env.REFRAIN_API_SERVER_URL ?? DEFAULT_SERVER_URL;\n try {\n const response = await fetch(`${baseUrl}/api/public/validate-key`, {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n },\n });\n\n if (response.ok) {\n const data = (await response.json()) as ValidateKeyResponse;\n if (data.valid && data.tier && data.tenantId) {\n const basePlan = TIER_TO_PLAN[data.tier] ?? COMMUNITY_PLAN;\n const plan: Plan = {\n ...basePlan,\n tenantId: data.tenantId,\n // サーバーが limits/features を返した場合はそれを使用\n ...(data.limits ? { limits: data.limits } : {}),\n ...(data.features ? { features: data.features } : {}),\n };\n\n // キャッシュに保存\n const cacheData: CachedKeyData = {\n tier: data.tier,\n tenantId: data.tenantId,\n limits: plan.limits,\n features: plan.features,\n expiresAt: data.expiresAt ?? new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),\n };\n await setCachedKey(apiKey, cacheData);\n\n return plan;\n }\n }\n\n // 401 or invalid → Community\n return COMMUNITY_PLAN;\n } catch {\n // ネットワークエラー → オフラインフォールバック\n return offlineFallback(apiKey);\n }\n}\n\n/**\n * オフライン時のフォールバック。\n * 期限切れキャッシュがあれば警告付きで使用、なければ Community。\n */\nasync function offlineFallback(apiKey: string): Promise<Plan> {\n const expired = await getCachedKey(apiKey, true);\n if (expired) {\n // 期限切れキャッシュを警告付きで使用\n console.warn(\n \"[refrain] Warning: Using expired key cache (offline mode). \" +\n \"Connect to the API server to refresh.\",\n );\n return planFromCachedData(expired);\n }\n\n // キャッシュなし → Community フォールバック\n console.warn(\n \"[refrain] Warning: Cannot validate API key (offline, no cache). \" +\n \"Falling back to Community plan.\",\n );\n return COMMUNITY_PLAN;\n}\n\n/**\n * キャッシュデータから Plan を構築する。\n */\nfunction planFromCachedData(data: CachedKeyData): Plan {\n const basePlan = TIER_TO_PLAN[data.tier] ?? COMMUNITY_PLAN;\n return {\n ...basePlan,\n tenantId: data.tenantId,\n limits: data.limits,\n features: data.features,\n };\n}\n","/**\n * plan/index --- プランティア定義・解決・機能ゲート\n *\n * Community(無料)/ Pro / Team / Enterprise の 4 ティア。\n * API キーで判定し、実行開始前に config を clamp する。\n */\n\nimport type { ExecutorConfig } from \"../runbook-executor/types\";\nimport { PlanLimitError, PlanFeatureError, QuotaExceededError, type LimitType } from \"./errors\";\nimport { detectKeyKind } from \"./key-kind\";\nimport { verifyDebugToken } from \"./debug-token\";\nimport { validateOpaqueKey } from \"./key-validator\";\n\n// ── ティア型定義 ──\n\nexport type PlanTier = \"community\" | \"pro\" | \"team\" | \"business\" | \"enterprise\";\n\nexport interface PlanLimits {\n /** 1 runbook あたりの最大ステップ数 */\n maxStepsPerRunbook: number;\n /** バッチ実行時の最大行数 */\n maxBatchRows: number;\n /** テナント同時実行ジョブ数(Phase 3 で enforcement。Community/Pro は Infinity) */\n maxConcurrentJobs: number;\n /** 月間ジョブ数上限(Phase 3 で enforcement。Community/Pro は Infinity) */\n maxMonthlyJobs: number;\n /** 月間ステップ数上限(Phase 3 で enforcement。Community/Pro は Infinity) */\n maxMonthlySteps: number;\n /** 1 ジョブの最大実行時間 (ms)。CLI / SDK で即時 enforce */\n maxJobDurationMs: number;\n /** 1 ステップの最大実行時間 (ms)(Phase 3 で enforcement。Community/Pro は Infinity) */\n maxStepDurationMs: number;\n /** スクリーンショット保存可能枚数 */\n maxScreenshots: number;\n /** 動画保存可能数(Business: 10、Enterprise: 無制限) */\n maxVideoRecordings: number;\n /** Runbook バージョン保持数(Community/Pro/Team: 1 = 上書き、Business: 10、Enterprise: 無制限) */\n maxRunbookVersions: number;\n}\n\nexport interface PlanFeatures {\n /** セレクタキャッシュ */\n selectorCache: boolean;\n /** Agent Fallback */\n agentFallback: boolean;\n /** Vision Fallback */\n visionFallback: boolean;\n /** 自動修正モード */\n selfHealMode: boolean;\n /** HITL(Human-in-the-Loop: Chat 承認 + 通知 — Slack / Teams / Discord) */\n hitl: boolean;\n /** 用途別モデルオーバーライド */\n modelOverrides: boolean;\n /** リモート実行 (HTTP API) */\n remoteExecution: boolean;\n /** ステルスモード(bot検出回避 + proxy) */\n stealthMode: boolean;\n /** スクリーンショット保存(--screenshots) */\n screenshotSave: boolean;\n /** 動画撮影(--video) */\n videoRecording: boolean;\n /** ジョブ管理・スケジューリング */\n scheduling: boolean;\n /** スキル(ドメイン特化プラグイン: --skill) */\n skills: boolean;\n /** SAML SSO */\n samlSso: boolean;\n /** 監査ログ(Audit Log) */\n auditLog: boolean;\n /** Runbook 承認ワークフロー(テナント設定の承認必須化を利用可能か) */\n runbookApprovalWorkflow: boolean;\n /** Runbook バージョンロールバック */\n runbookRollback: boolean;\n}\n\nexport interface Plan {\n tier: PlanTier;\n limits: PlanLimits;\n features: PlanFeatures;\n /** テナント ID。API キーから自動解決。Community(キーなし)は undefined */\n tenantId?: string;\n}\n\n// ── ティア定数 ──\n\nexport const COMMUNITY_PLAN: Plan = {\n tier: \"community\",\n limits: {\n maxStepsPerRunbook: 100,\n maxBatchRows: 20,\n maxConcurrentJobs: Number.POSITIVE_INFINITY,\n maxMonthlyJobs: Number.POSITIVE_INFINITY,\n maxMonthlySteps: 300,\n maxJobDurationMs: 10 * 60 * 1000, // 10 minutes\n maxStepDurationMs: Number.POSITIVE_INFINITY,\n maxVideoRecordings: 0,\n maxScreenshots: 10,\n maxRunbookVersions: 1,\n },\n features: {\n selectorCache: false,\n agentFallback: true,\n visionFallback: false,\n selfHealMode: false,\n hitl: false,\n modelOverrides: false,\n remoteExecution: false,\n stealthMode: false,\n screenshotSave: true,\n videoRecording: false,\n scheduling: false,\n skills: false,\n samlSso: false,\n auditLog: false,\n runbookApprovalWorkflow: false,\n runbookRollback: false,\n },\n};\n\nexport const PRO_PLAN: Plan = {\n tier: \"pro\",\n limits: {\n maxStepsPerRunbook: 500,\n maxBatchRows: 100,\n maxConcurrentJobs: Number.POSITIVE_INFINITY,\n maxMonthlyJobs: Number.POSITIVE_INFINITY,\n maxMonthlySteps: 1_500,\n maxJobDurationMs: 30 * 60 * 1000, // 30 minutes\n maxStepDurationMs: Number.POSITIVE_INFINITY,\n maxVideoRecordings: 0,\n maxScreenshots: 0,\n maxRunbookVersions: 1,\n },\n features: {\n selectorCache: true,\n agentFallback: true,\n visionFallback: true,\n selfHealMode: false,\n hitl: false,\n modelOverrides: false,\n remoteExecution: false,\n stealthMode: true,\n screenshotSave: false,\n videoRecording: false,\n scheduling: false,\n skills: true,\n samlSso: false,\n auditLog: false,\n runbookApprovalWorkflow: false,\n runbookRollback: false,\n },\n};\n\nexport const TEAM_PLAN: Plan = {\n tier: \"team\",\n limits: {\n maxStepsPerRunbook: Number.POSITIVE_INFINITY,\n maxBatchRows: 500,\n maxConcurrentJobs: 10,\n maxMonthlyJobs: 2_000,\n maxMonthlySteps: 8_000,\n maxJobDurationMs: 2 * 60 * 60 * 1000, // 2 hours\n maxStepDurationMs: 5 * 60 * 1000, // 5 minutes\n maxVideoRecordings: 0,\n maxScreenshots: 100,\n maxRunbookVersions: 1,\n },\n features: {\n selectorCache: true,\n agentFallback: true,\n visionFallback: true,\n selfHealMode: true,\n hitl: false,\n modelOverrides: false,\n remoteExecution: true,\n stealthMode: true,\n screenshotSave: true,\n videoRecording: false,\n scheduling: true,\n skills: true,\n samlSso: false,\n auditLog: false,\n runbookApprovalWorkflow: false,\n runbookRollback: false,\n },\n};\n\nexport const BUSINESS_PLAN: Plan = {\n tier: \"business\",\n limits: {\n maxStepsPerRunbook: Number.POSITIVE_INFINITY,\n maxBatchRows: 1_000,\n maxConcurrentJobs: 50,\n maxMonthlyJobs: 5_000,\n maxMonthlySteps: 20_000,\n maxJobDurationMs: 4 * 60 * 60 * 1000, // 4 hours\n maxStepDurationMs: 5 * 60 * 1000, // 5 minutes\n maxVideoRecordings: 10,\n maxScreenshots: 500,\n maxRunbookVersions: 10,\n },\n features: {\n selectorCache: true,\n agentFallback: true,\n visionFallback: true,\n selfHealMode: true,\n hitl: true,\n modelOverrides: true,\n remoteExecution: true,\n stealthMode: true,\n screenshotSave: true,\n videoRecording: true,\n scheduling: true,\n skills: true,\n samlSso: false,\n auditLog: false,\n runbookApprovalWorkflow: true,\n runbookRollback: true,\n },\n};\n\nexport const ENTERPRISE_PLAN: Plan = {\n tier: \"enterprise\",\n limits: {\n maxStepsPerRunbook: Number.POSITIVE_INFINITY,\n maxBatchRows: Number.POSITIVE_INFINITY,\n maxConcurrentJobs: Number.POSITIVE_INFINITY,\n maxMonthlyJobs: Number.POSITIVE_INFINITY,\n maxMonthlySteps: Number.POSITIVE_INFINITY,\n maxJobDurationMs: 24 * 60 * 60 * 1000, // 24 hours\n maxStepDurationMs: 10 * 60 * 1000, // 10 minutes\n maxVideoRecordings: Number.POSITIVE_INFINITY,\n maxScreenshots: Number.POSITIVE_INFINITY,\n maxRunbookVersions: Number.POSITIVE_INFINITY,\n },\n features: {\n selectorCache: true,\n agentFallback: true,\n visionFallback: true,\n selfHealMode: true,\n hitl: true,\n modelOverrides: true,\n remoteExecution: true,\n stealthMode: true,\n screenshotSave: true,\n videoRecording: true,\n scheduling: true,\n skills: true,\n samlSso: true,\n auditLog: true,\n runbookApprovalWorkflow: true,\n runbookRollback: true,\n },\n};\n\n// ── 価格定義 ──\n\n/** ティア別月額料金(USD)。null = カスタム価格(Enterprise) */\nexport const PLAN_PRICING: Record<PlanTier, number | null> = {\n community: 0,\n pro: 55,\n team: 269,\n business: 499,\n enterprise: null,\n};\n\n// ── API キー解決 ──\n\n/** ティア → プラン定数のルックアップ */\nexport const TIER_TO_PLAN: Record<PlanTier, Plan> = {\n community: COMMUNITY_PLAN,\n pro: PRO_PLAN,\n team: TEAM_PLAN,\n business: BUSINESS_PLAN,\n enterprise: ENTERPRISE_PLAN,\n};\n\n/**\n * ティア文字列からプランを解決する(tenantId 付き)。\n * セッション認証時に tenants.tier から Plan を解決するために使用。\n */\nexport function resolvePlanFromTier(tier: PlanTier, tenantId: string): Plan {\n const basePlan = TIER_TO_PLAN[tier] ?? COMMUNITY_PLAN;\n return { ...basePlan, tenantId };\n}\n\n/**\n * API キーからプランを解決する(非同期)。\n *\n * - キーなし → Community\n * - debug(rfnd-xxx)→ Ed25519 検証 + AES 復号 → Enterprise\n * - opaque(rfn_xxx)→ キャッシュ確認 → バリデーション API → Plan\n */\nexport async function resolvePlan(\n apiKey?: string,\n options?: { serverUrl?: string; forceRefresh?: boolean },\n): Promise<Plan> {\n if (!apiKey) return COMMUNITY_PLAN;\n\n const kind = detectKeyKind(apiKey);\n if (!kind) return COMMUNITY_PLAN;\n\n if (kind === \"debug\") {\n const verified = verifyDebugToken(apiKey);\n if (!verified) return COMMUNITY_PLAN;\n return { ...ENTERPRISE_PLAN, tenantId: verified.tenantId };\n }\n\n // opaque → バリデーション API\n return validateOpaqueKey(apiKey, options?.serverUrl, options?.forceRefresh);\n}\n\n/**\n * API キーを CLI 引数 or 環境変数から取得する。\n */\nexport function getApiKey(cliValue?: string): string | undefined {\n return cliValue ?? process.env.REFRAIN_API_KEY;\n}\n\n// ── 機能ゲート ──\n\n/**\n * ExecutorConfig を Plan に基づいて clamp する。\n *\n * - 許可されていない機能フラグ → false に強制\n * - 明示的に要求されたゲート対象機能(--self-heal 等) → PlanFeatureError\n * - 暗黙的なフラグ(--enable-selector-cache 等) → 静かに無効化\n */\nexport function enforceFeatureGates(config: ExecutorConfig, plan: Plan): void {\n // 未指定ならプラン許可ベースのデフォルトを適用\n config.enableSelectorCache ??= plan.features.selectorCache;\n config.enableAgentFallback ??= plan.features.agentFallback;\n config.enableVisionFallback ??= plan.features.visionFallback;\n\n // プランで許可されていない機能は強制 OFF\n if (!plan.features.selectorCache) config.enableSelectorCache = false;\n if (!plan.features.agentFallback) config.enableAgentFallback = false;\n if (!plan.features.visionFallback) config.enableVisionFallback = false;\n\n // 自動修正モード: 明示的に要求された場合はエラー\n if (!plan.features.selfHealMode && config.selfHeal) {\n throw new PlanFeatureError(\n \"Self-healing mode requires a Team plan. Upgrade: https://therefrain.ai/pricing\",\n );\n }\n\n // HITL(承認 + 通知): web 以外の全プラットフォームを Business+ に制限\n if (!plan.features.hitl) {\n if (config.approvalMode && config.approvalMode !== \"web\") {\n throw new PlanFeatureError(\n `${config.approvalMode} approval requires a Business plan. Upgrade: https://therefrain.ai/pricing`,\n );\n }\n if (config.notifyMode) {\n throw new PlanFeatureError(\n `${config.notifyMode} notification requires a Business plan. Upgrade: https://therefrain.ai/pricing`,\n );\n }\n }\n\n // モデルオーバーライド: 静かに無効化\n // NOTE (A-6): ユーザー指定の modelOverrides のみ無効化される。\n // オーバーライド未指定時はベースモデルにフォールバックする。\n if (!plan.features.modelOverrides && config.aiModelConfig?.modelOverrides) {\n config.aiModelConfig.modelOverrides = undefined;\n }\n\n // スクリーンショット保存: Community は例外的に許可、Pro は不可、Team+ は許可\n if (!plan.features.screenshotSave && config.screenshotDir) {\n throw new PlanFeatureError(\n \"Screenshot saving requires a Team plan (or Community tier for evaluation). Upgrade: https://therefrain.ai/pricing\",\n );\n }\n\n // 動画撮影: Business 未満では PlanFeatureError\n if (!plan.features.videoRecording && config.videoDir) {\n throw new PlanFeatureError(\n \"Video recording requires a Business plan. Upgrade: https://therefrain.ai/pricing\",\n );\n }\n\n // スキル(ドメイン特化プラグイン): Pro 未満では PlanFeatureError\n if (!plan.features.skills && config.skills?.length) {\n throw new PlanFeatureError(\n \"Skills require a Pro plan. Upgrade: https://therefrain.ai/pricing\",\n );\n }\n\n // ステルスモード / プロキシ: Pro 未満では PlanFeatureError\n if (!plan.features.stealthMode) {\n if (config.stealth) {\n throw new PlanFeatureError(\n \"Stealth mode requires a Pro plan. Upgrade: https://therefrain.ai/pricing\",\n );\n }\n if (config.proxy) {\n throw new PlanFeatureError(\n \"Proxy support requires a Pro plan. Upgrade: https://therefrain.ai/pricing\",\n );\n }\n }\n}\n\n/**\n * runbook のステップ数がプランの制限内か検証する。\n */\nexport function validateStepLimit(stepCount: number, plan: Plan): void {\n if (stepCount > plan.limits.maxStepsPerRunbook) {\n throw new PlanLimitError(\n `This runbook has ${stepCount} steps, but your plan allows up to ${plan.limits.maxStepsPerRunbook}. ` +\n \"Upgrade: https://therefrain.ai/pricing\",\n );\n }\n}\n\n/**\n * バッチの行数がプランの制限内か検証する。\n */\nexport function validateBatchLimit(rowCount: number, plan: Plan): void {\n if (rowCount > plan.limits.maxBatchRows) {\n throw new PlanLimitError(\n `Batch has ${rowCount} rows, but your plan allows up to ${plan.limits.maxBatchRows}. ` +\n \"Upgrade: https://therefrain.ai/pricing\",\n );\n }\n}\n\n// ── 表示用ヘルパー ──\n\n/** プランの表示用ラベルを返す */\nexport function formatPlanLabel(plan: Plan): string {\n const stepsLabel =\n plan.limits.maxStepsPerRunbook === Number.POSITIVE_INFINITY\n ? \"unlimited\"\n : `${plan.limits.maxStepsPerRunbook} steps`;\n const batchLabel =\n plan.limits.maxBatchRows === Number.POSITIVE_INFINITY\n ? \"unlimited\"\n : `${plan.limits.maxBatchRows} batch rows`;\n const monthlyLabel =\n plan.limits.maxMonthlySteps === Number.POSITIVE_INFINITY\n ? \"unlimited\"\n : `${plan.limits.maxMonthlySteps.toLocaleString(\"en-US\")}/mo`;\n\n return `${plan.tier.charAt(0).toUpperCase() + plan.tier.slice(1)} (${stepsLabel}, ${batchLabel}, ${monthlyLabel})`;\n}\n\nexport { PlanLimitError, PlanFeatureError, QuotaExceededError, type LimitType } from \"./errors\";\n","/**\n * selector-cache — セレクタ解決キャッシュ\n *\n * 成功した selector → ref マッピングを永続化し、\n * 再実行時に AI 呼び出しをスキップする高速パスを提供する。\n * キャッシュされた ref が stale(ページ上に存在しない)場合は\n * 無効化して通常の AI 解決にフォールバックする(self-healing loop)。\n *\n * executor / debugger から利用。generator では使用しない。\n */\n\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { createHash } from \"node:crypto\";\nimport { join, dirname, basename } from \"node:path\";\nimport type { Selector } from \"../runbook-executor/types\";\n\nexport interface CacheEntry {\n /** 解決済み ref(@ なし。例: \"e3\") */\n ref: string;\n /** 解決時刻 ISO8601 */\n resolvedAt: string;\n /** 解決時のスナップショットハッシュ */\n snapshotHash: string;\n /** キャッシュヒット成功回数 */\n hitCount: number;\n}\n\nexport interface SelectorCache {\n version: number;\n runbookPath: string;\n entries: Record<string, CacheEntry>;\n}\n\n/**\n * キャッシュキーを生成する。\n * フォーマット: `{stepOrdinal}:{urlWithoutQuery}:{selectorHash}`\n */\nexport function buildCacheKey(\n stepOrdinal: number,\n url: string,\n selector: Selector,\n): string {\n const selectorHash = createHash(\"sha256\")\n .update(JSON.stringify(selector))\n .digest(\"hex\")\n .slice(0, 12);\n const urlNormalized = url.split(\"?\")[0];\n return `${stepOrdinal}:${urlNormalized}:${selectorHash}`;\n}\n\n/**\n * スナップショット文字列のハッシュを生成する。\n */\nexport function buildSnapshotHash(snapshot: string): string {\n return createHash(\"sha256\").update(snapshot).digest(\"hex\").slice(0, 16);\n}\n\n/**\n * キャッシュファイルのパスを返す。\n * 手順書 YAML と同じディレクトリに `{basename}.selector-cache.json`。\n */\nexport function cacheFilePath(runbookPath: string): string {\n const dir = dirname(runbookPath);\n const base = basename(runbookPath, \".yaml\");\n return join(dir, `${base}.selector-cache.json`);\n}\n\n/**\n * キャッシュファイルを読み込む。存在しない/パース失敗時は空のキャッシュを返す。\n */\nexport async function loadCache(runbookPath: string): Promise<SelectorCache> {\n const path = cacheFilePath(runbookPath);\n if (!existsSync(path)) {\n return { version: 1, runbookPath, entries: {} };\n }\n try {\n const raw = await readFile(path, \"utf-8\");\n const parsed = JSON.parse(raw) as SelectorCache;\n // 旧フォーマット移行: instructionPath → runbookPath\n parsed.runbookPath = runbookPath;\n return parsed;\n } catch {\n return { version: 1, runbookPath, entries: {} };\n }\n}\n\n/**\n * キャッシュをファイルに書き出す。書き込み失敗はサイレントに無視する。\n */\nexport async function saveCache(cache: SelectorCache): Promise<void> {\n const path = cacheFilePath(cache.runbookPath);\n try {\n await writeFile(path, JSON.stringify(cache, null, 2), \"utf-8\");\n } catch {\n // キャッシュ書き込み失敗は non-fatal\n }\n}\n\n/**\n * キャッシュエントリをルックアップする。\n */\nexport function lookupCache(\n cache: SelectorCache,\n key: string,\n): CacheEntry | undefined {\n return cache.entries[key];\n}\n\n/**\n * キャッシュエントリを追加または更新する。\n */\nexport function updateCache(\n cache: SelectorCache,\n key: string,\n ref: string,\n snapshotHash: string,\n): void {\n const existing = cache.entries[key];\n cache.entries[key] = {\n ref,\n resolvedAt: new Date().toISOString(),\n snapshotHash,\n hitCount: (existing?.hitCount ?? 0) + 1,\n };\n}\n\n/**\n * キャッシュエントリを無効化(削除)する。\n */\nexport function invalidateCacheEntry(cache: SelectorCache, key: string): void {\n delete cache.entries[key];\n}\n","/**\n * executor — メイン実行ループ\n *\n * runbook YAML のステップを順に実行する。\n * RuntimeStore によるテンプレート展開 + キャプチャ実行。\n */\n\nimport { mkdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { AgentBrowser } from \"../browser/browser-client\";\nimport type { RefMap } from \"../browser/engine\";\nimport { findElementInSnapshot, countElements } from \"../browser/snapshot-parser\";\nimport { resolveWithAIDetailed } from \"../harness/selector-resolver\";\nimport type { AIResolveResult, RetryContext } from \"../harness/selector-resolver\";\nimport type { AIModelProvider } from \"../harness/ai-service\";\nimport { classifyFailure, getRecoveryHint, sanitizeBrowserError } from \"../harness/error-classifier\";\nimport { FailureRegistry } from \"../harness/failure-registry\";\nimport {\n buildCacheKey,\n buildSnapshotHash,\n lookupCache,\n updateCache,\n invalidateCacheEntry,\n type SelectorCache,\n} from \"../harness/selector-cache\";\nimport { runGoalAgent } from \"../harness/goal-agent\";\nimport { resolveWithVision } from \"../harness/vision-resolver\";\nimport { validateAction } from \"../harness/action-validator\";\nimport { resolveDeterministic } from \"../harness/deterministic-resolver\";\nimport { needsConfirmation } from \"./confirmation\";\nimport type { ConfirmationProvider } from \"../harness/confirmation\";\nimport { executeCapture } from \"../context/capture-handler\";\nimport { evaluateCondition } from \"../context/expression-evaluator\";\nimport { parseAndAppendToMemory } from \"../context/memory-operations\";\nimport { sleep } from \"../harness/sleep\";\nimport type { Logger, SpinnerLike } from \"../logger\";\nimport { NoopLogger, NoopSpinner } from \"../logger\";\nimport { createDebugLogger, type DebugLogger } from \"../cli/debug-logger\";\nimport { getActiveMetricsCollector } from \"../harness/ai-metrics\";\nimport { t, tf, getLocale } from \"../i18n\";\nimport type { Skill, SkillSnapshotResult, SkillStepContext } from \"../skills/types\";\nimport type { RuntimeStore } from \"../context/runtime-store\";\nimport { SnapshotCache } from \"../context/snapshot-cache\";\nimport { ContextChunker } from \"../context/context-chunker\";\nimport type {\n ExecutorConfig,\n ExecutionStrategy,\n ParsedRunbook,\n ParsedStep,\n StepExecutionResult,\n StepRetryDetail,\n StepDiagnostics,\n ExecutionReport,\n} from \"./types\";\n\nexport interface ExecuteOptions {\n /** RuntimeStore(テンプレート変数管理) */\n store: RuntimeStore;\n /** バッチ用: 既存ブラウザインスタンスを再利用 */\n browser?: AgentBrowser;\n /** 承認プロバイダ */\n confirmationProvider?: ConfirmationProvider;\n /** セレクタキャッシュ(null=無効) */\n selectorCache?: SelectorCache | null;\n /** データ蓄積・集計ストア */\n dataStore?: import(\"../context/data-store\").DataStore &\n import(\"../context/data-store\").DataAggregator;\n /** ダウンロードマネージャ */\n downloadManager?: import(\"../context/download-manager\").DownloadManager;\n /** Logger インスタンス(SDK 用にカスタム可能) */\n logger?: Logger;\n /** SpinnerLike ファクトリ(SDK 用にカスタム可能) */\n createSpinner?: () => SpinnerLike;\n /** ジョブレベルタイムアウト用 AbortSignal */\n abortSignal?: AbortSignal;\n /** Skill インスタンス(Google Sheets 等のドメイン特化スナップショット変換) */\n skills?: import(\"../skills/types\").Skill[];\n /** AI モデル提供(DI) */\n aiProvider?: AIModelProvider;\n /** ステップ開始コールバック */\n onStepStart?: (stepOrdinal: number, description: string, actionType: string) => Promise<void>;\n /** ステップ完了コールバック(アーティファクト保存等) */\n onStepComplete?: (stepOrdinal: number, status: string, durationMs: number, description: string, actionType: string) => Promise<void>;\n /** ステップ失敗コールバック */\n onStepFailed?: (stepOrdinal: number, error: string) => Promise<void>;\n}\n\n/**\n * スキルがアクティブな場合、スナップショットをスキル経由で変換する。\n * スキルが無い or 非アクティブの場合は null を返し、呼び出し元で通常フィルタを使う。\n */\nasync function applySkillTransform(\n browser: AgentBrowser,\n rawSnapshot: string,\n url: string,\n skills: Skill[] | undefined,\n stepContext?: SkillStepContext,\n): Promise<SkillSnapshotResult | null> {\n if (!skills || skills.length === 0) return null;\n const locale = getLocale();\n for (const skill of skills) {\n const shouldActivate = stepContext && skill.shouldActivateForStep\n ? skill.shouldActivateForStep(url, stepContext)\n : skill.shouldActivate(url);\n if (shouldActivate) {\n try {\n return await skill.transformSnapshot(browser, rawSnapshot, { url, locale });\n } catch {\n // スキル変換失敗 → 通常フィルタにフォールバック\n return null;\n }\n }\n }\n return null;\n}\n\n/**\n * runbook.notes(生成時の人間ガイダンス)を contextMarkdown に結合する。\n * セレクタ解決 AI に探索時の知見を渡すため。\n */\nfunction mergeNotesIntoContext(\n contextMarkdown: string,\n notes: string | undefined,\n): string {\n if (!notes) return contextMarkdown;\n const section = `## Generation Notes (Human Guidance)\\n${notes}`;\n return `${contextMarkdown}\\n\\n${section}`;\n}\n\n/**\n * contextMarkdown を解決する。\n * CLI --context / SDK / サーバーで常に指定されるため YAML 内蔵 context へのフォールバックは行わない。\n * notes のみマージする。\n */\nfunction resolveContextMarkdown(\n config: ExecutorConfig,\n runbook: ParsedRunbook,\n): string {\n return mergeNotesIntoContext(config.contextMarkdown, runbook.notes);\n}\n\n/**\n * runbook を実行する\n */\nexport async function execute(\n config: ExecutorConfig,\n runbook: ParsedRunbook,\n opts: ExecuteOptions,\n): Promise<ExecutionReport> {\n const totalStart = performance.now();\n const ownsBrowser = !opts.browser;\n const browser = opts.browser ?? new AgentBrowser();\n const results: StepExecutionResult[] = [];\n let aborted = false;\n let recordedVideoPaths: string[] | undefined;\n const logger: Logger = opts.logger ?? new NoopLogger();\n const createSpinner = opts.createSpinner ?? (() => new NoopSpinner());\n const debugLogger = createDebugLogger({\n filePath: config.debugLogPath,\n console: config.debugConsole,\n });\n\n const snapshotCache = new SnapshotCache();\n // context 解決: CLI --context > YAML/DB context > notes\n config.contextMarkdown = resolveContextMarkdown(config, runbook);\n const contextChunker = new ContextChunker(config.contextMarkdown);\n const failureRegistry = new FailureRegistry();\n\n const pauseMs = config.stepDelay ?? runbook.settings.pauseBetweenSteps;\n\n if (config.screenshotDir) {\n await mkdir(config.screenshotDir, { recursive: true });\n }\n\n try {\n // ブラウザ起動 + 初期ナビゲーション(自前ブラウザの場合のみ)\n if (ownsBrowser) {\n const startUrl = opts.store.resolveTemplate(runbook.metadata.startUrl);\n const openSpinner = createSpinner();\n openSpinner.start(tf(\"executor.openingUrl\", { url: startUrl }));\n await browser.open(startUrl, {\n headless: config.headless,\n stealth: config.stealth,\n proxy: config.proxy,\n });\n // 固定1秒sleep → DOM安定化待機に置換(高速ページで数百ms節約)\n await browser.waitForDOMStability(3000);\n openSpinner.stop(t(\"executor.browserReady\"));\n\n // 動画録画開始\n if (config.videoDir) {\n try {\n await browser.startRecording(config.videoDir);\n logger.info(tf(\"executor.recordingStarted\", { path: config.videoDir }));\n } catch (e) {\n logger.warn(tf(\"executor.recordingStartFailed\", { error: e instanceof Error ? e.message : String(e) }));\n }\n }\n }\n\n for (const step of runbook.steps) {\n if (aborted) break;\n if (opts.abortSignal?.aborted) {\n aborted = true;\n logger.warn(t(\"executor.jobAbortedTimeout\"));\n break;\n }\n\n logger.step(`Step ${step.ordinal}/${runbook.steps.length}: ${step.description}`);\n await opts.onStepStart?.(step.ordinal, step.description, step.action.type).catch(() => {});\n const start = Date.now();\n\n // 条件チェック\n if (step.condition) {\n const resolved = opts.store.resolveTemplate(step.condition);\n const evalResult = evaluateCondition(resolved);\n debugLogger.log({\n phase: \"executor\",\n event: \"condition_eval\",\n step: step.ordinal,\n data: { condition: step.condition, resolved, result: evalResult.value, error: evalResult.error },\n });\n if (!evalResult.value) {\n logger.warn(tf(\"executor.conditionSkipping\", { condition: step.condition }));\n const skipDuration = Date.now() - start;\n results.push({\n ordinal: step.ordinal,\n description: step.description,\n actionType: step.action.type,\n status: \"skipped\",\n durationMs: skipDuration,\n conditionSkipped: true,\n });\n await opts.onStepComplete?.(step.ordinal, \"skipped\", skipDuration, step.description, step.action.type).catch(() => {});\n continue;\n }\n }\n\n // ブランチステップ\n if (step.branches) {\n const branchResult = await executeBranchStep(\n browser,\n step,\n runbook,\n config,\n opts,\n debugLogger,\n pauseMs,\n logger,\n snapshotCache,\n contextChunker,\n failureRegistry,\n );\n results.push(branchResult);\n if (branchResult.status === \"failed\" && runbook.settings.stopOnError) {\n logger.error(t(\"executor.stopOnErrorAborting\"));\n aborted = true;\n }\n continue;\n }\n\n // ループステップ\n if (step.loop && step.steps) {\n const loopResult = await executeLoopStep(\n browser,\n step,\n runbook,\n config,\n opts,\n debugLogger,\n pauseMs,\n logger,\n snapshotCache,\n contextChunker,\n failureRegistry,\n );\n results.push(loopResult);\n if (loopResult.status === \"failed\" && runbook.settings.stopOnError) {\n logger.error(t(\"executor.stopOnErrorAborting\"));\n aborted = true;\n }\n continue;\n }\n\n // 承認チェック\n if (needsConfirmation(step, config.skipConfirmation) && opts.confirmationProvider) {\n logger.info(tf(\"executor.approvalWaiting\", { ordinal: step.ordinal, riskLevel: step.riskLevel }));\n debugLogger.log({\n phase: \"executor\",\n event: \"approval_pending\",\n step: step.ordinal,\n data: { riskLevel: step.riskLevel, description: step.description },\n });\n\n const result = await opts.confirmationProvider.confirm(step, step.ordinal, {\n goal: runbook.metadata.goal,\n });\n\n debugLogger.log({\n phase: \"executor\",\n event: \"approval_received\",\n step: step.ordinal,\n data: { result },\n });\n\n if (result === \"abort\") {\n logger.error(tf(\"executor.approvalAborted\", { ordinal: step.ordinal }));\n aborted = true;\n results.push({\n ordinal: step.ordinal,\n description: step.description,\n actionType: step.action.type,\n status: \"skipped\",\n durationMs: Date.now() - start,\n error: t(\"executor.userAborted\"),\n });\n await opts.onStepComplete?.(step.ordinal, \"skipped\", Date.now() - start, step.description, step.action.type).catch(() => {});\n break;\n }\n if (result === \"skip\") {\n logger.warn(tf(\"executor.approvalSkipped\", { ordinal: step.ordinal }));\n results.push({\n ordinal: step.ordinal,\n description: step.description,\n actionType: step.action.type,\n status: \"skipped\",\n durationMs: Date.now() - start,\n });\n await opts.onStepComplete?.(step.ordinal, \"skipped\", Date.now() - start, step.description, step.action.type).catch(() => {});\n continue;\n }\n\n logger.success(tf(\"executor.approvalApproved\", { ordinal: step.ordinal }));\n }\n\n try {\n const stepResult = await executeStep(\n browser,\n step,\n runbook,\n config,\n opts,\n debugLogger,\n logger,\n snapshotCache,\n contextChunker,\n failureRegistry,\n );\n results.push({ ...stepResult, ordinal: step.ordinal, description: step.description, actionType: step.action.type });\n\n // Working Memory 更新\n opts.store.updateWorkingMemory(\n step.ordinal,\n runbook.steps.length,\n stepResult.status === \"success\",\n step.url,\n step.action.type,\n step.description,\n );\n\n // extract結果をRuntimeStoreに保存(memoryOperationsで参照するため)\n if (stepResult.extractedData) {\n opts.store.set(\"extractedData\", stepResult.extractedData);\n }\n\n if (stepResult.status === \"failed\" && runbook.settings.stopOnError) {\n logger.error(t(\"executor.stopOnErrorAborting\"));\n aborted = true;\n break;\n }\n\n // キャプチャフェーズ\n if (step.captures && step.captures.length > 0) {\n await executeCapturePhase(browser, step, opts.store, results, runbook, debugLogger, logger);\n if (results[results.length - 1].status === \"failed\" && runbook.settings.stopOnError) {\n aborted = true;\n }\n }\n\n // メモリオペレーション(蓄積・集計)\n if (step.memoryOperations && opts.dataStore) {\n await executeMemoryOperations(step, opts.store, opts.dataStore, debugLogger, logger);\n }\n\n // スクリーンショット (オプション)\n if (config.screenshotDir) {\n const filename = `step-${String(step.ordinal).padStart(3, \"0\")}.png`;\n try {\n await browser.screenshot(join(config.screenshotDir, filename));\n } catch {\n // スクリーンショット失敗は無視\n }\n }\n\n // ステップ完了コールバック(アーティファクト保存等)\n const lastResult = results[results.length - 1];\n await opts.onStepComplete?.(step.ordinal, lastResult.status, lastResult.durationMs, step.description, step.action.type).catch(() => {});\n\n // ステップ間待機\n if (pauseMs > 0) {\n await new Promise((r) => setTimeout(r, pauseMs));\n }\n } catch (error) {\n const rawErrorMsg = error instanceof Error ? error.message : String(error);\n const errorMsg = sanitizeBrowserError(rawErrorMsg);\n logger.error(errorMsg);\n debugLogger.log({\n phase: \"executor\",\n event: \"step_error\",\n step: step.ordinal,\n data: { error: rawErrorMsg },\n });\n results.push({\n ordinal: step.ordinal,\n description: step.description,\n actionType: step.action.type,\n status: \"failed\",\n durationMs: Date.now() - start,\n error: errorMsg,\n });\n await opts.onStepFailed?.(step.ordinal, errorMsg).catch(() => {});\n\n if (runbook.settings.stopOnError) {\n aborted = true;\n break;\n }\n }\n }\n } finally {\n // 動画録画停止\n if (ownsBrowser && browser.isRecording()) {\n try {\n const result = await browser.stopRecording();\n if (result.paths.length > 0) {\n recordedVideoPaths = result.paths;\n for (const p of result.paths) {\n logger.info(tf(\"executor.recordingComplete\", { path: p }));\n }\n }\n } catch (e) {\n logger.warn(tf(\"executor.recordingStopFailed\", { error: e instanceof Error ? e.message : String(e) }));\n }\n }\n\n if (ownsBrowser) {\n try {\n await browser.close();\n } catch {\n // close失敗は無視\n }\n }\n }\n\n // AI メトリクスサマリーをデバッグログに出力\n const metricsSummary = getActiveMetricsCollector().getSummary();\n if (metricsSummary.totalCalls > 0) {\n debugLogger.log({\n phase: \"executor\",\n event: \"ai_metrics_summary\",\n data: metricsSummary as unknown as Record<string, unknown>,\n });\n }\n\n await debugLogger.flush();\n\n const succeeded = results.filter((r) => r.status === \"success\").length;\n const failed = results.filter((r) => r.status === \"failed\").length;\n const skipped = results.filter((r) => r.status === \"skipped\").length;\n\n // メモリコレクション情報を収集\n const memoryCollections: Record<string, number> | undefined = opts.dataStore\n ? Object.fromEntries(\n opts.dataStore.listCollections().map((c) => [c, opts.dataStore!.count(c)]),\n )\n : undefined;\n\n // ダウンロードファイル一覧を収集\n const downloadedFiles = opts.downloadManager\n ? opts.downloadManager.getAllPaths()\n : undefined;\n\n return {\n runbookTitle: runbook.title,\n startUrl: runbook.metadata.startUrl,\n totalSteps: runbook.steps.length,\n executed: succeeded + failed,\n succeeded,\n failed,\n skipped,\n aborted,\n steps: results,\n totalDurationMs: Math.round(performance.now() - totalStart),\n ...(memoryCollections && Object.keys(memoryCollections).length > 0 ? { memoryCollections } : {}),\n ...(downloadedFiles && downloadedFiles.length > 0 ? { downloadedFiles } : {}),\n ...(recordedVideoPaths && recordedVideoPaths.length > 0 ? { videoPaths: recordedVideoPaths } : {}),\n };\n}\n\n/** キャプチャフェーズの共通処理 */\nasync function executeCapturePhase(\n browser: AgentBrowser,\n step: ParsedStep,\n store: RuntimeStore,\n results: StepExecutionResult[],\n runbook: ParsedRunbook,\n debugLogger: DebugLogger,\n logger: Logger,\n): Promise<void> {\n if (!step.captures || step.captures.length === 0) return;\n\n const capturedValues: Record<string, string> = {};\n for (const capture of step.captures) {\n const value = await executeCapture(browser, capture, store);\n if (value !== null) {\n store.set(capture.name, value);\n const maskedValue = store.isSensitive(capture.name) ? \"****\" : value;\n capturedValues[capture.name] = maskedValue;\n logger.success(`Captured: ${capture.name} = \"${maskedValue}\"`);\n debugLogger.log({\n phase: \"executor\",\n event: \"capture\",\n step: step.ordinal,\n data: { name: capture.name, strategy: capture.strategy, value: maskedValue },\n });\n } else if (capture.required) {\n logger.error(`Required capture \"${capture.name}\" failed`);\n results[results.length - 1].status = \"failed\";\n results[results.length - 1].error = `Required capture \"${capture.name}\" failed`;\n } else {\n logger.warn(`Optional capture \"${capture.name}\" returned no value`);\n }\n }\n if (Object.keys(capturedValues).length > 0) {\n results[results.length - 1].capturedValues = capturedValues;\n }\n}\n\n/** ループステップの実行 */\nasync function executeLoopStep(\n browser: AgentBrowser,\n step: ParsedStep,\n runbook: ParsedRunbook,\n config: ExecutorConfig,\n opts: ExecuteOptions,\n debugLogger: DebugLogger,\n pauseMs: number,\n logger: Logger,\n snapshotCache?: SnapshotCache,\n contextChunker?: ContextChunker,\n failureRegistry?: FailureRegistry,\n): Promise<StepExecutionResult> {\n const loop = step.loop!;\n\n // forEach ループ\n if (loop.forEach) {\n return executeForEachLoop(\n browser,\n step,\n runbook,\n config,\n opts,\n debugLogger,\n pauseMs,\n logger,\n snapshotCache,\n contextChunker,\n failureRegistry,\n );\n }\n\n // while 型ループ\n const start = Date.now();\n const store = opts.store;\n const subSteps = step.steps!;\n const maxIter = loop.maxIterations ?? 10;\n const counterVar = loop.counterVariable ?? \"__loopIndex\";\n const allIterResults: StepExecutionResult[][] = [];\n let iterations = 0;\n let loopFailed = false;\n\n debugLogger.log({\n phase: \"executor\",\n event: \"loop_start\",\n step: step.ordinal,\n data: { condition: loop.condition, maxIterations: maxIter, counterVariable: counterVar },\n });\n\n for (let i = 0; i < maxIter; i++) {\n // ジョブタイムアウトチェック\n if (opts.abortSignal?.aborted) {\n loopFailed = true;\n break;\n }\n\n // ループ条件を評価\n const resolved = store.resolveTemplate(loop.condition!);\n const evalResult = evaluateCondition(resolved);\n debugLogger.log({\n phase: \"executor\",\n event: \"loop_condition\",\n step: step.ordinal,\n data: { iteration: i, condition: loop.condition, resolved, result: evalResult.value },\n });\n\n if (!evalResult.value) {\n logger.info(`Loop condition false at iteration ${i}, exiting loop`);\n break;\n }\n\n // カウンタ変数をセット\n store.set(counterVar, String(i));\n iterations++;\n\n logger.step(`Loop ${step.ordinal} iteration ${i}/${maxIter}`);\n\n const { results: iterResults, failed } = await executeSubSteps(\n browser,\n subSteps,\n runbook,\n config,\n opts,\n debugLogger,\n pauseMs,\n logger,\n snapshotCache,\n contextChunker,\n failureRegistry,\n );\n\n allIterResults.push(iterResults);\n if (failed) {\n loopFailed = true;\n break;\n }\n }\n\n debugLogger.log({\n phase: \"executor\",\n event: \"loop_end\",\n step: step.ordinal,\n data: { iterations, failed: loopFailed },\n });\n\n return {\n ordinal: step.ordinal,\n description: step.description,\n actionType: \"loop\",\n status: loopFailed ? \"failed\" : \"success\",\n durationMs: Date.now() - start,\n loopIterations: iterations,\n subStepResults: allIterResults,\n };\n}\n\n/** forEach ループの実行 */\nasync function executeForEachLoop(\n browser: AgentBrowser,\n step: ParsedStep,\n runbook: ParsedRunbook,\n config: ExecutorConfig,\n opts: ExecuteOptions,\n debugLogger: DebugLogger,\n pauseMs: number,\n logger: Logger,\n snapshotCache?: SnapshotCache,\n contextChunker?: ContextChunker,\n failureRegistry?: FailureRegistry,\n): Promise<StepExecutionResult> {\n const start = Date.now();\n const store = opts.store;\n const loop = step.loop!;\n const subSteps = step.steps!;\n const maxIter = loop.maxIterations ?? 100;\n const itemVar = loop.itemVariable ?? \"__item\";\n const indexVar = loop.indexVariable ?? \"__index\";\n\n // forEach 値をテンプレート展開\n const rawForEach = store.resolveTemplate(loop.forEach!);\n\n // データソース解決\n let items: unknown[];\n if (rawForEach.startsWith(\"collection:\")) {\n // DataStore コレクションから取得\n const collectionName = rawForEach.slice(\"collection:\".length);\n if (!opts.dataStore) {\n return {\n ordinal: step.ordinal,\n description: step.description,\n actionType: \"forEach\",\n status: \"failed\",\n durationMs: Date.now() - start,\n error: `forEach collection: requires dataStore (collection: ${collectionName})`,\n };\n }\n items = opts.dataStore.getAll(collectionName);\n } else {\n // JSON パース\n try {\n const parsed = JSON.parse(rawForEach);\n if (!Array.isArray(parsed)) {\n return {\n ordinal: step.ordinal,\n description: step.description,\n actionType: \"forEach\",\n status: \"failed\",\n durationMs: Date.now() - start,\n error: `forEach value must be a JSON array, got ${typeof parsed}`,\n };\n }\n items = parsed;\n } catch {\n return {\n ordinal: step.ordinal,\n description: step.description,\n actionType: \"forEach\",\n status: \"failed\",\n durationMs: Date.now() - start,\n error: `forEach value is not valid JSON: ${rawForEach.slice(0, 100)}`,\n };\n }\n }\n\n // 安全上限\n const effectiveItems = items.slice(0, maxIter);\n\n debugLogger.log({\n phase: \"executor\",\n event: \"forEach_start\",\n step: step.ordinal,\n data: {\n forEach: loop.forEach,\n itemCount: items.length,\n effectiveCount: effectiveItems.length,\n maxIterations: maxIter,\n itemVariable: itemVar,\n indexVariable: indexVar,\n },\n });\n\n const allIterResults: StepExecutionResult[][] = [];\n let loopFailed = false;\n\n for (let i = 0; i < effectiveItems.length; i++) {\n if (opts.abortSignal?.aborted) {\n loopFailed = true;\n break;\n }\n\n store.setForEachItem(itemVar, effectiveItems[i], indexVar, i);\n\n logger.step(`forEach ${step.ordinal} [${i + 1}/${effectiveItems.length}]`);\n\n const { results: iterResults, failed } = await executeSubSteps(\n browser,\n subSteps,\n runbook,\n config,\n opts,\n debugLogger,\n pauseMs,\n logger,\n snapshotCache,\n contextChunker,\n failureRegistry,\n );\n\n allIterResults.push(iterResults);\n if (failed) {\n loopFailed = true;\n break;\n }\n }\n\n // クリーンアップ\n store.clearForEachItem(itemVar, indexVar);\n\n debugLogger.log({\n phase: \"executor\",\n event: \"forEach_end\",\n step: step.ordinal,\n data: { iterations: allIterResults.length, failed: loopFailed },\n });\n\n return {\n ordinal: step.ordinal,\n description: step.description,\n actionType: \"forEach\",\n status: loopFailed ? \"failed\" : \"success\",\n durationMs: Date.now() - start,\n loopIterations: allIterResults.length,\n forEachItemCount: items.length,\n subStepResults: allIterResults,\n };\n}\n\n/** サブステップ群を順に実行する共通ヘルパー */\nasync function executeSubSteps(\n browser: AgentBrowser,\n subSteps: ParsedStep[],\n runbook: ParsedRunbook,\n config: ExecutorConfig,\n opts: ExecuteOptions,\n debugLogger: DebugLogger,\n pauseMs: number,\n logger: Logger,\n snapshotCache?: SnapshotCache,\n contextChunker?: ContextChunker,\n failureRegistry?: FailureRegistry,\n): Promise<{ results: StepExecutionResult[]; failed: boolean }> {\n const store = opts.store;\n const results: StepExecutionResult[] = [];\n let failed = false;\n\n for (const subStep of subSteps) {\n // サブステップの条件チェック\n if (subStep.condition) {\n const subResolved = store.resolveTemplate(subStep.condition);\n const subEval = evaluateCondition(subResolved);\n if (!subEval.value) {\n logger.warn(` Sub-step ${subStep.ordinal} condition false, skipping`);\n results.push({\n ordinal: subStep.ordinal,\n description: subStep.description,\n actionType: subStep.action.type,\n status: \"skipped\",\n durationMs: 0,\n conditionSkipped: true,\n });\n continue;\n }\n }\n\n // サブステップがブランチを持つ場合\n if (subStep.branches) {\n const branchResult = await executeBranchStep(\n browser,\n subStep,\n runbook,\n config,\n opts,\n debugLogger,\n pauseMs,\n logger,\n snapshotCache,\n contextChunker,\n failureRegistry,\n );\n results.push(branchResult);\n if (branchResult.status === \"failed\" && runbook.settings.stopOnError) {\n failed = true;\n break;\n }\n continue;\n }\n\n // サブステップがループを持つ場合\n if (subStep.loop && subStep.steps) {\n const loopResult = await executeLoopStep(\n browser,\n subStep,\n runbook,\n config,\n opts,\n debugLogger,\n pauseMs,\n logger,\n snapshotCache,\n contextChunker,\n failureRegistry,\n );\n results.push(loopResult);\n if (loopResult.status === \"failed\" && runbook.settings.stopOnError) {\n failed = true;\n break;\n }\n continue;\n }\n\n await opts.onStepStart?.(subStep.ordinal, subStep.description, subStep.action.type).catch(() => {});\n try {\n const subResult = await executeStep(\n browser,\n subStep,\n runbook,\n config,\n opts,\n debugLogger,\n logger,\n snapshotCache,\n contextChunker,\n failureRegistry,\n );\n results.push({\n ...subResult,\n ordinal: subStep.ordinal,\n description: subStep.description,\n actionType: subStep.action.type,\n });\n\n // Working Memory 更新\n store.updateWorkingMemory(\n subStep.ordinal,\n runbook.steps.length,\n subResult.status === \"success\",\n subStep.url,\n subStep.action.type,\n subStep.description,\n );\n\n // extract結果をRuntimeStoreに保存\n if (subResult.extractedData) {\n store.set(\"extractedData\", subResult.extractedData);\n }\n\n if (subResult.status === \"failed\" && runbook.settings.stopOnError) {\n failed = true;\n break;\n }\n\n // サブステップのキャプチャ\n if (subStep.captures && subStep.captures.length > 0) {\n await executeCapturePhase(\n browser,\n subStep,\n store,\n results,\n runbook,\n debugLogger,\n logger,\n );\n if (\n results[results.length - 1].status === \"failed\" &&\n runbook.settings.stopOnError\n ) {\n failed = true;\n break;\n }\n }\n\n // サブステップのメモリオペレーション\n if (subStep.memoryOperations && opts.dataStore) {\n await executeMemoryOperations(subStep, store, opts.dataStore, debugLogger, logger);\n }\n\n // ステップ完了コールバック\n const lastSubResult = results[results.length - 1];\n await opts.onStepComplete?.(subStep.ordinal, lastSubResult.status, lastSubResult.durationMs, subStep.description, subStep.action.type).catch(() => {});\n\n // ステップ間待機\n if (pauseMs > 0) {\n await new Promise((r) => setTimeout(r, pauseMs));\n }\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n logger.error(errorMsg);\n results.push({\n ordinal: subStep.ordinal,\n description: subStep.description,\n actionType: subStep.action.type,\n status: \"failed\",\n durationMs: 0,\n error: errorMsg,\n });\n await opts.onStepFailed?.(subStep.ordinal, errorMsg).catch(() => {});\n if (runbook.settings.stopOnError) {\n failed = true;\n break;\n }\n }\n }\n\n return { results, failed };\n}\n\n/** ブランチステップの実行 */\nasync function executeBranchStep(\n browser: AgentBrowser,\n step: ParsedStep,\n runbook: ParsedRunbook,\n config: ExecutorConfig,\n opts: ExecuteOptions,\n debugLogger: DebugLogger,\n pauseMs: number,\n logger: Logger,\n snapshotCache?: SnapshotCache,\n contextChunker?: ContextChunker,\n failureRegistry?: FailureRegistry,\n): Promise<StepExecutionResult> {\n const start = Date.now();\n const store = opts.store;\n const branches = step.branches!;\n\n // テンプレート展開\n const resolvedValue = store.resolveTemplate(branches.value);\n debugLogger.log({\n phase: \"executor\",\n event: \"branch_start\",\n step: step.ordinal,\n data: { value: branches.value, resolved: resolvedValue, caseCount: branches.cases.length },\n });\n\n // case マッチング\n let matchedSteps: ParsedStep[] | null = null;\n let matchLabel = \"\";\n\n for (const branchCase of branches.cases) {\n const resolvedMatch = store.resolveTemplate(branchCase.match);\n if (resolvedValue === resolvedMatch) {\n matchedSteps = branchCase.steps;\n matchLabel = branchCase.match;\n break;\n }\n }\n\n // default フォールバック\n if (!matchedSteps && branches.default) {\n matchedSteps = branches.default.steps;\n matchLabel = \"default\";\n }\n\n if (!matchedSteps) {\n logger.warn(`Branch: no matching case for \"${resolvedValue}\", skipping`);\n debugLogger.log({\n phase: \"executor\",\n event: \"branch_no_match\",\n step: step.ordinal,\n data: { value: resolvedValue },\n });\n return {\n ordinal: step.ordinal,\n description: step.description,\n actionType: \"branch\",\n status: \"skipped\",\n durationMs: Date.now() - start,\n branchMatch: undefined,\n };\n }\n\n logger.step(`Branch: matched \"${matchLabel}\" (value=\"${resolvedValue}\")`);\n debugLogger.log({\n phase: \"executor\",\n event: \"branch_matched\",\n step: step.ordinal,\n data: { value: resolvedValue, match: matchLabel, subStepCount: matchedSteps.length },\n });\n\n const { results: subResults, failed } = await executeSubSteps(\n browser,\n matchedSteps,\n runbook,\n config,\n opts,\n debugLogger,\n pauseMs,\n logger,\n snapshotCache,\n contextChunker,\n failureRegistry,\n );\n\n debugLogger.log({\n phase: \"executor\",\n event: \"branch_end\",\n step: step.ordinal,\n data: { match: matchLabel, failed },\n });\n\n return {\n ordinal: step.ordinal,\n description: step.description,\n actionType: \"branch\",\n status: failed ? \"failed\" : \"success\",\n durationMs: Date.now() - start,\n branchMatch: matchLabel,\n subStepResults: [subResults],\n };\n}\n\nasync function executeStep(\n browser: AgentBrowser,\n step: ParsedStep,\n runbook: ParsedRunbook,\n config: ExecutorConfig,\n opts: ExecuteOptions,\n debugLogger: DebugLogger,\n logger: Logger,\n snapshotCache?: SnapshotCache,\n contextChunker?: ContextChunker,\n failureRegistry?: FailureRegistry,\n): Promise<Omit<StepExecutionResult, \"ordinal\" | \"description\">> {\n const start = Date.now();\n\n // Skill extractedData capture: スキルがステップコンテキストに基づいて\n // 有効化を判断し、必要な場合のみ snapshot 取得 + extractedData 抽出する。\n // これにより memory/export 等の早期リターンアクションでも\n // memoryOperations が extractedData を参照できる。\n if (opts.skills?.length && step.url) {\n const stepContext: SkillStepContext = {\n actionType: step.action.type,\n memoryOperations: step.memoryOperations,\n };\n const hasActiveSkill = opts.skills.some((s) =>\n s.shouldActivateForStep\n ? s.shouldActivateForStep(step.url, stepContext)\n : s.shouldActivate(step.url),\n );\n if (hasActiveSkill) {\n try {\n const snap = await browser.snapshot();\n const skillResult = await applySkillTransform(browser, snap, step.url, opts.skills, stepContext);\n if (skillResult?.extractedData) {\n opts.store.set(\"extractedData\", skillResult.extractedData);\n }\n } catch {\n /* non-fatal: スキル抽出失敗は通常実行にフォールバック */\n }\n }\n }\n\n // navigate / scroll / wait はセレクタ不要\n if (step.action.type === \"navigate\") {\n const rawUrl = step.action.url ?? step.url;\n const url = opts.store.resolveTemplate(rawUrl);\n logger.step(`Navigate: ${opts.store.maskSensitive(url)}`);\n\n // chrome-error:// 検出時は最大2回リトライ(計3回試行)\n const maxNavRetries = 2;\n for (let navAttempt = 0; ; navAttempt++) {\n await browser.navigate(url);\n const pageCount = await browser.pageCount();\n await browser.waitForPossibleNavigation(await browser.url(), pageCount);\n\n const currentUrl = await browser.url();\n if (!currentUrl.startsWith(\"chrome-error://\")) break;\n\n if (navAttempt >= maxNavRetries) {\n logger.warn(tf(\"executor.chromeErrorDetected\", { url }));\n throw new Error(`Navigation failed: page landed on chrome-error:// (target: ${url})`);\n }\n logger.warn(tf(\"executor.chromeErrorDetected\", { url }) + ` — retrying (${navAttempt + 1}/${maxNavRetries})`);\n await sleep(2000 * (navAttempt + 1));\n }\n return { status: \"success\", durationMs: Date.now() - start };\n }\n\n if (step.action.type === \"scroll\") {\n logger.step(\"Scroll: down\");\n await browser.scroll(\"down\");\n return { status: \"success\", durationMs: Date.now() - start };\n }\n\n if (step.action.type === \"wait\") {\n const rawMs = step.action.value\n ? opts.store.resolveTemplate(step.action.value)\n : String(runbook.settings.defaultTimeout);\n const ms = Number(rawMs);\n logger.step(`Wait: ${ms}ms`);\n await browser.wait(ms);\n return { status: \"success\", durationMs: Date.now() - start };\n }\n\n // extract: ページ内 JavaScript 実行(セレクタ不要)\n if (step.action.type === \"extract\") {\n const script = opts.store.resolveTemplate(step.action.script ?? step.action.value ?? \"\");\n if (!script) {\n return { status: \"failed\", durationMs: Date.now() - start, error: \"extract requires script or value\" };\n }\n logger.step(`Extract: executing script`);\n debugLogger.log({\n phase: \"executor\",\n event: \"extract\",\n step: step.ordinal,\n data: { script: script.slice(0, 200) },\n });\n const result = await browser.evaluate(script);\n const isArray = Array.isArray(result);\n const stringifyApplied = typeof result !== \"string\" && result !== null && result !== undefined;\n const resultStr = result === null || result === undefined\n ? \"\"\n : typeof result === \"string\" ? result : JSON.stringify(result);\n debugLogger.log({\n phase: \"executor\",\n event: \"extract_result\",\n step: step.ordinal,\n data: {\n resultType: result === null ? \"null\" : typeof result,\n isArray,\n arrayLength: isArray ? (result as unknown[]).length : undefined,\n resultPreview: resultStr.slice(0, 200),\n storedLength: resultStr.length,\n stringifyApplied,\n },\n });\n if (resultStr === \"\") {\n logger.warn(\"Extract returned empty result\");\n debugLogger.log({\n phase: \"executor\",\n event: \"extract_empty_result\",\n step: step.ordinal,\n data: { script: script.slice(0, 200) },\n });\n }\n return { status: \"success\", durationMs: Date.now() - start, extractedData: resultStr };\n }\n\n // export: メモリコレクションをファイルに書き出し(セレクタ不要)\n if (step.action.type === \"export\") {\n if (!opts.dataStore) {\n return { status: \"failed\", durationMs: Date.now() - start, error: \"export requires dataStore\" };\n }\n const collection = opts.store.resolveTemplate(step.action.exportCollection ?? \"default\");\n const format = (step.action.exportFormat ?? \"csv\") as \"csv\" | \"json\";\n const outputDir = config.outputDir ?? \"/tmp\";\n const exportPath = opts.store.resolveTemplate(\n step.action.exportPath ?? `${outputDir}/${collection}.${format}`,\n );\n logger.step(`Export: ${collection} → ${exportPath} (${format})`);\n const exportItems = opts.dataStore.getAll(collection);\n const sampleKeys = exportItems.length > 0\n ? JSON.stringify(Object.keys(exportItems[0]))\n : \"N/A\";\n debugLogger.log({\n phase: \"executor\",\n event: \"export\",\n step: step.ordinal,\n data: {\n collection,\n itemCount: exportItems.length,\n format,\n path: exportPath,\n sampleKeys,\n },\n });\n await opts.dataStore.writeToFile(collection, exportPath, format);\n if (opts.downloadManager) {\n opts.downloadManager.addDownload({\n path: exportPath,\n filename: exportPath.split(\"/\").pop() ?? \"unknown\",\n stepOrdinal: step.ordinal,\n timestamp: new Date().toISOString(),\n });\n }\n return { status: \"success\", durationMs: Date.now() - start, exportedFile: exportPath };\n }\n\n // download (セレクタなし): 現在のダウンロードを待つ\n // セレクタありの場合はフォールスルーして通常のセレクタ解決パイプラインへ\n if (step.action.type === \"download\" && !step.action.selector) {\n const downloadPath = opts.store.resolveTemplate(\n step.action.downloadPath ?? `/tmp/download-${Date.now()}.bin`,\n );\n logger.step(`Download: waiting for download → ${downloadPath}`);\n await browser.waitForDownload(downloadPath);\n\n if (opts.downloadManager) {\n opts.downloadManager.addDownload({\n path: downloadPath,\n filename: downloadPath.split(\"/\").pop() ?? \"unknown\",\n stepOrdinal: step.ordinal,\n timestamp: new Date().toISOString(),\n });\n }\n\n return { status: \"success\", durationMs: Date.now() - start, downloadedFile: downloadPath };\n }\n\n // memory: データ操作のみ(メモリオペレーションは呼び出し元で実行)\n if (step.action.type === \"memory\") {\n logger.step(`Memory operation: ${step.description}`);\n return { status: \"success\", durationMs: Date.now() - start };\n }\n\n // key: キーボードキー押下(セレクタ不要)\n if (step.action.type === \"key\") {\n const keys = opts.store.resolveTemplate(step.action.keys ?? step.action.value ?? \"\");\n if (!keys) {\n return { status: \"failed\", durationMs: Date.now() - start, error: \"key action requires keys or value\" };\n }\n logger.step(`Key: ${keys}`);\n await browser.pressKeys(keys);\n return { status: \"success\", durationMs: Date.now() - start };\n }\n\n // Defensive: memoryOperations付きステップでセレクタが未定義の場合、memory-onlyとして扱う\n if (step.memoryOperations && step.memoryOperations.length > 0 && !step.action.selector) {\n logger.warn(\n `Step has memoryOperations but action type \"${step.action.type}\" with no selector — treating as memory-only`,\n );\n debugLogger.log({\n phase: \"executor\",\n event: \"memory_fallback\",\n step: step.ordinal,\n data: { originalActionType: step.action.type, memoryOpsCount: step.memoryOperations.length },\n });\n return { status: \"success\", durationMs: Date.now() - start };\n }\n\n // セレクタが必要なアクション\n if (!step.action.selector) {\n return {\n status: \"failed\",\n durationMs: Date.now() - start,\n error: \"No selector defined for this step\",\n diagnostics: {\n stepAction: {\n type: step.action.type,\n value: step.action.value,\n url: step.action.url,\n },\n stepUrl: step.url,\n },\n };\n }\n\n // スナップショット取得 + AI セレクタ解決(スマートリトライ)\n const defaultStrategy: ExecutionStrategy = {\n maxRetries: 3,\n changeTimeouts: [8000, 10000],\n finalRetryStabilizeMs: 3000,\n domStabilityMs: 5000,\n };\n const strategy = config.executionStrategy ?? defaultStrategy;\n const { maxRetries } = strategy;\n let aiResult: AIResolveResult | null = null;\n let lastSnapshot = \"\";\n let lastRefs: RefMap | undefined;\n let prevSnapshot = \"\";\n let lastAiResponseText = \"\";\n let lastAiPrompt = \"\";\n let attempts = 0;\n const failureHistory: string[] = [];\n const retryDetails: StepRetryDetail[] = [];\n let cachedRefUsed = false;\n let deterministicResolveResult = \"\";\n let agentFallbackResult: StepDiagnostics[\"agentFallbackResult\"] | undefined;\n let visionFallbackResult: StepDiagnostics[\"visionFallbackResult\"] | undefined;\n let resolveMethod: \"cache\" | \"deterministic\" | \"ai\" | \"scroll\" | \"vision\" | \"agent\" | null = null;\n let deterministicMatchType: string | undefined;\n let deterministicConfidence: number | undefined;\n let failureHintsProvided = false;\n\n // キャッシュ高速パス: キャッシュされた ref がスナップショット内に存在すればAIスキップ\n if (opts.selectorCache && step.action.selector) {\n const cacheKey = buildCacheKey(step.ordinal, step.url, step.action.selector);\n const cached = lookupCache(opts.selectorCache, cacheKey);\n if (cached) {\n cachedRefUsed = true;\n const snapshotResult = await browser.snapshotWithRefs();\n const snapshot = snapshotResult.tree;\n lastSnapshot = snapshot;\n lastRefs = snapshotResult.refs;\n prevSnapshot = snapshot;\n if (findElementInSnapshot(snapshot, cached.ref) !== null) {\n // キャッシュヒット: ref が存在する → AIスキップ\n updateCache(opts.selectorCache, cacheKey, cached.ref, buildSnapshotHash(snapshot));\n aiResult = { ref: cached.ref, aiResponseText: \"(cache hit)\", reasoning: \"cache hit\" };\n resolveMethod = \"cache\";\n debugLogger.log({\n phase: \"executor\",\n event: \"selector_cache_hit\",\n step: step.ordinal,\n data: { cacheKey, ref: cached.ref, hitCount: cached.hitCount + 1 },\n });\n logger.success(`Cache hit: @${cached.ref}`);\n } else {\n // キャッシュ stale: ref がスナップショットに存在しない → 無効化して通常フローへ\n invalidateCacheEntry(opts.selectorCache, cacheKey);\n debugLogger.log({\n phase: \"executor\",\n event: \"selector_cache_stale\",\n step: step.ordinal,\n data: { cacheKey, ref: cached.ref },\n });\n logger.warn(`Cache stale: @${cached.ref} not found in snapshot, falling back to AI`);\n cachedRefUsed = false;\n }\n }\n }\n\n // 決定論的セレクタ解決: AI を呼び出す前にパターンマッチで直接解決を試みる\n if (!aiResult && step.action.selector) {\n // スナップショットがまだ取得されていなければ取得\n if (!lastSnapshot) {\n // chrome-error:// 検出(前ステップのナビゲーション失敗をキャッチ)\n const currentUrl = await browser.url();\n if (currentUrl.startsWith(\"chrome-error://\")) {\n logger.warn(tf(\"executor.chromeErrorDetected\", { url: step.url }));\n await browser.navigate(step.url);\n await browser.waitForDOMStability(3000);\n }\n\n // DOM安定化を待ってからスナップショット取得\n await browser.waitForDOMStability(strategy.domStabilityMs);\n const snapshotResult = await browser.snapshotWithRefs();\n lastSnapshot = snapshotResult.tree;\n lastRefs = snapshotResult.refs;\n prevSnapshot = lastSnapshot;\n\n debugLogger.log({\n phase: \"executor\",\n event: \"initial_snapshot\",\n step: step.ordinal,\n data: {\n url: await browser.url(),\n elementCount: countSnapshotElements(lastSnapshot),\n snapshotLength: lastSnapshot.length,\n },\n });\n\n // 空スナップショット回復: DOM安定化を延長して再取得\n if (countSnapshotElements(lastSnapshot) === 0) {\n debugLogger.log({\n phase: \"executor\",\n event: \"empty_snapshot_recovery\",\n step: step.ordinal,\n data: { url: await browser.url(), attempt: \"initial\" },\n });\n logger.warn(\"Empty snapshot detected, waiting for DOM stability...\");\n await sleep(1000);\n await browser.waitForDOMStability(strategy.domStabilityMs);\n const retryResult = await browser.snapshotWithRefs();\n lastSnapshot = retryResult.tree;\n lastRefs = retryResult.refs;\n prevSnapshot = lastSnapshot;\n }\n }\n\n const deterministicResult = resolveDeterministic(lastSnapshot, step.action.selector, lastRefs);\n if (deterministicResult.ref) {\n aiResult = {\n ref: deterministicResult.ref,\n aiResponseText: `(deterministic: ${deterministicResult.matchType}, confidence=${deterministicResult.confidence})`,\n reasoning: `deterministic match: ${deterministicResult.matchType}`,\n };\n resolveMethod = \"deterministic\";\n deterministicMatchType = deterministicResult.matchType ?? undefined;\n deterministicConfidence = deterministicResult.confidence;\n debugLogger.log({\n phase: \"executor\",\n event: \"deterministic_resolve\",\n step: step.ordinal,\n data: {\n ref: deterministicResult.ref,\n matchType: deterministicResult.matchType,\n confidence: deterministicResult.confidence,\n selector: step.action.selector,\n },\n });\n deterministicResolveResult = `hit: @${deterministicResult.ref} (${deterministicResult.matchType}, confidence=${deterministicResult.confidence})`;\n logger.success(`Deterministic resolve: @${deterministicResult.ref} (${deterministicResult.matchType}, confidence=${deterministicResult.confidence})`);\n } else {\n deterministicResolveResult = \"miss: no match\";\n debugLogger.log({\n phase: \"executor\",\n event: \"deterministic_resolve_miss\",\n step: step.ordinal,\n data: { selector: step.action.selector },\n });\n }\n }\n\n for (let attempt = 0; attempt <= maxRetries && !aiResult; attempt++) {\n if (attempt > 0) {\n logger.warn(`Selector not found, retrying (${attempt}/${maxRetries})...`);\n\n if (attempt <= strategy.changeTimeouts.length) {\n // スナップショット変化を能動的に待機(SPA遷移検出)\n const timeout = strategy.changeTimeouts[attempt - 1];\n logger.info(`Waiting up to ${timeout / 1000}s for page transition...`);\n const changeResult = await browser.waitForSnapshotChange(lastSnapshot, timeout);\n\n if (changeResult.changed) {\n logger.success(\"Page transition detected\");\n lastSnapshot = changeResult.snapshot;\n } else {\n // 変化なし: ページ遷移は発生していない\n debugLogger.log({\n phase: \"executor\",\n event: \"snapshot_unchanged\",\n step: step.ordinal,\n data: { attempt, strategy: \"waitForSnapshotChange\", timeoutMs: timeout },\n });\n\n // 空スナップショットの場合はスキップせず回復を試みる(下流の回復ロジックに任せる)\n if (countSnapshotElements(lastSnapshot) === 0) {\n logger.warn(\"No page transition detected but snapshot is empty, attempting recovery...\");\n } else {\n logger.warn(\"No page transition detected, skipping AI call\");\n const reason = `Attempt ${attempt}: waited ${timeout / 1000}s for page transition, no change`;\n failureHistory.push(reason);\n retryDetails.push({\n attempt,\n snapshotChanged: false,\n snapshotElementCount: countSnapshotElements(lastSnapshot),\n failureReason: reason,\n });\n prevSnapshot = lastSnapshot;\n attempts = attempt + 1;\n continue;\n }\n }\n } else {\n // 最終リトライ: sleep + DOM安定化\n await sleep(strategy.finalRetryStabilizeMs);\n await browser.waitForDOMStability(strategy.domStabilityMs);\n lastSnapshot = await browser.snapshot();\n }\n } else {\n // 初回: 決定論的解決で既に取得済みならスナップショット再取得をスキップ\n if (!lastSnapshot) {\n lastSnapshot = await browser.snapshot();\n }\n }\n\n // 空スナップショット検出時は追加の安定化待機 + 再取得\n if (countSnapshotElements(lastSnapshot) === 0) {\n debugLogger.log({\n phase: \"executor\",\n event: \"empty_snapshot_recovery\",\n step: step.ordinal,\n data: { url: await browser.url(), attempt },\n });\n logger.warn(`Snapshot empty (attempt ${attempt}), forcing DOM stability wait...`);\n await sleep(1000);\n await browser.waitForDOMStability(strategy.domStabilityMs);\n const freshResult = await browser.snapshotWithRefs();\n lastSnapshot = freshResult.tree;\n lastRefs = freshResult.refs;\n }\n\n const snapshotChanged = attempt === 0 || lastSnapshot !== prevSnapshot;\n\n debugLogger.log({\n phase: \"executor\",\n event: attempt > 0 ? \"selector_retry\" : \"snapshot\",\n step: step.ordinal,\n data: {\n url: step.url,\n snapshot: lastSnapshot,\n attempt,\n ...(attempt > 0 ? { snapshotChanged } : {}),\n },\n });\n\n const failureHints = failureRegistry && step.action.selector\n ? failureRegistry.getRelevantHints(step.url, step.action.selector)\n : undefined;\n if (failureHints) failureHintsProvided = true;\n const retryContext: RetryContext | undefined = attempt > 0\n ? {\n attempt,\n previousAiResponse: lastAiResponseText || undefined,\n snapshotChanged,\n failureHistory,\n failureHints,\n }\n : undefined;\n\n const skillResult = await applySkillTransform(browser, lastSnapshot, step.url, opts.skills);\n if (skillResult?.extractedData) {\n opts.store.set(\"extractedData\", skillResult.extractedData);\n }\n const filteredSnap = skillResult?.snapshot\n ?? (snapshotCache ? snapshotCache.getFiltered(lastSnapshot) : lastSnapshot);\n const relevantContext = contextChunker\n ? contextChunker.selectRelevant(step.description, step.url)\n : config.contextMarkdown;\n const detailed = await resolveWithAIDetailed(\n filteredSnap,\n step.action.selector,\n step.description,\n step.url,\n relevantContext,\n debugLogger,\n retryContext,\n opts.store.getWorkingMemorySummary(),\n opts.aiProvider,\n );\n attempts = attempt + 1;\n lastAiResponseText = detailed.aiResponseText;\n lastAiPrompt = detailed.prompt ?? \"\";\n prevSnapshot = lastSnapshot;\n\n if (detailed.ref) {\n aiResult = detailed;\n resolveMethod = \"ai\";\n break;\n }\n\n const reason = `Attempt ${attempt + 1}: AI returned empty ref`;\n failureHistory.push(reason);\n retryDetails.push({\n attempt,\n snapshotChanged,\n snapshotElementCount: countSnapshotElements(lastSnapshot),\n failureReason: reason,\n aiReasoning: detailed.reasoning || undefined,\n aiPrompt: detailed.prompt?.slice(0, 2000),\n aiResponse: detailed.aiResponseText?.slice(0, 1000),\n snapshotPreview: lastSnapshot.slice(0, 2000),\n });\n }\n\n // スクロール回復: 全リトライ失敗後に画面外要素を探す\n if (!aiResult) {\n debugLogger.log({\n phase: \"executor\",\n event: \"recovery_attempt\",\n step: step.ordinal,\n data: { strategy: \"scroll_down\" },\n });\n logger.warn(\"All retries failed, attempting scroll recovery...\");\n\n try {\n await browser.scroll(\"down\", 500);\n await browser.waitForDOMStability(3000);\n const scrolledSnapshot = await browser.snapshot();\n\n if (scrolledSnapshot !== lastSnapshot) {\n const scrollSkillResult = await applySkillTransform(browser, scrolledSnapshot, step.url, opts.skills);\n if (scrollSkillResult?.extractedData) {\n opts.store.set(\"extractedData\", scrollSkillResult.extractedData);\n }\n const filteredScrollSnap = scrollSkillResult?.snapshot\n ?? (snapshotCache ? snapshotCache.getFiltered(scrolledSnapshot) : scrolledSnapshot);\n const relevantCtx = contextChunker\n ? contextChunker.selectRelevant(step.description, step.url)\n : config.contextMarkdown;\n const recoveryResult = await resolveWithAIDetailed(\n filteredScrollSnap,\n step.action.selector,\n step.description,\n step.url,\n relevantCtx,\n debugLogger,\n {\n attempt: attempts,\n snapshotChanged: true,\n failureHistory: [...failureHistory, \"Scroll recovery attempt\"],\n failureHints: failureRegistry && step.action.selector\n ? failureRegistry.getRelevantHints(step.url, step.action.selector)\n : undefined,\n },\n opts.store.getWorkingMemorySummary(),\n opts.aiProvider,\n );\n attempts++;\n lastAiResponseText = recoveryResult.aiResponseText;\n lastAiPrompt = recoveryResult.prompt ?? \"\";\n lastSnapshot = scrolledSnapshot;\n\n if (recoveryResult.ref) {\n aiResult = recoveryResult;\n resolveMethod = \"scroll\";\n logger.success(\"Scroll recovery succeeded\");\n // Record scroll recovery success in failure registry\n if (failureRegistry && step.action.selector) {\n failureRegistry.record(step.url, step.action.selector, \"element_not_found\", step.ordinal, { method: \"scroll\" });\n }\n } else {\n retryDetails.push({\n attempt: attempts - 1,\n snapshotChanged: true,\n snapshotElementCount: countSnapshotElements(scrolledSnapshot),\n failureReason: \"Scroll recovery: AI returned empty ref\",\n aiReasoning: recoveryResult.reasoning || undefined,\n aiPrompt: recoveryResult.prompt?.slice(0, 2000),\n aiResponse: recoveryResult.aiResponseText?.slice(0, 1000),\n snapshotPreview: scrolledSnapshot.slice(0, 2000),\n });\n }\n }\n } catch {\n // スクロール回復失敗は無視\n }\n }\n\n // Vision Fallback: スクリーンショットベースの視覚的セレクタ解決\n if (!aiResult && config.enableVisionFallback) {\n logger.warn(\"Attempting vision fallback (screenshot-based)...\");\n try {\n const { imageBuffer, annotations } = await browser.screenshotWithAnnotations();\n const visionResult = await resolveWithVision(\n imageBuffer,\n annotations,\n step.action.selector,\n step.description,\n step.url,\n failureHistory,\n debugLogger,\n opts.aiProvider,\n );\n if (visionResult?.ref) {\n aiResult = {\n ref: visionResult.ref,\n aiResponseText: `(vision: confidence=${visionResult.confidence})`,\n reasoning: visionResult.reasoning,\n };\n resolveMethod = \"vision\";\n visionFallbackResult = {\n annotationCount: annotations.length,\n reasoning: visionResult.reasoning,\n success: true,\n };\n logger.success(`Vision fallback succeeded: @${visionResult.ref}`);\n // Record vision recovery success in failure registry\n if (failureRegistry && step.action.selector) {\n failureRegistry.record(step.url, step.action.selector, \"element_not_found\", step.ordinal, { method: \"vision\" });\n }\n } else {\n visionFallbackResult = {\n annotationCount: annotations.length,\n reasoning: visionResult?.reasoning ?? \"no match\",\n success: false,\n };\n failureHistory.push(\"Vision fallback: no matching element\");\n }\n } catch (error) {\n failureHistory.push(`Vision fallback error: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n // Agent Fallback: 全リトライ + スクロール回復後の最終手段\n if (!aiResult && config.enableAgentFallback) {\n debugLogger.log({\n phase: \"executor\",\n event: \"agent_fallback_start\",\n step: step.ordinal,\n data: { failureHistory },\n });\n logger.warn(\"Attempting agent fallback...\");\n\n const fallbackContext = contextChunker\n ? contextChunker.selectRelevant(step.description, step.url)\n : config.contextMarkdown;\n const fallbackResult = await runGoalAgent(\n browser,\n { description: step.description, action: step.action },\n failureHistory,\n fallbackContext,\n debugLogger,\n opts.aiProvider,\n );\n\n debugLogger.log({\n phase: \"executor\",\n event: \"agent_fallback_result\",\n step: step.ordinal,\n data: fallbackResult as unknown as Record<string, unknown>,\n });\n\n agentFallbackResult = {\n strategy: fallbackResult.alternativeStrategy,\n analysis: fallbackResult.analysis,\n reasoning: fallbackResult.reasoning,\n success: fallbackResult.success,\n };\n\n if (fallbackResult.success && fallbackResult.alternativeRef) {\n aiResult = {\n ref: fallbackResult.alternativeRef,\n aiResponseText: JSON.stringify(fallbackResult),\n reasoning: fallbackResult.reasoning,\n };\n resolveMethod = \"agent\";\n logger.success(`Agent fallback succeeded: @${fallbackResult.alternativeRef} (${fallbackResult.alternativeStrategy})`);\n // Record agent recovery success in failure registry\n if (failureRegistry && step.action.selector) {\n failureRegistry.record(step.url, step.action.selector, \"element_not_found\", step.ordinal, { method: `agent:${fallbackResult.alternativeStrategy}` });\n }\n } else {\n logger.warn(`Agent fallback: ${fallbackResult.alternativeStrategy} — ${fallbackResult.analysis}`);\n }\n }\n\n // リトライ回数(0 = 初回で成功)\n const retryCount = attempts > 1 ? attempts - 1 : 0;\n\n if (!aiResult) {\n const elementCount = countSnapshotElements(lastSnapshot);\n const selectorInfo = JSON.stringify(step.action.selector);\n const aiExcerpt = lastAiResponseText.slice(0, 200);\n\n // エラー分類\n const failureCategory = classifyFailure({\n error: `Could not resolve selector after ${attempts} attempts`,\n selectorResolved: false,\n actionExecuted: false,\n retryDetails,\n cachedRefUsed,\n });\n\n // Record final failure in failure registry\n if (failureRegistry && step.action.selector) {\n failureRegistry.record(step.url, step.action.selector, failureCategory, step.ordinal);\n }\n\n return {\n status: \"failed\",\n durationMs: Date.now() - start,\n error: `Could not resolve selector after ${attempts} attempts (elements: ${elementCount}, selector: ${selectorInfo}, AI: \"${aiExcerpt}\")`,\n retryCount,\n retryDetails,\n failureCategory,\n diagnostics: {\n lastSnapshotPreview: lastSnapshot.slice(0, 2000),\n failureHistory,\n lastAiResponseText,\n recoveryHint: getRecoveryHint(failureCategory),\n deterministicResolveResult: deterministicResolveResult || undefined,\n visionFallbackResult,\n agentFallbackResult,\n executionStrategy: strategy,\n stepAction: {\n type: step.action.type,\n selector: step.action.selector as Record<string, unknown> | undefined,\n value: step.action.value,\n url: step.action.url,\n },\n stepUrl: step.url,\n },\n // テレメトリフィールド\n resolveMethod,\n deterministicMatchType,\n deterministicConfidence,\n contextChunksUsed: contextChunker?.lastSelectedCount ?? 0,\n failureHintsProvided,\n workingMemoryTokens: opts.store.getWorkingMemorySummary()\n ? Math.ceil(opts.store.getWorkingMemorySummary()!.length / 4) : 0,\n snapshotElementCount: elementCount,\n };\n }\n\n debugLogger.log({\n phase: \"executor\",\n event: \"selector_resolve\",\n step: step.ordinal,\n data: { selector: step.action.selector, resolvedRef: aiResult.ref, url: step.url, attempts, resolveMethod },\n });\n\n // キャッシュ更新: AI解決成功時にキャッシュに書き込む\n if (opts.selectorCache && step.action.selector) {\n const cacheKey = buildCacheKey(step.ordinal, step.url, step.action.selector);\n updateCache(opts.selectorCache, cacheKey, aiResult.ref, buildSnapshotHash(lastSnapshot));\n }\n\n // キャッシュ・決定論的解決は既に個別ログを出しているのでスキップ\n if (resolveMethod !== \"cache\" && resolveMethod !== \"deterministic\") {\n logger.success(`AI resolved: @${aiResult.ref}${attempts > 1 ? ` (after ${attempts} attempts)` : \"\"}`);\n }\n const ref = `@${aiResult.ref}`;\n\n // アクション事前バリデーション(RefMap 優先 + type_mismatch 時リトライ)\n const value = resolveValue(step, opts.store);\n // optionText もテンプレート解決\n const optionText = step.action.optionText\n ? opts.store.resolveTemplate(step.action.optionText)\n : undefined;\n\n // 最新の refs を取得してバリデーション\n if (!lastRefs) {\n const freshResult = await browser.snapshotWithRefs();\n lastSnapshot = freshResult.tree;\n lastRefs = freshResult.refs;\n }\n\n let validation = validateAction(lastSnapshot, aiResult.ref, step.action.type, value, lastRefs);\n\n if (validation.warnings.length > 0) {\n for (const w of validation.warnings) {\n logger.warn(`Validation warning: ${w.message}`);\n }\n debugLogger.log({\n phase: \"executor\",\n event: \"validation_warnings\",\n step: step.ordinal,\n data: { warnings: validation.warnings },\n });\n }\n\n if (!validation.valid) {\n const hasTypeMismatch = validation.errors.some((e) => e.code === \"type_mismatch\");\n\n // type_mismatch の場合は新しいスナップショットでリトライ\n if (hasTypeMismatch) {\n debugLogger.log({\n phase: \"executor\",\n event: \"validation_retry\",\n step: step.ordinal,\n data: { errors: validation.errors, ref: aiResult.ref, actionType: step.action.type },\n });\n logger.warn(\"Validation failed with type_mismatch, retrying with fresh snapshot...\");\n\n // DOM安定化待機(固定500msスリープよりも効率的)\n await browser.waitForDOMStability(2000);\n const freshResult = await browser.snapshotWithRefs();\n\n if (freshResult.refs[aiResult.ref]) {\n lastSnapshot = freshResult.tree;\n lastRefs = freshResult.refs;\n validation = validateAction(lastSnapshot, aiResult.ref, step.action.type, value, lastRefs);\n\n if (validation.warnings.length > 0) {\n for (const w of validation.warnings) {\n logger.warn(`Validation warning (retry): ${w.message}`);\n }\n }\n }\n }\n\n if (!validation.valid) {\n const errorMessages = validation.errors.map((e) => e.message).join(\"; \");\n debugLogger.log({\n phase: \"executor\",\n event: \"validation_failed\",\n step: step.ordinal,\n data: { errors: validation.errors, ref: aiResult.ref, actionType: step.action.type },\n });\n return {\n status: \"failed\",\n durationMs: Date.now() - start,\n error: `Pre-execution validation failed: ${errorMessages}`,\n retryCount,\n retryDetails: retryDetails.length > 0 ? retryDetails : undefined,\n diagnostics: {\n lastSnapshotPreview: lastSnapshot.slice(0, 2000),\n failureHistory,\n lastAiResponseText,\n validationErrors: validation.errors.map((e) => `[${e.code}] ${e.message}`),\n validationWarnings: validation.warnings.map((w) => `[${w.code}] ${w.message}`),\n executionStrategy: strategy,\n stepAction: {\n type: step.action.type,\n selector: step.action.selector as Record<string, unknown> | undefined,\n value: step.action.value,\n url: step.action.url,\n },\n stepUrl: step.url,\n },\n // テレメトリフィールド\n resolveMethod,\n deterministicMatchType,\n deterministicConfidence,\n contextChunksUsed: contextChunker?.lastSelectedCount ?? 0,\n failureHintsProvided,\n snapshotElementCount: countSnapshotElements(lastSnapshot),\n };\n }\n\n logger.success(\"Validation retry succeeded\");\n }\n\n // ログ表示(sensitive マスク)\n const displayValue = value\n ? opts.store.maskSensitive(value)\n : value;\n\n // アクション実行\n const urlBefore = await browser.url();\n const pageCountBefore = await browser.pageCount();\n\n switch (step.action.type) {\n case \"click\":\n logger.step(`Click: ${ref}`);\n await browser.click(ref);\n break;\n case \"input\":\n logger.step(`Input: ${ref} = \"${displayValue ?? \"\"}\"`);\n await browser.fill(ref, value ?? \"\");\n break;\n case \"select\": {\n const displayOptionText = optionText ? opts.store.maskSensitive(optionText) : undefined;\n logger.step(`Select: ${ref} = \"${displayOptionText ?? displayValue ?? \"\"}\"`);\n await browser.select(ref, optionText ?? value ?? \"\");\n break;\n }\n case \"hover\":\n logger.step(`Hover (click fallback): ${ref}`);\n await browser.click(ref);\n break;\n case \"download\": {\n const downloadPath = opts.store.resolveTemplate(\n step.action.downloadPath ?? `/tmp/download-${Date.now()}.bin`,\n );\n logger.step(`Download: ${ref} → ${downloadPath}`);\n await browser.download(ref, downloadPath);\n\n if (opts.downloadManager) {\n opts.downloadManager.addDownload({\n path: downloadPath,\n filename: downloadPath.split(\"/\").pop() ?? \"unknown\",\n stepOrdinal: step.ordinal,\n timestamp: new Date().toISOString(),\n });\n }\n\n return {\n status: \"success\",\n durationMs: Date.now() - start,\n downloadedFile: downloadPath,\n retryCount,\n retryDetails: retryDetails.length > 0 ? retryDetails : undefined,\n };\n }\n }\n\n // click / input(submit) 後のナビゲーション待機\n if (step.action.type === \"click\") {\n await browser.waitForPossibleNavigation(urlBefore, pageCountBefore);\n\n // chrome-error:// 検出 → 前のURLに戻ってクリックをリトライ(最大2回)\n const maxClickRetries = 2;\n let clickRetryUrl = await browser.url();\n for (let clickAttempt = 0; clickRetryUrl.startsWith(\"chrome-error://\"); clickAttempt++) {\n if (clickAttempt >= maxClickRetries) {\n logger.warn(tf(\"executor.chromeErrorDetected\", { url: urlBefore }));\n throw new Error(`Navigation failed: page landed on chrome-error:// (from: ${urlBefore})`);\n }\n logger.warn(tf(\"executor.chromeErrorDetected\", { url: urlBefore }) + ` — retrying click (${clickAttempt + 1}/${maxClickRetries})`);\n await browser.navigate(urlBefore);\n await browser.waitForDOMStability(3000);\n await sleep(2000 * (clickAttempt + 1));\n\n // セレクタ再解決してクリック再実行\n await browser.click(ref);\n await browser.waitForPossibleNavigation(urlBefore, await browser.pageCount());\n clickRetryUrl = await browser.url();\n }\n }\n\n const durationMs = Date.now() - start;\n debugLogger.log({\n phase: \"executor\",\n event: \"action\",\n step: step.ordinal,\n data: {\n type: step.action.type,\n ref,\n value: displayValue,\n status: \"success\",\n durationMs,\n },\n });\n\n const workingMemorySummary = opts.store.getWorkingMemorySummary();\n return {\n status: \"success\",\n durationMs,\n retryCount,\n retryDetails: retryDetails.length > 0 ? retryDetails : undefined,\n // テレメトリフィールド\n resolveMethod,\n deterministicMatchType,\n deterministicConfidence,\n contextChunksUsed: contextChunker?.lastSelectedCount ?? 0,\n failureHintsProvided,\n workingMemoryTokens: workingMemorySummary\n ? Math.ceil(workingMemorySummary.length / 4) : 0,\n snapshotElementCount: lastSnapshot ? countSnapshotElements(lastSnapshot) : 0,\n };\n}\n\n/** メモリオペレーション(蓄積・集計)を実行 */\nasync function executeMemoryOperations(\n step: ParsedStep,\n store: RuntimeStore,\n dataStore: import(\"../context/data-store\").DataStore &\n import(\"../context/data-store\").DataAggregator,\n debugLogger: DebugLogger,\n logger: Logger,\n): Promise<void> {\n if (!step.memoryOperations) return;\n\n for (const op of step.memoryOperations) {\n if (op.type === \"append\") {\n if (!op.source) {\n logger.warn(`Memory append: source is required`);\n continue;\n }\n const rawValue = store.get(op.source);\n if (!rawValue) {\n logger.warn(`Memory append: variable \"${op.source}\" not found in store`);\n continue;\n }\n\n parseAndAppendToMemory(rawValue, {\n dataStore,\n debugLogger,\n phase: \"executor\",\n step: step.ordinal,\n collection: op.collection,\n });\n } else if (op.type === \"aggregate\") {\n if (!op.field || !op.operation || !op.outputVariable) {\n logger.warn(`Memory aggregate: field, operation, and outputVariable are required`);\n continue;\n }\n const result = dataStore.aggregate({\n collection: op.collection,\n field: op.field,\n operation: op.operation,\n });\n store.set(op.outputVariable, result);\n logger.success(`Memory: ${op.operation}(${op.collection}.${op.field}) = \"${result}\" → {{${op.outputVariable}}}`);\n debugLogger.log({\n phase: \"executor\",\n event: \"memory_aggregate\",\n step: step.ordinal,\n data: { collection: op.collection, field: op.field, operation: op.operation, result, outputVariable: op.outputVariable },\n });\n }\n }\n}\n\n/** RuntimeStore からテンプレート展開して値を解決 */\nfunction resolveValue(step: ParsedStep, store: RuntimeStore): string | undefined {\n const rawValue = step.action.value;\n if (rawValue === undefined) return undefined;\n return store.resolveTemplate(rawValue);\n}\n\n/** スナップショット内の要素数をカウント */\nfunction countSnapshotElements(snapshot: string): number {\n return countElements(snapshot);\n}\n","/**\n * ai-selector-resolver — セレクタ解決の AI フォールバック\n *\n * 決定的マッチングで要素が見つからない場合に、\n * AI にスナップショットを渡して @eN ref を推定させる。\n */\n\nimport { z } from \"zod\";\nimport { getModel, trackedGenerateObject, withAIRetry } from \"./ai-model\";\nimport type { AIModelProvider } from \"./ai-service\";\nimport { buildSelectorMessages } from \"../i18n/prompts\";\nimport type { Selector } from \"../runbook-executor/types\";\nimport type { DebugLogger } from \"../cli/debug-logger\";\n\nconst selectorResponseSchema = z.object({\n reasoning: z.string().describe(\"マッチング判断の理由を1-2文で説明\"),\n ref: z.string().describe(\"マッチした要素のref値(例: e3)。@は含めない。該当要素がスナップショット内に存在しない場合は空文字\"),\n});\n\nexport interface AIResolveResult {\n ref: string;\n aiResponseText: string;\n reasoning: string;\n /** AI に送ったプロンプト全文(診断レポート用) */\n prompt?: string;\n}\n\nexport interface RetryContext {\n attempt: number;\n previousAiResponse?: string;\n snapshotChanged: boolean;\n failureHistory: string[];\n /** FailureRegistry からの回復ヒント */\n failureHints?: string;\n}\n\n/** 共通の AI セレクタ解決実装 */\nasync function resolveImpl(\n snapshot: string,\n selector: Selector,\n stepDescription: string,\n url: string,\n contextMarkdown: string,\n debugLogger?: DebugLogger,\n retryContext?: RetryContext,\n workingMemorySummary?: string,\n aiProvider?: AIModelProvider,\n): Promise<AIResolveResult> {\n const { system, userPrompt } = buildSelectorMessages(snapshot, selector, stepDescription, url, contextMarkdown, retryContext, workingMemorySummary);\n const prompt = `${system}\\n---\\n${userPrompt}`;\n\n debugLogger?.log({\n phase: \"executor\",\n event: \"ai_selector_prompt\",\n data: { prompt, selector, stepDescription, url },\n });\n\n const model = aiProvider ? aiProvider.getModel(\"selector\") : getModel(\"selector\");\n const { object } = await withAIRetry(\n () =>\n trackedGenerateObject(\"selector\", {\n model,\n messages: [\n {\n role: \"system\",\n content: system,\n providerOptions: {\n anthropic: { cacheControl: { type: \"ephemeral\" } },\n },\n },\n { role: \"user\", content: userPrompt },\n ],\n schema: selectorResponseSchema,\n temperature: 0,\n }),\n { label: \"selector-resolve\" },\n );\n\n debugLogger?.log({\n phase: \"executor\",\n event: \"ai_selector_response\",\n data: { parsedResult: object as unknown as Record<string, unknown> },\n });\n\n return { ref: object.ref ?? \"\", aiResponseText: JSON.stringify(object), reasoning: object.reasoning, prompt };\n}\n\n/**\n * AI にスナップショット・セレクタ情報・ステップ説明を渡し、\n * 対応する @eN ref を返させる。\n * 該当要素が見つからなかった場合は null を返す。\n */\nexport async function resolveWithAI(\n snapshot: string,\n selector: Selector,\n stepDescription: string,\n url: string,\n contextMarkdown: string,\n debugLogger?: DebugLogger,\n workingMemorySummary?: string,\n aiProvider?: AIModelProvider,\n): Promise<AIResolveResult | null> {\n const result = await resolveImpl(snapshot, selector, stepDescription, url, contextMarkdown, debugLogger, undefined, workingMemorySummary, aiProvider);\n return result.ref ? result : null;\n}\n\n/**\n * resolveWithAI と同じだが、セレクタが見つからなかった場合でも\n * AI応答テキストを含む結果を返す(リトライ時のエラーメッセージ用)。\n */\nexport async function resolveWithAIDetailed(\n snapshot: string,\n selector: Selector,\n stepDescription: string,\n url: string,\n contextMarkdown: string,\n debugLogger?: DebugLogger,\n retryContext?: RetryContext,\n workingMemorySummary?: string,\n aiProvider?: AIModelProvider,\n): Promise<AIResolveResult> {\n return resolveImpl(snapshot, selector, stepDescription, url, contextMarkdown, debugLogger, retryContext, workingMemorySummary, aiProvider);\n}\n\n// buildSelectorMessages and pruneSelectorHints are now dispatched via i18n/prompts\n","/**\n * failure-registry — 失敗パターンの蓄積と回復ヒント生成\n *\n * 実行中に発生した失敗パターンを URL + セレクタヒント単位で蓄積し、\n * 類似セレクタの解決時に過去の回復成功パターンをヒントとして提供する。\n */\n\nimport type { FailureCategory } from \"./error-classifier\";\nimport type { Selector } from \"../runbook-executor/types\";\n\nexport interface FailurePattern {\n urlPattern: string;\n selectorHint: string;\n category: FailureCategory;\n recoveryUsed?: string;\n count: number;\n lastStepOrdinal: number;\n}\n\nconst MAX_PATTERNS = 50;\n\n/**\n * 実行中の失敗パターンを蓄積するレジストリ。\n * 類似パターンの回復ヒントを AI プロンプトに注入できる。\n */\nexport class FailureRegistry {\n private patterns: FailurePattern[] = [];\n\n /**\n * 失敗を記録する。\n * 同じ urlPattern + selectorHint + category の組み合わせは count をインクリメント。\n */\n record(\n url: string,\n selector: Selector,\n category: FailureCategory,\n stepOrdinal: number,\n resolution?: { method: string },\n ): void {\n const urlPattern = normalizeUrlPattern(url);\n const selectorHint = buildSelectorHint(selector);\n\n const existing = this.patterns.find(\n (p) => p.urlPattern === urlPattern && p.selectorHint === selectorHint && p.category === category,\n );\n\n if (existing) {\n existing.count++;\n existing.lastStepOrdinal = stepOrdinal;\n if (resolution) {\n existing.recoveryUsed = resolution.method;\n }\n } else {\n // LRU eviction\n if (this.patterns.length >= MAX_PATTERNS) {\n this.patterns.shift();\n }\n this.patterns.push({\n urlPattern,\n selectorHint,\n category,\n recoveryUsed: resolution?.method,\n count: 1,\n lastStepOrdinal: stepOrdinal,\n });\n }\n }\n\n /**\n * URL + セレクタに関連する回復ヒントを返す。\n * 類似パターンがなければ undefined。\n */\n getRelevantHints(url: string, selector: Selector): string | undefined {\n const urlPattern = normalizeUrlPattern(url);\n const selectorHint = buildSelectorHint(selector);\n\n // 同じ URL パターンでの失敗を検索\n const relevant = this.patterns.filter(\n (p) => p.urlPattern === urlPattern || p.selectorHint === selectorHint,\n );\n\n if (relevant.length === 0) return undefined;\n\n // 回復方法ごとの集計\n const recoveryMethods = new Map<string, number>();\n for (const p of relevant) {\n if (p.recoveryUsed) {\n recoveryMethods.set(\n p.recoveryUsed,\n (recoveryMethods.get(p.recoveryUsed) ?? 0) + p.count,\n );\n }\n }\n\n const parts: string[] = [];\n\n // 失敗パターンのサマリー\n const categoryCounts = new Map<string, number>();\n for (const p of relevant) {\n categoryCounts.set(p.category, (categoryCounts.get(p.category) ?? 0) + p.count);\n }\n const categoryStr = [...categoryCounts.entries()]\n .map(([cat, count]) => `${cat}(${count}x)`)\n .join(\", \");\n parts.push(`Similar failures on ${urlPattern}: ${categoryStr}`);\n\n // 回復方法のヒント\n if (recoveryMethods.size > 0) {\n const recoveryStr = [...recoveryMethods.entries()]\n .sort((a, b) => b[1] - a[1])\n .map(([method, count]) => `${method}(${count}x)`)\n .join(\", \");\n parts.push(`Resolved by: ${recoveryStr}`);\n }\n\n return parts.join(\". \");\n }\n\n /** 蓄積パターン数 */\n get size(): number {\n return this.patterns.length;\n }\n\n /** パターンをクリア */\n clear(): void {\n this.patterns = [];\n }\n}\n\n/**\n * URL をパスパラメータをワイルドカード化してパターン化する。\n * 例: /users/123/edit → /users/{id}/edit\n */\nexport function normalizeUrlPattern(url: string): string {\n try {\n const parsed = new URL(url);\n const normalizedPath = parsed.pathname\n .split(\"/\")\n .map((segment) => {\n // 数値のみ or UUID 的なセグメントをワイルドカード化\n if (/^\\d+$/.test(segment)) return \"*\";\n if (/^[0-9a-f]{8,}$/i.test(segment)) return \"*\";\n return segment;\n })\n .join(\"/\");\n return `${parsed.hostname}${normalizedPath}`;\n } catch {\n return url;\n }\n}\n\n/**\n * セレクタから ref 番号に依存しない識別子を生成する。\n * role + name ベースで、スナップショットの ref 番号が変わっても同じヒントになる。\n */\nexport function buildSelectorHint(selector: Selector): string {\n const parts: string[] = [];\n if (selector.role) parts.push(`role:${selector.role}`);\n if (selector.name) parts.push(`name:${selector.name}`);\n if (selector.ariaLabel) parts.push(`aria:${selector.ariaLabel}`);\n if (selector.dataTestId) parts.push(`testid:${selector.dataTestId}`);\n return parts.join(\"|\") || \"unknown\";\n}\n","/**\n * goal-agent — セレクタ解決が全フェーズ失敗した後の最終フォールバック\n *\n * ページ全体のスナップショットとステップの目的を AI に渡し、\n * 代替操作パス(折り畳み展開、モーダル閉じ、別要素等)を探させる。\n *\n * executor / debugger から利用。generator では Mastra Agent が自律的に再試行するため不使用。\n */\n\nimport { z } from \"zod\";\nimport { getModel, trackedGenerateObject } from \"./ai-model\";\nimport type { AIModelProvider } from \"./ai-service\";\nimport { buildFallbackMessages } from \"../i18n/prompts\";\nimport { findElementInSnapshot } from \"../browser/snapshot-parser\";\nimport { filterSnapshot } from \"../browser/snapshot-filter\";\nimport type { Selector } from \"../runbook-executor/types\";\nimport type { AgentBrowser } from \"../browser/browser-client\";\nimport type { DebugLogger } from \"../cli/debug-logger\";\n\nexport type AlternativeStrategy =\n | \"direct_ref\"\n | \"scroll_up_and_retry\"\n | \"expand_collapsed\"\n | \"dismiss_overlay\"\n | \"tab_navigation\"\n | \"not_found\";\n\nconst agentFallbackSchema = z.object({\n analysis: z.string().describe(\"ページの現状の分析(200字以内)\"),\n alternativeRef: z.string().describe(\n \"代替となる操作対象要素のref値(例: e5)。@は含めない。見つからない場合は空文字。\",\n ),\n alternativeStrategy: z.enum([\n \"direct_ref\",\n \"scroll_up_and_retry\",\n \"expand_collapsed\",\n \"dismiss_overlay\",\n \"tab_navigation\",\n \"not_found\",\n ]).describe(\"推奨する代替戦略\"),\n prerequisiteRef: z.string().optional().describe(\n \"alternativeStrategy が expand_collapsed/dismiss_overlay の場合: 先に操作する要素のref\",\n ),\n reasoning: z.string().describe(\"代替パスを選んだ理由(100字以内)\"),\n});\n\nexport interface AgentFallbackResult {\n success: boolean;\n alternativeRef: string;\n alternativeStrategy: AlternativeStrategy;\n prerequisiteRef?: string;\n analysis: string;\n reasoning: string;\n}\n\nexport interface GoalAgentStep {\n description: string;\n action: {\n type: string;\n selector?: Selector;\n };\n}\n\n/**\n * 全リトライ + スクロール回復が失敗した後に呼び出す。\n * ページ上部にスクロールし、完全スナップショットを取得して AI に代替パスを探させる。\n */\nexport async function runGoalAgent(\n browser: AgentBrowser,\n step: GoalAgentStep,\n failureHistory: string[],\n contextMarkdown: string,\n debugLogger?: DebugLogger,\n aiProvider?: AIModelProvider,\n): Promise<AgentFallbackResult> {\n // ページ上部にスクロールして全体を見渡す\n try {\n await browser.scroll(\"up\", 2000);\n await browser.waitForDOMStability(3000);\n } catch {\n // スクロール失敗は無視して続行\n }\n\n const fullSnapshot = filterSnapshot(await browser.snapshot());\n const currentUrl = await browser.url();\n\n const { system, userPrompt } = buildFallbackMessages(\n fullSnapshot,\n step,\n failureHistory,\n currentUrl,\n contextMarkdown,\n );\n\n try {\n const model = aiProvider ? aiProvider.getModel(\"fallback\") : getModel(\"fallback\");\n const { object } = await trackedGenerateObject(\"fallback\", {\n model,\n messages: [\n {\n role: \"system\",\n content: system,\n providerOptions: {\n anthropic: { cacheControl: { type: \"ephemeral\" } },\n },\n },\n { role: \"user\", content: userPrompt },\n ],\n schema: agentFallbackSchema,\n temperature: 0.3,\n });\n\n if (object.alternativeStrategy === \"not_found\" || !object.alternativeRef) {\n return { ...object, alternativeRef: object.alternativeRef ?? \"\", success: false };\n }\n\n // 前提操作が必要な場合は実行\n if (\n object.prerequisiteRef &&\n (object.alternativeStrategy === \"expand_collapsed\" ||\n object.alternativeStrategy === \"dismiss_overlay\")\n ) {\n debugLogger?.log({\n phase: \"executor\",\n event: \"agent_fallback_prerequisite\",\n data: {\n strategy: object.alternativeStrategy,\n prerequisiteRef: object.prerequisiteRef,\n },\n });\n\n try {\n await browser.click(`@${object.prerequisiteRef}`);\n await browser.waitForDOMStability(2000);\n } catch {\n return { ...object, alternativeRef: object.alternativeRef ?? \"\", success: false };\n }\n\n // 前提操作後にターゲット要素が存在するか確認\n const updatedSnapshot = await browser.snapshot();\n if (findElementInSnapshot(updatedSnapshot, object.alternativeRef) === null) {\n return { ...object, success: false };\n }\n }\n\n return { ...object, success: true };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n console.warn(`[goal-agent] Agent fallback AI call failed: ${msg}`);\n return {\n analysis: \"AI呼び出しに失敗\",\n alternativeRef: \"\",\n alternativeStrategy: \"not_found\",\n reasoning: \"AI fallback failed\",\n success: false,\n };\n }\n}\n\n// buildFallbackMessages is now dispatched via i18n/prompts\n","/**\n * vision-resolver — スクリーンショットベースのセレクタ解決\n *\n * A11y ツリーのテキストベース解決が失敗した場合のフォールバック。\n * アノテーション付きスクリーンショットを AI に渡し、\n * 視覚的に要素を特定して対応する ref を返す。\n *\n * canvas、Shadow DOM、iframe、カスタム Web Components など\n * A11y ツリーに表れない要素に有効。\n */\n\nimport { z } from \"zod\";\nimport { getModel, trackedGenerateObject, withAIRetry } from \"./ai-model\";\nimport type { AIModelProvider } from \"./ai-service\";\nimport { buildVisionMessages as buildVisionMessagesI18n } from \"../i18n/prompts\";\nimport type { Selector } from \"../runbook-executor/types\";\nimport type { Annotation } from \"../browser/engine\";\nimport type { DebugLogger } from \"../cli/debug-logger\";\n\nconst visionResponseSchema = z.object({\n reasoning: z.string().describe(\n \"スクリーンショット内で要素を特定した理由(1-3文)\",\n ),\n ref: z.string().describe(\n \"特定した要素の ref 値(例: e3)。@は含めない。該当する要素が見つからない場合は空文字\",\n ),\n annotationNumber: z.number().optional().describe(\n \"特定した要素のアノテーション番号(スクリーンショット上の番号ラベル)\",\n ),\n confidence: z.number().min(0).max(1).describe(\n \"特定の確信度(0.0-1.0)\",\n ),\n});\n\nexport interface VisionResolveResult {\n ref: string;\n reasoning: string;\n annotationNumber?: number;\n confidence: number;\n}\n\n/**\n * アノテーション付きスクリーンショットを AI に渡してセレクタを解決する。\n *\n * @returns 解決結果。要素が見つからない場合は null。\n */\nexport async function resolveWithVision(\n imageBuffer: Buffer,\n annotations: Annotation[],\n selector: Selector,\n stepDescription: string,\n url: string,\n failureHistory: string[],\n debugLogger?: DebugLogger,\n aiProvider?: AIModelProvider,\n): Promise<VisionResolveResult | null> {\n debugLogger?.log({\n phase: \"executor\",\n event: \"vision_fallback_start\",\n data: {\n annotationCount: annotations.length,\n selector,\n stepDescription,\n url,\n failureHistoryCount: failureHistory.length,\n },\n });\n\n // アノテーションが空ならスキップ(ページに要素が全くない場合)\n if (annotations.length === 0) {\n debugLogger?.log({\n phase: \"executor\",\n event: \"vision_fallback_skip\",\n data: { reason: \"no annotations\" },\n });\n return null;\n }\n\n const { system, userTextContent } = buildVisionMessagesI18n(\n annotations,\n selector,\n stepDescription,\n url,\n failureHistory,\n );\n\n try {\n const model = aiProvider ? aiProvider.getModel(\"vision\") : getModel(\"vision\");\n const { object } = await withAIRetry(\n () =>\n trackedGenerateObject(\"vision\", {\n model,\n messages: [\n {\n role: \"system\",\n content: system,\n providerOptions: {\n anthropic: { cacheControl: { type: \"ephemeral\" } },\n },\n },\n {\n role: \"user\",\n content: [\n { type: \"text\", text: userTextContent },\n { type: \"image\", image: imageBuffer },\n ],\n },\n ],\n schema: visionResponseSchema,\n temperature: 0,\n }),\n { label: \"vision-resolve\" },\n );\n\n debugLogger?.log({\n phase: \"executor\",\n event: \"vision_fallback_result\",\n data: {\n ref: object.ref,\n reasoning: object.reasoning,\n annotationNumber: object.annotationNumber,\n confidence: object.confidence,\n },\n });\n\n if (!object.ref) return null;\n\n // バリデーション: ref がアノテーション内に存在するか確認\n const matchingAnnotation = annotations.find((a) => a.ref === object.ref);\n if (!matchingAnnotation) {\n debugLogger?.log({\n phase: \"executor\",\n event: \"vision_fallback_invalid_ref\",\n data: {\n ref: object.ref,\n availableRefs: annotations.map((a) => a.ref),\n },\n });\n return null;\n }\n\n return {\n ref: object.ref,\n reasoning: object.reasoning,\n annotationNumber: object.annotationNumber,\n confidence: object.confidence,\n };\n } catch (error) {\n debugLogger?.log({\n phase: \"executor\",\n event: \"vision_fallback_error\",\n data: { error: error instanceof Error ? error.message : String(error) },\n });\n return null;\n }\n}\n\n/** @internal テスト用にエクスポート(i18n ディスパッチャー経由) */\nexport { buildVisionMessagesI18n as buildVisionMessages };\n","/**\n * action-validator — アクション事前バリデーション\n *\n * ref 解決後、アクション実行前にアクションの妥当性を検証する。\n * browser-use の Pydantic ベースバリデーション、\n * Stagehand の observe → act パターンを参考に、\n * 無効なアクション実行を事前に回避する。\n */\n\nimport {\n findElementInSnapshot,\n type ParsedSnapshotElement,\n} from \"../browser/snapshot-parser\";\nimport type { RefMap } from \"../browser/engine\";\n\nexport interface ValidationError {\n code: \"ref_not_found\" | \"type_mismatch\" | \"value_required\" | \"selector_missing\";\n message: string;\n}\n\nexport interface ValidationWarning {\n code: \"element_disabled\" | \"possible_overlay\" | \"element_readonly\";\n message: string;\n}\n\nexport interface ValidationResult {\n valid: boolean;\n errors: ValidationError[];\n warnings: ValidationWarning[];\n}\n\n/** action タイプごとに互換性のある role の一覧 */\nconst COMPATIBLE_ROLES: Record<string, Set<string>> = {\n click: new Set([\n \"button\",\n \"link\",\n \"checkbox\",\n \"radio\",\n \"tab\",\n \"menuitem\",\n \"menuitemcheckbox\",\n \"menuitemradio\",\n \"switch\",\n \"option\",\n \"treeitem\",\n \"row\",\n \"cell\",\n \"gridcell\",\n \"img\",\n \"figure\",\n ]),\n input: new Set([\"textbox\", \"searchbox\", \"combobox\", \"spinbutton\", \"textarea\"]),\n select: new Set([\"combobox\", \"listbox\", \"select\"]),\n download: new Set([\"link\", \"button\", \"menuitem\", \"menuitemcheckbox\", \"menuitemradio\"]),\n hover: new Set(), // 空 = 全ロール OK\n key: new Set(), // 空 = セレクタ不要、グローバルキーボード操作\n};\n\n/** click は幅広いため、明示的に非互換なロールだけ定義 */\nconst CLICK_INCOMPATIBLE_ROLES = new Set([\n \"textbox\",\n \"searchbox\",\n \"textarea\",\n \"spinbutton\",\n]);\n\n/** 値が必要なアクションタイプ */\nconst VALUE_REQUIRED_ACTIONS = new Set([\"input\", \"select\"]);\n\n/** ロール文字列が有効な ARIA ロールかを簡易判定 */\nfunction isValidRole(role: string): boolean {\n return role.length > 1 && /^[a-z]/.test(role);\n}\n\n/**\n * アクション実行前にバリデーションを行う。\n *\n * @param snapshot - 現在のアクセシビリティスナップショット\n * @param ref - 解決済みの ref 値(@ なし、例: \"e3\")\n * @param actionType - アクション種別(click, input, select, hover 等)\n * @param value - アクション実行時の値(input, select で使用)\n * @param refs - RefMap(構造化データ)。渡された場合はテキストパースを回避\n */\nexport function validateAction(\n snapshot: string,\n ref: string,\n actionType: string,\n value?: string,\n refs?: RefMap,\n): ValidationResult {\n const errors: ValidationError[] = [];\n const warnings: ValidationWarning[] = [];\n\n // 1. ref から要素情報を取得(RefMap 優先、フォールバックでテキストパース)\n let element: ParsedSnapshotElement | null = null;\n const refEntry = refs?.[ref];\n if (refEntry) {\n element = { ref, role: refEntry.role, name: refEntry.name ?? \"\", attributes: {} };\n } else {\n element = findElementInSnapshot(snapshot, ref);\n }\n\n if (!element) {\n errors.push({\n code: \"ref_not_found\",\n message: `[ref=${ref}] がスナップショット内に存在しません`,\n });\n // ref が見つからない場合、他のチェックは不可\n return { valid: false, errors, warnings };\n }\n\n // 2. action と role の互換性チェック\n const normalizedAction = normalizeActionType(actionType);\n\n // パーサーが不正なロールを返した場合は type_mismatch チェックをスキップ(安全ガード)\n if (normalizedAction !== \"hover\" && isValidRole(element.role)) {\n const compatible = COMPATIBLE_ROLES[normalizedAction];\n if (compatible && compatible.size > 0) {\n // 明示的な互換リストがある場合\n if (!compatible.has(element.role)) {\n // click は広範囲に互換だが、テキスト入力系は非互換\n if (normalizedAction === \"click\" && !CLICK_INCOMPATIBLE_ROLES.has(element.role)) {\n // click は互換リスト外でも、明示的非互換でなければ警告止まり\n } else {\n errors.push({\n code: \"type_mismatch\",\n message: `アクション \"${actionType}\" は role=\"${element.role}\" の要素と互換性がありません(ref=${ref})`,\n });\n }\n }\n }\n }\n\n // 3. 値が必要なアクションで値が空\n if (VALUE_REQUIRED_ACTIONS.has(normalizedAction) && (!value || value.trim() === \"\")) {\n errors.push({\n code: \"value_required\",\n message: `アクション \"${actionType}\" には値が必要です(ref=${ref})`,\n });\n }\n\n // 4. disabled チェック\n if (element.attributes.disabled || element.attributes.disabled === \"true\") {\n warnings.push({\n code: \"element_disabled\",\n message: `要素が disabled です(ref=${ref}, role=${element.role})`,\n });\n }\n\n // 5. readonly チェック\n if (element.attributes.readonly || element.attributes.readonly === \"true\") {\n if (normalizedAction === \"input\") {\n warnings.push({\n code: \"element_readonly\",\n message: `要素が readonly です(ref=${ref}, role=${element.role})`,\n });\n }\n }\n\n // 6. overlay(dialog)チェック\n const overlayWarning = checkOverlay(snapshot, ref);\n if (overlayWarning) {\n warnings.push(overlayWarning);\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\n/** アクションタイプを正規化 */\nfunction normalizeActionType(actionType: string): string {\n switch (actionType) {\n case \"fill\":\n case \"type\":\n case \"input\":\n return \"input\";\n case \"click\":\n return \"click\";\n case \"select\":\n return \"select\";\n case \"hover\":\n return \"hover\";\n default:\n return actionType;\n }\n}\n\n/**\n * dialog/alertdialog が存在し、ターゲット要素が dialog 外にある場合に警告を返す。\n * スナップショットのインデント構造から、要素が dialog のネスト内にあるか判定する。\n */\nfunction checkOverlay(snapshot: string, targetRef: string): ValidationWarning | null {\n const lines = snapshot.split(\"\\n\");\n\n // dialog/alertdialog の行インデックスとインデントレベルを取得\n let dialogLineIndex = -1;\n let dialogIndent = -1;\n for (let i = 0; i < lines.length; i++) {\n const trimmed = lines[i].trimStart();\n if (trimmed.startsWith(\"dialog\") || trimmed.startsWith(\"alertdialog\")) {\n dialogLineIndex = i;\n dialogIndent = lines[i].length - trimmed.length;\n break;\n }\n }\n\n if (dialogLineIndex === -1) return null;\n\n // ターゲット ref の行を探す\n const refPattern = `[ref=${targetRef}]`;\n let targetLineIndex = -1;\n for (let i = 0; i < lines.length; i++) {\n if (lines[i].includes(refPattern)) {\n targetLineIndex = i;\n break;\n }\n }\n\n if (targetLineIndex === -1) return null;\n\n // ターゲットが dialog の後にあり、dialog のインデント以下なら dialog 内\n if (targetLineIndex > dialogLineIndex) {\n const targetIndent = lines[targetLineIndex].length - lines[targetLineIndex].trimStart().length;\n if (targetIndent > dialogIndent) {\n // dialog 内 → 問題なし\n return null;\n }\n }\n\n // ターゲットが dialog 前、または dialog 外のインデント → 警告\n return {\n code: \"possible_overlay\",\n message: `dialog/alertdialog が存在し、ターゲット要素(ref=${targetRef})がその外側にあります。モーダルに遮られている可能性があります`,\n };\n}\n","/**\n * deterministic-resolver — 決定論的セレクタ解決\n *\n * AI を呼び出す前に、スナップショット内の要素をパターンマッチで直接解決する。\n * キャッシュが空でも AI なしで解決できるケースを増やし、安定性とコストを改善する。\n *\n * Stagehand の observe → act パターン、\n * browser-use のインデックスベース参照を参考。\n */\n\nimport {\n parseAllElements,\n} from \"../browser/snapshot-parser\";\nimport type { ParsedSnapshotElement } from \"../browser/snapshot-parser\";\nimport type { RefMap } from \"../browser/engine\";\nimport type { Selector } from \"../runbook-executor/types\";\n\nexport type MatchType =\n | \"exact_role_and_name\"\n | \"exact_name\"\n | \"role_and_partial_name\"\n | \"role_and_text\"\n | \"role_and_innerText\"\n | \"placeholder\"\n | \"unique_role\"\n | null;\n\nexport interface DeterministicResolveResult {\n /** 解決された ref 値(@ なし、例: \"e3\")。解決失敗時は null */\n ref: string | null;\n /** マッチの種類 */\n matchType: MatchType;\n /** マッチの信頼度(0-1) */\n confidence: number;\n}\n\n/**\n * セレクタ情報からスナップショット内の要素を決定論的に解決する。\n *\n * マッチング優先順位(上から順に試行):\n * 1. role + ariaLabel 完全一致(confidence: 1.0)\n * 2. ariaLabel 完全一致(role 不一致でも)(confidence: 0.9)\n * 3. role + ariaLabel 部分一致(大文字小文字無視)(confidence: 0.7)\n * 4. role + text 部分一致(confidence: 0.6)\n * 5. ariaLabel のみ部分一致(role なし)(confidence: 0.6)\n * 6. role + innerText 部分一致(confidence: 0.55)\n * 7. placeholder 完全一致(confidence: 0.5)\n * 8. role のみで一意特定(confidence: 0.4)\n *\n * 候補が 1 件かつ confidence ≥ 0.9 → 確定\n * 候補が複数、または confidence < 0.9 → null(AI に委譲)\n *\n * @param snapshot - 現在のアクセシビリティスナップショット\n * @param selector - セレクタ情報(ariaLabel, role, text 等)\n * @param refs - RefMap(構造化データ)。渡された場合はテキストパースを回避\n * @returns 解決結果\n */\nexport function resolveDeterministic(\n snapshot: string,\n selector: Selector,\n refs?: RefMap,\n): DeterministicResolveResult {\n const noMatch: DeterministicResolveResult = {\n ref: null,\n matchType: null,\n confidence: 0,\n };\n\n // RefMap 優先、フォールバックでテキストパース\n const parsedElements: ParsedSnapshotElement[] = [];\n const elements: Array<{ ref: string; role: string; name: string; placeholder?: string }> = [];\n if (refs) {\n for (const [ref, entry] of Object.entries(refs)) {\n elements.push({ ref, role: entry.role, name: entry.name ?? \"\" });\n }\n } else {\n const parsed = parseAllElements(snapshot);\n parsedElements.push(...parsed);\n for (const el of parsed) {\n elements.push({\n ref: el.ref,\n role: el.role,\n name: el.name,\n placeholder: el.attributes.placeholder,\n });\n }\n }\n if (elements.length === 0) return noMatch;\n\n const selectorRole = normalizeString(selector.role);\n const selectorAriaLabel = normalizeString(selector.ariaLabel);\n const selectorText = normalizeString(selector.text);\n const selectorInnerText = normalizeString(selector.innerText);\n const selectorPlaceholder = normalizeString(selector.placeholder);\n\n // テキスト識別子も role もなければパターンマッチ不可\n if (!selectorAriaLabel && !selectorText && !selectorInnerText && !selectorPlaceholder && !selectorRole) return noMatch;\n\n // シングルパス: 各要素を1回だけ走査し、全優先度のバケットに振り分ける。\n // 事前に toLowerCase を1回だけ計算してループ内の再計算を回避する。\n const labelLower = selectorAriaLabel?.toLowerCase();\n const textLower = selectorText?.toLowerCase();\n const innerTextLower = selectorInnerText?.toLowerCase();\n\n // 各優先度の候補バケット(最大1件 or 複数件を追跡)\n type Bucket = { ref: string; count: number };\n let p1: Bucket | null = null; // role + ariaLabel 完全一致\n let p2: Bucket | null = null; // ariaLabel 完全一致(role 不問)\n let p3: Bucket | null = null; // role + ariaLabel 部分一致\n let p4: Bucket | null = null; // role + text 部分一致\n let p5: Bucket | null = null; // ariaLabel のみ部分一致(role なし)\n let p6: Bucket | null = null; // role + innerText 部分一致\n let p7: Bucket | null = null; // placeholder 完全一致\n let p8: Bucket | null = null; // role のみで一意特定\n\n for (const el of elements) {\n const nameExact = selectorAriaLabel ? el.name === selectorAriaLabel : false;\n const roleMatch = selectorRole ? el.role === selectorRole : false;\n\n // 優先度 1: role + ariaLabel 完全一致 (confidence: 1.0)\n if (roleMatch && nameExact) {\n if (!p1) { p1 = { ref: el.ref, count: 1 }; }\n else { p1.count++; }\n }\n\n // 優先度 2: ariaLabel 完全一致(role 不問)(confidence: 0.9)\n if (nameExact) {\n if (!p2) { p2 = { ref: el.ref, count: 1 }; }\n else { p2.count++; }\n }\n\n // 部分一致は toLowerCase が必要\n const nameLower = (labelLower || textLower || innerTextLower) ? el.name.toLowerCase() : \"\";\n\n // 優先度 3: role + ariaLabel 部分一致 (confidence: 0.7)\n if (roleMatch && labelLower && nameLower.includes(labelLower)) {\n if (!p3) { p3 = { ref: el.ref, count: 1 }; }\n else { p3.count++; }\n }\n\n // 優先度 4: role + text 部分一致 (confidence: 0.6)\n if (roleMatch && textLower && nameLower.includes(textLower)) {\n if (!p4) { p4 = { ref: el.ref, count: 1 }; }\n else { p4.count++; }\n }\n\n // 優先度 5: ariaLabel のみの部分一致(role なし)(confidence: 0.6)\n if (!selectorRole && labelLower && nameLower.includes(labelLower)) {\n if (!p5) { p5 = { ref: el.ref, count: 1 }; }\n else { p5.count++; }\n }\n\n // 優先度 6: role + innerText 部分一致 (confidence: 0.55)\n // innerText は snapshot の name フィールドと同じ値なので、selector.innerText → 要素の name でマッチング\n if (roleMatch && innerTextLower && nameLower.includes(innerTextLower)) {\n if (!p6) { p6 = { ref: el.ref, count: 1 }; }\n else { p6.count++; }\n }\n\n // 優先度 7: placeholder 完全一致 (confidence: 0.5)\n if (selectorPlaceholder && el.placeholder && el.placeholder === selectorPlaceholder) {\n if (!p7) { p7 = { ref: el.ref, count: 1 }; }\n else { p7.count++; }\n }\n\n // 優先度 8: role のみで一意特定 (confidence: 0.4)\n if (selectorRole && el.role === selectorRole) {\n if (!p8) { p8 = { ref: el.ref, count: 1 }; }\n else { p8.count++; }\n }\n }\n\n // 優先度順に候補1件のバケットを返す\n if (p1 && p1.count === 1) return { ref: p1.ref, matchType: \"exact_role_and_name\", confidence: 1.0 };\n if (p2 && p2.count === 1) return { ref: p2.ref, matchType: \"exact_name\", confidence: 0.9 };\n if (p3 && p3.count === 1) return { ref: p3.ref, matchType: \"role_and_partial_name\", confidence: 0.7 };\n if (p4 && p4.count === 1) return { ref: p4.ref, matchType: \"role_and_text\", confidence: 0.6 };\n if (p5 && p5.count === 1) return { ref: p5.ref, matchType: \"role_and_partial_name\", confidence: 0.6 };\n if (p6 && p6.count === 1) return { ref: p6.ref, matchType: \"role_and_innerText\", confidence: 0.55 };\n if (p7 && p7.count === 1) return { ref: p7.ref, matchType: \"placeholder\", confidence: 0.5 };\n if (p8 && p8.count === 1) return { ref: p8.ref, matchType: \"unique_role\", confidence: 0.4 };\n\n return noMatch;\n}\n\n/** unknown 値を安全に string | undefined に変換 */\nfunction normalizeString(value: unknown): string | undefined {\n if (typeof value === \"string\" && value.trim() !== \"\") {\n return value.trim();\n }\n return undefined;\n}\n","/**\n * confirmation --- ConfirmationProvider インターフェース + 純粋ロジック\n *\n * TTY / HTTP の承認方式を抽象化する。\n */\n\nimport type { ParsedStep } from \"../runbook-executor/types\";\n\nexport type ConfirmationResult = \"approve\" | \"skip\" | \"abort\";\n\n/** confirm() に渡す追加コンテキスト */\nexport interface ConfirmationContext {\n /** 手順書のゴール(業務内容) */\n goal: string;\n}\n\n/**\n * ステップ実行前の承認プロバイダ。\n * CLI 実装は CliConfirmationProvider (runbook-executor/confirmation.ts)、\n * 将来の HTTP 実装は POST /execute-respond に対応。\n */\nexport interface ConfirmationProvider {\n confirm(step: ParsedStep, stepIndex: number, context?: ConfirmationContext): Promise<ConfirmationResult>;\n dispose?(): Promise<void>;\n}\n\n/**\n * ステップが承認を必要とするか判定(純粋ロジック)\n */\nexport function needsConfirmation(step: ParsedStep, skipAll: boolean): boolean {\n if (skipAll) return false;\n return step.requiresConfirmation;\n}\n","/**\n * confirmation --- CLI 実装の ConfirmationProvider\n */\n\nimport { promptSelect, formatRiskHint, note } from \"../cli/prompts\";\nimport type { ConfirmationProvider, ConfirmationResult, ConfirmationContext } from \"../harness/confirmation\";\nimport type { ParsedStep } from \"./types\";\nimport { t, tf } from \"../i18n\";\n\nexport type { ConfirmationResult } from \"../harness/confirmation\";\nexport { needsConfirmation } from \"../harness/confirmation\";\n\n/**\n * CLI (TTY) 用の承認プロバイダ\n */\nexport class CliConfirmationProvider implements ConfirmationProvider {\n async confirm(step: ParsedStep, _stepIndex: number, _context?: ConfirmationContext): Promise<ConfirmationResult> {\n return promptConfirmation(step);\n }\n}\n\n/**\n * ステップ実行前の承認プロンプトを表示\n */\nexport async function promptConfirmation(\n step: ParsedStep,\n): Promise<ConfirmationResult> {\n note(\n `${tf(\"confirmation.stepInfo\", { ordinal: step.ordinal, description: step.description })}\\n${tf(\"confirmation.riskLevelLabel\", { level: step.riskLevel, hint: formatRiskHint(step.riskLevel) })}`,\n t(\"confirmation.title\"),\n );\n\n return promptSelect<ConfirmationResult>(t(\"confirmation.selectAction\"), [\n { value: \"approve\", label: t(\"confirmation.approve\") },\n { value: \"skip\", label: t(\"confirmation.skip\") },\n { value: \"abort\", label: t(\"confirmation.abort\"), hint: t(\"confirmation.abortHint\") },\n ]);\n}\n","/**\n * capture-executor — ランタイムキャプチャの実行\n *\n * ステップ実行後にページから値を取得し、RuntimeStore に格納する。\n */\n\nimport { z } from \"zod\";\nimport { getModel, trackedGenerateObject, withAIRetry } from \"../harness/ai-model\";\nimport { filterSnapshot } from \"../browser/snapshot-filter\";\nimport type { AgentBrowser } from \"../browser/browser-client\";\nimport type { StepCapture } from \"../runbook-executor/types\";\nimport type { RuntimeStore } from \"./runtime-store\";\nimport { log } from \"../cli/prompts\";\n\nconst captureValueSchema = z.object({\n value: z.string().nullable().describe(\"抽出した値。見つからない場合はnull\"),\n});\n\n/**\n * 単一のキャプチャ定義を実行し、取得した値を返す。\n * 取得できなかった場合は null を返す。\n */\nexport async function executeCapture(\n browser: AgentBrowser,\n capture: StepCapture,\n store: RuntimeStore,\n): Promise<string | null> {\n switch (capture.strategy) {\n case \"snapshot\":\n return captureFromSnapshot(browser, capture);\n case \"url\":\n return captureFromUrl(browser, capture);\n case \"ai\":\n return captureWithAI(browser, capture);\n case \"expression\":\n return captureFromExpression(capture, store);\n case \"evaluate\":\n return captureWithEvaluate(browser, capture);\n default:\n log.warn(`Unknown capture strategy: ${capture.strategy}`);\n return null;\n }\n}\n\nasync function captureFromSnapshot(\n browser: AgentBrowser,\n capture: StepCapture,\n): Promise<string | null> {\n if (!capture.pattern) {\n log.warn(`Capture \"${capture.name}\": snapshot strategy requires pattern`);\n return null;\n }\n\n const snapshot = await browser.snapshot();\n let re: RegExp;\n try {\n re = new RegExp(capture.pattern);\n } catch {\n log.warn(`Capture \"${capture.name}\": invalid regex pattern: ${capture.pattern}`);\n return null;\n }\n const match = re.exec(snapshot);\n\n if (!match) {\n return null;\n }\n\n const group = capture.group ?? 1;\n return match[group] ?? match[0] ?? null;\n}\n\nasync function captureFromUrl(\n browser: AgentBrowser,\n capture: StepCapture,\n): Promise<string | null> {\n if (!capture.pattern) {\n log.warn(`Capture \"${capture.name}\": url strategy requires pattern`);\n return null;\n }\n\n const currentUrl = await browser.url();\n let re: RegExp;\n try {\n re = new RegExp(capture.pattern);\n } catch {\n log.warn(`Capture \"${capture.name}\": invalid regex pattern: ${capture.pattern}`);\n return null;\n }\n const match = re.exec(currentUrl);\n\n if (!match) {\n return null;\n }\n\n const group = capture.group ?? 1;\n return match[group] ?? match[0] ?? null;\n}\n\n/** 静的なキャプチャ用システムプロンプト(キャッシュ対象) */\nconst CAPTURE_SYSTEM_PROMPT = \"以下のページスナップショットから情報を抽出してください。抽出対象の説明に基づいて、スナップショット内から該当する値を特定して返してください。\";\n\nasync function captureWithAI(\n browser: AgentBrowser,\n capture: StepCapture,\n): Promise<string | null> {\n if (!capture.prompt) {\n log.warn(`Capture \"${capture.name}\": ai strategy requires prompt`);\n return null;\n }\n\n const snapshot = filterSnapshot(await browser.snapshot());\n const currentUrl = await browser.url();\n\n const userPrompt = [\n `## 抽出対象`,\n capture.prompt,\n \"\",\n `## 現在のURL`,\n currentUrl,\n \"\",\n `## スナップショット`,\n snapshot,\n ].join(\"\\n\");\n\n try {\n const { object } = await withAIRetry(\n () =>\n trackedGenerateObject(\"extraction\", {\n model: getModel(\"extraction\"),\n messages: [\n {\n role: \"system\",\n content: CAPTURE_SYSTEM_PROMPT,\n providerOptions: {\n anthropic: { cacheControl: { type: \"ephemeral\" } },\n },\n },\n { role: \"user\", content: userPrompt },\n ],\n schema: captureValueSchema,\n temperature: 0,\n }),\n { label: \"capture-ai\" },\n );\n\n return object.value ?? null;\n } catch (error) {\n log.warn(\n `Capture \"${capture.name}\" AI extraction failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n return null;\n }\n}\n\nasync function captureWithEvaluate(\n browser: AgentBrowser,\n capture: StepCapture,\n): Promise<string | null> {\n if (!capture.expression) {\n log.warn(`Capture \"${capture.name}\": evaluate strategy requires expression (JavaScript code)`);\n return null;\n }\n\n try {\n const result = await browser.evaluate(capture.expression);\n if (result === null || result === undefined) {\n return null;\n }\n return typeof result === \"string\" ? result : JSON.stringify(result);\n } catch (error) {\n log.warn(\n `Capture \"${capture.name}\" evaluate failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n return null;\n }\n}\n\nfunction captureFromExpression(\n capture: StepCapture,\n store: RuntimeStore,\n): string | null {\n if (!capture.expression) {\n log.warn(`Capture \"${capture.name}\": expression strategy requires expression`);\n return null;\n }\n\n const result = store.resolveTemplate(capture.expression);\n // 未解決テンプレートが残っていたら失敗とみなす\n if (/\\{\\{\\w+\\}\\}/.test(result)) {\n return null;\n }\n return result;\n}\n","/**\n * expression-evaluator -- 安全な条件式評価器\n *\n * eval() / Function() を使わず、限定的な比較式を評価する。\n *\n * サポートする構文:\n * - 比較: ===, !==, ==, !=, <, >, <=, >=\n * - 否定: !operand\n * - truthy チェック: 単一オペランド\n * - オペランド: 文字列リテラル ('...' / \"...\"), 数値, true/false, bareワード\n */\n\nexport interface EvalResult {\n value: boolean;\n error?: string;\n}\n\ntype Operand = string | number | boolean;\n\nconst COMPARISON_OPERATORS = [\"===\", \"!==\", \"==\", \"!=\", \"<=\", \">=\", \"<\", \">\"] as const;\ntype ComparisonOperator = (typeof COMPARISON_OPERATORS)[number];\n\n/**\n * 条件式を評価する。\n * テンプレート展開は呼び出し側で事前に行うこと。\n */\nexport function evaluateCondition(expression: string): EvalResult {\n const trimmed = expression.trim();\n if (!trimmed) {\n return { value: false, error: \"Empty expression\" };\n }\n\n // 否定: !operand\n if (trimmed.startsWith(\"!\") && !trimmed.startsWith(\"!=\")) {\n const inner = trimmed.slice(1).trim();\n const operand = parseOperand(inner);\n if (operand === undefined) {\n return { value: false, error: `Cannot parse operand: ${inner}` };\n }\n return { value: !isTruthy(operand) };\n }\n\n // 比較演算子を探す\n const comparison = findComparison(trimmed);\n if (comparison) {\n const { left, operator, right } = comparison;\n const leftVal = parseOperand(left);\n const rightVal = parseOperand(right);\n if (leftVal === undefined) {\n return { value: false, error: `Cannot parse left operand: ${left}` };\n }\n if (rightVal === undefined) {\n return { value: false, error: `Cannot parse right operand: ${right}` };\n }\n return { value: compare(leftVal, rightVal, operator) };\n }\n\n // truthy チェック: 単一オペランド\n const operand = parseOperand(trimmed);\n if (operand === undefined) {\n return { value: false, error: `Cannot parse expression: ${trimmed}` };\n }\n return { value: isTruthy(operand) };\n}\n\nfunction findComparison(\n expr: string,\n): { left: string; operator: ComparisonOperator; right: string } | null {\n // 長い演算子から先にマッチさせる\n for (const op of COMPARISON_OPERATORS) {\n // 文字列リテラル内の演算子を避けるため、リテラル外で探す\n const idx = findOperatorOutsideStrings(expr, op);\n if (idx !== -1) {\n return {\n left: expr.slice(0, idx).trim(),\n operator: op,\n right: expr.slice(idx + op.length).trim(),\n };\n }\n }\n return null;\n}\n\nfunction findOperatorOutsideStrings(expr: string, op: string): number {\n let inSingle = false;\n let inDouble = false;\n for (let i = 0; i < expr.length; i++) {\n const ch = expr[i];\n if (ch === \"'\" && !inDouble && (i === 0 || expr[i - 1] !== \"\\\\\")) {\n inSingle = !inSingle;\n } else if (ch === '\"' && !inSingle && (i === 0 || expr[i - 1] !== \"\\\\\")) {\n inDouble = !inDouble;\n } else if (!inSingle && !inDouble) {\n if (expr.slice(i, i + op.length) === op) {\n // ===, !== は == や != より先にマッチ済みなので OK\n // ただし < が <= の一部でないか確認\n if (op === \"<\" && expr[i + 1] === \"=\") continue;\n if (op === \">\" && expr[i + 1] === \"=\") continue;\n if (op === \"=\" && op.length === 1) continue; // 単独 = は無視\n if (op === \"==\" && expr[i + 2] === \"=\") continue;\n if (op === \"!=\" && expr[i + 2] === \"=\") continue;\n return i;\n }\n }\n }\n return -1;\n}\n\nfunction parseOperand(raw: string): Operand | undefined {\n const trimmed = raw.trim();\n if (!trimmed) return undefined;\n\n // 文字列リテラル: '...' or \"...\"\n if (\n (trimmed.startsWith(\"'\") && trimmed.endsWith(\"'\")) ||\n (trimmed.startsWith('\"') && trimmed.endsWith('\"'))\n ) {\n return trimmed.slice(1, -1).replace(/\\\\'/g, \"'\").replace(/\\\\\"/g, '\"');\n }\n\n // boolean\n if (trimmed === \"true\") return true;\n if (trimmed === \"false\") return false;\n\n // 数値\n if (/^-?\\d+(\\.\\d+)?$/.test(trimmed)) {\n return Number(trimmed);\n }\n\n // bareワード(テンプレート展開済みの値)\n return trimmed;\n}\n\nfunction isTruthy(val: Operand): boolean {\n if (typeof val === \"boolean\") return val;\n if (typeof val === \"number\") return val !== 0;\n if (typeof val === \"string\") return val !== \"\" && val !== \"false\" && val !== \"0\";\n return false;\n}\n\nfunction compare(left: Operand, right: Operand, op: ComparisonOperator): boolean {\n switch (op) {\n case \"===\":\n return left === right;\n case \"!==\":\n return left !== right;\n case \"==\":\n // eslint-disable-next-line eqeqeq\n return String(left) === String(right);\n case \"!=\":\n return String(left) !== String(right);\n case \"<\":\n return toNumber(left) < toNumber(right);\n case \">\":\n return toNumber(left) > toNumber(right);\n case \"<=\":\n return toNumber(left) <= toNumber(right);\n case \">=\":\n return toNumber(left) >= toNumber(right);\n default:\n return false;\n }\n}\n\nfunction toNumber(val: Operand): number {\n if (typeof val === \"number\") return val;\n if (typeof val === \"boolean\") return val ? 1 : 0;\n const n = Number(val);\n return Number.isNaN(n) ? 0 : n;\n}\n","/**\n * snapshot-cache — フィルタ済みスナップショットのキャッシュ\n *\n * 同一スナップショットの再フィルタリングを回避してCPU負荷を低減する。\n * リトライ時にスナップショットが変化していない場合、キャッシュからフィルタ済み結果を返す。\n */\n\nimport { createHash } from \"node:crypto\";\nimport {\n filterSnapshot,\n type SnapshotFilterOptions,\n} from \"../browser/snapshot-filter\";\n\ninterface SnapshotCacheEntry {\n rawHash: string;\n filtered: string;\n tokenEstimate: number;\n createdAt: number;\n}\n\n/**\n * スナップショットのフィルタリング結果をハッシュベースでキャッシュする。\n * LRU方式で最大 maxEntries 件を保持。\n */\nexport class SnapshotCache {\n private cache = new Map<string, SnapshotCacheEntry>();\n private readonly maxEntries: number;\n\n constructor(maxEntries = 5) {\n this.maxEntries = maxEntries;\n }\n\n /**\n * フィルタ済みスナップショットを返す(キャッシュがあればそれを利用)。\n *\n * opts が異なる場合は別キーとして扱う(filledSelectors のサイズをキーに含める)。\n */\n getFiltered(raw: string, opts?: SnapshotFilterOptions): string {\n const key = this.buildKey(raw, opts);\n const existing = this.cache.get(key);\n if (existing) {\n // LRU: アクセスされたエントリを末尾に移動\n this.cache.delete(key);\n this.cache.set(key, existing);\n return existing.filtered;\n }\n\n const filtered = filterSnapshot(raw, opts);\n const tokenEstimate = Math.ceil(filtered.length / 4);\n\n this.evictIfNeeded();\n this.cache.set(key, {\n rawHash: this.hashSnapshot(raw),\n filtered,\n tokenEstimate,\n createdAt: Date.now(),\n });\n\n return filtered;\n }\n\n /**\n * 2つのスナップショットが同一内容かどうかをハッシュで高速判定する。\n */\n hasChanged(rawA: string, rawB: string): boolean {\n return this.hashSnapshot(rawA) !== this.hashSnapshot(rawB);\n }\n\n /** キャッシュをクリアする */\n clear(): void {\n this.cache.clear();\n }\n\n /** 現在のキャッシュエントリ数 */\n get size(): number {\n return this.cache.size;\n }\n\n private buildKey(raw: string, opts?: SnapshotFilterOptions): string {\n const rawHash = this.hashSnapshot(raw);\n const filledCount = opts?.filledSelectors?.size ?? 0;\n return `${rawHash}:${filledCount}`;\n }\n\n private hashSnapshot(raw: string): string {\n return createHash(\"sha256\").update(raw).digest(\"hex\").slice(0, 16);\n }\n\n private evictIfNeeded(): void {\n while (this.cache.size >= this.maxEntries) {\n // Map は挿入順を保持するため、最初のキーが最古(LRU)\n const oldestKey = this.cache.keys().next().value;\n if (oldestKey !== undefined) {\n this.cache.delete(oldestKey);\n }\n }\n }\n}\n","/**\n * context-chunker — コンテキスト Markdown の関連チャンク選択\n *\n * 大きなコンテキスト Markdown をヘディング単位で分割し、\n * ステップ説明 + URL に関連するチャンクだけをキーワードスコアリングで選択する。\n * AI 呼び出し不要のローカル処理。\n */\n\ninterface ContextChunk {\n heading: string;\n content: string;\n tokenEstimate: number;\n keywords: string[];\n}\n\n/**\n * Markdown をヘディング単位で分割し、ステップごとに関連チャンクを選択する。\n */\nexport class ContextChunker {\n private chunks: ContextChunk[];\n private fullText: string;\n /** 直近の selectRelevant() で選択されたチャンク数 */\n private _lastSelectedCount = 0;\n\n constructor(markdown: string) {\n this.fullText = markdown;\n this.chunks = parseMarkdownIntoChunks(markdown);\n }\n\n /**\n * ステップ説明 + URL に関連するチャンクを選択して返す。\n * キーワードオーバーラップスコアリングによる選択(AI 不要)。\n *\n * @param stepDescription ステップの説明テキスト\n * @param url 現在のページURL\n * @param maxTokens 最大トークン数(デフォルト: 2000)\n * @returns 関連チャンクを結合したテキスト。関連チャンクがなければ空文字。\n */\n selectRelevant(\n stepDescription: string,\n url: string,\n maxTokens = 2000,\n ): string {\n if (this.chunks.length === 0) {\n this._lastSelectedCount = 0;\n return this.fullText;\n }\n\n const queryTerms = extractKeywords(`${stepDescription} ${url}`);\n if (queryTerms.length === 0) {\n this._lastSelectedCount = 0;\n return this.fullText;\n }\n\n const scored = this.chunks\n .map((chunk) => ({\n chunk,\n score: keywordOverlapScore(queryTerms, chunk.keywords),\n }))\n .filter((s) => s.score > 0)\n .sort((a, b) => b.score - a.score);\n\n if (scored.length === 0) {\n this._lastSelectedCount = 0;\n // 関連チャンクが見つからない場合: 全文が短ければそのまま返す\n const fullTokens = Math.ceil(this.fullText.length / 4);\n if (fullTokens <= maxTokens) return this.fullText;\n // 長い場合は先頭を切り詰め\n return this.fullText.slice(0, maxTokens * 4) + \"\\n[... truncated]\";\n }\n\n // トークン予算内で貪欲にチャンクを選択\n let tokens = 0;\n const selected: ContextChunk[] = [];\n for (const { chunk } of scored) {\n if (tokens + chunk.tokenEstimate > maxTokens) {\n // 残り予算に収まる小さいチャンクがあれば追加\n continue;\n }\n selected.push(chunk);\n tokens += chunk.tokenEstimate;\n }\n\n if (selected.length === 0 && scored.length > 0) {\n this._lastSelectedCount = 1;\n // 全チャンクが maxTokens を超える場合、最もスコアの高いチャンクを切り詰めて返す\n const best = scored[0].chunk;\n const maxChars = maxTokens * 4;\n return `### ${best.heading}\\n${best.content.slice(0, maxChars)}\\n[... truncated]`;\n }\n\n this._lastSelectedCount = selected.length;\n return selected.map((c) => `### ${c.heading}\\n${c.content}`).join(\"\\n\\n\");\n }\n\n /** 全文を返す(フォールバック用) */\n getFull(): string {\n return this.fullText;\n }\n\n /** チャンク数を返す(テスト・デバッグ用) */\n get chunkCount(): number {\n return this.chunks.length;\n }\n\n /** 直近の selectRelevant() で選択されたチャンク数 */\n get lastSelectedCount(): number {\n return this._lastSelectedCount;\n }\n}\n\n/**\n * Markdown をヘディング(#, ##, ###)単位で分割する。\n * ヘディングがない場合はドキュメント全体を1チャンクとして扱う。\n */\nfunction parseMarkdownIntoChunks(markdown: string): ContextChunk[] {\n const lines = markdown.split(\"\\n\");\n const chunks: ContextChunk[] = [];\n let currentHeading = \"\";\n let currentContent: string[] = [];\n\n for (const line of lines) {\n const headingMatch = line.match(/^#{1,3}\\s+(.+)/);\n if (headingMatch) {\n // 前のチャンクを確定\n if (currentContent.length > 0 || currentHeading) {\n const content = currentContent.join(\"\\n\").trim();\n if (content) {\n chunks.push(buildChunk(currentHeading || \"untitled\", content));\n }\n }\n currentHeading = headingMatch[1].trim();\n currentContent = [];\n } else {\n currentContent.push(line);\n }\n }\n\n // 最後のチャンクを確定\n const content = currentContent.join(\"\\n\").trim();\n if (content) {\n chunks.push(buildChunk(currentHeading || \"untitled\", content));\n }\n\n return chunks;\n}\n\nfunction buildChunk(heading: string, content: string): ContextChunk {\n const fullText = `${heading} ${content}`;\n return {\n heading,\n content,\n tokenEstimate: Math.ceil(fullText.length / 4),\n keywords: extractKeywords(fullText),\n };\n}\n\n/**\n * テキストからキーワードを抽出する。\n * URL パス、英単語、日本語の名詞的文字列を抽出。\n * ストップワードと短すぎる単語を除外。\n */\nexport function extractKeywords(text: string): string[] {\n const normalized = text.toLowerCase();\n const words = new Set<string>();\n\n // URL パス部分を抽出(/login, /dashboard, /users など)\n const urlPaths = normalized.match(/\\/[a-z0-9_-]+/g);\n if (urlPaths) {\n for (const path of urlPaths) {\n words.add(path.replace(\"/\", \"\"));\n }\n }\n\n // 英単語を抽出\n const englishWords = normalized.match(/[a-z][a-z0-9_-]{2,}/g);\n if (englishWords) {\n for (const w of englishWords) {\n if (!STOP_WORDS.has(w)) {\n words.add(w);\n }\n }\n }\n\n // 日本語キーワード抽出(カタカナ語、漢字列)\n const japaneseWords = text.match(/[\\u30A0-\\u30FF]{2,}|[\\u4E00-\\u9FFF]{2,}/g);\n if (japaneseWords) {\n for (const w of japaneseWords) {\n words.add(w);\n }\n }\n\n return [...words];\n}\n\n/**\n * クエリキーワードとチャンクキーワードのオーバーラップスコアを計算する。\n * 部分一致も考慮(\"login\" は \"login-form\" にマッチ)。\n */\nexport function keywordOverlapScore(\n queryTerms: string[],\n chunkKeywords: string[],\n): number {\n if (queryTerms.length === 0 || chunkKeywords.length === 0) return 0;\n\n let matchCount = 0;\n for (const qt of queryTerms) {\n for (const ck of chunkKeywords) {\n if (ck.includes(qt) || qt.includes(ck)) {\n matchCount++;\n break; // 1つのクエリタームにつき最大1マッチ\n }\n }\n }\n\n // Jaccard 的なスコアリング: マッチ数 / クエリターム数\n return matchCount / queryTerms.length;\n}\n\nconst STOP_WORDS = new Set([\n \"the\", \"and\", \"for\", \"are\", \"but\", \"not\", \"you\", \"all\", \"can\",\n \"has\", \"her\", \"was\", \"one\", \"our\", \"out\", \"day\", \"had\", \"hot\",\n \"may\", \"who\", \"did\", \"get\", \"let\", \"say\", \"she\", \"too\", \"use\",\n \"that\", \"this\", \"with\", \"have\", \"from\", \"they\", \"been\", \"will\",\n \"each\", \"make\", \"like\", \"when\", \"than\", \"them\", \"into\", \"some\",\n \"could\", \"other\", \"about\", \"which\", \"their\", \"there\", \"would\",\n \"click\", \"input\", \"select\", \"button\", \"page\", \"form\", \"step\",\n]);\n","/**\n * input-collector — context markdown からの変数値抽出\n */\n\nimport { z } from \"zod\";\nimport { getModel, trackedGenerateObject, withAIRetry } from \"../harness/ai-model\";\nimport type { AIModelProvider } from \"../harness/ai-service\";\n\nconst contextValuesSchema = z.object({\n values: z.record(z.string(), z.string()).describe(\"変数名→抽出値のマップ\"),\n});\n\ninterface InputDescriptor {\n name: string;\n description: string;\n required: boolean;\n}\n\n/** 静的な変数抽出用システムプロンプト(キャッシュ対象) */\nconst CONTEXT_EXTRACTION_SYSTEM_PROMPT = [\n \"以下の変数リストと context markdown が与えられます。\",\n \"context から各変数に対応する値を抽出してください。\",\n \"値が見つからない場合はそのキーを含めないでください。\",\n].join(\"\\n\");\n\n/**\n * context markdown から変数の値を AI で抽出する\n * execution-planner.ts から使用される\n */\nexport async function extractValuesFromContext(\n inputs: InputDescriptor[],\n contextMarkdown: string,\n aiProvider?: AIModelProvider,\n): Promise<Record<string, string>> {\n const inputDescriptions = inputs\n .map((i) => `- name: \"${i.name}\", description: \"${i.description}\"`)\n .join(\"\\n\");\n\n const userPrompt = [\n \"## 変数\",\n inputDescriptions,\n \"\",\n \"## Context\",\n contextMarkdown,\n ].join(\"\\n\");\n\n try {\n const model = aiProvider ? aiProvider.getModel(\"extraction\") : getModel(\"extraction\");\n const { object } = await withAIRetry(\n () =>\n trackedGenerateObject(\"extraction\", {\n model,\n messages: [\n {\n role: \"system\",\n content: CONTEXT_EXTRACTION_SYSTEM_PROMPT,\n providerOptions: {\n anthropic: { cacheControl: { type: \"ephemeral\" } },\n },\n },\n { role: \"user\", content: userPrompt },\n ],\n schema: contextValuesSchema,\n temperature: 0,\n }),\n { label: \"input-collect\" },\n );\n\n return object.values;\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n console.warn(`[input-collector] Context extraction failed: ${msg}`);\n return {};\n }\n}\n","/**\n * execution-planner --- 事前変数の解決 + 実行プラン表示\n *\n * 実行前に全変数を解決し、ユーザーに確認を求める。\n * 優先順位: secrets → data行値 → context抽出(全未解決変数) → env → expression → stored value → prompt(未解決必須変数)\n *\n * resolveVariablesCore() は SDK からも利用される非対話的コア関数。\n * planExecution() は CLI 用で、prompt (ステップ 7) を含む完全版。\n */\n\nimport { extractValuesFromContext } from \"./input-collector\";\nimport type { AIModelProvider } from \"../harness/ai-service\";\nimport { scanStepsForTemplates } from \"../context/template-resolver\";\nimport { resolveTemplate } from \"../context/template-resolver\";\nimport { promptText, promptConfirm, note, log } from \"../cli/prompts\";\nimport { t, tf } from \"../i18n\";\nimport type {\n ParsedRunbook,\n ExecutorConfig,\n ResolvedVariables,\n VariableDefinition,\n} from \"./types\";\nimport type { SecretsData } from \"../cli/secrets-loader\";\n\n/**\n * variables と secrets をマージし、sensitive キーを追跡する。\n * SDK / Server で共通利用する。\n */\nexport function mergeVariablesAndSecrets(\n variables?: Record<string, string>,\n secrets?: SecretsData,\n): { mergedValues: Record<string, string>; sensitiveKeys: Set<string> } {\n const mergedValues = { ...variables };\n const sensitiveKeys = new Set<string>();\n if (secrets) {\n for (const [k, v] of Object.entries(secrets.values)) {\n mergedValues[k] = v;\n sensitiveKeys.add(k);\n }\n for (const k of secrets.keys) sensitiveKeys.add(k);\n }\n return { mergedValues, sensitiveKeys };\n}\n\nexport interface ExecutionPlan {\n resolvedVariables: ResolvedVariables;\n unresolvedDataVars: string[]; // data ソース(行ごとに提供)\n captureVars: string[]; // ランタイムキャプチャ変数名\n dataFilePath?: string;\n contextExtractedKeys: Set<string>; // contextから抽出された変数名\n secretsKeys: Set<string>; // secretsから読み込まれた変数名\n}\n\n// ── resolveVariablesCore: 非対話的変数解決(SDK 共有) ──\n\n/** resolveVariablesCore に渡す入力 */\nexport interface CoreResolveInput {\n /** secrets データ */\n secrets?: SecretsData;\n /** 補足情報の markdown テキスト */\n contextMarkdown: string;\n /** env ソースをスキップするか (SDK: true, CLI: false) */\n skipEnv?: boolean;\n /** AI モデル提供(DI) */\n aiProvider?: AIModelProvider;\n}\n\n/** resolveVariablesCore の戻り値 */\nexport interface CoreResolveResult {\n values: Map<string, string>;\n sensitiveKeys: Set<string>;\n unresolvedDataVars: string[];\n captureVars: string[];\n contextExtractedKeys: Set<string>;\n secretsKeys: Set<string>;\n}\n\n/**\n * 手順書の変数をステップ 1-6 で非対話的に解決する。\n * ステップ 7 (prompt) は含まない。\n *\n * SDK と CLI の両方から利用される共通コア関数。\n */\nexport async function resolveVariablesCore(\n runbook: ParsedRunbook,\n input: CoreResolveInput,\n): Promise<CoreResolveResult> {\n const variables = runbook.variables ?? {};\n const values = new Map<string, string>();\n const sensitiveKeys = new Set<string>();\n const unresolvedDataVars: string[] = [];\n\n // キャプチャ変数名(サブステップ・ブランチも再帰スキャン)\n const captureVars: string[] = [];\n function collectCaptureVars(steps: typeof runbook.steps): void {\n for (const step of steps) {\n if (step.captures) {\n for (const c of step.captures) {\n captureVars.push(c.name);\n }\n }\n if (step.steps) {\n collectCaptureVars(step.steps);\n }\n if (step.branches) {\n for (const branchCase of step.branches.cases) {\n collectCaptureVars(branchCase.steps);\n }\n if (step.branches.default) {\n collectCaptureVars(step.branches.default.steps);\n }\n }\n }\n }\n collectCaptureVars(runbook.steps);\n\n // sensitive キーを収集\n for (const [name, def] of Object.entries(variables)) {\n if (def.sensitive) {\n sensitiveKeys.add(name);\n }\n }\n\n // 1. secrets(最高優先: secrets JSON から読み込んだ値、全て sensitive)\n const secretsKeys = new Set<string>();\n if (input.secrets) {\n for (const [key, val] of Object.entries(input.secrets.values)) {\n values.set(key, val);\n sensitiveKeys.add(key);\n secretsKeys.add(key);\n }\n }\n\n // 2. data ソースの変数は行ごとに提供されるためマーク\n for (const [name, def] of Object.entries(variables)) {\n if (def.source === \"data\" && !values.has(name)) {\n unresolvedDataVars.push(name);\n }\n }\n\n // 3. context 抽出: 全未解決変数を対象(data ソース除く)\n const unresolvedVars = Object.entries(variables).filter(\n ([name]) => !values.has(name) && !unresolvedDataVars.includes(name),\n );\n const contextExtractedKeys = new Set<string>();\n if (unresolvedVars.length > 0) {\n const extracted = await extractValuesFromContext(\n unresolvedVars.map(([name, def]) => ({\n name,\n description: def.description ?? name,\n required: def.required !== false,\n })),\n input.contextMarkdown,\n input.aiProvider,\n );\n for (const [name, val] of Object.entries(extracted)) {\n if (!values.has(name) && val) {\n values.set(name, val);\n contextExtractedKeys.add(name);\n }\n }\n }\n\n // 4. env(SDK ではスキップ)\n if (!input.skipEnv) {\n for (const [name, def] of Object.entries(variables)) {\n if (def.source === \"env\" && !values.has(name) && def.envKey) {\n const envVal = process.env[def.envKey];\n if (envVal !== undefined) {\n values.set(name, envVal);\n }\n }\n }\n }\n\n // 5. expression(他の事前変数を展開)\n for (const [name, def] of Object.entries(variables)) {\n if (def.source === \"expression\" && !values.has(name) && def.expression) {\n const resolved = resolveTemplate(def.expression, values);\n // 未解決テンプレートが残っていなければセット\n if (!/\\{\\{[\\w.]+\\}\\}/.test(resolved)) {\n values.set(name, resolved);\n }\n }\n }\n\n // 6. stored value fallback(ソースを問わず、事前定義値をフォールバック)\n for (const [name, def] of Object.entries(variables)) {\n if (!values.has(name) && !unresolvedDataVars.includes(name) && def.value !== undefined) {\n values.set(name, def.value);\n }\n }\n\n return {\n values,\n sensitiveKeys,\n unresolvedDataVars,\n captureVars,\n contextExtractedKeys,\n secretsKeys,\n };\n}\n\n/**\n * runbook の事前変数を解決する(CLI 用: prompt ステップ含む)\n */\nexport async function planExecution(\n runbook: ParsedRunbook,\n config: ExecutorConfig,\n): Promise<ExecutionPlan> {\n // ステップ 1-6 はコア関数で実行\n const variables = runbook.variables ?? {};\n\n const hasContextVars =\n Object.entries(variables).some(\n ([name]) =>\n !config.secrets?.keys.has(name) &&\n variables[name]?.source !== \"data\",\n );\n\n if (hasContextVars) {\n log.step(t(\"planner.extractingFromContext\"));\n }\n\n const coreResult = await resolveVariablesCore(runbook, {\n secrets: config.secrets,\n contextMarkdown: config.contextMarkdown,\n skipEnv: false,\n });\n\n if (hasContextVars) {\n log.info(tf(\"planner.extractedFromContext\", { count: coreResult.contextExtractedKeys.size }));\n }\n\n // 7. prompt: source に関係なく、まだ未解決の必須変数をユーザーに問い合わせ\n const captureVarNames = new Set(coreResult.captureVars);\n const stillUnresolved = Object.entries(variables).filter(\n ([name, def]) =>\n !coreResult.values.has(name) &&\n !coreResult.unresolvedDataVars.includes(name) &&\n !captureVarNames.has(name) &&\n def.required !== false,\n );\n if (stillUnresolved.length > 0) {\n log.warn(tf(\"planner.unresolvedRequired\", { count: stillUnresolved.length }));\n for (const [name, def] of stillUnresolved) {\n const answer = await promptText(def.description ?? name, {\n placeholder: t(\"planner.placeholder\"),\n validate: (v) => (!v?.trim() ? tf(\"planner.variableRequired\", { name }) : undefined),\n });\n coreResult.values.set(name, answer.trim());\n }\n }\n\n return {\n resolvedVariables: {\n values: coreResult.values,\n sensitiveKeys: coreResult.sensitiveKeys,\n },\n unresolvedDataVars: coreResult.unresolvedDataVars,\n captureVars: coreResult.captureVars,\n dataFilePath: config.dataFilePath,\n contextExtractedKeys: coreResult.contextExtractedKeys,\n secretsKeys: coreResult.secretsKeys,\n };\n}\n\n/**\n * 実行プランを表示する\n */\nexport function displayPlan(\n plan: ExecutionPlan,\n runbook: ParsedRunbook,\n dataRowCount?: number,\n): void {\n const lines: string[] = [];\n\n // 事前変数\n lines.push(t(\"planner.preVariables\"));\n if (plan.resolvedVariables.values.size === 0 && plan.unresolvedDataVars.length === 0) {\n lines.push(\" \" + t(\"common.none\"));\n } else {\n for (const [name, value] of plan.resolvedVariables.values) {\n const display = plan.resolvedVariables.sensitiveKeys.has(name)\n ? `\"${value.slice(0, 3)}****\"`\n : `\"${value}\"`;\n let source = \"\";\n if (plan.secretsKeys.has(name)) {\n source = t(\"planner.fromSecrets\");\n } else if (plan.contextExtractedKeys.has(name)) {\n source = t(\"planner.fromContext\");\n }\n lines.push(` ${name} → ${display}${source}`);\n }\n for (const name of plan.unresolvedDataVars) {\n lines.push(` ${name} → ${t(\"planner.fromDataSource\")}`);\n }\n }\n\n // ランタイムキャプチャ(サブステップ含む)\n if (plan.captureVars.length > 0) {\n lines.push(\"\");\n lines.push(t(\"planner.runtimeCaptures\"));\n function displayCaptures(\n steps: typeof runbook.steps,\n prefix: string,\n ): void {\n for (const step of steps) {\n if (step.captures) {\n for (const c of step.captures) {\n lines.push(` ${c.name} ← ${prefix}Step ${step.ordinal} (${c.strategy})`);\n }\n }\n if (step.steps) {\n displayCaptures(step.steps, `${prefix}Loop ${step.ordinal} > `);\n }\n if (step.branches) {\n for (const branchCase of step.branches.cases) {\n displayCaptures(branchCase.steps, `${prefix}Branch ${step.ordinal}/${branchCase.match} > `);\n }\n if (step.branches.default) {\n displayCaptures(step.branches.default.steps, `${prefix}Branch ${step.ordinal}/default > `);\n }\n }\n }\n }\n displayCaptures(runbook.steps, \"\");\n }\n\n // 条件付き・ループ・ブランチステップ\n const conditionSteps = runbook.steps.filter((s) => s.condition);\n const loopSteps = runbook.steps.filter((s) => s.loop && s.steps);\n const branchSteps = runbook.steps.filter((s) => s.branches);\n if (conditionSteps.length > 0 || loopSteps.length > 0 || branchSteps.length > 0) {\n lines.push(\"\");\n lines.push(t(\"planner.controlFlow\"));\n for (const step of conditionSteps) {\n lines.push(tf(\"planner.conditionLabel\", { ordinal: step.ordinal, condition: step.condition ?? \"\" }));\n }\n for (const step of loopSteps) {\n if (step.loop!.forEach) {\n const maxIter = step.loop!.maxIterations ?? 100;\n lines.push(\n tf(\"planner.forEachLabel\", { ordinal: step.ordinal, max: maxIter, subSteps: step.steps!.length, forEach: step.loop!.forEach }),\n );\n } else {\n const maxIter = step.loop!.maxIterations ?? 10;\n lines.push(\n tf(\"planner.loopLabel\", { ordinal: step.ordinal, max: maxIter, subSteps: step.steps!.length, condition: step.loop!.condition ?? \"\" }),\n );\n }\n }\n for (const step of branchSteps) {\n const caseLabels = step.branches!.cases.map((c) => c.match).join(\", \");\n lines.push(\n tf(\"planner.branchLabel\", { ordinal: step.ordinal, value: step.branches!.value, cases: caseLabels }),\n );\n }\n }\n\n // バッチ情報\n if (plan.dataFilePath && dataRowCount !== undefined) {\n lines.push(\"\");\n lines.push(tf(\"planner.batchMode\", { count: dataRowCount, path: plan.dataFilePath }));\n }\n\n lines.push(tf(\"planner.stepCount\", { count: runbook.steps.length }));\n\n note(lines.join(\"\\n\"), t(\"planner.executionPlan\"));\n}\n\n/**\n * 実行確認プロンプト\n */\nexport async function confirmPlan(): Promise<boolean> {\n return promptConfirm(t(\"planner.confirmStart\"), true);\n}\n","/**\n * runtime-store — 変数の統合管理ストア\n *\n * 事前解決値 + ランタイムキャプチャ値を一元管理。\n * テンプレート展開もストア経由で行う。\n * Working Memory: 実行フェーズ追跡・ステップ履歴・AI プロンプト注入用サマリー。\n */\n\nimport { resolveTemplate } from \"./template-resolver\";\n\n/** 実行フェーズ(自動検出) */\nexport interface ExecutionPhase {\n name: string;\n startStep: number;\n endStep?: number;\n summary: string;\n}\n\n/** Working Memory の内部状態 */\ninterface WorkingMemoryState {\n currentPhase: string;\n completedPhases: ExecutionPhase[];\n recentStepSummaries: string[];\n currentPageContext: string;\n successStreak: number;\n failureCount: number;\n totalSteps: number;\n lastUrl: string;\n lastActionType: string;\n /** 直近アクションタイプの連続カウント(フェーズ検出用) */\n actionTypeRun: number;\n}\n\nconst MAX_RECENT_SUMMARIES = 5;\n\nexport class RuntimeStore {\n private store = new Map<string, string>();\n private sensitiveKeys = new Set<string>();\n private wm: WorkingMemoryState = {\n currentPhase: \"initial\",\n completedPhases: [],\n recentStepSummaries: [],\n currentPageContext: \"\",\n successStreak: 0,\n failureCount: 0,\n totalSteps: 0,\n lastUrl: \"\",\n lastActionType: \"\",\n actionTypeRun: 0,\n };\n\n /** 事前解決済み変数をシードする */\n seed(values: Map<string, string>, sensitive: Set<string>): void {\n for (const [k, v] of values) {\n this.store.set(k, v);\n }\n for (const k of sensitive) {\n this.sensitiveKeys.add(k);\n }\n }\n\n get(name: string): string | undefined {\n return this.store.get(name);\n }\n\n set(name: string, value: string): void {\n this.store.set(name, value);\n }\n\n has(name: string): boolean {\n return this.store.has(name);\n }\n\n isSensitive(name: string): boolean {\n return this.sensitiveKeys.has(name);\n }\n\n /** sensitive として登録されたキー名一覧を返す */\n getSensitiveKeys(): string[] {\n return Array.from(this.sensitiveKeys);\n }\n\n /** store の値で {{varName}} を展開する */\n resolveTemplate(template: string): string {\n return resolveTemplate(template, this.store);\n }\n\n /** ログ出力用: sensitive な値をマスクした文字列を返す */\n maskSensitive(value: string): string {\n let masked = value;\n for (const key of this.sensitiveKeys) {\n const val = this.store.get(key);\n if (val && masked.includes(val)) {\n masked = masked.replaceAll(val, \"****\");\n }\n }\n return masked;\n }\n\n /** 全変数のスナップショット(デバッグ用) */\n entries(): [string, string][] {\n return Array.from(this.store.entries());\n }\n\n // ─────────────── forEach ヘルパー ───────────────\n\n /**\n * forEach ループの各アイテムを変数としてセットする。\n * オブジェクト → varName = JSON文字列, varName.key = value にフラット化(1階層のみ)\n * プリミティブ → varName = String(item)\n */\n setForEachItem(varName: string, item: unknown, indexVar?: string, index?: number): void {\n if (indexVar !== undefined && index !== undefined) {\n this.store.set(indexVar, String(index));\n }\n if (item !== null && typeof item === \"object\" && !Array.isArray(item)) {\n this.store.set(varName, JSON.stringify(item));\n for (const [key, value] of Object.entries(item as Record<string, unknown>)) {\n this.store.set(`${varName}.${key}`, String(value ?? \"\"));\n }\n } else {\n this.store.set(varName, String(item ?? \"\"));\n }\n }\n\n /**\n * forEach ループのアイテム変数をクリーンアップする。\n * varName と全 varName.* キーを削除。\n */\n clearForEachItem(varName: string, indexVar?: string): void {\n this.store.delete(varName);\n if (indexVar) {\n this.store.delete(indexVar);\n }\n // varName.* キーをすべて削除\n const prefix = `${varName}.`;\n for (const key of Array.from(this.store.keys())) {\n if (key.startsWith(prefix)) {\n this.store.delete(key);\n }\n }\n }\n\n // ─────────────── Working Memory ───────────────\n\n /**\n * ステップ完了後に Working Memory を更新する。\n * フェーズ自動検出 + ステップ履歴の記録。\n */\n updateWorkingMemory(\n stepOrdinal: number,\n totalStepCount: number,\n success: boolean,\n url: string,\n actionType: string,\n stepDescription: string,\n ): void {\n this.wm.totalSteps = totalStepCount;\n\n // 成功/失敗カウント\n if (success) {\n this.wm.successStreak++;\n this.wm.failureCount = 0;\n } else {\n this.wm.successStreak = 0;\n this.wm.failureCount++;\n }\n\n // ステップサマリー(ring buffer)\n const summary = `Step ${stepOrdinal}: ${stepDescription} → ${success ? \"OK\" : \"FAIL\"}`;\n this.wm.recentStepSummaries.push(summary);\n if (this.wm.recentStepSummaries.length > MAX_RECENT_SUMMARIES) {\n this.wm.recentStepSummaries.shift();\n }\n\n // ページコンテキスト更新\n this.wm.currentPageContext = url;\n\n // フェーズ遷移検出\n this.detectPhaseTransition(stepOrdinal, url, actionType);\n\n this.wm.lastUrl = url;\n this.wm.lastActionType = actionType;\n }\n\n /**\n * AI プロンプト注入用の Working Memory サマリーを返す。\n * 100〜200 トークンの簡潔な構造化テキスト。\n * Working Memory がまだ蓄積されていない場合は undefined を返す。\n */\n getWorkingMemorySummary(): string | undefined {\n if (this.wm.recentStepSummaries.length === 0) return undefined;\n\n const parts: string[] = [];\n\n // フェーズ情報\n if (this.wm.completedPhases.length > 0) {\n const phaseHistory = this.wm.completedPhases\n .map((p) => `${p.name}(steps ${p.startStep}-${p.endStep ?? \"?\"})`)\n .join(\" → \");\n parts.push(`Phases: ${phaseHistory} → ${this.wm.currentPhase}(current)`);\n } else {\n parts.push(`Phase: ${this.wm.currentPhase}`);\n }\n\n // 直近ステップ\n const recent = this.wm.recentStepSummaries.slice(-3).join(\"; \");\n parts.push(`Recent: ${recent}`);\n\n // ステータス\n const statusParts: string[] = [];\n if (this.wm.successStreak > 0) {\n statusParts.push(`${this.wm.successStreak} consecutive successes`);\n }\n if (this.wm.failureCount > 0) {\n statusParts.push(`${this.wm.failureCount} consecutive failures`);\n }\n if (statusParts.length > 0) {\n parts.push(`Status: ${statusParts.join(\", \")}`);\n }\n\n // 現在の URL\n parts.push(`URL: ${this.wm.currentPageContext}`);\n\n return parts.join(\"\\n\");\n }\n\n /**\n * URL パターン変化 + アクションタイプのクラスタリングでフェーズ遷移を検出。\n * AI 呼び出し不要のヒューリスティック。\n */\n private detectPhaseTransition(\n stepOrdinal: number,\n url: string,\n actionType: string,\n ): void {\n const urlPath = extractUrlPath(url);\n const lastUrlPath = extractUrlPath(this.wm.lastUrl);\n\n // URL パスの大幅変更を検出\n const pathChanged = urlPath !== lastUrlPath && this.wm.lastUrl !== \"\";\n\n // アクションタイプの連続を追跡\n if (actionType === this.wm.lastActionType) {\n this.wm.actionTypeRun++;\n } else {\n this.wm.actionTypeRun = 1;\n }\n\n // フェーズ遷移判定\n const newPhase = detectPhaseFromContext(urlPath, actionType, this.wm.actionTypeRun);\n\n if (newPhase !== this.wm.currentPhase && (pathChanged || this.wm.actionTypeRun >= 3)) {\n // 前のフェーズを完了として記録\n if (this.wm.currentPhase !== \"initial\") {\n const lastPhase = this.wm.completedPhases[this.wm.completedPhases.length - 1];\n const startStep = lastPhase ? (lastPhase.endStep ?? 0) + 1 : 1;\n this.wm.completedPhases.push({\n name: this.wm.currentPhase,\n startStep,\n endStep: stepOrdinal - 1,\n summary: `${this.wm.currentPhase} completed`,\n });\n }\n this.wm.currentPhase = newPhase;\n }\n }\n}\n\n/** URL からパス部分を抽出(クエリ・フラグメント除去) */\nfunction extractUrlPath(url: string): string {\n try {\n const parsed = new URL(url);\n return parsed.pathname;\n } catch {\n return url;\n }\n}\n\n/**\n * URL パス + アクションタイプからフェーズ名を推定するヒューリスティック。\n */\nfunction detectPhaseFromContext(\n urlPath: string,\n actionType: string,\n actionTypeRun: number,\n): string {\n // URL ベースの判定\n if (/\\/(login|signin|auth)/i.test(urlPath)) return \"authentication\";\n if (/\\/(dashboard|home|overview)/i.test(urlPath)) return \"navigation\";\n if (/\\/(settings|config|preferences)/i.test(urlPath)) return \"configuration\";\n\n // アクションタイプベースの判定\n if (actionType === \"input\" && actionTypeRun >= 2) return \"form_filling\";\n if (actionType === \"extract\" && actionTypeRun >= 2) return \"data_extraction\";\n if (actionType === \"click\" && actionTypeRun >= 3) return \"navigation\";\n if (actionType === \"download\") return \"data_export\";\n\n return \"general\";\n}\n","/**\n * messaging/chat-bot --- SharedChatBot(Chat SDK 共有インスタンス + Hono webhook サーバー)\n *\n * 承認プロバイダーと通知プロバイダーで同一 Chat SDK インスタンスを共有する。\n * 遅延初期化: 最初のメッセージ送信 or webhook 受信時に初期化。\n */\n\nimport { Chat, type Channel } from \"chat\";\nimport { createSlackAdapter } from \"@chat-adapter/slack\";\nimport { createTeamsAdapter } from \"@chat-adapter/teams\";\nimport { createDiscordAdapter } from \"@chat-adapter/discord\";\nimport { createMemoryState } from \"@chat-adapter/state-memory\";\nimport { Hono } from \"hono\";\nimport { serve, type ServerType } from \"@hono/node-server\";\nimport type { ChatMessagingConfig, ChatPlatform } from \"./config\";\n\n/**\n * Chat SDK のアダプター名(channel ID のプレフィックスに使用)\n */\nconst ADAPTER_NAME: Record<ChatPlatform, string> = {\n slack: \"slack\",\n teams: \"teams\",\n discord: \"discord\",\n};\n\nexport class SharedChatBot {\n private readonly config: ChatMessagingConfig;\n private bot: Chat | null = null;\n private server: ServerType | null = null;\n private channel: Channel | null = null;\n private initialized = false;\n\n constructor(config: ChatMessagingConfig) {\n this.config = config;\n }\n\n /**\n * 遅延初期化: Chat SDK インスタンスと Hono webhook サーバーを起動。\n * 複数回呼ばれても冪等。\n */\n async ensureInitialized(): Promise<void> {\n if (this.initialized) return;\n this.initialized = true;\n\n const adapter = this.createAdapter();\n this.bot = new Chat({\n userName: \"refrain\",\n adapters: { [ADAPTER_NAME[this.config.platform]]: adapter },\n state: createMemoryState(),\n logger: \"silent\",\n });\n\n // webhook サーバー起動(承認ボタンコールバック受信用)\n if (!this.config.skipWebhookServer) {\n this.startWebhookServer();\n }\n\n // Chat SDK 初期化(アダプター接続)\n await this.bot.initialize();\n }\n\n /**\n * プロアクティブメッセージ用チャンネルを取得。\n * chat.channel(\"slack:C12345\") 形式で指定。\n */\n getChannel(): Channel {\n if (!this.bot) throw new Error(\"SharedChatBot not initialized. Call ensureInitialized() first.\");\n if (!this.channel) {\n const adapterName = ADAPTER_NAME[this.config.platform];\n this.channel = this.bot.channel(`${adapterName}:${this.config.channelId}`);\n }\n return this.channel;\n }\n\n /**\n * ボタンクリック(Action)ハンドラを登録。\n * 承認カードのボタン ID に対応するハンドラを登録する。\n */\n onAction(actionIds: string[], handler: (event: { actionId: string; value?: string }) => void | Promise<void>): void {\n if (!this.bot) throw new Error(\"SharedChatBot not initialized. Call ensureInitialized() first.\");\n this.bot.onAction(actionIds, (event) => handler({ actionId: event.actionId, value: event.value }));\n }\n\n /**\n * Chat SDK + webhook サーバーをシャットダウン。\n */\n async dispose(): Promise<void> {\n if (this.bot) {\n await this.bot.shutdown();\n this.bot = null;\n }\n if (this.server) {\n this.server.close();\n this.server = null;\n }\n this.channel = null;\n this.initialized = false;\n }\n\n private createAdapter() {\n const creds = this.config.credentials;\n switch (this.config.platform) {\n case \"slack\":\n return creds\n ? createSlackAdapter({\n botToken: creds.SLACK_BOT_TOKEN,\n signingSecret: creds.SLACK_SIGNING_SECRET,\n })\n : createSlackAdapter();\n case \"teams\":\n return creds\n ? createTeamsAdapter({\n appId: creds.TEAMS_APP_ID,\n appPassword: creds.TEAMS_APP_PASSWORD,\n appTenantId: creds.TEAMS_APP_TENANT_ID,\n })\n : createTeamsAdapter();\n case \"discord\":\n return creds\n ? createDiscordAdapter({\n botToken: creds.DISCORD_BOT_TOKEN,\n publicKey: creds.DISCORD_PUBLIC_KEY,\n applicationId: creds.DISCORD_APPLICATION_ID,\n })\n : createDiscordAdapter();\n }\n }\n\n private startWebhookServer(): void {\n const app = new Hono();\n const platform = this.config.platform;\n\n // プラットフォーム別の webhook エンドポイント\n app.post(`/webhooks/${platform}`, async (c) => {\n if (!this.bot) return c.text(\"Bot not initialized\", 500);\n const webhookHandler = (this.bot.webhooks as Record<string, (req: Request) => Promise<Response>>)[\n ADAPTER_NAME[platform]\n ];\n if (!webhookHandler) return c.text(\"Unknown platform\", 400);\n return webhookHandler(c.req.raw);\n });\n\n this.server = serve({ fetch: app.fetch, port: this.config.callbackPort });\n }\n}\n","/**\n * messaging/config --- Chat SDK プラットフォーム設定 + 環境変数読み込み\n *\n * Slack / Teams / Discord 共通の設定型を定義し、\n * 環境変数からプラットフォーム固有の設定を読み込む。\n */\n\nexport const DEFAULT_APPROVAL_TIMEOUT_MS = 300_000;\nexport const DEFAULT_CALLBACK_PORT = 3100;\n\nexport type ChatPlatform = \"slack\" | \"teams\" | \"discord\";\n\nexport interface ChatMessagingConfig {\n /** 対象プラットフォーム */\n platform: ChatPlatform;\n /** プラットフォーム固有のチャンネル ID */\n channelId: string;\n /** Webhook コールバックサーバーのポート */\n callbackPort: number;\n /** 承認タイムアウト (ms) */\n approvalTimeoutMs: number;\n /** true の場合、内蔵 webhook サーバーを起動しない(外部 Hono app で受ける) */\n skipWebhookServer?: boolean;\n /** アダプターに直接渡すクレデンシャル(サーバーモード用、env 非依存) */\n credentials?: Record<string, string>;\n}\n\n/**\n * 環境変数からプラットフォーム固有の設定を読み込む。\n *\n * 各アダプターは独自の env 自動検出を持つため、ここではチャンネル ID と\n * 共通パラメータ(ポート・タイムアウト)のみ解決する。\n *\n * アダプター別の必須 env:\n * - Slack: SLACK_BOT_TOKEN, SLACK_SIGNING_SECRET, SLACK_CHANNEL_ID\n * - Teams: TEAMS_APP_ID, TEAMS_APP_PASSWORD, TEAMS_CHANNEL_ID\n * - Discord: DISCORD_BOT_TOKEN, DISCORD_PUBLIC_KEY, DISCORD_APPLICATION_ID, DISCORD_CHANNEL_ID\n */\nexport function loadChatConfig(\n platform: ChatPlatform,\n overrides?: { callbackPort?: number; approvalTimeoutMs?: number },\n): ChatMessagingConfig {\n const channelId = loadChannelId(platform);\n\n // ポート: CLI 引数 > CHAT_CALLBACK_PORT > SLACK_CALLBACK_PORT (互換) > 3100\n const callbackPort =\n overrides?.callbackPort ??\n parseIntEnv(\"CHAT_CALLBACK_PORT\") ??\n parseIntEnv(\"SLACK_CALLBACK_PORT\") ??\n DEFAULT_CALLBACK_PORT;\n\n // タイムアウト: CLI 引数 > CHAT_APPROVAL_TIMEOUT_MS > SLACK_APPROVAL_TIMEOUT_MS (互換) > 300000\n const approvalTimeoutMs =\n overrides?.approvalTimeoutMs ??\n parseIntEnv(\"CHAT_APPROVAL_TIMEOUT_MS\") ??\n parseIntEnv(\"SLACK_APPROVAL_TIMEOUT_MS\") ??\n DEFAULT_APPROVAL_TIMEOUT_MS;\n\n return { platform, channelId, callbackPort, approvalTimeoutMs };\n}\n\nfunction loadChannelId(platform: ChatPlatform): string {\n const envMap: Record<ChatPlatform, string> = {\n slack: \"SLACK_CHANNEL_ID\",\n teams: \"TEAMS_CHANNEL_ID\",\n discord: \"DISCORD_CHANNEL_ID\",\n };\n\n const envKey = envMap[platform];\n const value = process.env[envKey];\n if (!value) {\n throw new Error(`${envKey} environment variable is required for ${platform} messaging`);\n }\n return value;\n}\n\nfunction parseIntEnv(key: string): number | undefined {\n const v = process.env[key];\n if (!v) return undefined;\n const n = Number.parseInt(v, 10);\n return Number.isNaN(n) ? undefined : n;\n}\n","/**\n * self-heal-analyzer --- デバッグ実行結果の分析 + AI による修正提案生成\n *\n * 修正提案は 2 軸で生成:\n * 1. runbookFix — YAML 手順書への修正(セレクタ変更、ステップ追加/削除/値更新等)\n * 2. contextFix — context markdown への修正(ページ構造変更の記載、補足情報の追加等)\n */\n\nimport { z } from \"zod\";\nimport { getModel, trackedGenerateObject } from \"../harness/ai-model\";\nimport type { AIModelProvider } from \"../harness/ai-service\";\nimport { getRecoveryHint } from \"../harness/error-classifier\";\nimport { getSuggestionSystemPrompt, buildSuggestionUserPrompt } from \"../i18n/prompts\";\nimport type { FailureCategory } from \"../harness/error-classifier\";\nimport type {\n ExecutionReport,\n ParsedRunbook,\n} from \"./types\";\nimport type { DebugReport, DebugStepWarning, DebugSuggestion } from \"./self-heal-types\";\n\nconst suggestionSchema = z.array(\n z.object({\n stepOrdinal: z.number().describe(\"失敗したステップの ordinal\"),\n stepDescription: z.string().describe(\"ステップの説明\"),\n error: z.string().describe(\"失敗エラーの要約\"),\n runbookFix: z.string().describe(\n \"手順書(YAML)への修正提案: セレクタ変更、ステップ追加/削除、アクション値の更新など\",\n ),\n contextFix: z.string().describe(\n \"コンテキスト(markdown)への修正提案: ページ構造変更の記載、前提条件の追加など。context 未提供時は空文字\",\n ),\n severity: z.enum([\"error\", \"warning\"]).describe(\"error: 実行不可、warning: 不安定\"),\n failureCategory: z.enum([\n \"element_not_found\", \"element_stale\", \"page_structure_changed\",\n \"navigation_timeout\", \"action_failed\", \"unknown\",\n ]).optional().describe(\"エラー分類カテゴリ\"),\n suggestedStrategy: z.string().optional().describe(\"カテゴリに基づく推奨対応\"),\n }),\n);\n\n/**\n * ExecutionReport を分析して DebugReport を生成する。\n */\nexport async function analyzeDebugResult(\n report: ExecutionReport,\n runbook: ParsedRunbook,\n retryWarningThreshold: number,\n contextMarkdown: string,\n aiProvider?: AIModelProvider,\n): Promise<DebugReport> {\n const warningSteps = extractWarningSteps(report, retryWarningThreshold);\n\n // 失敗ステップがない場合は提案なし\n const failedSteps = report.steps.filter((s) => s.status === \"failed\");\n if (failedSteps.length === 0 && warningSteps.length === 0) {\n return { executionReport: report, warningSteps: [], suggestions: [] };\n }\n\n const suggestions = await generateSuggestions(report, runbook, contextMarkdown, aiProvider);\n return { executionReport: report, warningSteps, suggestions };\n}\n\nfunction extractWarningSteps(\n report: ExecutionReport,\n threshold: number,\n): DebugStepWarning[] {\n const warnings: DebugStepWarning[] = [];\n for (const step of report.steps) {\n if (step.retryCount !== undefined && step.retryCount >= threshold) {\n warnings.push({\n ordinal: step.ordinal,\n description: step.description,\n retryCount: step.retryCount,\n threshold,\n });\n }\n }\n return warnings;\n}\n\nasync function generateSuggestions(\n report: ExecutionReport,\n runbook: ParsedRunbook,\n contextMarkdown: string,\n aiProvider?: AIModelProvider,\n): Promise<DebugSuggestion[]> {\n const failedSteps = report.steps.filter((s) => s.status === \"failed\");\n if (failedSteps.length === 0) return [];\n\n // 失敗ステップの情報をまとめる\n const failedInfo = failedSteps.map((s) => {\n const retryInfo = s.retryDetails\n ? s.retryDetails.map((d) =>\n ` attempt ${d.attempt}: ${d.failureReason} (elements: ${d.snapshotElementCount}, changed: ${d.snapshotChanged}${d.aiReasoning ? `, AI: ${d.aiReasoning.slice(0, 100)}` : \"\"})`,\n ).join(\"\\n\")\n : \" リトライ詳細なし\";\n const categoryInfo = s.failureCategory\n ? `\\n エラー分類: ${s.failureCategory}\\n 推奨対応: ${getRecoveryHint(s.failureCategory)}`\n : \"\";\n return `Step #${s.ordinal}: ${s.description}\\n エラー: ${s.error}\\n リトライ回数: ${s.retryCount ?? 0}\\n${retryInfo}${categoryInfo}`;\n });\n\n // 手順書のステップ情報\n const stepsInfo = runbook.steps.map((s) => {\n const selector = s.action.selector ? JSON.stringify(s.action.selector) : \"なし\";\n const valuePart = s.action.value ? `\\n 値: ${s.action.value}` : \"\";\n return `Step #${s.ordinal}: ${s.description}\\n アクション: ${s.action.type}${valuePart}\\n セレクタ: ${selector}\\n URL: ${s.url}`;\n });\n\n const system = getSuggestionSystemPrompt();\n const userPrompt = buildSuggestionUserPrompt(failedInfo, stepsInfo, runbook, contextMarkdown);\n\n try {\n const model = aiProvider ? aiProvider.getModel(\"review\") : getModel(\"review\");\n const { object } = await trackedGenerateObject(\"review\", {\n model,\n messages: [\n {\n role: \"system\",\n content: system,\n providerOptions: {\n anthropic: { cacheControl: { type: \"ephemeral\" } },\n },\n },\n { role: \"user\", content: userPrompt },\n ],\n schema: suggestionSchema,\n temperature: 0.2,\n });\n return object;\n } catch {\n // AI 呼び出し失敗時は空配列\n return [];\n }\n}\n\n// SUGGESTION_SYSTEM_PROMPT and buildSuggestionMessages are now dispatched via i18n/prompts\n","/**\n * messaging/cards --- 承認カード / 通知カード ビルダー\n *\n * Chat SDK の Card / Button / Actions / Text / Section を使用して\n * プラットフォーム非依存のカードを構築する。\n * Slack → Block Kit, Teams → Adaptive Cards, Discord → Components に自動変換。\n */\n\nimport {\n Card,\n CardText,\n Button,\n Actions,\n Section,\n Fields,\n Field,\n Divider,\n} from \"chat\";\nimport type { CardElement, CardChild } from \"chat\";\nimport { formatDuration } from \"../cli/format\";\nimport { t, tf } from \"../i18n\";\nimport type { ParsedStep, ExecutionReport, BatchExecutionReport, StepExecutionResult } from \"../runbook-executor/types\";\nimport type { DebugReport } from \"../runbook-executor/types\";\nimport type { ConfirmationContext } from \"../harness/confirmation\";\n\n// ── 承認カード ──\n\n/** 承認リクエストカードのボタン ID(名前空間付き) */\nexport const ACTION_IDS = {\n approve: \"rfn-approve\",\n skip: \"rfn-skip\",\n abort: \"rfn-abort\",\n} as const;\n\nconst RISK_EMOJI: Record<string, string> = {\n low: \"\\u{1F7E2}\", // green circle\n medium: \"\\u26A0\\uFE0F\", // warning\n high: \"\\u{1F534}\", // red circle\n};\n\n/** サーバー利用時のメタデータ: ボタン value に jobId:stepOrdinal を埋め込む */\nexport interface ApprovalMetadata {\n jobId: string;\n stepOrdinal: number;\n}\n\nexport function buildApprovalCard(step: ParsedStep, context?: ConfirmationContext, metadata?: ApprovalMetadata): CardElement {\n const riskEmoji = RISK_EMOJI[step.riskLevel] ?? \"\";\n const goalLine = context?.goal ? `${t(\"chat.taskLabel\")}${context.goal}\\n` : \"\";\n\n // metadata あり(サーバーモード)→ id にメタデータを埋め込み(Discord は value を保持しないため id で統一)\n const buttonId = (actionId: string) =>\n metadata ? `${actionId}:${metadata.jobId}:${metadata.stepOrdinal}` : actionId;\n const buttonValue = metadata ? `${metadata.jobId}:${metadata.stepOrdinal}` : undefined;\n\n return Card({\n title: t(\"chat.approvalRequest\"),\n children: [\n Section([\n CardText(\n tf(\"chat.approvalDescription\", {\n goalLine,\n description: step.description,\n riskEmoji,\n riskLevel: step.riskLevel,\n }),\n ),\n ]),\n Actions([\n Button({ id: buttonId(ACTION_IDS.approve), label: t(\"chat.approveButton\"), style: \"primary\", value: buttonValue }),\n Button({ id: buttonId(ACTION_IDS.skip), label: t(\"chat.skipButton\"), value: buttonValue }),\n Button({ id: buttonId(ACTION_IDS.abort), label: t(\"chat.abortButton\"), style: \"danger\", value: buttonValue }),\n ]),\n ],\n });\n}\n\nexport function buildApprovalResultCard(step: ParsedStep, resultText: string): CardElement {\n return Card({\n children: [\n Section([\n CardText(`*${t(\"chat.stepPrefix\")} ${step.ordinal}* ${step.description}\\n${resultText}`),\n ]),\n ],\n });\n}\n\n// ── 通知カード ──\n\nfunction statusEmoji(report: ExecutionReport | BatchExecutionReport): string {\n if (\"totalRows\" in report) {\n const b = report as BatchExecutionReport;\n if (b.failed === 0) return \"\\u2705\"; // check mark\n if (b.succeeded === 0) return \"\\u274C\"; // cross mark\n return \"\\u26A0\\uFE0F\"; // warning\n }\n const r = report as ExecutionReport;\n if (r.aborted) return \"\\u{1F6D1}\"; // stop sign\n if (r.failed === 0) return \"\\u2705\";\n if (r.succeeded === 0) return \"\\u274C\";\n return \"\\u26A0\\uFE0F\";\n}\n\nexport function buildNotificationCard(report: ExecutionReport | BatchExecutionReport): CardElement {\n const isBatch = \"totalRows\" in report;\n return isBatch\n ? buildBatchCard(report as BatchExecutionReport)\n : buildSingleCard(report as ExecutionReport);\n}\n\nfunction buildSingleCard(report: ExecutionReport): CardElement {\n const emoji = statusEmoji(report);\n const abortTag = report.aborted ? ` \\u{1F6D1} ${t(\"chat.abortTag\")}` : \"\";\n\n const children: CardChild[] = [\n Section([\n CardText(`*${emoji} ${report.runbookTitle}*`),\n ]),\n Fields([\n Field({ label: t(\"chat.succeededFieldLabel\"), value: `\\u2705 ${report.succeeded}` }),\n Field({ label: t(\"chat.failedFieldLabel\"), value: `\\u274C ${report.failed}` }),\n Field({ label: t(\"chat.skippedFieldLabel\"), value: `\\u23E9 ${report.skipped}` }),\n Field({ label: t(\"chat.durationFieldLabel\"), value: `\\u23F1 ${formatDuration(report.totalDurationMs)}${abortTag}` }),\n ]),\n ];\n\n const failedSteps = report.steps.filter((s) => s.status === \"failed\");\n if (failedSteps.length > 0) {\n children.push(Divider());\n children.push(\n Section([\n CardText(`*${t(\"chat.failedLabel\")}*\\n${formatFailedSteps(failedSteps)}`),\n ]),\n );\n }\n\n return Card({ children });\n}\n\nfunction buildBatchCard(report: BatchExecutionReport): CardElement {\n const emoji = statusEmoji(report);\n\n const children: CardChild[] = [\n Section([\n CardText(`*${emoji} ${report.runbookTitle} (${t(\"chat.batchTag\")})*`),\n ]),\n Fields([\n Field({ label: t(\"chat.totalFieldLabel\"), value: tf(\"chat.totalRows\", { count: report.totalRows }) }),\n Field({ label: t(\"chat.succeededFieldLabel\"), value: `\\u2705 ${report.succeeded}` }),\n Field({ label: t(\"chat.failedFieldLabel\"), value: `\\u274C ${report.failed}` }),\n Field({ label: t(\"chat.durationFieldLabel\"), value: `\\u23F1 ${formatDuration(report.totalDurationMs)}` }),\n ]),\n ];\n\n const failedRows = report.rows.filter((r) => r.report.failed > 0 || r.report.aborted);\n if (failedRows.length > 0) {\n const rowLines = failedRows.slice(0, 10).map((row) => {\n const failed = row.report.steps.filter((s) => s.status === \"failed\");\n const stepInfo = failed.map((s) => `#${s.ordinal}`).join(\", \");\n return `- ${row.rowLabel}: ${stepInfo}`;\n });\n if (failedRows.length > 10) {\n rowLines.push(tf(\"chat.moreRows\", { count: failedRows.length - 10 }));\n }\n children.push(Divider());\n children.push(\n Section([\n CardText(`*${t(\"chat.failedRows\")}*\\n${rowLines.join(\"\\n\")}`),\n ]),\n );\n }\n\n return Card({ children });\n}\n\nexport function buildDebugNotificationCard(report: DebugReport): CardElement {\n const r = report.executionReport;\n\n const children: CardChild[] = [\n Section([\n CardText(`*\\u{1F50D} ${tf(\"chat.debugFailure\", { title: r.runbookTitle })}*`),\n ]),\n Fields([\n Field({ label: t(\"chat.succeededFieldLabel\"), value: `\\u2705 ${r.succeeded}` }),\n Field({ label: t(\"chat.failedFieldLabel\"), value: `\\u274C ${r.failed}` }),\n Field({ label: t(\"chat.skippedFieldLabel\"), value: `\\u23E9 ${r.skipped}` }),\n Field({ label: t(\"chat.durationFieldLabel\"), value: `\\u23F1 ${formatDuration(r.totalDurationMs)}` }),\n ]),\n ];\n\n // 失敗ステップ一覧\n const failedSteps = r.steps.filter((s) => s.status === \"failed\");\n if (failedSteps.length > 0) {\n children.push(Divider());\n children.push(\n Section([\n CardText(`*${t(\"chat.failedLabel\")}*\\n${formatFailedSteps(failedSteps, { limit: 15, errorMaxLen: 80, showRetries: true })}`),\n ]),\n );\n }\n\n // 修正提案\n const allSuggestionLines: string[] = [];\n const runbookSuggestions = report.suggestions.filter((s) => s.runbookFix);\n for (const s of runbookSuggestions.slice(0, 10)) {\n const prefix = s.severity === \"error\" ? \"\\u274C\" : \"\\u26A0\\uFE0F\";\n allSuggestionLines.push(`${prefix} #${s.stepOrdinal} [YAML]: ${s.runbookFix.slice(0, 100)}`);\n }\n const contextSuggestions = report.suggestions.filter((s) => s.contextFix);\n for (const s of contextSuggestions.slice(0, 10)) {\n const prefix = s.severity === \"error\" ? \"\\u274C\" : \"\\u26A0\\uFE0F\";\n allSuggestionLines.push(`${prefix} #${s.stepOrdinal} [ctx]: ${s.contextFix.slice(0, 100)}`);\n }\n const totalSuggestions = runbookSuggestions.length + contextSuggestions.length;\n if (allSuggestionLines.length > 0 && totalSuggestions > allSuggestionLines.length) {\n allSuggestionLines.push(tf(\"chat.moreItems\", { count: totalSuggestions - allSuggestionLines.length }));\n }\n if (allSuggestionLines.length > 0) {\n children.push(Divider());\n children.push(\n Section([\n CardText(`*${t(\"chat.suggestionsLabel\")}*\\n${allSuggestionLines.join(\"\\n\")}`),\n ]),\n );\n }\n\n // リトライ警告\n if (report.warningSteps.length > 0) {\n const lines = report.warningSteps.slice(0, 10).map((w) =>\n `- #${w.ordinal} ${w.description}: retry ${w.retryCount}/${w.threshold}`,\n );\n if (report.warningSteps.length > 10) {\n lines.push(tf(\"chat.moreItems\", { count: report.warningSteps.length - 10 }));\n }\n children.push(Divider());\n children.push(\n Section([\n CardText(`*${t(\"chat.retryWarningsLabel\")}*\\n${lines.join(\"\\n\")}`),\n ]),\n );\n }\n\n return Card({ children });\n}\n\n// ── 生成通知カード ──\n\nexport interface GenerateNotificationInfo {\n goal: string;\n goalAchieved: boolean;\n stepsCount: number;\n yamlGenerated: boolean;\n}\n\nexport function buildGenerateNotificationCard(info: GenerateNotificationInfo): CardElement {\n const emoji = info.goalAchieved ? \"\\u2705\" : \"\\u274C\";\n return Card({\n children: [\n Section([\n CardText(`*${emoji} ${t(\"chat.generateComplete\")}*`),\n ]),\n Fields([\n Field({ label: t(\"chat.goalFieldLabel\"), value: info.goal }),\n Field({ label: t(\"chat.goalAchievedFieldLabel\"), value: info.goalAchieved ? \"\\u2705\" : \"\\u274C\" }),\n Field({ label: t(\"chat.stepsFieldLabel\"), value: String(info.stepsCount) }),\n Field({ label: t(\"chat.yamlFieldLabel\"), value: info.yamlGenerated ? \"\\u2705\" : \"\\u274C\" }),\n ]),\n ],\n });\n}\n\n// ── ヘルパー ──\n\nfunction formatFailedSteps(\n steps: StepExecutionResult[],\n options?: { limit?: number; errorMaxLen?: number; showRetries?: boolean },\n): string {\n const { limit = 10, errorMaxLen = 100, showRetries = false } = options ?? {};\n const lines = steps.slice(0, limit).map((s) => {\n const errMsg = s.error ? `: ${s.error.slice(0, errorMaxLen)}` : \"\";\n const retries = showRetries && s.retryCount ? ` (retry:${s.retryCount})` : \"\";\n const categoryTag = s.failureCategory ? ` [${s.failureCategory}]` : \"\";\n return `- #${s.ordinal} ${s.description}${errMsg}${retries}${categoryTag}`;\n });\n if (steps.length > limit) {\n lines.push(tf(\"chat.moreSteps\", { count: steps.length - limit }));\n }\n return lines.join(\"\\n\");\n}\n"],"mappings":"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","names":["createHash","readFile","writeFile","createHash","join","mkdir","join","z","z","z","z","z","z","operand","createHash","createHash","content","mkdir","join","reason","z","z","displayCaptures","z","z"]}
|