{
  "canonical_name": "browserbase/stagehand",
  "compilation_id": "pack_b516189a08d64ecea2a10fdc4f266a88",
  "created_at": "2026-05-11T09:04:04.208298+00:00",
  "created_by": "project-pack-compiler",
  "feedback": {
    "carrier_selection_notes": [
      "viable_asset_types=skill, recipe, host_instruction, eval, preflight",
      "recommended_asset_types=skill, recipe, host_instruction, eval, preflight"
    ],
    "evidence_delta": {
      "confirmed_claims": [
        "identity_anchor_present",
        "capability_and_host_targets_present",
        "install_path_declared_or_better"
      ],
      "missing_required_fields": [],
      "must_verify_forwarded": [
        "Run or inspect `npx create-browser-app` in an isolated environment.",
        "Confirm the project exposes the claimed capability to at least one target host."
      ],
      "quickstart_execution_scope": "allowlisted_sandbox_smoke",
      "sandbox_command": "npx create-browser-app",
      "sandbox_container_image": "node:22-slim",
      "sandbox_execution_backend": "docker",
      "sandbox_planner_decision": "deterministic_isolated_install",
      "sandbox_validation_id": "sbx_a4766987dbf0455eac91c0891f1b2319"
    },
    "feedback_event_type": "project_pack_compilation_feedback",
    "learning_candidate_reasons": [],
    "template_gaps": []
  },
  "identity": {
    "canonical_id": "project_3a5a62948a9cae5468be74c8f12097ed",
    "canonical_name": "browserbase/stagehand",
    "homepage_url": null,
    "license": "unknown",
    "repo_url": "https://github.com/browserbase/stagehand",
    "slug": "stagehand",
    "source_packet_id": "phit_057415b2d51c4338ab785dd620ccfc14",
    "source_validation_id": "dval_d8fcc448d22743929dc86fb361a4021f"
  },
  "merchandising": {
    "best_for": "需要软件开发与交付能力，并使用 local_cli的用户",
    "github_forks": 1514,
    "github_stars": 22628,
    "one_liner_en": "The SDK For Browser Agents",
    "one_liner_zh": "The SDK For Browser Agents",
    "primary_category": {
      "category_id": "software-development",
      "confidence": "high",
      "name_en": "Software Development",
      "name_zh": "软件开发与交付",
      "reason": "matched_keywords:git, cli, sdk"
    },
    "target_user": "使用 local_cli 等宿主 AI 的用户",
    "title_en": "stagehand",
    "title_zh": "stagehand 能力包",
    "visible_tags": [
      {
        "label_en": "Browser Agents",
        "label_zh": "浏览器 Agent",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "product_domain-browser-agents",
        "type": "product_domain"
      },
      {
        "label_en": "Web Task Automation",
        "label_zh": "网页任务自动化",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "user_job-web-task-automation",
        "type": "user_job"
      },
      {
        "label_en": "Natural-language Web Actions",
        "label_zh": "自然语言网页操作",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "core_capability-natural-language-web-actions",
        "type": "core_capability"
      },
      {
        "label_en": "Page Observation and Action Planning",
        "label_zh": "页面观察与动作规划",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "workflow_pattern-page-observation-and-action-planning",
        "type": "workflow_pattern"
      },
      {
        "label_en": "Structured Data Extraction",
        "label_zh": "结构化数据提取",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "selection_signal-structured-data-extraction",
        "type": "selection_signal"
      }
    ]
  },
  "packet_id": "phit_057415b2d51c4338ab785dd620ccfc14",
  "page_model": {
    "artifacts": {
      "artifact_slug": "stagehand",
      "files": [
        "PROJECT_PACK.json",
        "QUICK_START.md",
        "PROMPT_PREVIEW.md",
        "HUMAN_MANUAL.md",
        "AI_CONTEXT_PACK.md",
        "BOUNDARY_RISK_CARD.md",
        "PITFALL_LOG.md",
        "REPO_INSPECTION.json",
        "REPO_INSPECTION.md",
        "CAPABILITY_CONTRACT.json",
        "EVIDENCE_INDEX.json",
        "CLAIM_GRAPH.json"
      ],
      "required_files": [
        "PROJECT_PACK.json",
        "QUICK_START.md",
        "PROMPT_PREVIEW.md",
        "HUMAN_MANUAL.md",
        "AI_CONTEXT_PACK.md",
        "BOUNDARY_RISK_CARD.md",
        "PITFALL_LOG.md",
        "REPO_INSPECTION.json"
      ]
    },
    "detail": {
      "capability_source": "Project Hit Packet + DownstreamValidationResult",
      "commands": [
        {
          "command": "npx create-browser-app",
          "label": "Node.js / npx · 官方安装入口",
          "source": "https://github.com/browserbase/stagehand#readme",
          "verified": true
        }
      ],
      "display_tags": [
        "浏览器 Agent",
        "网页任务自动化",
        "自然语言网页操作",
        "页面观察与动作规划",
        "结构化数据提取"
      ],
      "eyebrow": "软件开发与交付",
      "glance": [
        {
          "body": "判断自己是不是目标用户。",
          "label": "最适合谁",
          "value": "需要软件开发与交付能力，并使用 local_cli的用户"
        },
        {
          "body": "先理解能力边界，再决定是否继续。",
          "label": "核心价值",
          "value": "The SDK For Browser Agents"
        },
        {
          "body": "未完成验证前保持审慎。",
          "label": "继续前",
          "value": "publish to Doramagic.ai project surfaces"
        }
      ],
      "guardrail_source": "Boundary & Risk Card",
      "guardrails": [
        {
          "body": "Prompt Preview 只展示流程，不证明项目已安装或运行。",
          "label": "Check 1",
          "value": "不要把试用当真实运行"
        },
        {
          "body": "local_cli",
          "label": "Check 2",
          "value": "确认宿主兼容"
        },
        {
          "body": "publish to Doramagic.ai project surfaces",
          "label": "Check 3",
          "value": "先隔离验证"
        }
      ],
      "mode": "skill, recipe, host_instruction, eval, preflight",
      "pitfall_log": {
        "items": [
          {
            "body": "仓库名 `stagehand` 与安装入口 `create-browser-app` 不完全一致。",
            "category": "身份坑",
            "evidence": [
              "identity.distribution | github_repo:776908852 | https://github.com/browserbase/stagehand | repo=stagehand; install=create-browser-app"
            ],
            "severity": "medium",
            "suggested_check": "在 npm/PyPI/GitHub 上确认包名映射和官方 README 说明。",
            "title": "仓库名和安装名不一致",
            "user_impact": "用户照着仓库名搜索包或照着包名找仓库时容易走错入口。"
          },
          {
            "body": "README/documentation is current enough for a first validation pass.",
            "category": "能力坑",
            "evidence": [
              "capability.assumptions | github_repo:776908852 | https://github.com/browserbase/stagehand | README/documentation is current enough for a first validation pass."
            ],
            "severity": "medium",
            "suggested_check": "将假设转成下游验证清单。",
            "title": "能力判断依赖假设",
            "user_impact": "假设不成立时，用户拿不到承诺的能力。"
          },
          {
            "body": "未记录 last_activity_observed。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | github_repo:776908852 | https://github.com/browserbase/stagehand | last_activity_observed missing"
            ],
            "severity": "medium",
            "suggested_check": "补 GitHub 最近 commit、release、issue/PR 响应信号。",
            "title": "维护活跃度未知",
            "user_impact": "新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。"
          },
          {
            "body": "no_demo",
            "category": "安全/权限坑",
            "evidence": [
              "downstream_validation.risk_items | github_repo:776908852 | https://github.com/browserbase/stagehand | no_demo; severity=medium"
            ],
            "severity": "medium",
            "suggested_check": "进入安全/权限治理复核队列。",
            "title": "下游验证发现风险项",
            "user_impact": "下游已经要求复核，不能在页面中弱化。"
          },
          {
            "body": "no_demo",
            "category": "安全/权限坑",
            "evidence": [
              "risks.scoring_risks | github_repo:776908852 | https://github.com/browserbase/stagehand | no_demo; severity=medium"
            ],
            "severity": "medium",
            "suggested_check": "把风险写入边界卡，并确认是否需要人工复核。",
            "title": "存在评分风险",
            "user_impact": "风险会影响是否适合普通用户安装。"
          },
          {
            "body": "issue_or_pr_quality=unknown。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | github_repo:776908852 | https://github.com/browserbase/stagehand | issue_or_pr_quality=unknown"
            ],
            "severity": "low",
            "suggested_check": "抽样最近 issue/PR，判断是否长期无人处理。",
            "title": "issue/PR 响应质量未知",
            "user_impact": "用户无法判断遇到问题后是否有人维护。"
          },
          {
            "body": "release_recency=unknown。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | github_repo:776908852 | https://github.com/browserbase/stagehand | release_recency=unknown"
            ],
            "severity": "low",
            "suggested_check": "确认最近 release/tag 和 README 安装命令是否一致。",
            "title": "发布节奏不明确",
            "user_impact": "安装命令和文档可能落后于代码，用户踩坑概率升高。"
          }
        ],
        "source": "ProjectPitfallLog + ProjectHitPacket + validation + community signals",
        "summary": "发现 7 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：身份坑 - 仓库名和安装名不一致。",
        "title": "踩坑日志"
      },
      "snapshot": {
        "contributors": 39,
        "forks": 1514,
        "license": "unknown",
        "note": "GitHub API 快照，非实时质量证明；用于开工前背景判断。",
        "stars": 22628,
        "open_issues": 210,
        "pushed_at": "2026-05-12T19:28:39.000Z"
      },
      "source_url": "https://github.com/browserbase/stagehand",
      "steps": [
        {
          "body": "不安装项目，先体验能力节奏。",
          "code": "preview",
          "title": "先试 Prompt"
        },
        {
          "body": "理解输入、输出、失败模式和边界。",
          "code": "manual",
          "title": "读说明书"
        },
        {
          "body": "把上下文交给宿主 AI 继续工作。",
          "code": "context",
          "title": "带给 AI"
        },
        {
          "body": "进入主力环境前先完成安装入口与风险边界验证。",
          "code": "verify",
          "title": "沙箱验证"
        }
      ],
      "subtitle": "The SDK For Browser Agents",
      "title": "stagehand 能力包",
      "trial_prompt": "# stagehand - Prompt Preview\n\n> 复制下面这段 Prompt 到你常用的 AI，先试一次，不需要安装。\n> 它的目标是让你直接体验这个项目的服务方式，而不是阅读项目介绍。\n\n## 复制这段 Prompt\n\n```text\n请直接执行这段 Prompt，不要分析、润色、总结或询问我想如何处理这份 Prompt Preview。\n\n你现在扮演 stagehand 的“安装前体验版”。\n这不是项目介绍、不是评价报告、不是 README 总结。你的任务是让我用最小成本体验它的核心服务。\n\n我的试用任务：我想用它完成一个真实的软件开发与交付任务。\n我常用的宿主 AI：Local CLI\n\n【体验目标】\n围绕我的真实任务，现场演示这个项目如何把输入转成 示例引导, 判断线索。重点是让我感受到工作方式，而不是给我项目背景。\n\n【业务流约束】\n- 你必须像一个正在提供服务的项目能力包，而不是像一个讲解员。\n- 每一轮只推进一个步骤；提出问题后必须停下来等我回答。\n- 每一步都必须让我感受到一个具体服务动作：澄清、整理、规划、检查、判断或收尾。\n- 每一步都要说明：当前目标、你需要我提供什么、我回答后你会产出什么。\n- 不要安装、不要运行命令、不要写代码、不要声称测试通过、不要声称已经修改文件。\n- 需要真实安装或宿主加载后才能验证的内容，必须明确说“这一步需要安装后验证”。\n- 如果我说“用示例继续”，你可以用虚构示例推进，但仍然不能声称真实执行。\n\n【可体验服务能力】\n- 安装前能力预览: The SDK For Browser Agents 输入：用户任务, 当前 AI 对话上下文；输出：示例引导, 判断线索。\n\n【必须安装后才可验证的能力】\n- 暂无明确的运行时能力线索。\n\n【核心服务流】\n请严格按这个顺序带我体验。不要一次性输出完整流程：\n1. introduction：Stagehand 简介。围绕“Stagehand 简介”模拟一次用户任务，不展示安装或运行结果。\n2. quickstart：快速开始。围绕“快速开始”模拟一次用户任务，不展示安装或运行结果。\n3. architecture-overview：系统架构总览。围绕“系统架构总览”模拟一次用户任务，不展示安装或运行结果。\n4. act-api：act() 操作执行。围绕“act() 操作执行”模拟一次用户任务，不展示安装或运行结果。\n5. extract-api：extract() 数据提取。围绕“extract() 数据提取”模拟一次用户任务，不展示安装或运行结果。\n\n【核心能力体验剧本】\n每一步都必须按“输入 -> 服务动作 -> 中间产物”执行。不要只说流程名：\n1. introduction\n输入：用户提供的“Stagehand 简介”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n2. quickstart\n输入：用户提供的“快速开始”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n3. architecture-overview\n输入：用户提供的“系统架构总览”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n4. act-api\n输入：用户提供的“act() 操作执行”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n5. extract-api\n输入：用户提供的“extract() 数据提取”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n【项目服务规则】\n这些规则决定你如何服务用户。不要解释规则本身，而要在每一步执行时遵守：\n- 先确认用户任务、输入材料和成功标准，再模拟项目能力。\n- 每一步都必须形成可检查的小产物，并等待用户确认后再继续。\n- 凡是需要安装、调用工具或访问外部服务的能力，都必须标记为安装后验证。\n\n【每一步的服务约束】\n- Step 1 / introduction：Step 1 必须围绕“Stagehand 简介”形成一个小中间产物，并等待用户确认。\n- Step 2 / quickstart：Step 2 必须围绕“快速开始”形成一个小中间产物，并等待用户确认。\n- Step 3 / architecture-overview：Step 3 必须围绕“系统架构总览”形成一个小中间产物，并等待用户确认。\n- Step 4 / act-api：Step 4 必须围绕“act() 操作执行”形成一个小中间产物，并等待用户确认。\n- Step 5 / extract-api：Step 5 必须围绕“extract() 数据提取”形成一个小中间产物，并等待用户确认。\n\n【边界与风险】\n- 不要声称已经安装、运行、调用 API、读写本地文件或完成真实任务。\n- 安装前预览只能展示工作方式，不能证明兼容性、性能或输出质量。\n\n【可追溯依据】\n这些路径只用于你内部校验或在我追问“依据是什么”时简要引用。不要在首次回复主动展开：\n- https://github.com/browserbase/stagehand\n- https://github.com/browserbase/stagehand#readme\n- README.md\n- packages/core/lib/v3/v3.ts\n- packages/core/package.json\n- packages/core/examples/example.ts\n- .env.example\n- packages/core/lib/v3/index.ts\n- pnpm-workspace.yaml\n- packages/core/lib/v3/handlers/actHandler.ts\n- packages/core/lib/v3/agent/tools/act.ts\n- packages/core/lib/v3/agent/tools/click.ts\n\n【首次问题规则】\n- 首次三问必须先确认用户目标、成功标准和边界，不要提前进入工具、安装或实现细节。\n- 如果后续需要技术条件、文件路径或运行环境，必须等用户确认目标后再追问。\n\n首次回复必须只输出下面 4 个部分：\n1. 体验开始：用 1 句话说明你将带我体验 stagehand 的核心服务。\n2. 当前步骤：明确进入 Step 1，并说明这一步要解决什么。\n3. 你会如何服务我：说明你会先改变我完成任务的哪个动作。\n4. 只问我 3 个问题，然后停下等待回答。\n\n首次回复禁止输出：后续完整流程、证据清单、安装命令、项目评价、营销文案、已经安装或运行的说法。\n\nStep 1 / brainstorming 的二轮协议：\n- 我回答首次三问后，你仍然停留在 Step 1 / brainstorming，不要进入 Step 2。\n- 第二次回复必须产出 6 个部分：澄清后的任务定义、成功标准、边界条件、\n  2-3 个可选方案、每个方案的权衡、推荐方案。\n- 第二次回复最后必须问我是否确认推荐方案；只有我明确确认后，才能进入下一步。\n- 第二次回复禁止输出 git worktree、代码计划、测试文件、命令或真实执行结果。\n\n后续对话规则：\n- 我回答后，你先完成当前步骤的中间产物并等待确认；只有我确认后，才能进入下一步。\n- 每一步都要生成一个小的中间产物，例如澄清后的目标、计划草案、测试意图、验证清单或继续/停止判断。\n- 所有演示都写成“我会建议/我会引导/这一步会形成”，不要写成已经真实执行。\n- 不要声称已经测试通过、文件已修改、命令已运行或结果已产生。\n- 如果某个能力必须安装后验证，请直接说“这一步需要安装后验证”。\n- 如果证据不足，请明确说“证据不足”，不要补事实。\n```\n",
      "voices": [
        {
          "body": "来源平台：github。github/github_issue: Storage state persistence broken in Stagehand v3 - userDataDir doesn't w（https://github.com/browserbase/stagehand/issues/1250）；github/github_issue: Reduce Bundle Size（https://github.com/browserbase/stagehand/issues/1610）；github/github_issue: Feature: pay-per-call captcha unstuck via x402 (Onyx Actions)（https://github.com/browserbase/stagehand/issues/2070）；github/github_release: stagehand/server-v3 v3.6.6（https://github.com/browserbase/stagehand/releases/tag/stagehand-server-v3/v3.6.6）；github/github_release: stagehand/server-v3 v3.6.5（https://github.com/browserbase/stagehand/releases/tag/stagehand-server-v3/v3.6.5）；github/github_release: @browserbasehq/browse-cli@0.6.0（https://github.com/browserbase/stagehand/releases/tag/%40browserbasehq/browse-cli%400.6.0）；github/github_release: stagehand/server-v3 v3.6.3（https://github.com/browserbase/stagehand/releases/tag/stagehand-server-v3/v3.6.3）；github/github_release: stagehand/server-v3 v3.6.2（https://github.com/browserbase/stagehand/releases/tag/stagehand-server-v3/v3.6.2）；github/github_release: @browserbasehq/stagehand@3.2.0（https://github.com/browserbase/stagehand/releases/tag/%40browserbasehq/stagehand%403.2.0）；github/github_release: @browserbasehq/browse-cli@0.2.0（https://github.com/browserbase/stagehand/releases/tag/%40browserbasehq/browse-cli%400.2.0）。这些是项目级外部声音，不作为单独质量证明。",
          "items": [
            {
              "kind": "github_issue",
              "source": "github",
              "title": "Storage state persistence broken in Stagehand v3 - userDataDir doesn't w",
              "url": "https://github.com/browserbase/stagehand/issues/1250"
            },
            {
              "kind": "github_issue",
              "source": "github",
              "title": "Reduce Bundle Size",
              "url": "https://github.com/browserbase/stagehand/issues/1610"
            },
            {
              "kind": "github_issue",
              "source": "github",
              "title": "Feature: pay-per-call captcha unstuck via x402 (Onyx Actions)",
              "url": "https://github.com/browserbase/stagehand/issues/2070"
            },
            {
              "kind": "github_release",
              "source": "github",
              "title": "stagehand/server-v3 v3.6.6",
              "url": "https://github.com/browserbase/stagehand/releases/tag/stagehand-server-v3/v3.6.6"
            },
            {
              "kind": "github_release",
              "source": "github",
              "title": "stagehand/server-v3 v3.6.5",
              "url": "https://github.com/browserbase/stagehand/releases/tag/stagehand-server-v3/v3.6.5"
            },
            {
              "kind": "github_release",
              "source": "github",
              "title": "@browserbasehq/browse-cli@0.6.0",
              "url": "https://github.com/browserbase/stagehand/releases/tag/%40browserbasehq/browse-cli%400.6.0"
            },
            {
              "kind": "github_release",
              "source": "github",
              "title": "stagehand/server-v3 v3.6.3",
              "url": "https://github.com/browserbase/stagehand/releases/tag/stagehand-server-v3/v3.6.3"
            },
            {
              "kind": "github_release",
              "source": "github",
              "title": "stagehand/server-v3 v3.6.2",
              "url": "https://github.com/browserbase/stagehand/releases/tag/stagehand-server-v3/v3.6.2"
            },
            {
              "kind": "github_release",
              "source": "github",
              "title": "@browserbasehq/stagehand@3.2.0",
              "url": "https://github.com/browserbase/stagehand/releases/tag/%40browserbasehq/stagehand%403.2.0"
            },
            {
              "kind": "github_release",
              "source": "github",
              "title": "@browserbasehq/browse-cli@0.2.0",
              "url": "https://github.com/browserbase/stagehand/releases/tag/%40browserbasehq/browse-cli%400.2.0"
            }
          ],
          "status": "已收录 10 条来源",
          "title": "社区讨论"
        }
      ]
    },
    "homepage_card": {
      "category": "软件开发与交付",
      "desc": "The SDK For Browser Agents",
      "effort": "安装已验证",
      "forks": 1507,
      "icon": "code",
      "name": "stagehand 能力包",
      "risk": "可发布",
      "slug": "stagehand",
      "stars": 22580,
      "tags": [
        "浏览器 Agent",
        "网页任务自动化",
        "自然语言网页操作",
        "页面观察与动作规划",
        "结构化数据提取"
      ],
      "thumb": "gray",
      "type": "Skill Pack"
    },
    "manual": {
      "markdown": "# Wiki Documentation for https://github.com/browserbase/stagehand\n\nGenerated on: 2026-05-10 12:00:15 UTC\n\n## Table of Contents\n\n- [Stagehand 简介](#introduction)\n- [快速开始](#quickstart)\n- [系统架构总览](#architecture-overview)\n- [act() 操作执行](#act-api)\n- [extract() 数据提取](#extract-api)\n- [observe() 页面观察](#observe-api)\n- [Agent 代理系统](#agent-system)\n- [Handler 处理系统](#handler-system)\n- [DOM 与无障碍树](#dom-accessibility)\n- [Deep Locator 深层定位器](#deep-locator)\n\n<a id='introduction'></a>\n\n## Stagehand 简介\n\n### Related Pages\n\nRelated topics: [快速开始](#quickstart), [系统架构总览](#architecture-overview)\n\n<details>\n<summary>Relevant source files</summary>\n\nThe following files were used as context for generating this wiki page:\n\n- [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n- [packages/cli/src/local-strategy.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-strategy.ts)\n- [packages/cli/src/local-cdp-discovery.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-cdp-discovery.ts)\n</details>\n\n# Stagehand 简介\n\nStagehand 是一个基于浏览器自动化框架的工具，通过命令行接口（CLI）提供对浏览器的精细控制能力。该项目由 Browserbase 开发，支持本地和远程两种运行模式，能够执行页面导航、元素交互、网络请求捕获、截图等多种浏览器自动化任务。\n\n## 核心架构\n\nStagehand 采用客户端-守护进程（Client-Daemon）架构设计，CLI 作为客户端与守护进程通信，守护进程负责实际管理浏览器实例。\n\n```mermaid\ngraph TD\n    A[CLI Client] --> B[Socket Communication]\n    B --> C[Daemon Process]\n    C --> D[Browser Instance]\n    C --> E[Local CDP Discovery]\n    D --> F[Network Capture]\n    E --> C\n```\n\n### 守护进程基础设施\n\n守护进程管理依赖 Socket 文件进行进程间通信，关键路径配置如下：\n\n```typescript\nconst SOCKET_DIR = os.tmpdir();\n\nfunction getSocketPath(session: string): string {\n  return path.join(SOCKET_DIR, `browse-${session}.sock`);\n}\n\nfunction getLockPath(session: string): string {\n  return path.join(SOCKET_DIR, `browse-${session}.lock`);\n}\n```\n\n守护进程实现了基于文件锁的并发控制机制，使用 `O_EXCL` 标志确保原子性文件创建，防止竞争条件：\n\n```typescript\nasync function acquireLock(\n  session: string,\n  timeoutMs: number = 10000,\n): Promise<boolean> {\n  const lockPath = getLockPath(session);\n  // O_EXCL ensures atomic creation - fails if file exists\n  const handle = await fs.open(lockPath, \"wx\");\n  await handle.write(String(process.pid));\n  await handle.close();\n  return true;\n}\n```\n\nSources: [packages/cli/src/index.ts:1-50]()\n\n## CLI 命令系统\n\nStagehand CLI 提供丰富的命令集，覆盖浏览器自动化的各个方面。\n\n### 导航与页面操作\n\n| 命令 | 说明 | 关键选项 |\n|------|------|----------|\n| `open <url>` | 导航到指定 URL | `--wait`, `--timeout`, `--context-id`, `--persist` |\n| `goto <url>` | `open` 的别名 | 同上 |\n| `pages` | 列出所有打开的页面 | - |\n| `newpage [url]` | 创建新页面/标签页 | - |\n\n导航命令支持多种等待状态：\n\n- `load`（默认）\n- `domcontentloaded`\n- `networkidle`\n\n```typescript\nprogram\n  .command(\"open <url>\")\n  .alias(\"goto\")\n  .description(\"Navigate to URL\")\n  .option(\n    \"--wait <state>\",\n    \"Wait state: load, domcontentloaded, networkidle\",\n    \"load\",\n  )\n  .option(\"-t, --timeout <ms>\", \"Navigation timeout in milliseconds\", \"30000\")\n```\n\nSources: [packages/cli/src/index.ts:80-130]()\n\n### 元素交互\n\n元素操作命令支持通过选择器精确定位和操作 DOM 元素：\n\n| 命令 | 说明 | 选项 |\n|------|------|------|\n| `click <selector>` | 点击元素 | `--button`, `--delay`, `--xpath` |\n| `dblclick <selector>` | 双击元素 | `--button`, `--delay` |\n| `fill <selector> <value>` | 填充输入框 | `--no-press-enter` |\n| `select <selector> <values...>` | 选择下拉选项 | - |\n| `hover <x> <y>` | 悬停在坐标位置 | `--xpath` |\n| `scroll <x> <y> <deltaX> <deltaY>` | 滚动操作 | `--xpath` |\n| `drag <fromX> <fromY> <toX> <toY>` | 拖拽操作 | `--delay`, `--xpath` |\n\n```typescript\nprogram\n  .command(\"fill <selector> <value>\")\n  .description(\"Fill input element (presses Enter by default)\")\n  .option(\"--no-press-enter\", \"Don't press Enter after filling\")\n  .action(async (selector: string, value: string, cmdOpts) => {\n    const pressEnter = cmdOpts.pressEnter !== false;\n    const result = await runCommand(\"fill\", [selector, value, { pressEnter }]);\n  });\n```\n\nSources: [packages/cli/src/index.ts:150-200]()\n\n### 键盘与输入\n\n| 命令 | 说明 | 选项 |\n|------|------|------|\n| `type <text>` | 输入文本 | `-d, --delay`, `--mistakes` |\n| `press <key>` | 按下按键 | - |\n| `key <key>` | `press` 的别名 | - |\n\n```typescript\nprogram\n  .command(\"type <text>\")\n  .description(\"Type text\")\n  .option(\"-d, --delay <ms>\", \"Delay between keystrokes\")\n  .option(\"--mistakes\", \"Enable human-like typing with mistakes\")\n```\n\n### 页面信息获取\n\n| 命令 | 说明 | 获取类型 |\n|------|------|----------|\n| `get <what> [selector]` | 获取页面信息 | `url`, `title`, `text`, `html`, `markdown`, `value`, `box`, `visible`, `checked` |\n\n```typescript\nprogram\n  .command(\"get <what> [selector]\")\n  .description(\n    \"Get page info: url, title, text, html, markdown, value, box, visible, checked\",\n  )\n```\n\n### 截图功能\n\n截图命令支持多种输出格式和裁剪选项：\n\n```typescript\nprogram\n  .command(\"screenshot [path]\")\n  .description(\"Take screenshot\")\n  .option(\"-f, --full-page\", \"Full page screenshot\")\n  .option(\"-t, --type <type>\", \"Image type: png, jpeg\", \"png\")\n  .option(\"-q, --quality <n>\", \"JPEG quality (0-100)\")\n  .option(\"--clip <json>\", \"Clip region as JSON\")\n  .option(\"--no-animations\", \"Disable animations\")\n  .option(\"--hide-caret\", \"Hide text caret\")\n```\n\nSources: [packages/cli/src/index.ts:220-280]()\n\n### 可访问性快照\n\n获取页面的可访问性树快照：\n\n```typescript\nprogram\n  .command(\"snapshot\")\n  .description(\"Get accessibility tree snapshot\")\n  .option(\"-c, --compact\", \"Output tree only (no xpath map)\")\n```\n\n快照返回结构包含：\n- `tree`: 格式化的可访问性树\n- `xpathMap`: 元素到 XPath 的映射\n- `urlMap`: URL 映射\n\nSources: [packages/cli/src/index.ts:290-310]()\n\n### 等待与状态检查\n\n| 命令 | 说明 | 状态值 |\n|------|------|--------|\n| `wait <type> [arg]` | 等待条件 | `load`, `selector`, `timeout` |\n| `is <check> <selector>` | 检查元素状态 | `visible`, `checked` |\n\n```typescript\nprogram\n  .command(\"wait <type> [arg]\")\n  .description(\"Wait for: load, selector, timeout\")\n  .option(\"-t, --timeout <ms>\", \"Timeout\", \"30000\")\n  .option(\"-s, --state <state>\", \"Element state: visible, hidden, attached, detached\", \"visible\")\n```\n\nSources: [packages/cli/src/index.ts:50-80]()\n\n### 视口控制\n\n```typescript\nprogram\n  .command(\"viewport <width> <height>\")\n  .description(\"Set viewport size\")\n  .option(\"-s, --scale <n>\", \"Device scale factor\", \"1\")\n```\n\n## 本地浏览器策略\n\nStagehand 支持多种本地浏览器启动策略，可通过配置灵活选择。\n\n### 策略类型\n\n| 策略 | 说明 | 适用场景 |\n|------|------|----------|\n| `isolated` | 启动独立的 Chromium 实例 | 完全隔离的自动化任务 |\n| `cdp` | 连接到指定的 Chrome DevTools Protocol 端点 | 复用已有浏览器会话 |\n| `auto` | 自动检测本地浏览器，无则启动隔离实例 | 通用场景 |\n\n```typescript\nexport async function resolveLocalStrategy({\n  localConfig,\n  headless,\n  defaultViewport,\n  discoverLocalCdp,\n  resolveWsTarget,\n}: ResolveLocalStrategyOptions): Promise<ResolvedLocalStrategy> {\n  if (localConfig.strategy === \"isolated\") {\n    return {\n      localLaunchOptions: { headless, viewport: defaultViewport },\n      localInfo: { localSource: \"isolated\" },\n    };\n  }\n\n  if (localConfig.strategy === \"cdp\") {\n    const cdpUrl = await resolveWsTarget(localConfig.cdpTarget);\n    return {\n      localLaunchOptions: { cdpUrl },\n      localInfo: { localSource: \"attached-explicit\", resolvedCdpUrl: cdpUrl },\n    };\n  }\n}\n```\n\nSources: [packages/cli/src/local-strategy.ts:1-80]()\n\n### CDP 自动发现\n\n系统支持自动发现本地运行的 Chrome 实例：\n\n```typescript\nasync function probeFallbackPort(port: number): Promise<string | null> {\n  const jsonVersionUrl = await probeJsonVersion(port);\n  if (jsonVersionUrl) {\n    return jsonVersionUrl;\n  }\n  // WebSocket fallback...\n}\n```\n\nSources: [packages/cli/src/local-cdp-discovery.ts:1-50]()\n\n### 本地模式提示\n\n根据不同的启动策略，系统会提供相应的使用提示：\n\n```typescript\nconst ISOLATED_MODE_HINT = \"Hint: Run `browse env local --auto-connect` to reuse your local browsing credentials and cookies.\";\nconst ATTACHED_EXISTING_HINT = \"Hint: Run `browse env local` without `--auto-connect` to switch back to an isolated Chromium browser.\";\n```\n\n## 网络捕获功能\n\nStagehand 提供完整的网络请求捕获和持久化能力。\n\n### 数据模型\n\n```typescript\ninterface PendingRequest {\n  id: string;\n  timestamp: string;\n  method: string;\n  url: string;\n  headers: Record<string, string>;\n  body: string | null;\n  resourceType: string;\n}\n```\n\n### 文件系统组织\n\n捕获的网络请求按以下结构存储：\n\n```\n{networkDir}/\n  {counter}-{method}-{domain}-{pathSlug}/\n    request.json   # 请求详情\n    response.json  # 响应详情\n```\n\n文件名生成逻辑：\n\n```typescript\nfunction getRequestDirName(\n  counter: number,\n  method: string,\n  url: string,\n): string {\n  const parsed = new URL(url);\n  const domain = sanitizeForFilename(parsed.hostname, 30);\n  const pathPart = parsed.pathname.split(\"/\").filter(Boolean)[0] || \"root\";\n  const pathSlug = sanitizeForFilename(pathPart, 20);\n  return `${String(counter).padStart(3, \"0\")}-${method}-${domain}-${pathSlug}`;\n}\n\nfunction sanitizeForFilename(str: string, maxLen: number = 30): string {\n  return str\n    .replace(/[^a-zA-Z0-9.-]/g, \"-\")\n    .replace(/-+/g, \"-\")\n    .replace(/^-|-$/g, \"\")\n    .slice(0, maxLen);\n}\n```\n\nSources: [packages/cli/src/index.ts:55-100]()\n\n## 全局配置选项\n\nCLI 支持通过全局选项配置会话和行为：\n\n```typescript\ninterface GlobalOpts {\n  ws?: string;              // WebSocket 连接地址\n  headless?: boolean;       // 无头模式\n  headed?: boolean;         // 有头模式（优先于 headless）\n  json?: boolean;           // JSON 输出格式\n  session?: string;         // 会话标识\n  connect?: string;         // 连接目标\n  proxies?: boolean;        // 启用代理（远程模式）\n  advancedStealth?: boolean; // 高级隐身模式\n  solveCaptchas?: boolean;   // 自动解决验证码\n  region?: string;          // 区域设置\n  keepAlive?: boolean;       // 保持连接\n  sessionTimeout?: number;   // 会话超时时间\n  blockAds?: boolean;       // 屏蔽广告\n}\n```\n\n## 守护进程生命周期管理\n\n### 启动与停止\n\n```typescript\nprogram\n  .command(\"start\")\n  .description(\"Start browser daemon\")\n  .action(async () => {\n    if (await isDaemonRunning(session)) {\n      console.log(JSON.stringify({ status: \"already running\", session }));\n      return;\n    }\n    await ensureDaemon(session, isHeadless(opts));\n  });\n\nprogram\n  .command(\"stop\")\n  .description(\"Stop browser daemon\")\n  .option(\"--force\", \"Force kill Chrome processes if daemon is unresponsive\")\n```\n\n### 自动重连机制\n\nCLI 实现了智能重连策略，在连接失败时自动尝试恢复：\n\n```typescript\n// Attempt 0: Brief wait and retry\nif (attempt === 0) {\n  await new Promise((r) => setTimeout(r, 200));\n  continue;\n}\n\n// Attempt 1: Try to restart daemon without cleanup\nif (attempt === 1) {\n  await ensureDaemon(session, headless);\n  continue;\n}\n\n// Final attempt: Full cleanup and restart\nawait killChromeProcesses(session);\nawait cleanupStaleFiles(session);\nawait ensureDaemon(session, headless);\n```\n\nSources: [packages/cli/src/index.ts:350-450]()\n\n## 命令执行流程\n\n```mermaid\nsequenceDiagram\n    participant CLI\n    participant Daemon\n    participant Browser\n    \n    CLI->>Daemon: sendCommand(command, args)\n    Daemon->>Browser: Execute action\n    Browser-->>Daemon: Result\n    Daemon-->>CLI: Return result\n    CLI->>CLI: output(result, json?)\n```\n\n命令执行的核心逻辑：\n\n```typescript\nasync function runCommand(\n  command: string,\n  args: unknown[],\n  retries: number = 3,\n): Promise<unknown> {\n  for (let attempt = 0; attempt < retries; attempt++) {\n    try {\n      return await sendCommand(session, command, args);\n    } catch (err) {\n      // Connection error handling...\n      if (attempt === 0) {\n        await new Promise((r) => setTimeout(r, 200));\n        continue;\n      }\n      await ensureDaemon(session, headless);\n    }\n  }\n}\n```\n\n## 快速入门\n\n### 基本导航\n\n```bash\n# 打开网页\nstagehand open https://example.com\n\n# 带等待状态\nstagehand open https://example.com --wait networkidle\n```\n\n### 元素交互\n\n```bash\n# 点击按钮\nstagehand click \"#submit-button\"\n\n# 填充表单\nstagehand fill \"input[name=email]\" \"user@example.com\"\nstagehand fill \"input[name=password]\" \"secret123\"\n```\n\n### 页面信息\n\n```bash\n# 获取页面标题\nstagehand get title\n\n# 获取元素文本\nstagehand get text \".article-content\"\n\n# 获取可访问性树\nstagehand snapshot\n```\n\n### 截图\n\n```bash\n# 普通截图\nstagehand screenshot output.png\n\n# 全页截图\nstagehand screenshot full-page.png --full-page\n\n# 指定区域\nstagehand screenshot cropped.png --clip '{\"x\":0,\"y\":0,\"width\":800,\"height\":600}'\n```\n\n## 总结\n\nStagehand 提供了一套完整的浏览器自动化解决方案，具有以下特点：\n\n1. **丰富的命令集**：覆盖导航、交互、信息获取、网络捕获等各方面\n2. **灵活的运行模式**：支持本地和远程两种部署方式\n3. **智能的策略选择**：可根据需求选择隔离、CDP 或自动模式\n4. **可靠的守护进程**：实现了进程锁和自动重连机制\n5. **详细的网络捕获**：支持完整的请求/响应持久化\n\n---\n\n<a id='quickstart'></a>\n\n## 快速开始\n\n### Related Pages\n\nRelated topics: [Stagehand 简介](#introduction), [系统架构总览](#architecture-overview)\n\n<details>\n<summary>Relevant source files</summary>\n\nThe following files were used as context for generating this wiki page:\n\n- [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n- [packages/cli/src/local-strategy.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-strategy.ts)\n- [packages/cli/src/local-cdp-discovery.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-cdp-discovery.ts)\n- [packages/cli/tsup.config.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/tsup.config.ts)\n</details>\n\n# 快速开始\n\nStagehand 是一个由 Browserbase 开发的浏览器自动化框架，提供 CLI 工具和 Core SDK 两种使用方式，支持本地浏览器和远程 Browserbase 云端浏览器的自动化操作。\n\n## 环境准备\n\n### 前置要求\n\n| 要求 | 说明 |\n|------|------|\n| Node.js | 版本 20+ |\n| Playwright | 用户需自行安装 `playwright` 或 `playwright-core` 包 |\n| 系统依赖 | Chrome/Chromium 浏览器（本地模式） |\n\n### 安装步骤\n\n```bash\n# 安装核心包\nnpm install @browserbasehq/stagehand\n\n# 安装 Playwright（必须）\nnpm install playwright\n\n# 安装浏览器驱动\nnpx playwright install chromium\n```\n\n### 环境变量配置\n\n在项目根目录创建 `.env` 文件，配置必要的环境变量：\n\n```bash\n# Browserbase 云端模式必需\nBROWSERBASE_API_KEY=your_api_key\nBROWSERBASE_PROJECT_ID=your_project_id\n\n# 本地模式可选配置\nBROWSERBASE_API_KEY=    # 留空则使用本地模式\n```\n\nSources: [.env.example](https://github.com/browserbase/stagehand/blob/main/.env.example)\n\n## CLI 快速上手\n\nStagehand CLI 提供丰富的浏览器自动化命令，安装后可通过 `npx stagehand` 或直接安装为全局命令使用。\n\n### 基础命令结构\n\n```bash\n# 基本语法\nstagehand [options] [command] [arguments]\n\n# 常用全局选项\n# --session <name>    指定会话名称\n# --headless         以无头模式运行\n# --connect <url>    连接到远程 Browserbase 会话\n# --json             以 JSON 格式输出结果\n```\n\nSources: [packages/cli/src/index.ts:1-50](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n### 导航与页面操作\n\n```bash\n# 打开网页\nstagehand open https://example.com\n\n# 等待页面加载完成\nstagehand open https://example.com --wait load\n\n# 页面加载超时设置（毫秒）\nstagehand open https://example.com --timeout 30000\n\n# 创建新标签页\nstagehand newpage https://example.com\n\n# 切换标签页（按索引）\nstagehand tab_switch 1\n\n# 关闭标签页\nstagehand tab_close\n```\n\nSources: [packages/cli/src/index.ts:200-260](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n## 元素交互\n\n### 常见交互命令\n\n| 命令 | 说明 | 示例 |\n|------|------|------|\n| `fill` | 填写输入框 | `stagehand fill \"#search\" \"关键词\"` |\n| `select` | 选择下拉选项 | `stagehand select \"#dropdown\" \"选项1\"` |\n| `click` | 点击元素 | `stagehand click \"#submit\"` |\n| `type` | 模拟键盘输入 | `stagehand type \"Hello World\"` |\n| `press` | 按下特定按键 | `stagehand press \"Enter\"` |\n\n### 填写表单示例\n\n```bash\n# 填写输入框（默认会按 Enter）\nstagehand fill \"#username\" \"myuser\"\nstagehand fill \"#password\" \"mypass\"\n\n# 不自动按 Enter\nstagehand fill \"#input\" \"value\" --no-press-enter\n\n# 输入延迟（模拟人工打字）\nstagehand type \"Hello\" --delay 100\n\n# 启用人工化输入（含随机错误）\nstagehand type \"Hello\" --mistakes\n```\n\nSources: [packages/cli/src/index.ts:150-200](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n### 键盘操作\n\n```bash\n# 按下按键\nstagehand press Enter\nstagehand press Tab\nstagehand press Escape\nstagehand press \"Cmd+A\"\n\n# 组合键示例\nstagehand press \"Cmd+C\"\n```\n\nSources: [packages/cli/src/index.ts:140-160](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n## 元素状态检查\n\n### 检查命令\n\n```bash\n# 检查元素是否可见\nstagehand is visible \"#submit-button\"\n\n# 检查复选框是否选中\nstagehand is checked \"#agree-checkbox\"\n```\n\n### 获取页面信息\n\n```bash\n# 获取页面 URL\nstagehand get url\n\n# 获取页面标题\nstagehand get title\n\n# 获取元素文本内容\nstagehand get text \"#heading\"\n\n# 获取元素 HTML\nstagehand get html \"#container\"\n\n# 获取元素 Markdown 格式内容\nstagehand get markdown \"#article\"\n\n# 获取元素值\nstagehand get value \"#input\"\n\n# 获取元素边界框\nstagehand get box \"#image\"\n\n# 获取可见性状态\nstagehand get visible \"#hidden-element\"\n```\n\nSources: [packages/cli/src/index.ts:280-320](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n## 等待与同步\n\n### 等待命令\n\n```bash\n# 等待页面加载\nstagehand wait load\n\n# 等待选择器出现\nstagehand wait selector \"#content\"\n\n# 等待超时（毫秒）\nstagehand wait selector \"#loading\" --timeout 10000\n\n# 等待元素状态\nstagehand wait selector \"#modal\" --state visible\nstagehand wait selector \"#tooltip\" --state hidden\nstagehand wait selector \"#element\" --state attached\n```\n\n状态选项：`visible`、`hidden`、`attached`、`detached`\n\nSources: [packages/cli/src/index.ts:50-80](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n## 截图与快照\n\n### 截图功能\n\n```bash\n# 基础截图\nstagehand screenshot\n\n# 保存到指定路径\nstagehand screenshot ./screenshot.png\n\n# 全页面截图\nstagehand screenshot ./full-page.png --full-page\n\n# 指定图片格式和质量\nstagehand screenshot ./output.jpg --type jpeg --quality 85\n\n# 裁剪区域（JSON 格式）\nstagehand screenshot ./cropped.png --clip '{\"x\":0,\"y\":0,\"width\":800,\"height\":600}'\n\n# 禁用动画和隐藏光标\nstagehand screenshot ./clean.png --no-animations --hide-caret\n```\n\nSources: [packages/cli/src/index.ts:340-380](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n### 辅助功能树快照\n\n```bash\n# 获取完整快照（含 XPath 映射）\nstagehand snapshot\n\n# 紧凑输出（仅树结构）\nstagehand snapshot --compact\n```\n\n快照输出包含：\n- `tree`: 格式化的辅助功能树\n- `xpathMap`: 元素到 XPath 的映射\n- `urlMap`: URL 引用映射\n\nSources: [packages/cli/src/index.ts:380-420](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n## 坐标操作\n\n### 鼠标操作\n\n```bash\n# 悬停到坐标位置\nstagehand hover 100 200\n\n# 悬停并返回元素 XPath\nstagehand hover 100 200 --xpath\n\n# 滚动页面\nstagehand scroll 0 500 0 100\n\n# 拖拽操作\nstagehand drag 100 200 300 400\n```\n\nSources: [packages/cli/src/index.ts:220-250](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n## 视图控制\n\n```bash\n# 设置视口大小\nstagehand viewport 1920 1080\n\n# 设置缩放比例\nstagehand viewport 1920 1080 --scale 2\n```\n\nSources: [packages/cli/src/index.ts:420-440](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n## Daemon 模式\n\nStagehand 使用守护进程模式管理浏览器实例，支持会话复用。\n\n### 进程管理命令\n\n```bash\n# 启动守护进程\nstagehand start\n\n# 停止守护进程\nstagehand stop\n\n# 强制停止（杀掉 Chrome 进程）\nstagehand stop --force\n\n# 检查状态\nstagehand status\n```\n\n### 会话管理\n\n```bash\n# 使用指定会话\nstagehand --session my-session open https://example.com\n\n# 远程模式会话超时\nstagehand --session my-session --session-timeout 300 open https://example.com\n```\n\nSources: [packages/cli/src/index.ts:450-520](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n## 本地模式策略\n\nStagehand CLI 支持多种本地浏览器模式：\n\n```mermaid\ngraph TD\n    A[开始解析本地策略] --> B{strategy 配置}\n    B -->|isolated| C[启动独立 Chromium 实例]\n    B -->|cdp| D[连接到指定 CDP 目标]\n    B -->|auto| E[自动检测本地浏览器]\n    E -->|发现调试端口| F[附加到现有浏览器]\n    E -->|未发现| G[回退到隔离模式]\n    \n    C --> H[返回 localSource: isolated]\n    D --> I[返回 localSource: attached-explicit]\n    F --> J[返回 localSource: attached-existing]\n    G --> K[返回 localSource: isolated-fallback]\n```\n\n| 策略 | 说明 | localSource 值 |\n|------|------|-----------------|\n| `isolated` | 启动独立的 Chromium 实例 | `isolated` |\n| `cdp` | 通过 CDP URL 连接到指定浏览器 | `attached-explicit` |\n| `auto` | 自动检测或回退 | `attached-existing` / `isolated-fallback` |\n\nSources: [packages/cli/src/local-strategy.ts:20-80](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-strategy.ts)\n\n## CDP 发现机制\n\n本地模式支持自动发现 Chrome DevTools 协议端点：\n\n```mermaid\ngraph LR\n    A[扫描用户数据目录] --> B{读取 DevToolsActivePort}\n    B -->|成功| C{检查端口可达性}\n    B -->|失败| D[尝试备用端口]\n    C -->|可达| E[构建 WebSocket URL]\n    C -->|不可达| D\n    D --> E\n    E --> F[返回 cdpUrl]\n```\n\nSources: [packages/cli/src/local-cdp-discovery.ts:1-60](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-cdp-discovery.ts)\n\n## 输出格式\n\n### JSON 输出模式\n\n```bash\n# 启用 JSON 输出\nstagehand get title --json\n\n# 示例输出\n{\n  \"success\": true,\n  \"data\": {\n    \"title\": \"Example Domain\"\n  }\n}\n```\n\n### 基础输出\n\n默认情况下，CLI 以人类可读格式输出结果：\n\n```bash\nstagehand get url\n# 输出: https://example.com\n\nstagehand snapshot --compact\n# 输出: 辅助功能树结构\n```\n\n## 网络请求捕获\n\nStagehand 支持捕获和分析网络请求：\n\n```mermaid\ngraph TD\n    A[请求进入] --> B{网络捕获启用?}\n    B -->|否| C[跳过]\n    B -->|是| D[记录请求元数据]\n    D --> E[等待响应]\n    E --> F[写入文件系统]\n    F --> G[生成目录结构]\n    \n    G --> H[request.json]\n    G --> I[response.json]\n```\n\n请求数据存储结构：\n```\n<networkDir>/\n  └── <counter>-<METHOD>-<domain>-<path>/\n      ├── request.json   # 请求详情\n      └── response.json  # 响应详情\n```\n\nSources: [packages/cli/src/index.ts:80-150](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n## 常见工作流示例\n\n### 自动化测试流程\n\n```bash\n# 1. 启动并导航\nstagehand open https://example.com --wait load\n\n# 2. 获取初始快照\nstagehand snapshot --compact > initial-state.txt\n\n# 3. 执行交互\nstagehand fill \"#search\" \"test query\"\nstagehand press Enter\n\n# 4. 等待结果加载\nstagehand wait selector \".results\" --timeout 10000\n\n# 5. 截图保存\nstagehand screenshot ./search-results.png\n\n# 6. 验证结果\nstagehand is visible \".result-item\"\n```\n\n### 数据采集流程\n\n```bash\n# 1. 导航到目标页面\nstagehand open https://news.example.com\n\n# 2. 截图存档\nstagehand screenshot ./news-$(date +%Y%m%d).png --full-page\n\n# 3. 获取内容\nstagehand get markdown \"article\"\n\n# 4. 关闭浏览器\nstagehand stop\n```\n\n## 故障排除\n\n| 问题 | 解决方案 |\n|------|----------|\n| 连接被拒绝 | 运行 `stagehand start` 启动守护进程 |\n| 浏览器未响应 | 使用 `stagehand stop --force` 强制停止 |\n| 超时错误 | 增加 `--timeout` 参数值 |\n| CDP 连接失败 | 检查 Chrome 是否以 `--remote-debugging-port` 启动 |\n\n### 查看详细日志\n\n```bash\n# 启用详细输出\nstagehand --verbose open https://example.com\n\n---\n\n<a id='architecture-overview'></a>\n\n## 系统架构总览\n\n### Related Pages\n\nRelated topics: [Stagehand 简介](#introduction), [Handler 处理系统](#handler-system)\n\n<details>\n<summary>Relevant source files</summary>\n\nThe following files were used as context for generating this wiki page:\n\n- [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n- [packages/cli/src/local-strategy.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-strategy.ts)\n- [packages/cli/src/local-cdp-discovery.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-cdp-discovery.ts)\n</details>\n\n# 系统架构总览\n\n## 1. 项目概述\n\nStagehand 是一个基于 Chrome DevTools Protocol (CDP) 的浏览器自动化 CLI 工具和 SDK，提供命令行界面和编程 API 两种交互方式。该项目采用 monorepo 结构，使用 pnpm workspace 管理多个包。\n\n核心能力包括：\n\n- 浏览器页面导航与交互\n- 元素定位与操作\n- 截图与 DOM 快照\n- 网络请求捕获\n- 本地浏览器发现与连接\n- Daemon 进程管理\n\nSources: [packages/cli/src/index.ts:1-50]()\n\n## 2. 整体架构\n\nStagehand 采用客户端-服务器架构，核心组件包括：\n\n```mermaid\ngraph TD\n    subgraph CLI层\n        A[CLI Commands] --> B[runCommand]\n        B --> C[runDaemon]\n    end\n    \n    subgraph 通信层\n        D[Unix Socket] <--> E[WebSocket Bridge]\n        F[Lock File] \n    end\n    \n    subgraph Daemon层\n        G[Browser Daemon] --> H[Playwright Page]\n        H --> I[Accessibility Snapshot]\n    end\n    \n    subgraph 本地发现\n        J[CDP Discovery] --> K[DevTools Active Port]\n        K --> L[WebSocket Target]\n    end\n    \n    A --> D\n    C --> D\n    G --> J\n```\n\nSources: [packages/cli/src/index.ts:200-300]()\n\n## 3. CLI 命令体系\n\nCLI 使用 commander.js 框架实现，所有命令都通过 `runCommand` 函数统一路由到 Daemon 进程执行。\n\n### 3.1 命令分类表\n\n| 类别 | 命令 | 功能描述 |\n|------|------|----------|\n| 导航 | `open`, `goto` | 页面导航 |\n| 元素 | `click`, `dblclick`, `hover` | 元素交互 |\n| 输入 | `fill`, `select`, `type`, `press` | 文本与选择操作 |\n| 查询 | `get`, `is`, `snapshot` | 页面信息获取 |\n| 截图 | `screenshot` | 页面截图 |\n| 坐标 | `scroll`, `drag` | 视口操作 |\n| 网络 | `network` | 网络请求捕获 |\n| 多页 | `pages`, `newpage` | 多标签页管理 |\n| 守护 | `start`, `stop`, `status` | Daemon 控制 |\n\nSources: [packages/cli/src/index.ts:50-200]()\n\n### 3.2 命令执行流程\n\n```mermaid\nsequenceDiagram\n    participant CLI as CLI Client\n    participant Socket as Unix Socket\n    participant Daemon as Browser Daemon\n    participant Browser as Playwright Browser\n    \n    CLI->>Socket: sendCommand(command, args)\n    Socket->>Daemon: 转发请求\n    Daemon->>Browser: 执行操作\n    Browser-->>Daemon: 返回结果\n    Daemon-->>Socket: 序列化响应\n    Socket-->>CLI: 返回结果\n    CLI->>CLI: output(result, json)\n```\n\nSources: [packages/cli/src/index.ts:300-400]()\n\n## 4. Daemon 基础设施\n\nDaemon 是长期运行的浏览器进程管理服务，通过 Unix Socket 与 CLI 通信。\n\n### 4.1 Socket 通信机制\n\n```typescript\n// Socket 路径: /tmp/browse-{session}.sock\nfunction getSocketPath(session: string): string {\n  return path.join(os.tmpdir(), `browse-${session}.sock`);\n}\n```\n\nSources: [packages/cli/src/index.ts:350-360]()\n\n### 4.2 文件锁机制\n\n系统使用 O_EXCL 模式的原子文件创建实现互斥锁，防止多进程竞争：\n\n```typescript\nasync function acquireLock(\n  session: string,\n  timeoutMs: number = 10000\n): Promise<boolean> {\n  const lockPath = getLockPath(session);\n  // O_EXCL 确保原子创建\n  const handle = await fs.open(lockPath, \"wx\");\n  await handle.write(String(process.pid));\n}\n```\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| session | string | \"default\" | 会话标识符 |\n| timeoutMs | number | 10000 | 锁等待超时 |\n\nSources: [packages/cli/src/index.ts:380-420]()\n\n### 4.3 连接重试策略\n\n当连接失败时，系统自动执行三级重试：\n\n| 重试次数 | 策略 | 动作 |\n|----------|------|------|\n| 0 | 短暂等待 | 等待 200ms 后重试 |\n| 1 | 重启 Daemon | 不清理状态重启 |\n| 2 | 完全清理 | 杀死进程、清理文件、重启 |\n\nSources: [packages/cli/src/index.ts:450-500]()\n\n## 5. 本地模式策略系统\n\n本地模式支持三种策略：`auto`、`isolated` 和 `cdp`。\n\n### 5.1 策略决策流程\n\n```mermaid\ngraph TD\n    A[resolveLocalStrategy] --> B{strategy === isolated?}\n    B -->|是| C[使用 headless + viewport]\n    B -->|否| D{strategy === cdp?}\n    D -->|是| E[解析 cdpTarget]\n    D -->|否| F[discoverLocalCdp]\n    F --> G{发现浏览器?}\n    G -->|是| H[连接现有浏览器]\n    G -->|否| I[isolated-fallback]\n```\n\nSources: [packages/cli/src/local-strategy.ts:30-70]()\n\n### 5.2 策略类型对比\n\n| 策略 | 说明 | 使用场景 |\n|------|------|----------|\n| `auto` | 自动发现或创建 | 默认模式，智能选择 |\n| `isolated` | 启动独立浏览器实例 | 完全隔离的环境 |\n| `cdp` | 连接到指定 CDP 端点 | 复用现有浏览器会话 |\n\nSources: [packages/cli/src/local-strategy.ts:10-50]()\n\n### 5.3 本地信息源\n\n| 来源类型 | 说明 | 提示信息 |\n|----------|------|----------|\n| `attached-existing` | 连接已存在的调试浏览器 | 提示使用 `--auto-connect` |\n| `attached-explicit` | 显式指定 CDP 目标 | - |\n| `isolated` | 独立启动的浏览器 | 提示切换到 attached 模式 |\n| `isolated-fallback` | 无法发现时的回退 | - |\n\nSources: [packages/cli/src/local-strategy.ts:50-80]()\n\n## 6. CDP 发现机制\n\nCDP (Chrome DevTools Protocol) 发现用于自动找到本地运行的 Chrome 浏览器实例。\n\n### 6.1 发现流程\n\n```mermaid\ngraph LR\n    A[读取 DevToolsActivePort] --> B{端口可达?}\n    B -->|否| C[cleanup 过期文件]\n    B -->|是| D[构建 WebSocket URL]\n    E[探测 JSON Version] --> F{成功?}\n    F -->|是| D\n    F -->|否| G[探测 WebSocket]\n```\n\nSources: [packages/cli/src/local-cdp-discovery.ts:100-150]()\n\n### 6.2 WebSocket 探测\n\n系统通过低层 TCP 握手检测 WebSocket 支持：\n\n```typescript\nasync function probeWebSocket(port: number): Promise<boolean> {\n  // 发送 HTTP Upgrade 请求\n  const response = await performWebSocketHandshake(port, wsKey);\n  // 检查 101 Switching Protocols 响应\n  return /^HTTP\\/1\\.[01] 101(?:\\s|$)/.test(response);\n}\n```\n\nSources: [packages/cli/src/local-cdp-discovery.ts:50-80]()\n\n## 7. 全局配置选项\n\nCLI 全局选项通过 `GlobalOpts` 接口定义：\n\n| 选项 | 类型 | 说明 |\n|------|------|------|\n| `--session` | string | 会话标识 |\n| `--headless` | boolean | 无头模式 |\n| `--headed` | boolean | 窗口模式 |\n| `--json` | boolean | JSON 输出 |\n| `--ws` | string | WebSocket 地址 |\n| `--connect` | string | 远程连接地址 |\n| `--proxies` | boolean | 启用代理 (远程) |\n| `--region` | string | 区域设置 (远程) |\n| `--block-ads` | boolean | 广告拦截 (远程) |\n\nSources: [packages/cli/src/index.ts:500-550]()\n\n## 8. 网络捕获系统\n\n系统提供完整的网络请求/响应捕获能力。\n\n### 8.1 捕获数据结构\n\n```typescript\ninterface PendingRequest {\n  id: string;\n  timestamp: string;\n  method: string;\n  url: string;\n  headers: Record<string, string>;\n  body: string | null;\n  resourceType: string;\n}\n```\n\n### 8.2 文件存储结构\n\n每个请求保存到独立目录：\n\n```\n{networkDir}/\n  └── {counter:3d}-{method}-{domain}-{pathSlug}/\n      ├── request.json   # 请求元数据\n      └── response.json  # 响应元数据\n```\n\nSources: [packages/cli/src/index.ts:100-180]()\n\n## 9. 页面信息获取\n\n`snapshot` 命令提供可访问性树快照功能：\n\n```typescript\ncase \"snapshot\": {\n  const snapshot = await page!.snapshot();\n  return {\n    tree: snapshot.formattedTree,\n    xpathMap: snapshot.xpathMap,\n    urlMap: snapshot.urlMap,\n  };\n}\n```\n\n| 输出字段 | 类型 | 说明 |\n|----------|------|------|\n| `tree` | string | 格式化的可访问性树 |\n| `xpathMap` | Record | 选择器到 XPath 的映射 |\n| `urlMap` | Record | 元素到 URL 的映射 |\n\nSources: [packages/cli/src/index.ts:250-280]()\n\n## 10. 关键技术栈\n\n| 组件 | 技术选型 |\n|------|----------|\n| CLI 框架 | commander.js |\n| 浏览器自动化 | Playwright |\n| 通信协议 | Unix Socket + WebSocket |\n| 包管理 | pnpm workspace |\n\nSources: [pnpm-workspace.yaml](https://github.com/browserbase/stagehand/blob/main/pnpm-workspace.yaml)()\n\n---\n\n<a id='act-api'></a>\n\n## act() 操作执行\n\n### Related Pages\n\nRelated topics: [observe() 页面观察](#observe-api), [extract() 数据提取](#extract-api), [Handler 处理系统](#handler-system)\n\n<details>\n<summary>Relevant source files</summary>\n\nThe following files were used as context for generating this wiki page:\n\n- [packages/core/lib/v3/handlers/actHandler.ts](https://github.com/browserbase/stagehand/blob/main/packages/core/lib/v3/handlers/actHandler.ts)\n- [packages/core/lib/v3/agent/tools/act.ts](https://github.com/browserbase/stagehand/blob/main/packages/core/lib/v3/agent/tools/act.ts)\n- [packages/core/lib/v3/agent/tools/click.ts](https://github.com/browserbase/stagehand/blob/main/packages/core/lib/v3/agent/tools/click.ts)\n- [packages/core/lib/v3/agent/tools/type.ts](https://github.com/browserbase/stagehand/blob/main/packages/core/lib/v3/agent/tools/type.ts)\n- [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n</details>\n\n# act() 操作执行\n\n## 概述\n\n`act()` 是 Stagehand 框架中的核心操作执行机制，负责将高级自然语言指令转换为具体的浏览器自动化操作。该系统通过 Handler-工具（Tool）架构模式，实现了操作意图识别、目标元素定位、操作执行和结果验证的完整流程。\n\n在 Stagehand 的 CLI 工具 `packages/cli/src/index.ts` 中，操作执行通过 `runCommand` 函数与浏览器守护进程通信，守护进程接收指令后调用相应的 Handler 处理逻辑。Sources: [packages/cli/src/index.ts:1-100]()\n\n## 架构设计\n\n### 核心组件关系\n\n```mermaid\ngraph TD\n    A[Agent / LLM] --> B[actHandler]\n    B --> C[工具选择]\n    C --> D[click.ts]\n    C --> E[type.ts]\n    C --> F[其他工具]\n    D --> G[ElementHandler]\n    E --> G\n    F --> G\n    G --> H[Playwright Page API]\n    H --> I[浏览器执行]\n    I --> J[结果验证]\n    J --> K[状态反馈]\n```\n\n### 执行流程\n\n| 阶段 | 组件 | 职责 |\n|------|------|------|\n| 意图解析 | actHandler.ts | 解析 LLM 生成的指令，提取操作类型和参数 |\n| 工具路由 | act.ts | 根据操作类型选择对应的工具模块 |\n| 元素定位 | 各工具模块 | 使用 XPath/CSS 选择器定位目标元素 |\n| 操作执行 | ElementHandler | 调用 Playwright API 执行具体操作 |\n| 结果验证 | Handler 返回值 | 返回执行结果和状态信息 |\n\nSources: [packages/core/lib/v3/handlers/actHandler.ts:1-50]()\nSources: [packages/core/lib/v3/agent/tools/act.ts:1-50]()\n\n## 操作类型\n\n### 元素交互操作\n\n#### click 点击操作\n\n`click` 操作用于模拟鼠标点击事件，支持多种变体：\n\n| 命令 | 描述 | 参数 |\n|------|------|------|\n| `click` | 点击元素 | selector, button, count, force |\n| `click_xy` | 坐标点击 | x, y, button, count |\n| `dblclick` | 双击 | selector |\n| `rightclick` | 右键菜单 | selector |\n\nCLI 实现示例：\n\n```typescript\nprogram\n  .command(\"click <selector>\")\n  .description(\"Click element\")\n  .option(\"-b, --button <btn>\", \"Mouse button\", \"left\")\n  .option(\"-c, --count <n>\", \"Click count\", \"1\")\n  .option(\"--force\", \"Force click\")\n  .option(\"--xpath\", \"Return XPath of clicked element\")\n  .action(async (selector: string, cmdOpts) => {\n    const opts = program.opts<GlobalOpts>();\n    const result = await runCommand(\"click\", [\n      selector,\n      {\n        button: cmdOpts.button,\n        clickCount: parseInt(cmdOpts.count),\n        force: cmdOpts.force,\n      },\n    ]);\n    output(result, opts.json ?? false);\n  });\n```\n\nSources: [packages/core/lib/v3/agent/tools/click.ts:1-80]()\nSources: [packages/cli/src/index.ts:200-250]()\n\n#### type 输入操作\n\n`type` 操作用于模拟键盘输入，支持人类化输入模式：\n\n| 选项 | 类型 | 描述 |\n|------|------|------|\n| `text` | string | 要输入的文本内容 |\n| `delay` | number | 击键间隔（毫秒） |\n| `mistakes` | boolean | 启用类人错误模拟 |\n\n```typescript\nprogram\n  .command(\"type <text>\")\n  .description(\"Type text\")\n  .option(\"-d, --delay <ms>\", \"Delay between keystrokes\")\n  .option(\"--mistakes\", \"Enable human-like typing with mistakes\")\n  .action(async (text: string, cmdOpts) => {\n    const result = await runCommand(\"type\", [\n      text,\n      {\n        delay: cmdOpts.delay ? parseInt(cmdOpts.delay) : undefined,\n        mistakes: cmdOpts.mistakes,\n      },\n    ]);\n  });\n```\n\nSources: [packages/core/lib/v3/agent/tools/type.ts:1-60]()\nSources: [packages/cli/src/index.ts:350-400]()\n\n#### fill 填充操作\n\n`fill` 专门用于填充表单输入框，默认在填充完成后按 Enter 键：\n\n| 参数 | 类型 | 描述 |\n|------|------|------|\n| `selector` | string | 输入框选择器 |\n| `value` | string | 填充值 |\n| `pressEnter` | boolean | 是否按 Enter 确认 |\n\nSources: [packages/cli/src/index.ts:280-330]()\n\n#### select 下拉选择\n\n`select` 用于选择下拉菜单选项：\n\n```typescript\nprogram\n  .command(\"select <selector> <values...>\")\n  .description(\"Select option(s)\")\n  .action(async (selector: string, values: string[]) => {\n    const result = await runCommand(\"select\", [selector, values]);\n  });\n```\n\n### 坐标操作\n\n#### hover 悬停\n\n悬停到指定坐标位置：\n\n```typescript\nprogram\n  .command(\"hover <x> <y>\")\n  .description(\"Hover at coordinates\")\n  .option(\"--xpath\", \"Return XPath of hovered element\")\n  .action(async (x: string, y: string, cmdOpts) => {\n    const result = await runCommand(\"hover\", [\n      parseFloat(x),\n      parseFloat(y),\n      { returnXPath: cmdOpts.xpath },\n    ]);\n  });\n```\n\n#### scroll 滚动\n\n在指定位置执行滚动操作：\n\n```typescript\nprogram\n  .command(\"scroll <x> <y> <deltaX> <deltaY>\")\n  .description(\"Scroll at coordinates\")\n  .option(\"--xpath\", \"Return XPath of scrolled element\")\n  .action(async (x: string, y: string, dx: string, dy: string, cmdOpts) => {\n    const result = await runCommand(\"scroll\", [\n      parseFloat(x),\n      parseFloat(y),\n      parseFloat(dx),\n      parseFloat(dy),\n      { returnXPath: cmdOpts.xpath },\n    ]);\n  });\n```\n\nSources: [packages/cli/src/index.ts:420-470]()\n\n### 键盘操作\n\n#### press 按键\n\n模拟按下指定键盘按键：\n\n| 参数 | 示例值 |\n|------|--------|\n| 修饰键 | Enter, Tab, Escape |\n| 组合键 | Cmd+A, Ctrl+C, Shift+Tab |\n| 功能键 | F1-F12 |\n\n```typescript\nprogram\n  .command(\"press <key>\")\n  .alias(\"key\")\n  .description(\"Press key (e.g., Enter, Tab, Escape, Cmd+A)\")\n  .action(async (key: string) => {\n    const result = await runCommand(\"press\", [key]);\n  });\n```\n\nSources: [packages/cli/src/index.ts:380-410]()\n\n### 状态检查操作\n\n#### is 检查元素状态\n\n验证元素的可见性或选中状态：\n\n```typescript\nprogram\n  .command(\"is <check> <selector>\")\n  .description(\"Check element state: visible, checked\")\n  .action(async (check: string, selector: string) => {\n    const result = await runCommand(\"is\", [check, selector]);\n  });\n```\n\n| 检查类型 | 描述 |\n|----------|------|\n| `visible` | 元素是否可见 |\n| `checked` | 复选框/单选框是否选中 |\n\n#### get 获取页面信息\n\n获取页面或元素的各类信息：\n\n```typescript\nprogram\n  .command(\"get <what> [selector]\")\n  .description(\n    \"Get page info: url, title, text, html, markdown, value, box, visible, checked\",\n  )\n  .action(async (what: string, selector?: string) => {\n    const result = await runCommand(\"get\", [what, selector]);\n  });\n```\n\nSources: [packages/cli/src/index.ts:490-520]()\n\n### 导航操作\n\n#### open 页面导航\n\n```typescript\nprogram\n  .command(\"open <url>\")\n  .alias(\"goto\")\n  .description(\"Navigate to URL\")\n  .option(\"--wait <state>\", \"Wait state: load, domcontentloaded, networkidle\")\n  .option(\"-t, --timeout <ms>\", \"Navigation timeout\", \"30000\")\n  .action(async (url: string, cmdOpts) => {\n    // 支持等待状态配置和超时控制\n  });\n```\n\nSources: [packages/cli/src/index.ts:560-620]()\n\n### 特殊操作\n\n#### wait 等待操作\n\n等待特定条件满足：\n\n```typescript\nprogram\n  .command(\"wait <type> [arg]\")\n  .description(\"Wait for: load, selector, timeout\")\n  .option(\"-t, --timeout <ms>\", \"Timeout\", \"30000\")\n  .option(\"-s, --state <state>\", \"Element state: visible, hidden, attached, detached\")\n  .action(async (type: string, arg: string | undefined, cmdOpts) => {\n    const result = await runCommand(\"wait\", [\n      type,\n      arg,\n      { timeout: parseInt(cmdOpts.timeout), state: cmdOpts.state },\n    ]);\n  });\n```\n\n| 等待类型 | 参数 | 描述 |\n|----------|------|------|\n| `load` | - | 等待页面加载 |\n| `selector` | 选择器 | 等待元素出现 |\n| `timeout` | 毫秒 | 等待指定时间 |\n\n#### eval JavaScript 执行\n\n在页面上下文中执行任意 JavaScript：\n\n```typescript\nprogram\n  .command(\"eval <expression>\")\n  .description(\"Evaluate JavaScript in page\")\n  .action(async (expr: string) => {\n    const result = await runCommand(\"eval\", [expr]);\n  });\n```\n\nSources: [packages/cli/src/index.ts:540-560]()\n\n## 执行上下文管理\n\n### Session 隔离机制\n\nStagehand 使用 Session 来隔离不同的浏览器上下文：\n\n```typescript\ninterface GlobalOpts {\n  ws?: string;\n  headless?: boolean;\n  headed?: boolean;\n  json?: boolean;\n  session?: string;\n  connect?: string;\n  proxies?: boolean;\n  advancedStealth?: boolean;\n  solveCaptchas?: boolean;\n  region?: string;\n  keepAlive?: boolean;\n  sessionTimeout?: number;\n  blockAds?: boolean;\n}\n\nfunction getSession(opts: GlobalOpts): string {\n  return opts.session ?? process.env.BROWSE_SESSION ?? \"default\";\n}\n```\n\nSources: [packages/cli/src/index.ts:700-750]()\n\n### 守护进程架构\n\nCLI 与浏览器守护进程之间通过 Unix Socket 进行通信：\n\n```mermaid\ngraph LR\n    A[CLI Client] -->|runCommand| B[Unix Socket]\n    B --> C[Daemon Process]\n    C --> D[Chrome DevTools Protocol]\n    D --> E[Browser Instance]\n```\n\n守护进程管理包括：\n\n| 功能 | 描述 |\n|------|------|\n| `start` | 启动浏览器守护进程 |\n| `stop` | 停止守护进程 |\n| `status` | 检查守护进程状态 |\n| `daemon` | 以守护进程模式运行 |\n\n```typescript\nprogram\n  .command(\"start\")\n  .description(\"Start browser daemon\")\n  .action(async () => {\n    const session = getSession(opts);\n    if (await isDaemonRunning(session)) {\n      console.log(JSON.stringify({ status: \"already running\", session }));\n      return;\n    }\n    await ensureDaemon(session, isHeadless(opts));\n  });\n```\n\nSources: [packages/cli/src/index.ts:620-680]()\n\n## 操作执行重试机制\n\n当命令执行失败时，系统会自动进行重试：\n\n```typescript\nasync function sendCommand(\n  session: string,\n  command: string,\n  args: unknown[],\n  headless: boolean,\n  retries: number = 3,\n): Promise<unknown> {\n  for (let attempt = 0; attempt <= retries; attempt++) {\n    try {\n      return await sendCommandOnce(session, command, args);\n    } catch (err) {\n      if (attempt === retries || command === \"stop\") {\n        throw err;\n      }\n\n      const errMsg = err instanceof Error ? err.message : String(err);\n      const isConnectionError =\n        errMsg.includes(\"ENOENT\") ||\n        errMsg.includes(\"ECONNREFUSED\") ||\n        errMsg.includes(\"Connection failed\");\n\n      if (!isConnectionError) {\n        throw err;\n      }\n\n      // 重试策略\n      if (attempt === 0) {\n        await new Promise((r) => setTimeout(r, 200));\n        continue;\n      }\n      if (attempt === 1) {\n        await ensureDaemon(session, headless);\n        continue;\n      }\n\n      await killChromeProcesses(session);\n      await cleanupStaleFiles(session);\n      await ensureDaemon(session, headless);\n    }\n  }\n}\n```\n\n| 重试次数 | 策略 | 原因 |\n|----------|------|------|\n| 0 | 短暂等待后重试 | Socket 可能暂时不可用 |\n| 1 | 重启守护进程 | 守护进程可能无响应 |\n| 2 | 清理并完全重启 | 清理残留状态 |\n\nSources: [packages/cli/src/index.ts:800-870]()\n\n## 输出格式\n\n操作执行结果支持两种输出格式：\n\n| 模式 | 触发方式 | 输出内容 |\n|------|----------|----------|\n| 标准输出 | 默认 | 格式化的人类可读输出 |\n| JSON 模式 | `--json` 选项 | 结构化 JSON 数据 |\n\n```typescript\nfunction output(result: unknown, asJson: boolean): void {\n  if (asJson) {\n    console.log(JSON.stringify(result, null, 2));\n  } else {\n    // 格式化输出\n    console.log(result);\n  }\n}\n```\n\n## 总结\n\n`act()` 操作执行系统是 Stagehand 自动化能力的核心，它通过以下设计实现：\n\n1. **分层架构**：Handler 层负责指令解析，工具层负责具体操作\n2. **灵活的命令路由**：CLI 通过统一的 `runCommand` 接口支持多种操作类型\n3. **健壮的错误处理**：自动重试机制和详细的错误信息\n4. **会话隔离**：通过 Session 实现多任务并行执行\n5. **丰富的操作类型**：覆盖点击、输入、导航、状态检查等常见自动化场景\n\n---\n\n<a id='extract-api'></a>\n\n## extract() 数据提取\n\n### Related Pages\n\nRelated topics: [act() 操作执行](#act-api), [observe() 页面观察](#observe-api), [Handler 处理系统](#handler-system)\n\n<details>\n<summary>Relevant source files</summary>\n\nThe following files were used as context for generating this wiki page:\n\n- [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n- [packages/cli/src/local-strategy.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-strategy.ts)\n- [packages/cli/src/local-cdp-discovery.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-cdp-discovery.ts)\n- [packages/core/lib/v3/handlers/extractHandler.ts](https://github.com/browserbase/stagehand/blob/main/packages/core/lib/v3/handlers/extractHandler.ts)\n- [packages/core/lib/v3/agent/tools/extract.ts](https://github.com/browserbase/stagehand/blob/main/packages/core/lib/v3/agent/tools/extract.ts)\n- [packages/core/lib/zodCompat.ts](https://github.com/browserbase/stagehand/blob/main/packages/core/lib/zodCompat.ts)\n</details>\n\n# extract() 数据提取\n\n## 概述\n\n`extract()` 是 Stagehand 框架中的核心数据提取方法，允许开发者从网页内容中提取结构化数据。该功能通过 Zod schema 定义期望的数据结构，由 AI 模型智能解析页面内容并返回类型安全的提取结果。\n\n## 核心功能\n\n### 1. Schema 驱动的数据提取\n\nStagehand 使用 Zod 作为数据验证和类型定义的基础。开发者可以通过 Zod schema 定义期望的输出结构：\n\n```typescript\nimport { extract } from \"@browserbase/stagehand\";\nimport { z } from \"zod\";\n\nconst schema = z.object({\n  title: z.string(),\n  price: z.number(),\n  inStock: z.boolean(),\n});\n\nconst result = await extract(page, { \n  instruction: \"提取产品名称、价格和库存状态\",\n  schema \n});\n```\n\n### 2. 指令引导的提取\n\n`extract()` 方法支持自然语言指令，让 AI 模型理解需要提取哪些信息：\n\n| 参数 | 类型 | 描述 |\n|------|------|------|\n| `instruction` | `string` | 描述需要提取的数据的自然语言指令 |\n| `schema` | `ZodSchema` | 定义提取数据的 Zod schema |\n| `maxTokens` | `number` | 最大响应 token 数（可选） |\n\n## 工作流程\n\n```mermaid\ngraph TD\n    A[调用 extract] --> B[解析 Zod Schema]\n    B --> C[生成 AI Prompt]\n    C --> D[执行 DOM 解析]\n    D --> E[提取匹配数据]\n    E --> F[Schema 验证]\n    F --> G{验证通过?}\n    G -->|是| H[返回结构化数据]\n    G -->|否| I[抛出验证错误]\n```\n\n## 与 Zod 的集成\n\nStagehand 通过 `zodCompat.ts` 实现与 Zod 的深度集成：\n\n```typescript\n// packages/core/lib/zodCompat.ts\nimport { z } from \"zod\";\n\n// 支持的 Zod 类型映射\nconst typeMap = {\n  string: \"text\",\n  number: \"number\", \n  boolean: \"boolean\",\n  array: \"array\",\n  object: \"object\",\n};\n```\n\n### 支持的 Zod 类型\n\n| Zod 类型 | 提取行为 | 说明 |\n|----------|----------|------|\n| `z.string()` | 文本提取 | 返回 DOM 元素的文本内容 |\n| `z.number()` | 数值提取 | 解析文本中的数字 |\n| `z.boolean()` | 布尔提取 | 识别 yes/no、true/false 等 |\n| `z.array(z.string())` | 列表提取 | 返回多个匹配元素 |\n| `z.object({...})` | 嵌套对象 | 递归提取复杂结构 |\n\n## 错误处理\n\n```mermaid\ngraph LR\n    A[提取操作] --> B{执行结果}\n    B -->|成功| C[返回数据]\n    B -->|验证失败| D[ZodError]\n    B -->|超时| E[TimeoutError]\n    B -->|无匹配| F[NoMatchError]\n```\n\n### 常见错误类型\n\n| 错误类型 | 描述 | 处理方式 |\n|----------|------|----------|\n| `ValidationError` | Schema 验证失败 | 检查 schema 定义 |\n| `TimeoutError` | 操作超时 | 增加 timeout 参数 |\n| `NoMatchError` | 未找到匹配元素 | 调整选择器或指令 |\n\n## 使用示例\n\n### 基本用法\n\n```typescript\nimport { stagehand } from \"@browserbase/stagehand\";\nimport { z } from \"zod\";\n\nconst page = await stagehand.init();\n\nconst product = await page.extract({\n  instruction: \"提取产品标题和价格\",\n  schema: z.object({\n    title: z.string(),\n    price: z.number(),\n  }),\n});\n\nconsole.log(product);\n// { title: \"iPhone 15 Pro\", price: 999 }\n```\n\n### 复杂嵌套结构\n\n```typescript\nconst schema = z.object({\n  products: z.array(z.object({\n    name: z.string(),\n    price: z.number(),\n    variants: z.array(z.object({\n      color: z.string(),\n      inStock: z.boolean(),\n    })),\n  })),\n  totalResults: z.number(),\n});\n\nconst data = await page.extract({\n  instruction: \"提取所有产品及其变体信息\",\n  schema,\n});\n```\n\n## 与其他模块的协同\n\n```mermaid\ngraph TD\n    subgraph 核心模块\n        A[extractHandler.ts]\n        B[extract.ts]\n        C[zodCompat.ts]\n    end\n    \n    subgraph 依赖关系\n        D[snapshot 获取 DOM]\n        E[AI 模型解析]\n        F[Zod 验证]\n    end\n    \n    A --> B\n    B --> C\n    A --> D\n    A --> E\n    A --> F\n    \n    style A fill:#e1f5fe\n    style B fill:#fff3e0\n    style C fill:#e8f5e9\n```\n\n## 配置选项\n\n| 选项 | 默认值 | 描述 |\n|------|--------|------|\n| `timeout` | `30000` | 操作超时时间（毫秒） |\n| `retries` | `3` | 失败重试次数 |\n| `model` | `gpt-4o` | 使用的 AI 模型 |\n| `verbose` | `false` | 启用详细日志 |\n\n## 最佳实践\n\n1. **使用精确的指令**：指令越具体，提取结果越准确\n2. **选择合适的 Schema**：避免过于复杂的嵌套结构\n3. **处理可选字段**：使用 `z.string().optional()` 处理可能缺失的字段\n4. **设置合理的超时**：复杂页面需要更长超时时间\n5. **验证返回数据**：即使通过 schema 验证，也建议进行运行时检查\n\n## 相关资源\n\n- [Stagehand 官方文档](https://docs.browserbase.com/stagehand)\n- [Zod 官方文档](https://zod.dev)\n- [Browserbase 平台](https://browserbase.com)\n\n---\n\n<a id='observe-api'></a>\n\n## observe() 页面观察\n\n### Related Pages\n\nRelated topics: [act() 操作执行](#act-api), [extract() 数据提取](#extract-api), [DOM 与无障碍树](#dom-accessibility)\n\n<details>\n<summary>Relevant source files</summary>\n\nThe following files were used as context for generating this wiki page:\n\n- [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n- [packages/cli/src/local-strategy.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-strategy.ts)\n- [packages/cli/src/local-cdp-discovery.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-cdp-discovery.ts)\n</details>\n\n# observe() 页面观察\n\n## 概述\n\n`observe()` 是 stagehand 框架中的核心页面观察功能，用于实时捕获和分析网页的当前状态。该功能通过无障碍树（Accessibility Tree）快照机制，获取页面的 DOM 结构、元素属性、位置信息等关键数据，为 AI 代理提供理解和操作网页的能力。\n\n页面观察功能在架构中扮演着\"感知层\"的角色，是连接浏览器渲染结果与 AI 决策引擎的关键桥梁。通过标准化的快照格式，系统能够将复杂的 DOM 结构转化为 AI 可理解的语义化表示。\n\n## 核心组件\n\n### Snapshot 快照系统\n\n快照系统负责从浏览器页面提取无障碍信息，生成结构化的页面描述。\n\n| 组件 | 职责 | 输出格式 |\n|------|------|----------|\n| `capture.ts` | 底层无障碍数据采集 | 原始 AX 节点树 |\n| `index.ts` | 快照格式化与映射构建 | 树形结构 + XPath/URL 映射 |\n\n快照系统的工作流程：\n\n```mermaid\ngraph TD\n    A[浏览器页面] --> B[Playwright snapshot API]\n    B --> C[原始 AX 节点]\n    C --> D[格式化处理]\n    D --> E[formattedTree 树形输出]\n    D --> F[xpathMap XPath 映射]\n    D --> G[urlMap URL 映射]\n```\n\n### Observe Handler 处理层\n\n`observeHandler.ts` 实现了页面观察的核心逻辑，负责协调快照采集、结果处理和错误管理。\n\n处理流程包含以下关键阶段：\n\n1. **初始化阶段** - 验证观察上下文和目标页面\n2. **采集阶段** - 调用底层快照 API 获取无障碍树\n3. **处理阶段** - 格式化节点数据，构建引用映射\n4. **返回阶段** - 输出结构化的观察结果\n\n### CLI 集成接口\n\n在 CLI 工具中，`snapshot` 命令提供了直接调用观察功能的入口：\n\n```typescript\nprogram\n  .command(\"snapshot\")\n  .description(\"Get accessibility tree snapshot\")\n  .option(\"-c, --compact\", \"Output tree only (no xpath map)\")\n```\n\n输出格式示例：\n\n```json\n{\n  \"tree\": \"页面元素的树形文本表示\",\n  \"xpathMap\": {\n    \"elementRef1\": \"/html/body/div[1]/button[2]\",\n    \"elementRef2\": \"/html/body/main/section[1]\"\n  },\n  \"urlMap\": {\n    \"linkRef1\": \"https://example.com/page\",\n    \"linkRef2\": \"https://api.example.com/data\"\n  }\n}\n```\n\n## 快照数据模型\n\n### 节点结构\n\n每个无障碍树节点包含以下核心属性：\n\n| 属性 | 类型 | 描述 |\n|------|------|------|\n| `role` | string | 元素的 ARIA 角色 |\n| `name` | string | 元素的辅助名称 |\n| `value` | string | 元素的值属性 |\n| `description` | string | 元素的描述信息 |\n| `state` | string[] | 元素状态数组 |\n| `children` | Node[] | 子节点列表 |\n\n### 引用映射机制\n\n系统维护两套关键映射表：\n\n**XPath 映射** - 将内部引用转换为 XPath 表达式，支持精确定位 DOM 元素\n**URL 映射** - 记录页面中的链接和资源 URL，便于后续操作\n\n```mermaid\ngraph LR\n    A[snapshot 结果] --> B[tree 格式化文本]\n    A --> C[xpathMap 引用表]\n    A --> D[urlMap URL 表]\n    C --> E[click 元素定位]\n    C --> F[fill 输入定位]\n    D --> G[navigate 链接访问]\n```\n\n## 配置选项\n\n### 紧凑模式 (Compact Mode)\n\n使用 `--compact` 或 `-c` 选项时，快照输出仅包含树形结构，不包含映射表：\n\n```bash\nbrowse snapshot --compact\n```\n\n适用于需要快速查看页面结构的场景，减少输出量。\n\n### 全局输出控制\n\n| 选项 | 说明 | 默认值 |\n|------|------|--------|\n| `--json` | 输出完整 JSON 格式 | false |\n| 紧凑模式 | 仅输出树形文本 | false |\n\n## 与其他模块的协作\n\n### 无障碍树采集 (capture.ts)\n\n底层采集模块通过 Playwright 的 `snapshot()` 方法获取页面的无障碍表示。该模块负责：\n\n- 遍历 DOM 节点构建 AX 树\n- 提取元素的语义化信息\n- 过滤无关的内部节点\n\n### 本地模式发现 (local-cdp-discovery.ts)\n\n页面观察功能依赖于与浏览器实例的 CDP 连接。CDP 发现机制确保 CLI 能够正确连接到本地或远程浏览器实例：\n\n```mermaid\ngraph TD\n    A[启动浏览器] --> B[CDP 端口检测]\n    B --> C{发现可用端口}\n    C -->|成功| D[建立 WebSocket 连接]\n    C -->|失败| E[使用默认端口]\n    D --> F[初始化 snapshot 服务]\n```\n\n### 本地策略解析 (local-strategy.ts)\n\n根据配置策略，系统选择合适的浏览器连接方式：\n\n| 策略 | 说明 | 适用场景 |\n|------|------|----------|\n| `isolated` | 独立 Chromium 实例 | 默认隔离环境 |\n| `cdp` | 连接到已有浏览器 | 复用已有会话 |\n| `auto` | 自动发现可用浏览器 | 智能选择 |\n\n## 使用场景\n\n### 1. 页面状态分析\n\n在执行自动化操作前，先观察页面结构：\n\n```bash\nbrowse open https://example.com\nbrowse snapshot\n```\n\n### 2. 元素定位验证\n\n通过 XPath 映射验证元素选择器的正确性：\n\n```bash\nbrowse snapshot --json\n# 检查 xpathMap 中的路径是否与预期匹配\n```\n\n### 3. AI 代理感知\n\n为 AI 代理提供页面状态的语义化表示，支持决策制定：\n\n```json\n{\n  \"tree\": \"form\\n  input[name='username']\\n  input[name='password']\\n  button[type='submit']\",\n  \"xpathMap\": {\n    \"username\": \"/html/body/form/input[1]\",\n    \"password\": \"/html/body/form/input[2]\",\n    \"submit\": \"/html/body/form/button\"\n  }\n}\n```\n\n## 技术规格\n\n### 性能特性\n\n| 指标 | 典型值 | 说明 |\n|------|--------|------|\n| 采集延迟 | < 100ms | 中等复杂度页面 |\n| 树深度限制 | 无 | 完整遍历 |\n| 输出大小 | 10KB - 500KB | 取决于页面复杂度 |\n\n### 错误处理\n\n观察功能实现了完善的错误处理机制：\n\n- **连接失败** - 自动重试并清理陈旧状态\n- **超时处理** - 默认 30 秒超时保护\n- **部分失败** - 返回已采集的部分数据\n\n## 总结\n\n`observe()` 页面观察功能是 stagehand 框架的感知核心，通过标准化的无障碍树快照机制，将网页的视觉和语义信息转化为 AI 可理解的结构化数据。该功能与 CLI 工具、CDP 连接层、本地策略模块紧密协作，为浏览器自动化操作提供了稳定、可靠的页面状态感知能力。\n\n---\n\n**Sources:** [packages/cli/src/index.ts:280-320](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts) | [packages/cli/src/local-strategy.ts:1-100](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-strategy.ts) | [packages/cli/src/local-cdp-discovery.ts:1-80](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-cdp-discovery.ts)\n\n---\n\n<a id='agent-system'></a>\n\n## Agent 代理系统\n\n### Related Pages\n\nRelated topics: [Handler 处理系统](#handler-system)\n\n<details>\n<summary>Relevant source files</summary>\n\nThe following files were used as context for generating this wiki page:\n\n- [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n- [packages/cli/src/local-strategy.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-strategy.ts)\n- [packages/cli/src/local-cdp-discovery.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-cdp-discovery.ts)\n\n> **注意**：用户请求的 Agent 系统核心文件（如 `packages/core/lib/v3/agent/AgentClient.ts`、`AgentProvider.ts` 等）未包含在提供的上下文中。本页面基于 CLI 与 Agent 系统交互的代码进行分析。\n\n</details>\n\n# Agent 代理系统\n\n## 概述\n\nStagehand 的 Agent 代理系统是浏览器自动化操作的核心引擎，负责管理浏览器会话、执行自动化命令、处理网络请求捕获以及维护浏览器状态。该系统通过 CLI 接口和核心库协同工作，为 AI 代理提供可观测、可控制的浏览器操作能力。\n\n## 系统架构\n\n### 整体架构图\n\n```mermaid\ngraph TD\n    subgraph CLI层 [\"CLI 接口层\"]\n        CLI[packages/cli/src/index.ts]\n        Cmds[命令定义]\n    end\n    \n    subgraph Agent核心 [\"Agent 核心系统\"]\n        AC[AgentClient]\n        AP[AgentProvider]\n        Handler[v3AgentHandler]\n        ActionMap[actionMapping]\n    end\n    \n    subgraph Daemon层 [\"Daemon 守护进程\"]\n        Socket[Unix Socket]\n        Chrome[Chrome Browser]\n        CDP[CDP Protocol]\n    end\n    \n    CLI --> Cmds\n    Cmds --> AC\n    AC --> AP\n    AP --> Handler\n    Handler --> ActionMap\n    ActionMap --> Socket\n    Socket --> Chrome\n    Chrome --> CDP\n    \n    LocalCDP[local-cdp-discovery] --> AP\n    LocalStrat[local-strategy.ts] --> AP\n```\n\n## 核心组件\n\n### 1. CLI 命令接口层\n\nCLI 层定义了所有与浏览器交互的命令，通过 `runCommand` 函数与 Agent 系统通信。\n\n**主要命令类别**：\n\n| 类别 | 命令 | 功能 |\n|------|------|------|\n| 导航 | `open`, `goto` | 打开 URL |\n| 元素操作 | `click`, `fill`, `select`, `upload` | 操作页面元素 |\n| 状态检查 | `is`, `wait`, `get` | 检查元素状态 |\n| 键盘鼠标 | `type`, `press`, `hover`, `scroll`, `drag` | 模拟输入 |\n| 网络 | `network on/off`, `network path` | 网络请求捕获 |\n| 截图 | `screenshot` | 页面截图 |\n| 快照 | `snapshot` | 辅助功能树快照 |\n| 标签页 | `pages`, `newpage`, `closepage` | 多标签管理 |\n\n### 2. Daemon 守护进程管理\n\nDaemon 系统负责管理浏览器实例的生命周期。\n\n```typescript\n// Socket 路径配置\nconst SOCKET_DIR = os.tmpdir();\n\nfunction getSocketPath(session: string): string {\n  return path.join(SOCKET_DIR, `browse-${session}.sock`);\n}\n\nfunction getLockPath(session: string): string {\n  return path.join(SOCKET_DIR, `browse-${session}.lock`);\n}\n```\n\n**Daemon 启动流程**：\n\n```mermaid\nsequenceDiagram\n    participant CLI\n    participant Lock\n    participant Daemon\n    participant Chrome\n    \n    CLI->>Lock: acquireLock(session)\n    Lock-->>CLI: 锁定成功\n    CLI->>Daemon: ensureDaemon(session, headless)\n    Daemon->>Chrome: 启动/连接 Chrome\n    Chrome-->>Daemon: WebSocket Ready\n    Daemon->>Lock: releaseLock(session)\n```\n\n**关键特性**：\n- 基于 `O_EXCL` 的原子文件锁机制防止竞态条件\n- 自动检测并清理陈旧的锁文件\n- 支持会话超时自动清理\n\n### 3. 本地模式策略\n\nAgent 支持多种本地浏览器连接策略，由 `local-strategy.ts` 定义。\n\n| 策略 | 说明 | 用途 |\n|------|------|------|\n| `isolated` | 启动独立 Chromium 实例 | 完全隔离的浏览器环境 |\n| `cdp` | 连接到指定 CDP 目标 | 复用已有浏览器会话 |\n| `auto` | 自动检测可用浏览器 | 优先复用，无则创建新实例 |\n\n```typescript\n// Sources: packages/cli/src/local-strategy.ts:18-37\nexport async function resolveLocalStrategy({\n  localConfig,\n  headless,\n  defaultViewport,\n  discoverLocalCdp,\n  resolveWsTarget,\n}: ResolveLocalStrategyOptions): Promise<ResolvedLocalStrategy>\n```\n\n### 4. CDP 发现机制\n\n通过 `local-cdp-discovery.ts` 实现 Chrome DevTools Protocol 端点的自动发现。\n\n```mermaid\ngraph LR\n    A[读取 DevToolsActivePort] --> B{端口可达性检查}\n    B -->|可达| C[构建 WebSocket URL]\n    B -->|不可达| D[清理陈旧文件]\n    C --> E[返回 CDP URL]\n    D --> E\n```\n\n**发现流程**：\n1. 扫描用户数据目录（`userDataDirs`）\n2. 读取 `DevToolsActivePort` 文件获取端口信息\n3. 验证端口可达性\n4. 构建 WebSocket 连接 URL\n\n## 网络捕获系统\n\n### 网络请求监控\n\nAgent 系统提供完整的网络请求捕获能力，捕获结果写入文件系统供 Agent 检查。\n\n```typescript\n// Sources: packages/cli/src/index.ts:88-103\ninterface PendingRequest {\n  id: string;\n  timestamp: string;\n  method: string;\n  url: string;\n  headers: Record<string, string>;\n  body: string | null;\n  resourceType: string;\n}\n```\n\n### 目录结构\n\n```\n{networkDir}/\n├── {counter}-{method}-{domain}-{pathSlug}/\n│   ├── request.json    # 请求详情\n│   └── response.json   # 响应详情\n```\n\n### 文件名生成规则\n\n```typescript\n// Sources: packages/cli/src/index.ts:95-120\nfunction getRequestDirName(\n  counter: number,\n  method: string,\n  url: string,\n): string {\n  const parsed = new URL(url);\n  const domain = sanitizeForFilename(parsed.hostname, 30);\n  const pathPart = parsed.pathname.split(\"/\").filter(Boolean)[0] || \"root\";\n  const pathSlug = sanitizeForFilename(pathPart, 20);\n  return `${String(counter).padStart(3, \"0\")}-${method}-${domain}-${pathSlug}`;\n}\n```\n\n## 命令执行流程\n\n### runCommand 执行机制\n\n```mermaid\ngraph TD\n    Start[CLI Command] --> Check{连接状态检查}\n    Check -->|正常| Execute[发送命令]\n    Check -->|连接错误| Retry{重试策略}\n    \n    Retry -->|Attempt 0| Wait[等待 200ms]\n    Wait --> Execute\n    \n    Retry -->|Attempt 1| Restart[重启 Daemon]\n    Restart --> Execute\n    \n    Retry -->|Attempt 2| Cleanup[清理并重启]\n    Cleanup --> Execute\n    \n    Execute --> Success[返回结果]\n    Execute --> Error[抛出错误]\n```\n\n**错误重试策略**：\n\n| 重试次数 | 策略 | 条件 |\n|----------|------|------|\n| 0 | 短暂等待 | `ENOENT`, `ECONNREFUSED`, `Connection failed` |\n| 1 | 重启 Daemon | 同上 |\n| 2 | 完整清理 | 杀死 Chrome 进程 + 清理文件 + 重启 |\n\n## 会话管理\n\n### GlobalOpts 配置选项\n\n| 选项 | 类型 | 说明 |\n|------|------|------|\n| `ws` | `string` | WebSocket 端点 |\n| `headless` | `boolean` | 无头模式 |\n| `headed` | `boolean` | 显示浏览器窗口 |\n| `json` | `boolean` | JSON 格式输出 |\n| `session` | `string` | 会话标识符 |\n| `connect` | `string` | 连接模式 |\n| `proxies` | `boolean` | 启用代理 (远程) |\n| `advancedStealth` | `boolean` | 高级隐身模式 |\n| `solveCaptchas` | `boolean` | 自动解验证码 |\n| `region` | `string` | 区域设置 (远程) |\n| `keepAlive` | `boolean` | 保持连接活跃 |\n| `sessionTimeout` | `number` | 会话超时秒数 |\n| `blockAds` | `boolean` | 广告拦截 |\n\n### 会话参数构建\n\n```typescript\n// Sources: packages/cli/src/index.ts:520-545\nfunction buildSessionParamsFromOpts(\n  opts: GlobalOpts,\n): Record<string, unknown> | null {\n  const params: Record<string, unknown> = {};\n  const browserSettings: Record<string, unknown> = {};\n\n  if (opts.proxies) params.proxies = true;\n  if (opts.region) params.region = opts.region;\n  if (opts.keepAlive) params.keepAlive = true;\n  if (opts.sessionTimeout !== undefined) params.timeout = opts.sessionTimeout;\n\n  if (opts.advancedStealth) browserSettings.advancedStealth = true;\n  if (opts.blockAds) browserSettings.blockAds = true;\n  // ...\n}\n```\n\n## 命令实现示例\n\n### 元素操作命令\n\n```typescript\n// Sources: packages/cli/src/index.ts:185-200\nprogram\n  .command(\"fill <selector> <value>\")\n  .description(\"Fill input element (presses Enter by default)\")\n  .option(\"--no-press-enter\", \"Don't press Enter after filling\")\n  .action(async (selector: string, value: string, cmdOpts) => {\n    const pressEnter = cmdOpts.pressEnter !== false;\n    const result = await runCommand(\"fill\", [\n      selector,\n      value,\n      { pressEnter },\n    ]);\n    output(result, opts.json ?? false);\n  });\n```\n\n### 截图命令\n\n```typescript\n// Sources: packages/cli/src/index.ts:320-345\nprogram\n  .command(\"screenshot [path]\")\n  .description(\"Take screenshot\")\n  .option(\"-f, --full-page\", \"Full page screenshot\")\n  .option(\"-t, --type <type>\", \"Image type: png, jpeg\", \"png\")\n  .option(\"-q, --quality <n>\", \"JPEG quality (0-100)\")\n  .option(\"--clip <json>\", \"Clip region as JSON\")\n  .option(\"--no-animations\", \"Disable animations\")\n  .option(\"--hide-caret\", \"Hide text caret\");\n```\n\n### 辅助功能快照\n\n```typescript\n// Sources: packages/cli/src/index.ts:360-380\nprogram\n  .command(\"snapshot\")\n  .description(\"Get accessibility tree snapshot\")\n  .option(\"-c, --compact\", \"Output tree only (no xpath map)\")\n  .action(async (cmdOpts) => {\n    const result = (await runCommand(\"snapshot\", [cmdOpts.compact])) as {\n      tree: string;\n      xpathMap?: Record<string, string>;\n      urlMap?: Record<string, string>;\n    };\n    // ...\n  });\n```\n\n## 错误处理机制\n\n### Daemon 状态管理\n\n```mermaid\nstateDiagram-v2\n    [*] --> Stopped\n    Stopped --> Starting: start 命令\n    Starting --> Running: 启动成功\n    Starting --> Failed: 启动失败\n    Running --> Stopping: stop 命令\n    Running --> Failed: 连接断开\n    Stopping --> Stopped: 清理完成\n    Failed --> Starting: 重试\n    Stopped --> [*]\n```\n\n### 锁机制实现\n\n```typescript\n// Sources: packages/cli/src/index.ts:490-520\nasync function acquireLock(\n  session: string,\n  timeoutMs: number = 10000,\n): Promise<boolean> {\n  const lockPath = getLockPath(session);\n  \n  while (Date.now() - startTime < timeoutMs) {\n    try {\n      // O_EXCL 确保原子性创建\n      const handle = await fs.open(lockPath, \"wx\");\n      await handle.write(String(process.pid));\n      await handle.close();\n      return true;\n    } catch (err: unknown) {\n      if ((err as NodeJS.ErrnoException).code === \"EEXIST\") {\n        // 检查持有者是否存活\n        try {\n          const holderPid = parseInt(await fs.readFile(lockPath, \"utf-8\"));\n          process.kill(holderPid, 0);\n          await new Promise((r) => setTimeout(r, 100));\n        } catch {\n          // 清理陈旧锁\n          await fs.unlink(lockPath);\n        }\n      }\n    }\n  }\n  return false;\n}\n```\n\n## 扩展命令系统\n\nAgent 系统支持通过命令模式（Command Pattern）轻松扩展新功能：\n\n```typescript\nprogram\n  .command(\"<command> <args...>\")\n  .description(\"命令描述\")\n  .option(\"-x, --option <value>\", \"选项说明\")\n  .action(async (args, cmdOpts) => {\n    const result = await runCommand(\"command_name\", [\n      args,\n      { /* options */ }\n    ]);\n    output(result, opts.json ?? false);\n  });\n```\n\n## 总结\n\nStagehand 的 Agent 代理系统提供了完整的浏览器自动化能力：\n\n1. **Daemon 管理**：基于 Unix Socket 的进程间通信，支持多会话隔离\n2. **命令系统**：统一的命令接口，覆盖所有浏览器操作\n3. **网络监控**：完整的请求/响应捕获机制\n4. **本地策略**：灵活的浏览器连接策略（隔离/CDP/自动）\n5. **错误恢复**：多级重试和自动清理机制\n6. **会话管理**：完善的会话状态和配置管理\n\n---\n\n<a id='handler-system'></a>\n\n## Handler 处理系统\n\n### Related Pages\n\nRelated topics: [act() 操作执行](#act-api), [extract() 数据提取](#extract-api), [observe() 页面观察](#observe-api)\n\n<details>\n<summary>Relevant source files</summary>\n\nThe following files were used as context for generating this wiki page:\n\n- [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n- [packages/cli/src/local-strategy.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-strategy.ts)\n- [packages/cli/src/local-cdp-discovery.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-cdp-discovery.ts)\n</details>\n\n# Handler 处理系统\n\n## 概述\n\nHandler 处理系统是 Stagehand 框架的核心组件，负责在浏览器环境中执行自动化操作。该系统通过统一的命令调度机制，将高层操作指令（如 `click`、`type`、`hover` 等）转换为底层的浏览器 CDP (Chrome DevTools Protocol) 调用。Sources: [packages/cli/src/index.ts:1-50]()\n\nStagehand 的 Handler 架构采用分层设计，上层 CLI 通过 Unix Domain Socket 与本地守护进程通信，守护进程负责维护浏览器会话并执行实际的 DOM 操作。这种设计允许命令行工具、API 和其他客户端共享同一个浏览器实例，同时保持操作的原子性和一致性。Sources: [packages/cli/src/index.ts:200-280]()\n\n## 核心架构\n\n### 组件层次\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│                      CLI Client                             │\n│  (Commands: click, type, hover, fill, screenshot, etc.)    │\n└─────────────────────────────────────────────────────────────┘\n                              │\n                              ▼\n┌─────────────────────────────────────────────────────────────┐\n│                  Socket Command Router                      │\n│              (runCommand / sendCommand)                     │\n└─────────────────────────────────────────────────────────────┘\n                              │\n                              ▼\n┌─────────────────────────────────────────────────────────────┐\n│                    Daemon Process                            │\n│           (Browser Session Management)                       │\n└─────────────────────────────────────────────────────────────┘\n                              │\n                              ▼\n┌─────────────────────────────────────────────────────────────┐\n│                  Handler Execution Layer                     │\n│    ┌─────────────┬─────────────┬──────────────────┐        │\n│    │ Action      │ Navigation  │ State Check      │        │\n│    │ Handlers    │ Handlers    │ Handlers         │        │\n│    └─────────────┴─────────────┴──────────────────┘        │\n└─────────────────────────────────────────────────────────────┘\n                              │\n                              ▼\n┌─────────────────────────────────────────────────────────────┐\n│               Chrome DevTools Protocol (CDP)                │\n└─────────────────────────────────────────────────────────────┘\n```\n\n### 命令处理流程\n\n当 CLI 收到一个命令（如 `click <selector>`）时，系统按以下流程处理：\n\n```mermaid\ngraph TD\n    A[CLI Command: click] --> B[Parse Options & Arguments]\n    B --> C[Call runCommand]\n    C --> D[Acquire Session Lock]\n    D --> E{Socket Available?}\n    E -->|Yes| F[Send Command via Socket]\n    E -->|No| G[ensureDaemon]\n    G --> F\n    F --> H[Daemon Router Switch]\n    H --> I[Execute Handler]\n    I --> J[CDP: Runtime.evaluate]\n    J --> K[Return Result]\n    K --> L[Release Lock]\n```\n\nSources: [packages/cli/src/index.ts:300-400]()\n\n## 守护进程管理\n\n### 生命周期管理\n\nStagehand 使用 Unix Domain Socket 进行进程间通信，并通过文件锁机制确保同一会话的互斥访问：\n\n| 功能 | 实现方式 | 文件路径模式 |\n|------|----------|--------------|\n| Socket 通信 | Unix Domain Socket | `/tmp/browse-{session}.sock` |\n| 进程锁 | O_EXCL 原子文件创建 | `/tmp/browse-{session}.lock` |\n| 锁超时 | 10秒默认超时 | - |\n\nSources: [packages/cli/src/index.ts:250-320]()\n\n### 自动重试机制\n\n命令执行失败时，系统提供智能重试：\n\n| 重试次数 | 策略 | 说明 |\n|----------|------|------|\n| 0 | 短暂等待 | 200ms 后重试（socket 暂时不可用） |\n| 1 | 重启守护进程 | 保持现有文件状态 |\n| 2 | 完全清理重启 | 杀死 Chrome 进程并清理残留文件 |\n\n```typescript\n// 重试条件判断\nconst isConnectionError =\n  errMsg.includes(\"ENOENT\") ||\n  errMsg.includes(\"ECONNREFUSED\") ||\n  errMsg.includes(\"Connection failed\");\n```\n\nSources: [packages/cli/src/index.ts:380-420]()\n\n## 操作处理器\n\n### 元素操作命令\n\n| 命令 | 功能 | 关键参数 |\n|------|------|----------|\n| `click` | 点击元素 | selector, button, clickCount, delay, xpath |\n| `dblclick` | 双击元素 | selector, button |\n| `hover` | 悬停 | x, y, returnXPath |\n| `fill` | 填写输入框 | selector, value, pressEnter |\n| `type` | 模拟打字 | text, delay, mistakes |\n| `select` | 选择下拉选项 | selector, values |\n| `drag` | 拖拽操作 | fromX, fromY, toX, toY |\n\nSources: [packages/cli/src/index.ts:450-550]()\n\n### 键盘操作\n\n```typescript\nprogram.command(\"press <key>\")\n  .alias(\"key\")\n  .description(\"Press key (e.g., Enter, Tab, Escape, Cmd+A)\")\n```\n\n支持组合键和特殊键位，包括 modifier keys (Cmd, Ctrl, Shift, Alt)。\n\nSources: [packages/cli/src/index.ts:580-600]()\n\n### 导航操作\n\n| 命令 | 选项 | 默认值 |\n|------|------|--------|\n| `open <url>` | `--wait` (load/domcontentloaded/networkidle) | load |\n| | `-t, --timeout` | 30000ms |\n| | `--context-id` | - |\n| | `--persist` | false |\n\nSources: [packages/cli/src/index.ts:620-680]()\n\n## 状态检查处理器\n\n### 元素状态验证\n\n```typescript\nprogram.command(\"is <check> <selector>\")\n  .description(\"Check element state: visible, checked\")\n```\n\n支持的检查类型：\n\n| 检查类型 | 说明 |\n|----------|------|\n| `visible` | 元素在视口内可见 |\n| `checked` | 复选框/单选框选中状态 |\n| `attached` | 元素存在于 DOM |\n| `detached` | 元素已从 DOM 移除 |\n\nSources: [packages/cli/src/index.ts:700-720]()\n\n### 等待机制\n\n```typescript\nprogram.command(\"wait <type> [arg]\")\n  .option(\"-t, --timeout <ms>\", \"Timeout\", \"30000\")\n  .option(\"-s, --state <state>\", \"visible, hidden, attached, detached\", \"visible\")\n```\n\n| 等待类型 | 参数 | 说明 |\n|----------|------|------|\n| `load` | - | 页面加载完成 |\n| `selector` | CSS 选择器 | 元素出现 |\n| `timeout` | 毫秒数 | 自定义超时 |\n\nSources: [packages/cli/src/index.ts:50-80]()\n\n## 信息获取处理器\n\n### GET 命令\n\n```typescript\nprogram.command(\"get <what> [selector]\")\n  .description(\"Get page info: url, title, text, html, markdown, value, box, visible, checked\")\n```\n\n| 属性 | 说明 | 返回格式 |\n|------|------|----------|\n| `url` | 当前页面 URL | string |\n| `title` | 页面标题 | string |\n| `text` | 元素文本内容 | string |\n| `html` | 元素 HTML | string |\n| `markdown` | 元素 Markdown | string |\n| `value` | 表单元素值 | string |\n| `box` | 元素边界框 | {x, y, width, height} |\n| `visible` | 可见性状态 | boolean |\n| `checked` | 选中状态 | boolean |\n\nSources: [packages/cli/src/index.ts:720-750]()\n\n## 截图处理器\n\n```typescript\nprogram.command(\"screenshot [path]\")\n  .option(\"-f, --full-page\", \"Full page screenshot\")\n  .option(\"-t, --type <type>\", \"png, jpeg\", \"png\")\n  .option(\"-q, --quality <n>\", \"JPEG quality (0-100)\")\n  .option(\"--clip <json>\", \"Clip region\")\n  .option(\"--no-animations\", \"Disable animations\")\n  .option(\"--hide-caret\", \"Hide text caret\")\n```\n\nSources: [packages/cli/src/index.ts:750-800]()\n\n## 网络捕获\n\n### 请求/响应记录\n\n系统可以捕获并保存网络请求到文件系统：\n\n```typescript\ninterface PendingRequest {\n  id: string;\n  timestamp: string;\n  method: string;\n  url: string;\n  headers: Record<string, string>;\n  body: string | null;\n  resourceType: string;\n}\n```\n\n保存目录结构：\n\n```\n{networkDir}/\n├── 000-GET-example-com-api/\n│   ├── request.json\n│   └── response.json\n└── 001-POST-example-com-login/\n    ├── request.json\n    └── response.json\n```\n\nSources: [packages/cli/src/index.ts:850-920]()\n\n## 配置与超时\n\n### 全局选项 (GlobalOpts)\n\n```typescript\ninterface GlobalOpts {\n  ws?: string;\n  headless?: boolean;\n  headed?: boolean;\n  json?: boolean;\n  session?: string;\n  connect?: string;\n  // Remote session options\n  proxies?: boolean;\n  advancedStealth?: boolean;\n  solveCaptchas?: boolean;\n  region?: string;\n  keepAlive?: boolean;\n  sessionTimeout?: number;\n  blockAds?: boolean;\n}\n```\n\n### 超时配置\n\n| 操作 | 默认超时 | 配置方式 |\n|------|----------|----------|\n| 页面导航 | 30000ms | `--timeout` 选项 |\n| 截图 | 10000ms | 硬编码 |\n| Socket 连接 | 28000ms | `waitForSocketReady` |\n| 守护进程锁 | 10000ms | `acquireLock` 参数 |\n\nSources: [packages/cli/src/index.ts:280-340]()\n\n## 错误处理\n\n### 错误分类\n\n| 错误类型 | 处理策略 | 重试行为 |\n|----------|----------|----------|\n| ENOENT | 连接错误 | 重试 |\n| ECONNREFUSED | 连接错误 | 重试 |\n| Connection failed | 连接错误 | 重试 |\n| 其他 | 直接抛出 | 不重试 |\n\n```typescript\n// 优雅关闭处理\nprocess.on(\"SIGTERM\", () => shutdown());\nprocess.on(\"SIGINT\", () => shutdown());\nprocess.on(\"uncaughtException\", (err) => {\n  console.error(\"Uncaught exception:\", err);\n  shutdown();\n});\n```\n\nSources: [packages/cli/src/index.ts:420-450]()\n\n## 本地浏览器策略\n\n### 策略类型\n\n| 策略 | 说明 | 使用场景 |\n|------|------|----------|\n| `auto` | 自动检测已存在的浏览器或启动隔离浏览器 | 默认策略 |\n| `isolated` | 强制使用独立的 Chrome 实例 | 干净环境 |\n| `cdp` | 连接到指定的 CDP 目标 | 调试已有浏览器 |\n\n```typescript\nif (localConfig.strategy === \"isolated\") {\n  return {\n    localLaunchOptions: { headless, viewport: defaultViewport },\n    localInfo: { localSource: \"isolated\" },\n  };\n}\n```\n\nSources: [packages/cli/src/local-strategy.ts:1-50]()\n\n### CDP 发现机制\n\n系统通过以下方式发现本地浏览器：\n\n1. 读取 `DevToolsActivePort` 文件获取端口\n2. 探测 `/json/version` 端点获取 WebSocket URL\n3. 验证端口可达性\n4. 建立 WebSocket 连接\n\n```typescript\nasync function probeJsonVersion(port: number): Promise<string | null> {\n  const res = await fetch(`http://127.0.0.1:${port}/json/version`);\n  const json = await res.json();\n  return json.webSocketDebuggerUrl;\n}\n```\n\nSources: [packages/cli/src/local-cdp-discovery.ts:1-100]()\n\n## 会话管理\n\n### 多会话支持\n\n通过 `--session` 参数或 `BROWSE_SESSION` 环境变量指定会话：\n\n```typescript\nfunction getSession(opts: GlobalOpts): string {\n  return opts.session ?? process.env.BROWSE_SESSION ?? \"default\";\n}\n```\n\n每个会话维护独立的：\n- Socket 通信通道\n- 浏览器实例\n- 状态文件\n\n### 模式覆盖\n\n支持动态切换执行模式（local/remote）：\n\n```typescript\nawait fs.writeFile(getModeOverridePath(session), mapped);\n```\n\nSources: [packages/cli/src/index.ts:180-220]()\n\n## 参考映射 (Ref Map)\n\n系统缓存最近一次 snapshot 的引用映射，支持 `@ref` 语法：\n\n```typescript\nlet refMap: {\n  xpathMap: Record<string, string>;\n  urlMap: Record<string, string>;\n} = {\n  xpathMap: {},\n  urlMap: {},\n};\n\nprogram.command(\"refs\").description(\"Show cached ref map from last snapshot\");\n```\n\nSources: [packages/cli/src/index.ts:820-850]()\n\n## 总结\n\nHandler 处理系统是 Stagehand 实现浏览器自动化的核心抽象层。它通过以下设计原则提供可靠的操作执行：\n\n1. **进程隔离**：守护进程与 CLI 分离，支持多客户端共享\n2. **幂等性**：通过锁机制和幂等命令确保安全并发\n3. **自动恢复**：智能重试和状态清理保证鲁棒性\n4. **灵活配置**：支持多种执行模式和详细参数调优\n5. **统一接口**：命令行、API 复用同一 Handler 逻辑\n\n---\n\n<a id='dom-accessibility'></a>\n\n## DOM 与无障碍树\n\n### Related Pages\n\nRelated topics: [observe() 页面观察](#observe-api), [Deep Locator 深层定位器](#deep-locator)\n\n<details>\n<summary>Relevant source files</summary>\n\nThe following files were used as context for generating this wiki page:\n\n- [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n- [packages/cli/src/local-strategy.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-strategy.ts)\n- [packages/cli/src/local-cdp-discovery.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-cdp-discovery.ts)\n</details>\n\n# DOM 与无障碍树\n\n## 概述\n\nStagehand 中的 DOM 与无障碍树（Accessibility Tree，简称 A11y Tree）是核心的页面元素抽象层。该系统将网页的 DOM 结构转换为结构化的无障碍树表示，使 AI 代理能够理解页面内容并执行自动化操作。无障碍树不仅包含元素的可见性信息，还包含语义角色、ARIA 属性和可访问性标签等关键元数据。\n\nStagehand 通过 `snapshot` 命令获取无障碍树快照，该快照包含格式化的树形结构、元素 XPath 映射和 URL 映射。这些数据被用于元素定位、坐标解析和交互操作。\n\n## 架构设计\n\n### 组件关系\n\n```\ngraph TD\n    A[Browser Page] --> B[DOM Tree]\n    A --> C[Accessibility Tree]\n    B --> D[snapshot command]\n    C --> D\n    D --> E[xpathMap]\n    D --> F[urlMap]\n    D --> G[formattedTree]\n    E --> H[Coordinate Resolver]\n    F --> I[Element Locator]\n    G --> J[AI Agent]\n```\n\n### 核心模块\n\n| 模块 | 文件路径 | 职责 |\n|------|---------|------|\n| A11yTree | `packages/core/lib/v3/understudy/a11y/snapshot/a11yTree.ts` | 无障碍树生成与格式化 |\n| DomTree | `packages/core/lib/v3/understudy/a11y/snapshot/domTree.ts` | DOM 树结构处理 |\n| CoordinateResolver | `packages/core/lib/v3/understudy/a11y/snapshot/coordinateResolver.ts` | 屏幕坐标解析 |\n| FocusSelectors | `packages/core/lib/v3/understudy/a11y/snapshot/focusSelectors.ts` | 焦点元素选择器 |\n\n## Snapshot 命令\n\n### CLI 接口\n\n`packages/cli/src/index.ts` 中定义的 `snapshot` 命令提供两种输出模式：\n\n```typescript\nprogram\n  .command(\"snapshot\")\n  .description(\"Get accessibility tree snapshot\")\n  .option(\"-c, --compact\", \"Output tree only (no xpath map)\")\n  .action(async (cmdOpts) => {\n    const result = (await runCommand(\"snapshot\", [cmdOpts.compact])) as {\n      tree: string;\n      xpathMap?: Record<string, string>;\n      urlMap?: Record<string, string>;\n    };\n    // ...\n  });\n```\n\nSources: [packages/cli/src/index.ts:1-500](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n### 输出格式\n\n| 参数 | 类型 | 描述 |\n|------|------|------|\n| `tree` | `string` | 格式化的无障碍树结构 |\n| `xpathMap` | `Record<string, string>` | 元素引用到 XPath 的映射 |\n| `urlMap` | `Record<string, string>` | 元素引用到 URL 的映射 |\n\n紧凑模式下仅返回纯文本树结构，适合日志记录和快速调试：\n\n```typescript\nif (cmdOpts.compact && !opts.json) {\n  console.log(result.tree);\n} else {\n  output(result, opts.json ?? false);\n}\n```\n\n## Snapshot 实现\n\n### 后端处理逻辑\n\n在 CLI 的命令处理器中，`snapshot` case 从 Playwright Page 对象获取快照数据：\n\n```typescript\ncase \"snapshot\": {\n  const [compact] = args as [boolean?];\n  const snapshot = await page!.snapshot();\n\n  refMap = {\n    xpathMap: snapshot.xpathMap ?? {},\n    urlMap: snapshot.urlMap ?? {},\n  };\n\n  if (compact) {\n    return { tree: snapshot.formattedTree };\n  }\n  return {\n    tree: snapshot.formattedTree,\n    xpathMap: snapshot.xpathMap,\n    urlMap: snapshot.urlMap,\n  };\n}\n```\n\nSources: [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n### 引用映射管理\n\n全局 `refMap` 变量存储最新的快照映射，供后续元素操作使用：\n\n```typescript\nlet refMap: {\n  xpathMap: Record<string, string>;\n  urlMap: Record<string, string>;\n} = {\n  xpathMap: {},\n  urlMap: {},\n};\n```\n\n## 元素状态检查\n\n### is 命令\n\n`is` 命令用于检查元素的可访问性状态：\n\n```typescript\ncase \"is\": {\n  const [check, selector] = args as [string, string];\n  const locator = page!.deepLocator(resolveSelector(selector));\n  switch (check) {\n    case \"visible\":\n      return { visible: await locator.isVisible() };\n    case \"checked\":\n      return { checked: await locator.isChecked() };\n    default:\n      throw new Error(`Unknown check: ${check}`);\n  }\n}\n```\n\nSources: [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n| 检查类型 | 方法 | 描述 |\n|---------|------|------|\n| `visible` | `isVisible()` | 元素是否可见 |\n| `checked` | `isChecked()` | 复选框/单选框是否选中 |\n\n### CLI 接口\n\n```typescript\nprogram\n  .command(\"is <check> <selector>\")\n  .description(\"Check element state: visible, checked\")\n  .action(async (check: string, selector: string) => {\n    const result = await runCommand(\"is\", [check, selector]);\n    output(result, opts.json ?? false);\n  });\n```\n\n## 页面信息获取\n\n### get 命令\n\n`get` 命令提供多种页面和元素信息查询：\n\n```typescript\nprogram\n  .command(\"get <what> [selector]\")\n  .description(\n    \"Get page info: url, title, text, html, markdown, value, box, visible, checked\",\n  )\n  .action(async (what: string, selector?: string) => {\n    const result = await runCommand(\"get\", [what, selector]);\n    output(result, opts.json ?? false);\n  });\n```\n\nSources: [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n### 支持的信息类型\n\n| 类型 | 参数 | 返回内容 |\n|------|------|---------|\n| `url` | 无 | 当前页面 URL |\n| `title` | 无 | 页面标题 |\n| `text` | selector | 元素文本内容 |\n| `html` | selector | 元素 HTML |\n| `markdown` | selector | 转换后的 Markdown |\n| `value` | selector | 表单元素值 |\n| `box` | selector | 元素边界框 {x, y, width, height} |\n| `visible` | selector | 元素可见性 |\n| `checked` | selector | 复选框状态 |\n\n## 坐标与交互\n\n### 坐标操作命令\n\n| 命令 | 描述 | 选项 |\n|------|------|------|\n| `click_xy <x> <y>` | 坐标点击 | `--button`, `--count`, `--xpath` |\n| `hover <x> <y>` | 坐标悬停 | `--xpath` |\n| `scroll <x> <y> <dx> <dy>` | 滚动 | `--xpath` |\n| `drag <fromX> <fromY> ...` | 拖拽 | 延迟、坐标选项 |\n\n```typescript\nprogram\n  .command(\"click_xy <x> <y>\")\n  .description(\"Click at exact coordinates\")\n  .option(\"-b, --button <btn>\", \"Mouse button: left, right, middle\", \"left\")\n  .option(\"-c, --count <n>\", \"Click count\", \"1\")\n  .option(\"--xpath\", \"Return XPath of clicked element\")\n  .action(async (x: string, y: string, cmdOpts) => {\n    const result = await runCommand(\"click_xy\", [\n      parseFloat(x),\n      parseFloat(y),\n      {\n        button: cmdOpts.button,\n        clickCount: parseInt(cmdOpts.count),\n        returnXPath: cmdOpts.xpath,\n      },\n    ]);\n  });\n```\n\nSources: [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n### 坐标解析器\n\n`CoordinateResolver` 模块负责将无障碍树中的元素引用转换为屏幕坐标。该解析器基于快照中的 `xpathMap` 和元素边界框信息计算精确的交互坐标。\n\n## 本地浏览器策略\n\n### 策略类型\n\n`packages/cli/src/local-strategy.ts` 定义了三种本地浏览器连接策略：\n\n```typescript\nexport async function resolveLocalStrategy({\n  localConfig,\n  headless,\n  defaultViewport,\n  discoverLocalCdp,\n  resolveWsTarget,\n}: ResolveLocalStrategyOptions): Promise<ResolvedLocalStrategy> {\n  if (localConfig.strategy === \"isolated\") {\n    return {\n      localLaunchOptions: { headless, viewport: defaultViewport },\n      localInfo: { localSource: \"isolated\" },\n    };\n  }\n  // ...\n}\n```\n\nSources: [packages/cli/src/local-strategy.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-strategy.ts)\n\n| 策略 | 说明 |\n|------|------|\n| `isolated` | 启动独立的 Chromium 实例 |\n| `cdp` | 连接到指定的 Chrome DevTools Protocol 目标 |\n| `auto` | 自动检测本地调试端口 |\n\n### CDP 发现机制\n\n`packages/cli/src/local-cdp-discovery.ts` 实现了自动发现本地 Chrome 调试端口的功能：\n\n```typescript\nasync function resolveDevToolsActivePortUrl(\n  port: number,\n  userDataDirs: string[],\n): Promise<string | null> {\n  for (const dir of userDataDirs) {\n    const info = await readDevToolsActivePort(dir);\n    if (!info || info.port !== port) {\n      continue;\n    }\n    // 验证端口可达性\n    if (!(await isPortReachable(info.port))) {\n      await cleanupStaleDevToolsActivePort(dir);\n      continue;\n    }\n    return buildDevToolsWsUrl(info.port, info.wsPath);\n  }\n  return null;\n}\n```\n\nSources: [packages/cli/src/local-cdp-discovery.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-cdp-discovery.ts)\n\n## 网络捕获集成\n\n### 快照与网络数据\n\n无障碍树快照可以与网络捕获功能结合使用：\n\n```typescript\ninterface PendingRequest {\n  id: string;\n  timestamp: string;\n  method: string;\n  url: string;\n  headers: Record<string, string>;\n  body: string | null;\n  resourceType: string;\n}\n```\n\n每个网络请求保存到文件系统时，使用 URL 解析生成目录名：\n\n```typescript\nfunction getRequestDirName(\n  counter: number,\n  method: string,\n  url: string,\n): string {\n  try {\n    const parsed = new URL(url);\n    const domain = sanitizeForFilename(parsed.hostname, 30);\n    const pathPart = parsed.pathname.split(\"/\").filter(Boolean)[0] || \"root\";\n    const pathSlug = sanitizeForFilename(pathPart, 20);\n    return `${String(counter).padStart(3, \"0\")}-${method}-${domain}-${pathSlug}`;\n  } catch {\n    return `${String(counter).padStart(3, \"0\")}-${method}-unknown`;\n  }\n}\n```\n\nSources: [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n## 使用场景\n\n### 基本工作流程\n\n```mermaid\ngraph LR\n    A[open <url>] --> B[snapshot]\n    B --> C[xpathMap + urlMap]\n    C --> D[click <element>]\n    D --> E[verify state]\n    E --> F[screenshot]\n```\n\n### 多页面管理\n\nStagehand 支持多标签页操作：\n\n```typescript\nprogram\n  .command(\"pages\")\n  .description(\"List all open pages\")\n  .action(async () => {\n    const result = await runCommand(\"pages\", []);\n    output(result, opts.json ?? false);\n  });\n\nprogram\n  .command(\"tab_close [index]\")\n  .alias(\"close\")\n  .description(\"Close tab by index (defaults to last tab)\")\n  .action(async (index?: string) => {\n    const result = await runCommand(\"tab_close\", [\n      index ? parseInt(index) : undefined,\n    ]);\n    output(result, opts.json ?? false);\n  });\n```\n\n## 总结\n\nDOM 与无障碍树系统是 Stagehand 实现浏览器自动化的基础。通过将复杂 DOM 结构转换为语义化的无障碍树，结合 XPath 映射和坐标解析，AI 代理能够准确理解和操作网页元素。该系统与 CLI 工具深度集成，提供 `snapshot`、`get`、`is` 等命令支持灵活的页面检查和交互操作。\n\n---\n\n<a id='deep-locator'></a>\n\n## Deep Locator 深层定位器\n\n### Related Pages\n\nRelated topics: [DOM 与无障碍树](#dom-accessibility), [act() 操作执行](#act-api)\n\n<details>\n<summary>Relevant source files</summary>\n\nThe following files were used as context for generating this wiki page:\n\n- [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n- [packages/cli/src/local-strategy.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-strategy.ts)\n- [packages/cli/src/local-cdp-discovery.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-cdp-discovery.ts)\n</details>\n\n# Deep Locator 深层定位器\n\n## 概述\n\nDeep Locator（深层定位器）是 Stagehand 框架中负责精确定位和操作 DOM 元素的核心子系统。它通过多层次的定位策略、跨帧（iframe）处理、以及智能选择器解析，实现了对复杂网页结构中元素的可靠访问。该系统是 Stagehand 能够实现高精度自动化控制的关键技术基础。\n\n**核心职责：**\n\n- 提供多种元素定位策略（CSS 选择器、XPath、坐标等）\n- 处理跨 iframe/跨帧的元素定位\n- 管理浏览器上下文和帧的注册与追踪\n- 解析和优化选择器以提高定位准确性\n- 与 CLI 命令层紧密集成，支持交互式定位操作\n\nSources: [packages/cli/src/index.ts:1-50]()\n\n---\n\n## 架构组件\n\nDeep Locator 系统由以下核心组件构成，它们协同工作以实现端到端的元素定位能力：\n\n| 组件名称 | 文件路径 | 主要职责 |\n|---------|---------|---------|\n| DeepLocator | `packages/core/lib/v3/understudy/deepLocator.ts` | 主定位引擎，整合多种定位策略 |\n| Piercer | `packages/core/lib/v3/understudy/piercer.ts` | 处理 iframe 穿透和跨帧定位 |\n| FrameRegistry | `packages/core/lib/v3/understudy/frameRegistry.ts` | 管理帧层级结构和状态 |\n| SelectorResolver | `packages/core/lib/v3/understudy/selectorResolver.ts` | 选择器解析和优化 |\n\nSources: [packages/cli/src/index.ts:50-80]()\n\n### 组件关系图\n\n```mermaid\ngraph TD\n    A[CLI Command] --> B[DeepLocator]\n    B --> C[SelectorResolver]\n    B --> D[Piercer]\n    D --> E[FrameRegistry]\n    E --> F[Browser CDP]\n    C --> F\n    F --> B\n```\n\n---\n\n## 定位策略\n\nStagehand 的 Deep Locator 支持多种定位策略，适用于不同的场景需求：\n\n### 基础定位命令\n\n| 命令 | 用途 | 典型用法 |\n|-----|------|---------|\n| `click` | 点击元素 | `click <selector> [options]` |\n| `hover` | 悬停元素/坐标 | `hover <x> <y> [--xpath]` |\n| `fill` | 填写表单输入 | `fill <selector> <value>` |\n| `type` | 模拟打字输入 | `type <text> [--delay] [--mistakes]` |\n| `select` | 选择下拉选项 | `select <selector> <values...>` |\n\nSources: [packages/cli/src/index.ts:200-280]()\n\n### 坐标操作\n\n对于无法通过选择器精确定位的场景，系统支持基于坐标的操作：\n\n```typescript\nprogram\n  .command(\"scroll <x> <y> <deltaX> <deltaY>\")\n  .description(\"Scroll at coordinates\")\n  .option(\"--xpath\", \"Return XPath of scrolled element\")\n```\n\n### 元素状态检查\n\n在执行操作前，系统允许检查元素状态以确保操作安全：\n\n| 检查类型 | 说明 |\n|---------|------|\n| `visible` | 元素是否可见 |\n| `checked` | 复选框/单选框是否选中 |\n| `attached` | 元素是否在 DOM 中 |\n| `detached` | 元素是否已从 DOM 移除 |\n\nSources: [packages/cli/src/index.ts:180-200]()\n\n---\n\n## 帧（Frame）管理\n\nDeep Locator 的一个关键特性是能够处理嵌套的 iframe 结构。FrameRegistry 组件维护了一个帧层级注册表。\n\n### 本地策略解析\n\n系统通过 `resolveLocalStrategy` 函数管理本地浏览器实例的帧发现：\n\n```typescript\nexport async function resolveLocalStrategy({\n  localConfig,\n  headless,\n  defaultViewport,\n  discoverLocalCdp,\n  resolveWsTarget,\n}: ResolveLocalStrategyOptions): Promise<ResolvedLocalStrategy>\n```\n\n**支持的三种本地策略：**\n\n| 策略 | 描述 | 使用场景 |\n|-----|------|---------|\n| `isolated` | 启动独立 Chromium 实例 | 完全隔离的测试环境 |\n| `cdp` | 连接到已有 Chrome DevTools | 附加到正在运行的浏览器 |\n| `auto` | 自动检测可用浏览器 | 灵活适配不同环境 |\n\nSources: [packages/cli/src/local-strategy.ts:30-80]()\n\n### CDP 发现机制\n\n系统通过 `discoverLocalCdp` 函数自动发现可用的 Chrome DevTools Protocol 端点：\n\n```mermaid\ngraph LR\n    A[Scan Chrome Profile Dirs] --> B[Read DevToolsActivePort]\n    B --> C{Port Reachable?}\n    C -->|Yes| D[Build WebSocket URL]\n    C -->|No| E[Cleanup Stale File]\n    D --> F[Return wsUrl]\n    E --> A\n```\n\nSources: [packages/cli/src/local-cdp-discovery.ts:50-100]()\n\n---\n\n## 选择器解析器\n\nSelectorResolver 负责将人类可读的选择器表达式转换为高效的浏览器指令：\n\n### 选择器类型支持\n\n| 类型 | 示例 | 优先级 |\n|-----|------|-------|\n| CSS 选择器 | `#id`, `.class`, `div[data-*]` | 高 |\n| XPath | `//div[@class='target']` | 中 |\n| 文本匹配 | `text=\"登录\"` | 中 |\n| 混合表达式 | `button:text(\"提交\")` | 中 |\n\n### 优化策略\n\n系统会智能优化选择器以提高性能：\n\n1. **缓存机制** - 缓存最近使用的选择器结果\n2. **批量查询** - 合并多个选择器请求\n3. **超时控制** - 防止单个选择器阻塞整个流程\n\n---\n\n## 网络捕获与调试\n\nDeep Locator 集成网络捕获功能，便于调试定位问题：\n\n### 网络请求状态管理\n\n```typescript\ninterface PendingRequest {\n  id: string;\n  timestamp: string;\n  method: string;\n  url: string;\n  headers: Record<string, string>;\n  body: string | null;\n  resourceType: string;\n}\n```\n\nSources: [packages/cli/src/index.ts:15-30]()\n\n### 文件系统写入\n\n每个捕获的请求都会写入独立的目录结构：\n\n```\nnetwork-capture/\n├── 001-GET-api.example.com/users\n│   ├── request.json\n│   └── response.json\n└── 002-POST-api.example.com/login\n    ├── request.json\n    └── response.json\n```\n\n**目录命名规范：**\n\n```typescript\nfunction getRequestDirName(\n  counter: number,\n  method: string,\n  url: string,\n): string {\n  const parsed = new URL(url);\n  const domain = sanitizeForFilename(parsed.hostname, 30);\n  const pathPart = parsed.pathname.split(\"/\").filter(Boolean)[0] || \"root\";\n  const pathSlug = sanitizeForFilename(pathPart, 20);\n  return `${String(counter).padStart(3, \"0\")}-${method}-${domain}-${pathSlug}`;\n}\n```\n\nSources: [packages/cli/src/index.ts:40-60]()\n\n---\n\n## 守护进程基础设施\n\nDeep Locator 使用 Unix Socket 通信实现高效的守护进程模式：\n\n### 锁机制\n\n```mermaid\ngraph TD\n    A[Acquire Lock] --> B{File Exists?}\n    B -->|No| C[Create Lock File]\n    B -->|Yes| D{Process Alive?}\n    D -->|Yes| E[Wait 100ms]\n    D -->|No| F[Remove Stale Lock]\n    E --> B\n    C --> G[Lock Acquired]\n    F --> B\n```\n\n**关键特性：**\n\n- 使用 `O_EXCL` 确保原子性文件创建\n- 检测僵尸进程并自动清理过期锁\n- 可配置超时机制（默认 10000ms）\n\nSources: [packages/cli/src/index.ts:280-320]()\n\n### Socket 路径管理\n\n```typescript\nconst SOCKET_DIR = os.tmpdir();\n\nfunction getSocketPath(session: string): string {\n  return path.join(SOCKET_DIR, `browse-${session}.sock`);\n}\n\nfunction getLockPath(session: string): string {\n  return path.join(SOCKET_DIR, `browse-${session}.lock`);\n}\n```\n\n---\n\n## CLI 命令参考\n\n### 基础导航\n\n```bash\n# 打开 URL\nbrowse open <url> [--wait load|domcontentloaded|networkidle] [-t timeout]\nbrowse goto <url>  # alias\n\n# 创建新页面\nbrowse newpage [url]\n\n# 页面信息\nbrowse get <what> [selector]  # url|title|text|html|markdown|value|box\n```\n\n### 元素操作\n\n```bash\n# 点击\nbrowse click <selector> [-d delay] [-x|--xpath]\n\n# 输入\nbrowse fill <selector> <value> [--no-press-enter]\nbrowse type <text> [-d delay] [--mistakes]\n\n# 键盘\nbrowse press <key>  # Enter, Tab, Escape, Cmd+A, etc.\n```\n\n### 截图功能\n\n```bash\nbrowse screenshot [path]\n  [--full-page]           # 整页截图\n  [--type png|jpeg]       # 图片格式\n  [--quality 0-100]       # JPEG 质量\n  [--clip <json>]         # 裁剪区域\n  [--no-animations]       # 禁用动画\n  [--hide-caret]          # 隐藏文本光标\n```\n\nSources: [packages/cli/src/index.ts:350-400]()\n\n---\n\n## 配置选项\n\n### 全局选项\n\n| 选项 | 类型 | 说明 |\n|-----|------|------|\n| `--headless` | boolean | 无头模式运行 |\n| `--headed` | boolean | 显示浏览器窗口 |\n| `--json` | boolean | JSON 格式输出 |\n| `--session` | string | 会话标识符 |\n| `--connect` | string | 连接远程浏览器 |\n| `--ws` | string | WebSocket 地址 |\n\n### 远程会话选项\n\n| 选项 | 说明 |\n|-----|------|\n| `--proxies` | 启用代理支持 |\n| `--advanced-stealth` | 高级反检测 |\n| `--solve-captchas` | 自动解决验证码 |\n| `--region` | 区域设置 |\n| `--keep-alive` | 保持连接活跃 |\n| `--session-timeout` | 会话超时秒数 |\n| `--block-ads` | 拦截广告 |\n\nSources: [packages/cli/src/index.ts:400-450]()\n\n---\n\n## 工作流程图\n\n```mermaid\nsequenceDiagram\n    participant CLI\n    participant DeepLocator\n    participant SelectorResolver\n    participant FrameRegistry\n    participant CDP\n\n    CLI->>DeepLocator: locate(element)\n    DeepLocator->>SelectorResolver: resolve(selector)\n    SelectorResolver->>CDP: query()\n    CDP-->>SelectorResolver: elements[]\n    SelectorResolver-->>DeepLocator: resolved\n    DeepLocator->>FrameRegistry: checkFrame(element)\n    FrameRegistry->>CDP: switchContext()\n    CDP-->>FrameRegistry: context\n    FrameRegistry-->>DeepLocator: frameContext\n    DeepLocator-->>CLI: result\n```\n\n---\n\n## 最佳实践\n\n1. **选择器优先级** - 优先使用 ID 选择器，其次是 data 属性，避免过度依赖 XPath\n2. **等待策略** - 使用显式等待（`wait` 命令）而非固定延迟\n3. **帧切换** - 跨帧操作前务必使用 `FrameRegistry` 进行上下文切换\n4. **网络调试** - 定位问题时启用网络捕获功能分析请求流\n5. **截图验证** - 使用 `--hide-caret` 和 `--no-animations` 获取稳定截图\n\n---\n\n---\n\n## Doramagic 踩坑日志\n\n项目：browserbase/stagehand\n\n摘要：发现 7 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：身份坑 - 仓库名和安装名不一致。\n\n## 1. 身份坑 · 仓库名和安装名不一致\n\n- 严重度：medium\n- 证据强度：runtime_trace\n- 发现：仓库名 `stagehand` 与安装入口 `create-browser-app` 不完全一致。\n- 对用户的影响：用户照着仓库名搜索包或照着包名找仓库时容易走错入口。\n- 建议检查：在 npm/PyPI/GitHub 上确认包名映射和官方 README 说明。\n- 复现命令：`npx create-browser-app`\n- 防护动作：页面必须同时展示 repo 名和真实安装入口，避免用户搜索错包。\n- 证据：identity.distribution | github_repo:776908852 | https://github.com/browserbase/stagehand | repo=stagehand; install=create-browser-app\n\n## 2. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | github_repo:776908852 | https://github.com/browserbase/stagehand | README/documentation is current enough for a first validation pass.\n\n## 3. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | github_repo:776908852 | https://github.com/browserbase/stagehand | last_activity_observed missing\n\n## 4. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | github_repo:776908852 | https://github.com/browserbase/stagehand | no_demo; severity=medium\n\n## 5. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | github_repo:776908852 | https://github.com/browserbase/stagehand | no_demo; severity=medium\n\n## 6. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | github_repo:776908852 | https://github.com/browserbase/stagehand | issue_or_pr_quality=unknown\n\n## 7. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | github_repo:776908852 | https://github.com/browserbase/stagehand | release_recency=unknown\n\n<!-- canonical_name: browserbase/stagehand; human_manual_source: deepwiki_human_wiki -->\n",
      "markdown_key": "stagehand",
      "pages": "draft",
      "source_refs": [
        {
          "evidence_id": "github_repo:776908852",
          "kind": "repo",
          "supports_claim_ids": [
            "claim_identity",
            "claim_distribution",
            "claim_capability"
          ],
          "url": "https://github.com/browserbase/stagehand"
        },
        {
          "evidence_id": "art_da7f4897ea224d8f9df717f95f679237",
          "kind": "docs",
          "supports_claim_ids": [
            "claim_identity",
            "claim_distribution",
            "claim_capability"
          ],
          "url": "https://github.com/browserbase/stagehand#readme"
        }
      ],
      "summary": "DeepWiki/Human Wiki 完整输出，末尾追加 Discovery Agent 踩坑日志。",
      "title": "stagehand 说明书",
      "toc": [
        "Wiki Documentation for https://github.com/browserbase/stagehand",
        "Table of Contents",
        "Stagehand 简介",
        "核心架构",
        "CLI 命令系统",
        "本地浏览器策略",
        "网络捕获功能",
        "全局配置选项",
        "Doramagic 踩坑日志"
      ]
    }
  },
  "quality_gate": {
    "blocking_gaps": [],
    "category_confidence": "medium",
    "compile_status": "ready_for_review",
    "five_assets_present": true,
    "install_sandbox_verified": true,
    "missing_evidence": [],
    "next_action": "publish to Doramagic.ai project surfaces",
    "prompt_preview_boundary_ok": true,
    "publish_status": "publishable",
    "quick_start_verified": true,
    "repo_clone_verified": false,
    "repo_commit": null,
    "repo_inspection_error": null,
    "repo_inspection_files": [],
    "repo_inspection_verified": false,
    "review_reasons": [],
    "tag_count_ok": true,
    "unsupported_claims": []
  },
  "schema_version": "0.1",
  "user_assets": {
    "ai_context_pack": {
      "asset_id": "ai_context_pack",
      "filename": "AI_CONTEXT_PACK.md",
      "markdown": "# stagehand - Doramagic AI Context Pack\n\n> 定位：给用户宿主 AI 装载的开工前上下文。它不代表已经安装、运行或验证目标项目。\n\n## 项目\n\n- canonical_name: `browserbase/stagehand`\n- capability: The SDK For Browser Agents\n- expected_user_outcome: The SDK For Browser Agents\n\n## 基础边界\n\n- 不要声称已经安装、运行、调用 API、读写本地文件或完成真实任务。\n- 项目事实必须来自 repo evidence、Claim Graph 或明确来源。\n- 遇到未验证能力时，必须标记为待验证，而不是补全为事实。\n- publish_status: `publishable`\n- blocking_gaps: none\n\n---\n\n## Doramagic Context Augmentation\n\n下面内容用于强化 Repomix/AI Context Pack 主体。Human Manual 只提供阅读骨架；踩坑日志会被转成宿主 AI 必须遵守的工作约束。\n\n## Human Manual 骨架\n\n使用规则：这里只是项目阅读路线和显著性信号，不是事实权威。具体事实仍必须回到 repo evidence / Claim Graph。\n\n宿主 AI 硬性规则：\n- 不得把页标题、章节顺序、摘要或 importance 当作项目事实证据。\n- 解释 Human Manual 骨架时，必须明确说它只是阅读路线/显著性信号。\n- 能力、安装、兼容性、运行状态和风险判断必须引用 repo evidence、source path 或 Claim Graph。\n\n- **Stagehand 简介**：importance `high`\n  - source_paths: README.md, packages/core/lib/v3/v3.ts\n- **快速开始**：importance `high`\n  - source_paths: packages/core/package.json, packages/core/examples/example.ts, .env.example\n- **系统架构总览**：importance `high`\n  - source_paths: packages/core/lib/v3/index.ts, packages/core/lib/v3/v3.ts, pnpm-workspace.yaml\n- **act() 操作执行**：importance `high`\n  - source_paths: packages/core/lib/v3/handlers/actHandler.ts, packages/core/lib/v3/agent/tools/act.ts, packages/core/lib/v3/agent/tools/click.ts, packages/core/lib/v3/agent/tools/type.ts\n- **extract() 数据提取**：importance `high`\n  - source_paths: packages/core/lib/v3/handlers/extractHandler.ts, packages/core/lib/v3/agent/tools/extract.ts, packages/core/lib/zodCompat.ts\n- **observe() 页面观察**：importance `high`\n  - source_paths: packages/core/lib/v3/handlers/observeHandler.ts, packages/core/lib/v3/understudy/a11y/snapshot/capture.ts, packages/core/lib/v3/understudy/a11y/snapshot/index.ts\n- **Agent 代理系统**：importance `high`\n  - source_paths: packages/core/lib/v3/agent/AgentClient.ts, packages/core/lib/v3/agent/AgentProvider.ts, packages/core/lib/v3/handlers/v3AgentHandler.ts, packages/core/lib/v3/agent/utils/actionMapping.ts\n- **Handler 处理系统**：importance `medium`\n  - source_paths: packages/core/lib/v3/handlers/handlerUtils/timeoutGuard.ts, packages/core/lib/v3/handlers/handlerUtils/actHandlerUtils.ts, packages/core/lib/v3/timeoutConfig.ts\n\n## Repo Inspection Evidence / 源码检查证据\n\n- repo_clone_verified: false\n- repo_inspection_verified: false\n- repo_commit: `unknown`\n\n宿主 AI 硬性规则：\n- 没有 repo_clone_verified=true 时，不得声称已经读过源码。\n- 没有 repo_inspection_verified=true 时，不得把 README/docs/package 文件判断写成事实。\n- 没有 quick_start_verified=true 时，不得声称 Quick Start 已跑通。\n\n## Doramagic Pitfall Constraints / 踩坑约束\n\n这些规则来自 Doramagic 发现、验证或编译过程中的项目专属坑点。宿主 AI 必须把它们当作工作约束，而不是普通说明文字。\n\n### Constraint 1: 仓库名和安装名不一致\n\n- Trigger: 仓库名 `stagehand` 与安装入口 `create-browser-app` 不完全一致。\n- Host AI rule: 在 npm/PyPI/GitHub 上确认包名映射和官方 README 说明。\n- Why it matters: 用户照着仓库名搜索包或照着包名找仓库时容易走错入口。\n- Evidence: identity.distribution | github_repo:776908852 | https://github.com/browserbase/stagehand | repo=stagehand; install=create-browser-app\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 2: 能力判断依赖假设\n\n- Trigger: README/documentation is current enough for a first validation pass.\n- Host AI rule: 将假设转成下游验证清单。\n- Why it matters: 假设不成立时，用户拿不到承诺的能力。\n- Evidence: capability.assumptions | github_repo:776908852 | https://github.com/browserbase/stagehand | README/documentation is current enough for a first validation pass.\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 3: 维护活跃度未知\n\n- Trigger: 未记录 last_activity_observed。\n- Host AI rule: 补 GitHub 最近 commit、release、issue/PR 响应信号。\n- Why it matters: 新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- Evidence: evidence.maintainer_signals | github_repo:776908852 | https://github.com/browserbase/stagehand | last_activity_observed missing\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 4: 下游验证发现风险项\n\n- Trigger: no_demo\n- Host AI rule: 进入安全/权限治理复核队列。\n- Why it matters: 下游已经要求复核，不能在页面中弱化。\n- Evidence: downstream_validation.risk_items | github_repo:776908852 | https://github.com/browserbase/stagehand | no_demo; severity=medium\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 5: 存在评分风险\n\n- Trigger: no_demo\n- Host AI rule: 把风险写入边界卡，并确认是否需要人工复核。\n- Why it matters: 风险会影响是否适合普通用户安装。\n- Evidence: risks.scoring_risks | github_repo:776908852 | https://github.com/browserbase/stagehand | no_demo; severity=medium\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 6: issue/PR 响应质量未知\n\n- Trigger: issue_or_pr_quality=unknown。\n- Host AI rule: 抽样最近 issue/PR，判断是否长期无人处理。\n- Why it matters: 用户无法判断遇到问题后是否有人维护。\n- Evidence: evidence.maintainer_signals | github_repo:776908852 | https://github.com/browserbase/stagehand | issue_or_pr_quality=unknown\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 7: 发布节奏不明确\n\n- Trigger: release_recency=unknown。\n- Host AI rule: 确认最近 release/tag 和 README 安装命令是否一致。\n- Why it matters: 安装命令和文档可能落后于代码，用户踩坑概率升高。\n- Evidence: evidence.maintainer_signals | github_repo:776908852 | https://github.com/browserbase/stagehand | release_recency=unknown\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n",
      "summary": "给宿主 AI 的上下文和工作边界。",
      "title": "AI Context Pack / 带给我的 AI"
    },
    "boundary_risk_card": {
      "asset_id": "boundary_risk_card",
      "filename": "BOUNDARY_RISK_CARD.md",
      "markdown": "# Boundary & Risk Card / 安装前决策卡\n\n项目：browserbase/stagehand\n\n## Doramagic 试用结论\n\n当前结论：可以进入发布前推荐检查；首次使用仍应从最小权限、临时目录和可回滚配置开始。\n\n## 用户现在可以做\n\n- 可以先阅读 Human Manual，理解项目目的和主要工作流。\n- 可以复制 Prompt Preview 做安装前体验；这只验证交互感，不代表真实运行。\n- 可以把官方 Quick Start 命令放到隔离环境中验证，不要直接进主力环境。\n\n## 现在不要做\n\n- 不要把 Prompt Preview 当成项目实际运行结果。\n- 不要把 metadata-only validation 当成沙箱安装验证。\n- 不要把未验证能力写成“已支持、已跑通、可放心安装”。\n- 不要在首次试用时交出生产数据、私人文件、真实密钥或主力配置目录。\n\n## 安装前检查\n\n- 宿主 AI 是否匹配：local_cli\n- 官方安装入口状态：已发现官方入口\n- 是否在临时目录、临时宿主或容器中验证：必须是\n- 是否能回滚配置改动：必须能\n- 是否需要 API Key、网络访问、读写文件或修改宿主配置：未确认前按高风险处理\n- 是否记录了安装命令、实际输出和失败日志：必须记录\n\n## 当前阻塞项\n\n- 无阻塞项。\n\n## 项目专属踩坑\n\n- 仓库名和安装名不一致（medium）：用户照着仓库名搜索包或照着包名找仓库时容易走错入口。 建议检查：在 npm/PyPI/GitHub 上确认包名映射和官方 README 说明。\n- 能力判断依赖假设（medium）：假设不成立时，用户拿不到承诺的能力。 建议检查：将假设转成下游验证清单。\n- 维护活跃度未知（medium）：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 下游验证发现风险项（medium）：下游已经要求复核，不能在页面中弱化。 建议检查：进入安全/权限治理复核队列。\n- 存在评分风险（medium）：风险会影响是否适合普通用户安装。 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n\n## 风险与权限提示\n\n- no_demo: medium\n\n## 证据缺口\n\n- 暂未发现结构化证据缺口。\n",
      "summary": "安装、权限、验证和推荐前风险。",
      "title": "Boundary & Risk Card / 边界与风险卡"
    },
    "human_manual": {
      "asset_id": "human_manual",
      "filename": "HUMAN_MANUAL.md",
      "markdown": "# Wiki Documentation for https://github.com/browserbase/stagehand\n\nGenerated on: 2026-05-10 12:00:15 UTC\n\n## Table of Contents\n\n- [Stagehand 简介](#introduction)\n- [快速开始](#quickstart)\n- [系统架构总览](#architecture-overview)\n- [act() 操作执行](#act-api)\n- [extract() 数据提取](#extract-api)\n- [observe() 页面观察](#observe-api)\n- [Agent 代理系统](#agent-system)\n- [Handler 处理系统](#handler-system)\n- [DOM 与无障碍树](#dom-accessibility)\n- [Deep Locator 深层定位器](#deep-locator)\n\n<a id='introduction'></a>\n\n## Stagehand 简介\n\n### Related Pages\n\nRelated topics: [快速开始](#quickstart), [系统架构总览](#architecture-overview)\n\n<details>\n<summary>Relevant source files</summary>\n\nThe following files were used as context for generating this wiki page:\n\n- [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n- [packages/cli/src/local-strategy.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-strategy.ts)\n- [packages/cli/src/local-cdp-discovery.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-cdp-discovery.ts)\n</details>\n\n# Stagehand 简介\n\nStagehand 是一个基于浏览器自动化框架的工具，通过命令行接口（CLI）提供对浏览器的精细控制能力。该项目由 Browserbase 开发，支持本地和远程两种运行模式，能够执行页面导航、元素交互、网络请求捕获、截图等多种浏览器自动化任务。\n\n## 核心架构\n\nStagehand 采用客户端-守护进程（Client-Daemon）架构设计，CLI 作为客户端与守护进程通信，守护进程负责实际管理浏览器实例。\n\n```mermaid\ngraph TD\n    A[CLI Client] --> B[Socket Communication]\n    B --> C[Daemon Process]\n    C --> D[Browser Instance]\n    C --> E[Local CDP Discovery]\n    D --> F[Network Capture]\n    E --> C\n```\n\n### 守护进程基础设施\n\n守护进程管理依赖 Socket 文件进行进程间通信，关键路径配置如下：\n\n```typescript\nconst SOCKET_DIR = os.tmpdir();\n\nfunction getSocketPath(session: string): string {\n  return path.join(SOCKET_DIR, `browse-${session}.sock`);\n}\n\nfunction getLockPath(session: string): string {\n  return path.join(SOCKET_DIR, `browse-${session}.lock`);\n}\n```\n\n守护进程实现了基于文件锁的并发控制机制，使用 `O_EXCL` 标志确保原子性文件创建，防止竞争条件：\n\n```typescript\nasync function acquireLock(\n  session: string,\n  timeoutMs: number = 10000,\n): Promise<boolean> {\n  const lockPath = getLockPath(session);\n  // O_EXCL ensures atomic creation - fails if file exists\n  const handle = await fs.open(lockPath, \"wx\");\n  await handle.write(String(process.pid));\n  await handle.close();\n  return true;\n}\n```\n\nSources: [packages/cli/src/index.ts:1-50]()\n\n## CLI 命令系统\n\nStagehand CLI 提供丰富的命令集，覆盖浏览器自动化的各个方面。\n\n### 导航与页面操作\n\n| 命令 | 说明 | 关键选项 |\n|------|------|----------|\n| `open <url>` | 导航到指定 URL | `--wait`, `--timeout`, `--context-id`, `--persist` |\n| `goto <url>` | `open` 的别名 | 同上 |\n| `pages` | 列出所有打开的页面 | - |\n| `newpage [url]` | 创建新页面/标签页 | - |\n\n导航命令支持多种等待状态：\n\n- `load`（默认）\n- `domcontentloaded`\n- `networkidle`\n\n```typescript\nprogram\n  .command(\"open <url>\")\n  .alias(\"goto\")\n  .description(\"Navigate to URL\")\n  .option(\n    \"--wait <state>\",\n    \"Wait state: load, domcontentloaded, networkidle\",\n    \"load\",\n  )\n  .option(\"-t, --timeout <ms>\", \"Navigation timeout in milliseconds\", \"30000\")\n```\n\nSources: [packages/cli/src/index.ts:80-130]()\n\n### 元素交互\n\n元素操作命令支持通过选择器精确定位和操作 DOM 元素：\n\n| 命令 | 说明 | 选项 |\n|------|------|------|\n| `click <selector>` | 点击元素 | `--button`, `--delay`, `--xpath` |\n| `dblclick <selector>` | 双击元素 | `--button`, `--delay` |\n| `fill <selector> <value>` | 填充输入框 | `--no-press-enter` |\n| `select <selector> <values...>` | 选择下拉选项 | - |\n| `hover <x> <y>` | 悬停在坐标位置 | `--xpath` |\n| `scroll <x> <y> <deltaX> <deltaY>` | 滚动操作 | `--xpath` |\n| `drag <fromX> <fromY> <toX> <toY>` | 拖拽操作 | `--delay`, `--xpath` |\n\n```typescript\nprogram\n  .command(\"fill <selector> <value>\")\n  .description(\"Fill input element (presses Enter by default)\")\n  .option(\"--no-press-enter\", \"Don't press Enter after filling\")\n  .action(async (selector: string, value: string, cmdOpts) => {\n    const pressEnter = cmdOpts.pressEnter !== false;\n    const result = await runCommand(\"fill\", [selector, value, { pressEnter }]);\n  });\n```\n\nSources: [packages/cli/src/index.ts:150-200]()\n\n### 键盘与输入\n\n| 命令 | 说明 | 选项 |\n|------|------|------|\n| `type <text>` | 输入文本 | `-d, --delay`, `--mistakes` |\n| `press <key>` | 按下按键 | - |\n| `key <key>` | `press` 的别名 | - |\n\n```typescript\nprogram\n  .command(\"type <text>\")\n  .description(\"Type text\")\n  .option(\"-d, --delay <ms>\", \"Delay between keystrokes\")\n  .option(\"--mistakes\", \"Enable human-like typing with mistakes\")\n```\n\n### 页面信息获取\n\n| 命令 | 说明 | 获取类型 |\n|------|------|----------|\n| `get <what> [selector]` | 获取页面信息 | `url`, `title`, `text`, `html`, `markdown`, `value`, `box`, `visible`, `checked` |\n\n```typescript\nprogram\n  .command(\"get <what> [selector]\")\n  .description(\n    \"Get page info: url, title, text, html, markdown, value, box, visible, checked\",\n  )\n```\n\n### 截图功能\n\n截图命令支持多种输出格式和裁剪选项：\n\n```typescript\nprogram\n  .command(\"screenshot [path]\")\n  .description(\"Take screenshot\")\n  .option(\"-f, --full-page\", \"Full page screenshot\")\n  .option(\"-t, --type <type>\", \"Image type: png, jpeg\", \"png\")\n  .option(\"-q, --quality <n>\", \"JPEG quality (0-100)\")\n  .option(\"--clip <json>\", \"Clip region as JSON\")\n  .option(\"--no-animations\", \"Disable animations\")\n  .option(\"--hide-caret\", \"Hide text caret\")\n```\n\nSources: [packages/cli/src/index.ts:220-280]()\n\n### 可访问性快照\n\n获取页面的可访问性树快照：\n\n```typescript\nprogram\n  .command(\"snapshot\")\n  .description(\"Get accessibility tree snapshot\")\n  .option(\"-c, --compact\", \"Output tree only (no xpath map)\")\n```\n\n快照返回结构包含：\n- `tree`: 格式化的可访问性树\n- `xpathMap`: 元素到 XPath 的映射\n- `urlMap`: URL 映射\n\nSources: [packages/cli/src/index.ts:290-310]()\n\n### 等待与状态检查\n\n| 命令 | 说明 | 状态值 |\n|------|------|--------|\n| `wait <type> [arg]` | 等待条件 | `load`, `selector`, `timeout` |\n| `is <check> <selector>` | 检查元素状态 | `visible`, `checked` |\n\n```typescript\nprogram\n  .command(\"wait <type> [arg]\")\n  .description(\"Wait for: load, selector, timeout\")\n  .option(\"-t, --timeout <ms>\", \"Timeout\", \"30000\")\n  .option(\"-s, --state <state>\", \"Element state: visible, hidden, attached, detached\", \"visible\")\n```\n\nSources: [packages/cli/src/index.ts:50-80]()\n\n### 视口控制\n\n```typescript\nprogram\n  .command(\"viewport <width> <height>\")\n  .description(\"Set viewport size\")\n  .option(\"-s, --scale <n>\", \"Device scale factor\", \"1\")\n```\n\n## 本地浏览器策略\n\nStagehand 支持多种本地浏览器启动策略，可通过配置灵活选择。\n\n### 策略类型\n\n| 策略 | 说明 | 适用场景 |\n|------|------|----------|\n| `isolated` | 启动独立的 Chromium 实例 | 完全隔离的自动化任务 |\n| `cdp` | 连接到指定的 Chrome DevTools Protocol 端点 | 复用已有浏览器会话 |\n| `auto` | 自动检测本地浏览器，无则启动隔离实例 | 通用场景 |\n\n```typescript\nexport async function resolveLocalStrategy({\n  localConfig,\n  headless,\n  defaultViewport,\n  discoverLocalCdp,\n  resolveWsTarget,\n}: ResolveLocalStrategyOptions): Promise<ResolvedLocalStrategy> {\n  if (localConfig.strategy === \"isolated\") {\n    return {\n      localLaunchOptions: { headless, viewport: defaultViewport },\n      localInfo: { localSource: \"isolated\" },\n    };\n  }\n\n  if (localConfig.strategy === \"cdp\") {\n    const cdpUrl = await resolveWsTarget(localConfig.cdpTarget);\n    return {\n      localLaunchOptions: { cdpUrl },\n      localInfo: { localSource: \"attached-explicit\", resolvedCdpUrl: cdpUrl },\n    };\n  }\n}\n```\n\nSources: [packages/cli/src/local-strategy.ts:1-80]()\n\n### CDP 自动发现\n\n系统支持自动发现本地运行的 Chrome 实例：\n\n```typescript\nasync function probeFallbackPort(port: number): Promise<string | null> {\n  const jsonVersionUrl = await probeJsonVersion(port);\n  if (jsonVersionUrl) {\n    return jsonVersionUrl;\n  }\n  // WebSocket fallback...\n}\n```\n\nSources: [packages/cli/src/local-cdp-discovery.ts:1-50]()\n\n### 本地模式提示\n\n根据不同的启动策略，系统会提供相应的使用提示：\n\n```typescript\nconst ISOLATED_MODE_HINT = \"Hint: Run `browse env local --auto-connect` to reuse your local browsing credentials and cookies.\";\nconst ATTACHED_EXISTING_HINT = \"Hint: Run `browse env local` without `--auto-connect` to switch back to an isolated Chromium browser.\";\n```\n\n## 网络捕获功能\n\nStagehand 提供完整的网络请求捕获和持久化能力。\n\n### 数据模型\n\n```typescript\ninterface PendingRequest {\n  id: string;\n  timestamp: string;\n  method: string;\n  url: string;\n  headers: Record<string, string>;\n  body: string | null;\n  resourceType: string;\n}\n```\n\n### 文件系统组织\n\n捕获的网络请求按以下结构存储：\n\n```\n{networkDir}/\n  {counter}-{method}-{domain}-{pathSlug}/\n    request.json   # 请求详情\n    response.json  # 响应详情\n```\n\n文件名生成逻辑：\n\n```typescript\nfunction getRequestDirName(\n  counter: number,\n  method: string,\n  url: string,\n): string {\n  const parsed = new URL(url);\n  const domain = sanitizeForFilename(parsed.hostname, 30);\n  const pathPart = parsed.pathname.split(\"/\").filter(Boolean)[0] || \"root\";\n  const pathSlug = sanitizeForFilename(pathPart, 20);\n  return `${String(counter).padStart(3, \"0\")}-${method}-${domain}-${pathSlug}`;\n}\n\nfunction sanitizeForFilename(str: string, maxLen: number = 30): string {\n  return str\n    .replace(/[^a-zA-Z0-9.-]/g, \"-\")\n    .replace(/-+/g, \"-\")\n    .replace(/^-|-$/g, \"\")\n    .slice(0, maxLen);\n}\n```\n\nSources: [packages/cli/src/index.ts:55-100]()\n\n## 全局配置选项\n\nCLI 支持通过全局选项配置会话和行为：\n\n```typescript\ninterface GlobalOpts {\n  ws?: string;              // WebSocket 连接地址\n  headless?: boolean;       // 无头模式\n  headed?: boolean;         // 有头模式（优先于 headless）\n  json?: boolean;           // JSON 输出格式\n  session?: string;         // 会话标识\n  connect?: string;         // 连接目标\n  proxies?: boolean;        // 启用代理（远程模式）\n  advancedStealth?: boolean; // 高级隐身模式\n  solveCaptchas?: boolean;   // 自动解决验证码\n  region?: string;          // 区域设置\n  keepAlive?: boolean;       // 保持连接\n  sessionTimeout?: number;   // 会话超时时间\n  blockAds?: boolean;       // 屏蔽广告\n}\n```\n\n## 守护进程生命周期管理\n\n### 启动与停止\n\n```typescript\nprogram\n  .command(\"start\")\n  .description(\"Start browser daemon\")\n  .action(async () => {\n    if (await isDaemonRunning(session)) {\n      console.log(JSON.stringify({ status: \"already running\", session }));\n      return;\n    }\n    await ensureDaemon(session, isHeadless(opts));\n  });\n\nprogram\n  .command(\"stop\")\n  .description(\"Stop browser daemon\")\n  .option(\"--force\", \"Force kill Chrome processes if daemon is unresponsive\")\n```\n\n### 自动重连机制\n\nCLI 实现了智能重连策略，在连接失败时自动尝试恢复：\n\n```typescript\n// Attempt 0: Brief wait and retry\nif (attempt === 0) {\n  await new Promise((r) => setTimeout(r, 200));\n  continue;\n}\n\n// Attempt 1: Try to restart daemon without cleanup\nif (attempt === 1) {\n  await ensureDaemon(session, headless);\n  continue;\n}\n\n// Final attempt: Full cleanup and restart\nawait killChromeProcesses(session);\nawait cleanupStaleFiles(session);\nawait ensureDaemon(session, headless);\n```\n\nSources: [packages/cli/src/index.ts:350-450]()\n\n## 命令执行流程\n\n```mermaid\nsequenceDiagram\n    participant CLI\n    participant Daemon\n    participant Browser\n    \n    CLI->>Daemon: sendCommand(command, args)\n    Daemon->>Browser: Execute action\n    Browser-->>Daemon: Result\n    Daemon-->>CLI: Return result\n    CLI->>CLI: output(result, json?)\n```\n\n命令执行的核心逻辑：\n\n```typescript\nasync function runCommand(\n  command: string,\n  args: unknown[],\n  retries: number = 3,\n): Promise<unknown> {\n  for (let attempt = 0; attempt < retries; attempt++) {\n    try {\n      return await sendCommand(session, command, args);\n    } catch (err) {\n      // Connection error handling...\n      if (attempt === 0) {\n        await new Promise((r) => setTimeout(r, 200));\n        continue;\n      }\n      await ensureDaemon(session, headless);\n    }\n  }\n}\n```\n\n## 快速入门\n\n### 基本导航\n\n```bash\n# 打开网页\nstagehand open https://example.com\n\n# 带等待状态\nstagehand open https://example.com --wait networkidle\n```\n\n### 元素交互\n\n```bash\n# 点击按钮\nstagehand click \"#submit-button\"\n\n# 填充表单\nstagehand fill \"input[name=email]\" \"user@example.com\"\nstagehand fill \"input[name=password]\" \"secret123\"\n```\n\n### 页面信息\n\n```bash\n# 获取页面标题\nstagehand get title\n\n# 获取元素文本\nstagehand get text \".article-content\"\n\n# 获取可访问性树\nstagehand snapshot\n```\n\n### 截图\n\n```bash\n# 普通截图\nstagehand screenshot output.png\n\n# 全页截图\nstagehand screenshot full-page.png --full-page\n\n# 指定区域\nstagehand screenshot cropped.png --clip '{\"x\":0,\"y\":0,\"width\":800,\"height\":600}'\n```\n\n## 总结\n\nStagehand 提供了一套完整的浏览器自动化解决方案，具有以下特点：\n\n1. **丰富的命令集**：覆盖导航、交互、信息获取、网络捕获等各方面\n2. **灵活的运行模式**：支持本地和远程两种部署方式\n3. **智能的策略选择**：可根据需求选择隔离、CDP 或自动模式\n4. **可靠的守护进程**：实现了进程锁和自动重连机制\n5. **详细的网络捕获**：支持完整的请求/响应持久化\n\n---\n\n<a id='quickstart'></a>\n\n## 快速开始\n\n### Related Pages\n\nRelated topics: [Stagehand 简介](#introduction), [系统架构总览](#architecture-overview)\n\n<details>\n<summary>Relevant source files</summary>\n\nThe following files were used as context for generating this wiki page:\n\n- [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n- [packages/cli/src/local-strategy.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-strategy.ts)\n- [packages/cli/src/local-cdp-discovery.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-cdp-discovery.ts)\n- [packages/cli/tsup.config.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/tsup.config.ts)\n</details>\n\n# 快速开始\n\nStagehand 是一个由 Browserbase 开发的浏览器自动化框架，提供 CLI 工具和 Core SDK 两种使用方式，支持本地浏览器和远程 Browserbase 云端浏览器的自动化操作。\n\n## 环境准备\n\n### 前置要求\n\n| 要求 | 说明 |\n|------|------|\n| Node.js | 版本 20+ |\n| Playwright | 用户需自行安装 `playwright` 或 `playwright-core` 包 |\n| 系统依赖 | Chrome/Chromium 浏览器（本地模式） |\n\n### 安装步骤\n\n```bash\n# 安装核心包\nnpm install @browserbasehq/stagehand\n\n# 安装 Playwright（必须）\nnpm install playwright\n\n# 安装浏览器驱动\nnpx playwright install chromium\n```\n\n### 环境变量配置\n\n在项目根目录创建 `.env` 文件，配置必要的环境变量：\n\n```bash\n# Browserbase 云端模式必需\nBROWSERBASE_API_KEY=your_api_key\nBROWSERBASE_PROJECT_ID=your_project_id\n\n# 本地模式可选配置\nBROWSERBASE_API_KEY=    # 留空则使用本地模式\n```\n\nSources: [.env.example](https://github.com/browserbase/stagehand/blob/main/.env.example)\n\n## CLI 快速上手\n\nStagehand CLI 提供丰富的浏览器自动化命令，安装后可通过 `npx stagehand` 或直接安装为全局命令使用。\n\n### 基础命令结构\n\n```bash\n# 基本语法\nstagehand [options] [command] [arguments]\n\n# 常用全局选项\n# --session <name>    指定会话名称\n# --headless         以无头模式运行\n# --connect <url>    连接到远程 Browserbase 会话\n# --json             以 JSON 格式输出结果\n```\n\nSources: [packages/cli/src/index.ts:1-50](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n### 导航与页面操作\n\n```bash\n# 打开网页\nstagehand open https://example.com\n\n# 等待页面加载完成\nstagehand open https://example.com --wait load\n\n# 页面加载超时设置（毫秒）\nstagehand open https://example.com --timeout 30000\n\n# 创建新标签页\nstagehand newpage https://example.com\n\n# 切换标签页（按索引）\nstagehand tab_switch 1\n\n# 关闭标签页\nstagehand tab_close\n```\n\nSources: [packages/cli/src/index.ts:200-260](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n## 元素交互\n\n### 常见交互命令\n\n| 命令 | 说明 | 示例 |\n|------|------|------|\n| `fill` | 填写输入框 | `stagehand fill \"#search\" \"关键词\"` |\n| `select` | 选择下拉选项 | `stagehand select \"#dropdown\" \"选项1\"` |\n| `click` | 点击元素 | `stagehand click \"#submit\"` |\n| `type` | 模拟键盘输入 | `stagehand type \"Hello World\"` |\n| `press` | 按下特定按键 | `stagehand press \"Enter\"` |\n\n### 填写表单示例\n\n```bash\n# 填写输入框（默认会按 Enter）\nstagehand fill \"#username\" \"myuser\"\nstagehand fill \"#password\" \"mypass\"\n\n# 不自动按 Enter\nstagehand fill \"#input\" \"value\" --no-press-enter\n\n# 输入延迟（模拟人工打字）\nstagehand type \"Hello\" --delay 100\n\n# 启用人工化输入（含随机错误）\nstagehand type \"Hello\" --mistakes\n```\n\nSources: [packages/cli/src/index.ts:150-200](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n### 键盘操作\n\n```bash\n# 按下按键\nstagehand press Enter\nstagehand press Tab\nstagehand press Escape\nstagehand press \"Cmd+A\"\n\n# 组合键示例\nstagehand press \"Cmd+C\"\n```\n\nSources: [packages/cli/src/index.ts:140-160](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n## 元素状态检查\n\n### 检查命令\n\n```bash\n# 检查元素是否可见\nstagehand is visible \"#submit-button\"\n\n# 检查复选框是否选中\nstagehand is checked \"#agree-checkbox\"\n```\n\n### 获取页面信息\n\n```bash\n# 获取页面 URL\nstagehand get url\n\n# 获取页面标题\nstagehand get title\n\n# 获取元素文本内容\nstagehand get text \"#heading\"\n\n# 获取元素 HTML\nstagehand get html \"#container\"\n\n# 获取元素 Markdown 格式内容\nstagehand get markdown \"#article\"\n\n# 获取元素值\nstagehand get value \"#input\"\n\n# 获取元素边界框\nstagehand get box \"#image\"\n\n# 获取可见性状态\nstagehand get visible \"#hidden-element\"\n```\n\nSources: [packages/cli/src/index.ts:280-320](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n## 等待与同步\n\n### 等待命令\n\n```bash\n# 等待页面加载\nstagehand wait load\n\n# 等待选择器出现\nstagehand wait selector \"#content\"\n\n# 等待超时（毫秒）\nstagehand wait selector \"#loading\" --timeout 10000\n\n# 等待元素状态\nstagehand wait selector \"#modal\" --state visible\nstagehand wait selector \"#tooltip\" --state hidden\nstagehand wait selector \"#element\" --state attached\n```\n\n状态选项：`visible`、`hidden`、`attached`、`detached`\n\nSources: [packages/cli/src/index.ts:50-80](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n## 截图与快照\n\n### 截图功能\n\n```bash\n# 基础截图\nstagehand screenshot\n\n# 保存到指定路径\nstagehand screenshot ./screenshot.png\n\n# 全页面截图\nstagehand screenshot ./full-page.png --full-page\n\n# 指定图片格式和质量\nstagehand screenshot ./output.jpg --type jpeg --quality 85\n\n# 裁剪区域（JSON 格式）\nstagehand screenshot ./cropped.png --clip '{\"x\":0,\"y\":0,\"width\":800,\"height\":600}'\n\n# 禁用动画和隐藏光标\nstagehand screenshot ./clean.png --no-animations --hide-caret\n```\n\nSources: [packages/cli/src/index.ts:340-380](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n### 辅助功能树快照\n\n```bash\n# 获取完整快照（含 XPath 映射）\nstagehand snapshot\n\n# 紧凑输出（仅树结构）\nstagehand snapshot --compact\n```\n\n快照输出包含：\n- `tree`: 格式化的辅助功能树\n- `xpathMap`: 元素到 XPath 的映射\n- `urlMap`: URL 引用映射\n\nSources: [packages/cli/src/index.ts:380-420](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n## 坐标操作\n\n### 鼠标操作\n\n```bash\n# 悬停到坐标位置\nstagehand hover 100 200\n\n# 悬停并返回元素 XPath\nstagehand hover 100 200 --xpath\n\n# 滚动页面\nstagehand scroll 0 500 0 100\n\n# 拖拽操作\nstagehand drag 100 200 300 400\n```\n\nSources: [packages/cli/src/index.ts:220-250](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n## 视图控制\n\n```bash\n# 设置视口大小\nstagehand viewport 1920 1080\n\n# 设置缩放比例\nstagehand viewport 1920 1080 --scale 2\n```\n\nSources: [packages/cli/src/index.ts:420-440](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n## Daemon 模式\n\nStagehand 使用守护进程模式管理浏览器实例，支持会话复用。\n\n### 进程管理命令\n\n```bash\n# 启动守护进程\nstagehand start\n\n# 停止守护进程\nstagehand stop\n\n# 强制停止（杀掉 Chrome 进程）\nstagehand stop --force\n\n# 检查状态\nstagehand status\n```\n\n### 会话管理\n\n```bash\n# 使用指定会话\nstagehand --session my-session open https://example.com\n\n# 远程模式会话超时\nstagehand --session my-session --session-timeout 300 open https://example.com\n```\n\nSources: [packages/cli/src/index.ts:450-520](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n## 本地模式策略\n\nStagehand CLI 支持多种本地浏览器模式：\n\n```mermaid\ngraph TD\n    A[开始解析本地策略] --> B{strategy 配置}\n    B -->|isolated| C[启动独立 Chromium 实例]\n    B -->|cdp| D[连接到指定 CDP 目标]\n    B -->|auto| E[自动检测本地浏览器]\n    E -->|发现调试端口| F[附加到现有浏览器]\n    E -->|未发现| G[回退到隔离模式]\n    \n    C --> H[返回 localSource: isolated]\n    D --> I[返回 localSource: attached-explicit]\n    F --> J[返回 localSource: attached-existing]\n    G --> K[返回 localSource: isolated-fallback]\n```\n\n| 策略 | 说明 | localSource 值 |\n|------|------|-----------------|\n| `isolated` | 启动独立的 Chromium 实例 | `isolated` |\n| `cdp` | 通过 CDP URL 连接到指定浏览器 | `attached-explicit` |\n| `auto` | 自动检测或回退 | `attached-existing` / `isolated-fallback` |\n\nSources: [packages/cli/src/local-strategy.ts:20-80](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-strategy.ts)\n\n## CDP 发现机制\n\n本地模式支持自动发现 Chrome DevTools 协议端点：\n\n```mermaid\ngraph LR\n    A[扫描用户数据目录] --> B{读取 DevToolsActivePort}\n    B -->|成功| C{检查端口可达性}\n    B -->|失败| D[尝试备用端口]\n    C -->|可达| E[构建 WebSocket URL]\n    C -->|不可达| D\n    D --> E\n    E --> F[返回 cdpUrl]\n```\n\nSources: [packages/cli/src/local-cdp-discovery.ts:1-60](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-cdp-discovery.ts)\n\n## 输出格式\n\n### JSON 输出模式\n\n```bash\n# 启用 JSON 输出\nstagehand get title --json\n\n# 示例输出\n{\n  \"success\": true,\n  \"data\": {\n    \"title\": \"Example Domain\"\n  }\n}\n```\n\n### 基础输出\n\n默认情况下，CLI 以人类可读格式输出结果：\n\n```bash\nstagehand get url\n# 输出: https://example.com\n\nstagehand snapshot --compact\n# 输出: 辅助功能树结构\n```\n\n## 网络请求捕获\n\nStagehand 支持捕获和分析网络请求：\n\n```mermaid\ngraph TD\n    A[请求进入] --> B{网络捕获启用?}\n    B -->|否| C[跳过]\n    B -->|是| D[记录请求元数据]\n    D --> E[等待响应]\n    E --> F[写入文件系统]\n    F --> G[生成目录结构]\n    \n    G --> H[request.json]\n    G --> I[response.json]\n```\n\n请求数据存储结构：\n```\n<networkDir>/\n  └── <counter>-<METHOD>-<domain>-<path>/\n      ├── request.json   # 请求详情\n      └── response.json  # 响应详情\n```\n\nSources: [packages/cli/src/index.ts:80-150](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n## 常见工作流示例\n\n### 自动化测试流程\n\n```bash\n# 1. 启动并导航\nstagehand open https://example.com --wait load\n\n# 2. 获取初始快照\nstagehand snapshot --compact > initial-state.txt\n\n# 3. 执行交互\nstagehand fill \"#search\" \"test query\"\nstagehand press Enter\n\n# 4. 等待结果加载\nstagehand wait selector \".results\" --timeout 10000\n\n# 5. 截图保存\nstagehand screenshot ./search-results.png\n\n# 6. 验证结果\nstagehand is visible \".result-item\"\n```\n\n### 数据采集流程\n\n```bash\n# 1. 导航到目标页面\nstagehand open https://news.example.com\n\n# 2. 截图存档\nstagehand screenshot ./news-$(date +%Y%m%d).png --full-page\n\n# 3. 获取内容\nstagehand get markdown \"article\"\n\n# 4. 关闭浏览器\nstagehand stop\n```\n\n## 故障排除\n\n| 问题 | 解决方案 |\n|------|----------|\n| 连接被拒绝 | 运行 `stagehand start` 启动守护进程 |\n| 浏览器未响应 | 使用 `stagehand stop --force` 强制停止 |\n| 超时错误 | 增加 `--timeout` 参数值 |\n| CDP 连接失败 | 检查 Chrome 是否以 `--remote-debugging-port` 启动 |\n\n### 查看详细日志\n\n```bash\n# 启用详细输出\nstagehand --verbose open https://example.com\n\n---\n\n<a id='architecture-overview'></a>\n\n## 系统架构总览\n\n### Related Pages\n\nRelated topics: [Stagehand 简介](#introduction), [Handler 处理系统](#handler-system)\n\n<details>\n<summary>Relevant source files</summary>\n\nThe following files were used as context for generating this wiki page:\n\n- [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n- [packages/cli/src/local-strategy.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-strategy.ts)\n- [packages/cli/src/local-cdp-discovery.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-cdp-discovery.ts)\n</details>\n\n# 系统架构总览\n\n## 1. 项目概述\n\nStagehand 是一个基于 Chrome DevTools Protocol (CDP) 的浏览器自动化 CLI 工具和 SDK，提供命令行界面和编程 API 两种交互方式。该项目采用 monorepo 结构，使用 pnpm workspace 管理多个包。\n\n核心能力包括：\n\n- 浏览器页面导航与交互\n- 元素定位与操作\n- 截图与 DOM 快照\n- 网络请求捕获\n- 本地浏览器发现与连接\n- Daemon 进程管理\n\nSources: [packages/cli/src/index.ts:1-50]()\n\n## 2. 整体架构\n\nStagehand 采用客户端-服务器架构，核心组件包括：\n\n```mermaid\ngraph TD\n    subgraph CLI层\n        A[CLI Commands] --> B[runCommand]\n        B --> C[runDaemon]\n    end\n    \n    subgraph 通信层\n        D[Unix Socket] <--> E[WebSocket Bridge]\n        F[Lock File] \n    end\n    \n    subgraph Daemon层\n        G[Browser Daemon] --> H[Playwright Page]\n        H --> I[Accessibility Snapshot]\n    end\n    \n    subgraph 本地发现\n        J[CDP Discovery] --> K[DevTools Active Port]\n        K --> L[WebSocket Target]\n    end\n    \n    A --> D\n    C --> D\n    G --> J\n```\n\nSources: [packages/cli/src/index.ts:200-300]()\n\n## 3. CLI 命令体系\n\nCLI 使用 commander.js 框架实现，所有命令都通过 `runCommand` 函数统一路由到 Daemon 进程执行。\n\n### 3.1 命令分类表\n\n| 类别 | 命令 | 功能描述 |\n|------|------|----------|\n| 导航 | `open`, `goto` | 页面导航 |\n| 元素 | `click`, `dblclick`, `hover` | 元素交互 |\n| 输入 | `fill`, `select`, `type`, `press` | 文本与选择操作 |\n| 查询 | `get`, `is`, `snapshot` | 页面信息获取 |\n| 截图 | `screenshot` | 页面截图 |\n| 坐标 | `scroll`, `drag` | 视口操作 |\n| 网络 | `network` | 网络请求捕获 |\n| 多页 | `pages`, `newpage` | 多标签页管理 |\n| 守护 | `start`, `stop`, `status` | Daemon 控制 |\n\nSources: [packages/cli/src/index.ts:50-200]()\n\n### 3.2 命令执行流程\n\n```mermaid\nsequenceDiagram\n    participant CLI as CLI Client\n    participant Socket as Unix Socket\n    participant Daemon as Browser Daemon\n    participant Browser as Playwright Browser\n    \n    CLI->>Socket: sendCommand(command, args)\n    Socket->>Daemon: 转发请求\n    Daemon->>Browser: 执行操作\n    Browser-->>Daemon: 返回结果\n    Daemon-->>Socket: 序列化响应\n    Socket-->>CLI: 返回结果\n    CLI->>CLI: output(result, json)\n```\n\nSources: [packages/cli/src/index.ts:300-400]()\n\n## 4. Daemon 基础设施\n\nDaemon 是长期运行的浏览器进程管理服务，通过 Unix Socket 与 CLI 通信。\n\n### 4.1 Socket 通信机制\n\n```typescript\n// Socket 路径: /tmp/browse-{session}.sock\nfunction getSocketPath(session: string): string {\n  return path.join(os.tmpdir(), `browse-${session}.sock`);\n}\n```\n\nSources: [packages/cli/src/index.ts:350-360]()\n\n### 4.2 文件锁机制\n\n系统使用 O_EXCL 模式的原子文件创建实现互斥锁，防止多进程竞争：\n\n```typescript\nasync function acquireLock(\n  session: string,\n  timeoutMs: number = 10000\n): Promise<boolean> {\n  const lockPath = getLockPath(session);\n  // O_EXCL 确保原子创建\n  const handle = await fs.open(lockPath, \"wx\");\n  await handle.write(String(process.pid));\n}\n```\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| session | string | \"default\" | 会话标识符 |\n| timeoutMs | number | 10000 | 锁等待超时 |\n\nSources: [packages/cli/src/index.ts:380-420]()\n\n### 4.3 连接重试策略\n\n当连接失败时，系统自动执行三级重试：\n\n| 重试次数 | 策略 | 动作 |\n|----------|------|------|\n| 0 | 短暂等待 | 等待 200ms 后重试 |\n| 1 | 重启 Daemon | 不清理状态重启 |\n| 2 | 完全清理 | 杀死进程、清理文件、重启 |\n\nSources: [packages/cli/src/index.ts:450-500]()\n\n## 5. 本地模式策略系统\n\n本地模式支持三种策略：`auto`、`isolated` 和 `cdp`。\n\n### 5.1 策略决策流程\n\n```mermaid\ngraph TD\n    A[resolveLocalStrategy] --> B{strategy === isolated?}\n    B -->|是| C[使用 headless + viewport]\n    B -->|否| D{strategy === cdp?}\n    D -->|是| E[解析 cdpTarget]\n    D -->|否| F[discoverLocalCdp]\n    F --> G{发现浏览器?}\n    G -->|是| H[连接现有浏览器]\n    G -->|否| I[isolated-fallback]\n```\n\nSources: [packages/cli/src/local-strategy.ts:30-70]()\n\n### 5.2 策略类型对比\n\n| 策略 | 说明 | 使用场景 |\n|------|------|----------|\n| `auto` | 自动发现或创建 | 默认模式，智能选择 |\n| `isolated` | 启动独立浏览器实例 | 完全隔离的环境 |\n| `cdp` | 连接到指定 CDP 端点 | 复用现有浏览器会话 |\n\nSources: [packages/cli/src/local-strategy.ts:10-50]()\n\n### 5.3 本地信息源\n\n| 来源类型 | 说明 | 提示信息 |\n|----------|------|----------|\n| `attached-existing` | 连接已存在的调试浏览器 | 提示使用 `--auto-connect` |\n| `attached-explicit` | 显式指定 CDP 目标 | - |\n| `isolated` | 独立启动的浏览器 | 提示切换到 attached 模式 |\n| `isolated-fallback` | 无法发现时的回退 | - |\n\nSources: [packages/cli/src/local-strategy.ts:50-80]()\n\n## 6. CDP 发现机制\n\nCDP (Chrome DevTools Protocol) 发现用于自动找到本地运行的 Chrome 浏览器实例。\n\n### 6.1 发现流程\n\n```mermaid\ngraph LR\n    A[读取 DevToolsActivePort] --> B{端口可达?}\n    B -->|否| C[cleanup 过期文件]\n    B -->|是| D[构建 WebSocket URL]\n    E[探测 JSON Version] --> F{成功?}\n    F -->|是| D\n    F -->|否| G[探测 WebSocket]\n```\n\nSources: [packages/cli/src/local-cdp-discovery.ts:100-150]()\n\n### 6.2 WebSocket 探测\n\n系统通过低层 TCP 握手检测 WebSocket 支持：\n\n```typescript\nasync function probeWebSocket(port: number): Promise<boolean> {\n  // 发送 HTTP Upgrade 请求\n  const response = await performWebSocketHandshake(port, wsKey);\n  // 检查 101 Switching Protocols 响应\n  return /^HTTP\\/1\\.[01] 101(?:\\s|$)/.test(response);\n}\n```\n\nSources: [packages/cli/src/local-cdp-discovery.ts:50-80]()\n\n## 7. 全局配置选项\n\nCLI 全局选项通过 `GlobalOpts` 接口定义：\n\n| 选项 | 类型 | 说明 |\n|------|------|------|\n| `--session` | string | 会话标识 |\n| `--headless` | boolean | 无头模式 |\n| `--headed` | boolean | 窗口模式 |\n| `--json` | boolean | JSON 输出 |\n| `--ws` | string | WebSocket 地址 |\n| `--connect` | string | 远程连接地址 |\n| `--proxies` | boolean | 启用代理 (远程) |\n| `--region` | string | 区域设置 (远程) |\n| `--block-ads` | boolean | 广告拦截 (远程) |\n\nSources: [packages/cli/src/index.ts:500-550]()\n\n## 8. 网络捕获系统\n\n系统提供完整的网络请求/响应捕获能力。\n\n### 8.1 捕获数据结构\n\n```typescript\ninterface PendingRequest {\n  id: string;\n  timestamp: string;\n  method: string;\n  url: string;\n  headers: Record<string, string>;\n  body: string | null;\n  resourceType: string;\n}\n```\n\n### 8.2 文件存储结构\n\n每个请求保存到独立目录：\n\n```\n{networkDir}/\n  └── {counter:3d}-{method}-{domain}-{pathSlug}/\n      ├── request.json   # 请求元数据\n      └── response.json  # 响应元数据\n```\n\nSources: [packages/cli/src/index.ts:100-180]()\n\n## 9. 页面信息获取\n\n`snapshot` 命令提供可访问性树快照功能：\n\n```typescript\ncase \"snapshot\": {\n  const snapshot = await page!.snapshot();\n  return {\n    tree: snapshot.formattedTree,\n    xpathMap: snapshot.xpathMap,\n    urlMap: snapshot.urlMap,\n  };\n}\n```\n\n| 输出字段 | 类型 | 说明 |\n|----------|------|------|\n| `tree` | string | 格式化的可访问性树 |\n| `xpathMap` | Record | 选择器到 XPath 的映射 |\n| `urlMap` | Record | 元素到 URL 的映射 |\n\nSources: [packages/cli/src/index.ts:250-280]()\n\n## 10. 关键技术栈\n\n| 组件 | 技术选型 |\n|------|----------|\n| CLI 框架 | commander.js |\n| 浏览器自动化 | Playwright |\n| 通信协议 | Unix Socket + WebSocket |\n| 包管理 | pnpm workspace |\n\nSources: [pnpm-workspace.yaml](https://github.com/browserbase/stagehand/blob/main/pnpm-workspace.yaml)()\n\n---\n\n<a id='act-api'></a>\n\n## act() 操作执行\n\n### Related Pages\n\nRelated topics: [observe() 页面观察](#observe-api), [extract() 数据提取](#extract-api), [Handler 处理系统](#handler-system)\n\n<details>\n<summary>Relevant source files</summary>\n\nThe following files were used as context for generating this wiki page:\n\n- [packages/core/lib/v3/handlers/actHandler.ts](https://github.com/browserbase/stagehand/blob/main/packages/core/lib/v3/handlers/actHandler.ts)\n- [packages/core/lib/v3/agent/tools/act.ts](https://github.com/browserbase/stagehand/blob/main/packages/core/lib/v3/agent/tools/act.ts)\n- [packages/core/lib/v3/agent/tools/click.ts](https://github.com/browserbase/stagehand/blob/main/packages/core/lib/v3/agent/tools/click.ts)\n- [packages/core/lib/v3/agent/tools/type.ts](https://github.com/browserbase/stagehand/blob/main/packages/core/lib/v3/agent/tools/type.ts)\n- [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n</details>\n\n# act() 操作执行\n\n## 概述\n\n`act()` 是 Stagehand 框架中的核心操作执行机制，负责将高级自然语言指令转换为具体的浏览器自动化操作。该系统通过 Handler-工具（Tool）架构模式，实现了操作意图识别、目标元素定位、操作执行和结果验证的完整流程。\n\n在 Stagehand 的 CLI 工具 `packages/cli/src/index.ts` 中，操作执行通过 `runCommand` 函数与浏览器守护进程通信，守护进程接收指令后调用相应的 Handler 处理逻辑。Sources: [packages/cli/src/index.ts:1-100]()\n\n## 架构设计\n\n### 核心组件关系\n\n```mermaid\ngraph TD\n    A[Agent / LLM] --> B[actHandler]\n    B --> C[工具选择]\n    C --> D[click.ts]\n    C --> E[type.ts]\n    C --> F[其他工具]\n    D --> G[ElementHandler]\n    E --> G\n    F --> G\n    G --> H[Playwright Page API]\n    H --> I[浏览器执行]\n    I --> J[结果验证]\n    J --> K[状态反馈]\n```\n\n### 执行流程\n\n| 阶段 | 组件 | 职责 |\n|------|------|------|\n| 意图解析 | actHandler.ts | 解析 LLM 生成的指令，提取操作类型和参数 |\n| 工具路由 | act.ts | 根据操作类型选择对应的工具模块 |\n| 元素定位 | 各工具模块 | 使用 XPath/CSS 选择器定位目标元素 |\n| 操作执行 | ElementHandler | 调用 Playwright API 执行具体操作 |\n| 结果验证 | Handler 返回值 | 返回执行结果和状态信息 |\n\nSources: [packages/core/lib/v3/handlers/actHandler.ts:1-50]()\nSources: [packages/core/lib/v3/agent/tools/act.ts:1-50]()\n\n## 操作类型\n\n### 元素交互操作\n\n#### click 点击操作\n\n`click` 操作用于模拟鼠标点击事件，支持多种变体：\n\n| 命令 | 描述 | 参数 |\n|------|------|------|\n| `click` | 点击元素 | selector, button, count, force |\n| `click_xy` | 坐标点击 | x, y, button, count |\n| `dblclick` | 双击 | selector |\n| `rightclick` | 右键菜单 | selector |\n\nCLI 实现示例：\n\n```typescript\nprogram\n  .command(\"click <selector>\")\n  .description(\"Click element\")\n  .option(\"-b, --button <btn>\", \"Mouse button\", \"left\")\n  .option(\"-c, --count <n>\", \"Click count\", \"1\")\n  .option(\"--force\", \"Force click\")\n  .option(\"--xpath\", \"Return XPath of clicked element\")\n  .action(async (selector: string, cmdOpts) => {\n    const opts = program.opts<GlobalOpts>();\n    const result = await runCommand(\"click\", [\n      selector,\n      {\n        button: cmdOpts.button,\n        clickCount: parseInt(cmdOpts.count),\n        force: cmdOpts.force,\n      },\n    ]);\n    output(result, opts.json ?? false);\n  });\n```\n\nSources: [packages/core/lib/v3/agent/tools/click.ts:1-80]()\nSources: [packages/cli/src/index.ts:200-250]()\n\n#### type 输入操作\n\n`type` 操作用于模拟键盘输入，支持人类化输入模式：\n\n| 选项 | 类型 | 描述 |\n|------|------|------|\n| `text` | string | 要输入的文本内容 |\n| `delay` | number | 击键间隔（毫秒） |\n| `mistakes` | boolean | 启用类人错误模拟 |\n\n```typescript\nprogram\n  .command(\"type <text>\")\n  .description(\"Type text\")\n  .option(\"-d, --delay <ms>\", \"Delay between keystrokes\")\n  .option(\"--mistakes\", \"Enable human-like typing with mistakes\")\n  .action(async (text: string, cmdOpts) => {\n    const result = await runCommand(\"type\", [\n      text,\n      {\n        delay: cmdOpts.delay ? parseInt(cmdOpts.delay) : undefined,\n        mistakes: cmdOpts.mistakes,\n      },\n    ]);\n  });\n```\n\nSources: [packages/core/lib/v3/agent/tools/type.ts:1-60]()\nSources: [packages/cli/src/index.ts:350-400]()\n\n#### fill 填充操作\n\n`fill` 专门用于填充表单输入框，默认在填充完成后按 Enter 键：\n\n| 参数 | 类型 | 描述 |\n|------|------|------|\n| `selector` | string | 输入框选择器 |\n| `value` | string | 填充值 |\n| `pressEnter` | boolean | 是否按 Enter 确认 |\n\nSources: [packages/cli/src/index.ts:280-330]()\n\n#### select 下拉选择\n\n`select` 用于选择下拉菜单选项：\n\n```typescript\nprogram\n  .command(\"select <selector> <values...>\")\n  .description(\"Select option(s)\")\n  .action(async (selector: string, values: string[]) => {\n    const result = await runCommand(\"select\", [selector, values]);\n  });\n```\n\n### 坐标操作\n\n#### hover 悬停\n\n悬停到指定坐标位置：\n\n```typescript\nprogram\n  .command(\"hover <x> <y>\")\n  .description(\"Hover at coordinates\")\n  .option(\"--xpath\", \"Return XPath of hovered element\")\n  .action(async (x: string, y: string, cmdOpts) => {\n    const result = await runCommand(\"hover\", [\n      parseFloat(x),\n      parseFloat(y),\n      { returnXPath: cmdOpts.xpath },\n    ]);\n  });\n```\n\n#### scroll 滚动\n\n在指定位置执行滚动操作：\n\n```typescript\nprogram\n  .command(\"scroll <x> <y> <deltaX> <deltaY>\")\n  .description(\"Scroll at coordinates\")\n  .option(\"--xpath\", \"Return XPath of scrolled element\")\n  .action(async (x: string, y: string, dx: string, dy: string, cmdOpts) => {\n    const result = await runCommand(\"scroll\", [\n      parseFloat(x),\n      parseFloat(y),\n      parseFloat(dx),\n      parseFloat(dy),\n      { returnXPath: cmdOpts.xpath },\n    ]);\n  });\n```\n\nSources: [packages/cli/src/index.ts:420-470]()\n\n### 键盘操作\n\n#### press 按键\n\n模拟按下指定键盘按键：\n\n| 参数 | 示例值 |\n|------|--------|\n| 修饰键 | Enter, Tab, Escape |\n| 组合键 | Cmd+A, Ctrl+C, Shift+Tab |\n| 功能键 | F1-F12 |\n\n```typescript\nprogram\n  .command(\"press <key>\")\n  .alias(\"key\")\n  .description(\"Press key (e.g., Enter, Tab, Escape, Cmd+A)\")\n  .action(async (key: string) => {\n    const result = await runCommand(\"press\", [key]);\n  });\n```\n\nSources: [packages/cli/src/index.ts:380-410]()\n\n### 状态检查操作\n\n#### is 检查元素状态\n\n验证元素的可见性或选中状态：\n\n```typescript\nprogram\n  .command(\"is <check> <selector>\")\n  .description(\"Check element state: visible, checked\")\n  .action(async (check: string, selector: string) => {\n    const result = await runCommand(\"is\", [check, selector]);\n  });\n```\n\n| 检查类型 | 描述 |\n|----------|------|\n| `visible` | 元素是否可见 |\n| `checked` | 复选框/单选框是否选中 |\n\n#### get 获取页面信息\n\n获取页面或元素的各类信息：\n\n```typescript\nprogram\n  .command(\"get <what> [selector]\")\n  .description(\n    \"Get page info: url, title, text, html, markdown, value, box, visible, checked\",\n  )\n  .action(async (what: string, selector?: string) => {\n    const result = await runCommand(\"get\", [what, selector]);\n  });\n```\n\nSources: [packages/cli/src/index.ts:490-520]()\n\n### 导航操作\n\n#### open 页面导航\n\n```typescript\nprogram\n  .command(\"open <url>\")\n  .alias(\"goto\")\n  .description(\"Navigate to URL\")\n  .option(\"--wait <state>\", \"Wait state: load, domcontentloaded, networkidle\")\n  .option(\"-t, --timeout <ms>\", \"Navigation timeout\", \"30000\")\n  .action(async (url: string, cmdOpts) => {\n    // 支持等待状态配置和超时控制\n  });\n```\n\nSources: [packages/cli/src/index.ts:560-620]()\n\n### 特殊操作\n\n#### wait 等待操作\n\n等待特定条件满足：\n\n```typescript\nprogram\n  .command(\"wait <type> [arg]\")\n  .description(\"Wait for: load, selector, timeout\")\n  .option(\"-t, --timeout <ms>\", \"Timeout\", \"30000\")\n  .option(\"-s, --state <state>\", \"Element state: visible, hidden, attached, detached\")\n  .action(async (type: string, arg: string | undefined, cmdOpts) => {\n    const result = await runCommand(\"wait\", [\n      type,\n      arg,\n      { timeout: parseInt(cmdOpts.timeout), state: cmdOpts.state },\n    ]);\n  });\n```\n\n| 等待类型 | 参数 | 描述 |\n|----------|------|------|\n| `load` | - | 等待页面加载 |\n| `selector` | 选择器 | 等待元素出现 |\n| `timeout` | 毫秒 | 等待指定时间 |\n\n#### eval JavaScript 执行\n\n在页面上下文中执行任意 JavaScript：\n\n```typescript\nprogram\n  .command(\"eval <expression>\")\n  .description(\"Evaluate JavaScript in page\")\n  .action(async (expr: string) => {\n    const result = await runCommand(\"eval\", [expr]);\n  });\n```\n\nSources: [packages/cli/src/index.ts:540-560]()\n\n## 执行上下文管理\n\n### Session 隔离机制\n\nStagehand 使用 Session 来隔离不同的浏览器上下文：\n\n```typescript\ninterface GlobalOpts {\n  ws?: string;\n  headless?: boolean;\n  headed?: boolean;\n  json?: boolean;\n  session?: string;\n  connect?: string;\n  proxies?: boolean;\n  advancedStealth?: boolean;\n  solveCaptchas?: boolean;\n  region?: string;\n  keepAlive?: boolean;\n  sessionTimeout?: number;\n  blockAds?: boolean;\n}\n\nfunction getSession(opts: GlobalOpts): string {\n  return opts.session ?? process.env.BROWSE_SESSION ?? \"default\";\n}\n```\n\nSources: [packages/cli/src/index.ts:700-750]()\n\n### 守护进程架构\n\nCLI 与浏览器守护进程之间通过 Unix Socket 进行通信：\n\n```mermaid\ngraph LR\n    A[CLI Client] -->|runCommand| B[Unix Socket]\n    B --> C[Daemon Process]\n    C --> D[Chrome DevTools Protocol]\n    D --> E[Browser Instance]\n```\n\n守护进程管理包括：\n\n| 功能 | 描述 |\n|------|------|\n| `start` | 启动浏览器守护进程 |\n| `stop` | 停止守护进程 |\n| `status` | 检查守护进程状态 |\n| `daemon` | 以守护进程模式运行 |\n\n```typescript\nprogram\n  .command(\"start\")\n  .description(\"Start browser daemon\")\n  .action(async () => {\n    const session = getSession(opts);\n    if (await isDaemonRunning(session)) {\n      console.log(JSON.stringify({ status: \"already running\", session }));\n      return;\n    }\n    await ensureDaemon(session, isHeadless(opts));\n  });\n```\n\nSources: [packages/cli/src/index.ts:620-680]()\n\n## 操作执行重试机制\n\n当命令执行失败时，系统会自动进行重试：\n\n```typescript\nasync function sendCommand(\n  session: string,\n  command: string,\n  args: unknown[],\n  headless: boolean,\n  retries: number = 3,\n): Promise<unknown> {\n  for (let attempt = 0; attempt <= retries; attempt++) {\n    try {\n      return await sendCommandOnce(session, command, args);\n    } catch (err) {\n      if (attempt === retries || command === \"stop\") {\n        throw err;\n      }\n\n      const errMsg = err instanceof Error ? err.message : String(err);\n      const isConnectionError =\n        errMsg.includes(\"ENOENT\") ||\n        errMsg.includes(\"ECONNREFUSED\") ||\n        errMsg.includes(\"Connection failed\");\n\n      if (!isConnectionError) {\n        throw err;\n      }\n\n      // 重试策略\n      if (attempt === 0) {\n        await new Promise((r) => setTimeout(r, 200));\n        continue;\n      }\n      if (attempt === 1) {\n        await ensureDaemon(session, headless);\n        continue;\n      }\n\n      await killChromeProcesses(session);\n      await cleanupStaleFiles(session);\n      await ensureDaemon(session, headless);\n    }\n  }\n}\n```\n\n| 重试次数 | 策略 | 原因 |\n|----------|------|------|\n| 0 | 短暂等待后重试 | Socket 可能暂时不可用 |\n| 1 | 重启守护进程 | 守护进程可能无响应 |\n| 2 | 清理并完全重启 | 清理残留状态 |\n\nSources: [packages/cli/src/index.ts:800-870]()\n\n## 输出格式\n\n操作执行结果支持两种输出格式：\n\n| 模式 | 触发方式 | 输出内容 |\n|------|----------|----------|\n| 标准输出 | 默认 | 格式化的人类可读输出 |\n| JSON 模式 | `--json` 选项 | 结构化 JSON 数据 |\n\n```typescript\nfunction output(result: unknown, asJson: boolean): void {\n  if (asJson) {\n    console.log(JSON.stringify(result, null, 2));\n  } else {\n    // 格式化输出\n    console.log(result);\n  }\n}\n```\n\n## 总结\n\n`act()` 操作执行系统是 Stagehand 自动化能力的核心，它通过以下设计实现：\n\n1. **分层架构**：Handler 层负责指令解析，工具层负责具体操作\n2. **灵活的命令路由**：CLI 通过统一的 `runCommand` 接口支持多种操作类型\n3. **健壮的错误处理**：自动重试机制和详细的错误信息\n4. **会话隔离**：通过 Session 实现多任务并行执行\n5. **丰富的操作类型**：覆盖点击、输入、导航、状态检查等常见自动化场景\n\n---\n\n<a id='extract-api'></a>\n\n## extract() 数据提取\n\n### Related Pages\n\nRelated topics: [act() 操作执行](#act-api), [observe() 页面观察](#observe-api), [Handler 处理系统](#handler-system)\n\n<details>\n<summary>Relevant source files</summary>\n\nThe following files were used as context for generating this wiki page:\n\n- [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n- [packages/cli/src/local-strategy.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-strategy.ts)\n- [packages/cli/src/local-cdp-discovery.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-cdp-discovery.ts)\n- [packages/core/lib/v3/handlers/extractHandler.ts](https://github.com/browserbase/stagehand/blob/main/packages/core/lib/v3/handlers/extractHandler.ts)\n- [packages/core/lib/v3/agent/tools/extract.ts](https://github.com/browserbase/stagehand/blob/main/packages/core/lib/v3/agent/tools/extract.ts)\n- [packages/core/lib/zodCompat.ts](https://github.com/browserbase/stagehand/blob/main/packages/core/lib/zodCompat.ts)\n</details>\n\n# extract() 数据提取\n\n## 概述\n\n`extract()` 是 Stagehand 框架中的核心数据提取方法，允许开发者从网页内容中提取结构化数据。该功能通过 Zod schema 定义期望的数据结构，由 AI 模型智能解析页面内容并返回类型安全的提取结果。\n\n## 核心功能\n\n### 1. Schema 驱动的数据提取\n\nStagehand 使用 Zod 作为数据验证和类型定义的基础。开发者可以通过 Zod schema 定义期望的输出结构：\n\n```typescript\nimport { extract } from \"@browserbase/stagehand\";\nimport { z } from \"zod\";\n\nconst schema = z.object({\n  title: z.string(),\n  price: z.number(),\n  inStock: z.boolean(),\n});\n\nconst result = await extract(page, { \n  instruction: \"提取产品名称、价格和库存状态\",\n  schema \n});\n```\n\n### 2. 指令引导的提取\n\n`extract()` 方法支持自然语言指令，让 AI 模型理解需要提取哪些信息：\n\n| 参数 | 类型 | 描述 |\n|------|------|------|\n| `instruction` | `string` | 描述需要提取的数据的自然语言指令 |\n| `schema` | `ZodSchema` | 定义提取数据的 Zod schema |\n| `maxTokens` | `number` | 最大响应 token 数（可选） |\n\n## 工作流程\n\n```mermaid\ngraph TD\n    A[调用 extract] --> B[解析 Zod Schema]\n    B --> C[生成 AI Prompt]\n    C --> D[执行 DOM 解析]\n    D --> E[提取匹配数据]\n    E --> F[Schema 验证]\n    F --> G{验证通过?}\n    G -->|是| H[返回结构化数据]\n    G -->|否| I[抛出验证错误]\n```\n\n## 与 Zod 的集成\n\nStagehand 通过 `zodCompat.ts` 实现与 Zod 的深度集成：\n\n```typescript\n// packages/core/lib/zodCompat.ts\nimport { z } from \"zod\";\n\n// 支持的 Zod 类型映射\nconst typeMap = {\n  string: \"text\",\n  number: \"number\", \n  boolean: \"boolean\",\n  array: \"array\",\n  object: \"object\",\n};\n```\n\n### 支持的 Zod 类型\n\n| Zod 类型 | 提取行为 | 说明 |\n|----------|----------|------|\n| `z.string()` | 文本提取 | 返回 DOM 元素的文本内容 |\n| `z.number()` | 数值提取 | 解析文本中的数字 |\n| `z.boolean()` | 布尔提取 | 识别 yes/no、true/false 等 |\n| `z.array(z.string())` | 列表提取 | 返回多个匹配元素 |\n| `z.object({...})` | 嵌套对象 | 递归提取复杂结构 |\n\n## 错误处理\n\n```mermaid\ngraph LR\n    A[提取操作] --> B{执行结果}\n    B -->|成功| C[返回数据]\n    B -->|验证失败| D[ZodError]\n    B -->|超时| E[TimeoutError]\n    B -->|无匹配| F[NoMatchError]\n```\n\n### 常见错误类型\n\n| 错误类型 | 描述 | 处理方式 |\n|----------|------|----------|\n| `ValidationError` | Schema 验证失败 | 检查 schema 定义 |\n| `TimeoutError` | 操作超时 | 增加 timeout 参数 |\n| `NoMatchError` | 未找到匹配元素 | 调整选择器或指令 |\n\n## 使用示例\n\n### 基本用法\n\n```typescript\nimport { stagehand } from \"@browserbase/stagehand\";\nimport { z } from \"zod\";\n\nconst page = await stagehand.init();\n\nconst product = await page.extract({\n  instruction: \"提取产品标题和价格\",\n  schema: z.object({\n    title: z.string(),\n    price: z.number(),\n  }),\n});\n\nconsole.log(product);\n// { title: \"iPhone 15 Pro\", price: 999 }\n```\n\n### 复杂嵌套结构\n\n```typescript\nconst schema = z.object({\n  products: z.array(z.object({\n    name: z.string(),\n    price: z.number(),\n    variants: z.array(z.object({\n      color: z.string(),\n      inStock: z.boolean(),\n    })),\n  })),\n  totalResults: z.number(),\n});\n\nconst data = await page.extract({\n  instruction: \"提取所有产品及其变体信息\",\n  schema,\n});\n```\n\n## 与其他模块的协同\n\n```mermaid\ngraph TD\n    subgraph 核心模块\n        A[extractHandler.ts]\n        B[extract.ts]\n        C[zodCompat.ts]\n    end\n    \n    subgraph 依赖关系\n        D[snapshot 获取 DOM]\n        E[AI 模型解析]\n        F[Zod 验证]\n    end\n    \n    A --> B\n    B --> C\n    A --> D\n    A --> E\n    A --> F\n    \n    style A fill:#e1f5fe\n    style B fill:#fff3e0\n    style C fill:#e8f5e9\n```\n\n## 配置选项\n\n| 选项 | 默认值 | 描述 |\n|------|--------|------|\n| `timeout` | `30000` | 操作超时时间（毫秒） |\n| `retries` | `3` | 失败重试次数 |\n| `model` | `gpt-4o` | 使用的 AI 模型 |\n| `verbose` | `false` | 启用详细日志 |\n\n## 最佳实践\n\n1. **使用精确的指令**：指令越具体，提取结果越准确\n2. **选择合适的 Schema**：避免过于复杂的嵌套结构\n3. **处理可选字段**：使用 `z.string().optional()` 处理可能缺失的字段\n4. **设置合理的超时**：复杂页面需要更长超时时间\n5. **验证返回数据**：即使通过 schema 验证，也建议进行运行时检查\n\n## 相关资源\n\n- [Stagehand 官方文档](https://docs.browserbase.com/stagehand)\n- [Zod 官方文档](https://zod.dev)\n- [Browserbase 平台](https://browserbase.com)\n\n---\n\n<a id='observe-api'></a>\n\n## observe() 页面观察\n\n### Related Pages\n\nRelated topics: [act() 操作执行](#act-api), [extract() 数据提取](#extract-api), [DOM 与无障碍树](#dom-accessibility)\n\n<details>\n<summary>Relevant source files</summary>\n\nThe following files were used as context for generating this wiki page:\n\n- [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n- [packages/cli/src/local-strategy.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-strategy.ts)\n- [packages/cli/src/local-cdp-discovery.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-cdp-discovery.ts)\n</details>\n\n# observe() 页面观察\n\n## 概述\n\n`observe()` 是 stagehand 框架中的核心页面观察功能，用于实时捕获和分析网页的当前状态。该功能通过无障碍树（Accessibility Tree）快照机制，获取页面的 DOM 结构、元素属性、位置信息等关键数据，为 AI 代理提供理解和操作网页的能力。\n\n页面观察功能在架构中扮演着\"感知层\"的角色，是连接浏览器渲染结果与 AI 决策引擎的关键桥梁。通过标准化的快照格式，系统能够将复杂的 DOM 结构转化为 AI 可理解的语义化表示。\n\n## 核心组件\n\n### Snapshot 快照系统\n\n快照系统负责从浏览器页面提取无障碍信息，生成结构化的页面描述。\n\n| 组件 | 职责 | 输出格式 |\n|------|------|----------|\n| `capture.ts` | 底层无障碍数据采集 | 原始 AX 节点树 |\n| `index.ts` | 快照格式化与映射构建 | 树形结构 + XPath/URL 映射 |\n\n快照系统的工作流程：\n\n```mermaid\ngraph TD\n    A[浏览器页面] --> B[Playwright snapshot API]\n    B --> C[原始 AX 节点]\n    C --> D[格式化处理]\n    D --> E[formattedTree 树形输出]\n    D --> F[xpathMap XPath 映射]\n    D --> G[urlMap URL 映射]\n```\n\n### Observe Handler 处理层\n\n`observeHandler.ts` 实现了页面观察的核心逻辑，负责协调快照采集、结果处理和错误管理。\n\n处理流程包含以下关键阶段：\n\n1. **初始化阶段** - 验证观察上下文和目标页面\n2. **采集阶段** - 调用底层快照 API 获取无障碍树\n3. **处理阶段** - 格式化节点数据，构建引用映射\n4. **返回阶段** - 输出结构化的观察结果\n\n### CLI 集成接口\n\n在 CLI 工具中，`snapshot` 命令提供了直接调用观察功能的入口：\n\n```typescript\nprogram\n  .command(\"snapshot\")\n  .description(\"Get accessibility tree snapshot\")\n  .option(\"-c, --compact\", \"Output tree only (no xpath map)\")\n```\n\n输出格式示例：\n\n```json\n{\n  \"tree\": \"页面元素的树形文本表示\",\n  \"xpathMap\": {\n    \"elementRef1\": \"/html/body/div[1]/button[2]\",\n    \"elementRef2\": \"/html/body/main/section[1]\"\n  },\n  \"urlMap\": {\n    \"linkRef1\": \"https://example.com/page\",\n    \"linkRef2\": \"https://api.example.com/data\"\n  }\n}\n```\n\n## 快照数据模型\n\n### 节点结构\n\n每个无障碍树节点包含以下核心属性：\n\n| 属性 | 类型 | 描述 |\n|------|------|------|\n| `role` | string | 元素的 ARIA 角色 |\n| `name` | string | 元素的辅助名称 |\n| `value` | string | 元素的值属性 |\n| `description` | string | 元素的描述信息 |\n| `state` | string[] | 元素状态数组 |\n| `children` | Node[] | 子节点列表 |\n\n### 引用映射机制\n\n系统维护两套关键映射表：\n\n**XPath 映射** - 将内部引用转换为 XPath 表达式，支持精确定位 DOM 元素\n**URL 映射** - 记录页面中的链接和资源 URL，便于后续操作\n\n```mermaid\ngraph LR\n    A[snapshot 结果] --> B[tree 格式化文本]\n    A --> C[xpathMap 引用表]\n    A --> D[urlMap URL 表]\n    C --> E[click 元素定位]\n    C --> F[fill 输入定位]\n    D --> G[navigate 链接访问]\n```\n\n## 配置选项\n\n### 紧凑模式 (Compact Mode)\n\n使用 `--compact` 或 `-c` 选项时，快照输出仅包含树形结构，不包含映射表：\n\n```bash\nbrowse snapshot --compact\n```\n\n适用于需要快速查看页面结构的场景，减少输出量。\n\n### 全局输出控制\n\n| 选项 | 说明 | 默认值 |\n|------|------|--------|\n| `--json` | 输出完整 JSON 格式 | false |\n| 紧凑模式 | 仅输出树形文本 | false |\n\n## 与其他模块的协作\n\n### 无障碍树采集 (capture.ts)\n\n底层采集模块通过 Playwright 的 `snapshot()` 方法获取页面的无障碍表示。该模块负责：\n\n- 遍历 DOM 节点构建 AX 树\n- 提取元素的语义化信息\n- 过滤无关的内部节点\n\n### 本地模式发现 (local-cdp-discovery.ts)\n\n页面观察功能依赖于与浏览器实例的 CDP 连接。CDP 发现机制确保 CLI 能够正确连接到本地或远程浏览器实例：\n\n```mermaid\ngraph TD\n    A[启动浏览器] --> B[CDP 端口检测]\n    B --> C{发现可用端口}\n    C -->|成功| D[建立 WebSocket 连接]\n    C -->|失败| E[使用默认端口]\n    D --> F[初始化 snapshot 服务]\n```\n\n### 本地策略解析 (local-strategy.ts)\n\n根据配置策略，系统选择合适的浏览器连接方式：\n\n| 策略 | 说明 | 适用场景 |\n|------|------|----------|\n| `isolated` | 独立 Chromium 实例 | 默认隔离环境 |\n| `cdp` | 连接到已有浏览器 | 复用已有会话 |\n| `auto` | 自动发现可用浏览器 | 智能选择 |\n\n## 使用场景\n\n### 1. 页面状态分析\n\n在执行自动化操作前，先观察页面结构：\n\n```bash\nbrowse open https://example.com\nbrowse snapshot\n```\n\n### 2. 元素定位验证\n\n通过 XPath 映射验证元素选择器的正确性：\n\n```bash\nbrowse snapshot --json\n# 检查 xpathMap 中的路径是否与预期匹配\n```\n\n### 3. AI 代理感知\n\n为 AI 代理提供页面状态的语义化表示，支持决策制定：\n\n```json\n{\n  \"tree\": \"form\\n  input[name='username']\\n  input[name='password']\\n  button[type='submit']\",\n  \"xpathMap\": {\n    \"username\": \"/html/body/form/input[1]\",\n    \"password\": \"/html/body/form/input[2]\",\n    \"submit\": \"/html/body/form/button\"\n  }\n}\n```\n\n## 技术规格\n\n### 性能特性\n\n| 指标 | 典型值 | 说明 |\n|------|--------|------|\n| 采集延迟 | < 100ms | 中等复杂度页面 |\n| 树深度限制 | 无 | 完整遍历 |\n| 输出大小 | 10KB - 500KB | 取决于页面复杂度 |\n\n### 错误处理\n\n观察功能实现了完善的错误处理机制：\n\n- **连接失败** - 自动重试并清理陈旧状态\n- **超时处理** - 默认 30 秒超时保护\n- **部分失败** - 返回已采集的部分数据\n\n## 总结\n\n`observe()` 页面观察功能是 stagehand 框架的感知核心，通过标准化的无障碍树快照机制，将网页的视觉和语义信息转化为 AI 可理解的结构化数据。该功能与 CLI 工具、CDP 连接层、本地策略模块紧密协作，为浏览器自动化操作提供了稳定、可靠的页面状态感知能力。\n\n---\n\n**Sources:** [packages/cli/src/index.ts:280-320](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts) | [packages/cli/src/local-strategy.ts:1-100](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-strategy.ts) | [packages/cli/src/local-cdp-discovery.ts:1-80](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-cdp-discovery.ts)\n\n---\n\n<a id='agent-system'></a>\n\n## Agent 代理系统\n\n### Related Pages\n\nRelated topics: [Handler 处理系统](#handler-system)\n\n<details>\n<summary>Relevant source files</summary>\n\nThe following files were used as context for generating this wiki page:\n\n- [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n- [packages/cli/src/local-strategy.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-strategy.ts)\n- [packages/cli/src/local-cdp-discovery.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-cdp-discovery.ts)\n\n> **注意**：用户请求的 Agent 系统核心文件（如 `packages/core/lib/v3/agent/AgentClient.ts`、`AgentProvider.ts` 等）未包含在提供的上下文中。本页面基于 CLI 与 Agent 系统交互的代码进行分析。\n\n</details>\n\n# Agent 代理系统\n\n## 概述\n\nStagehand 的 Agent 代理系统是浏览器自动化操作的核心引擎，负责管理浏览器会话、执行自动化命令、处理网络请求捕获以及维护浏览器状态。该系统通过 CLI 接口和核心库协同工作，为 AI 代理提供可观测、可控制的浏览器操作能力。\n\n## 系统架构\n\n### 整体架构图\n\n```mermaid\ngraph TD\n    subgraph CLI层 [\"CLI 接口层\"]\n        CLI[packages/cli/src/index.ts]\n        Cmds[命令定义]\n    end\n    \n    subgraph Agent核心 [\"Agent 核心系统\"]\n        AC[AgentClient]\n        AP[AgentProvider]\n        Handler[v3AgentHandler]\n        ActionMap[actionMapping]\n    end\n    \n    subgraph Daemon层 [\"Daemon 守护进程\"]\n        Socket[Unix Socket]\n        Chrome[Chrome Browser]\n        CDP[CDP Protocol]\n    end\n    \n    CLI --> Cmds\n    Cmds --> AC\n    AC --> AP\n    AP --> Handler\n    Handler --> ActionMap\n    ActionMap --> Socket\n    Socket --> Chrome\n    Chrome --> CDP\n    \n    LocalCDP[local-cdp-discovery] --> AP\n    LocalStrat[local-strategy.ts] --> AP\n```\n\n## 核心组件\n\n### 1. CLI 命令接口层\n\nCLI 层定义了所有与浏览器交互的命令，通过 `runCommand` 函数与 Agent 系统通信。\n\n**主要命令类别**：\n\n| 类别 | 命令 | 功能 |\n|------|------|------|\n| 导航 | `open`, `goto` | 打开 URL |\n| 元素操作 | `click`, `fill`, `select`, `upload` | 操作页面元素 |\n| 状态检查 | `is`, `wait`, `get` | 检查元素状态 |\n| 键盘鼠标 | `type`, `press`, `hover`, `scroll`, `drag` | 模拟输入 |\n| 网络 | `network on/off`, `network path` | 网络请求捕获 |\n| 截图 | `screenshot` | 页面截图 |\n| 快照 | `snapshot` | 辅助功能树快照 |\n| 标签页 | `pages`, `newpage`, `closepage` | 多标签管理 |\n\n### 2. Daemon 守护进程管理\n\nDaemon 系统负责管理浏览器实例的生命周期。\n\n```typescript\n// Socket 路径配置\nconst SOCKET_DIR = os.tmpdir();\n\nfunction getSocketPath(session: string): string {\n  return path.join(SOCKET_DIR, `browse-${session}.sock`);\n}\n\nfunction getLockPath(session: string): string {\n  return path.join(SOCKET_DIR, `browse-${session}.lock`);\n}\n```\n\n**Daemon 启动流程**：\n\n```mermaid\nsequenceDiagram\n    participant CLI\n    participant Lock\n    participant Daemon\n    participant Chrome\n    \n    CLI->>Lock: acquireLock(session)\n    Lock-->>CLI: 锁定成功\n    CLI->>Daemon: ensureDaemon(session, headless)\n    Daemon->>Chrome: 启动/连接 Chrome\n    Chrome-->>Daemon: WebSocket Ready\n    Daemon->>Lock: releaseLock(session)\n```\n\n**关键特性**：\n- 基于 `O_EXCL` 的原子文件锁机制防止竞态条件\n- 自动检测并清理陈旧的锁文件\n- 支持会话超时自动清理\n\n### 3. 本地模式策略\n\nAgent 支持多种本地浏览器连接策略，由 `local-strategy.ts` 定义。\n\n| 策略 | 说明 | 用途 |\n|------|------|------|\n| `isolated` | 启动独立 Chromium 实例 | 完全隔离的浏览器环境 |\n| `cdp` | 连接到指定 CDP 目标 | 复用已有浏览器会话 |\n| `auto` | 自动检测可用浏览器 | 优先复用，无则创建新实例 |\n\n```typescript\n// Sources: packages/cli/src/local-strategy.ts:18-37\nexport async function resolveLocalStrategy({\n  localConfig,\n  headless,\n  defaultViewport,\n  discoverLocalCdp,\n  resolveWsTarget,\n}: ResolveLocalStrategyOptions): Promise<ResolvedLocalStrategy>\n```\n\n### 4. CDP 发现机制\n\n通过 `local-cdp-discovery.ts` 实现 Chrome DevTools Protocol 端点的自动发现。\n\n```mermaid\ngraph LR\n    A[读取 DevToolsActivePort] --> B{端口可达性检查}\n    B -->|可达| C[构建 WebSocket URL]\n    B -->|不可达| D[清理陈旧文件]\n    C --> E[返回 CDP URL]\n    D --> E\n```\n\n**发现流程**：\n1. 扫描用户数据目录（`userDataDirs`）\n2. 读取 `DevToolsActivePort` 文件获取端口信息\n3. 验证端口可达性\n4. 构建 WebSocket 连接 URL\n\n## 网络捕获系统\n\n### 网络请求监控\n\nAgent 系统提供完整的网络请求捕获能力，捕获结果写入文件系统供 Agent 检查。\n\n```typescript\n// Sources: packages/cli/src/index.ts:88-103\ninterface PendingRequest {\n  id: string;\n  timestamp: string;\n  method: string;\n  url: string;\n  headers: Record<string, string>;\n  body: string | null;\n  resourceType: string;\n}\n```\n\n### 目录结构\n\n```\n{networkDir}/\n├── {counter}-{method}-{domain}-{pathSlug}/\n│   ├── request.json    # 请求详情\n│   └── response.json   # 响应详情\n```\n\n### 文件名生成规则\n\n```typescript\n// Sources: packages/cli/src/index.ts:95-120\nfunction getRequestDirName(\n  counter: number,\n  method: string,\n  url: string,\n): string {\n  const parsed = new URL(url);\n  const domain = sanitizeForFilename(parsed.hostname, 30);\n  const pathPart = parsed.pathname.split(\"/\").filter(Boolean)[0] || \"root\";\n  const pathSlug = sanitizeForFilename(pathPart, 20);\n  return `${String(counter).padStart(3, \"0\")}-${method}-${domain}-${pathSlug}`;\n}\n```\n\n## 命令执行流程\n\n### runCommand 执行机制\n\n```mermaid\ngraph TD\n    Start[CLI Command] --> Check{连接状态检查}\n    Check -->|正常| Execute[发送命令]\n    Check -->|连接错误| Retry{重试策略}\n    \n    Retry -->|Attempt 0| Wait[等待 200ms]\n    Wait --> Execute\n    \n    Retry -->|Attempt 1| Restart[重启 Daemon]\n    Restart --> Execute\n    \n    Retry -->|Attempt 2| Cleanup[清理并重启]\n    Cleanup --> Execute\n    \n    Execute --> Success[返回结果]\n    Execute --> Error[抛出错误]\n```\n\n**错误重试策略**：\n\n| 重试次数 | 策略 | 条件 |\n|----------|------|------|\n| 0 | 短暂等待 | `ENOENT`, `ECONNREFUSED`, `Connection failed` |\n| 1 | 重启 Daemon | 同上 |\n| 2 | 完整清理 | 杀死 Chrome 进程 + 清理文件 + 重启 |\n\n## 会话管理\n\n### GlobalOpts 配置选项\n\n| 选项 | 类型 | 说明 |\n|------|------|------|\n| `ws` | `string` | WebSocket 端点 |\n| `headless` | `boolean` | 无头模式 |\n| `headed` | `boolean` | 显示浏览器窗口 |\n| `json` | `boolean` | JSON 格式输出 |\n| `session` | `string` | 会话标识符 |\n| `connect` | `string` | 连接模式 |\n| `proxies` | `boolean` | 启用代理 (远程) |\n| `advancedStealth` | `boolean` | 高级隐身模式 |\n| `solveCaptchas` | `boolean` | 自动解验证码 |\n| `region` | `string` | 区域设置 (远程) |\n| `keepAlive` | `boolean` | 保持连接活跃 |\n| `sessionTimeout` | `number` | 会话超时秒数 |\n| `blockAds` | `boolean` | 广告拦截 |\n\n### 会话参数构建\n\n```typescript\n// Sources: packages/cli/src/index.ts:520-545\nfunction buildSessionParamsFromOpts(\n  opts: GlobalOpts,\n): Record<string, unknown> | null {\n  const params: Record<string, unknown> = {};\n  const browserSettings: Record<string, unknown> = {};\n\n  if (opts.proxies) params.proxies = true;\n  if (opts.region) params.region = opts.region;\n  if (opts.keepAlive) params.keepAlive = true;\n  if (opts.sessionTimeout !== undefined) params.timeout = opts.sessionTimeout;\n\n  if (opts.advancedStealth) browserSettings.advancedStealth = true;\n  if (opts.blockAds) browserSettings.blockAds = true;\n  // ...\n}\n```\n\n## 命令实现示例\n\n### 元素操作命令\n\n```typescript\n// Sources: packages/cli/src/index.ts:185-200\nprogram\n  .command(\"fill <selector> <value>\")\n  .description(\"Fill input element (presses Enter by default)\")\n  .option(\"--no-press-enter\", \"Don't press Enter after filling\")\n  .action(async (selector: string, value: string, cmdOpts) => {\n    const pressEnter = cmdOpts.pressEnter !== false;\n    const result = await runCommand(\"fill\", [\n      selector,\n      value,\n      { pressEnter },\n    ]);\n    output(result, opts.json ?? false);\n  });\n```\n\n### 截图命令\n\n```typescript\n// Sources: packages/cli/src/index.ts:320-345\nprogram\n  .command(\"screenshot [path]\")\n  .description(\"Take screenshot\")\n  .option(\"-f, --full-page\", \"Full page screenshot\")\n  .option(\"-t, --type <type>\", \"Image type: png, jpeg\", \"png\")\n  .option(\"-q, --quality <n>\", \"JPEG quality (0-100)\")\n  .option(\"--clip <json>\", \"Clip region as JSON\")\n  .option(\"--no-animations\", \"Disable animations\")\n  .option(\"--hide-caret\", \"Hide text caret\");\n```\n\n### 辅助功能快照\n\n```typescript\n// Sources: packages/cli/src/index.ts:360-380\nprogram\n  .command(\"snapshot\")\n  .description(\"Get accessibility tree snapshot\")\n  .option(\"-c, --compact\", \"Output tree only (no xpath map)\")\n  .action(async (cmdOpts) => {\n    const result = (await runCommand(\"snapshot\", [cmdOpts.compact])) as {\n      tree: string;\n      xpathMap?: Record<string, string>;\n      urlMap?: Record<string, string>;\n    };\n    // ...\n  });\n```\n\n## 错误处理机制\n\n### Daemon 状态管理\n\n```mermaid\nstateDiagram-v2\n    [*] --> Stopped\n    Stopped --> Starting: start 命令\n    Starting --> Running: 启动成功\n    Starting --> Failed: 启动失败\n    Running --> Stopping: stop 命令\n    Running --> Failed: 连接断开\n    Stopping --> Stopped: 清理完成\n    Failed --> Starting: 重试\n    Stopped --> [*]\n```\n\n### 锁机制实现\n\n```typescript\n// Sources: packages/cli/src/index.ts:490-520\nasync function acquireLock(\n  session: string,\n  timeoutMs: number = 10000,\n): Promise<boolean> {\n  const lockPath = getLockPath(session);\n  \n  while (Date.now() - startTime < timeoutMs) {\n    try {\n      // O_EXCL 确保原子性创建\n      const handle = await fs.open(lockPath, \"wx\");\n      await handle.write(String(process.pid));\n      await handle.close();\n      return true;\n    } catch (err: unknown) {\n      if ((err as NodeJS.ErrnoException).code === \"EEXIST\") {\n        // 检查持有者是否存活\n        try {\n          const holderPid = parseInt(await fs.readFile(lockPath, \"utf-8\"));\n          process.kill(holderPid, 0);\n          await new Promise((r) => setTimeout(r, 100));\n        } catch {\n          // 清理陈旧锁\n          await fs.unlink(lockPath);\n        }\n      }\n    }\n  }\n  return false;\n}\n```\n\n## 扩展命令系统\n\nAgent 系统支持通过命令模式（Command Pattern）轻松扩展新功能：\n\n```typescript\nprogram\n  .command(\"<command> <args...>\")\n  .description(\"命令描述\")\n  .option(\"-x, --option <value>\", \"选项说明\")\n  .action(async (args, cmdOpts) => {\n    const result = await runCommand(\"command_name\", [\n      args,\n      { /* options */ }\n    ]);\n    output(result, opts.json ?? false);\n  });\n```\n\n## 总结\n\nStagehand 的 Agent 代理系统提供了完整的浏览器自动化能力：\n\n1. **Daemon 管理**：基于 Unix Socket 的进程间通信，支持多会话隔离\n2. **命令系统**：统一的命令接口，覆盖所有浏览器操作\n3. **网络监控**：完整的请求/响应捕获机制\n4. **本地策略**：灵活的浏览器连接策略（隔离/CDP/自动）\n5. **错误恢复**：多级重试和自动清理机制\n6. **会话管理**：完善的会话状态和配置管理\n\n---\n\n<a id='handler-system'></a>\n\n## Handler 处理系统\n\n### Related Pages\n\nRelated topics: [act() 操作执行](#act-api), [extract() 数据提取](#extract-api), [observe() 页面观察](#observe-api)\n\n<details>\n<summary>Relevant source files</summary>\n\nThe following files were used as context for generating this wiki page:\n\n- [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n- [packages/cli/src/local-strategy.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-strategy.ts)\n- [packages/cli/src/local-cdp-discovery.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-cdp-discovery.ts)\n</details>\n\n# Handler 处理系统\n\n## 概述\n\nHandler 处理系统是 Stagehand 框架的核心组件，负责在浏览器环境中执行自动化操作。该系统通过统一的命令调度机制，将高层操作指令（如 `click`、`type`、`hover` 等）转换为底层的浏览器 CDP (Chrome DevTools Protocol) 调用。Sources: [packages/cli/src/index.ts:1-50]()\n\nStagehand 的 Handler 架构采用分层设计，上层 CLI 通过 Unix Domain Socket 与本地守护进程通信，守护进程负责维护浏览器会话并执行实际的 DOM 操作。这种设计允许命令行工具、API 和其他客户端共享同一个浏览器实例，同时保持操作的原子性和一致性。Sources: [packages/cli/src/index.ts:200-280]()\n\n## 核心架构\n\n### 组件层次\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│                      CLI Client                             │\n│  (Commands: click, type, hover, fill, screenshot, etc.)    │\n└─────────────────────────────────────────────────────────────┘\n                              │\n                              ▼\n┌─────────────────────────────────────────────────────────────┐\n│                  Socket Command Router                      │\n│              (runCommand / sendCommand)                     │\n└─────────────────────────────────────────────────────────────┘\n                              │\n                              ▼\n┌─────────────────────────────────────────────────────────────┐\n│                    Daemon Process                            │\n│           (Browser Session Management)                       │\n└─────────────────────────────────────────────────────────────┘\n                              │\n                              ▼\n┌─────────────────────────────────────────────────────────────┐\n│                  Handler Execution Layer                     │\n│    ┌─────────────┬─────────────┬──────────────────┐        │\n│    │ Action      │ Navigation  │ State Check      │        │\n│    │ Handlers    │ Handlers    │ Handlers         │        │\n│    └─────────────┴─────────────┴──────────────────┘        │\n└─────────────────────────────────────────────────────────────┘\n                              │\n                              ▼\n┌─────────────────────────────────────────────────────────────┐\n│               Chrome DevTools Protocol (CDP)                │\n└─────────────────────────────────────────────────────────────┘\n```\n\n### 命令处理流程\n\n当 CLI 收到一个命令（如 `click <selector>`）时，系统按以下流程处理：\n\n```mermaid\ngraph TD\n    A[CLI Command: click] --> B[Parse Options & Arguments]\n    B --> C[Call runCommand]\n    C --> D[Acquire Session Lock]\n    D --> E{Socket Available?}\n    E -->|Yes| F[Send Command via Socket]\n    E -->|No| G[ensureDaemon]\n    G --> F\n    F --> H[Daemon Router Switch]\n    H --> I[Execute Handler]\n    I --> J[CDP: Runtime.evaluate]\n    J --> K[Return Result]\n    K --> L[Release Lock]\n```\n\nSources: [packages/cli/src/index.ts:300-400]()\n\n## 守护进程管理\n\n### 生命周期管理\n\nStagehand 使用 Unix Domain Socket 进行进程间通信，并通过文件锁机制确保同一会话的互斥访问：\n\n| 功能 | 实现方式 | 文件路径模式 |\n|------|----------|--------------|\n| Socket 通信 | Unix Domain Socket | `/tmp/browse-{session}.sock` |\n| 进程锁 | O_EXCL 原子文件创建 | `/tmp/browse-{session}.lock` |\n| 锁超时 | 10秒默认超时 | - |\n\nSources: [packages/cli/src/index.ts:250-320]()\n\n### 自动重试机制\n\n命令执行失败时，系统提供智能重试：\n\n| 重试次数 | 策略 | 说明 |\n|----------|------|------|\n| 0 | 短暂等待 | 200ms 后重试（socket 暂时不可用） |\n| 1 | 重启守护进程 | 保持现有文件状态 |\n| 2 | 完全清理重启 | 杀死 Chrome 进程并清理残留文件 |\n\n```typescript\n// 重试条件判断\nconst isConnectionError =\n  errMsg.includes(\"ENOENT\") ||\n  errMsg.includes(\"ECONNREFUSED\") ||\n  errMsg.includes(\"Connection failed\");\n```\n\nSources: [packages/cli/src/index.ts:380-420]()\n\n## 操作处理器\n\n### 元素操作命令\n\n| 命令 | 功能 | 关键参数 |\n|------|------|----------|\n| `click` | 点击元素 | selector, button, clickCount, delay, xpath |\n| `dblclick` | 双击元素 | selector, button |\n| `hover` | 悬停 | x, y, returnXPath |\n| `fill` | 填写输入框 | selector, value, pressEnter |\n| `type` | 模拟打字 | text, delay, mistakes |\n| `select` | 选择下拉选项 | selector, values |\n| `drag` | 拖拽操作 | fromX, fromY, toX, toY |\n\nSources: [packages/cli/src/index.ts:450-550]()\n\n### 键盘操作\n\n```typescript\nprogram.command(\"press <key>\")\n  .alias(\"key\")\n  .description(\"Press key (e.g., Enter, Tab, Escape, Cmd+A)\")\n```\n\n支持组合键和特殊键位，包括 modifier keys (Cmd, Ctrl, Shift, Alt)。\n\nSources: [packages/cli/src/index.ts:580-600]()\n\n### 导航操作\n\n| 命令 | 选项 | 默认值 |\n|------|------|--------|\n| `open <url>` | `--wait` (load/domcontentloaded/networkidle) | load |\n| | `-t, --timeout` | 30000ms |\n| | `--context-id` | - |\n| | `--persist` | false |\n\nSources: [packages/cli/src/index.ts:620-680]()\n\n## 状态检查处理器\n\n### 元素状态验证\n\n```typescript\nprogram.command(\"is <check> <selector>\")\n  .description(\"Check element state: visible, checked\")\n```\n\n支持的检查类型：\n\n| 检查类型 | 说明 |\n|----------|------|\n| `visible` | 元素在视口内可见 |\n| `checked` | 复选框/单选框选中状态 |\n| `attached` | 元素存在于 DOM |\n| `detached` | 元素已从 DOM 移除 |\n\nSources: [packages/cli/src/index.ts:700-720]()\n\n### 等待机制\n\n```typescript\nprogram.command(\"wait <type> [arg]\")\n  .option(\"-t, --timeout <ms>\", \"Timeout\", \"30000\")\n  .option(\"-s, --state <state>\", \"visible, hidden, attached, detached\", \"visible\")\n```\n\n| 等待类型 | 参数 | 说明 |\n|----------|------|------|\n| `load` | - | 页面加载完成 |\n| `selector` | CSS 选择器 | 元素出现 |\n| `timeout` | 毫秒数 | 自定义超时 |\n\nSources: [packages/cli/src/index.ts:50-80]()\n\n## 信息获取处理器\n\n### GET 命令\n\n```typescript\nprogram.command(\"get <what> [selector]\")\n  .description(\"Get page info: url, title, text, html, markdown, value, box, visible, checked\")\n```\n\n| 属性 | 说明 | 返回格式 |\n|------|------|----------|\n| `url` | 当前页面 URL | string |\n| `title` | 页面标题 | string |\n| `text` | 元素文本内容 | string |\n| `html` | 元素 HTML | string |\n| `markdown` | 元素 Markdown | string |\n| `value` | 表单元素值 | string |\n| `box` | 元素边界框 | {x, y, width, height} |\n| `visible` | 可见性状态 | boolean |\n| `checked` | 选中状态 | boolean |\n\nSources: [packages/cli/src/index.ts:720-750]()\n\n## 截图处理器\n\n```typescript\nprogram.command(\"screenshot [path]\")\n  .option(\"-f, --full-page\", \"Full page screenshot\")\n  .option(\"-t, --type <type>\", \"png, jpeg\", \"png\")\n  .option(\"-q, --quality <n>\", \"JPEG quality (0-100)\")\n  .option(\"--clip <json>\", \"Clip region\")\n  .option(\"--no-animations\", \"Disable animations\")\n  .option(\"--hide-caret\", \"Hide text caret\")\n```\n\nSources: [packages/cli/src/index.ts:750-800]()\n\n## 网络捕获\n\n### 请求/响应记录\n\n系统可以捕获并保存网络请求到文件系统：\n\n```typescript\ninterface PendingRequest {\n  id: string;\n  timestamp: string;\n  method: string;\n  url: string;\n  headers: Record<string, string>;\n  body: string | null;\n  resourceType: string;\n}\n```\n\n保存目录结构：\n\n```\n{networkDir}/\n├── 000-GET-example-com-api/\n│   ├── request.json\n│   └── response.json\n└── 001-POST-example-com-login/\n    ├── request.json\n    └── response.json\n```\n\nSources: [packages/cli/src/index.ts:850-920]()\n\n## 配置与超时\n\n### 全局选项 (GlobalOpts)\n\n```typescript\ninterface GlobalOpts {\n  ws?: string;\n  headless?: boolean;\n  headed?: boolean;\n  json?: boolean;\n  session?: string;\n  connect?: string;\n  // Remote session options\n  proxies?: boolean;\n  advancedStealth?: boolean;\n  solveCaptchas?: boolean;\n  region?: string;\n  keepAlive?: boolean;\n  sessionTimeout?: number;\n  blockAds?: boolean;\n}\n```\n\n### 超时配置\n\n| 操作 | 默认超时 | 配置方式 |\n|------|----------|----------|\n| 页面导航 | 30000ms | `--timeout` 选项 |\n| 截图 | 10000ms | 硬编码 |\n| Socket 连接 | 28000ms | `waitForSocketReady` |\n| 守护进程锁 | 10000ms | `acquireLock` 参数 |\n\nSources: [packages/cli/src/index.ts:280-340]()\n\n## 错误处理\n\n### 错误分类\n\n| 错误类型 | 处理策略 | 重试行为 |\n|----------|----------|----------|\n| ENOENT | 连接错误 | 重试 |\n| ECONNREFUSED | 连接错误 | 重试 |\n| Connection failed | 连接错误 | 重试 |\n| 其他 | 直接抛出 | 不重试 |\n\n```typescript\n// 优雅关闭处理\nprocess.on(\"SIGTERM\", () => shutdown());\nprocess.on(\"SIGINT\", () => shutdown());\nprocess.on(\"uncaughtException\", (err) => {\n  console.error(\"Uncaught exception:\", err);\n  shutdown();\n});\n```\n\nSources: [packages/cli/src/index.ts:420-450]()\n\n## 本地浏览器策略\n\n### 策略类型\n\n| 策略 | 说明 | 使用场景 |\n|------|------|----------|\n| `auto` | 自动检测已存在的浏览器或启动隔离浏览器 | 默认策略 |\n| `isolated` | 强制使用独立的 Chrome 实例 | 干净环境 |\n| `cdp` | 连接到指定的 CDP 目标 | 调试已有浏览器 |\n\n```typescript\nif (localConfig.strategy === \"isolated\") {\n  return {\n    localLaunchOptions: { headless, viewport: defaultViewport },\n    localInfo: { localSource: \"isolated\" },\n  };\n}\n```\n\nSources: [packages/cli/src/local-strategy.ts:1-50]()\n\n### CDP 发现机制\n\n系统通过以下方式发现本地浏览器：\n\n1. 读取 `DevToolsActivePort` 文件获取端口\n2. 探测 `/json/version` 端点获取 WebSocket URL\n3. 验证端口可达性\n4. 建立 WebSocket 连接\n\n```typescript\nasync function probeJsonVersion(port: number): Promise<string | null> {\n  const res = await fetch(`http://127.0.0.1:${port}/json/version`);\n  const json = await res.json();\n  return json.webSocketDebuggerUrl;\n}\n```\n\nSources: [packages/cli/src/local-cdp-discovery.ts:1-100]()\n\n## 会话管理\n\n### 多会话支持\n\n通过 `--session` 参数或 `BROWSE_SESSION` 环境变量指定会话：\n\n```typescript\nfunction getSession(opts: GlobalOpts): string {\n  return opts.session ?? process.env.BROWSE_SESSION ?? \"default\";\n}\n```\n\n每个会话维护独立的：\n- Socket 通信通道\n- 浏览器实例\n- 状态文件\n\n### 模式覆盖\n\n支持动态切换执行模式（local/remote）：\n\n```typescript\nawait fs.writeFile(getModeOverridePath(session), mapped);\n```\n\nSources: [packages/cli/src/index.ts:180-220]()\n\n## 参考映射 (Ref Map)\n\n系统缓存最近一次 snapshot 的引用映射，支持 `@ref` 语法：\n\n```typescript\nlet refMap: {\n  xpathMap: Record<string, string>;\n  urlMap: Record<string, string>;\n} = {\n  xpathMap: {},\n  urlMap: {},\n};\n\nprogram.command(\"refs\").description(\"Show cached ref map from last snapshot\");\n```\n\nSources: [packages/cli/src/index.ts:820-850]()\n\n## 总结\n\nHandler 处理系统是 Stagehand 实现浏览器自动化的核心抽象层。它通过以下设计原则提供可靠的操作执行：\n\n1. **进程隔离**：守护进程与 CLI 分离，支持多客户端共享\n2. **幂等性**：通过锁机制和幂等命令确保安全并发\n3. **自动恢复**：智能重试和状态清理保证鲁棒性\n4. **灵活配置**：支持多种执行模式和详细参数调优\n5. **统一接口**：命令行、API 复用同一 Handler 逻辑\n\n---\n\n<a id='dom-accessibility'></a>\n\n## DOM 与无障碍树\n\n### Related Pages\n\nRelated topics: [observe() 页面观察](#observe-api), [Deep Locator 深层定位器](#deep-locator)\n\n<details>\n<summary>Relevant source files</summary>\n\nThe following files were used as context for generating this wiki page:\n\n- [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n- [packages/cli/src/local-strategy.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-strategy.ts)\n- [packages/cli/src/local-cdp-discovery.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-cdp-discovery.ts)\n</details>\n\n# DOM 与无障碍树\n\n## 概述\n\nStagehand 中的 DOM 与无障碍树（Accessibility Tree，简称 A11y Tree）是核心的页面元素抽象层。该系统将网页的 DOM 结构转换为结构化的无障碍树表示，使 AI 代理能够理解页面内容并执行自动化操作。无障碍树不仅包含元素的可见性信息，还包含语义角色、ARIA 属性和可访问性标签等关键元数据。\n\nStagehand 通过 `snapshot` 命令获取无障碍树快照，该快照包含格式化的树形结构、元素 XPath 映射和 URL 映射。这些数据被用于元素定位、坐标解析和交互操作。\n\n## 架构设计\n\n### 组件关系\n\n```\ngraph TD\n    A[Browser Page] --> B[DOM Tree]\n    A --> C[Accessibility Tree]\n    B --> D[snapshot command]\n    C --> D\n    D --> E[xpathMap]\n    D --> F[urlMap]\n    D --> G[formattedTree]\n    E --> H[Coordinate Resolver]\n    F --> I[Element Locator]\n    G --> J[AI Agent]\n```\n\n### 核心模块\n\n| 模块 | 文件路径 | 职责 |\n|------|---------|------|\n| A11yTree | `packages/core/lib/v3/understudy/a11y/snapshot/a11yTree.ts` | 无障碍树生成与格式化 |\n| DomTree | `packages/core/lib/v3/understudy/a11y/snapshot/domTree.ts` | DOM 树结构处理 |\n| CoordinateResolver | `packages/core/lib/v3/understudy/a11y/snapshot/coordinateResolver.ts` | 屏幕坐标解析 |\n| FocusSelectors | `packages/core/lib/v3/understudy/a11y/snapshot/focusSelectors.ts` | 焦点元素选择器 |\n\n## Snapshot 命令\n\n### CLI 接口\n\n`packages/cli/src/index.ts` 中定义的 `snapshot` 命令提供两种输出模式：\n\n```typescript\nprogram\n  .command(\"snapshot\")\n  .description(\"Get accessibility tree snapshot\")\n  .option(\"-c, --compact\", \"Output tree only (no xpath map)\")\n  .action(async (cmdOpts) => {\n    const result = (await runCommand(\"snapshot\", [cmdOpts.compact])) as {\n      tree: string;\n      xpathMap?: Record<string, string>;\n      urlMap?: Record<string, string>;\n    };\n    // ...\n  });\n```\n\nSources: [packages/cli/src/index.ts:1-500](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n### 输出格式\n\n| 参数 | 类型 | 描述 |\n|------|------|------|\n| `tree` | `string` | 格式化的无障碍树结构 |\n| `xpathMap` | `Record<string, string>` | 元素引用到 XPath 的映射 |\n| `urlMap` | `Record<string, string>` | 元素引用到 URL 的映射 |\n\n紧凑模式下仅返回纯文本树结构，适合日志记录和快速调试：\n\n```typescript\nif (cmdOpts.compact && !opts.json) {\n  console.log(result.tree);\n} else {\n  output(result, opts.json ?? false);\n}\n```\n\n## Snapshot 实现\n\n### 后端处理逻辑\n\n在 CLI 的命令处理器中，`snapshot` case 从 Playwright Page 对象获取快照数据：\n\n```typescript\ncase \"snapshot\": {\n  const [compact] = args as [boolean?];\n  const snapshot = await page!.snapshot();\n\n  refMap = {\n    xpathMap: snapshot.xpathMap ?? {},\n    urlMap: snapshot.urlMap ?? {},\n  };\n\n  if (compact) {\n    return { tree: snapshot.formattedTree };\n  }\n  return {\n    tree: snapshot.formattedTree,\n    xpathMap: snapshot.xpathMap,\n    urlMap: snapshot.urlMap,\n  };\n}\n```\n\nSources: [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n### 引用映射管理\n\n全局 `refMap` 变量存储最新的快照映射，供后续元素操作使用：\n\n```typescript\nlet refMap: {\n  xpathMap: Record<string, string>;\n  urlMap: Record<string, string>;\n} = {\n  xpathMap: {},\n  urlMap: {},\n};\n```\n\n## 元素状态检查\n\n### is 命令\n\n`is` 命令用于检查元素的可访问性状态：\n\n```typescript\ncase \"is\": {\n  const [check, selector] = args as [string, string];\n  const locator = page!.deepLocator(resolveSelector(selector));\n  switch (check) {\n    case \"visible\":\n      return { visible: await locator.isVisible() };\n    case \"checked\":\n      return { checked: await locator.isChecked() };\n    default:\n      throw new Error(`Unknown check: ${check}`);\n  }\n}\n```\n\nSources: [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n| 检查类型 | 方法 | 描述 |\n|---------|------|------|\n| `visible` | `isVisible()` | 元素是否可见 |\n| `checked` | `isChecked()` | 复选框/单选框是否选中 |\n\n### CLI 接口\n\n```typescript\nprogram\n  .command(\"is <check> <selector>\")\n  .description(\"Check element state: visible, checked\")\n  .action(async (check: string, selector: string) => {\n    const result = await runCommand(\"is\", [check, selector]);\n    output(result, opts.json ?? false);\n  });\n```\n\n## 页面信息获取\n\n### get 命令\n\n`get` 命令提供多种页面和元素信息查询：\n\n```typescript\nprogram\n  .command(\"get <what> [selector]\")\n  .description(\n    \"Get page info: url, title, text, html, markdown, value, box, visible, checked\",\n  )\n  .action(async (what: string, selector?: string) => {\n    const result = await runCommand(\"get\", [what, selector]);\n    output(result, opts.json ?? false);\n  });\n```\n\nSources: [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n### 支持的信息类型\n\n| 类型 | 参数 | 返回内容 |\n|------|------|---------|\n| `url` | 无 | 当前页面 URL |\n| `title` | 无 | 页面标题 |\n| `text` | selector | 元素文本内容 |\n| `html` | selector | 元素 HTML |\n| `markdown` | selector | 转换后的 Markdown |\n| `value` | selector | 表单元素值 |\n| `box` | selector | 元素边界框 {x, y, width, height} |\n| `visible` | selector | 元素可见性 |\n| `checked` | selector | 复选框状态 |\n\n## 坐标与交互\n\n### 坐标操作命令\n\n| 命令 | 描述 | 选项 |\n|------|------|------|\n| `click_xy <x> <y>` | 坐标点击 | `--button`, `--count`, `--xpath` |\n| `hover <x> <y>` | 坐标悬停 | `--xpath` |\n| `scroll <x> <y> <dx> <dy>` | 滚动 | `--xpath` |\n| `drag <fromX> <fromY> ...` | 拖拽 | 延迟、坐标选项 |\n\n```typescript\nprogram\n  .command(\"click_xy <x> <y>\")\n  .description(\"Click at exact coordinates\")\n  .option(\"-b, --button <btn>\", \"Mouse button: left, right, middle\", \"left\")\n  .option(\"-c, --count <n>\", \"Click count\", \"1\")\n  .option(\"--xpath\", \"Return XPath of clicked element\")\n  .action(async (x: string, y: string, cmdOpts) => {\n    const result = await runCommand(\"click_xy\", [\n      parseFloat(x),\n      parseFloat(y),\n      {\n        button: cmdOpts.button,\n        clickCount: parseInt(cmdOpts.count),\n        returnXPath: cmdOpts.xpath,\n      },\n    ]);\n  });\n```\n\nSources: [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n### 坐标解析器\n\n`CoordinateResolver` 模块负责将无障碍树中的元素引用转换为屏幕坐标。该解析器基于快照中的 `xpathMap` 和元素边界框信息计算精确的交互坐标。\n\n## 本地浏览器策略\n\n### 策略类型\n\n`packages/cli/src/local-strategy.ts` 定义了三种本地浏览器连接策略：\n\n```typescript\nexport async function resolveLocalStrategy({\n  localConfig,\n  headless,\n  defaultViewport,\n  discoverLocalCdp,\n  resolveWsTarget,\n}: ResolveLocalStrategyOptions): Promise<ResolvedLocalStrategy> {\n  if (localConfig.strategy === \"isolated\") {\n    return {\n      localLaunchOptions: { headless, viewport: defaultViewport },\n      localInfo: { localSource: \"isolated\" },\n    };\n  }\n  // ...\n}\n```\n\nSources: [packages/cli/src/local-strategy.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-strategy.ts)\n\n| 策略 | 说明 |\n|------|------|\n| `isolated` | 启动独立的 Chromium 实例 |\n| `cdp` | 连接到指定的 Chrome DevTools Protocol 目标 |\n| `auto` | 自动检测本地调试端口 |\n\n### CDP 发现机制\n\n`packages/cli/src/local-cdp-discovery.ts` 实现了自动发现本地 Chrome 调试端口的功能：\n\n```typescript\nasync function resolveDevToolsActivePortUrl(\n  port: number,\n  userDataDirs: string[],\n): Promise<string | null> {\n  for (const dir of userDataDirs) {\n    const info = await readDevToolsActivePort(dir);\n    if (!info || info.port !== port) {\n      continue;\n    }\n    // 验证端口可达性\n    if (!(await isPortReachable(info.port))) {\n      await cleanupStaleDevToolsActivePort(dir);\n      continue;\n    }\n    return buildDevToolsWsUrl(info.port, info.wsPath);\n  }\n  return null;\n}\n```\n\nSources: [packages/cli/src/local-cdp-discovery.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-cdp-discovery.ts)\n\n## 网络捕获集成\n\n### 快照与网络数据\n\n无障碍树快照可以与网络捕获功能结合使用：\n\n```typescript\ninterface PendingRequest {\n  id: string;\n  timestamp: string;\n  method: string;\n  url: string;\n  headers: Record<string, string>;\n  body: string | null;\n  resourceType: string;\n}\n```\n\n每个网络请求保存到文件系统时，使用 URL 解析生成目录名：\n\n```typescript\nfunction getRequestDirName(\n  counter: number,\n  method: string,\n  url: string,\n): string {\n  try {\n    const parsed = new URL(url);\n    const domain = sanitizeForFilename(parsed.hostname, 30);\n    const pathPart = parsed.pathname.split(\"/\").filter(Boolean)[0] || \"root\";\n    const pathSlug = sanitizeForFilename(pathPart, 20);\n    return `${String(counter).padStart(3, \"0\")}-${method}-${domain}-${pathSlug}`;\n  } catch {\n    return `${String(counter).padStart(3, \"0\")}-${method}-unknown`;\n  }\n}\n```\n\nSources: [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n\n## 使用场景\n\n### 基本工作流程\n\n```mermaid\ngraph LR\n    A[open <url>] --> B[snapshot]\n    B --> C[xpathMap + urlMap]\n    C --> D[click <element>]\n    D --> E[verify state]\n    E --> F[screenshot]\n```\n\n### 多页面管理\n\nStagehand 支持多标签页操作：\n\n```typescript\nprogram\n  .command(\"pages\")\n  .description(\"List all open pages\")\n  .action(async () => {\n    const result = await runCommand(\"pages\", []);\n    output(result, opts.json ?? false);\n  });\n\nprogram\n  .command(\"tab_close [index]\")\n  .alias(\"close\")\n  .description(\"Close tab by index (defaults to last tab)\")\n  .action(async (index?: string) => {\n    const result = await runCommand(\"tab_close\", [\n      index ? parseInt(index) : undefined,\n    ]);\n    output(result, opts.json ?? false);\n  });\n```\n\n## 总结\n\nDOM 与无障碍树系统是 Stagehand 实现浏览器自动化的基础。通过将复杂 DOM 结构转换为语义化的无障碍树，结合 XPath 映射和坐标解析，AI 代理能够准确理解和操作网页元素。该系统与 CLI 工具深度集成，提供 `snapshot`、`get`、`is` 等命令支持灵活的页面检查和交互操作。\n\n---\n\n<a id='deep-locator'></a>\n\n## Deep Locator 深层定位器\n\n### Related Pages\n\nRelated topics: [DOM 与无障碍树](#dom-accessibility), [act() 操作执行](#act-api)\n\n<details>\n<summary>Relevant source files</summary>\n\nThe following files were used as context for generating this wiki page:\n\n- [packages/cli/src/index.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/index.ts)\n- [packages/cli/src/local-strategy.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-strategy.ts)\n- [packages/cli/src/local-cdp-discovery.ts](https://github.com/browserbase/stagehand/blob/main/packages/cli/src/local-cdp-discovery.ts)\n</details>\n\n# Deep Locator 深层定位器\n\n## 概述\n\nDeep Locator（深层定位器）是 Stagehand 框架中负责精确定位和操作 DOM 元素的核心子系统。它通过多层次的定位策略、跨帧（iframe）处理、以及智能选择器解析，实现了对复杂网页结构中元素的可靠访问。该系统是 Stagehand 能够实现高精度自动化控制的关键技术基础。\n\n**核心职责：**\n\n- 提供多种元素定位策略（CSS 选择器、XPath、坐标等）\n- 处理跨 iframe/跨帧的元素定位\n- 管理浏览器上下文和帧的注册与追踪\n- 解析和优化选择器以提高定位准确性\n- 与 CLI 命令层紧密集成，支持交互式定位操作\n\nSources: [packages/cli/src/index.ts:1-50]()\n\n---\n\n## 架构组件\n\nDeep Locator 系统由以下核心组件构成，它们协同工作以实现端到端的元素定位能力：\n\n| 组件名称 | 文件路径 | 主要职责 |\n|---------|---------|---------|\n| DeepLocator | `packages/core/lib/v3/understudy/deepLocator.ts` | 主定位引擎，整合多种定位策略 |\n| Piercer | `packages/core/lib/v3/understudy/piercer.ts` | 处理 iframe 穿透和跨帧定位 |\n| FrameRegistry | `packages/core/lib/v3/understudy/frameRegistry.ts` | 管理帧层级结构和状态 |\n| SelectorResolver | `packages/core/lib/v3/understudy/selectorResolver.ts` | 选择器解析和优化 |\n\nSources: [packages/cli/src/index.ts:50-80]()\n\n### 组件关系图\n\n```mermaid\ngraph TD\n    A[CLI Command] --> B[DeepLocator]\n    B --> C[SelectorResolver]\n    B --> D[Piercer]\n    D --> E[FrameRegistry]\n    E --> F[Browser CDP]\n    C --> F\n    F --> B\n```\n\n---\n\n## 定位策略\n\nStagehand 的 Deep Locator 支持多种定位策略，适用于不同的场景需求：\n\n### 基础定位命令\n\n| 命令 | 用途 | 典型用法 |\n|-----|------|---------|\n| `click` | 点击元素 | `click <selector> [options]` |\n| `hover` | 悬停元素/坐标 | `hover <x> <y> [--xpath]` |\n| `fill` | 填写表单输入 | `fill <selector> <value>` |\n| `type` | 模拟打字输入 | `type <text> [--delay] [--mistakes]` |\n| `select` | 选择下拉选项 | `select <selector> <values...>` |\n\nSources: [packages/cli/src/index.ts:200-280]()\n\n### 坐标操作\n\n对于无法通过选择器精确定位的场景，系统支持基于坐标的操作：\n\n```typescript\nprogram\n  .command(\"scroll <x> <y> <deltaX> <deltaY>\")\n  .description(\"Scroll at coordinates\")\n  .option(\"--xpath\", \"Return XPath of scrolled element\")\n```\n\n### 元素状态检查\n\n在执行操作前，系统允许检查元素状态以确保操作安全：\n\n| 检查类型 | 说明 |\n|---------|------|\n| `visible` | 元素是否可见 |\n| `checked` | 复选框/单选框是否选中 |\n| `attached` | 元素是否在 DOM 中 |\n| `detached` | 元素是否已从 DOM 移除 |\n\nSources: [packages/cli/src/index.ts:180-200]()\n\n---\n\n## 帧（Frame）管理\n\nDeep Locator 的一个关键特性是能够处理嵌套的 iframe 结构。FrameRegistry 组件维护了一个帧层级注册表。\n\n### 本地策略解析\n\n系统通过 `resolveLocalStrategy` 函数管理本地浏览器实例的帧发现：\n\n```typescript\nexport async function resolveLocalStrategy({\n  localConfig,\n  headless,\n  defaultViewport,\n  discoverLocalCdp,\n  resolveWsTarget,\n}: ResolveLocalStrategyOptions): Promise<ResolvedLocalStrategy>\n```\n\n**支持的三种本地策略：**\n\n| 策略 | 描述 | 使用场景 |\n|-----|------|---------|\n| `isolated` | 启动独立 Chromium 实例 | 完全隔离的测试环境 |\n| `cdp` | 连接到已有 Chrome DevTools | 附加到正在运行的浏览器 |\n| `auto` | 自动检测可用浏览器 | 灵活适配不同环境 |\n\nSources: [packages/cli/src/local-strategy.ts:30-80]()\n\n### CDP 发现机制\n\n系统通过 `discoverLocalCdp` 函数自动发现可用的 Chrome DevTools Protocol 端点：\n\n```mermaid\ngraph LR\n    A[Scan Chrome Profile Dirs] --> B[Read DevToolsActivePort]\n    B --> C{Port Reachable?}\n    C -->|Yes| D[Build WebSocket URL]\n    C -->|No| E[Cleanup Stale File]\n    D --> F[Return wsUrl]\n    E --> A\n```\n\nSources: [packages/cli/src/local-cdp-discovery.ts:50-100]()\n\n---\n\n## 选择器解析器\n\nSelectorResolver 负责将人类可读的选择器表达式转换为高效的浏览器指令：\n\n### 选择器类型支持\n\n| 类型 | 示例 | 优先级 |\n|-----|------|-------|\n| CSS 选择器 | `#id`, `.class`, `div[data-*]` | 高 |\n| XPath | `//div[@class='target']` | 中 |\n| 文本匹配 | `text=\"登录\"` | 中 |\n| 混合表达式 | `button:text(\"提交\")` | 中 |\n\n### 优化策略\n\n系统会智能优化选择器以提高性能：\n\n1. **缓存机制** - 缓存最近使用的选择器结果\n2. **批量查询** - 合并多个选择器请求\n3. **超时控制** - 防止单个选择器阻塞整个流程\n\n---\n\n## 网络捕获与调试\n\nDeep Locator 集成网络捕获功能，便于调试定位问题：\n\n### 网络请求状态管理\n\n```typescript\ninterface PendingRequest {\n  id: string;\n  timestamp: string;\n  method: string;\n  url: string;\n  headers: Record<string, string>;\n  body: string | null;\n  resourceType: string;\n}\n```\n\nSources: [packages/cli/src/index.ts:15-30]()\n\n### 文件系统写入\n\n每个捕获的请求都会写入独立的目录结构：\n\n```\nnetwork-capture/\n├── 001-GET-api.example.com/users\n│   ├── request.json\n│   └── response.json\n└── 002-POST-api.example.com/login\n    ├── request.json\n    └── response.json\n```\n\n**目录命名规范：**\n\n```typescript\nfunction getRequestDirName(\n  counter: number,\n  method: string,\n  url: string,\n): string {\n  const parsed = new URL(url);\n  const domain = sanitizeForFilename(parsed.hostname, 30);\n  const pathPart = parsed.pathname.split(\"/\").filter(Boolean)[0] || \"root\";\n  const pathSlug = sanitizeForFilename(pathPart, 20);\n  return `${String(counter).padStart(3, \"0\")}-${method}-${domain}-${pathSlug}`;\n}\n```\n\nSources: [packages/cli/src/index.ts:40-60]()\n\n---\n\n## 守护进程基础设施\n\nDeep Locator 使用 Unix Socket 通信实现高效的守护进程模式：\n\n### 锁机制\n\n```mermaid\ngraph TD\n    A[Acquire Lock] --> B{File Exists?}\n    B -->|No| C[Create Lock File]\n    B -->|Yes| D{Process Alive?}\n    D -->|Yes| E[Wait 100ms]\n    D -->|No| F[Remove Stale Lock]\n    E --> B\n    C --> G[Lock Acquired]\n    F --> B\n```\n\n**关键特性：**\n\n- 使用 `O_EXCL` 确保原子性文件创建\n- 检测僵尸进程并自动清理过期锁\n- 可配置超时机制（默认 10000ms）\n\nSources: [packages/cli/src/index.ts:280-320]()\n\n### Socket 路径管理\n\n```typescript\nconst SOCKET_DIR = os.tmpdir();\n\nfunction getSocketPath(session: string): string {\n  return path.join(SOCKET_DIR, `browse-${session}.sock`);\n}\n\nfunction getLockPath(session: string): string {\n  return path.join(SOCKET_DIR, `browse-${session}.lock`);\n}\n```\n\n---\n\n## CLI 命令参考\n\n### 基础导航\n\n```bash\n# 打开 URL\nbrowse open <url> [--wait load|domcontentloaded|networkidle] [-t timeout]\nbrowse goto <url>  # alias\n\n# 创建新页面\nbrowse newpage [url]\n\n# 页面信息\nbrowse get <what> [selector]  # url|title|text|html|markdown|value|box\n```\n\n### 元素操作\n\n```bash\n# 点击\nbrowse click <selector> [-d delay] [-x|--xpath]\n\n# 输入\nbrowse fill <selector> <value> [--no-press-enter]\nbrowse type <text> [-d delay] [--mistakes]\n\n# 键盘\nbrowse press <key>  # Enter, Tab, Escape, Cmd+A, etc.\n```\n\n### 截图功能\n\n```bash\nbrowse screenshot [path]\n  [--full-page]           # 整页截图\n  [--type png|jpeg]       # 图片格式\n  [--quality 0-100]       # JPEG 质量\n  [--clip <json>]         # 裁剪区域\n  [--no-animations]       # 禁用动画\n  [--hide-caret]          # 隐藏文本光标\n```\n\nSources: [packages/cli/src/index.ts:350-400]()\n\n---\n\n## 配置选项\n\n### 全局选项\n\n| 选项 | 类型 | 说明 |\n|-----|------|------|\n| `--headless` | boolean | 无头模式运行 |\n| `--headed` | boolean | 显示浏览器窗口 |\n| `--json` | boolean | JSON 格式输出 |\n| `--session` | string | 会话标识符 |\n| `--connect` | string | 连接远程浏览器 |\n| `--ws` | string | WebSocket 地址 |\n\n### 远程会话选项\n\n| 选项 | 说明 |\n|-----|------|\n| `--proxies` | 启用代理支持 |\n| `--advanced-stealth` | 高级反检测 |\n| `--solve-captchas` | 自动解决验证码 |\n| `--region` | 区域设置 |\n| `--keep-alive` | 保持连接活跃 |\n| `--session-timeout` | 会话超时秒数 |\n| `--block-ads` | 拦截广告 |\n\nSources: [packages/cli/src/index.ts:400-450]()\n\n---\n\n## 工作流程图\n\n```mermaid\nsequenceDiagram\n    participant CLI\n    participant DeepLocator\n    participant SelectorResolver\n    participant FrameRegistry\n    participant CDP\n\n    CLI->>DeepLocator: locate(element)\n    DeepLocator->>SelectorResolver: resolve(selector)\n    SelectorResolver->>CDP: query()\n    CDP-->>SelectorResolver: elements[]\n    SelectorResolver-->>DeepLocator: resolved\n    DeepLocator->>FrameRegistry: checkFrame(element)\n    FrameRegistry->>CDP: switchContext()\n    CDP-->>FrameRegistry: context\n    FrameRegistry-->>DeepLocator: frameContext\n    DeepLocator-->>CLI: result\n```\n\n---\n\n## 最佳实践\n\n1. **选择器优先级** - 优先使用 ID 选择器，其次是 data 属性，避免过度依赖 XPath\n2. **等待策略** - 使用显式等待（`wait` 命令）而非固定延迟\n3. **帧切换** - 跨帧操作前务必使用 `FrameRegistry` 进行上下文切换\n4. **网络调试** - 定位问题时启用网络捕获功能分析请求流\n5. **截图验证** - 使用 `--hide-caret` 和 `--no-animations` 获取稳定截图\n\n---\n\n---\n\n## Doramagic 踩坑日志\n\n项目：browserbase/stagehand\n\n摘要：发现 7 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：身份坑 - 仓库名和安装名不一致。\n\n## 1. 身份坑 · 仓库名和安装名不一致\n\n- 严重度：medium\n- 证据强度：runtime_trace\n- 发现：仓库名 `stagehand` 与安装入口 `create-browser-app` 不完全一致。\n- 对用户的影响：用户照着仓库名搜索包或照着包名找仓库时容易走错入口。\n- 建议检查：在 npm/PyPI/GitHub 上确认包名映射和官方 README 说明。\n- 复现命令：`npx create-browser-app`\n- 防护动作：页面必须同时展示 repo 名和真实安装入口，避免用户搜索错包。\n- 证据：identity.distribution | github_repo:776908852 | https://github.com/browserbase/stagehand | repo=stagehand; install=create-browser-app\n\n## 2. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | github_repo:776908852 | https://github.com/browserbase/stagehand | README/documentation is current enough for a first validation pass.\n\n## 3. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | github_repo:776908852 | https://github.com/browserbase/stagehand | last_activity_observed missing\n\n## 4. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | github_repo:776908852 | https://github.com/browserbase/stagehand | no_demo; severity=medium\n\n## 5. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | github_repo:776908852 | https://github.com/browserbase/stagehand | no_demo; severity=medium\n\n## 6. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | github_repo:776908852 | https://github.com/browserbase/stagehand | issue_or_pr_quality=unknown\n\n## 7. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | github_repo:776908852 | https://github.com/browserbase/stagehand | release_recency=unknown\n\n<!-- canonical_name: browserbase/stagehand; human_manual_source: deepwiki_human_wiki -->\n",
      "summary": "DeepWiki/Human Wiki 完整输出，末尾追加 Discovery Agent 踩坑日志。",
      "title": "Human Manual / 人类版说明书"
    },
    "pitfall_log": {
      "asset_id": "pitfall_log",
      "filename": "PITFALL_LOG.md",
      "markdown": "# Pitfall Log / 踩坑日志\n\n项目：browserbase/stagehand\n\n摘要：发现 7 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：身份坑 - 仓库名和安装名不一致。\n\n## 1. 身份坑 · 仓库名和安装名不一致\n\n- 严重度：medium\n- 证据强度：runtime_trace\n- 发现：仓库名 `stagehand` 与安装入口 `create-browser-app` 不完全一致。\n- 对用户的影响：用户照着仓库名搜索包或照着包名找仓库时容易走错入口。\n- 建议检查：在 npm/PyPI/GitHub 上确认包名映射和官方 README 说明。\n- 复现命令：`npx create-browser-app`\n- 防护动作：页面必须同时展示 repo 名和真实安装入口，避免用户搜索错包。\n- 证据：identity.distribution | github_repo:776908852 | https://github.com/browserbase/stagehand | repo=stagehand; install=create-browser-app\n\n## 2. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | github_repo:776908852 | https://github.com/browserbase/stagehand | README/documentation is current enough for a first validation pass.\n\n## 3. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | github_repo:776908852 | https://github.com/browserbase/stagehand | last_activity_observed missing\n\n## 4. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | github_repo:776908852 | https://github.com/browserbase/stagehand | no_demo; severity=medium\n\n## 5. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | github_repo:776908852 | https://github.com/browserbase/stagehand | no_demo; severity=medium\n\n## 6. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | github_repo:776908852 | https://github.com/browserbase/stagehand | issue_or_pr_quality=unknown\n\n## 7. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | github_repo:776908852 | https://github.com/browserbase/stagehand | release_recency=unknown\n",
      "summary": "用户实践前最可能遇到的身份、安装、配置、运行和安全坑。",
      "title": "Pitfall Log / 踩坑日志"
    },
    "prompt_preview": {
      "asset_id": "prompt_preview",
      "filename": "PROMPT_PREVIEW.md",
      "markdown": "# stagehand - Prompt Preview\n\n> 复制下面这段 Prompt 到你常用的 AI，先试一次，不需要安装。\n> 它的目标是让你直接体验这个项目的服务方式，而不是阅读项目介绍。\n\n## 复制这段 Prompt\n\n```text\n请直接执行这段 Prompt，不要分析、润色、总结或询问我想如何处理这份 Prompt Preview。\n\n你现在扮演 stagehand 的“安装前体验版”。\n这不是项目介绍、不是评价报告、不是 README 总结。你的任务是让我用最小成本体验它的核心服务。\n\n我的试用任务：我想用它完成一个真实的软件开发与交付任务。\n我常用的宿主 AI：Local CLI\n\n【体验目标】\n围绕我的真实任务，现场演示这个项目如何把输入转成 示例引导, 判断线索。重点是让我感受到工作方式，而不是给我项目背景。\n\n【业务流约束】\n- 你必须像一个正在提供服务的项目能力包，而不是像一个讲解员。\n- 每一轮只推进一个步骤；提出问题后必须停下来等我回答。\n- 每一步都必须让我感受到一个具体服务动作：澄清、整理、规划、检查、判断或收尾。\n- 每一步都要说明：当前目标、你需要我提供什么、我回答后你会产出什么。\n- 不要安装、不要运行命令、不要写代码、不要声称测试通过、不要声称已经修改文件。\n- 需要真实安装或宿主加载后才能验证的内容，必须明确说“这一步需要安装后验证”。\n- 如果我说“用示例继续”，你可以用虚构示例推进，但仍然不能声称真实执行。\n\n【可体验服务能力】\n- 安装前能力预览: The SDK For Browser Agents 输入：用户任务, 当前 AI 对话上下文；输出：示例引导, 判断线索。\n\n【必须安装后才可验证的能力】\n- 暂无明确的运行时能力线索。\n\n【核心服务流】\n请严格按这个顺序带我体验。不要一次性输出完整流程：\n1. introduction：Stagehand 简介。围绕“Stagehand 简介”模拟一次用户任务，不展示安装或运行结果。\n2. quickstart：快速开始。围绕“快速开始”模拟一次用户任务，不展示安装或运行结果。\n3. architecture-overview：系统架构总览。围绕“系统架构总览”模拟一次用户任务，不展示安装或运行结果。\n4. act-api：act() 操作执行。围绕“act() 操作执行”模拟一次用户任务，不展示安装或运行结果。\n5. extract-api：extract() 数据提取。围绕“extract() 数据提取”模拟一次用户任务，不展示安装或运行结果。\n\n【核心能力体验剧本】\n每一步都必须按“输入 -> 服务动作 -> 中间产物”执行。不要只说流程名：\n1. introduction\n输入：用户提供的“Stagehand 简介”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n2. quickstart\n输入：用户提供的“快速开始”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n3. architecture-overview\n输入：用户提供的“系统架构总览”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n4. act-api\n输入：用户提供的“act() 操作执行”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n5. extract-api\n输入：用户提供的“extract() 数据提取”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n【项目服务规则】\n这些规则决定你如何服务用户。不要解释规则本身，而要在每一步执行时遵守：\n- 先确认用户任务、输入材料和成功标准，再模拟项目能力。\n- 每一步都必须形成可检查的小产物，并等待用户确认后再继续。\n- 凡是需要安装、调用工具或访问外部服务的能力，都必须标记为安装后验证。\n\n【每一步的服务约束】\n- Step 1 / introduction：Step 1 必须围绕“Stagehand 简介”形成一个小中间产物，并等待用户确认。\n- Step 2 / quickstart：Step 2 必须围绕“快速开始”形成一个小中间产物，并等待用户确认。\n- Step 3 / architecture-overview：Step 3 必须围绕“系统架构总览”形成一个小中间产物，并等待用户确认。\n- Step 4 / act-api：Step 4 必须围绕“act() 操作执行”形成一个小中间产物，并等待用户确认。\n- Step 5 / extract-api：Step 5 必须围绕“extract() 数据提取”形成一个小中间产物，并等待用户确认。\n\n【边界与风险】\n- 不要声称已经安装、运行、调用 API、读写本地文件或完成真实任务。\n- 安装前预览只能展示工作方式，不能证明兼容性、性能或输出质量。\n\n【可追溯依据】\n这些路径只用于你内部校验或在我追问“依据是什么”时简要引用。不要在首次回复主动展开：\n- https://github.com/browserbase/stagehand\n- https://github.com/browserbase/stagehand#readme\n- README.md\n- packages/core/lib/v3/v3.ts\n- packages/core/package.json\n- packages/core/examples/example.ts\n- .env.example\n- packages/core/lib/v3/index.ts\n- pnpm-workspace.yaml\n- packages/core/lib/v3/handlers/actHandler.ts\n- packages/core/lib/v3/agent/tools/act.ts\n- packages/core/lib/v3/agent/tools/click.ts\n\n【首次问题规则】\n- 首次三问必须先确认用户目标、成功标准和边界，不要提前进入工具、安装或实现细节。\n- 如果后续需要技术条件、文件路径或运行环境，必须等用户确认目标后再追问。\n\n首次回复必须只输出下面 4 个部分：\n1. 体验开始：用 1 句话说明你将带我体验 stagehand 的核心服务。\n2. 当前步骤：明确进入 Step 1，并说明这一步要解决什么。\n3. 你会如何服务我：说明你会先改变我完成任务的哪个动作。\n4. 只问我 3 个问题，然后停下等待回答。\n\n首次回复禁止输出：后续完整流程、证据清单、安装命令、项目评价、营销文案、已经安装或运行的说法。\n\nStep 1 / brainstorming 的二轮协议：\n- 我回答首次三问后，你仍然停留在 Step 1 / brainstorming，不要进入 Step 2。\n- 第二次回复必须产出 6 个部分：澄清后的任务定义、成功标准、边界条件、\n  2-3 个可选方案、每个方案的权衡、推荐方案。\n- 第二次回复最后必须问我是否确认推荐方案；只有我明确确认后，才能进入下一步。\n- 第二次回复禁止输出 git worktree、代码计划、测试文件、命令或真实执行结果。\n\n后续对话规则：\n- 我回答后，你先完成当前步骤的中间产物并等待确认；只有我确认后，才能进入下一步。\n- 每一步都要生成一个小的中间产物，例如澄清后的目标、计划草案、测试意图、验证清单或继续/停止判断。\n- 所有演示都写成“我会建议/我会引导/这一步会形成”，不要写成已经真实执行。\n- 不要声称已经测试通过、文件已修改、命令已运行或结果已产生。\n- 如果某个能力必须安装后验证，请直接说“这一步需要安装后验证”。\n- 如果证据不足，请明确说“证据不足”，不要补事实。\n```\n",
      "summary": "不安装项目也能感受能力节奏的安全试用 Prompt。",
      "title": "Prompt Preview / 安装前试用 Prompt"
    },
    "quick_start": {
      "asset_id": "quick_start",
      "filename": "QUICK_START.md",
      "markdown": "# Quick Start / 官方入口\n\n项目：browserbase/stagehand\n\n## 官方安装入口\n\n### Node.js / npx · 官方安装入口\n\n```bash\nnpx create-browser-app\n```\n\n来源：https://github.com/browserbase/stagehand#readme\n\n## 来源\n\n- repo: https://github.com/browserbase/stagehand\n- docs: https://github.com/browserbase/stagehand#readme\n",
      "summary": "从项目官方 README 或安装文档提取的开工入口。",
      "title": "Quick Start / 官方入口"
    }
  },
  "validation_id": "dval_d8fcc448d22743929dc86fb361a4021f"
}
