(async () => {
  let runtimeLifecycleInitialized = false;
  let extensionContextInvalidated = false;
  if (
    window.top !== window
    || window.__MMW_QIANCHUAN_AGENT__
    || window.__MMW_QIANCHUAN_AGENT_LOADING__
  ) return;
  window.__MMW_QIANCHUAN_AGENT_LOADING__ = true;
  try {
    const access = await sendRuntime({ type: "QIANCHUAN_AGENT_ACCESS" });
    if (access?.payload?.allowed !== true) return;
    window.__MMW_QIANCHUAN_AGENT__ = true;
  } finally {
    window.__MMW_QIANCHUAN_AGENT_LOADING__ = false;
  }

  const ACTION_LABELS = {
    open_target: "打开计划",
    pause: "暂停",
    resume: "恢复",
    set_budget: "调整预算",
    set_roi: "调整 ROI"
  };
  const actionExecutor = window.MMWQianchuanActionExecutor;
  const OperationStateMachine = window.MMWQianchuanOperationStateMachine?.OperationStateMachine;
  const takeoverControllerApi = window.MMWQianchuanTakeoverController;
  const agentPlannerApi = window.MMWQianchuanAgentPlanner;
  const DEFAULT_SETTINGS = {
    mode: "confirm",
    budget_cap: 0,
    max_budget_change_percent: 20,
    max_actions_per_day: 8,
    patrol_interval_minutes: 5,
    notifications_enabled: true
  };
  const LAUNCHER_POSITION_KEY = "mmw.qianchuanAgent.launcher.v1";
  const TOOLS_PANEL_STATE_KEY = "mmw.qianchuanAgent.toolsPanel.v1";
  const AGENT_POWER_STORAGE_PREFIX = "mmw.qianchuanAgent.power.v1:";
  const PANEL_ENTRY_EVENT = "MMW_QIANCHUAN_AGENT_PANEL";
  const LAUNCHER_EDGE_GAP = 10;
  const LAUNCHER_COLLAPSED_SIZE = 42;
  const PANEL_GAP = 8;
  const pageContextApi = window.MMWQianchuanPageContext;
  const readonlyObserverApi = window.MMWQianchuanReadonlyObserver;
  const remoteControlApi = window.MMWQianchuanRemoteControl;
  const monitorRuleApi = window.MMWQianchuanMonitorRules;
  const workflowApi = window.MMWQianchuanWorkflowTemplate;
  const dataReportApi = window.MMWQianchuanDataReport;
  const planControlCooldownApi = window.MMWQianchuanPlanControlCooldown;
  const workflowRuntimeApi = window.MMWQianchuanWorkflowRuntime;
  const preferenceApi = window.MMWQianchuanPersonalPreferences;
  const taskPatrolApi = window.MMWQianchuanTaskPatrol;
  const confirmationApi = window.MMWQianchuanCommandConfirmation;
  const usageNoticeApi = window.MMWQianchuanUsageNotice;
  const initialPageContext = detectPageContext();
  const INSTANCE_ID = `qca-${Date.now()}-${Math.random().toString(36).slice(2)}`;
  const state = {
    open: false,
    toolsOpen: readToolsPanelOpen(),
    busy: false,
    agentEnabled: false,
    agentPowerLoaded: false,
    agentPowerKey: "",
    agentPowerEpoch: 0,
    agentPhase: "off",
    agentPhaseDetail: "自动任务与远程指令已停止",
    pageContext: initialPageContext,
    scope: initialPageContext.scope,
    accountKey: detectAccountKey(),
    accountName: "",
    modelId: "",
    messages: [],
    activityRecords: [],
    proposals: [],
    memories: [],
    monitorRules: [],
    preferences: {
      dialogue_habit: "",
      operation_habit: "",
      configured_count: 0,
      updated_at: ""
    },
    skills: {
      mode: "workbench",
      personal_rule_count: 0,
      public_rule_count: 0,
      public_candidate_count: 0
    },
    audits: [],
    settings: { ...DEFAULT_SETTINGS },
    workflowConfig: workflowApi?.normalizeConfig?.({}) || {},
    workflowRuntime: workflowApi?.normalizeRuntime?.({}) || {},
    persistedMode: "confirm",
    weixin: { bound: false, ready: false, message: "正在读取客户端微信连接" },
    feishu: { configured: false, connected: false, notificationsReady: false, message: "正在读取客户端飞书连接" },
    miniapp: { enabled: false, connected: false, lastSyncAt: 0, lastError: "", message: "正在读取小程序通道" },
    remotePolling: false,
    remoteCommandBusy: false,
    remoteDeferredCommands: new Map(),
    lastWeixinCommandStatusAt: 0,
    lastWorkerHeartbeatAt: 0,
    lastPatrolAt: 0,
    lastMonitorPatrolAt: 0,
    modelRecovery: null,
    status: { ready: false, message: "正在连接本机 Claw" }
  };

  const root = document.createElement("div");
  root.id = "mmw-qianchuan-agent-root";
  root.dataset.pluginVersion = chrome.runtime.getManifest().version;
  root.dataset.agentRuntime = "managed-remote-v2";
  root.innerHTML = `
    <button class="mmw-qca-launch" type="button" aria-label="打开千川 Agent" title="请从插件悬浮窗的千川托管入口打开" hidden>
      <span class="mmw-qca-launch-mark" aria-hidden="true">川</span><span class="mmw-qca-launch-label">千川 Agent</span>
    </button>
    <aside class="mmw-qca-panel" aria-label="千川 Agent 运行记录" hidden>
      <header class="mmw-qca-header">
        <div><strong>千川 Agent</strong><span class="mmw-qca-scope"></span></div>
        <div class="mmw-qca-header-actions">
          <button class="mmw-qca-tools-toggle" type="button" data-action="toggle-tools" aria-controls="mmw-qca-tools-panel" aria-expanded="false">
            <span class="mmw-qca-tools-indicator" aria-hidden="true"></span><span>功能栏</span><span class="mmw-qca-tools-chevron" aria-hidden="true">‹</span>
          </button>
          <button class="mmw-qca-icon" type="button" data-action="close" aria-label="关闭千川 Agent">×</button>
        </div>
      </header>
      <div class="mmw-qca-wallet-reminder" role="note">
        <span>AI 托管功能请在 AI 钱包内预留余额，确保稳定正常使用。</span>
      </div>
      <div class="mmw-qca-usage-notice-bar">
        <button type="button" data-usage-notice-open>
          <span>使用须知</span><strong>查看</strong>
        </button>
      </div>
      <div class="mmw-qca-connection" role="status"></div>
      <div class="mmw-qca-body mmw-qca-chat-body">
        <section class="mmw-qca-runtime-summary" aria-label="自动化运行状态">
          <span class="mmw-qca-runtime-dot" aria-hidden="true"></span>
          <div><strong class="mmw-qca-runtime-title">规则任务未启用</strong><span class="mmw-qca-runtime-detail">保存模板后开始按周期巡检</span></div>
        </section>
        <section class="mmw-qca-messages" role="log" aria-live="polite" aria-relevant="additions"></section>
        <section class="mmw-qca-proposals" aria-label="待确认操作"></section>
      </div>
      <footer class="mmw-qca-runtime-footer">
        <div class="mmw-qca-power-control">
          <div><strong>AI 盯盘</strong><span data-agent-power-caption>已关闭</span></div>
          <button class="mmw-qca-agent-power" type="button" role="switch" aria-checked="false" data-action="toggle-agent-power" title="开启当前账户与场景的千川 Agent">
            <span data-agent-power-off>关闭</span><span data-agent-power-on>开启</span>
          </button>
        </div>
        <button type="button" class="mmw-qca-secondary" data-action="refresh">刷新状态</button>
      </footer>
    </aside>
    <aside id="mmw-qca-tools-panel" class="mmw-qca-tools-panel" aria-label="千川 Agent 功能栏" hidden>
      <header class="mmw-qca-tools-header">
        <div><strong>功能栏</strong><span class="mmw-qca-tools-summary">人工确认 · 0 条盯盘</span></div>
        <button class="mmw-qca-icon" type="button" data-action="close-tools" aria-label="收纳功能栏">×</button>
      </header>
      <div class="mmw-qca-tools-body">
        <details class="mmw-qca-managed-settings">
          <summary><span>一、运行模式</span><strong class="mmw-qca-mode-label">人工确认</strong></summary>
          <div class="mmw-qca-mode-switch" role="radiogroup" aria-label="千川 Agent 运行模式">
            <label><input type="radio" name="mmw-qca-mode" value="confirm" checked><span>人工确认</span></label>
            <label><input type="radio" name="mmw-qca-mode" value="managed"><span>全托管</span></label>
          </div>
          <p class="mmw-qca-section-note">人工确认在调控前等待点击确认；全托管仅在模板与安全上限内执行。</p>
          <div class="mmw-qca-managed-fields">
            <div class="mmw-qca-setting-grid">
              <label><span>每日调控安全上限</span><input type="number" min="1" max="30" step="1" data-setting="max_actions_per_day"><em>次</em></label>
              <label><span>预算目标安全上限</span><input type="number" min="0" max="100000000" step="100" data-setting="budget_cap"><em>元</em></label>
              <label class="is-wide"><span>ROI / 预算单次变化安全上限</span><input type="number" min="1" max="50" step="1" data-setting="max_budget_change_percent"><em>%</em></label>
            </div>
            <p class="mmw-qca-safety-note">这是安全刹车，不是本轮调控值。例如目标 ROI 从 2.0 提高 0.1，实际变化为 5%，需低于这里的上限才会执行。</p>
            <label class="mmw-qca-consent"><input type="checkbox" data-setting="managed_consent"><span>我授权 Agent 仅按当前账户、场景、计划范围、模板规则和安全上限自动调控</span></label>
          </div>
        </details>
        <details class="mmw-qca-workflow-automation" open>
          <summary><span>二、自动化任务</span><strong class="mmw-qca-workflow-enabled-label">未启用</strong></summary>
          <div class="mmw-qca-workflow-basics">
            <header>
              <div><strong>任务基础设置</strong></div>
              <em class="mmw-qca-workflow-basics-summary">全部计划 · 每 5 分钟</em>
            </header>
            <label class="mmw-qca-workflow-enable"><input type="checkbox" data-workflow="enabled"><span>启用当前账户与场景的规则任务</span></label>
            <div class="mmw-qca-workflow-scope">
              <span>计划范围</span>
              <div class="mmw-qca-mode-switch mmw-qca-target-switch" role="radiogroup" aria-label="计划监控范围">
                <label><input type="radio" name="mmw-qca-target-mode" value="all" checked><span>当前列表全部计划</span></label>
                <label><input type="radio" name="mmw-qca-target-mode" value="selected"><span>指定计划</span></label>
              </div>
              <div class="mmw-qca-target-plan" hidden>
                <header><span>指定计划 ID</span><button type="button" data-action="add-target-plan">＋ 新增指定计划</button></header>
                <div class="mmw-qca-target-plan-list" data-workflow-plan-list></div>
              </div>
              <p>指定计划最多添加 20 条，并按完整 ID 独立记录；每轮最多生成 1 个明确计划的调控。</p>
            </div>
            <div class="mmw-qca-workflow-interval">
              <label><span>巡检频率</span><input type="number" min="1" max="1440" step="1" data-workflow="intervalMinutes"><em>分钟一次</em></label>
            </div>
          </div>
          <div class="mmw-qca-workflow-rules-heading">
            <strong>调控规则</strong><span>点击规则查看和修改参数</span>
          </div>
          <div class="mmw-qca-workflow-rule-list">
            <details class="mmw-qca-workflow-rule mmw-qca-cold-start-rule">
              <summary>
                <span class="mmw-qca-rule-heading"><span class="mmw-qca-rule-kind is-down">下调</span><span><strong>计划冷启动</strong><small data-rule-preview="coldStart">低消耗时逐步降低目标 ROI</small></span></span>
                <span class="mmw-qca-rule-meta"><em class="mmw-qca-rule-state" data-rule-state="coldStart">未启用</em><i class="mmw-qca-rule-chevron" aria-hidden="true"></i></span>
              </summary>
              <div class="mmw-qca-workflow-rule-content">
                <div class="mmw-qca-rule-control-row"><span>规则参数</span><label class="mmw-qca-workflow-rule-toggle"><input type="checkbox" data-workflow="coldStartEnabled"><span>启用</span></label></div>
                <div class="mmw-qca-workflow-rule-fields mmw-qca-cold-start-rule-fields">
                  <label><span>累计最多下调</span><input type="number" min="0.01" max="99" step="0.01" data-workflow="coldStartMaxDecrease"></label>
                  <label><span>每次下调</span><input type="number" min="0.01" max="99" step="0.01" data-workflow="coldStartRoiDecrease"></label>
                  <label><span>近一小时消耗低于</span><input type="number" min="0" max="100000000" step="1" data-workflow="coldStartHourlySpendBelow"><em>元</em></label>
                </div>
                <p>先连续观察满一小时，再按实际消耗增量判断；低于目标时逐步下调，达到累计下限或小时消耗达标即停止。暂停安全规则优先，同轮不会再执行上涨。</p>
              </div>
            </details>
            <details class="mmw-qca-workflow-rule mmw-qca-spend-pacing-rule">
              <summary>
                <span class="mmw-qca-rule-heading"><span class="mmw-qca-rule-kind is-up">上调</span><span><strong>消耗流速调控</strong><small data-rule-preview="spendPacing">消耗过快时提高目标 ROI</small></span></span>
                <span class="mmw-qca-rule-meta"><em class="mmw-qca-rule-state" data-rule-state="spendPacing">未启用</em><i class="mmw-qca-rule-chevron" aria-hidden="true"></i></span>
              </summary>
              <div class="mmw-qca-workflow-rule-content">
                <div class="mmw-qca-workflow-rule-fields mmw-qca-spend-pacing-rule-fields">
                  <label><span>近一小时目标消耗</span><input type="number" min="0" max="100000000" step="1" data-workflow="hourlySpendTarget"><em>元</em></label>
                  <label><span>实际消耗超过目标</span><input type="number" min="0" max="10000" step="0.1" data-workflow="spendOverPercent"><em>%</em></label>
                  <label><span>每次提高目标 ROI</span><input type="number" min="0.1" max="99" step="0.1" data-workflow="roiIncrease"></label>
                </div>
                <p>完整观察满一小时后计算消耗流速；超过目标与容差才提高 ROI。目标为 0 时不执行上涨，重试不会重复累加。</p>
              </div>
            </details>
            <details class="mmw-qca-workflow-rule mmw-qca-pause-rule is-enabled">
              <summary>
                <span class="mmw-qca-rule-heading"><span class="mmw-qca-rule-kind is-guard">保护</span><span><strong>暂停调控</strong><small data-rule-preview="pause">三个条件同时满足才暂停</small></span></span>
                <span class="mmw-qca-rule-meta"><em class="mmw-qca-rule-state is-guard" data-rule-state="pause">安全规则</em><i class="mmw-qca-rule-chevron" aria-hidden="true"></i></span>
              </summary>
              <div class="mmw-qca-workflow-rule-content">
                <div class="mmw-qca-workflow-rule-fields mmw-qca-pause-rule-fields">
                  <label><span>净 ROI 低于</span><input type="number" min="0.01" max="100" step="0.01" data-workflow="pauseBelowNetRoi"></label>
                  <label><span>计划当前消耗至少</span><input type="number" min="0" max="100000000" step="1" data-workflow="minimumSpend"><em>元</em></label>
                  <label><span>连续达到条件</span><input type="number" min="1" max="12" step="1" data-workflow="lowRoiCycles"><em>轮后暂停</em></label>
                </div>
                <p>最低消耗是暂停门槛，不参与上涨判断；任一条件不满足都不会暂停。</p>
              </div>
            </details>
          </div>
        </details>
        <details class="mmw-qca-workflow-notifications" open>
          <summary><span>三、通知设置</span><strong class="mmw-qca-notification-label">仅客户端</strong></summary>
          <div class="mmw-qca-notification-rules">
            <label><input type="checkbox" data-workflow="balanceEnabled"><span>账户余额低于</span><input type="number" min="0" max="100000000" step="1" data-workflow="balanceBelow"><em>元提醒</em></label>
            <label><input type="checkbox" data-workflow="revenueRiseEnabled"><span>净成交较上轮上涨</span><input type="number" min="0.1" max="10000" step="0.1" data-workflow="revenueRisePercent"><em>% 提醒</em></label>
            <label><input type="checkbox" data-workflow="netRoiEnabled"><span>账户净 ROI 低于</span><input type="number" min="0.01" max="100" step="0.01" data-workflow="netRoiBelow"><em>提醒</em></label>
          </div>
          <section class="mmw-qca-data-report-settings">
            <header><strong>定时数据通知</strong><span>跟随上方计划范围</span></header>
            <label class="mmw-qca-data-report-enable"><input type="checkbox" data-workflow="dataReportEnabled"><span>每</span><input type="number" min="1" max="1440" step="1" data-workflow="dataReportIntervalMinutes"><em>分钟发送一次</em></label>
            <div class="mmw-qca-data-report-types" aria-label="数据通知类型">
              <label><input type="checkbox" data-workflow="dataReportDashboard"><span>千川表盘总数据</span></label>
              <label><input type="checkbox" data-workflow="dataReportPlans"><span>计划数据（全部 / 指定计划）</span></label>
            </div>
            <div class="mmw-qca-report-delivery-default"><strong>默认多账户合并发送</strong><span>同一轮数据由客户端汇总后发送</span></div>
            <details class="mmw-qca-report-advanced">
              <summary><span>高级通知设置</span><strong class="mmw-qca-report-delivery-label">默认合并</strong></summary>
              <label><input type="checkbox" data-workflow="deliveryModePerAccount"><span>按账户分别发送</span></label>
              <p>开启后仍由客户端按队列逐个发送，不会让多个插件同时挤占通知通道。</p>
            </details>
            <p>多个浏览器和插件只负责采集；客户端统一去重、排队并通过 Claw 通道发送，避免微信或飞书消息并发挤线。</p>
          </section>
          <div class="mmw-qca-routing-summary">
            <span class="mmw-qca-routing-mark" aria-hidden="true">总</span>
            <div><strong>由 Agent 总控统一分发</strong><small class="mmw-qca-routing-detail">正在读取可用通道</small></div>
            <em class="mmw-qca-routing-status">读取中</em>
          </div>
          <details class="mmw-qca-channel-activation-note">
            <summary><span>外部通道使用提示</span><strong>查看</strong></summary>
            <div>
              <p>请保持客户端登录。微信和飞书需完成 Claw 配置，并先在对应 Bot 会话中主动发送消息，激活消息收发。</p>
              <p>微信受官方通道限制，无法常驻接收消息，建议约每 30 分钟主动对话一次；常驻消息请优先使用飞书或小程序。</p>
              <p>数据格式和个人习惯可直接向 Agent 总控（AI）说明。</p>
            </div>
          </details>
        </details>
        <div class="mmw-qca-settings-actions">
          <button type="button" class="mmw-qca-primary" data-action="save-workflow">保存并应用模板</button>
          <button type="button" class="mmw-qca-danger" data-action="emergency-stop" hidden>停止全托管</button>
        </div>
      </div>
    </aside>
    <dialog class="mmw-qca-usage-notice-dialog" aria-labelledby="mmw-qca-usage-notice-title">
      <header>
        <div>
          <h2 id="mmw-qca-usage-notice-title">千川 Agent 使用须知</h2>
          <p data-usage-notice-version></p>
        </div>
        <button type="button" class="mmw-qca-icon" data-usage-notice-close aria-label="关闭使用须知">×</button>
      </header>
      <p class="mmw-qca-usage-notice-trigger" data-usage-notice-trigger></p>
      <div class="mmw-qca-usage-notice-content" data-usage-notice-content></div>
      <footer>
        <button type="button" class="mmw-qca-primary" data-usage-notice-close>关闭</button>
      </footer>
    </dialog>`;
  document.documentElement.appendChild(root);
  const usageNoticeController = usageNoticeApi?.mount?.(root);
  let activeOperationMachine = null;
  const takeoverController = takeoverControllerApi?.createTakeoverController?.({
    isEnabled: () => isAgentPowerOn(),
    onUserStop: () => isAgentPowerOn() ? toggleAgentPower() : Promise.resolve()
  });
  state.accountName = detectAccountName(state.accountKey);
  const planControlCooldown = planControlCooldownApi?.createPlanControlCooldown?.({
    chromeApi: chrome,
    getContext: () => ({
      accountKey: state.accountKey,
      scope: state.scope,
      supported: state.pageContext?.supported === true
    }),
    getAudits: () => state.audits
  });
  const workflowController = workflowRuntimeApi?.createWorkflowRuntime?.({
    workflowApi,
    dataReportApi,
    chromeApi: chrome,
    root,
    state,
    actionLabels: ACTION_LABELS,
    collectSnapshot: collectPageSnapshot,
    acquireLease: acquirePatrolLease,
    setBusy,
    normalizeProposal,
    executeProposal,
    checkPlanControlCooldown: inspectPlanControlCooldown,
    postEvent: postConversationEvent,
    submitDataReport: (report) => sendRuntime({ type: "QIANCHUAN_AGENT_DATA_REPORT", report }).then((response) => response?.payload || {}),
    submitNotification: submitTotalControllerNotification,
    isAgentEnabled: () => isAgentPowerOn(),
    isFatalRuntimeError: isExtensionContextInvalidated,
    onFatalRuntimeError: invalidateExtensionContext,
    setAgentPhase,
    workerInstanceId: INSTANCE_ID,
    render
  });

  const launch = root.querySelector(".mmw-qca-launch");
  const panel = root.querySelector(".mmw-qca-panel");
  const toolsPanel = root.querySelector(".mmw-qca-tools-panel");
  const composer = root.querySelector(".mmw-qca-composer textarea");
  let launcherDrag = null;
  let suppressLauncherClick = false;
  let pageContextSyncTimer = 0;
  let recognitionRetryTimer = 0;
  let recognitionRetryCount = 0;
  let agentAccessActive = true;
  let pageObserver = null;
  launch.addEventListener("click", (event) => {
    if (suppressLauncherClick) {
      event.preventDefault();
      suppressLauncherClick = false;
      return;
    }
    togglePanel(true);
  });
  launch.addEventListener("pointerdown", beginLauncherDrag);
  launch.addEventListener("pointermove", moveLauncher);
  launch.addEventListener("pointerup", endLauncherDrag);
  launch.addEventListener("pointercancel", endLauncherDrag);
  root.addEventListener("click", handleClick);
  root.addEventListener("input", handleWorkflowRulePreviewInput);
  root.addEventListener("change", handleChange);
  window.addEventListener("resize", syncLauncherPosition);
  window.addEventListener(PANEL_ENTRY_EVENT, handlePanelEntryEvent);
  applyLauncherPosition(readLauncherPosition());
  togglePanel(new URL(location.href).searchParams.get("mmw_qc_agent") === "1", { focus: false });

  render();
  void refreshState();
  const workflowTimer = window.setInterval(() => {
    void workflowController?.run();
    void workflowController?.runDataReport();
  }, 15 * 1000);
  const remotePollTimer = window.setInterval(() => void runRemotePollCycle(), 4 * 1000);
  chrome.runtime.onMessage.addListener(handleRuntimeMessage);
  chrome.storage.onChanged.addListener(handleAgentPowerStorageChange);
  function handleRuntimeMessage(message, _sender, sendResponse) {
    if (message?.type === "QIANCHUAN_AGENT_ACCESS_REVOKED") {
      revokeQianchuanAgentAccess();
      return false;
    }
    if (message?.type !== "QIANCHUAN_AGENT_REMOTE_PULSE" || !agentAccessActive) return false;
    runBackgroundAgentPulse()
      .then(() => sendResponse({ ok: true, accountKey: state.accountKey, scope: state.scope }))
      .catch((error) => sendResponse({ ok: false, error: error.message || "千川远程指令轮询失败" }));
    return true;
  }

  function handlePanelEntryEvent(event) {
    if (!agentAccessActive || event?.detail?.source !== "mmw-floating-desktop") return;
    togglePanel(event.detail.open !== false);
  }
  document.addEventListener("click", schedulePageContextSync, true);
  const handleVisibilityChange = () => {
    if (agentAccessActive) void registerWorkerHeartbeat(true);
  };
  document.addEventListener("visibilitychange", handleVisibilityChange);
  window.addEventListener("pagehide", handlePageHide);
  function handlePageHide() {
    if (agentAccessActive) void reportDispatchObservation(false);
  }
  window.addEventListener("popstate", schedulePageContextSync);
  window.addEventListener("hashchange", schedulePageContextSync);
  pageObserver = new MutationObserver((mutations) => {
    if (mutations.some((mutation) => !root.contains(mutation.target))) schedulePageContextSync();
  });
  pageObserver.observe(document.body || document.documentElement, { childList: true, subtree: true, attributes: true });
  runtimeLifecycleInitialized = true;
  if (extensionContextInvalidated) {
    extensionContextInvalidated = false;
    invalidateExtensionContext(new Error("Extension context invalidated."));
  }

  function deactivateAgentRuntime(reason) {
    window.clearInterval(workflowTimer);
    window.clearInterval(remotePollTimer);
    window.clearTimeout(pageContextSyncTimer);
    window.clearTimeout(recognitionRetryTimer);
    activeOperationMachine?.cancel(reason);
    activeOperationMachine = null;
    takeoverController?.deactivate?.();
    takeoverController?.setMonitoring?.(false);
    pageObserver?.disconnect();
    try { chrome.runtime.onMessage.removeListener(handleRuntimeMessage); } catch {}
    try { chrome.storage.onChanged.removeListener(handleAgentPowerStorageChange); } catch {}
    document.removeEventListener("click", schedulePageContextSync, true);
    document.removeEventListener("visibilitychange", handleVisibilityChange);
    window.removeEventListener("pagehide", handlePageHide);
    window.removeEventListener("popstate", schedulePageContextSync);
    window.removeEventListener("hashchange", schedulePageContextSync);
    window.removeEventListener("resize", syncLauncherPosition);
    window.removeEventListener(PANEL_ENTRY_EVENT, handlePanelEntryEvent);
  }

  function revokeQianchuanAgentAccess() {
    if (!agentAccessActive) return;
    agentAccessActive = false;
    deactivateAgentRuntime("千川 Agent 会员权限已失效");
    root.remove();
    document.querySelectorAll(".mmw-qca-takeover").forEach((node) => node.remove());
    document.documentElement.classList.remove("mmw-qca-is-taken-over", "mmw-qca-managed-loop");
    window.__MMW_QIANCHUAN_AGENT__ = false;
  }

  function isExtensionContextInvalidated(error) {
    return /extension context invalidated|context invalidated/i.test(String(error?.message || error || ""));
  }

  function invalidateExtensionContext(error) {
    if (!isExtensionContextInvalidated(error)) return false;
    if (extensionContextInvalidated) return true;
    extensionContextInvalidated = true;
    if (!runtimeLifecycleInitialized) return true;

    agentAccessActive = false;
    stopAgentRuntime("插件已更新，当前页面需要刷新");
    deactivateAgentRuntime("插件已更新，当前页面需要刷新");
    state.remotePolling = false;
    state.remoteCommandBusy = false;
    state.modelRecovery = null;
    state.status = { ready: false, message: "插件已更新，请刷新当前千川页面" };
    setToolsPanelOpen(false, { focus: false, persist: false });
    state.activityRecords = dedupeActivityRecords(state.activityRecords).filter(
      (record) => !isExtensionContextInvalidated(record?.text)
    );
    state.activityRecords = workflowController?.mergeRecords(state.activityRecords, [{
      id: "extension-context-invalidated",
      createdAt: Date.now(),
      level: "warning",
      text: "插件已更新，旧页面已停止巡检和调控。刷新当前千川页面后即可恢复。"
    }]) || state.activityRecords;
    root.dataset.contextInvalidated = "true";
    launch.title = "插件已更新，请打开 Agent 并刷新页面";
    launch.setAttribute("aria-label", "插件已更新，请打开千川 Agent 并刷新页面");
    render();
    return true;
  }

  function dedupeActivityRecords(records) {
    const seen = new Set();
    return [...(Array.isArray(records) ? records : [])].reverse().filter((record) => {
      const key = `${record?.level || "info"}:${String(record?.text || "")}`;
      if (!record?.text || seen.has(key)) return false;
      seen.add(key);
      return true;
    }).reverse();
  }

  function agentPowerStorageKey(accountKey = state.accountKey, scope = state.scope) {
    if (!accountKey || !scope) return "";
    return `${AGENT_POWER_STORAGE_PREFIX}${encodeURIComponent(accountKey)}:${encodeURIComponent(scope)}`;
  }

  function hasAgentPowerContext() {
    return state.pageContext?.supported === true
      && Boolean(state.pageContext?.deliveryMode)
      && state.pageContext?.deliveryMode !== "unknown"
      && Boolean(state.pageContext?.promotionTarget)
      && state.pageContext?.promotionTarget !== "unknown"
      && Boolean(state.accountKey)
      && Boolean(state.scope);
  }

  function isAgentPowerOn(epoch = state.agentPowerEpoch) {
    return agentAccessActive === true
      && extensionContextInvalidated === false
      && state.agentPowerLoaded === true
      && state.agentEnabled === true
      && hasAgentPowerContext()
      && epoch === state.agentPowerEpoch;
  }

  function requireAgentPower(epoch = state.agentPowerEpoch) {
    if (!isAgentPowerOn(epoch)) throw new Error("千川 Agent 总开关已关闭，本次未执行。");
  }

  function setAgentPhase(phase, detail = "") {
    const allowed = new Set(["monitoring", "observing", "executing", "verifying", "attention"]);
    if (!isAgentPowerOn()) {
      state.agentPhase = "off";
      state.agentPhaseDetail = "自动任务与远程指令已停止";
    } else {
      state.agentPhase = allowed.has(phase) ? phase : "monitoring";
      state.agentPhaseDetail = String(detail || monitoringPhaseDetail()).slice(0, 160);
    }
    renderAgentPowerState();
  }

  function monitoringPhaseDetail() {
    const config = workflowApi?.normalizeConfig?.(state.workflowConfig) || state.workflowConfig || {};
    const childTaskCount = Number(config.enabled === true)
      + Number(config.dataReport?.enabled === true)
      + state.monitorRules.filter((rule) => rule.enabled).length
      + Number(state.persistedMode === "managed");
    return childTaskCount ? "当前账户与场景的已启用任务正在盯盘" : "主电源已开启，等待启用规则或数据通知";
  }

  function stopAgentRuntime(reason = "千川 Agent 总开关已关闭") {
    state.agentPowerEpoch += 1;
    activeOperationMachine?.cancel(reason);
    activeOperationMachine = null;
    takeoverController?.deactivate?.();
    takeoverController?.setMonitoring?.(false);
    state.agentPhase = "off";
    state.agentPhaseDetail = "自动任务与远程指令已停止";
  }

  function readAgentPower(key) {
    return new Promise((resolve, reject) => {
      try {
        chrome.storage.local.get(key, (values) => {
          let error = null;
          try { error = chrome.runtime.lastError; } catch (caught) { error = caught; }
          if (error) {
            const normalized = new Error(error.message || "总开关状态读取失败");
            invalidateExtensionContext(normalized);
            reject(normalized);
          } else resolve(values?.[key] === true);
        });
      } catch (error) {
        invalidateExtensionContext(error);
        reject(error);
      }
    });
  }

  function persistAgentPower(key, enabled) {
    return new Promise((resolve, reject) => {
      try {
        chrome.storage.local.set({ [key]: enabled === true }, () => {
          let error = null;
          try { error = chrome.runtime.lastError; } catch (caught) { error = caught; }
          if (error) {
            const normalized = new Error(error.message || "总开关状态保存失败");
            invalidateExtensionContext(normalized);
            reject(normalized);
          } else resolve();
        });
      } catch (error) {
        invalidateExtensionContext(error);
        reject(error);
      }
    });
  }

  async function loadAgentPower() {
    const key = hasAgentPowerContext() ? agentPowerStorageKey() : "";
    if (!key) {
      state.agentEnabled = false;
      state.agentPowerLoaded = true;
      state.agentPowerKey = "";
      stopAgentRuntime("千川账号或场景尚未明确");
      return;
    }
    if (state.agentPowerKey !== key) {
      state.agentEnabled = false;
      state.agentPowerLoaded = false;
      state.agentPowerKey = key;
      stopAgentRuntime("千川账号或场景已切换");
    }
    try {
      const enabled = await readAgentPower(key);
      if (state.agentPowerKey !== key || agentPowerStorageKey() !== key || !hasAgentPowerContext()) return;
      state.agentPowerLoaded = true;
      state.agentEnabled = enabled;
      if (enabled) {
        state.agentPowerEpoch += 1;
        state.agentPhase = "monitoring";
        state.agentPhaseDetail = monitoringPhaseDetail();
      } else {
        stopAgentRuntime("千川 Agent 总开关处于关闭状态");
      }
    } catch (error) {
      if (state.agentPowerKey !== key) return;
      state.agentEnabled = false;
      state.agentPowerLoaded = true;
      stopAgentRuntime("千川 Agent 总开关读取失败");
      state.agentPhaseDetail = error.message || "总开关状态读取失败，请重试";
    }
  }

  async function toggleAgentPower() {
    if (!state.agentPowerLoaded || !hasAgentPowerContext()) {
      state.status = { ready: false, message: "请等待当前千川账号和投放场景识别完成" };
      render();
      return;
    }
    const key = agentPowerStorageKey();
    if (!key || key !== state.agentPowerKey) return;
    const nextEnabled = !state.agentEnabled;
    try {
      await persistAgentPower(key, nextEnabled);
      if (key !== state.agentPowerKey || key !== agentPowerStorageKey()) return;
      state.agentPowerLoaded = true;
      state.agentEnabled = nextEnabled;
      if (nextEnabled) {
        state.agentPowerEpoch += 1;
        state.agentPhase = "monitoring";
        state.agentPhaseDetail = monitoringPhaseDetail();
        state.status = { ...state.status, message: "千川 Agent 已开启，等待已启用的子任务" };
      } else {
        stopAgentRuntime("用户已关闭千川 Agent 总开关");
        state.status = { ...state.status, message: "千川 Agent 已关闭，自动任务和远程指令已停止" };
      }
    } catch (error) {
      state.status = { ...state.status, message: error.message || "千川 Agent 总开关保存失败" };
    }
    render();
  }

  function handleAgentPowerStorageChange(changes, areaName) {
    const key = state.agentPowerKey;
    if (areaName !== "local" || !key || !changes?.[key] || !hasAgentPowerContext()) return;
    const enabled = changes[key].newValue === true;
    state.agentPowerLoaded = true;
    state.agentEnabled = enabled;
    if (enabled) {
      state.agentPowerEpoch += 1;
      state.agentPhase = "monitoring";
      state.agentPhaseDetail = monitoringPhaseDetail();
    } else {
      stopAgentRuntime("千川 Agent 总开关已在另一页面关闭");
    }
    render();
  }

  function togglePanel(open, { focus = true } = {}) {
    const wasOpen = state.open;
    state.open = Boolean(open);
    panel.hidden = !state.open;
    toolsPanel.hidden = !state.open || !state.toolsOpen;
    toolsPanel.inert = toolsPanel.hidden;
    launch.hidden = true;
    if (state.open) {
      applyPanelPosition(readLauncherPosition());
      if (!wasOpen) void usageNoticeController?.openOnce?.();
      if (focus) root.querySelector("[data-action='toggle-tools']")?.focus();
    }
    syncToolsPanelToggle();
  }

  function collapseAgentPanelsForOperation() {
    const restoreOpen = state.open;
    togglePanel(false, { focus: false });
    launch.hidden = true;
    return () => {
      launch.hidden = true;
      if (restoreOpen) togglePanel(true, { focus: false });
    };
  }

  function readToolsPanelOpen() {
    try {
      return localStorage.getItem(TOOLS_PANEL_STATE_KEY) === "open";
    } catch {
      return false;
    }
  }

  function setToolsPanelOpen(open, { focus = true, persist = true } = {}) {
    state.toolsOpen = Boolean(open);
    toolsPanel.hidden = !state.open || !state.toolsOpen;
    toolsPanel.inert = toolsPanel.hidden;
    if (persist) {
      try {
        localStorage.setItem(TOOLS_PANEL_STATE_KEY, state.toolsOpen ? "open" : "closed");
      } catch {}
    }
    applyPanelPosition(readLauncherPosition());
    syncToolsPanelToggle();
    if (!focus) return;
    if (state.toolsOpen) toolsPanel.querySelector("[data-action='close-tools']")?.focus();
    else root.querySelector("[data-action='toggle-tools']")?.focus();
  }

  function syncToolsPanelToggle() {
    const toggle = root.querySelector("[data-action='toggle-tools']");
    if (!toggle) return;
    const open = state.open && state.toolsOpen;
    const side = panel.dataset.side === "left" ? "left" : "right";
    toggle.setAttribute("aria-expanded", String(open));
    toggle.setAttribute("aria-label", `${open ? "收纳" : "打开"}功能栏，当前${toggle.dataset.summary || "人工确认"}`);
    toggle.classList.toggle("is-open", open);
    toggle.querySelector(".mmw-qca-tools-chevron").textContent = open
      ? side === "right" ? "›" : "‹"
      : side === "right" ? "‹" : "›";
  }

  function readLauncherPosition() {
    const fallback = { side: "right", top: Math.max(LAUNCHER_EDGE_GAP, window.innerHeight - 90) };
    try {
      const saved = JSON.parse(localStorage.getItem(LAUNCHER_POSITION_KEY) || "{}");
      return {
        side: saved.side === "left" ? "left" : "right",
        top: clampLauncherTop(saved.top ?? fallback.top)
      };
    } catch {
      return fallback;
    }
  }

  function saveLauncherPosition(position) {
    localStorage.setItem(LAUNCHER_POSITION_KEY, JSON.stringify(position));
  }

  function clampLauncherTop(value) {
    const maxTop = Math.max(LAUNCHER_EDGE_GAP, window.innerHeight - LAUNCHER_COLLAPSED_SIZE - LAUNCHER_EDGE_GAP);
    return Math.max(LAUNCHER_EDGE_GAP, Math.min(Number(value) || LAUNCHER_EDGE_GAP, maxTop));
  }

  function applyLauncherPosition(position) {
    const side = position.side === "left" ? "left" : "right";
    const top = clampLauncherTop(position.top);
    launch.classList.remove("is-dragging", "is-docked-left", "is-docked-right");
    launch.classList.add(`is-docked-${side}`);
    launch.style.top = `${top}px`;
    launch.style.bottom = "auto";
    launch.style.left = side === "left" ? "0" : "auto";
    launch.style.right = side === "right" ? "0" : "auto";
    if (state.open) applyPanelPosition({ side, top });
  }

  function applyPanelPosition(position) {
    const side = position.side === "left" ? "left" : "right";
    const panelHeight = Math.min(690, Math.max(0, window.innerHeight - 20));
    const maxTop = Math.max(LAUNCHER_EDGE_GAP, window.innerHeight - panelHeight - LAUNCHER_EDGE_GAP);
    const top = Math.max(LAUNCHER_EDGE_GAP, Math.min(Number(position.top) || LAUNCHER_EDGE_GAP, maxTop));
    panel.style.top = `${top}px`;
    panel.style.bottom = "auto";
    panel.style.left = side === "left" ? `${LAUNCHER_EDGE_GAP}px` : "auto";
    panel.style.right = side === "right" ? `${LAUNCHER_EDGE_GAP}px` : "auto";
    panel.dataset.side = side;
    const panelWidth = panel.getBoundingClientRect().width || Math.min(390, Math.max(0, window.innerWidth - 28));
    const toolsWidth = Math.min(320, Math.max(0, window.innerWidth - 20));
    const inline = window.innerWidth >= panelWidth + toolsWidth + (LAUNCHER_EDGE_GAP * 2) + PANEL_GAP;
    toolsPanel.dataset.layout = inline ? "inline" : "overlay";
    toolsPanel.dataset.side = side;
    toolsPanel.style.top = `${top}px`;
    toolsPanel.style.bottom = "auto";
    if (inline) {
      const offset = LAUNCHER_EDGE_GAP + panelWidth + PANEL_GAP;
      toolsPanel.style.left = side === "left" ? `${offset}px` : "auto";
      toolsPanel.style.right = side === "right" ? `${offset}px` : "auto";
    } else {
      toolsPanel.style.left = side === "left" ? `${LAUNCHER_EDGE_GAP}px` : "auto";
      toolsPanel.style.right = side === "right" ? `${LAUNCHER_EDGE_GAP}px` : "auto";
    }
  }

  function beginLauncherDrag(event) {
    if (event.button !== 0) return;
    const rect = launch.getBoundingClientRect();
    launcherDrag = {
      pointerId: event.pointerId,
      startX: event.clientX,
      startY: event.clientY,
      left: rect.left,
      top: rect.top,
      moved: false
    };
    launch.setPointerCapture?.(event.pointerId);
    launch.classList.remove("is-docked-left", "is-docked-right");
    launch.classList.add("is-dragging");
    launch.style.left = `${rect.left}px`;
    launch.style.right = "auto";
    launch.style.top = `${rect.top}px`;
    launch.style.bottom = "auto";
  }

  function moveLauncher(event) {
    if (!launcherDrag || launcherDrag.pointerId !== event.pointerId) return;
    const deltaX = event.clientX - launcherDrag.startX;
    const deltaY = event.clientY - launcherDrag.startY;
    if (Math.abs(deltaX) + Math.abs(deltaY) > 5) launcherDrag.moved = true;
    if (!launcherDrag.moved) return;
    event.preventDefault();
    const width = launch.offsetWidth || LAUNCHER_COLLAPSED_SIZE;
    const height = launch.offsetHeight || LAUNCHER_COLLAPSED_SIZE;
    const left = Math.max(0, Math.min(launcherDrag.left + deltaX, window.innerWidth - width));
    const top = Math.max(LAUNCHER_EDGE_GAP, Math.min(launcherDrag.top + deltaY, window.innerHeight - height - LAUNCHER_EDGE_GAP));
    launch.style.left = `${left}px`;
    launch.style.top = `${top}px`;
  }

  function endLauncherDrag(event) {
    if (!launcherDrag || launcherDrag.pointerId !== event.pointerId) return;
    const moved = launcherDrag.moved;
    launcherDrag = null;
    launch.releasePointerCapture?.(event.pointerId);
    const rect = launch.getBoundingClientRect();
    const position = {
      side: rect.left + rect.width / 2 < window.innerWidth / 2 ? "left" : "right",
      top: clampLauncherTop(rect.top)
    };
    suppressLauncherClick = moved;
    if (moved) window.setTimeout(() => { suppressLauncherClick = false; }, 0);
    saveLauncherPosition(position);
    applyLauncherPosition(position);
  }

  function syncLauncherPosition() {
    const position = readLauncherPosition();
    position.top = clampLauncherTop(position.top);
    saveLauncherPosition(position);
    applyLauncherPosition(position);
  }

  async function handleClick(event) {
    const button = event.target.closest("button[data-action]");
    if (!button) return;
    const action = button.dataset.action;
    if (action === "reload-page") {
      window.location.reload();
      return;
    }
    if (action === "close") {
      togglePanel(false);
      return;
    }
    if (extensionContextInvalidated) return;
    if (action === "toggle-tools") {
      setToolsPanelOpen(!state.toolsOpen);
      return;
    }
    if (action === "close-tools") {
      setToolsPanelOpen(false);
      return;
    }
    if (action === "toggle-agent-power") {
      if (event.isTrusted === true) await toggleAgentPower();
      return;
    }
    if (action === "add-target-plan") {
      addTargetPlanField();
      return;
    }
    if (action === "remove-target-plan") {
      removeTargetPlanField(button);
      return;
    }
    if (action === "emergency-stop") {
      await emergencyStop();
      return;
    }
    if (state.busy || state.remoteCommandBusy) return;
    if (action === "refresh") await refreshState();
    if (action === "retry-model") await recoverModelRequest(false);
    if (action === "fallback-model") await recoverModelRequest(true);
    if (action === "save-memory") await saveManualMemory();
    if (action === "save-proposal-memory") await saveProposalMemory(button.dataset.proposalId);
    if (action === "dismiss") dismissProposal(button.dataset.proposalId);
    if (action === "delete-memory") await deleteMemory(button.dataset.memoryId);
    if (action === "toggle-monitor-rule") await toggleMonitorRule(button.dataset.ruleId, button.dataset.enabled !== "true");
    if (action === "delete-monitor-rule") await deleteMonitorRule(button.dataset.ruleId);
    if (action === "focus-monitor-rule") focusMonitorRuleComposer();
    if (action === "save-settings") await saveSettings();
    if (action === "save-workflow") await saveWorkflowTemplate();
    if (action === "confirm-workflow-action") await workflowController?.confirm(button.dataset.proposalId);
    if (action === "dismiss-workflow-action") await workflowController?.dismiss(button.dataset.proposalId);
    if (action === "save-task-patrol") await saveTaskPatrol();
    if (action === "save-skill") await saveSkillSettings();
    if (action === "save-preferences") await savePersonalPreferences();
  }

  function handleChange(event) {
    const input = event.target;
    if (input.matches("input[name='mmw-qca-mode']")) {
      state.settings.mode = input.value === "managed" ? "managed" : "confirm";
      state.workflowConfig.executionMode = state.settings.mode;
      renderSettings();
    }
    if (input.matches("input[name='mmw-qca-target-mode']")) {
      state.workflowConfig.targetMode = input.value === "selected" ? "selected" : "all";
      renderSettings();
    }
    if (input.matches("[data-workflow='coldStartEnabled']")) {
      const section = input.closest(".mmw-qca-cold-start-rule");
      section?.classList.toggle("is-enabled", input.checked);
      section?.querySelectorAll(".mmw-qca-cold-start-rule-fields input").forEach((field) => {
        field.disabled = !input.checked;
      });
      renderWorkflowRuleSummaries();
    }
    if (input.matches("input[name='mmw-qca-skill']")) {
      state.skills.mode = input.value === "personal" ? "personal" : "workbench";
      renderSkillSettings();
      renderProposals();
    }
  }

  function handleWorkflowRulePreviewInput(event) {
    if (event.target.matches("[data-workflow]")) renderWorkflowRuleSummaries();
  }

  async function refreshState(nextPageContext = detectPageContext(), nextAccountKey = detectAccountKey()) {
    if (extensionContextInvalidated) return;
    state.pageContext = nextPageContext;
    state.scope = nextPageContext.scope;
    state.accountKey = nextAccountKey;
    state.accountName = detectAccountName(nextAccountKey);
    await loadAgentPower();
    if (extensionContextInvalidated) return;
    if (!state.pageContext.supported || !state.scope) {
      void reportDispatchObservation(false);
      const waitingForScene = Boolean(state.accountKey)
        && (state.pageContext.deliveryMode === "unknown" || state.pageContext.promotionTarget === "unknown");
      state.status = {
        ready: false,
        message: waitingForScene ? "千川账号已识别，正在等待投放场景加载" : state.pageContext.message
      };
      state.settings = { ...DEFAULT_SETTINGS };
      state.monitorRules = [];
      state.persistedMode = "confirm";
      state.weixin = { bound: false, ready: false, message: "请先进入支持的投放场景" };
      state.feishu = { configured: false, connected: false, notificationsReady: false, message: "请先进入支持的投放场景" };
      state.miniapp = { enabled: false, connected: false, lastSyncAt: 0, lastError: "", message: "请先进入支持的投放场景" };
      render();
      scheduleRecognitionRetry();
      return;
    }
    if (!state.accountKey) {
      void reportDispatchObservation(false);
      state.status = { ready: false, message: "投放场景已识别，正在等待千川账号加载" };
      state.weixin = { bound: false, ready: false, message: "正在等待千川账号加载" };
      state.feishu = { configured: false, connected: false, notificationsReady: false, message: "正在等待千川账号加载" };
      state.miniapp = { enabled: false, connected: false, lastSyncAt: 0, lastError: "", message: "正在等待千川账号加载" };
      render();
      scheduleRecognitionRetry();
      return;
    }
    resetRecognitionRetry();
    const workflowStore = await workflowController?.loadStore().catch(() => ({})) || {};
    if (extensionContextInvalidated) return;
    state.workflowConfig = workflowApi?.normalizeConfig?.(workflowStore.config) || {};
    state.workflowRuntime = workflowApi?.normalizeRuntime?.(workflowStore.runtime) || {};
    state.activityRecords = Array.isArray(workflowStore.records) ? workflowStore.records.slice(-50) : [];
    await registerWorkerHeartbeat(true);
    try {
      const [status, cloud, weixin, conversation] = await Promise.all([
        sendRuntime({ type: "QIANCHUAN_AGENT_STATUS" }),
        sendRuntime({ type: "QIANCHUAN_AGENT_STATE", accountKey: state.accountKey, scope: state.scope }),
        sendRuntime({ type: "QIANCHUAN_AGENT_WEIXIN", action: "status", accountKey: state.accountKey, scope: state.scope }),
        sendRuntime({ type: "QIANCHUAN_AGENT_CONVERSATION", action: "history", accountKey: state.accountKey, scope: state.scope })
      ]);
      state.status = {
        ready: status?.payload?.gatewayOnline === true,
        message: status?.payload?.gatewayOnline
          ? pageReadinessMessage(collectPageSnapshot())
          : "请打开 MMW 客户端并启动 Claw 助手"
      };
      state.memories = Array.isArray(cloud?.payload?.memories) ? cloud.payload.memories : [];
      state.monitorRules = (Array.isArray(cloud?.payload?.monitor_rules) ? cloud.payload.monitor_rules : [])
        .map((item) => monitorRuleApi?.normalizeRule?.(item))
        .filter(Boolean);
      state.audits = Array.isArray(cloud?.payload?.audits) ? cloud.payload.audits : [];
      state.settings = normalizeSettings(cloud?.payload?.settings);
      state.skills = normalizeSkillState(cloud?.payload?.skills);
      state.preferences = normalizePersonalPreferences(cloud?.payload?.preferences);
      state.persistedMode = state.settings.mode;
      state.workflowConfig = workflowApi?.normalizeConfig?.({
        ...state.workflowConfig,
        executionMode: state.settings.mode,
        maxActionsPerDay: state.settings.max_actions_per_day
      }) || state.workflowConfig;
      state.weixin = weixin?.payload || { bound: false, ready: false, message: "客户端微信 Bot 尚未连接" };
      state.feishu = status?.payload?.feishu || {
        configured: false,
        connected: false,
        notificationsReady: false,
        message: "未读取到客户端飞书状态"
      };
      state.miniapp = status?.payload?.miniapp || {
        enabled: false,
        connected: false,
        lastSyncAt: 0,
        lastError: "",
        message: "未读取到小程序同步状态"
      };
      const conversationState = conversation?.payload?.conversation || {};
      state.modelId = String(conversationState.modelId || "");
      const history = Array.isArray(conversationState.messages)
        ? conversationState.messages
        : [];
      if (history.length && !state.busy) {
        state.messages = history
          .filter((item) => item?.kind !== "event" && ["user", "assistant"].includes(item?.role))
          .slice(-60)
          .map((item) => ({
            id: String(item.id || ""),
            role: item.role,
            content: String(item.content || ""),
            remote: item.source === "weixin",
            client: item.source === "client"
          }));
      }
      const serverEvents = history
        .filter((item) => item?.kind === "event")
        .slice(-30)
        .map((item) => ({
          id: String(item.id || ""),
          createdAt: Number(item.createdAt || 0),
          level: "info",
          text: workflowController?.compactText(item.content) || ""
        }));
      state.activityRecords = workflowController?.mergeRecords(state.activityRecords, serverEvents) || state.activityRecords;
      state.lastPatrolAt = readLastPatrolAt();
      state.lastMonitorPatrolAt = readLastMonitorPatrolAt();
    } catch (error) {
      if (invalidateExtensionContext(error)) return;
      state.status = { ready: false, message: error.message || "本机 Claw 未连接" };
      state.feishu = { configured: false, connected: false, notificationsReady: false, message: "客户端状态暂不可用" };
      state.miniapp = { enabled: false, connected: false, lastSyncAt: 0, lastError: "", message: "小程序同步状态暂不可用" };
    }
    render();
  }

  async function sendMessage() {
    const content = composer.value.trim();
    if (!content || state.busy || state.remoteCommandBusy) return;
    if (!state.scope || !state.accountKey) {
      state.status = { ready: false, message: state.pageContext.message || "请先进入支持的千川投放页面" };
      render();
      return;
    }
    const externalId = `plugin-${Date.now()}-${Math.random().toString(36).slice(2)}`;
    state.messages.push({ role: "user", content, id: externalId });
    composer.value = "";
    persistComposerDraft();
    setBusy(true);
    render();
    try {
      const monitorDraft = monitorRuleApi?.parseInstruction?.(content);
      const decision = confirmationApi?.parseDecision?.(content);
      if (decision) {
        await handleCommandDecision(decision.kind, decision.code, { source: "plugin", sourceId: externalId });
        return;
      }
      if (monitorDraft) {
        const proposal = normalizeProposal({ kind: "monitor_rule", payload: monitorDraft });
        state.proposals.push(proposal);
        await queueCommandConfirmation(proposal, { source: "plugin", sourceId: externalId });
        return;
      }
      if (await tryHandleReadonlyDataRequest(content, { source: "plugin", externalId })) return;
      const request = {
        messages: state.messages.filter((item) => !item.failed).slice(-12),
        contextExtra: {},
        meta: { source: "plugin", externalMessageId: externalId },
        modelId: state.modelId
      };
      const payload = await requestAgent(request.messages, request.contextExtra, request.meta);
      state.modelRecovery = null;
      await applyAgentPayload(payload, {
        executeDeterministicAction: true,
        authority: "explicit_instruction"
      });
    } catch (error) {
      state.messages.push({ role: "assistant", content: error.message || "千川 Agent 暂时无法回复。", failed: true });
      const message = error.message || "本机 Claw 未连接";
      if (isRecoverableModelError(message, state.modelId)) {
        state.modelRecovery = {
          messages: state.messages.filter((item) => !item.failed).slice(-12),
          contextExtra: {},
          meta: { source: "plugin", externalMessageId: externalId },
          modelId: state.modelId
        };
      }
      state.status = { ready: false, message };
    } finally {
      setBusy(false);
      render();
    }
  }

  async function requestAgent(messages, contextExtra = {}, meta = {}) {
    const latestUser = [...(Array.isArray(messages) ? messages : [])]
      .reverse()
      .find((item) => item?.role === "user" && String(item?.content || "").trim());
    const requestMessages = latestUser ? [latestUser] : [];
    const context = latestUser && qianchuanRequestNeedsPageContext(latestUser.content)
      ? { ...collectPageSnapshot(latestUser.content), ...contextExtra }
      : { ...contextExtra };
    const readonlyRequest = readonlyObserverApi?.parseRequest?.(latestUser?.content || "");
    if (readonlyRequest?.recognized) {
      const resolved = await resolveReadonlyDataObservation(latestUser.content);
      context.targetedReadonlyObservation = {
        facts: resolved.observation.facts.map(({ id, label, value, unit, evidence, confidence, source }) => ({ id, label, value, unit, evidence, confidence, source })),
        missingMetricIds: resolved.observation.missingMetricIds,
        pageUpdate: resolved.observation.pageUpdate?.value || "",
        visualError: resolved.visualError
      };
    }
    const response = await sendRuntime({
      type: "QIANCHUAN_AGENT_CHAT",
      accountKey: state.accountKey,
      scope: state.scope,
      sessionKey: `${state.accountKey}:${state.scope}`,
      messages: requestMessages,
      context,
      source: meta.source || "plugin",
      externalMessageId: meta.externalMessageId || "",
      modelId: meta.modelId || "",
      fallbackFromModelId: meta.fallbackFromModelId || "",
      persistConversation: meta.persistConversation !== false
    });
    return response?.payload || {};
  }

  async function applyAgentPayload(payload, options = {}) {
    const assistantText = String(payload.content || "").trim();
    if (assistantText) state.messages.push({ role: "assistant", content: assistantText });
    const proposals = Array.isArray(payload.proposals) ? payload.proposals : [];
    const normalized = proposals.map(normalizeProposal).filter(Boolean);
    state.proposals.push(...normalized);
    await executeUtilityProposals(normalized);
    const action = normalized.find((item) => item.kind === "action");
    if (action && options.executeDeterministicAction && isDeterministicIntentPayload(payload)) {
      await executeProposal(action, options.authority || "explicit_instruction");
    } else if (action && state.settings.mode === "managed") {
      await executeProposal(action, "managed");
    } else if (action) {
      await queueCommandConfirmation(action, { source: options.source || "plugin", sourceId: options.sourceId || "" });
    }
    if (!assistantText && !proposals.length) {
      state.messages.push({ role: "assistant", content: "我没有生成可执行建议，请补充目标计划或直播间名称后再试。" });
    }
    return normalized;
  }

  function isDeterministicIntentPayload(payload) {
    return payload?.contextDiagnostics?.route === "deterministic_intent";
  }

  function qianchuanRequestNeedsPageContext(message) {
    return /千川|投放|计划|预算|roi|消耗|成交|退款|暂停|恢复|开启|关闭|微信|发送|推商品|直播|全域|乘方|分析|数据|页面|账户|账号|导航|切换|记住|技能/i
      .test(String(message || ""));
  }

  function isRecoverableModelError(message, modelId) {
    const selected = String(modelId || "").trim();
    return Boolean(selected)
      && selected.toLowerCase() !== "gpt-5.4"
      && /线路不可用|响应超时|线路繁忙|限流|provider timeout|route unavailable/i.test(String(message || ""));
  }

  async function requestRemoteAgentWithFallback(messages, contextExtra = {}, meta = {}) {
    const selectedModel = String(meta.modelId || state.modelId || "").trim();
    try {
      return await requestAgent(messages, contextExtra, { ...meta, modelId: selectedModel });
    } catch (error) {
      if (!isRecoverableModelError(error?.message, selectedModel)) throw error;
      return requestAgent(messages, contextExtra, {
        ...meta,
        modelId: "gpt-5.4",
        fallbackFromModelId: selectedModel
      });
    }
  }

  async function recoverModelRequest(useFallback) {
    const recovery = state.modelRecovery;
    if (!recovery) return refreshState();
    setBusy(true);
    state.messages = state.messages.filter((item) => !item.failed);
    render();
    try {
      const payload = await requestAgent(recovery.messages, recovery.contextExtra, {
        ...recovery.meta,
        modelId: useFallback ? "gpt-5.4" : recovery.modelId,
        fallbackFromModelId: useFallback ? recovery.modelId : ""
      });
      await applyAgentPayload(payload);
      state.modelRecovery = null;
      state.status = {
        ready: true,
        message: useFallback
          ? `本次已由 GPT 5.4 完成，会话默认模型仍为 ${recovery.modelId}`
          : pageReadinessMessage(collectPageSnapshot())
      };
    } catch (error) {
      const message = error.message || "千川 Agent 暂时无法回复。";
      state.messages.push({ role: "assistant", content: message, failed: true });
      state.status = { ready: false, message };
    } finally {
      setBusy(false);
      render();
    }
  }

  function normalizeSettings(raw) {
    const source = raw && typeof raw === "object" ? raw : {};
    return {
      mode: source.mode === "managed" ? "managed" : "confirm",
      budget_cap: Number(source.budget_cap ?? source.budgetCap) || 0,
      max_budget_change_percent: Number(source.max_budget_change_percent ?? source.maxBudgetChangePercent) || 20,
      max_actions_per_day: Number(source.max_actions_per_day ?? source.maxActionsPerDay) || 8,
      patrol_interval_minutes: taskPatrolApi?.normalizeIntervalMinutes?.(
        source.patrol_interval_minutes ?? source.patrolIntervalMinutes,
        DEFAULT_SETTINGS.patrol_interval_minutes
      ) || 5,
      notifications_enabled: source.notifications_enabled !== false && source.notificationsEnabled !== false
    };
  }

  function normalizeSkillState(raw) {
    const source = raw && typeof raw === "object" ? raw : {};
    return {
      mode: source.mode === "personal" ? "personal" : "workbench",
      personal_rule_count: Number(source.personal_rule_count || 0),
      public_rule_count: Number(source.public_rule_count || 0),
      public_candidate_count: Number(source.public_candidate_count || 0)
    };
  }

  function normalizePersonalPreferences(raw) {
    if (preferenceApi?.normalizePreferences) return preferenceApi.normalizePreferences(raw);
    const source = raw && typeof raw === "object" ? raw : {};
    const dialogue = String(source.dialogue_habit || source.dialogueHabit || "").trim();
    const operation = String(source.operation_habit || source.operationHabit || "").trim();
    return {
      dialogue_habit: dialogue,
      operation_habit: operation,
      configured_count: Number(Boolean(dialogue)) + Number(Boolean(operation)),
      updated_at: String(source.updated_at || source.updatedAt || "")
    };
  }

  function workflowField(name) {
    return root.querySelector(`[data-workflow='${name}']`);
  }

  async function saveWorkflowTemplate() {
    if (!workflowApi?.validateConfig) {
      state.status = { ready: state.status.ready, message: "规则模板模块未加载，请刷新插件后重试" };
      render();
      return;
    }
    const validation = workflowApi.validateConfig(workflowController.readDraft(settingNumber));
    if (!validation.ok) {
      state.status = { ready: state.status.ready, message: validation.message };
      render();
      return;
    }
    const notificationReady = state.miniapp.connected
      || state.weixin.ready
      || state.feishu.notificationsReady;
    if (validation.value.executionMode === "managed" && !notificationReady) {
      state.status = { ready: state.status.ready, message: "开启全托管前请先连接可用的小程序、微信或飞书通知" };
      render();
      return;
    }
    const previous = state.workflowConfig;
    state.workflowConfig = validation.value;
    state.settings.mode = validation.value.executionMode;
    state.settings.patrol_interval_minutes = validation.value.intervalMinutes;
    state.settings.max_actions_per_day = validation.value.maxActionsPerDay;
    const settingsSaved = await saveSettings();
    if (!settingsSaved) {
      state.workflowConfig = previous;
      return;
    }
    try {
      state.workflowRuntime = workflowApi.normalizeRuntime({});
      const targetLabel = validation.value.targetMode === "all"
        ? "当前列表全部计划"
        : `${validation.value.planIds.length} 个指定计划`;
      await workflowController.addRecord(
        `自动化模板已保存 · ${validation.value.enabled ? `每 ${validation.value.intervalMinutes} 分钟巡检${targetLabel}` : "任务未启用"}`,
        "success"
      );
      state.status = { ready: state.status.ready, message: validation.value.enabled ? "规则模板已启用" : "规则模板已保存但未启用" };
      render();
      if (validation.value.enabled) void workflowController.run(true);
      if (validation.value.dataReport.enabled) void workflowController.runDataReport(true);
    } catch (error) {
      state.status = { ready: state.status.ready, message: error.message || "规则模板保存失败" };
      render();
    }
  }

  async function saveSettings(forcedMode = "") {
    if (!state.scope || !state.accountKey) {
      state.status = { ready: false, message: state.pageContext.message || "请先进入支持的千川投放页面" };
      render();
      return;
    }
    const mode = forcedMode || root.querySelector("input[name='mmw-qca-mode']:checked")?.value || "confirm";
    const next = {
      mode: mode === "managed" ? "managed" : "confirm",
      budget_cap: settingNumber("budget_cap"),
      max_budget_change_percent: settingNumber("max_budget_change_percent"),
      max_actions_per_day: settingNumber("max_actions_per_day"),
      patrol_interval_minutes: state.settings.patrol_interval_minutes,
      notifications_enabled: true
    };
    if (next.mode === "managed") {
      if (!root.querySelector("[data-setting='managed_consent']")?.checked && state.persistedMode !== "managed") {
        state.status = { ready: state.status.ready, message: "请先确认全托管授权范围" };
        render();
        return;
      }
      if (!state.weixin.ready) {
        state.status = { ready: state.status.ready, message: "开启全托管前请先在客户端 Claw 中连接微信 Bot" };
        render();
        return;
      }
    }
    const previousMode = state.persistedMode;
    let saved = false;
    setBusy(true);
    try {
      const response = await sendRuntime({
        type: "QIANCHUAN_AGENT_SETTINGS",
        accountKey: state.accountKey,
        scope: state.scope,
        payload: { account_key: state.accountKey, scope: state.scope, ...next }
      });
      state.settings = normalizeSettings(response?.payload);
      state.persistedMode = state.settings.mode;
      saved = true;
      state.status = {
        ready: state.status.ready,
        message: state.settings.mode === "managed" ? "全托管已开启，将按设置自动巡检" : "已切换为人工确认"
      };
      if (previousMode !== state.settings.mode && state.weixin.ready) {
        try {
          await sendWeixinNotification(
            state.settings.mode === "managed"
              ? `【千川 Agent】已开启全托管\n范围：${scopeLabel()}\n预算上限：${state.settings.budget_cap} 元\n单次最大调整：${state.settings.max_budget_change_percent}%\n每日最多操作：${state.settings.max_actions_per_day} 次`
              : `【千川 Agent】已停止全托管\n范围：${scopeLabel()}\n当前已恢复人工确认模式。`
          );
        } catch (notificationError) {
          if (state.settings.mode === "managed") {
            const rollback = await sendRuntime({
              type: "QIANCHUAN_AGENT_SETTINGS",
              accountKey: state.accountKey,
              scope: state.scope,
              payload: { account_key: state.accountKey, scope: state.scope, ...state.settings, mode: "confirm" }
            });
            state.settings = normalizeSettings(rollback?.payload);
            state.persistedMode = "confirm";
            throw new Error(`微信通知发送失败，已保持人工确认：${notificationError.message || "请在客户端 Claw 中检查微信连接"}`);
          }
          state.status = { ready: state.status.ready, message: `已停止全托管，但微信通知发送失败：${notificationError.message || "请在客户端 Claw 中检查微信连接"}` };
        }
      }
    } catch (error) {
      state.status = { ready: state.status.ready, message: error.message || "托管设置保存失败" };
    } finally {
      setBusy(false);
      render();
    }
    return saved;
  }

  async function emergencyStop() {
    state.settings.mode = "confirm";
    state.workflowConfig.executionMode = "confirm";
    const saved = await saveSettings("confirm");
    if (saved) {
      await workflowController?.addRecord("已停止全托管，规则任务保留为人工确认模式。", "warning").catch(() => null);
    }
  }

  async function saveTaskPatrol() {
    if (!state.scope || !state.accountKey) {
      state.status = { ready: false, message: state.pageContext.message || "请先进入支持的千川投放页面" };
      render();
      return;
    }
    const input = root.querySelector("[data-patrol-interval]");
    const interval = taskPatrolApi?.parseIntervalMinutes?.(input?.value);
    if (!interval) {
      state.status = { ready: state.status.ready, message: "任务轮巡间隔须为 1 到 1440 分钟的整数。" };
      render();
      return;
    }
    setBusy(true);
    try {
      const response = await sendRuntime({
        type: "QIANCHUAN_AGENT_SETTINGS",
        accountKey: state.accountKey,
        scope: state.scope,
        payload: {
          account_key: state.accountKey,
          scope: state.scope,
          ...state.settings,
          patrol_interval_minutes: interval
        }
      });
      state.settings = normalizeSettings(response?.payload);
      state.status = { ready: state.status.ready, message: `任务轮巡已设为每 ${state.settings.patrol_interval_minutes} 分钟检查一次` };
    } catch (error) {
      state.status = { ready: state.status.ready, message: error.message || "任务轮巡保存失败" };
    } finally {
      setBusy(false);
      render();
    }
  }

  async function saveSkillSettings() {
    if (!state.scope || !state.accountKey) {
      state.status = { ready: false, message: state.pageContext.message || "请先进入支持的千川投放页面" };
      render();
      return;
    }
    setBusy(true);
    try {
      const response = await sendRuntime({
        type: "QIANCHUAN_AGENT_SKILL",
        accountKey: state.accountKey,
        scope: state.scope,
        payload: {
          account_key: state.accountKey,
          scope: state.scope,
          mode: state.skills.mode,
          share_personal_insights: state.skills.mode === "personal"
        }
      });
      state.skills = normalizeSkillState(response?.payload);
      state.status = {
        ready: state.status.ready,
        message: state.skills.mode === "personal" ? "已切换到个人自定义技能" : "已切换到工作台投放技能"
      };
    } catch (error) {
      state.status = { ready: state.status.ready, message: error.message || "投放技能设置保存失败" };
    } finally {
      setBusy(false);
      render();
    }
  }

  async function savePersonalPreferences() {
    const draft = {
      dialogue_habit: root.querySelector("[data-preference='dialogue_habit']")?.value || "",
      operation_habit: root.querySelector("[data-preference='operation_habit']")?.value || ""
    };
    const validation = preferenceApi?.validatePreferences
      ? preferenceApi.validatePreferences(draft)
      : { ok: true, value: normalizePersonalPreferences(draft) };
    if (!validation.ok) {
      state.status = { ready: state.status.ready, message: validation.message || "个人习惯内容无效" };
      render();
      return;
    }
    setBusy(true);
    try {
      const response = await sendRuntime({
        type: "QIANCHUAN_AGENT_PREFERENCES",
        payload: validation.value
      });
      state.preferences = normalizePersonalPreferences(response?.payload);
      state.status = { ready: state.status.ready, message: "个人习惯已保存，将用于后续千川对话和执行回报" };
    } catch (error) {
      state.status = { ready: state.status.ready, message: error.message || "个人习惯保存失败" };
    } finally {
      setBusy(false);
      render();
    }
  }

  function focusMonitorRuleComposer() {
    if (!composer.value.trim()) composer.value = "如果综合营销ROI低于2，就发微信提醒我，30分钟内不要重复";
    persistComposerDraft();
    composer.focus();
  }

  async function saveMonitorRuleProposal(proposalId) {
    const proposal = state.proposals.find((item) => item?.id === proposalId && item.kind === "monitor_rule");
    const rule = monitorRuleApi?.normalizeRule?.(proposal?.payload);
    if (!proposal || !rule) return;
    setBusy(true);
    try {
      const response = await updateMonitorRule({ action: "save", ...rule });
      const saved = monitorRuleApi.normalizeRule(response?.payload);
      if (!saved) throw new Error("服务器返回的盯盘规则无效");
      replaceMonitorRule(saved);
      proposal.done = true;
      proposal.result = "规则已保存，将从下一次巡检开始生效。";
      await postConversationEvent(
        `【千川 Agent 盯盘规则已保存】\n${monitorRuleApi.describeRule(saved)}`,
        `monitor-saved-${saved.id}-${Date.now()}`
      );
    } catch (error) {
      proposal.error = error.message || "盯盘规则保存失败";
    } finally {
      setBusy(false);
      render();
    }
  }

  async function toggleMonitorRule(ruleId, enabled) {
    const current = state.monitorRules.find((item) => item.id === Number(ruleId));
    if (!current) return;
    setBusy(true);
    try {
      const response = await updateMonitorRule({ action: "toggle", id: current.id, enabled });
      const updated = monitorRuleApi.normalizeRule(response?.payload);
      if (updated) replaceMonitorRule(updated);
      state.status = { ...state.status, message: enabled ? "盯盘规则已启用" : "盯盘规则已暂停" };
    } catch (error) {
      state.status = { ...state.status, message: error.message || "盯盘规则更新失败" };
    } finally {
      setBusy(false);
      render();
    }
  }

  async function deleteMonitorRule(ruleId) {
    const current = state.monitorRules.find((item) => item.id === Number(ruleId));
    if (!current || !window.confirm(`删除盯盘规则“${current.name}”？`)) return;
    setBusy(true);
    try {
      await updateMonitorRule({ action: "delete", id: current.id });
      state.monitorRules = state.monitorRules.filter((item) => item.id !== current.id);
      state.status = { ...state.status, message: "盯盘规则已删除" };
    } catch (error) {
      state.status = { ...state.status, message: error.message || "盯盘规则删除失败" };
    } finally {
      setBusy(false);
      render();
    }
  }

  function updateMonitorRule(payload) {
    return sendRuntime({
      type: "QIANCHUAN_AGENT_MONITOR_RULE",
      accountKey: state.accountKey,
      scope: state.scope,
      payload: { account_key: state.accountKey, scope: state.scope, ...payload }
    });
  }

  function replaceMonitorRule(rule) {
    state.monitorRules = [rule, ...state.monitorRules.filter((item) => item.id !== rule.id)];
  }

  function settingNumber(name) {
    return Number(root.querySelector(`[data-setting='${name}']`)?.value || 0);
  }

  function normalizeProposal(raw) {
    if (!raw || typeof raw !== "object") return null;
    const kind = ["action", "memory", "weixin_message", "navigation", "monitor_rule"].includes(raw.kind) ? raw.kind : "action";
    const payload = raw.payload && typeof raw.payload === "object" ? raw.payload : {};
    if (kind === "action" && !ACTION_LABELS[payload.action]) return null;
    if (kind === "memory" && state.skills.mode !== "personal") return null;
    if (kind === "weixin_message" && !String(payload.message || "").trim()) return null;
    if (kind === "monitor_rule" && !monitorRuleApi?.normalizeRule?.(payload)) return null;
    return {
      id: String(raw.id || `proposal-${Date.now()}-${Math.random().toString(36).slice(2)}`),
      kind,
      payload,
      createdAt: Date.now(),
      remoteSourceChannel: externalChannelFromSource(raw.remoteSourceChannel)
    };
  }

  async function executeUtilityProposals(proposals, receipt = null) {
    const powerEpoch = state.agentPowerEpoch;
    if (!isAgentPowerOn(powerEpoch)) return [];
    const results = [];
    for (const proposal of proposals) {
      if (!isAgentPowerOn(powerEpoch)) break;
      if (proposal.kind === "weixin_message") {
        try {
          requireAgentPower(powerEpoch);
          if (!state.weixin.ready) throw new Error("客户端 Claw 尚未连接微信 Bot，无法发送消息。");
          await sendWeixinNotification(String(proposal.payload.message || "").slice(0, 3000));
          requireAgentPower(powerEpoch);
          proposal.done = true;
          proposal.result = `已发送到${state.weixin.targetLabel || "客户端微信 Bot"}。`;
          results.push({ kind: proposal.kind, ok: true, message: proposal.result });
        } catch (error) {
          proposal.error = error.message || "微信消息发送失败";
          results.push({ kind: proposal.kind, ok: false, message: proposal.error });
        }
      }
      if (proposal.kind === "navigation") {
        let navigationCancelled = false;
        setAgentPhase("executing", "正在切换千川页面");
        takeoverController?.activate?.({
          mode: state.settings.mode === "managed" ? "managed" : "confirm",
          label: "正在识别千川导航入口",
          stop: () => { navigationCancelled = true; }
        });
        try {
          if (!remoteControlApi?.navigateToScene) throw new Error("千川页面导航组件未加载，请重新加载插件。");
          proposal.result = await remoteControlApi.navigateToScene(
            proposal.payload, document, state.pageContext, sendRuntime,
            () => navigationCancelled || !isAgentPowerOn(powerEpoch)
          );
          requireAgentPower(powerEpoch);
          setAgentPhase("verifying", "正在确认页面切换结果");
          proposal.done = true;
          results.push({ kind: proposal.kind, ok: true, message: proposal.result || "页面已切换并重新识别。" });
        } catch (error) {
          proposal.error = error.message || "页面切换失败";
          results.push({ kind: proposal.kind, ok: false, message: proposal.error });
        } finally {
          takeoverController?.deactivate?.();
        }
      }
    }
    if (receipt?.externalId && results.length && isAgentPowerOn(powerEpoch)) {
      const lines = results.map((item) => {
        const label = item.kind === "weixin_message" ? "微信投递" : "页面切换";
        return `${label}：${item.ok ? "已完成" : "未完成"}；${item.message}`;
      });
      await postConversationEvent(
        `【千川 Agent 执行回执】\n${lines.join("\n")}`,
        `utility-${String(receipt.source || "remote").slice(0, 20)}-${String(receipt.externalId).slice(0, 96)}`
      ).catch(() => {});
    }
    if (isAgentPowerOn(powerEpoch)) {
      if (results.some((item) => !item.ok)) setAgentPhase("attention", "有远程任务未完成，请查看执行回执");
      else setAgentPhase("monitoring", monitoringPhaseDetail());
    }
    return results;
  }

  async function executeProposal(proposal, authority = "confirm") {
    const powerEpoch = state.agentPowerEpoch;
    if (!isAgentPowerOn(powerEpoch)) {
      proposal.error = "千川 Agent 总开关已关闭，本次未执行。";
      render();
      return;
    }
    if (Date.now() - proposal.createdAt > 5 * 60 * 1000) {
      proposal.error = "建议已过期，请让 Agent 基于最新页面重新分析。";
      render();
      return;
    }
    const restoreAgentPanels = collapseAgentPanelsForOperation();
    setBusy(true);
    proposal.executionAuthority = authority;
    let operationCancelled = false;
    setAgentPhase("observing", `正在识别“${ACTION_LABELS[proposal.payload.action] || "目标操作"}”的当前页面`);
    takeoverController?.activate?.({
      mode: authority === "managed" ? "managed" : "confirm",
      label: `正在识别“${ACTION_LABELS[proposal.payload.action] || "目标操作"}”的当前页面`,
      stop: (reason) => {
        operationCancelled = true;
        activeOperationMachine?.cancel(reason);
      }
    });
    try {
      requireAgentPower(powerEpoch);
      const before = await locateActionTarget(proposal.payload);
      requireAgentPower(powerEpoch);
      if (operationCancelled) throw new Error("用户已停止 AI 接管。");
      const cooldown = await inspectPlanControlCooldown(proposal.payload);
      if (cooldown?.allowed !== true) throw new Error(cooldown?.message || "每计划 1 小时调控限制校验失败，本次未执行。");
      proposal.controlCooldownException = cooldown?.exception === true;
      if (authority === "managed") validateManagedProposal(proposal, before.snapshot);
      if (new Set(["weixin_confirmed", "weixin_explicit"]).has(authority)) {
        validateWeixinConfirmedProposal(proposal, before.snapshot);
      }
      if (authority === "command_confirmed") validateCommandConfirmedProposal(proposal, before.snapshot, "口令确认");
      if (authority === "explicit_instruction") validateExplicitInstructionProposal(proposal, before.snapshot);
      const result = await executeWhitelistedActionWithTakeover(
        proposal.payload, before, authority,
        () => operationCancelled || !isAgentPowerOn(powerEpoch),
      );
      requireAgentPower(powerEpoch);
      setAgentPhase("verifying", "正在核验操作结果并保存记录");
      result.after.executionMode = authority;
      await auditAction(proposal, before.snapshot, result.after, result.status, result.error || "");
      if (result.status === "succeeded") {
        await planControlCooldown.recordSuccess(proposal.payload, result.status).catch((error) => {
          proposal.controlCooldownRecordError = String(error?.message || "调控计时保存失败").slice(0, 180);
        });
      }
      proposal.executionStatus = result.status;
      proposal.done = new Set(["succeeded", "confirmed"]).has(result.status);
      proposal.error = result.error || "";
      proposal.result = result.message;
      proposal.automatic = authority === "managed";
      proposal.remoteConfirmed = new Set(["weixin_confirmed", "weixin_explicit", "command_confirmed"]).has(authority);
      await notifyActionResult(proposal, before.snapshot, result.after, result.status, result.error || "");
    } catch (error) {
      proposal.executionStatus = "stale";
      proposal.error = error.message || "页面状态已变化，本次未执行。";
      if (isAgentPowerOn(powerEpoch)) {
        await auditAction(proposal, {}, {}, "stale", proposal.error).catch(() => {});
        await notifyActionResult(proposal, {}, {}, "stale", proposal.error).catch(() => {});
        setAgentPhase("attention", proposal.error);
      }
    } finally {
      activeOperationMachine = null;
      takeoverController?.deactivate?.();
      restoreAgentPanels();
      setBusy(false);
      if (isAgentPowerOn(powerEpoch) && proposal.executionStatus === "succeeded") {
        setAgentPhase("monitoring", monitoringPhaseDetail());
      }
      render();
    }
  }

  async function inspectPlanControlCooldown(payload, providedSnapshot) {
    if (!planControlCooldown?.inspect) {
      throw new Error("每计划 1 小时调控限制组件未加载，本次未执行。");
    }
    const targetId = String(payload?.target_id || payload?.targetId || "").trim();
    const snapshot = providedSnapshot && typeof providedSnapshot === "object"
      ? providedSnapshot
      : collectPageSnapshot(targetId);
    return planControlCooldown.inspect(payload, snapshot);
  }

  function validateExplicitInstructionProposal(proposal, before) {
    const payload = proposal.payload || {};
    if (!/^\d{10,24}$/.test(String(payload.target_id || ""))) {
      throw new Error("明确指令必须包含页面内唯一计划 ID，本次未执行。");
    }
    validateDailyActionLimit(new Set(["managed", "weixin_confirmed", "weixin_explicit", "explicit_instruction"]));
    if (payload.action === "set_roi") {
      validateRoiAdjustment(payload, before, "明确指令");
      return;
    }
    if (payload.action !== "set_budget") return;
    const current = Number(before.budget ?? payload.expected_current?.budget);
    const next = Number(payload.new_budget ?? payload.newBudget);
    if (!Number.isFinite(current) || current < 300) throw new Error("无法确认当前预算，明确指令未执行调整。");
    if (!Number.isFinite(next) || next < 300) throw new Error("新预算无效或低于 300 元，本次未执行。");
    if (state.settings.budget_cap > 0 && next > state.settings.budget_cap) {
      throw new Error(`新预算超过 ${state.settings.budget_cap} 元安全上限，本次未执行。`);
    }
    const changePercent = Math.abs(next - current) / current * 100;
    if (changePercent > state.settings.max_budget_change_percent + 0.001) {
      throw new Error(`本次预算变化 ${changePercent.toFixed(1)}%，超过单次 ${state.settings.max_budget_change_percent}% 上限。`);
    }
  }

  function validateWeixinConfirmedProposal(proposal, before) {
    if (!state.weixin.ready || !state.weixin.commandsReady) throw new Error("客户端微信指令通道已失效，本次未执行。");
    validateCommandConfirmedProposal(proposal, before, "微信确认");
  }

  function validateCommandConfirmedProposal(proposal, before, label) {
    if (!/^\d{10,24}$/.test(String(proposal.payload.target_id || ""))) {
      throw new Error(`${label}的计划操作必须包含页面内唯一计划 ID，本次未执行。`);
    }
    validateDailyActionLimit(new Set(["managed", "weixin_confirmed", "weixin_explicit", "explicit_instruction", "command_confirmed"]));
    if (proposal.payload.action === "set_roi") {
      if (!Number.isFinite(Number(proposal.payload.expected_current?.roi))) {
        throw new Error(`${label}的 ROI 调整必须包含当前值和新值，本次未执行。`);
      }
      validateRoiAdjustment(proposal.payload, before, label);
      return;
    }
    if (proposal.payload.action !== "set_budget") return;
    if (!Number.isFinite(Number(proposal.payload.expected_current?.budget))) {
      throw new Error(`${label}的预算调整必须包含当前值和新值，本次未执行。`);
    }
    const current = Number(before.budget ?? proposal.payload.expected_current?.budget);
    const next = Number(proposal.payload.new_budget ?? proposal.payload.newBudget);
    if (!Number.isFinite(current) || current < 300) throw new Error(`无法确认当前预算，${label}未执行调整。`);
    if (!Number.isFinite(next) || next < 300) throw new Error("建议预算无效或低于 300 元，本次未执行。");
    if (!(state.settings.budget_cap > 0)) throw new Error("请先在 Agent 面板设置预算上限，再确认调整预算。");
    if (next > state.settings.budget_cap) throw new Error(`建议预算超过 ${state.settings.budget_cap} 元上限，本次未执行。`);
    const changePercent = Math.abs(next - current) / current * 100;
    if (changePercent > state.settings.max_budget_change_percent + 0.001) {
      throw new Error(`本次预算变化 ${changePercent.toFixed(1)}%，超过单次 ${state.settings.max_budget_change_percent}% 上限。`);
    }
  }

  function validateDailyActionLimit(executionModes) {
    const today = new Date().toISOString().slice(0, 10);
    const completedToday = state.audits.filter((audit) =>
      String(audit.created_at || audit.createdAt || "").slice(0, 10) === today
      && audit.status === "succeeded"
      && executionModes.has(audit.after?.executionMode)
    ).length;
    if (completedToday >= state.settings.max_actions_per_day) {
      throw new Error(`今日受控操作已达到 ${state.settings.max_actions_per_day} 次上限。`);
    }
  }

  function validateManagedProposal(proposal, before) {
    if (state.settings.mode !== "managed") throw new Error("全托管已关闭，本次未执行。");
    if (!state.weixin.ready) throw new Error("客户端微信通知通道未连接或已失效，全托管已阻止操作。");
    validateDailyActionLimit(new Set(["managed"]));
    const payload = proposal.payload;
    const targetKey = String(payload.target_id || payload.target_name || "").trim();
    const duplicate = state.audits.find((audit) => {
      if (audit.status !== "succeeded" || audit.after?.executionMode !== "managed") return false;
      const sameTarget = targetKey && targetKey === String(audit.target_id || audit.target_name || "").trim();
      const sameAction = audit.action === payload.action;
      const createdAt = Date.parse(String(audit.created_at || audit.createdAt || "").replace(" ", "T"));
      return sameTarget && sameAction && Number.isFinite(createdAt) && Date.now() - createdAt < 10 * 60 * 1000;
    });
    if (duplicate) throw new Error("同一目标的相同操作在 10 分钟内已执行过，本次巡检跳过。");
    if (payload.action === "set_roi") {
      validateRoiAdjustment(payload, before, "全托管");
      return;
    }
    if (payload.action !== "set_budget") return;
    const current = Number(before.budget ?? payload.expected_current?.budget);
    const next = Number(payload.new_budget ?? payload.newBudget);
    if (!Number.isFinite(current) || current < 300) throw new Error("无法确认当前预算，全托管未执行调整。");
    if (!Number.isFinite(next) || next < 300 || next > state.settings.budget_cap) {
      throw new Error(`建议预算超出 300 至 ${state.settings.budget_cap} 元的自动执行范围。`);
    }
    const changePercent = Math.abs(next - current) / current * 100;
    if (changePercent > state.settings.max_budget_change_percent + 0.001) {
      throw new Error(`本次预算变化 ${changePercent.toFixed(1)}%，超过单次 ${state.settings.max_budget_change_percent}% 上限。`);
    }
  }

  function validateRoiAdjustment(payload, before, label) {
    const current = Number(before.roi ?? payload.expected_current?.roi);
    const next = Number(payload.new_roi ?? payload.newRoi);
    if (!Number.isFinite(current) || current <= 0) throw new Error(`无法确认当前 ROI，${label}未执行调整。`);
    if (!Number.isFinite(next) || next <= 0 || next > 100) throw new Error("建议 ROI 不在 0 到 100 的安全范围内，本次未执行。");
    const changePercent = Math.abs(next - current) / current * 100;
    if (changePercent > state.settings.max_budget_change_percent + 0.001) {
      throw new Error(`本次 ROI 变化 ${changePercent.toFixed(1)}%，超过单次 ${state.settings.max_budget_change_percent}% 上限。`);
    }
  }

  async function locateActionTarget(payload) {
    const targetId = String(payload.target_id || payload.targetId || "").trim();
    const targetName = String(payload.target_name || payload.targetName || "").trim();
    let matches = findActionTargetMatches(targetId, targetName);
    if (!matches.length && (targetId || targetName)) {
      await searchActionTarget(targetId || targetName);
      matches = findActionTargetMatches(targetId, targetName);
    }
    if (matches.length !== 1) {
      throw new Error(matches.length ? "页面上找到多个同名目标，请缩小筛选范围后重试。" : "当前页面没有找到该投放目标，本次未执行。请刷新后重新分析。");
    }
    const row = matches[0];
    const text = compactText(row.innerText);
    const expected = payload.expected_current && typeof payload.expected_current === "object" ? payload.expected_current : {};
    const expectedStatus = String(expected.status || "").trim();
    const actualStatus = actionExecutor?.normalizePlanStatus?.(text) || "";
    const normalizedExpectedStatus = actionExecutor?.normalizePlanStatus?.(expectedStatus) || "";
    const statusMatches = normalizedExpectedStatus
      ? actualStatus === normalizedExpectedStatus
      : !expectedStatus || text.includes(expectedStatus);
    if (!statusMatches) {
      throw new Error(`目标当前状态已不是“${expectedStatus}”，本次未执行。`);
    }
    const snapshot = { text: text.slice(0, 800), status: actualStatus || expectedStatus, budget: readBudget(text), roi: readRoi(text) };
    const valueChecks = payload.action === "set_budget"
      ? [["budget", "预算"]]
      : payload.action === "set_roi"
        ? [["roi", "ROI"]]
        : [];
    for (const [name, label] of valueChecks) {
      const expectedValue = Number(expected[name]);
      const currentValue = Number(snapshot[name]);
      if (Number.isFinite(expectedValue) && (!Number.isFinite(currentValue) || Math.abs(expectedValue - currentValue) > 0.01)) {
        throw new Error(`目标当前${label}已变化或无法验证，本次未执行。`);
      }
    }
    return { row, snapshot };
  }

  function findActionTargetMatches(targetId, targetName) {
    return visibleElements("tr,[role='row'],[data-row-key],[data-testid*='row']")
      .filter((row) => row !== root && !root.contains(row))
      .filter((row) => {
      const text = compactText(row.innerText);
      const dataId = row.dataset?.rowKey || row.dataset?.id || row.getAttribute("data-ad-id") || row.getAttribute("data-project-id") || "";
      return (targetId && (String(dataId) === targetId || text.includes(targetId))) || (targetName && text.includes(targetName));
    });
  }

  async function searchActionTarget(query) {
    const inputs = visibleElements("input")
      .filter((input) => !root.contains(input) && !input.disabled && !input.readOnly)
      .filter((input) => /计划.*(?:名称|ID)|(?:名称|ID).*计划|输入.*ID.*搜索/i.test(String(input.placeholder || input.getAttribute("aria-label") || "")));
    if (inputs.length !== 1) return false;
    if (!actionExecutor?.typeAndSubmit) throw new Error("千川真实键盘搜索组件未加载，请重新加载插件后再试。");
    await actionExecutor.typeAndSubmit({
      element: inputs[0],
      text: String(query).slice(0, 128),
      businessAction: "search_target",
      sendRuntime
    });
    await wait(1200);
    return true;
  }

  async function executeWhitelistedActionWithTakeover(payload, target, authority = "confirm", isCancelled = () => false) {
    if (isCancelled()) throw new Error("千川 Agent 总开关已关闭，本次未执行。");
    if (!OperationStateMachine || !actionExecutor?.observeOperation || !actionExecutor?.performRealStep || !agentPlannerApi?.createPlanner) {
      throw new Error("千川 AI 接管状态机未加载，请重新加载插件后再试。");
    }
    const action = String(payload.action || "");
    const targetId = String(payload.target_id || payload.targetId || "").trim();
    const targetName = String(payload.target_name || payload.targetName || "").trim();
    const desiredValue = action === "set_budget"
      ? Number(payload.new_budget ?? payload.newBudget)
      : action === "set_roi" ? Number(payload.new_roi ?? payload.newRoi) : null;
    if (action === "set_budget" && (!Number.isFinite(desiredValue) || desiredValue < 300)) {
      throw new Error("建议预算无效或低于页面允许的 300 元，本次未执行。");
    }
    if (action === "set_roi" && (!Number.isFinite(desiredValue) || desiredValue <= 0 || desiredValue > 100)) {
      throw new Error("建议 ROI 不在 0 到 100 的安全范围内，本次未执行。");
    }
    const task = { action, targetId, targetName, desiredValue, startedUrl: location.href, authority, scope: state.scope };
    const adaptivePlanner = agentPlannerApi.createPlanner({
      maxInferenceCalls: 2,
      allowVisual: true,
      requestInference: async ({ task: plannerTask, observation, allowedSteps, visualDataUrl }) => {
        if (isCancelled()) throw new Error("千川 Agent 总开关已关闭，本次未执行。");
        takeoverController?.update?.(visualDataUrl ? "正在结合目标区域画面规划下一步" : "正在根据页面候选规划下一步");
        const response = await sendRuntime({
          type: "QIANCHUAN_AGENT_PLAN_STEP",
          requestId: crypto.randomUUID(),
          accountKey: state.accountKey,
          scope: state.scope,
          modelId: state.modelId,
          task: plannerTask,
          observation,
          allowedSteps,
          visualDataUrl
        });
        if (isCancelled()) throw new Error("千川 Agent 总开关已关闭，本次未执行。");
        return response?.payload || {};
      },
      captureVisual: async ({ clip }) => {
        if (isCancelled()) throw new Error("千川 Agent 总开关已关闭，本次未执行。");
        if (!clip) return null;
        const response = await sendRuntime({
          type: "QIANCHUAN_AGENT_REAL_ACTION",
          business_action: action,
          action: "screenshot",
          payload: { clip }
        });
        if (isCancelled()) throw new Error("千川 Agent 总开关已关闭，本次未执行。");
        return response?.payload || null;
      }
    });
    const machine = new OperationStateMachine({
      maxSteps: 12,
      timeoutMs: 90000,
      stepTimeoutMs: 30000,
      wait,
      onStatus: (status) => {
        const phase = status.phase === "acting"
          ? "executing"
          : status.phase === "completed" || (status.phase === "observing" && status.step > 1)
            ? "verifying"
            : "observing";
        setAgentPhase(phase, status.message);
        takeoverController?.update?.(status.message);
      },
      observe: async (currentTask, runContext) => {
        if (isCancelled()) throw new Error("千川 Agent 总开关已关闭，本次未执行。");
        const dialogs = visibleElements("[role='dialog'],.ant-modal,.semi-modal,.ovui-dialog,.ovui-drawer").filter((node) => !root.contains(node));
        const controlClicked = runContext.audit.some((item) => item.action === "click_control");
        const mayBeRefreshingAfterControl = controlClicked && new Set(["open_target", "pause", "resume"]).has(currentTask.action);
        let row = null;
        const matches = findActionTargetMatches(currentTask.targetId, currentTask.targetName);
        if (matches.length === 1) row = matches[0];
        else if (!dialogs.length && !mayBeRefreshingAfterControl) {
          if (matches.length > 1) throw new Error("页面上找到多个同名目标，AI 接管已停止。");
          throw new Error("页面变化后无法唯一定位目标计划，AI 接管已停止。");
        }
        const observation = actionExecutor.observeOperation({
          row,
          action: currentTask.action,
          desiredValue: currentTask.desiredValue,
          targetId: currentTask.targetId,
          targetName: currentTask.targetName,
          scope: currentTask.scope
        });
        observation.row = row;
        observation.currentBudget = readBudget(observation.rowText);
        observation.currentRoi = readRoi(observation.rowText);
        if (observation.dialogCount > 1) observation.blocker = "页面出现多个弹窗，无法唯一识别，AI 接管已停止。";
        return observation;
      },
      plan: async (currentTask, observation, context) => adaptivePlanner.plan(
        currentTask,
        observation,
        context,
        planOperationStep
      ).then((decision) => {
        if (isCancelled()) throw new Error("千川 Agent 总开关已关闭，本次未执行。");
        return decision;
      }),
      execute: async (step, currentTask, observation) => {
        if (isCancelled()) throw new Error("千川 Agent 总开关已关闭，本次未执行。");
        if (step.type === "wait") return { waited: true };
        const result = await actionExecutor.performRealStep({
          step,
          observation,
          businessAction: currentTask.action,
          sendRuntime
        });
        if (isCancelled()) throw new Error("千川 Agent 总开关已关闭，本次未执行。");
        return result;
      }
    });
    activeOperationMachine = machine;
    if (isCancelled()) machine.cancel("用户已停止 AI 接管。");
    const outcome = await machine.run(task);
    if (isCancelled()) throw new Error("千川 Agent 总开关已关闭，本次未执行。");
    const final = outcome.observation || {};
    const modeLabel = authority === "managed"
      ? "全托管"
      : authority === "weixin_explicit"
        ? "微信明确指令"
        : authority === "weixin_confirmed"
          ? "微信确认"
          : authority === "explicit_instruction"
            ? "明确指令"
            : "人工确认";
    const after = {
      text: String(final.rowText || "").slice(0, 800),
      budget: Number.isFinite(final.currentBudget) ? final.currentBudget : undefined,
      roi: Number.isFinite(final.currentRoi) ? final.currentRoi : undefined,
      platformConfirmed: outcome.audit.some((item) => item.action === "confirm_platform"),
      takeoverSteps: outcome.steps,
      plannerFallbacks: outcome.audit.filter((item) => item.plannerSource === "model").length,
      visualObservations: outcome.audit.filter((item) => item.visualUsed === true).length,
      plannerInputTokens: outcome.audit.reduce((total, item) => total + Math.max(0, Number(item.plannerTokens) || 0), 0),
      pageFingerprint: String(final.pageFingerprint || "").slice(0, 64),
      verifiedUrl: String(final.url || location.href).slice(0, 1000)
    };
    return {
      status: "succeeded",
      message: `${modeLabel}已完成“${ACTION_LABELS[action] || action}”，并重新识别页面验证目标状态。`,
      after
    };
  }

  function planOperationStep(task, observation, context) {
    const actions = context.audit.map((item) => item.action);
    if (observation.securityText) return { done: false };
    if ((task.action === "set_budget" || task.action === "set_roi") && actions.includes("confirm_platform")) {
      const current = task.action === "set_budget" ? observation.currentBudget : observation.currentRoi;
      if (Number.isFinite(current) && Math.abs(current - task.desiredValue) <= 0.01) {
        return { done: true, message: `${task.action === "set_roi" ? "ROI" : "预算"}已验证更新` };
      }
    }
    if (observation.dialog) {
      if (observation.confirmButtonCount === 1) {
        if (task.action === "set_budget" || task.action === "set_roi") {
          if (!observation.input) throw new Error("调整窗口中没有唯一可验证的输入框，AI 接管已停止。");
          const current = Number(observation.currentValue);
          if (!Number.isFinite(current) || Math.abs(current - task.desiredValue) > 0.001) {
            return { action: { type: "type_value", value: task.desiredValue }, message: `正在真实输入${task.action === "set_roi" ? " ROI" : "预算"}`, waitMs: 450 };
          }
        }
        return { action: { type: "confirm_platform" }, message: "正在处理本次业务动作的千川二次确认", waitMs: 900 };
      }
      throw new Error("平台弹窗中没有唯一安全的确认按钮，AI 接管已停止。");
    }
    if (task.action === "open_target") {
      if (actions.includes("click_control")) {
        if (observation.url !== task.startedUrl || !observation.row) return { done: true, message: "计划已打开" };
        throw new Error("真实点击后页面未发生可验证变化，AI 接管已停止。");
      }
      if (!observation.control) throw new Error("未识别到唯一计划入口，AI 接管已停止。");
      return { action: { type: "click_control" }, message: "正在真实点击计划入口", waitMs: 800 };
    }
    if (task.action === "pause" || task.action === "resume") {
      const desiredChecked = task.action === "resume";
      if (observation.checked === desiredChecked || /已经处于暂停|当前仍在投放/.test(observation.controlError || "")) {
        return { done: true, message: "计划开关状态已验证" };
      }
      const confirmIndex = actions.lastIndexOf("confirm_platform");
      if (confirmIndex >= 0) {
        const verificationWaits = actions.slice(confirmIndex + 1).filter((item) => item === "wait").length;
        if (verificationWaits < 3) {
          return { action: { type: "wait" }, message: `平台已确认，正在等待计划${task.action === "resume" ? "开启" : "暂停"}状态刷新`, waitMs: 900 };
        }
        throw new Error(`平台确认后仍未验证计划${task.action === "resume" ? "开启" : "暂停"}状态，AI 接管已停止。`);
      }
      if (!observation.control) throw new Error(observation.controlError || "未识别到唯一计划开关，AI 接管已停止。");
      if (actions.filter((item) => item === "click_control").length >= 1) {
        throw new Error("计划开关点击后状态未变化，AI 接管已停止。");
      }
      return { action: { type: "click_control" }, message: `正在真实点击“${ACTION_LABELS[task.action]}”开关`, waitMs: 700 };
    }
    if (task.action === "set_budget" || task.action === "set_roi") {
      if (!actions.includes("click_trigger")) {
        if (observation.triggerCount === 1) {
          return { action: { type: "click_trigger" }, message: `正在打开${task.action === "set_roi" ? " ROI" : "预算"}调整窗口`, waitMs: 650 };
        }
        const hoverCount = actions.filter((item) => item === "hover_value").length;
        const waitCount = actions.filter((item) => item === "wait").length;
        if (hoverCount === 0) {
          if (observation.hoverTargetCount !== 1) throw new Error(`未找到唯一的${task.action === "set_roi" ? " ROI" : "预算"}数值区域，AI 接管已停止。`);
          return { action: { type: "hover_value" }, message: `正在真实悬停${task.action === "set_roi" ? " ROI" : "预算"}数值区域`, waitMs: 400 };
        }
        if (waitCount < hoverCount) {
          return { action: { type: "wait" }, message: "正在等待悬停编辑入口出现并重新观察页面", waitMs: 350 };
        }
        if (hoverCount < 2) {
          if (observation.hoverTargetCount !== 1) throw new Error(`重新观察后无法唯一定位${task.action === "set_roi" ? " ROI" : "预算"}数值区域，AI 接管已停止。`);
          return { action: { type: "hover_value" }, message: `编辑入口尚未出现，正在重新悬停${task.action === "set_roi" ? " ROI" : "预算"}数值区域`, waitMs: 450 };
        }
        throw new Error(`悬停后未出现唯一的${task.action === "set_roi" ? " ROI" : "预算"}调整入口，AI 接管已停止。`);
      }
      if (actions.includes("confirm_platform")) {
        if (context.step < 12) return { action: { type: "wait" }, message: "正在等待页面刷新并验证结果", waitMs: 800 };
      }
      throw new Error("调整窗口未按预期出现或结果未验证，AI 接管已停止。");
    }
    throw new Error("该动作不在千川 AI 接管白名单内。");
  }

  async function auditAction(proposal, before, after, status, error) {
    const payload = proposal.payload;
    const response = await sendRuntime({
      type: "QIANCHUAN_AGENT_AUDIT",
      accountKey: state.accountKey,
      scope: state.scope,
      payload: {
        request_id: proposal.id,
        account_key: state.accountKey,
        scope: state.scope,
        action: payload.action,
        target_id: payload.target_id || "",
        target_name: payload.target_name || "",
        before,
        after,
        status,
        error_message: error,
        confirmed_at: new Date().toISOString()
      }
    });
    if (response?.payload) state.audits.unshift(response.payload);
    return response;
  }

  async function notifyActionResult(proposal, before, after, status, error) {
    const payload = proposal.payload;
    const lines = [
      "【千川 Agent 操作通知】",
      `范围：${scopeLabel()}`,
      `模式：${proposal.remoteSourceChannel
        ? `${proposal.remoteSourceChannel === "feishu" ? "飞书" : "微信"}明确指令`
        : proposal.executionAuthority === "weixin_explicit"
          ? "微信明确指令"
        : proposal.executionAuthority === "explicit_instruction"
          ? "明确指令"
          : proposal.automatic
            ? "全托管"
            : proposal.remoteConfirmed
              ? "微信确认"
              : "人工确认"}`,
      `操作：${ACTION_LABELS[payload.action] || payload.action}`,
      `对象：${payload.target_name || payload.target_id || "当前目标"}`,
      `结果：${status === "succeeded" ? "已执行" : status === "confirmed" ? "待平台保存" : "未执行"}`
    ];
    const oldBudget = Number(before?.budget);
    const newBudget = Number(after?.budget ?? payload.new_budget ?? payload.newBudget);
    if (payload.action === "set_budget" && Number.isFinite(newBudget)) {
      lines.push(`预算：${Number.isFinite(oldBudget) ? `${oldBudget} → ` : ""}${newBudget} 元`);
    }
    const oldRoi = Number(before?.roi);
    const newRoi = Number(after?.roi ?? payload.new_roi ?? payload.newRoi);
    if (payload.action === "set_roi" && Number.isFinite(newRoi)) {
      lines.push(`ROI：${Number.isFinite(oldRoi) ? `${oldRoi} → ` : ""}${newRoi}`);
    }
    if (payload.reason) lines.push(`原因：${String(payload.reason).slice(0, 300)}`);
    if (error) lines.push(`说明：${String(error).slice(0, 300)}`);
    lines.push(`时间：${new Date().toLocaleString("zh-CN", { hour12: false })}`);
    const eventMessage = lines.join("\n");
    await workflowController?.addRecord(
      `${status === "succeeded" ? "执行成功" : status === "confirmed" ? "等待平台确认" : "未执行"} · ${ACTION_LABELS[payload.action] || payload.action} · 计划 ${payload.target_id || "未识别"}${payload.reason ? ` · ${String(payload.reason).slice(0, 160)}` : ""}`,
      status === "succeeded" ? "success" : status === "confirmed" ? "pending" : "error"
    ).catch(() => null);
    const externalId = `audit-${proposal.id}-${status}`;
    await sendRuntime({
      type: "QIANCHUAN_AGENT_CONVERSATION",
      action: "event",
      accountKey: state.accountKey,
      scope: state.scope,
      externalId,
      message: eventMessage
    }).catch(() => {});
    if (!state.settings.notifications_enabled) return;
    try {
      await submitTotalControllerNotification({
        eventId: externalId,
        message: eventMessage,
        targetChannel: proposal.remoteSourceChannel || ""
      });
    } catch (notificationError) {
      proposal.notificationError = notificationError.message || "总控通知发送失败";
    }
  }

  function confirmationApproval(pending, status = "pending", decision = "") {
    const proposal = pending?.proposal || {};
    const payload = proposal.payload && typeof proposal.payload === "object" ? proposal.payload : {};
    const action = ACTION_LABELS[payload.action]
      || (proposal.kind === "monitor_rule" ? "保存盯盘规则" : "执行千川任务");
    const target = String(
      payload.target_id || payload.targetId || payload.plan_id || payload.planId || "账户级任务"
    ).slice(0, 80);
    const createdAt = Number(pending?.createdAt || Date.now());
    return {
      approvalId: `qca-${String(proposal.id || "task").slice(0, 80)}-${String(pending?.code || "").slice(0, 12)}`,
      proposalId: String(proposal.id || "").slice(0, 160),
      code: String(pending?.code || "").slice(0, 12),
      status,
      decision: decision === "cancel" ? "cancel" : decision === "confirm" ? "confirm" : "",
      createdAt,
      expiresAt: createdAt + Number(confirmationApi?.TTL_MS || 5 * 60 * 1000),
      title: action,
      summary: `${action} · ${target}`
    };
  }

  function postConversationEvent(message, externalId, approval = null) {
    return sendRuntime({
      type: "QIANCHUAN_AGENT_CONVERSATION",
      action: "event",
      accountKey: state.accountKey,
      scope: state.scope,
      externalId,
      message: withAccountIdentity(message),
      approval
    });
  }

  function submitTotalControllerNotification(notification = {}) {
    return sendRuntime({
      type: "QIANCHUAN_AGENT_NOTIFICATION",
      notification: {
        ...notification,
        workerInstanceId: INSTANCE_ID,
        accountKey: state.accountKey,
        accountName: state.accountName,
        scope: state.scope,
        channels: { weixin: false, feishu: false }
      }
    }).then((response) => response?.payload || {});
  }

  function externalChannelFromSource(source) {
    return new Set(["weixin", "feishu"]).has(String(source || "")) ? String(source) : "";
  }

  function sendExternalChannelNotification(channel, message, eventId = "") {
    const targetChannel = externalChannelFromSource(channel);
    if (!targetChannel) return Promise.resolve(null);
    return submitTotalControllerNotification({
      eventId: eventId || `external-${targetChannel}-${Date.now()}-${Math.random().toString(36).slice(2)}`,
      message: String(message || "").slice(0, 600),
      targetChannel
    });
  }

  async function sendConfirmationNotification(source, message, eventId) {
    const targetChannel = externalChannelFromSource(source);
    if (!targetChannel && !state.settings.notifications_enabled) return null;
    try {
      return await submitTotalControllerNotification({
        eventId: String(eventId || `confirmation-${Date.now()}`).slice(0, 128),
        message: withAccountIdentity(message),
        targetChannel
      });
    } catch (error) {
      await workflowController?.addRecord(
        `审核通知等待重试 · ${String(error?.message || "当前通知通道不可用").slice(0, 180)}`,
        "warning"
      ).catch(() => null);
      return null;
    }
  }

  async function sendWeixinNotification(message) {
    return sendRuntime({
      type: "QIANCHUAN_AGENT_WEIXIN",
      action: "notify",
      accountKey: state.accountKey,
      scope: state.scope,
      message: withAccountIdentity(message)
    });
  }

  function withAccountIdentity(message) {
    const text = String(message || "").trim();
    const identity = state.accountName
      ? `千川账户：${state.accountName}${state.accountKey ? `（ID：${state.accountKey}）` : ""}`
      : `千川账户ID：${state.accountKey || "未识别"}`;
    return text.startsWith("千川账户：") || text.startsWith("千川账户ID：") ? text : `${identity}\n${text}`;
  }

  async function tryHandleReadonlyDataRequest(content, meta = {}) {
    if (!state.status.ready || !readonlyObserverApi?.observe) return false;
    const request = readonlyObserverApi.parseRequest?.(content);
    if (!request?.recognized || !request.directReply) return false;
    const { observation, visualError } = await resolveReadonlyDataObservation(content);
    let result = readonlyObserverApi.formatResult(observation, { sceneLabel: scopeLabel() });
    if (visualError && observation.missingMetricIds.length) result += `\n画面识别未完成：${visualError}`;
    const externalChannel = externalChannelFromSource(meta.source);
    const shouldNotifyWeixin = !externalChannel && observation.request.deliverToWeixin;
    let localResult = result;
    if (externalChannel) {
      await sendExternalChannelNotification(
        externalChannel,
        result,
        `readonly-${externalChannel}-${String(meta.externalId || Date.now()).slice(0, 96)}`
      );
    } else if (shouldNotifyWeixin) {
      if (!state.weixin.ready) {
        if (meta.source === "weixin") throw new Error("客户端微信 Bot 当前未连接，无法回传只读数据。");
        localResult += "\n微信未发送：请先在客户端 Claw 中连接微信 Bot。";
      } else {
        await sendWeixinNotification(result);
        if (meta.source !== "weixin") localResult += "\n已发送到当前微信 Bot。";
      }
    }
    state.messages.push({
      role: "assistant",
      content: localResult,
      remote: Boolean(externalChannel),
      client: meta.source === "client"
    });
    await postConversationEvent(
      localResult,
      `readonly-${String(meta.source || "plugin")}-${String(meta.externalId || Date.now()).slice(0, 128)}`
    ).catch(() => {});
    render();
    return true;
  }

  async function resolveReadonlyDataObservation(content) {
    const snapshot = collectPageSnapshot(content);
    let observation = readonlyObserverApi.observe(document, content, snapshot);
    let visualError = "";
    if (observation.missingMetricIds.length) {
      try {
        const visualFacts = await requestReadonlyVisualFacts(observation);
        const facts = readonlyObserverApi.mergeFacts(observation.facts, visualFacts);
        observation = {
          ...observation,
          facts,
          missingMetricIds: observation.request.metricIds.filter((id) => !facts.some((fact) => fact.id === id))
        };
      } catch (error) {
        visualError = String(error?.message || "画面识别暂时不可用").slice(0, 240);
      }
    }
    return { observation, visualError };
  }

  async function requestReadonlyVisualFacts(observation) {
    const width = Math.min(4096, Math.max(8, Number(document.documentElement?.clientWidth || window.innerWidth || 0)));
    const height = Math.min(4096, Math.max(8, Number(document.documentElement?.clientHeight || window.innerHeight || 0)));
    const previousVisibility = root.style.visibility;
    let visualDataUrl = "";
    try {
      root.style.visibility = "hidden";
      await wait(50);
      const screenshot = await sendRuntime({
        type: "QIANCHUAN_AGENT_REAL_ACTION",
        business_action: "readonly_observe",
        action: "screenshot",
        payload: { clip: { left: Math.max(0, window.scrollX), top: Math.max(0, window.scrollY), width, height } }
      });
      visualDataUrl = String(screenshot?.payload?.dataUrl || "");
    } finally {
      root.style.visibility = previousVisibility;
    }
    if (!visualDataUrl) throw new Error("当前千川画面截图为空");
    const response = await sendRuntime({
      type: "QIANCHUAN_AGENT_READONLY_OBSERVE",
      requestId: crypto.randomUUID(),
      accountKey: state.accountKey,
      scope: state.scope,
      metricIds: observation.missingMetricIds,
      domEvidence: observation.evidenceText,
      pageMeta: {
        title: document.title.slice(0, 200),
        url: `${location.origin}${location.pathname}`,
        sceneLabel: scopeLabel(),
        pageUpdatedText: observation.pageUpdate?.value || ""
      },
      visualDataUrl
    });
    return (Array.isArray(response?.payload?.facts) ? response.payload.facts : [])
      .filter((fact) => observation.missingMetricIds.includes(String(fact?.id || "")))
      .filter((fact) => String(fact?.value || "").trim() && String(fact?.evidence || "").trim() && Number(fact?.confidence || 0) >= 0.75)
      .map((fact) => ({
        id: String(fact.id),
        label: String(fact.label || fact.id).slice(0, 80),
        value: String(fact.value).slice(0, 80),
        unit: String(fact.unit || "").slice(0, 12),
        evidence: String(fact.evidence).slice(0, 160),
        confidence: Number(fact.confidence),
        source: "page_visual"
      }));
  }

  async function maybePollWeixinCommands() {
    const powerEpoch = state.agentPowerEpoch;
    if (!isAgentPowerOn(powerEpoch) || state.remotePolling || state.busy || !state.weixin.commandsReady) return;
    if (!state.accountKey || !state.scope || !acquireRemotePollLease()) return;
    state.remotePolling = true;
    let hasRemoteWork = false;
    try {
      const response = await sendRuntime({
        type: "QIANCHUAN_AGENT_WEIXIN",
        action: "poll",
        accountKey: state.accountKey,
        scope: state.scope
      });
      if (!isAgentPowerOn(powerEpoch)) return;
      const commands = (Array.isArray(response?.payload?.commands) ? response.payload.commands : [])
        .filter((command) => !command?.targetInstanceId || command.targetInstanceId === INSTANCE_ID)
        .slice(0, 4);
      if (commands.length) {
        hasRemoteWork = true;
        state.remoteCommandBusy = true;
        setAgentPhase("observing", "正在处理微信千川指令");
        render();
      }
      for (const command of commands) {
        if (!isAgentPowerOn(powerEpoch)) break;
        const commandId = String(command.id || "");
        if (Number(state.remoteDeferredCommands.get(commandId) || 0) > Date.now()) continue;
        try {
          const processed = await handleWeixinCommand(command);
          if (!isAgentPowerOn(powerEpoch)) break;
          if (!processed) {
            state.remoteDeferredCommands.set(commandId, Date.now() + 8000);
            continue;
          }
          state.remoteDeferredCommands.delete(commandId);
          await sendRuntime({
            type: "QIANCHUAN_AGENT_WEIXIN",
            action: "ack",
            accountKey: state.accountKey,
            scope: state.scope,
            commandIds: [commandId]
          });
        } catch (error) {
          if (!isAgentPowerOn(powerEpoch)) break;
          const failure = await reportWeixinCommandFailure(commandId, error);
          if (failure?.terminal) {
            await sendWeixinNotification(
              `【千川 Agent 未完成】\n指令：${String(command.text || command.kind || "微信指令").slice(0, 300)}\n原因：${String(error.message || error).slice(0, 500)}\n本次没有继续操作投放数据，请检查电脑端状态后重试。`
            ).catch(() => {});
          }
        }
      }
    } catch (error) {
      if (!/尚未绑定|重新点击|会话记录/.test(String(error.message || ""))) return;
      state.weixin.commandsReady = false;
      state.status = { ready: state.status.ready, message: error.message };
      render();
    } finally {
      state.remotePolling = false;
      if (hasRemoteWork) {
        state.remoteCommandBusy = false;
        if (isAgentPowerOn(powerEpoch) && state.agentPhase === "observing") {
          setAgentPhase("monitoring", monitoringPhaseDetail());
        }
        render();
      }
    }
  }

  async function maybePollConversationCommands() {
    const powerEpoch = state.agentPowerEpoch;
    if (!isAgentPowerOn(powerEpoch) || state.remotePolling || state.busy) return;
    if (!state.accountKey || !state.scope || !acquireRemotePollLease()) return;
    state.remotePolling = true;
    let hasRemoteWork = false;
    try {
      const response = await sendRuntime({
        type: "QIANCHUAN_AGENT_CONVERSATION",
        action: "poll",
        accountKey: state.accountKey,
        scope: state.scope
      });
      if (!isAgentPowerOn(powerEpoch)) return;
      const messages = Array.isArray(response?.payload?.messages) ? response.payload.messages.slice(0, 4) : [];
      if (messages.length) {
        hasRemoteWork = true;
        state.remoteCommandBusy = true;
        setAgentPhase("observing", "正在处理客户端千川指令");
        render();
      }
      for (const message of messages) {
        if (!isAgentPowerOn(powerEpoch)) break;
        const messageId = String(message?.id || "");
        try {
          await handleClientConversationMessage(message);
          if (!isAgentPowerOn(powerEpoch)) break;
          if (messageId) {
            await sendRuntime({
              type: "QIANCHUAN_AGENT_CONVERSATION",
              action: "ack",
              accountKey: state.accountKey,
              scope: state.scope,
              messageIds: [messageId]
            });
          }
        } catch (error) {
          if (!isAgentPowerOn(powerEpoch)) break;
          const failure = await reportConversationFailure(messageId, error);
          if (failure?.terminal) {
            state.messages.push({
              role: "assistant",
              content: `客户端指令未完成：${String(error.message || error).slice(0, 500)}`,
              client: true,
              failed: true
            });
          }
        }
      }
    } catch (error) {
      state.status = { ready: state.status.ready, message: error.message || "客户端千川会话同步失败" };
    } finally {
      state.remotePolling = false;
      if (hasRemoteWork) {
        state.remoteCommandBusy = false;
        if (isAgentPowerOn(powerEpoch) && state.agentPhase === "observing") {
          setAgentPhase("monitoring", monitoringPhaseDetail());
        }
        render();
      }
    }
  }

  async function handleClientConversationMessage(message) {
    const powerEpoch = state.agentPowerEpoch;
    requireAgentPower(powerEpoch);
    const content = String(message?.content || "").trim();
    if (!content) return;
    const externalId = String(message.externalId || message.id || "");
    const source = externalChannelFromSource(message?.source) || "client";
    if (!state.messages.some((item) => item.id === message.id)) {
      const channelLabel = source === "weixin" ? "微信指令" : source === "feishu" ? "飞书指令" : "";
      state.messages.push({
        id: String(message.id || ""),
        role: "user",
        content: channelLabel ? `${channelLabel}：${content}` : content,
        remote: Boolean(externalChannelFromSource(source)),
        client: source === "client"
      });
    }
    const decision = confirmationApi?.parseDecision?.(content);
    if (decision) {
      await handleCommandDecision(decision.kind, decision.code, { source, sourceId: externalId });
      return;
    }
    const monitorDraft = monitorRuleApi?.parseInstruction?.(content);
    if (monitorDraft) {
      const proposal = normalizeProposal({ kind: "monitor_rule", payload: monitorDraft });
      if (proposal) {
        state.proposals.push(proposal);
        await queueCommandConfirmation(proposal, { source, sourceId: externalId });
      }
      return;
    }
    if (await tryHandleReadonlyDataRequest(content, { source, externalId })) return;
    const payload = await requestRemoteAgentWithFallback(
      [{ role: "user", content }],
      { clientConversation: true },
      { source, externalMessageId: externalId, modelId: message.modelId || state.modelId }
    );
    requireAgentPower(powerEpoch);
    const assistantText = String(payload.content || "").trim();
    if (assistantText) state.messages.push({
      role: "assistant",
      content: assistantText,
      remote: Boolean(externalChannelFromSource(source)),
      client: source === "client"
    });
    const proposals = (Array.isArray(payload.proposals) ? payload.proposals : []).map(normalizeProposal).filter(Boolean);
    state.proposals.push(...proposals);
    await executeUtilityProposals(proposals, { source, externalId });
    const action = proposals.find((item) => item.kind === "action");
    if (action) action.remoteSourceChannel = externalChannelFromSource(source);
    if (action && state.settings.mode === "managed") await executeProposal(action, "managed");
    else if (action && isDeterministicIntentPayload(payload)) await executeProposal(action, "explicit_instruction");
    else if (action) await queueCommandConfirmation(action, { source, sourceId: externalId });
    else if (externalChannelFromSource(source) && !proposals.some((item) => item.kind === "weixin_message")) {
      await sendExternalChannelNotification(
        source,
        `【千川 Agent 回复】\n${(assistantText || "我没有从当前页面生成可执行结果，请补充计划 ID、操作目标或分析要求。").slice(0, 520)}`,
        `reply-${source}-${externalId.slice(0, 96)}`
      );
    }
  }

  async function handleWeixinCommand(command) {
    const powerEpoch = state.agentPowerEpoch;
    requireAgentPower(powerEpoch);
    const kind = String(command?.kind || "");
    const code = String(command?.code || "").toUpperCase();
    if (kind === "confirm" || kind === "cancel") {
      return handleCommandDecision(kind, code, { source: "weixin", sourceId: String(command?.id || "") });
    }
    const content = String(command?.text || "").trim();
    if (!content) return true;
    state.messages.push({ role: "user", content: `微信指令：${content}`, remote: true });
    render();
    if (!Number(command.deliveryAttempts || 0)) {
      void sendWeixinNotification(`【千川 Agent 已收到】\n${content.slice(0, 500)}\n正在读取当前电脑上的千川页面并处理。`).catch(() => {});
    }
    const monitorDraft = monitorRuleApi?.parseInstruction?.(content);
    if (monitorDraft) {
      const proposal = normalizeProposal({ kind: "monitor_rule", payload: monitorDraft });
      if (!proposal) return true;
      state.proposals.push(proposal);
      await queueCommandConfirmation(proposal, { source: "weixin", sourceId: String(command.id || "") });
      render();
      return true;
    }
    if (await tryHandleReadonlyDataRequest(content, { source: "weixin", externalId: String(command.id || "") })) return true;
    const payload = await requestRemoteAgentWithFallback(
      [{ role: "user", content }],
      { remoteCommand: true },
      { source: "weixin", externalMessageId: String(command.id || ""), modelId: state.modelId }
    );
    requireAgentPower(powerEpoch);
    const assistantText = String(payload.content || "").trim();
    if (assistantText) state.messages.push({ role: "assistant", content: assistantText, remote: true });
    const proposals = (Array.isArray(payload.proposals) ? payload.proposals : []).map(normalizeProposal).filter(Boolean);
    state.proposals.push(...proposals);
    const navigation = proposals.find((item) => item.kind === "navigation");
    await executeUtilityProposals(proposals, { source: "weixin", externalId: String(command.id || "") });
    if (navigation) {
      const result = navigation.error
        ? `未完成：${navigation.error}`
        : `已完成：${navigation.result || "页面已切换并重新识别"}`;
      await sendWeixinNotification(`【千川 Agent 页面切换结果】\n${result.slice(0, 1200)}`);
    }

    const action = proposals.find((item) => item.kind === "action");
    if (action) {
      if (state.settings.mode === "managed") {
        await executeProposal(action, "managed");
      } else if (isDeterministicIntentPayload(payload)) {
        await executeProposal(action, "weixin_explicit");
      } else {
        await queueCommandConfirmation(action, { source: "weixin", sourceId: String(command.id || "") });
      }
    } else if (!proposals.some((item) => item.kind === "weixin_message" || item.kind === "navigation")) {
      const reply = assistantText || (proposals.some((item) => item.kind === "memory")
        ? "已生成训练记忆建议，请在当前电脑的千川 Agent 面板中确认保存。"
        : "我没有从当前页面生成可执行结果，请补充计划名称、操作目标或分析要求。"
      );
      await sendWeixinNotification(`【千川 Agent 回复】\n${reply.slice(0, 2600)}`);
    }
    render();
    return true;
  }

  async function runRemotePollCycle() {
    if (extensionContextInvalidated) return;
    try {
      await registerWorkerHeartbeat();
      if (!isAgentPowerOn()) return;
      await maybeRefreshWeixinCommandStatus();
      if (!isAgentPowerOn()) return;
      await maybePollWeixinCommands();
      if (!isAgentPowerOn()) return;
      await maybePollConversationCommands();
    } catch (error) {
      if (!invalidateExtensionContext(error)) throw error;
    }
  }

  async function runBackgroundAgentPulse() {
    await runRemotePollCycle();
    await workflowController?.run();
    await workflowController?.runDataReport();
  }

  async function maybeRefreshWeixinCommandStatus() {
    if (!isAgentPowerOn()) return;
    const now = Date.now();
    if (state.weixin.commandsReady || now - state.lastWeixinCommandStatusAt < 30000) return;
    state.lastWeixinCommandStatusAt = now;
    try {
      const response = await sendRuntime({
        type: "QIANCHUAN_AGENT_WEIXIN",
        action: "status",
        accountKey: state.accountKey,
        scope: state.scope
      });
      state.weixin = response?.payload || state.weixin;
    } catch {}
  }

  async function registerWorkerHeartbeat(force = false) {
    if (!state.accountKey || !state.scope || !state.pageContext.supported) return;
    const now = Date.now();
    if (!force && now - state.lastWorkerHeartbeatAt < 15000) return;
    state.lastWorkerHeartbeatAt = now;
    void reportDispatchObservation(true).catch(() => null);
    try {
      await sendRuntime({
        type: "QIANCHUAN_AGENT_WORKER",
        action: "register",
        accountKey: state.accountKey,
        accountName: state.accountName,
        scope: state.scope,
        instanceId: INSTANCE_ID,
        pageVisibility: document.visibilityState || "visible",
        pluginVersion: chrome.runtime.getManifest().version
      });
    } catch {
      state.lastWorkerHeartbeatAt = 0;
    }
  }

  function reportDispatchObservation(pageSupported) {
    return sendRuntime({
      type: "QIANCHUAN_DISPATCH_OBSERVE",
      accountKey: state.accountKey,
      accountName: state.accountName,
      scope: state.scope,
      pageSupported: pageSupported === true
    });
  }

  function remoteFailureIsRetryable(error) {
    return !/会员|登录|验证码|风控|安全校验|账号失效|会话已过期|不支持|禁止|高风险|用户已停止/i
      .test(String(error?.message || error || ""));
  }

  function reportConversationFailure(messageId, error) {
    return sendRuntime({
      type: "QIANCHUAN_AGENT_CONVERSATION",
      action: "fail",
      accountKey: state.accountKey,
      scope: state.scope,
      messageId,
      error: String(error?.message || error || "客户端千川指令处理失败").slice(0, 600),
      retryable: remoteFailureIsRetryable(error)
    }).then((response) => response?.payload || {});
  }

  function reportWeixinCommandFailure(commandId, error) {
    return sendRuntime({
      type: "QIANCHUAN_AGENT_WEIXIN",
      action: "fail",
      accountKey: state.accountKey,
      scope: state.scope,
      commandId,
      error: String(error?.message || error || "微信千川指令处理失败").slice(0, 600),
      retryable: remoteFailureIsRetryable(error)
    }).then((response) => response?.payload || {});
  }

  async function queueCommandConfirmation(proposal, { source = "plugin", sourceId = "" } = {}) {
    requireAgentPower();
    if (!proposal || !confirmationApi?.save) throw new Error("口令确认组件未加载，请重新加载插件。");
    const externalChannel = externalChannelFromSource(source);
    proposal.remoteSourceChannel = externalChannel || proposal.remoteSourceChannel || "";
    const pending = confirmationApi.save({
      proposal,
      sourceId,
      accountKey: state.accountKey,
      scope: state.scope,
      scopeLabel: scopeLabel()
    });
    proposal.remotePendingCode = pending.code;
    const message = proposal.kind === "monitor_rule"
      ? `【千川 Agent 盯盘规则待确认】\n${monitorRuleApi.describeRule(proposal.payload)}\n${confirmationApi.commandHint(pending.code)}`
      : remoteControlApi.formatConfirmationMessage(proposal, pending.code, scopeLabel());
    const confirmationEventId = `confirmation-${proposal.id}-${pending.code}`.slice(0, 128);
    state.messages.push({ role: "assistant", content: message, remote: Boolean(externalChannel), client: source === "client" });
    await postConversationEvent(
      message,
      confirmationEventId,
      confirmationApproval(pending, "pending")
    ).catch(() => {});
    await sendConfirmationNotification(source, message, confirmationEventId);
    setAgentPhase("attention", proposal.kind === "monitor_rule" ? "有盯盘规则等待确认" : "有调控建议等待确认");
    render();
    return pending;
  }

  async function handleCommandDecision(kind, code, { source = "plugin", sourceId = "" } = {}) {
    requireAgentPower();
    const found = confirmationApi?.claimDecision?.(
      code,
      { accountKey: state.accountKey, scope: state.scope },
      kind,
      sourceId
    )
      || { status: "missing", pending: null };
    if (found.status === "missing") {
      await deliverConfirmationReply(source, `【千川 Agent】确认码 ${code || "无效"} 不存在或已过期，请重新发送原指令。`, sourceId);
      return true;
    }
    const pending = found.pending;
    if (found.status === "wrong_scope") {
      await deliverConfirmationReply(
        source,
        `【千川 Agent】确认码 ${code} 属于“${pending.scopeLabel || "其他账号或场景"}”，当前页面未执行，也未消费该确认码。`,
        sourceId,
        confirmationApproval(pending, "pending")
      );
      return true;
    }
    if (found.status === "duplicate") {
      const status = pending.decisionStatus === "processing"
        ? "已收到，正在处理，请勿重复发送"
        : pending.decisionStatus === "failed"
          ? "上次处理未完成，请重新发送原指令获取新确认码"
          : "已处理，不会重复执行，请查看上一条结果";
      const approvalStatus = pending.decisionStatus === "processing"
        ? "processing"
        : pending.decisionStatus === "failed"
          ? "failed"
          : pending.decisionKind === "cancel" ? "cancelled" : "completed";
      await deliverConfirmationReply(
        source,
        `【千川 Agent】确认码 ${code} ${status}。`,
        sourceId,
        confirmationApproval(pending, approvalStatus, pending.decisionKind)
      );
      return true;
    }
    const visible = state.proposals.find((item) => item.id === pending.proposal.id);
    if (kind === "cancel") {
      if (visible) {
        visible.done = true;
        visible.result = "已通过口令取消。";
      }
      confirmationApi.finishDecision(code, "completed");
      await deliverConfirmationReply(
        source,
        `【千川 Agent】已取消确认码 ${code} 对应的任务。`,
        sourceId,
        confirmationApproval(pending, "cancelled", "cancel")
      );
      setAgentPhase("monitoring", monitoringPhaseDetail());
      render();
      return true;
    }
    const proposal = normalizeProposal(pending.proposal);
    if (!proposal) {
      confirmationApi.finishDecision(code, "failed");
      await deliverConfirmationReply(
        source,
        `【千川 Agent】确认码 ${code} 对应的任务内容已失效，请重新发送原指令。`,
        sourceId,
        confirmationApproval(pending, "failed", "confirm")
      ).catch(() => {});
      throw new Error("待确认任务内容已失效，请重新发送原指令。");
    }
    await deliverConfirmationReply(
      source,
      `【千川 Agent】确认码 ${code} 已收到，正在按原审核任务处理。`,
      sourceId,
      confirmationApproval(pending, "processing", "confirm")
    ).catch(() => {});
    proposal.remotePendingCode = code;
    proposal.remoteConfirmed = true;
    if (!state.proposals.some((item) => item.id === proposal.id)) state.proposals.push(proposal);
    if (proposal.kind === "monitor_rule") {
      try {
        await saveMonitorRuleProposal(proposal.id);
        confirmationApi.finishDecision(code, "completed");
        if (proposal.done) {
          await deliverConfirmationReply(
            source,
            `【千川 Agent】盯盘规则已保存。\n${monitorRuleApi.describeRule(proposal.payload)}`,
            sourceId,
            confirmationApproval(pending, "completed", "confirm")
          );
        }
      } catch (error) {
        confirmationApi.finishDecision(code, "failed");
        await deliverConfirmationReply(
          source,
          `【千川 Agent】确认码 ${code} 处理失败：${String(error?.message || error || "未知错误").slice(0, 300)}`,
          sourceId,
          confirmationApproval(pending, "failed", "confirm")
        ).catch(() => {});
        throw error;
      }
      return true;
    }
    try {
      proposal.remoteSourceChannel = externalChannelFromSource(source) || proposal.remoteSourceChannel || "";
      await executeProposal(proposal, proposal.remoteSourceChannel ? "weixin_confirmed" : "command_confirmed");
      confirmationApi.finishDecision(code, "completed");
      await deliverConfirmationReply(
        source,
        `【千川 Agent】确认码 ${code} 已处理，实际结果以执行与验证记录为准。`,
        sourceId,
        confirmationApproval(pending, "completed", "confirm")
      ).catch(() => {});
    } catch (error) {
      confirmationApi.finishDecision(code, "failed");
      await deliverConfirmationReply(
        source,
        `【千川 Agent】确认码 ${code} 处理失败：${String(error?.message || error || "未知错误").slice(0, 300)}`,
        sourceId,
        confirmationApproval(pending, "failed", "confirm")
      ).catch(() => {});
      throw error;
    }
    return true;
  }

  async function deliverConfirmationReply(source, message, sourceId, approval = null) {
    const externalChannel = externalChannelFromSource(source);
    const resultEventId = `confirmation-result-${String(sourceId || Date.now()).slice(0, 64)}-${String(approval?.status || "reply").slice(0, 16)}`.slice(0, 128);
    state.messages.push({ role: "assistant", content: message, remote: Boolean(externalChannel), client: source === "client" });
    await postConversationEvent(
      message,
      resultEventId,
      approval
    ).catch(() => {});
    await sendConfirmationNotification(source, message, resultEventId);
  }

  function acquireRemotePollLease() {
    const key = `mmw.qianchuanAgent.remotePollLease:${state.accountKey}:${state.scope}`;
    const now = Date.now();
    try {
      const current = JSON.parse(localStorage.getItem(key) || "{}");
      if (Number(current.expiresAt) > now && current.owner !== INSTANCE_ID) return false;
    } catch {}
    localStorage.setItem(key, JSON.stringify({ owner: INSTANCE_ID, expiresAt: now + 7000 }));
    try {
      return JSON.parse(localStorage.getItem(key) || "{}").owner === INSTANCE_ID;
    } catch {
      return false;
    }
  }

  async function maybeRunMonitorRules() {
    const powerEpoch = state.agentPowerEpoch;
    if (!isAgentPowerOn(powerEpoch) || state.busy || state.remoteCommandBusy || !state.status.ready) return;
    const enabledRules = state.monitorRules.filter((rule) => rule.enabled);
    if (!enabledRules.length || !monitorRuleApi?.evaluateRule || !acquireMonitorRuleLease()) return;
    const intervalMs = taskPatrolApi?.intervalMilliseconds?.(state.settings.patrol_interval_minutes)
      || Math.max(1, state.settings.patrol_interval_minutes) * 60 * 1000;
    const now = Date.now();
    state.lastMonitorPatrolAt = Math.max(state.lastMonitorPatrolAt, readLastMonitorPatrolAt());
    if (now - state.lastMonitorPatrolAt < intervalMs) return;
    const dueRules = enabledRules.filter((rule) => {
      const evaluatedAt = Date.parse(String(rule.last_evaluated_at || "").replace(" ", "T"));
      return !Number.isFinite(evaluatedAt) || now - evaluatedAt >= intervalMs;
    });
    if (!dueRules.length) return;
    state.lastMonitorPatrolAt = now;
    writeLastMonitorPatrolAt(now);
    setBusy(true);
    setAgentPhase("observing", "正在检查已启用的盯盘规则");
    try {
      const snapshot = collectPageSnapshot();
      requireAgentPower(powerEpoch);
      for (const rule of dueRules) {
        requireAgentPower(powerEpoch);
        const evaluation = monitorRuleApi.evaluateRule(rule, snapshot, now);
        if (!evaluation.evaluable) continue;
        let delivered = false;
        if (evaluation.matched) delivered = await handleMonitorRuleTrigger(rule, evaluation, snapshot);
        const response = await updateMonitorRule({
          action: "evaluate",
          id: rule.id,
          current_value: evaluation.matched && !delivered && Number.isFinite(rule.last_value)
            ? rule.last_value
            : evaluation.currentValue,
          triggered: delivered
        });
        requireAgentPower(powerEpoch);
        const updated = monitorRuleApi.normalizeRule(response?.payload);
        if (updated) replaceMonitorRule(updated);
      }
    } catch (error) {
      if (isAgentPowerOn(powerEpoch)) {
        state.status = { ...state.status, message: error.message || "盯盘规则巡检失败" };
        setAgentPhase("attention", error.message || "盯盘规则需要处理");
      }
    } finally {
      setBusy(false);
      if (isAgentPowerOn(powerEpoch) && state.agentPhase !== "attention") {
        setAgentPhase("monitoring", monitoringPhaseDetail());
      }
      render();
    }
  }

  async function handleMonitorRuleTrigger(rule, evaluation, snapshot) {
    const powerEpoch = state.agentPowerEpoch;
    requireAgentPower(powerEpoch);
    const triggerText = monitorRuleApi.formatTrigger(rule, evaluation);
    let analysis = "";
    let action = null;
    if (rule.delivery !== "notify") {
      try {
        const response = await sendRuntime({
          type: "QIANCHUAN_AGENT_CHAT",
          accountKey: state.accountKey,
          scope: state.scope,
          sessionKey: `${state.accountKey}:${state.scope}:monitor-rule:${rule.id}`,
          messages: [{
            role: "user",
            content: `盯盘规则刚刚触发：${monitorRuleApi.describeRule(rule)}。请只依据当前快照分析原因并给出简短建议；如确有必要，最多提出一个暂停、恢复或预算调整操作。`
          }],
          context: { ...snapshot, monitorRule: rule, monitorEvaluation: evaluation, managedSettings: state.settings },
          source: "system",
          persistConversation: false
        });
        requireAgentPower(powerEpoch);
        const payload = response?.payload || {};
        analysis = String(payload.content || "").trim().slice(0, 1800);
        const proposals = (Array.isArray(payload.proposals) ? payload.proposals : [])
          .map(normalizeProposal)
          .filter(Boolean);
        action = proposals.find((item) => item.kind === "action") || null;
        if (action) {
          state.proposals.push(action);
          if (rule.delivery === "managed" && state.settings.mode === "managed") {
            action.automatic = true;
          }
        }
      } catch (error) {
        analysis = `Claw 分析暂时不可用：${error.message || "请稍后重试"}`;
      }
    }

    const modeNote = rule.delivery === "managed" && state.settings.mode !== "managed"
      ? "规则要求全托管调整，但总开关当前为人工确认；本次只生成建议，不会自动操作。"
      : "";
    const message = ["【千川 Agent 盯盘提醒】", `范围：${scopeLabel()}`, triggerText, analysis && `Claw 建议：${analysis}`, modeNote]
      .filter(Boolean)
      .join("\n");
    requireAgentPower(powerEpoch);
    await postConversationEvent(message, `monitor-trigger-${rule.id}-${Date.now()}`).catch(() => {});
    requireAgentPower(powerEpoch);
    if (!state.weixin.ready) {
      state.status = { ...state.status, message: `规则“${rule.name}”已触发，但客户端微信 Bot 未连接` };
      return false;
    }
    try {
      await sendWeixinNotification(message);
      requireAgentPower(powerEpoch);
    } catch (error) {
      state.status = { ...state.status, message: `规则已触发，但微信发送失败：${error.message || "请检查连接"}` };
      return false;
    }
    if (action?.automatic) {
      setBusy(false);
      requireAgentPower(powerEpoch);
      await executeProposal(action, "managed");
      setBusy(true);
    } else if (action) {
      setAgentPhase("attention", "盯盘规则已生成调控建议，等待人工确认");
    }
    return true;
  }

  function acquireMonitorRuleLease() {
    const key = `mmw.qianchuanAgent.monitorLease:${state.accountKey}:${state.scope}`;
    const now = Date.now();
    try {
      const current = JSON.parse(localStorage.getItem(key) || "{}");
      if (Number(current.expiresAt) > now && current.owner !== INSTANCE_ID) return false;
    } catch {}
    localStorage.setItem(key, JSON.stringify({ owner: INSTANCE_ID, expiresAt: now + 55 * 1000 }));
    try {
      return JSON.parse(localStorage.getItem(key) || "{}").owner === INSTANCE_ID;
    } catch {
      return false;
    }
  }

  async function maybeRunManagedPatrol() {
    const powerEpoch = state.agentPowerEpoch;
    if (!isAgentPowerOn(powerEpoch) || state.settings.mode !== "managed" || state.busy || !state.status.ready) return;
    state.lastPatrolAt = Math.max(state.lastPatrolAt, readLastPatrolAt());
    const due = taskPatrolApi?.isDue?.(state.lastPatrolAt, state.settings.patrol_interval_minutes)
      ?? Date.now() - state.lastPatrolAt >= Math.max(1, state.settings.patrol_interval_minutes) * 60 * 1000;
    if (!due || !acquirePatrolLease()) return;
    state.lastPatrolAt = Date.now();
    writeLastPatrolAt(state.lastPatrolAt);
    setBusy(true);
    setAgentPhase("observing", "正在执行全托管盯盘检查");
    try {
      const response = await sendRuntime({
        type: "QIANCHUAN_AGENT_CHAT",
        accountKey: state.accountKey,
        scope: state.scope,
        sessionKey: `${state.accountKey}:${state.scope}:managed`,
        messages: [{
          role: "user",
          content: "执行一次全托管巡检。只依据当前页面快照和训练记忆判断；没有充分依据时不要提出操作。最多提出一个暂停、恢复或预算调整建议。"
        }],
        context: { ...collectPageSnapshot(), managedSettings: state.settings },
        source: "system",
        persistConversation: false
      });
      requireAgentPower(powerEpoch);
      const payload = response?.payload || {};
      const proposal = (Array.isArray(payload.proposals) ? payload.proposals : [])
        .map(normalizeProposal)
        .find((item) => item?.kind === "action");
      if (proposal) {
        proposal.automatic = true;
        state.proposals.push(proposal);
        setBusy(false);
        requireAgentPower(powerEpoch);
        await executeProposal(proposal, "managed");
      }
    } catch (error) {
      if (isAgentPowerOn(powerEpoch)) {
        state.status = { ready: state.status.ready, message: error.message || "全托管巡检失败" };
        setAgentPhase("attention", error.message || "全托管巡检需要处理");
      }
    } finally {
      setBusy(false);
      if (isAgentPowerOn(powerEpoch) && state.agentPhase !== "attention") {
        setAgentPhase("monitoring", monitoringPhaseDetail());
      }
      render();
    }
  }

  function patrolStorageKey(suffix) {
    return `mmw.qianchuanAgent.${suffix}.${state.accountKey}.${state.scope}`;
  }

  function readLastPatrolAt() {
    return Number(localStorage.getItem(patrolStorageKey("lastPatrolAt")) || 0);
  }

  function writeLastPatrolAt(value) {
    localStorage.setItem(patrolStorageKey("lastPatrolAt"), String(value));
  }

  function readLastMonitorPatrolAt() {
    return Number(localStorage.getItem(patrolStorageKey("lastMonitorPatrolAt")) || 0);
  }

  function writeLastMonitorPatrolAt(value) {
    localStorage.setItem(patrolStorageKey("lastMonitorPatrolAt"), String(value));
  }

  function acquirePatrolLease() {
    const key = patrolStorageKey("lease");
    const now = Date.now();
    try {
      const current = JSON.parse(localStorage.getItem(key) || "{}");
      if (Number(current.expiresAt) > now && current.owner !== INSTANCE_ID) return false;
    } catch {}
    const lease = { owner: INSTANCE_ID, expiresAt: now + 55 * 1000 };
    localStorage.setItem(key, JSON.stringify(lease));
    try {
      return JSON.parse(localStorage.getItem(key) || "{}").owner === INSTANCE_ID;
    } catch {
      return false;
    }
  }

  function scopeLabel() {
    return state.pageContext?.label || "场景未识别";
  }

  async function saveManualMemory() {
    if (state.skills.mode !== "personal") return;
    const textarea = root.querySelector(".mmw-qca-memory-add textarea");
    const content = textarea.value.trim();
    if (!content) return;
    setBusy(true);
    try {
      await saveMemory({ title: "用户投放经验", content, category: "strategy" });
      textarea.value = "";
      await refreshState();
    } catch (error) {
      state.status = { ready: state.status.ready, message: error.message || "训练记忆保存失败" };
    } finally {
      setBusy(false);
      render();
    }
  }

  async function saveProposalMemory(proposalId) {
    if (state.skills.mode !== "personal") return;
    const proposal = state.proposals.find((item) => item.id === proposalId && item.kind === "memory");
    if (!proposal) return;
    setBusy(true);
    try {
      await saveMemory(proposal.payload);
      proposal.done = true;
      await refreshState();
    } catch (error) {
      proposal.error = error.message || "训练记忆保存失败";
    } finally {
      setBusy(false);
      render();
    }
  }

  function saveMemory(payload) {
    return sendRuntime({
      type: "QIANCHUAN_AGENT_MEMORY",
      accountKey: state.accountKey,
      scope: state.scope,
      payload: { action: "save", account_key: state.accountKey, scope: state.scope, ...payload }
    });
  }

  async function deleteMemory(memoryId) {
    setBusy(true);
    try {
      await sendRuntime({
        type: "QIANCHUAN_AGENT_MEMORY",
        accountKey: state.accountKey,
        scope: state.scope,
        payload: { action: "delete", id: Number(memoryId), account_key: state.accountKey, scope: state.scope }
      });
      await refreshState();
    } catch (error) {
      state.status = { ready: state.status.ready, message: error.message || "训练记忆删除失败" };
    } finally {
      setBusy(false);
      render();
    }
  }

  function dismissProposal(proposalId) {
    state.proposals = state.proposals.filter((item) => item.id !== proposalId);
    render();
  }

  function render() {
    const scope = root.querySelector(".mmw-qca-scope");
    scope.textContent = scopeLabel();
    scope.title = state.pageContext?.message || scopeLabel();
    const connection = root.querySelector(".mmw-qca-connection");
    const connectionReady = state.status.ready === true && !extensionContextInvalidated;
    connection.classList.toggle("is-ready", connectionReady);
    connection.classList.toggle("is-context-invalidated", extensionContextInvalidated);
    connection.innerHTML = "";
    const dot = document.createElement("span");
    const text = document.createElement("span");
    text.textContent = extensionContextInvalidated
      ? "插件已更新，请刷新当前千川页面"
      : state.status.message;
    connection.append(dot, text);
    if (!connectionReady) {
      const actions = document.createElement("span");
      actions.className = "mmw-qca-connection-actions";
      const retry = document.createElement("button");
      retry.type = "button";
      retry.dataset.action = extensionContextInvalidated
        ? "reload-page"
        : state.modelRecovery ? "retry-model" : "refresh";
      retry.textContent = extensionContextInvalidated
        ? "刷新页面"
        : state.modelRecovery ? `重试 ${state.modelRecovery.modelId}` : "重试";
      actions.appendChild(retry);
      if (state.modelRecovery && !extensionContextInvalidated) {
        const fallback = document.createElement("button");
        fallback.type = "button";
        fallback.dataset.action = "fallback-model";
        fallback.textContent = "用 GPT 5.4 完成本次";
        actions.appendChild(fallback);
      }
      connection.appendChild(actions);
    }
    renderMessages();
    renderProposals();
    renderSettings();
    renderAgentPowerState();
    syncToolsPanelToggle();
    if (state.open) applyPanelPosition(readLauncherPosition());
    const sceneUnavailable = !state.scope || !state.accountKey;
    root.querySelectorAll(".mmw-qca-panel button,.mmw-qca-panel textarea,.mmw-qca-panel input,.mmw-qca-tools-panel button,.mmw-qca-tools-panel textarea,.mmw-qca-tools-panel input").forEach((node) => {
      const action = node.dataset?.action;
      if (extensionContextInvalidated) {
        node.disabled = !["close", "reload-page"].includes(action);
        return;
      }
      const alwaysAvailable = ["close", "toggle-tools", "close-tools", "emergency-stop"].includes(action);
      const canUseWithoutScene = ["refresh", "retry-model", "fallback-model"].includes(action);
      if (action === "toggle-agent-power") {
        node.disabled = !state.agentPowerLoaded || !hasAgentPowerContext();
        return;
      }
      if (node.matches("[data-always-disabled]")) {
        node.disabled = true;
        return;
      }
      if (alwaysAvailable || node.matches("[data-usage-notice-open]")) {
        node.disabled = false;
        return;
      }
      node.disabled = state.busy || state.remoteCommandBusy || (sceneUnavailable && !canUseWithoutScene);
    });
  }

  function renderAgentPowerState() {
    const powered = isAgentPowerOn();
    const phaseLabels = {
      monitoring: "盯盘中",
      observing: "观察中",
      executing: "执行中",
      verifying: "验证中",
      attention: "需处理"
    };
    const button = root.querySelector(".mmw-qca-agent-power");
    if (button) {
      button.classList.toggle("is-on", powered);
      button.dataset.phase = powered ? state.agentPhase : "off";
      button.setAttribute("aria-checked", String(powered));
      button.setAttribute("aria-label", `千川 Agent 总开关，当前${powered ? "已开启" : "已关闭"}`);
      button.title = !hasAgentPowerContext()
        ? "等待识别当前千川账号与投放场景"
        : powered ? "关闭后立即停止自动任务、远程指令和调控" : "开启当前账户与场景的千川 Agent";
    }
    const runtime = root.querySelector(".mmw-qca-runtime-summary");
    if (!runtime) return;
    const phase = powered && phaseLabels[state.agentPhase] ? state.agentPhase : "off";
    runtime.hidden = !powered;
    runtime.dataset.phase = phase;
    runtime.classList.toggle("is-active", powered);
    runtime.classList.toggle("is-managed", powered && state.persistedMode === "managed");
    runtime.classList.toggle("is-attention", phase === "attention");
    root.querySelector(".mmw-qca-runtime-title").textContent = powered ? phaseLabels[phase] : "Agent 已关闭";
    root.querySelector(".mmw-qca-runtime-detail").textContent = powered
      ? state.agentPhaseDetail || monitoringPhaseDetail()
      : state.agentPhaseDetail || "自动任务与远程指令已停止";
    const caption = root.querySelector("[data-agent-power-caption]");
    if (caption) caption.textContent = powered ? `已开启 · ${phaseLabels[phase]}` : "已关闭";
    takeoverController?.setMonitoring?.(
      powered,
      powered ? state.agentPhaseDetail || monitoringPhaseDetail() : "",
      phase
    );
  }

  function composerDraftKey() {
    if (!state.accountKey || !state.scope) return "";
    return `mmw:qianchuan-agent:draft:${encodeURIComponent(state.accountKey)}:${encodeURIComponent(state.scope)}`;
  }

  function persistComposerDraft() {
    const key = composerDraftKey();
    if (!key) return;
    try {
      if (composer.value) sessionStorage.setItem(key, composer.value);
      else sessionStorage.removeItem(key);
    } catch (_error) {
      // Browsing modes that deny session storage can still use the live editor.
    }
  }

  function restoreComposerDraft() {
    const key = composerDraftKey();
    if (!key || composer.value || document.activeElement === composer) return;
    try {
      composer.value = sessionStorage.getItem(key) || "";
    } catch (_error) {
      // Keep the editor usable when storage is unavailable.
    }
  }

  function formatWorkflowRuleNumber(value) {
    if (String(value ?? "").trim() === "") return "—";
    const number = Number(value);
    if (!Number.isFinite(number)) return "—";
    return number.toLocaleString("zh-CN", { maximumFractionDigits: 2 });
  }

  function renderWorkflowRuleSummaries() {
    const numberValue = (name) => formatWorkflowRuleNumber(workflowField(name)?.value);
    const targetMode = root.querySelector("input[name='mmw-qca-target-mode']:checked")?.value;
    const interval = numberValue("intervalMinutes");
    const basicsSummary = root.querySelector(".mmw-qca-workflow-basics-summary");
    if (basicsSummary) basicsSummary.textContent = `${targetMode === "selected" ? "指定计划" : "全部计划"} · 每 ${interval} 分钟`;

    const setSummary = (name, status, preview, tone) => {
      const stateNode = root.querySelector(`[data-rule-state='${name}']`);
      const previewNode = root.querySelector(`[data-rule-preview='${name}']`);
      if (stateNode) {
        stateNode.textContent = status;
        stateNode.className = `mmw-qca-rule-state ${tone}`.trim();
      }
      if (previewNode) previewNode.textContent = preview;
    };

    const coldStartEnabled = Boolean(workflowField("coldStartEnabled")?.checked);
    root.querySelector(".mmw-qca-cold-start-rule")?.classList.toggle("is-enabled", coldStartEnabled);
    setSummary(
      "coldStart",
      coldStartEnabled ? "已启用" : "未启用",
      coldStartEnabled
        ? `低于 ¥${numberValue("coldStartHourlySpendBelow")}/小时 · 每次 -${numberValue("coldStartRoiDecrease")} · 最多 -${numberValue("coldStartMaxDecrease")}`
        : "低消耗时逐步降低目标 ROI",
      coldStartEnabled ? "is-on" : "is-off"
    );

    const hourlySpendTarget = Number(workflowField("hourlySpendTarget")?.value) || 0;
    const spendPacingEnabled = hourlySpendTarget > 0;
    root.querySelector(".mmw-qca-spend-pacing-rule")?.classList.toggle("is-enabled", spendPacingEnabled);
    setSummary(
      "spendPacing",
      spendPacingEnabled ? "已配置" : "未启用",
      spendPacingEnabled
        ? `¥${formatWorkflowRuleNumber(hourlySpendTarget)}/小时 · 超出 ${numberValue("spendOverPercent")}% · 每次 +${numberValue("roiIncrease")}`
        : "目标为 0，暂不执行上涨",
      spendPacingEnabled ? "is-on" : "is-off"
    );

    setSummary(
      "pause",
      "安全规则",
      `净 ROI＜${numberValue("pauseBelowNetRoi")} · 消耗≥¥${numberValue("minimumSpend")} · 连续 ${numberValue("lowRoiCycles")} 轮`,
      "is-guard"
    );
  }

  function renderSettings() {
    const config = workflowApi?.normalizeConfig?.(state.workflowConfig) || state.workflowConfig;
    const managed = config.executionMode === "managed";
    const persistedManaged = state.persistedMode === "managed";
    root.querySelector(".mmw-qca-mode-label").textContent = managed ? "全托管" : "人工确认";
    root.querySelectorAll("input[name='mmw-qca-mode']").forEach((input) => {
      input.checked = input.value === config.executionMode;
    });
    root.querySelectorAll("input[name='mmw-qca-target-mode']").forEach((input) => {
      input.checked = input.value === config.targetMode;
    });
    const targetPlan = root.querySelector(".mmw-qca-target-plan");
    targetPlan.hidden = config.targetMode !== "selected";
    if (!targetPlan.contains(document.activeElement)) renderTargetPlanFields(config.planIds);
    for (const name of ["budget_cap", "max_budget_change_percent", "max_actions_per_day"]) {
      const input = root.querySelector(`[data-setting='${name}']`);
      if (input && document.activeElement !== input) input.value = String(state.settings[name] || "");
    }
    const workflowValues = {
      intervalMinutes: config.intervalMinutes,
      hourlySpendTarget: config.hourlySpendTarget,
      spendOverPercent: config.spendOverPercent,
      roiIncrease: config.roiIncrease,
      coldStartMaxDecrease: config.coldStartMaxDecrease,
      coldStartHourlySpendBelow: config.coldStartHourlySpendBelow,
      coldStartRoiDecrease: config.coldStartRoiDecrease,
      pauseBelowNetRoi: config.pauseBelowNetRoi,
      lowRoiCycles: config.lowRoiCycles,
      minimumSpend: config.minimumSpend,
      balanceBelow: config.notifications.balanceBelow,
      revenueRisePercent: config.notifications.revenueRisePercent,
      netRoiBelow: config.notifications.netRoiBelow,
      dataReportIntervalMinutes: config.dataReport.intervalMinutes
    };
    Object.entries(workflowValues).forEach(([name, value]) => {
      const input = workflowField(name);
      if (input && document.activeElement !== input) input.value = String(value ?? "");
    });
    workflowField("enabled").checked = config.enabled;
    workflowField("coldStartEnabled").checked = config.coldStartEnabled;
    const coldStartRule = root.querySelector(".mmw-qca-cold-start-rule");
    coldStartRule?.classList.toggle("is-enabled", config.coldStartEnabled);
    coldStartRule?.querySelectorAll(".mmw-qca-cold-start-rule-fields input").forEach((input) => {
      input.disabled = !config.coldStartEnabled;
    });
    renderWorkflowRuleSummaries();
    workflowField("balanceEnabled").checked = config.notifications.balanceEnabled;
    workflowField("revenueRiseEnabled").checked = config.notifications.revenueRiseEnabled;
    workflowField("netRoiEnabled").checked = config.notifications.netRoiEnabled;
    workflowField("dataReportEnabled").checked = config.dataReport.enabled;
    workflowField("dataReportDashboard").checked = config.dataReport.includeDashboard;
    workflowField("dataReportPlans").checked = config.dataReport.includePlans;
    workflowField("deliveryModePerAccount").checked = config.dataReport.deliveryMode === "per_account";
    root.querySelector(".mmw-qca-report-delivery-label").textContent = config.dataReport.deliveryMode === "per_account"
      ? "分账户发送"
      : "默认合并";
    const settings = root.querySelector(".mmw-qca-managed-settings");
    settings.classList.toggle("is-managed", managed);
    root.querySelector("[data-action='emergency-stop']").hidden = !persistedManaged;
    const toolsToggle = root.querySelector("[data-action='toggle-tools']");
    toolsToggle?.querySelector(".mmw-qca-tools-indicator")?.classList.toggle("is-managed", isAgentPowerOn() && persistedManaged);
    if (toolsToggle) {
      toolsToggle.title = `${isAgentPowerOn() ? "Agent 已开启" : "Agent 已关闭"} · ${persistedManaged ? "全托管" : "人工确认"} · ${config.enabled ? "自动化任务已启用" : "自动化任务未启用"}`;
      toolsToggle.dataset.summary = toolsToggle.title;
    }
    root.querySelector(".mmw-qca-tools-summary").textContent = `${persistedManaged ? "全托管" : "人工确认"} · ${config.enabled ? "任务已启用" : "任务未启用"}`;
    const routes = [
      state.miniapp.connected && "小程序",
      state.weixin.ready && "微信",
      state.feishu.notificationsReady && "飞书"
    ].filter(Boolean);
    root.querySelector(".mmw-qca-routing-detail").textContent = routes.length
      ? `可用：${routes.join("、")}`
      : "暂无外部通道，数据仍保留在客户端";
    const routeStatus = root.querySelector(".mmw-qca-routing-status");
    routeStatus.textContent = routes.length ? `${routes.length} 个通道可用` : "仅客户端";
    routeStatus.classList.toggle("is-ready", routes.length > 0);
    root.querySelector(".mmw-qca-workflow-enabled-label").textContent = config.enabled ? `每 ${config.intervalMinutes} 分钟` : "未启用";
    root.querySelector(".mmw-qca-notification-label").textContent = config.dataReport.enabled
      ? `每 ${config.dataReport.intervalMinutes} 分钟 · ${config.dataReport.deliveryMode === "aggregate" ? "汇总" : "分账户"}`
      : routes.length ? `总控分发 · ${routes.length} 个通道` : "总控记录";
    renderAgentPowerState();
  }

  function renderTargetPlanFields(planIds = []) {
    const list = root.querySelector("[data-workflow-plan-list]");
    if (!list) return;
    const values = Array.isArray(planIds) && planIds.length ? planIds.slice(0, 20) : [""];
    list.replaceChildren(...values.map((value) => createTargetPlanField(value)));
    updateTargetPlanFieldControls();
  }

  function createTargetPlanField(value = "") {
    const row = document.createElement("div");
    row.className = "mmw-qca-target-plan-row";
    const input = document.createElement("input");
    input.type = "text";
    input.inputMode = "numeric";
    input.maxLength = 24;
    input.dataset.workflowPlanId = "";
    input.placeholder = "例如 1872411763668106";
    input.value = String(value || "");
    const remove = document.createElement("button");
    remove.type = "button";
    remove.dataset.action = "remove-target-plan";
    remove.textContent = "移除";
    row.append(input, remove);
    return row;
  }

  function addTargetPlanField() {
    const list = root.querySelector("[data-workflow-plan-list]");
    if (!list || list.children.length >= 20) return;
    const row = createTargetPlanField();
    list.appendChild(row);
    updateTargetPlanFieldControls();
    row.querySelector("input")?.focus();
  }

  function removeTargetPlanField(button) {
    const list = root.querySelector("[data-workflow-plan-list]");
    const row = button.closest(".mmw-qca-target-plan-row");
    if (!list || !row) return;
    if (list.children.length === 1) row.querySelector("input").value = "";
    else row.remove();
    updateTargetPlanFieldControls();
  }

  function updateTargetPlanFieldControls() {
    const rows = [...root.querySelectorAll(".mmw-qca-target-plan-row")];
    rows.forEach((row, index) => {
      const input = row.querySelector("input");
      const remove = row.querySelector("[data-action='remove-target-plan']");
      if (input) input.setAttribute("aria-label", `指定计划 ID ${index + 1}`);
      if (remove) remove.hidden = rows.length === 1;
    });
    const add = root.querySelector("[data-action='add-target-plan']");
    if (add) add.disabled = rows.length >= 20;
  }

  function renderTaskPatrol() {
    const minutes = taskPatrolApi?.normalizeIntervalMinutes?.(state.settings.patrol_interval_minutes) || 5;
    root.querySelector(".mmw-qca-task-patrol-label").textContent = `每 ${minutes} 分钟`;
    const input = root.querySelector("[data-patrol-interval]");
    if (input && document.activeElement !== input) input.value = String(minutes);
  }

  function renderSkillSettings() {
    const personal = state.skills.mode === "personal";
    root.querySelector(".mmw-qca-skill-label").textContent = personal ? "个人自定义技能" : "工作台投放技能";
    root.querySelectorAll("input[name='mmw-qca-skill']").forEach((input) => {
      input.checked = input.value === state.skills.mode;
    });
    const memory = root.querySelector(".mmw-qca-memory");
    memory.hidden = !personal;
    if (!personal) memory.open = false;
  }

  function renderPersonalPreferences() {
    const count = Number(state.preferences.configured_count || 0);
    root.querySelector(".mmw-qca-preference-label").textContent = count ? `${count} 类已设置` : "未设置";
    for (const name of ["dialogue_habit", "operation_habit"]) {
      const input = root.querySelector(`[data-preference='${name}']`);
      if (input && document.activeElement !== input) input.value = state.preferences[name] || "";
    }
  }

  function renderMonitorRules() {
    const active = state.monitorRules.filter((rule) => rule.enabled).length;
    root.querySelector(".mmw-qca-monitor-count").textContent = String(active);
    root.querySelector(".mmw-qca-tools-summary").textContent = `${state.persistedMode === "managed" ? "全托管" : "人工确认"} · ${active} 条盯盘`;
    const list = root.querySelector(".mmw-qca-monitor-list");
    list.innerHTML = "";
    if (!state.monitorRules.length) {
      const empty = document.createElement("p");
      empty.className = "mmw-qca-monitor-empty";
      empty.textContent = "还没有规则。用一句话告诉 Agent 指标、条件和触发后的处理方式。";
      list.appendChild(empty);
      return;
    }
    state.monitorRules.forEach((rule) => {
      const row = document.createElement("div");
      row.className = `mmw-qca-monitor-row${rule.enabled ? "" : " is-disabled"}`;
      const copy = document.createElement("div");
      const name = document.createElement("strong");
      name.textContent = rule.name;
      const detail = document.createElement("span");
      detail.textContent = monitorRuleApi.describeRule(rule);
      copy.append(name, detail);
      const actions = document.createElement("div");
      const toggle = document.createElement("button");
      toggle.type = "button";
      toggle.dataset.action = "toggle-monitor-rule";
      toggle.dataset.ruleId = String(rule.id);
      toggle.dataset.enabled = String(rule.enabled);
      toggle.textContent = rule.enabled ? "暂停" : "启用";
      const remove = document.createElement("button");
      remove.type = "button";
      remove.dataset.action = "delete-monitor-rule";
      remove.dataset.ruleId = String(rule.id);
      remove.textContent = "删除";
      actions.append(toggle, remove);
      row.append(copy, actions);
      list.appendChild(row);
    });
  }

  function renderMessages() {
    const container = root.querySelector(".mmw-qca-messages");
    container.innerHTML = "";
    if (!state.activityRecords.length) {
      const empty = document.createElement("div");
      empty.className = "mmw-qca-empty";
      empty.textContent = "暂无任务反馈。启用规则后，这里只显示每轮数据、触发原因和执行结果。";
      container.appendChild(empty);
      return;
    }
    state.activityRecords.slice(-30).forEach((record) => {
      const item = document.createElement("article");
      item.className = `mmw-qca-activity-item is-${record.level || "info"}`;
      const time = document.createElement("time");
      time.dateTime = new Date(record.createdAt || Date.now()).toISOString();
      time.textContent = new Date(record.createdAt || Date.now()).toLocaleTimeString("zh-CN", { hour: "2-digit", minute: "2-digit", hour12: false });
      const text = document.createElement("p");
      text.textContent = record.text;
      item.append(time, text);
      container.appendChild(item);
    });
    container.scrollTop = container.scrollHeight;
  }

  function renderProposals() {
    const container = root.querySelector(".mmw-qca-proposals");
    container.innerHTML = "";
    state.proposals.filter((proposal) => proposal && (proposal.kind !== "memory" || state.skills.mode === "personal")).slice(-8).forEach((proposal) => {
      const card = document.createElement("article");
      card.className = `mmw-qca-proposal is-${proposal.kind}${proposal.done ? " is-done" : ""}`;
      const payload = proposal.payload;
      const title = document.createElement("strong");
      title.textContent = proposal.kind === "memory"
        ? "保存为训练记忆"
        : proposal.kind === "monitor_rule"
          ? "确认盯盘规则"
        : proposal.kind === "weixin_message"
          ? "发送微信消息"
          : proposal.kind === "navigation"
            ? "切换千川页面"
            : proposal.executionAuthority === "weixin_explicit"
              ? `微信明确指令${proposal.done ? "已执行" : "执行结果"}：${ACTION_LABELS[payload.action]}`
              : proposal.executionAuthority === "explicit_instruction"
                ? `明确指令${proposal.done ? "已执行" : "执行结果"}：${ACTION_LABELS[payload.action]}`
                : proposal.automatic
              ? `${proposal.done ? "全托管已执行" : "全托管巡检"}：${ACTION_LABELS[payload.action]}`
              : proposal.remoteConfirmed
                ? `口令已确认：${ACTION_LABELS[payload.action]}`
                : `待口令确认：${ACTION_LABELS[payload.action]}`;
      const detail = document.createElement("p");
      detail.textContent = proposal.kind === "memory"
        ? `${payload.title || "投放经验"}：${payload.content || ""}`
        : proposal.kind === "monitor_rule"
          ? monitorRuleApi.describeRule(payload)
        : proposal.kind === "weixin_message"
          ? String(payload.message || "")
          : proposal.kind === "navigation"
            ? `产品线：${payload.delivery_mode || "current"}；推广对象：${payload.promotion_target || "current"}`
            : `${payload.target_name || payload.target_id || "当前目标"}${payload.action === "set_budget" ? ` → ${payload.new_budget} 元` : payload.action === "set_roi" ? ` → ROI ${payload.new_roi ?? payload.newRoi}` : ""}\n${payload.reason || ""}${proposal.remotePendingCode ? `\n确认口令：确认 ${proposal.remotePendingCode}（5 分钟内有效）` : ""}`;
      card.append(title, detail);
      if (proposal.result) {
        const result = document.createElement("p");
        result.className = "mmw-qca-result";
        result.textContent = proposal.result;
        card.appendChild(result);
      }
      if (proposal.error) {
        const error = document.createElement("p");
        error.className = "mmw-qca-error";
        error.textContent = proposal.error;
        card.appendChild(error);
      }
      if (proposal.notificationError) {
        const notice = document.createElement("p");
        notice.className = "mmw-qca-error";
        notice.textContent = `操作记录已保存，但${proposal.notificationError}`;
        card.appendChild(notice);
      }
      if (!proposal.done && proposal.workflowAction && state.workflowConfig.executionMode === "confirm") {
        const actions = document.createElement("div");
        actions.className = "mmw-qca-proposal-actions";
        actions.append(
          actionButton("确认执行", "confirm-workflow-action", proposal.id, true),
          actionButton("本次跳过", "dismiss-workflow-action", proposal.id, false)
        );
        card.appendChild(actions);
      }
      if (!proposal.done && proposal.kind === "memory") {
        const actions = document.createElement("div");
        actions.className = "mmw-qca-proposal-actions";
        actions.append(
          actionButton(
            "保存",
            "save-proposal-memory",
            proposal.id,
            true
          ),
          actionButton("取消", "dismiss", proposal.id, false)
        );
        card.appendChild(actions);
      }
      container.appendChild(card);
    });
  }

  function renderMemories() {
    root.querySelector(".mmw-qca-memory-count").textContent = String(state.memories.length);
    const list = root.querySelector(".mmw-qca-memory-list");
    list.innerHTML = "";
    state.memories.forEach((memory) => {
      const row = document.createElement("div");
      const text = document.createElement("span");
      text.textContent = memory.title ? `${memory.title}：${memory.content}` : memory.content;
      const remove = document.createElement("button");
      remove.type = "button";
      remove.dataset.action = "delete-memory";
      remove.dataset.memoryId = String(memory.id);
      remove.textContent = "删除";
      row.append(text, remove);
      list.appendChild(row);
    });
  }

  function actionButton(label, action, proposalId, primary) {
    const button = document.createElement("button");
    button.type = "button";
    button.dataset.action = action;
    button.dataset.proposalId = proposalId;
    button.className = primary ? "mmw-qca-primary" : "mmw-qca-secondary";
    button.textContent = label;
    return button;
  }

  function collectPageSnapshot(query = "") {
    const pageData = pageContextApi?.detectPageData?.(document, location) || {
      summaryMetrics: [], planTotals: [], dataRange: "", planTab: "", planCount: null, emptyReason: "", pageUpdatedText: ""
    };
    const structuredRows = pageContextApi?.extractPlanRows?.(document) || [];
    const fallbackRows = visibleElements("tr,[role='row'],[data-row-key],[data-testid*='row']")
      .filter((row) => !root.contains(row))
      .slice(0, 40)
      .map((row) => {
        const text = compactText(row.innerText).slice(0, 700);
        const labelledPlanId = text.match(/(?:计划)?ID\s*[：:]\s*(\d{10,24})/i)?.[1] || "";
        return {
          id: String(row.dataset?.rowKey || row.dataset?.id || row.getAttribute("data-ad-id") || row.getAttribute("data-project-id") || labelledPlanId).slice(0, 128),
          text,
          budget: readBudget(text),
          roi: readRoi(text),
          status: /(?:已暂停|暂停中|已关闭)/.test(text) ? "paused" : /(?:投放中|生效中|已开启)/.test(text) ? "active" : ""
        };
      })
      .filter((row) => row.text);
    const rowCandidates = structuredRows.length ? structuredRows : fallbackRows;
    const likelyPlanRows = rowCandidates.filter((row) => row.id || /\b\d{12,20}\b/.test(row.text));
    const rows = pageData.planCount === 0
      ? []
      : likelyPlanRows.length ? likelyPlanRows : rowCandidates;
    const selection = selectSnapshotRows(rows, query);
    const summaryAvailable = [...pageData.summaryMetrics, ...(pageData.planTotals || [])]
      .some((metric) => Number.isFinite(metric.numericValue));
    const planRowsAvailable = pageData.planCount === 0
      ? false
      : pageData.planCount != null ? pageData.planCount > 0 && rows.length > 0 : rows.length > 0;
    const dataAvailability = describeDataAvailability({
      summaryAvailable,
      planRowsAvailable,
      planCount: pageData.planCount,
      emptyReason: pageData.emptyReason
    });
    return {
      title: document.title.slice(0, 200),
      url: `${location.origin}${location.pathname}`,
      scope: state.scope,
      sceneLabel: scopeLabel(),
      deliveryMode: state.pageContext.deliveryMode,
      promotionTarget: state.pageContext.promotionTarget,
      accountKey: state.accountKey,
      accountName: state.accountName,
      accountBalance: workflowApi?.extractAccountBalance?.(document.body?.innerText || "") ?? null,
      summaryMetrics: pageData.summaryMetrics,
      planTotals: pageData.planTotals || [],
      dataRange: pageData.dataRange,
      planTab: pageData.planTab,
      planCount: pageData.planCount,
      emptyReason: pageData.emptyReason,
      capturedAt: new Date().toISOString(),
      pageUpdatedText: pageData.pageUpdatedText || "",
      pageVisibility: document.visibilityState || "visible",
      dataAvailability,
      planSelection: selection.meta,
      rows: selection.rows
    };
  }

  function selectSnapshotRows(rows, query) {
    const source = Array.isArray(rows) ? rows : [];
    const text = String(query || "").toLowerCase();
    const first = text.match(/(?:前|头)\s*([1-9]|10|一|二|三|四|五|六|七|八|九|十)\s*(?:条|个|行)?/);
    const values = { 一: 1, 二: 2, 三: 3, 四: 4, 五: 5, 六: 6, 七: 7, 八: 8, 九: 9, 十: 10 };
    if (first) {
      const limit = Math.min(10, /^\d+$/.test(first[1]) ? Number(first[1]) : values[first[1]]);
      return { rows: source.slice(0, limit), meta: { mode: "first", requestedLimit: limit, availableRows: source.length } };
    }
    if (/(?:全部|所有|完整|逐条|每条)/.test(text)) {
      return { rows: source.slice(0, 40), meta: { mode: "full", requestedLimit: 40, availableRows: source.length } };
    }
    const anomalyQuery = text.replace(/(?:不要|禁止|不得|无需|不)\s*(?:暂停|关闭)/g, "");
    const anomaly = /(?:异常|波动|风险|暂停|关闭|审核|限流|下滑|下降)/.test(anomalyQuery);
    const stopTerms = new Set(["当前", "页面", "数据", "计划", "分析", "查看", "获取", "千川"]);
    const terms = (text.match(/[a-z0-9_.-]{2,}|[\u4e00-\u9fff]{2,}/g) || []).filter((term) => !stopTerms.has(term));
    const ranked = source.map((row, index) => ({
      row,
      score: terms.reduce((total, term) => total + (String(`${row.id} ${row.text}`).toLowerCase().includes(term) ? 2 : 0), 0)
        + (anomaly && /(?:异常|暂停|关闭|审核|限流|下降)/.test(String(row.text || "")) ? 3 : 0)
        - index * 0.001
    }));
    const matched = ranked.filter((item) => item.score > 0).sort((left, right) => right.score - left.score);
    return {
      rows: (matched.length ? matched : ranked).slice(0, 5).map((item) => item.row),
      meta: { mode: anomaly ? "anomaly" : matched.length ? "relevant" : "first", requestedLimit: 5, availableRows: source.length }
    };
  }

  function describeDataAvailability({ summaryAvailable, planRowsAvailable, planCount, emptyReason }) {
    if (summaryAvailable && planRowsAvailable) {
      return { status: "complete", summaryAvailable: true, planRowsAvailable: true, uiMessage: "账户和计划数据可用", message: "账户汇总与计划明细均可用" };
    }
    if (summaryAvailable) {
      const detail = planCount === 0 ? "当前筛选下没有计划明细" : "计划明细尚未加载";
      return {
        status: "summary_only",
        summaryAvailable: true,
        planRowsAvailable: false,
        uiMessage: planCount === 0 ? "账户汇总可用，当前筛选无计划明细" : "账户汇总可用，计划明细加载中",
        message: `账户汇总可用，${detail}${emptyReason ? `：${emptyReason}` : ""}`.slice(0, 260)
      };
    }
    if (planRowsAvailable) {
      return { status: "plans_only", summaryAvailable: false, planRowsAvailable: true, uiMessage: "计划明细可用，账户汇总加载中", message: "计划明细可用，账户汇总尚未加载" };
    }
    return {
      status: "loading_or_empty",
      summaryAvailable: false,
      planRowsAvailable: false,
      uiMessage: "正在等待千川数据加载",
      message: emptyReason ? `当前页面暂无可读取数据：${emptyReason}`.slice(0, 260) : "正在等待千川数据加载"
    };
  }

  function pageReadinessMessage(snapshot) {
    const availability = snapshot?.dataAvailability;
    if (availability?.status === "summary_only") return `本机 Claw 已连接 · ${availability.uiMessage}`;
    if (availability?.status === "plans_only") return `本机 Claw 已连接 · ${availability.uiMessage}`;
    return "本机 Claw 已连接";
  }

  function detectPageContext() {
    if (pageContextApi?.detectPageContext) return pageContextApi.detectPageContext(document, location);
    return { deliveryMode: "unknown", promotionTarget: "unknown", supported: false, scope: "", label: "场景未识别", message: "千川场景识别组件未加载，请重新加载插件。" };
  }

  function detectAccountKey() {
    return pageContextApi?.detectAccountKey?.(document, location) || "";
  }

  function detectAccountName(accountKey = "") {
    return pageContextApi?.detectAccountName?.(document, accountKey) || "";
  }

  function schedulePageContextSync(event) {
    if (event?.target && root.contains(event.target)) return;
    window.clearTimeout(pageContextSyncTimer);
    pageContextSyncTimer = window.setTimeout(() => void syncPageContext(), 280);
  }

  async function syncPageContext() {
    const nextPageContext = detectPageContext();
    const nextAccountKey = detectAccountKey();
    const nextAccountName = detectAccountName(nextAccountKey);
    const changed = nextPageContext.scope !== state.scope
      || nextPageContext.label !== state.pageContext.label
      || nextAccountKey !== state.accountKey
      || nextAccountName !== state.accountName;
    if (!changed) {
      const message = state.status.ready ? pageReadinessMessage(collectPageSnapshot()) : state.status.message;
      if (message !== state.status.message) {
        state.status = { ...state.status, message };
        render();
      }
      return;
    }
    state.agentEnabled = false;
    state.agentPowerLoaded = false;
    stopAgentRuntime("千川账号或场景已切换");
    state.messages = [];
    state.proposals = [];
    state.memories = [];
    state.monitorRules = [];
    state.audits = [];
    state.settings = { ...DEFAULT_SETTINGS };
    state.persistedMode = "confirm";
    state.weixin = { bound: false, ready: false, message: "正在识别当前场景" };
    await refreshState(nextPageContext, nextAccountKey);
  }

  function scheduleRecognitionRetry() {
    if ((state.scope && state.accountKey) || recognitionRetryTimer || recognitionRetryCount >= 8) return;
    const delay = Math.min(400 * (2 ** recognitionRetryCount), 4000);
    recognitionRetryCount += 1;
    recognitionRetryTimer = window.setTimeout(() => {
      recognitionRetryTimer = 0;
      void syncPageContext();
      if (!state.scope || !state.accountKey) scheduleRecognitionRetry();
    }, delay);
  }

  function resetRecognitionRetry() {
    recognitionRetryCount = 0;
    window.clearTimeout(recognitionRetryTimer);
    recognitionRetryTimer = 0;
  }

  function readBudget(text) {
    const match = String(text || "").match(/(?:日预算|预算)\s*[:：]?\s*[¥￥]?\s*([\d,.]+)/);
    if (!match) return null;
    const value = Number(match[1].replace(/,/g, ""));
    return Number.isFinite(value) ? value : null;
  }

  function readRoi(text) {
    const match = String(text || "").match(/(?:净成交\s*ROI\s*目标|综合营销\s*ROI\s*目标|目标\s*ROI|ROI\s*目标|净成交\s*ROI|ROI)\s*[:：]?\s*([\d.]+)/i);
    if (!match) return null;
    const value = Number(match[1]);
    return Number.isFinite(value) && value > 0 ? value : null;
  }

  function visibleElements(selector, scope = document) {
    return Array.from(scope.querySelectorAll(selector)).filter((node) => {
      const style = getComputedStyle(node);
      const rect = node.getBoundingClientRect();
      return style.display !== "none" && style.visibility !== "hidden" && rect.width > 0 && rect.height > 0;
    });
  }

  function compactText(value) {
    return String(value || "").replace(/\s+/g, " ").trim();
  }

  function setBusy(busy) {
    state.busy = Boolean(busy);
  }

  function wait(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms));
  }

  function sendRuntime(message) {
    return new Promise((resolve, reject) => {
      if (extensionContextInvalidated) {
        reject(new Error("Extension context invalidated."));
        return;
      }
      try {
        chrome.runtime.sendMessage(message, (response) => {
          let runtimeError = null;
          try { runtimeError = chrome.runtime.lastError; } catch (error) { runtimeError = error; }
          if (runtimeError) {
            const normalized = new Error(runtimeError.message || "插件通信失败");
            invalidateExtensionContext(normalized);
            reject(normalized);
            return;
          }
          if (!response?.ok) {
            const normalized = new Error(response?.error || "请求失败");
            invalidateExtensionContext(normalized);
            reject(normalized);
            return;
          }
          resolve(response);
        });
      } catch (error) {
        invalidateExtensionContext(error);
        reject(error);
      }
    });
  }
})().catch(() => {
  window.__MMW_QIANCHUAN_AGENT_LOADING__ = false;
});
