浏览使用说明
插件精灵 DOCS

插件精灵脚本开发说明

面向开发者和 AI 的完整脚本契约,涵盖元数据、执行模式、常用配置、任务结果和 MCP Tool。

本文是插件精灵的公开开发契约,面向脚本开发者和协助生成脚本的 AI。为兼容既有脚本,JavaScript 全局对象和元数据前缀继续使用 SellerFeeds@sellerfeeds-*。平台实测差异与故障排查请同时参考《插件精灵脚本开发知识库》。

1. 先理解运行模型

插件精灵是 Chrome MV3 用户脚本运行器。脚本负责业务逻辑,插件负责安装、权限申请、任务调度、常用配置传递、任务历史和可选的 MCP 接入。

  • 官方脚本和社区脚本使用同一套运行接口。
  • 每个脚本可以声明一个或多个 Tool,但应优先把一个完整业务动作设计成一个 Tool。
  • 手动、批量、定时和 MCP 调用最终都会进入同一个 SellerFeeds.onTask 处理器。
  • 脚本自行决定外部 API 调用、字段映射、追加或覆盖、去重、报告及链接返回方式。
  • 插件不会替脚本保存目标网站 Cookie,也不会替脚本实现某个平台的业务写入规则。

2. 最小可运行脚本

// ==UserScript==
// @name         示例商品查询
// @namespace    https://example.com/sellerfeeds
// @version      1.0.0
// @description  根据商品编号查询商品信息
// @match        https://www.example.com/*
// @run-at       document-idle
// @grant        none
// @sellerfeeds-execution-mode page
// @sellerfeeds-tool {"name":"example_query_product","title":"查询商品","description":"当用户需要查询 Example 网站中的单个商品信息时使用。读取商品标题与价格,不修改网站数据;需要用户已登录 Example。","inputSchema":{"type":"object","properties":{"productId":{"type":"string","title":"商品编号","description":"Example 网站中的商品编号,不能为空。","minLength":1}},"required":["productId"],"additionalProperties":false},"outputSchema":{"type":"object","properties":{"productId":{"type":"string","description":"商品编号。"},"title":{"type":"string","description":"商品标题。"},"price":{"type":"number","description":"商品价格;网页未返回时省略该字段。"}},"required":["productId","title"]}}
// ==/UserScript==

SellerFeeds.onTask(async ({ taskId, tool, input, variables, source }) => {
  if (tool !== 'example_query_product') throw new Error(`不支持的 Tool:${tool}`);
  if (!input.productId) throw new Error('请填写商品编号');

  return {
    message: '查询完成',
    data: {
      productId: input.productId,
      title: '网页返回的真实标题',
    },
  };
});

@sellerfeeds-tool@sellerfeeds-variable 的 JSON 必须各自写在一行中;文档中的格式化 JSON 只用于讲解。

3. 元数据字段

3.1 标准 UserScript 字段

字段要求
@name必填,脚本显示名称;与 @namespace 一起决定脚本身份。
@namespace建议使用稳定且属于开发者的命名空间;不要在更新时修改。
@version建议使用 x.y.z 数字版本;只有更高版本才会被识别为更新。
@description清楚说明脚本用途,会显示在安装预览和脚本库中。
@author可选,开发者名称。
@match必填至少一条,仅支持明确的 HTTP/HTTPS 范围,禁止 <all_urls>
@exclude-match / @include / @exclude可选,用于进一步修正注入范围。
@run-at可选,常用值为 document-idle
@grant建议固定为 none,通过 SellerFeeds API 使用运行能力。
@noframes可选,声明后不注入 iframe。
@downloadURL / @updateURLHTTPS .user.js 地址;通过插件精灵脚本市场发布时由平台生成。
@homepageURL / @supportURL可选,项目主页和支持地址。

