con un clic
chat-plus-adapter-debugger
// 为 Chat Plus 新框架编写、修复、审查站点适配脚本。先读取完整 builtin://chat-plus-adapter-debugger/SKILL.md 获取 skillToken;这次读取 SKILL.md 不需要 skillToken。不要用正则或局部读取只抓 token。后续调用不带或带错 skillToken 会报错并必须重试,所以正式调试前先拿到正确 token。
// 为 Chat Plus 新框架编写、修复、审查站点适配脚本。先读取完整 builtin://chat-plus-adapter-debugger/SKILL.md 获取 skillToken;这次读取 SKILL.md 不需要 skillToken。不要用正则或局部读取只抓 token。后续调用不带或带错 skillToken 会报错并必须重试,所以正式调试前先拿到正确 token。
Run CodeGraph CLI commands through npx for local codebase indexing, semantic search, context building, and impact analysis. First read the complete builtin://codegraph/SKILL.md to get skillToken; this SKILL.md read does not require skillToken. Calls without the correct skillToken will fail and must be retried.
Create, analyze, proofread, and modify Office documents (.docx, .xlsx, .pptx) using the officecli CLI tool. First read the complete builtin://officecli/SKILL.md to get skillToken; this SKILL.md read does not require skillToken. Calls without the correct skillToken will fail and must be retried.
Browser automation and debugging through bundled Chrome DevTools Protocol. First read the complete builtin://chrome-cdp/SKILL.md to get skillToken; this SKILL.md read does not require skillToken. Do not use regex or partial reads to fetch only the token. Later calls without the correct skillToken will fail and must be retried, so get the token before debugging.
Run non-interactive shell commands inside an allowed workspace. First read the complete builtin://shell_command/SKILL.md to get skillToken; this SKILL.md read does not require skillToken. Do not use regex or partial reads to fetch only the token. Later calls without the correct skillToken will fail and must be retried, so get the token before running real commands. For search, discovery, broad inventories, and file counts, prefer rg or rg --files before recursive shell listings, and exclude dependency folders, VCS metadata, generated outputs, virtual environments, and caches such as node_modules, .git, target, dist, build, coverage, .next, .cache, .venv, and __pycache__.
Apply validated text file operations through the gateway: exact replacements, multi-file edits, file creation, deletion, and moves. First read the complete builtin://multi_edit_file/SKILL.md to get skillToken; this SKILL.md read does not require skillToken. Do not use regex or partial reads to fetch only the token. Calls without the correct skillToken will fail and must be retried.
Read text files through the gateway with line-numbered output, allowed-directory enforcement, binary-file rejection, and bounded line windows. Use this before editing files with multi_edit_file. First read the complete builtin://read_file/SKILL.md to get skillToken; this SKILL.md read does not require skillToken. Calls without the correct skillToken will fail and must be retried.
| name | chat-plus-adapter-debugger |
| description | 为 Chat Plus 新框架编写、修复、审查站点适配脚本。先读取完整 builtin://chat-plus-adapter-debugger/SKILL.md 获取 skillToken;这次读取 SKILL.md 不需要 skillToken。不要用正则或局部读取只抓 token。后续调用不带或带错 skillToken 会报错并必须重试,所以正式调试前先拿到正确 token。 |
产出或修复一段可直接粘贴到 Chat Plus 的站点适配脚本,并满足新框架硬规则:
return { ... }metatransformRequestextractResponsedecorateBubblescontinueConversationdecorateBubbles 必须使用 ctx.helpers.ui.decorateProtocolBubbles(...)continueConversation 必须使用 ctx.helpers.plans.dom(...)continueConversation 必须使用 ctx.continuationTextextractResponse 必须返回 responseContentPreviewtransformRequest 要么使用 ctx.helpers.buildInjectedText(...) 改写请求,要么明确 return nullextractResponse准备页面调试前,先确认工具列表存在 chrome-cdp,并读取 builtin://chrome-cdp/SKILL.md。本 skill 的执行入口可直接代理常用 CDP 调试命令,也可用更贴近 Chat Plus 工作流的别名。
只有用户明确允许启动浏览器调试会话后,才使用浏览器调试命令。MCP Gateway 内置 chrome-cdp 默认通过原生 Chrome DevTools Protocol 启动或复用独立的持久 profile Chrome,不连接用户已经打开的 Chrome 调试端口。
常用别名:
capture start
capture clear
network search <filter>
network get <request-id>
network perf
等价 CDP 命令:
netclear
net <filter>
netget <request-id>
perfnet
html [target] [selector]
snap [target]
evalraw <target> <method> [json]
如果 chrome-cdp 启动或浏览器连接失败:
stopopen <url> 或 launch <url>按这个顺序抓样本。不要把 URL、Performance index 或页面 DOM 文本当作稳定 request id。
capture start 或 netclear,让 CDP Network 从用户操作前开始记录CHATPLUS_ADAPTER_PROBE_YYYYMMDD_001发好了network search <关键词> 或 net <关键词> 搜索 CDP Network 记录net 输出里的 CDP request idnetwork get <request-id> 查看请求体、响应体、状态码、content-type 和传输类型network get 输出总结协议结构,不复述敏感 headers--request-file / --response-file 保存到临时文件后再读取capture start,让用户发第二条 follow-up 样本硬要求:
发好了 前假设请求已经产生chrome-cdp 直接看netget 输出可能包含 Authorization、Cookie、设备 ID、会话 ID;最终回答和中间总结都不要复述这些值允许的查询方式:
capture start 或 netclearnetwork search <url-fragment>、network search <api-path>、network search <method>、network search <mime> 或其它从候选里来的关键词network search <关键词> 定位,再用 network get <request-id> 读取 framesnetwork search 没有结果,用 network perf 或 perfnet 辅助确认是否漏开 Network、页面是否跳转、请求是否发生在 worker / service worker禁止的反推方式:
capture start / netclear 的情况下期待 CDP Network 有用户操作前的历史记录抓取必须按三层证据链推进:
network search <filter> 搜索真实 request idnetwork get <request-id> 补齐浏览器层原始请求体、响应体、状态码和 content-typenetwork perf 查看发送后新增资源html / snap 确认用户消息、AI 消息、输入框、发送按钮、模式开关和消息气泡选择器extractResponse 的真实响应协议先分类,不要直接归因为站点没有发请求:
OPTIONS、埋点、标题生成、历史同步、配置、心跳、模型列表、附件上传netget 输出被截断或 body 太长:才用 request id 和 --request-file / --response-file 保存到临时文件transformRequest 返回 nullcapture start 后再让用户发送netget 看到的是网络 body,不是 F12 Preview。网络 body 可能包含应用层 framing / transport envelope,必须按协议层次还原。
网络 body 解码顺序:
netget 里的 status、content-type、content-encoding、request/response headers,不要只看文件扩展名application/json 或纯文本,按 UTF-8 直接读\0、控制字符、�、、 等字节,先检查是否是 length-prefixed JSON 帧有些站点存在会明显改变请求结构、响应结构或消息 DOM 的模式开关,例如:
遇到这种情况时,必须先确认用户实际使用的是哪种模式,再决定抓样本和写 adapter。
硬要求:
extractResponse 必须排除思考文本,只提取最终 assistant 正文和需要保留的协议块decorateBubbles 的目标选择器必须避开思考组件,不把思考组件纳入协议卡片渲染范围默认策略:
renderProtocolCard、getProtocolCardTheme、detectToolResultTone 这类旧 UI 辅助函数decorateBubblescontinueConversation 自己 click() / dispatchEvent() / setTimeout()[CHAT_PLUS_...] 协议标记meta、缺 adapterName、缺 capabilitiesJSON.parse(bodyText) 直接解析请求体,必须走 ctx.helpers.json.parse(bodyText)ctx.helpers.buildInjectedText(...)ctx.bodyText / ctx.responseText 转字符串,必须走 ctx.helpers.text.toText(...)meta.contractVersion 必须是整数,按当前 Chat Plus 项目范式优先用 2meta.capabilities 必须用对象写明四类能力,不要写成数组、字符串或空对象transformRequest(ctx)
负责请求层注入。输入注入优先走协议层。请求可稳定改写时,必须用 ctx.helpers.text.toText(ctx.bodyText) 取文本、用 ctx.helpers.json.parse(bodyText) 解析 JSON、用 ctx.helpers.buildInjectedText(...) 生成注入文本。请求不可稳定改写时,必须保留 hook 并 return null。
extractResponse(ctx)
负责从真实响应里提取 AI 正文。输出抓取必须走真实协议 / 真实响应。不要从页面现成消息 DOM 倒推正文,当成响应提取。必须保留协议块,不要把 toolCall / toolResult / codeMode 过滤掉。必须返回 responseContentPreview。不要随意 slice(...)。
decorateBubbles(ctx)
负责隐藏用户注入块,把可见协议块变成统一卡片,并保留协议块之外的普通文本。必须直接走 ctx.helpers.ui.decorateProtocolBubbles(...)。
continueConversation(ctx)
负责返回 DOM 发送方案。必须直接走 ctx.helpers.plans.dom(...)。必须使用 ctx.continuationText。不能自己执行真实 DOM 副作用。第一次 send 默认用 mode: "click",只有确认站点必须 Enter 时才改。
toolCall 默认只展示,不等于自动执行codeModecodeMode 卡片的手动运行按钮、卡片容器、源码节点,统一由平台 helper 负责,不让站点脚本重复造轮子按下面顺序工作:
transformRequest 能不能稳定改写extractResponse 怎么提取正文和协议块decorateBubblescontinueConversation如果样本不足,先指出缺什么,不要装作信息足够。
不要只看四个函数在不在。必须逐项检查:
meta 是否完整transformRequest 是否使用 ctx.helpers.buildInjectedText(...) 或明确 return nullextractResponse 是否返回 responseContentPreviewdecorateBubbles 是否直接使用 ctx.helpers.ui.decorateProtocolBubbles(...)continueConversation 是否直接使用 ctx.helpers.plans.dom(...)continueConversation 是否使用 ctx.continuationText输出顺序固定:
responseContentPreviewcodeMode begin/end 是否能完整保留assistantSelectors / 协议卡片装饰范围中排除input / change必须包含 contractVersion、adapterName、capabilities。默认能力结构按真实样本填写,常见 JSON 请求体 + SSE 响应 + helper 卡片 + DOM 续写应写成:
meta: {
contractVersion: 2,
adapterName: "...",
capabilities: {
requestInjection: "json-body",
responseExtraction: "sse",
protocolCards: "helper",
autoContinuation: "dom-plan",
},
},
字段语义:
requestInjection: 请求层注入方式,例如 "json-body";如果请求不可稳定改写,可写 "none",但 transformRequest 必须明确 return nullresponseExtraction: 真实响应提取方式,例如 "sse"、"ndjson"、"json"、"websocket"、"grpc-web"、"dom-fallback";优先真实协议,不要默认 DOMprotocolCards: 必须是 "helper",对应 ctx.helpers.ui.decorateProtocolBubbles(...)autoContinuation: 必须是 "dom-plan",对应 ctx.helpers.plans.dom(...)ctx.helpers.json.parse(bodyText) 解析,不要写 JSON.parse(bodyText)ctx.helpers.text.toText(ctx.bodyText) 获取,不要自己转字符串ctx.helpers.buildInjectedText(...)applied / bodyText / requestMessagePath / requestMessagePreviewreturn null标准请求体读取和注入模板:
const bodyText = ctx.helpers.text.toText(ctx.bodyText);
if (!ctx.injectionText || !bodyText) return null;
const body = ctx.helpers.json.parse(bodyText);
if (!body) return null;
const originalText = slot.text;
const nextText = ctx.helpers.buildInjectedText(ctx.injectionText, originalText, ctx.injectionMode);
if (nextText === originalText) return null;
slot.apply(nextText);
responseContentPreviewresponseContentPreviewinnerText / textContent 当作主提取方案标准响应体读取模板:
const responseText = ctx.helpers.text.toText(ctx.responseText);
if (!responseText) return null;
只能写成这种方向:
decorateBubbles(ctx) {
return ctx.helpers.ui.decorateProtocolBubbles({
root: ctx.root || document,
protocol: ctx.protocol,
userSelectors: [...],
assistantSelectors: [...],
});
}
允许传:
normalizeUserTextnormalizeAssistantTextbeforeRenderUserNodebeforeRenderAssistantNode但不要自己重写整套卡片系统。
如果站点有思考组件:
assistantSelectors 应只命中最终回答消息区域,不要命中思考容器禁止:
ctx.helpers.ui.decorateProtocolBubbles(...)只能写成这种方向:
continueConversation(ctx) {
return ctx.helpers.plans.dom({
root: ctx.root,
composerText: ctx.continuationText,
input: {
selectors: [...],
kind: "textarea",
dispatchEvents: ["input", "change"],
},
send: {
mode: "click",
selectors: [...],
waitForEnabled: true,
maxWaitMs: 2000,
},
});
}
输入侧策略说明:
input.kind 必须按真实 DOM 确认后写 "textarea" 或 "contenteditable",不要看见输入框就猜send 时优先 mode: "click",不要默认 Enter;只有真实站点要求 Enter 且有证据时才用键盘发送禁止:
btn.click()dispatchEvent(...)setTimeout(...)return { dispatched: true }ctx.continuationText这些不是风格偏好,是生成和审查 adapter 时必须拦截的错误:
| 检查点 | 正确做法 | 错误做法 |
|---|---|---|
| JSON 解析 | ctx.helpers.json.parse(bodyText) | JSON.parse(bodyText) |
| 文本注入 | ctx.helpers.buildInjectedText(...) | 手写字符串拼接 |
| 文本获取 | ctx.helpers.text.toText(ctx.bodyText) | String(...)、.toString()、手动解码 |
decorateBubbles | ctx.helpers.ui.decorateProtocolBubbles({...}) | 自己操作 DOM 或重造卡片 |
continueConversation | ctx.helpers.plans.dom({...}) | 自己 click() / dispatchEvent() |
continueConversation.send | 首次默认 mode: "click" | 没证据就默认 Enter |
| 输入框 kind | 先确认 "textarea" 或 "contenteditable" | 对号入座、凭经验猜 |
| 最外层 | return { meta: {...}, transformRequest, extractResponse, decorateBubbles, continueConversation } | 裸函数、对象字面量、漏 hook |
| 协议注入 | JSON 可解析且能稳定定位消息时优先协议注入 | 能改请求却直接退 DOM |
输出脚本前必须自己检查:
return { ... }metameta 有 contractVersionmeta 有 adapterNamemeta 有 capabilitiesmeta.capabilities.requestInjection、responseExtraction、protocolCards、autoContinuation 都已按真实实现填写protocolCards 是 "helper"autoContinuation 是 "dom-plan"transformRequest 不是乱改请求transformRequest 用 ctx.helpers.text.toText(ctx.bodyText) 读取请求文本ctx.helpers.json.parse(bodyText) 解析,没有直接 JSON.parse(bodyText)ctx.helpers.buildInjectedText(...) 生成,没有手写字符串拼接extractResponse 返回 responseContentPreviewextractResponse 已排除思考文本,只保留最终正文和协议块decorateBubbles 直接使用平台 helperdecorateBubbles 的选择器 / 过滤逻辑已避开思考组件continueConversation 直接使用平台 helpercontinueConversation 使用 ctx.continuationTextcontinueConversation.send.mode 首次默认 "click",除非有证据必须 Enterinput.kind 已从真实 DOM 确认为 "textarea" 或 "contenteditable"[CHAT_PLUS_...]最终先给:
最终先给 findings,不要先说“整体不错”。
decorateBubbles 降级成纯样式函数continueConversation 写成真实 DOM 执行器responseContentPreviewtransformRequest 里使用 JSON.parse(bodyText)、手写注入拼接、手动字符串转换textarea / contenteditable 就写输入框 kindnetget 输出或临时文件里的敏感 header、cookie、token、设备 ID 或会话 IDctx.helpers.ui.decorateProtocolBubbles(...),就判定不符合新框架ctx.helpers.plans.dom(...),就判定不符合新框架transformRequest 里直接 JSON.parse(bodyText),就判定需要改成 helperctx.helpers.buildInjectedText(...),就判定需要修改meta,就判定不符合新框架responseContentPreview,就判定响应提取错误decorateBubbles 的卡片渲染范围,就判定 DOM 选择器错误transformRequest 明确 return null 且 continueConversation 可用,就算符合框架本 skill 只负责产出或修复 Chat Plus 适配脚本;脚本本身、临时样本、抓回来的 request/response 文件不要走 shell_command 的 echo > / Set-Content / here-doc / cat 再自己写文件。
multi_edit_file,让网关记录变更路径、执行 path guard、产出可审查的 diff。netget --request-file / --response-file 产出的内容一律走 read_file,输出带行号、受 allowed directories 约束、二进制自动拒绝。chrome-cdp,不要试图在 shell_command 里自己起 Chrome 或 node 调 CDP。