# 源视频溯源插件接口

插件不保存、不读取上游密钥。源视频溯源统一请求 MMWGZT 后端，由后端保存密钥、调用上游并完成预扣与自动返还。

## 后台消息

```js
chrome.runtime.sendMessage({
  type: "SOURCE_TRACE",
  url: "https://www.douyin.com/..."
});
```

## 后端接口

```http
POST /api/plugin/source-trace
Authorization: Bearer <pluginAuth.token>
Content-Type: application/json

{"url":"https://www.douyin.com/..."}
```

成功返回 `title`、`normal`、`source`、`sources`、`configured_cost_points`、`request_id`、`points_balance_after`、`free_quota_remaining` 和 `source_trace_free_remaining`。

`sources` 保留上游返回的全部可下载视频候选，标准化后的候选通过 `is_original` 标记是否为原视频。插件单条溯源入口不再把其中一条候选重写为默认素材，也不会在成功后自动下载。

计费规则：
- 用户确认开始溯源后，`POST /api/plugin/source-trace` 立即按账号定价预扣积分；仍有免费额度时先预占 1 次免费额度。
- 上游结果只要包含 `is_original=true` 的 Original 原视频候选，就保留本次预扣。
- 上游结果没有任何 Original 原视频时，后端在同一请求内自动返还预扣积分或恢复免费额度，并返回 `refunded_points`、`free_quota_refunded` 和 `has_original=false`。
- 上游请求失败或解析失败时，同样自动返还预扣，避免异常吞费。
- 弹窗里的素材下载不再触发第二次计费。

## 抖音页快捷入口

普通视频下载只走移包版 AIX 链路，避免自研候选匹配造成串视频或无音频。

`mmw-douyin-source-bridge.js` 只在 AIX 下载面板里插入“下载源视频”入口：提取当前卡片或详情页的抖音链接，发送 `SOURCE_TRACE` 到后台。成功后在该菜单项旁打开跟随弹窗，按“素材 1、素材 2……”展示格式和大小，不显示或复制上游地址；每条素材只提供独立的“下载”按钮。

搜索页卡片优先读取 AIX 按钮上下文中的视频 ID，生成当前搜索页的 `modal_id=<视频ID>` 地址，避免等待分享链接或错误提交裸搜索页。

详情页如果 AIX 没有挂出按钮，桥接脚本会提供轻量兜底面板：
- 下载当前视频：仅提交当前详情页最大可见 `<video>` 的播放地址到 `DOWNLOAD_SELECTED`，不做卡片匹配和资源池扫描。
- 下载源视频：确认预扣规则后走 `SOURCE_TRACE` 后端溯源，成功后显示全部素材候选，不自动选择或下载其中一条；没有 Original 时，成功提示会同时说明已经返还。

插件只向 MMWGZT 后端提交抖音页面链接，不保存也不下发上游密钥。