3.2 插件精灵扩展字段(@sellerfeeds-*

字段要求
@sellerfeeds-execution-modepage(默认)或 offscreen;旧的 background 已废弃。
@sellerfeeds-entry-urlpage 模式可选;任务没有现成页面时自动打开的 HTTPS 地址,支持 {input.字段} 占位符。
@sellerfeeds-world / @inject-intocontent(默认隔离世界)或 main/page(MAIN 世界)。MAIN 世界能访问页面 JS,但网站也能观察和影响脚本。
@connectoffscreen 模式可声明额外 API 域,例如 https://api.example.com/*。可写多条。
@sellerfeeds-toolTool 的单行 JSON 声明,可写多条。
@sellerfeeds-variable“常用配置”的可选表单模板,单行 JSON,可写多条。
@sellerfeeds-official插件精灵官方分发专用;社区脚本不得声明。

脚本源码最大 2MB。安装和更新地址必须使用 HTTPS,并以 .user.js 结尾。

4. 选择执行模式

对比项pageoffscreen
适合场景读取或操作目标网页真实 DOM、页面 JS 状态、页面导航纯 HTTP 请求与响应解析,不需要目标页 DOM
执行位置匹配网页的 USER_SCRIPT 或 MAIN 世界插件的隔离 sandbox
没有打开目标页时插件按入口地址静默打开后台标签页不打开标签页,直接在后台沙箱运行
网络访问页面环境网络能力使用 SellerFeeds.fetch 由扩展代发
Cookie使用目标网页当前登录态代发请求使用浏览器当前登录态
DOM目标网站真实 DOM只有沙箱自身 DOM,可用 DOMParser 解析 HTML 字符串

选择原则:必须操作网页就用 page;只做“请求 + 解析”就用 offscreen

4.1 page 模式入口

// @sellerfeeds-execution-mode page
// @sellerfeeds-entry-url https://www.example.com/product/{input.productId}

占位符只能读取 input 顶层字段。缺少可选字段时,运行器会尝试回退到 @match 可推导出的首页,因此脚本仍需自行检查当前页面和输入。

4.2 offscreen 模式网络域

// @match   https://www.example.com/*
// @connect https://api.example.com/*
// @sellerfeeds-execution-mode offscreen

@match 表示目标网站及基础授权范围;@connect 只增加允许请求的 API 域,不会把脚本注入该域。初始 URL 和每一次重定向都必须处于脚本声明且用户已授权的范围内。

5. SellerFeeds 运行时 API

5.1 接收任务

SellerFeeds.onTask(async ({ taskId, tool, input, variables, source }) => {
  // source: manual | batch | scheduled | mcp
  return { message: '完成', data: {} };
});
字段含义
taskId本次任务的唯一编号。
tool被调用的 Tool name。一个脚本有多个 Tool 时必须据此分派。
input已按 inputSchema 生成并校验的任务参数。
variables用户为本次任务选择的完整“常用配置”,未选择时为 {}
sourcemanualbatchscheduledmcp

处理器返回值必须可被 JSON 序列化。抛出 Error 会使任务失败,错误信息会进入任务历史和 MCP 报告。

5.2 后台网络请求

offscreen 脚本通过以下接口请求目标网站或 @connect 域:

const response = await SellerFeeds.fetch(url, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ keyword: input.keyword }),
});

if (!response.ok) throw new Error(`请求失败:HTTP ${response.status}`);
const result = await response.json();

限制如下:

  • body 只支持字符串,JSON 对象必须先 JSON.stringify
  • headers 使用普通对象。
  • 沙箱内不能直接使用 chrome.*
  • 桥接请求不能真正中止;需要超时提示时可使用 Promise.race,并忽略迟到结果。
  • 不要在日志、报告或错误消息中输出 Cookie、Token 或完整常用配置。

5.3 日志与进度

SellerFeeds.log('开始查询', { productId: input.productId });
SellerFeeds.emit('task-progress', { current: 20, total: 100 });

日志只写必要的诊断信息,不要记录凭据和完整响应中的隐私数据。

6. Tool 与输入 Schema

6.1 Tool 声明结构

{
  "name": "amazon_collect_search_results",
  "title": "采集亚马逊搜索结果",
  "description": "当用户需要分析亚马逊关键词搜索结果时使用。读取自然位与广告位,返回商品列表和位置类型;需要浏览器已登录目标站点,只读取数据,不修改店铺。",
  "inputSchema": {
    "type": "object",
    "properties": {},
    "required": [],
    "additionalProperties": false
  },
  "outputSchema": {
    "type": "object",
    "properties": {}
  }
}

6.2 MCP 发布硬性要求

脚本能在本地运行,不代表它会自动成为 MCP Tool。安装后默认不发布到 MCP;只有用户开启全局 MCP,并在脚本中心单独打开该脚本的 MCP 开关,AI 才能看到它。

发布前必须满足:

  1. name 匹配 ^[A-Za-z0-9_-]{1,128}$,不能使用保留名 get_report
  2. name 应稳定且具有业务前缀,推荐“平台_动作_对象”,如 amazon_collect_search_results
  3. description 明确回答:何时使用、做什么、作用范围、返回什么、需要什么前提、是否有副作用。
  4. inputSchema 根节点必须是 {"type":"object"}
  5. 每个顶层参数必须有准确的 typedescription;数组还必须声明 items.type
  6. required 只能引用 properties 中存在的字段。
  7. 同名 Tool 会冲突,发生冲突的 Tool 都不会发布。

建议为 Tool 和参数提供普通用户能看懂的 title,并声明稳定的 outputSchema

6.3 Schema 设计要求

支持常用 JSON Schema 约束,包括 typeenumdefaultminimummaximumminLengthpatternminItemsrequiredadditionalProperties

  • 字段必须对应网页或接口真实存在的输入。
  • 枚举只列出真实选项,不虚构“自动”等页面没有的值。
  • 数值使用 numberinteger,不要让用户填写带单位的字符串。
  • 描述中写清单位、格式、示例、范围以及字段间关系。
  • Schema 负责基础校验;登录状态、跨字段关系和业务错误仍由脚本检查。
  • 没有获取到的数据返回 null 或省略,不得使用 0 或空字符串伪造真实值。

7. 常用配置与配置模板

“常用配置”让普通用户保存一组经常重复填写的名称和值,例如表格地址、授权码、店铺编号或固定筛选条件。它是通用参数库,不绑定某个脚本或平台。

7.1 自动匹配规则

用户为任务选择一项常用配置后:

  • 与 Tool inputSchema 同名、同路径的值会自动填入 input
  • 用户在任务表单中手动修改的值优先。
  • 不在 Schema 中的内容不会混入 input,但脚本仍能从完整的 variables 中读取。
  • 未选择常用配置时,variables{}
  • 手动、批量和定时任务都可以选择常用配置;定时任务运行时读取该配置的最新值。

优先级为:用户手动填写 > 常用配置同名值 > Schema 默认值。

7.2 预制录入模板

脚本可声明一个或多个表单模板:

// @sellerfeeds-variable {"title":"飞书多维表格配置","description":"填写表格写入所需信息","schema":{"type":"object","properties":{"baseToken":{"type":"string","title":"多维表格授权码"},"appToken":{"type":"string","title":"App Token"},"tableId":{"type":"string","title":"Table ID"},"baseUrl":{"type":"string","title":"表格链接"}},"required":["baseToken","appToken","tableId"]}}

安装脚本时,用户可以选择模板或“稍后设置”。选中后,安装完成会打开对应表单。模板只改善录入体验,不绑定或过滤常用配置,也不限制开发者增加任意字段。

7.3 在脚本中读取

SellerFeeds.onTask(async ({ input, variables }) => {
  const { baseToken, appToken, tableId, baseUrl } = variables;
  if (!baseToken || !appToken || !tableId) {
    throw new Error('所选常用配置缺少授权码、App Token 或 Table ID');
  }

  // 追加、覆盖、更新、去重和字段映射均由脚本决定。
  return {
    message: '多维表格更新成功',
    links: baseUrl ? [{ title: '打开多维表格', url: baseUrl }] : [],
  };
});

常用配置可以在自动表单和 JSON 模式之间切换。脚本与常用配置分别由用户手动同步;保存或编辑本身不会自动上传。

8. 手动、批量与定时任务

同一个 Tool 不需要为三种任务模式编写三套代码。

  • 手动任务:执行一次表单或 JSON 输入。
  • 批量任务:选定一个批量字段,多行值会拆成多个任务;其余字段作为每项任务的公共输入。
  • 定时任务:保存 Tool、输入、常用配置选择和时间规则,到点后自动调用。
  • 运行时可通过 source 区分来源,但除非业务确实不同,不建议分叉核心逻辑。

脚本应保证重复执行的行为可预测。是否追加、覆盖、更新或去重必须由脚本根据业务要求明确实现,不要假设插件会代为处理。

9. 任务结果、报告和通知

脚本返回值可以同时包含结构化数据、摘要、链接和文件:

return {
  message: '采集和写入完成',
  data: { total: records.length, records },
  links: [{ title: '打开结果表格', url: tableUrl }],
  files: [
    { name: '结果.md', format: 'markdown', content: '# 结果' }
  ],
};

结果规则:

  • message 用于任务摘要和通知文字。
  • data 是结构化结果,会进入任务报告和 MCP public_report
  • links 是用户可打开的 HTTPS 链接。
  • files 是脚本主动返回的文件;链接和文件可以同时存在。
  • 有文件就发送文件,有链接就发送链接,两者都有就一起发送。
  • 只有链接时,插件不会擅自生成报告文件。
  • 没有 files 不等于任务失败;报告形式由脚本结果和脚本声明共同决定。

大结果应主动精简。任务历史对超大数据可能只保留截断摘要;不要依赖任务历史保存无限量业务数据。

10. MCP 调用模型

MCP 业务 Tool 使用异步任务模型:

  1. AI 调用脚本 Tool。
  2. 服务返回 task_id
  3. 浏览器插件领取并执行任务。
  4. AI 使用系统 Tool get_reporttask_id 查询状态及结果。

因此 Tool 的描述和 Schema 必须足够清楚,让 AI 在不阅读源码的情况下判断是否应该调用、怎样填写参数以及会产生什么结果。

控制规则:

  • 脚本安装后 MCP 默认关闭。
  • 全局 MCP 开关和脚本级 MCP 开关必须同时开启。
  • 脚本不能替用户开启 MCP。
  • 停用脚本后,它的 Tool 会退出 MCP 清单。
  • 脚本更新保留用户原来的 MCP 选择。
  • MCP 来源任务不发送普通任务通知,结果由 MCP 客户端通过 get_report 获取。

11. 权限和安全边界

  • @match@connect 应遵循最小范围原则,不要申请无关域名。
  • 安装或更新增加新域名时,必须由用户确认网站权限。
  • 脚本只能读取用户主动为任务选择的那一项常用配置。
  • 脚本拿不到插件精灵 License、服务端密钥或其他脚本的数据。
  • 不得把 Cookie、Token、授权码或用户业务数据上传到声明用途之外的第三方。
  • 不要把完整凭据写入源码、日志、异常信息、任务返回值或报告。
  • 使用 MAIN 世界、evalnew Function、Cookie、本地存储或页面跳转等能力会产生风险提示,应仅在确有必要时使用。
  • 未登录、Cookie 失效、验证码、Robot Check、HTTP 401/403/429、超时和平台业务错误都必须真实报告,不得伪造成功。

12. 安装、更新和身份

  • 脚本身份由稳定的 @namespace@name 共同确定;修改其中任意一个会被视为新脚本。
  • 更新必须提高 @version,并保持脚本身份不变。
  • 更新新增网站权限时,用户需要重新授权。
  • 本地修改过源码的脚本不会被无提示覆盖。
  • 卸载脚本后,运行器会回收不再被其他脚本使用的网站权限。
  • 社区脚本安装前应让用户审阅源码、网站范围和风险提示。

13. 开发与测试清单

提交脚本前至少确认:

  1. 元数据块完整,@sellerfeeds-tool@sellerfeeds-variable 均为单行 JSON。
  2. @match@connect 和执行模式符合真实需求。
  3. Tool 名称稳定、唯一,描述能让普通用户和 AI 判断使用场景。
  4. 所有输入字段都有准确类型、标题、说明、单位、范围或示例。
  5. onTask 校验必填项、跨字段规则、登录状态和业务响应码。
  6. 正常结果、空结果、未登录、限流、验证码、超时和接口错误均经过测试。
  7. 批量和定时运行不依赖当前活动页面,或已正确提供 @sellerfeeds-entry-url
  8. 没有在源码、日志和结果中泄露 Cookie 或常用配置。
  9. 返回字段来自真实网页或接口;缺失值不伪造为 0。
  10. 手动、批量、定时和 MCP 共用同一个稳定业务入口。

仓库开发时运行:

pnpm run verify

14. 如何把文档交给 AI

生成或修改脚本时,建议向 AI 同时提供:

  1. 本开发说明 Markdown:https://www.sellerfeeds.com/docs/development.md
  2. 实测知识库 Markdown:https://www.sellerfeeds.com/docs/knowledge.md
  3. 具体业务需求、目标网站、输入字段、预期输出和是否允许写入外部系统。

可以直接使用以下提示词:

请先完整阅读插件精灵脚本开发说明和知识库,再根据我的需求编写一个可安装的 .user.js。
必须遵守元数据、执行模式、常用配置、Tool Schema、MCP 描述、权限和结果契约。
对知识库没有确认的页面字段或接口行为,不要猜测,请明确列出需要我实测的信息。
我的需求是:……

知识库记录平台的实测事实;开发说明定义运行器契约。两份文档发生表述冲突时,以开发说明的运行器契约为准,以知识库中标注的最新实测结论解释目标平台行为。

本文档由 Markdown 原文自动生成;网页与可交给 AI 的源文件保持一致。