{"id":"32e4484b-1a42-4168-9cd5-337c74388ff7","entityType":"agent","slug":"clawhub-noaheleven-webchat-extension","name":"webchat-extension","canonicalUrl":"https://www.xpersona.co/agent/clawhub-noaheleven-webchat-extension","canonicalPath":"/agent/clawhub-noaheleven-webchat-extension","generatedAt":"2026-10-11T21:52:12.280Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T18:50:44.017Z","emptyReason":null},"description":"部署「网页划线对话」浏览器扩展（Chrome MV3 / 兼容 Chrome·Edge·千问·夸克 等 Chromium 内核浏览器）。在任意网页选中文字，点工具栏图标唤起可拖动对话浮层，带着网页上下文用 CodeBuddy AI 流式问答。包含本地 Express + SSE 后端（CodeBuddy Agent SDK）与前端扩展。当用户要「做一个网页划词对话插件 / 给浏览器装个网页对话工具 / 选中文字问 AI / 部署小虾网页对话扩展 / web highlight chat extension / 把网页内容丢给 AI 聊」时使用本技能。","descriptionLabel":"Source description","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1K downloads reported by the source. Last updated 10/11/2026.","installCommand":"clawhub skill install s176ns2k88htgg2h6v9myyxg7x83q8k1:webchat-extension","sourceUrl":"https://clawhub.ai/noaheleven/webchat-extension","homepage":"https://clawhub.ai/noaheleven/skills/webchat-extension","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/noaheleven/webchat-extension","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/noaheleven/skills/webchat-extension","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":60,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"webchat-extension technical dossier on Xpersona with agent coverage, OPENCLEW support, and live trust metadata."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-11T18:50:44.017Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T18:50:44.017Z","emptyReason":null},"stars":null,"forks":null,"downloads":1007,"likes":null,"task":null,"library":null,"packageName":null,"latestVersion":"0.1.5","tractionLabel":"1K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T18:50:43.956Z","emptyReason":null},"lastUpdatedAt":"2026-10-11T18:50:44.017Z","lastCrawledAt":"2026-10-11T18:50:43.956Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-12T18:50:43.956Z","lastVerifiedAt":null,"highlights":[{"version":"0.1.5","createdAt":"2026-08-07T06:54:40.332Z","changelog":"本地最新版原样同步","fileCount":26,"zipByteSize":82570},{"version":"0.1.4","createdAt":"2026-08-07T06:44:07.021Z","changelog":"本地最新版原样同步","fileCount":26,"zipByteSize":82396},{"version":"0.1.3","createdAt":"2026-07-16T04:41:01.443Z","changelog":"**CodeBuddy认证与后端演示模式支持：** - 支持 CodeBuddy「登录模式」：未配置 API Key 时自动复用本机 codebuddy CLI 已登录凭据（走真实 AI，零配置）。 - 明确演示模式启动方式：仅当显式设 `WEBCHAT_DEMO=1` 时才返回模拟回复，默认走真实模型。 - 丰富认证相关说明，详细区分「Key 模式」「登录模式」与「演示模式」的使用场景与启动流程。 - 明确后端自检、认证流程与安全边界，强调后端绝不代填或保存登录凭据。 - 技术细节补充和文档完善，无功能变动。 - 移除 skill-card.md，保持结构简洁。","fileCount":3,"zipByteSize":7629},{"version":"0.1.2","createdAt":"2026-07-16T01:34:13.106Z","changelog":"webchat-extension 0.1.2 - 移除示例文件 skill-card.md，精简 skill 目录结构。 - 其余功能与核心文档保持一致，无用户侧变更。","fileCount":3,"zipByteSize":6739},{"version":"0.1.1","createdAt":"2026-07-15T02:44:13.396Z","changelog":"**webchat-extension 0.1.1 — 目录结构与发布流程增强** - 重新组织并详细说明文件与脚本布局，引入独立 `pack.mjs`（分享包生成）、`gen-icons.mjs`（零依赖图标生成）、`scripts/gen-vbs.mjs` 和 `scripts/register-protocol.cjs`（协议注册/修复）。 - 明确 “唯一 source of truth” 原则，强调生产目录与部署产物分离，避免多人维护“双形态”目录引歧义。 - 移除 `skill-card.md`，提升 SKILL.md 为全部说明入口，新增“发布分享包”方法与部分关键坑补充。 - 补充 Windows 下 `backend/launcher.vbs` 由部署脚本生成、绝不进 git/分享包，故障时一键补齐方法。 - 进一步细化 `webchat://` 协议修复流程。","fileCount":3,"zipByteSize":6690},{"version":"0.1.0","createdAt":"2026-07-10T02:11:19.213Z","changelog":"webchat-extension 0.1.0 - 首发发布，提供网页划线（选中文字）后，与 AI 对话的浏览器扩展及本地后端。 - 支持 Chrome MV3 及各类 Chromium 内核浏览器（Chrome、Edge、千问、夸克等）。 - 后端基于 CodeBuddy Agent SDK，通过 Express + SSE 提供流式对话。 - 一键式脚手架部署，含工具自动生成必需图标和注册协议（Windows 支持免终端一键启动）。 - 自动读取网页上下文、剪贴板内容，支持上下文持久化和对话历史保存。 - 提供详细部署、常见问题及故障排查指南。","fileCount":3,"zipByteSize":5509}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s176ns2k88htgg2h6v9myyxg7x83q8k1:webchat-extension","setupComplexity":"low","setupSteps":["Install using `clawhub skill install s176ns2k88htgg2h6v9myyxg7x83q8k1:webchat-extension` in an isolated environment before connecting it to live workloads.","No published capability contract is available yet, so validate auth and request/response behavior manually.","Review the upstream CLAWHUB listing at https://clawhub.ai/noaheleven/webchat-extension before using production credentials."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-noaheleven-webchat-extension/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-noaheleven-webchat-extension/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-noaheleven-webchat-extension/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-noaheleven-webchat-extension/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-noaheleven-webchat-extension/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-noaheleven-webchat-extension/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-11T21:52:12.277Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-noaheleven-webchat-extension/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-noaheleven-webchat-extension/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-noaheleven-webchat-extension/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-noaheleven-webchat-extension/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T18:50:44.017Z","emptyReason":null},"readme":"Skill: webchat-extension\n\nOwner: noaheleven\n\nSummary: 部署「网页划线对话」浏览器扩展（Chrome MV3 / 兼容 Chrome·Edge·千问·夸克 等 Chromium 内核浏览器）。在任意网页选中文字，点工具栏图标唤起可拖动对话浮层，带着网页上下文用 CodeBuddy AI 流式问答。包含本地 Express + SSE 后端（CodeBuddy Agent SDK）与前端扩展。当用户要「做一个网页划词对话插件 / 给浏览器装个网页对话工具 / 选中文字问 AI / 部署小虾网页对话扩展 / web highlight chat extension / 把网页内容丢给 AI 聊」时使用本技能。\n\nTags: latest:0.1.5\n\nVersion history:\n\nv0.1.5 | 2026-08-07T06:54:40.332Z | user\n\n本地最新版原样同步\n\nv0.1.4 | 2026-08-07T06:44:07.021Z | user\n\n本地最新版原样同步\n\nv0.1.3 | 2026-07-16T04:41:01.443Z | auto\n\n**CodeBuddy认证与后端演示模式支持：**\n- 支持 CodeBuddy「登录模式」：未配置 API Key 时自动复用本机 codebuddy CLI 已登录凭据（走真实 AI，零配置）。\n- 明确演示模式启动方式：仅当显式设 `WEBCHAT_DEMO=1` 时才返回模拟回复，默认走真实模型。\n- 丰富认证相关说明，详细区分「Key 模式」「登录模式」与「演示模式」的使用场景与启动流程。\n- 明确后端自检、认证流程与安全边界，强调后端绝不代填或保存登录凭据。\n- 技术细节补充和文档完善，无功能变动。  \n- 移除 skill-card.md，保持结构简洁。\n\nv0.1.2 | 2026-07-16T01:34:13.106Z | auto\n\nwebchat-extension 0.1.2\n\n- 移除示例文件 skill-card.md，精简 skill 目录结构。\n- 其余功能与核心文档保持一致，无用户侧变更。\n\nv0.1.1 | 2026-07-15T02:44:13.396Z | auto\n\n**webchat-extension 0.1.1 — 目录结构与发布流程增强**\n\n- 重新组织并详细说明文件与脚本布局，引入独立 `pack.mjs`（分享包生成）、`gen-icons.mjs`（零依赖图标生成）、`scripts/gen-vbs.mjs` 和 `scripts/register-protocol.cjs`（协议注册/修复）。\n- 明确 “唯一 source of truth” 原则，强调生产目录与部署产物分离，避免多人维护“双形态”目录引歧义。\n- 移除 `skill-card.md`，提升 SKILL.md 为全部说明入口，新增“发布分享包”方法与部分关键坑补充。\n- 补充 Windows 下 `backend/launcher.vbs` 由部署脚本生成、绝不进 git/分享包，故障时一键补齐方法。\n- 进一步细化 `webchat://` 协议修复流程。\n\nv0.1.0 | 2026-07-10T02:11:19.213Z | auto\n\nwebchat-extension 0.1.0\n\n- 首发发布，提供网页划线（选中文字）后，与 AI 对话的浏览器扩展及本地后端。\n- 支持 Chrome MV3 及各类 Chromium 内核浏览器（Chrome、Edge、千问、夸克等）。\n- 后端基于 CodeBuddy Agent SDK，通过 Express + SSE 提供流式对话。\n- 一键式脚手架部署，含工具自动生成必需图标和注册协议（Windows 支持免终端一键启动）。\n- 自动读取网页上下文、剪贴板内容，支持上下文持久化和对话历史保存。\n- 提供详细部署、常见问题及故障排查指南。\n\nArchive index:\n\nArchive v0.1.5: 26 files, 82570 bytes\n\nFiles: assets/backend/launcher.mjs (3081b), assets/backend/package-lock.json (57090b), assets/backend/package.json (461b), assets/backend/patch-sdk.mjs (1701b), assets/backend/server.js (22537b), assets/extension/background.js (3224b), assets/extension/content.js (7247b), assets/extension/icons/icon128.png (2436b), assets/extension/icons/icon16.png (419b), assets/extension/icons/icon32.png (715b), assets/extension/icons/icon48.png (966b), assets/extension/manifest.json (1129b), assets/extension/panel.css (5252b), assets/extension/panel.html (1958b), assets/extension/panel.js (17053b), assets/root/README.md (14179b), assets/root/webchat-protocol.reg.example (1156b), gen-icons.mjs (2525b), pack.mjs (8627b), references/deploy-guide.md (8553b), scripts/deploy.mjs (9450b), scripts/gen-vbs.mjs (5512b), scripts/register-protocol.cjs (6836b), skill-card.md (2842b), SKILL.md (13494b), _meta.json (136b)\n\nFile v0.1.5:SKILL.md\n\n---\nname: webchat-extension\ndescription: 部署「网页划线对话」浏览器扩展（Chrome MV3 / 兼容 Chrome·Edge·千问·夸克 等 Chromium 内核浏览器）。在任意网页选中文字，点工具栏图标唤起可拖动对话浮层，带着网页上下文用 CodeBuddy AI 流式问答。包含本地 Express + SSE 后端（CodeBuddy Agent SDK）与前端扩展。当用户要「做一个网页划词对话插件 / 给浏览器装个网页对话工具 / 选中文字问 AI / 部署小虾网页对话扩展 / web highlight chat extension / 把网页内容丢给 AI 聊」时使用本技能。\n---\n\n# 网页划线对话 · 小虾 🦐\n\n一个浏览器扩展 + 本地 AI 后端：用户在任意网页**选中文字**或**复制文字**，点工具栏图标弹出对话浮层，带着网页上下文直接和 AI 流式对话。后端基于 **CodeBuddy Agent SDK**（官方 `@tencent-ai/codebuddy-code` CLI 做 transport）。\n\n## 什么时候用\n- 用户想要「在网页上选中一段文字，直接问 AI 这是什么 / 帮我总结 / 翻译 / 解释」。\n- 用户想把某个网页内容作为上下文和 AI 聊。\n- 用户要部署/打包一个浏览器划词对话工具。\n\n## 架构\n```\n浏览器扩展 (Chrome MV3)                本地后端 (Express + SSE)\n┌──────────────────────────┐          ┌────────────────────────────┐\n│ 点工具栏图标 → 浮层(iframe) │──fetch──▶│  /api/chat  (SSE 流式)      │\n│ content.js 注入网页          │          │  query() → codebuddy CLI    │\n│ background.js service worker│          │  (CodeBuddy Agent SDK)      │\n│ 选区经 executeScript 跨 iframe│         │  buildSystemPrompt 注入网页上下文│\n└──────────────────────────┘          └────────────────────────────┘\n```\n- 前端只请求 `http://localhost:3000`，**API Key 只在后端**。\n- 面板状态（开关/位置/上下文/对话）用 `chrome.storage` 持久化，刷新不丢。\n\n## 文件布局（本 skill 内）\n```\nwebchat-extension/\n├── SKILL.md\n├── pack.mjs                  # 发布工具：在 deploy 产物(双形态目录)下 node pack.mjs → 生成干净分享包 zip\n├── gen-icons.mjs             # 独立图标生成（零依赖）：node gen-icons.mjs [dir]\n├── scripts/\n│   ├── deploy.mjs            # 脚手架：复制 assets 源码 + npm install + 生成 icons/（Windows 部署时生成 launcher.vbs + 注册协议）\n│   ├── gen-vbs.mjs           # 唯一 source of truth：写出 backend/launcher.vbs（agent 部署时调用，不随包分发）\n│   └── register-protocol.cjs # 一键注册/修复 webchat:// 协议（协议丢失或被识别成 Store 应用时用）\n├── assets/\n│   ├── extension/            # 浏览器扩展（manifest/background/content/panel.*/icons）\n│   ├── backend/              # server.js / launcher.mjs / patch-sdk.mjs / package.json / .env.example（launcher.vbs 由 agent 在部署时用 scripts/gen-vbs.mjs 生成，不随包分发）\n│   └── root/                 # 部署到目标根目录的文档：README.md（.gitignore / 协议模板不随包分发）\n└── references/deploy-guide.md  # 详细排错表\n```\n\n> **统一原则**：本 skill 是**唯一 source of truth**。运行环境一律由 `deploy.mjs` 生成（assets → 目标目录），不要在别处手维护一份带 `extension/ backend/` 的\"双形态\"目录，以免与 skill 不同步产生歧义。deploy 产物（目标目录）本身就是双形态目录（含 `extension/ backend/ SKILL.md pack.mjs gen-icons.mjs`），可直接加载运行，也可 `node pack.mjs` 生成分享包。\n\n## 部署步骤（agent 照做）\n1. **脚手架**：运行 `node <skill_dir>/scripts/deploy.mjs <targetDir>`（不加 `[targetDir]` 默认 `./webchat-extension` 或 `~/webchat-extension`）。脚本把 `assets/` 里的扩展、后端、根文档复制到目标目录并 `npm install`；**在 Windows 上，agent 会自动用 `scripts/gen-vbs.mjs` 生成 `backend/launcher.vbs`（即使带 `--no-protocol` 也会生成），并自动注册 `webchat://start` 协议**，使面板「🚀 启动后端」按钮免终端生效。`launcher.vbs` 是部署期产物，**绝不随分享包分发/上传**——若目标目录缺失它，可随时补：`node <skill_dir>/scripts/gen-vbs.mjs <target>/backend`。加 `--no-install` 只复制不装依赖；加 `--no-protocol` 跳过协议注册（但 vbs 仍会生成）。非 Windows 或需手动注册时，按 README「四、一键启动后端」用面板「📋 复制启动命令」手动 `npm start`，或参考 README/references 手动 `reg add` 注册协议。\n2. **配置后端**：在 `<target>/backend/` 复制 `.env.example` 为 `.env`，按需填 `CODEBUDDY_API_KEY`（**不填也能跑：复用本机 `codebuddy` CLI 已登录凭据走登录模式真实 AI**；只有显式设 `WEBCHAT_DEMO=1` 才进演示模式）。确认 `CODEBUDDY_MODEL=deepseek-v4-flash`（默认，该账户不支持 `claude-sonnet-4`）。\n3. **启动后端（后台运行）**：`cd <target>/backend && npm start`。监听 `http://localhost:3000`。改代码后重启才生效。也可用面板「🚀 启动后端」按钮（需协议已注册）。\n4. **加载扩展**：浏览器（Chrome / Edge / 千问 / 夸克 等 Chromium 内核）进入**开发者模式 → 加载已解压的扩展程序**，目录选 `<target>/extension/`。（`deploy` 已自动生成 `extension/icons` 四张图标；若手动加载项目根 `extension/`，请先跑 `node gen-icons.mjs`）改了扩展代码要回扩展管理页点「重新加载」。\n5. **验证**：访问 `http://localhost:3000/api/health` 应返回 `{\"status\":\"ok\",...}`；打开任意网页 → 点工具栏「🦐 小虾」图标 → 弹出面板 → 选中网页文字点「➕ 添加选中文本」→ 提问 → 流式回答。\n\n## 发布分享包（可选，给其他人用）\ndeploy 产物（目标目录）即为双形态目录，内含 `pack.mjs`。在其中运行：\n```bash\ncd <target>            # 例如 ~/webchat-extension\nnode pack.mjs         # 在父目录生成 webchat-extension-share-YYYYMMDD.zip\n```\n`pack.mjs` 自动按 `.gitignore` + 硬性黑名单排除：`node_modules/`、`.env`、私钥 `*.pem`、`extension.crx`、协议注册表模板、所有 `*.png`（图标由收件人部署时生成）。生成的 zip 即干净分享包，可直接发给他人或推送到仓库。\n\n## CodeBuddy 认证（登录 / API Key 二选一，零配置优先）\n后端 `server.js` 通过 CodeBuddy Agent SDK 调真实模型，认证方式参考 dingtalk-auto-reply 的「Key / CLI 已登录」范式：\n- **登录模式（默认，零配置）**：未配置 `CODEBUDDY_API_KEY` 时，SDK 自动复用本机 `codebuddy` CLI 已登录凭据（与你在终端 / WorkBuddy 登录的是同一套 `~/.codebuddy/local_storage`），无需任何 Key 即可走真实 AI。首次启动前请确保 `codebuddy` 已登录（终端跑一次 `codebuddy` 完成登录）。\n- **Key 模式（推荐无人值守）**：在 `backend/.env` 填 `CODEBUDDY_API_KEY=<你的key>`（申请：https://copilot.tencent.com 控制台）→ 用 Key 直连，不依赖交互登录。\n- **演示模式**：仅当显式设 `WEBCHAT_DEMO=1` 时强制进入（返回模拟回复验收交互）；否则无 Key 也走「登录模式」真实模型，**不再降级为 demo**。\n- `CODEBUDDY_INTERNET_ENVIRONMENT`：中国版自动设为 `internal`（已在 server.js 兜底），无需手动配。\n- 自检：`/api/health` 返回 `mode`（key｜login）、`demo`；`/api/auth` 用一次极短 query 实测登录态（15s 超时兜底，不卡死），失败回退到凭据目录存在性判断并给出明确修复提示。**后端绝不代填 / 存储登录凭据**——认证动作由你本人在终端完成。\n\n> ⚠️ **进程清理绝不误杀**：后端退出（`/api/stop`、空闲超时、托管心跳断、全局退出）时只清理「自己 spawn 出来的 codebuddy CLI 子进程」——按**进程树（本进程后代）+ CLI 路径精确匹配**，绝不按端口 `netstat` 乱扫（端口子串匹配会把 `45012` 误中 `450123`，且易误杀带看门狗、会被自动重拉的进程，如 dingtalk 监控）。即使某进程有看门狗会自愈，我们也连误杀都不做；另有「监听端口 + CLI 路径二次确认」兜底，确保外来进程永不被误杀。\n\n## 关键坑（务必先读，否则部署必踩）\n- **端口冲突导致一直转圈**：官方 CLI 启动会起 prewarm 本地 server，端口由 `SERVER__PORT` 控制。若该端口被本机其他程序（**WorkBuddy 桌面应用**）占用，CLI 会 `EADDRINUSE` 卡死。解决：`.env` 设 `SERVER__PORT=40123`（空闲端口）并重启。**面板「🚀 启动后端」按钮路径**下，`launcher.mjs` 会自动从 `.env` 读取 `SERVER__PORT` 并**显式注入**子进程环境，覆盖本机可能存在的系统级 `SERVER__PORT`（dotenv 不覆盖已存在变量，故必须靠 launcher 注入）；未设置时则不注入、由 `server.js` 自动分配空闲端口。若走 `npm start` 手动启动且系统变量残留旧值，用 `SERVER__PORT=40123 npm start` 显式覆盖。\n- **模型名 400**：本账户不支持 `claude-sonnet-4`。用 `deepseek-v4-flash`（默认）、`hy3` 或 `auto`。\n- **CLI 路径**：`server.js` 通过 `resolveCli()` 自动定位官方 CLI（优先级：显式 `CODEBUDDY_CLI_PATH` → PATH 上的 `codebuddy` → 受管 node 目录固定路径）。不要用 WorkBuddy 自带的那份 cli（协议不匹配会 initialize 超时）。\n- **演示 vs 真实**：未填 `CODEBUDDY_API_KEY` 时后端走「登录模式」复用 codebuddy CLI 已登录凭据，是**真实 AI**（不是模拟回复）；只有显式设 `WEBCHAT_DEMO=1` 才进演示模式（模拟回复用来验收交互闭环）。填了 Key 则走 Key 模式，也是真实 AI。\n- **扩展不注入系统页**：`chrome://`、`edge://` 等页面扩展无法注入，点图标无反应属正常。\n- **图标由 agent 部署时生成（分享包不含任何 *.png）**：`manifest.json` 声明了 `icons/icon{16,32,48,128}.png`，加载扩展前这 4 张必须存在，否则报 `Could not load icon` 加载失败。`deploy.mjs` 复制 extension 后会**自动生成**珊瑚橙 PNG（不依赖源图标）；手动从项目根加载（不跑 deploy）时，请先跑 `node gen-icons.mjs` 生成。想换正式品牌图标，部署后替换这 4 张 png 即可。\n- **launcher.vbs 由 agent 部署时生成（绝不随包分发/上传）**：`backend/launcher.vbs` 是 Windows 隐藏启动器，用于「🚀 启动后端」按钮免终端拉起 `launcher.mjs`。它**不进分享包、不进 git**（被 `pack.mjs` 与 `.gitignore` 排除），由 agent 在部署时经 `scripts/gen-vbs.mjs` 现生成。若某次部署后按钮失效 / 报「找不到 launcher.vbs」，直接重跑 `node scripts/gen-vbs.mjs <target>/backend`（或重新 `deploy.mjs`）即可，无需手动编辑 vbs 内容。\n- **微信读书等 iframe 阅读器**：选区由 `background.js` 用 `chrome.scripting.executeScript({allFrames:true})` 直插每一帧读取，能抓到；若阅读器是 sandboxed iframe（无 allow-scripts）且屏蔽 copy，则只能手动粘贴/输入到输入框再发送（发送会自动收进上下文）。\n- **webchat:// 协议被识别成 Microsoft Store 应用（弹\"获取打开此链接的应用\"）**：这是 `HKCU\\Software\\Classes\\webchat` 注册表项丢失/损坏导致，Windows 找不到处理程序就去 Store 找 UWP 应用了。修复：运行 `node scripts/register-protocol.cjs`（自动探测 `launcher.vbs` 位置并重新注册协议，支持 `--check` 仅检查、`--force` 强制重写）。注册指向的 `launcher.vbs` 由 agent 在部署时用 `scripts/gen-vbs.mjs` 在目标目录生成，若你迁移过项目目录，用 `WEBCHAT_DIR=新目录 node scripts/register-protocol.cjs --force` 重新指向（缺失则先 `node scripts/gen-vbs.mjs <新目录>/backend` 生成）。\n\n## 使用方式（交付给用户）\n- 任意网页 → 点工具栏「🦐 小虾」图标 → 右侧弹出对话面板（高约视口 2/3，可拖动，双击标题栏复位，位置自动记住）。\n- 喂上下文：选网页文字点「➕ 添加选中文本」（同时读选区 + 系统剪切板，含输入法复制）；或直接发送（自动收剪贴板/提问文本）。\n- 上下文只显示 10~20 字摘要 + …，不可编辑；多段累加，✕ 删除。\n- 输入框回车发送，AI 逐字流式回答，多轮保持上下文。\n\n## 验证清单\n- [ ] `http://localhost:3000/api/health` 返回 ok\n- [ ] 扩展已加载、未被禁用\n- [ ] 点图标弹出面板、可拖动不抖、不跳左上角\n- [ ] 选中文字 → 添加上下文 → 提问有流式回答\n- [ ] 刷新网页后面板自动重开、上下文/对话不丢\n- [ ] 真实 AI 模式（登录模式默认零配置 / 或填 Key）回答正常；`WEBCHAT_DEMO=1` 演示模式也能跑通闭环\n\n## 参考\n- 详细排错表见 `references/deploy-guide.md`。\n- 来源项目：本地 `webchat-extension/`（本 skill 由其封装，扩展版本 1.5.5；路径随各人工作区不同，无硬编码）。\n\nFile v0.1.5:assets/root/README.md\n\n# 网页划线对话 · 小虾 🦐\n\n> 📦 仓库地址：https://github.com/NoahEleven/webchat-extension\n\n一个 **Chrome / Edge / 千问 / 夸克 等 Chromium 内核浏览器** 扩展：在任意网页上**选中或复制文字**，点一下工具栏图标，就能带着这段网页上下文，直接和 AI 对话、流式得到回答。\n\n> 本质：复用 CodeBuddy Agent SDK 的 **Express + SSE 后端**，前端换成「浏览器扩展 + 网页划线交互」。\n\n---\n\n## 目录结构\n\n```\nwebchat-extension/\n├── README.md\n├── webchat-protocol.reg.example   # 仅仓库内模板，不随分享包分发（协议改由部署脚本自动注册）\n├── pack.mjs                       # 一键打包分享 zip（按 .gitignore 排除 node_modules/.env/私钥等）\n├── extension/                     # 浏览器扩展（Chrome MV3）\n│   ├── manifest.json\n│   ├── background.js              # service worker：图标点击→开关浮层；心跳 ping 后端\n│   ├── content.js                 # 注入网页：开/关浮层、读选区、状态持久化、触发协议\n│   ├── panel.html / panel.js / panel.css   # 对话浮层界面与逻辑\n│   └── icons/                     # 图标 icon16/32/48/128.png（分享包不含，由 deploy/gen-icons 自动生成）\n└── backend/                       # AI 后端（Express + CodeBuddy SDK + SSE）\n    ├── server.js                  # /api/chat(SSE) /api/health /api/heartbeat /api/stop\n    ├── launcher.mjs               # 协议触发：托管模式静默拉起 server.js\n    ├── launcher.vbs               # 隐藏窗口启动 launcher.mjs（由 agent 在部署时用 scripts/gen-vbs.mjs 生成，不随分享包分发）\n    ├── patch-sdk.mjs              # postinstall 自动给 SDK 注入 windowsHide，消除 Windows 黑框\n    ├── package.json / package-lock.json\n    └── .env.example               # 复制为 .env 后填写（含 API Key）\n```\n\n---\n\n## 前置依赖（重要）\n\n- **Node.js 18+**：后端是 Node 程序。\n- **codebuddy CLI（核心外部依赖，需收件人自备）**：后端通过 `@tencent-ai/agent-sdk` 在运行时 `spawn` 一个 `codebuddy` 子进程来真正调用 AI。`server.js` 的 `resolveCli()` 按以下顺序找它：\n  1. 环境变量 `CODEBUDDY_CLI_PATH` 显式指定；\n  2. 系统 `PATH` 上的 `codebuddy` 命令；\n  3. 兜底固定路径 `~/.workbuddy/binaries/node/versions/22.22.2/node_modules/@tencent-ai/codebuddy-code/bin/codebuddy`（**仅本机 WorkBuddy 托管环境才有**）。\n  - 本机因装了 WorkBuddy，托管 Node 已自带 `codebuddy`，所以开箱可用。\n  - **分享给别人的机器若没有 WorkBuddy**：需对方自行安装 CLI —— `npm i -g @tencent-ai/codebuddy-code`，并保证 `codebuddy` 在 `PATH` 上（或在 `.env` 设 `CODEBUDDY_CLI_PATH=绝对路径` 指向 CLI）。否则 `query()` 拉不起进程、后端连不上（登录模式和 Key 模式都依赖该 CLI）；此时仅 `WEBCHAT_DEMO=1` 演示模式可跑通交互闭环。\n\n---\n\n## 一、启动后端\n\n```bash\ncd backend\nnpm install\ncp .env.example .env        # 然后按需填写 CODEBUDDY_API_KEY\nnpm start                   # 默认监听 http://localhost:3000\n```\n\n启动后访问 `http://localhost:3000/api/health` 应返回 `{ \"status\": \"ok\", ... }`。\n\n### 三种模式\n| 模式 | 条件 | 表现 |\n|---|---|---|\n| **登录模式（默认，零配置）** | 没填 `CODEBUDDY_API_KEY` 且未设 `WEBCHAT_DEMO` | 复用本机 `codebuddy` CLI 已登录凭据，**真实 AI**（首次需在终端跑一次 `codebuddy` 完成登录） |\n| **Key 模式（推荐无人值守）** | 填了 `CODEBUDDY_API_KEY` | 用 Key 直连 CodeBuddy AI，不依赖交互登录，**真实 AI** |\n| **演示模式** | 显式设 `WEBCHAT_DEMO=1` | 后端返回模拟流式回复，用来验收「划线→对话」交互闭环（无需任何账号/登录） |\n\n---\n\n## 二、申请 CODEBUDDY_API_KEY（可选，无人值守场景才需要）\n\n> 默认**不填 Key 也是真实 AI**（登录模式，复用本机 `codebuddy` CLI 已登录凭据）。只有想脱离交互登录、无人值守直连时才需要配 Key。\n\n1. 打开 https://www.codebuddy.cn → 登录\n2. 进入「个人中心 / API 密钥」生成 Key\n3. 把 Key 填进 `backend/.env` 的 `CODEBUDDY_API_KEY=`\n4. 重启后端 `npm start`\n\n> 没 Key 也没关系——登录模式默认就是真实 AI；纯验收交互闭环可设 `WEBCHAT_DEMO=1` 进演示模式。\n\n---\n\n## 三、在浏览器加载扩展\n\n本扩展是标准 Chrome MV3，兼容一切 Chromium 内核浏览器（Chrome / Edge / 千问 / 夸克等）。**无法从 `.crx` 文件直接安装**（现代浏览器已禁止本地 `.crx` 安装），请用「加载已解压」方式：\n\n1. 浏览器进入 **扩展管理页 → 开启「开发者模式」**（`chrome://extensions` 或 `edge://extensions` 等）\n2. 点 **「加载已解压的扩展程序」**，目录选本项目的 `extension/`\n   - ⚠️ **分享包不含图标 png**：加载前请先生成图标——已跑过 `node scripts/deploy.mjs` 会自动生成；手动加载则先跑 `node gen-icons.mjs`。否则报 `Could not load icon` 加载失败。\n3. 加载成功后，图标出现在扩展栏\n4. **改了扩展代码后**，回扩展管理页点「重新加载」才能生效\n\n---\n\n## 四、一键启动后端（可选但推荐，免开终端）\n\n面板里的「🚀 启动后端」按钮靠自定义协议 `webchat://start` 自动拉起后端，需要**先注册一次协议处理器**。\n\n- **若由 agent 按本 skill 部署（推荐）**：运行 `node scripts/deploy.mjs` 会**自动注册协议**，并自动在 `backend/` 生成 `launcher.vbs` 隐藏启动器，开箱即用，无需手动操作（`launcher.vbs` 是部署期产物，绝不随分享包分发/上传；缺失时可单独 `node scripts/gen-vbs.mjs <backend目录>` 生成）。\n- **手动 / 分享给别人（无 WorkBuddy）**：\n  - **最省事**：跳过协议，面板点「📋 复制启动命令」→ 终端执行，或直接 `cd backend && npm start`。\n  - **想要协议按钮免终端**：手动注册（把下列命令里的路径改成你机器真实的 `backend` 路径）。注意命令指向 `launcher.mjs`，直接用 `node` 跑会有一个 cmd 窗口闪现；若要完全无黑框，先 `node scripts/gen-vbs.mjs <backend目录>` 生成 `launcher.vbs`（唯一 source of truth 见 `scripts/gen-vbs.mjs`，隐藏启动 `launcher.mjs`），再让命令指向该 `.vbs`：\n    ```bat\n    reg add \"HKCU\\Software\\Classes\\webchat\" /ve /t REG_SZ /d \"webchat Protocol\" /f\n    reg add \"HKCU\\Software\\Classes\\webchat\" /v \"URL Protocol\" /t REG_SZ /d \"\" /f\n    reg add \"HKCU\\Software\\Classes\\webchat\\shell\\open\\command\" /ve /t REG_SZ /d \"\\\"C:\\Windows\\System32\\wscript.exe\\\" \\\"C:\\你的路径\\webchat-extension\\backend\\launcher.mjs\\\" \\\"%1\\\"\" /f\n    ```\n\n注册后：点「🚀 启动后端」即可无感拉起（首次会问「是否允许打开 webchat 链接」，允许即可）。**后端生命周期由扩展心跳托管**：浏览器开着→后端存活；浏览器关→心跳断→约 2.5 分钟后后端自退，不常驻、无需手动停。想立即停可点面板「⏹ 停止后端」或访问 `POST /api/stop`。\n\n---\n\n## 五、怎么用\n\n1. 打开任意网页（新闻、文档、微信读书、千问等都行）\n2. **点工具栏上的「🦐 小虾」图标** → 右侧弹出对话面板（高约视口 2/3，自适应）\n3. **拖动浮层**：拖顶部标题栏移动面板（移出浮层也跟手、不抖）；**双击标题栏**复位到右上角。位置自动记住，刷新/换页后还在\n4. 喂上下文，任选：\n   - **选中网页文字** → 点 **「➕ 添加选中文本」**（同时读网页选区 + 系统剪切板：选区由 background 用 `chrome.scripting.executeScript(allFrames)` 直插每帧读取，**微信读书/千问等 iframe 阅读器也能抓到**；剪切板含输入法复制内容）\n   - **直接发送**：在输入框粘贴/输入并回车，发送时**自动把本次内容（剪贴板或提问文本）收进上下文**\n5. 上下文片段只显示 **10~20 字摘要 + …**（悬停看全文），不可直接编辑；多段累加，右侧 ✕ 单独删除\n6. 回车发送，AI 回答**逐字流式**显示，多轮保持上下文\n7. **状态持久化**：开关/位置/上下文/对话存 `chrome.storage`，刷新或换页后自动重开不丢（手动 ✕ 关闭后记住关闭状态）\n\n---\n\n## 六、分享给别人 / 打包\n\n**`backend/` 是必须的，必须一起打包。** 浏览器扩展只是「UI 外壳」——真正的 AI 能力（连接 CodeBuddy SDK、spawn `codebuddy` CLI、管理 API Key）全在后端。没有 `backend/`，扩展没有 AI 能力、连不上。**所以分享时 `extension/` + `backend/` 两个目录都要带。**\n\n- **不要**只发 `.crx`：现代 Chrome/Edge 禁止本地 `.crx` 安装，发了也装不上。\n- **正确做法**：把整个 `webchat-extension/` 文件夹发给对方 → 对方按上面步骤 `npm install` + 加载 `extension/` +（可选）注册协议。\n- **一键打包（推荐）**：在项目根目录执行 `node pack.mjs` → 自动按 `.gitignore` 在父目录生成干净的 `webchat-extension-share-YYYYMMDD.zip`。**打包出来是一个「二合一」目录 `webchat-extension/`**：\n  - `SKILL.md` 直接位于 `webchat-extension/` **根目录**（满足技能规范：SKILL.md 在根目录或一级目录）。\n  - 同时含 `extension/`、`backend/`（手动安装用）与 `scripts/`、`references/`、`assets/`（agent 技能用）。\n  - 给**不使用 WorkBuddy** 的收件人：用里面的 `extension/` + `backend/` 按上面步骤 `npm install` + 加载扩展即可。\n  - 给**用 WorkBuddy** 的收件人：把整个 `webchat-extension/` 文件夹复制到 `~/.workbuddy/skills/webchat-extension/`，agent 部署时自动注册协议、开箱即用。\n  - 脚本已自动排除 `node_modules/`、`.env`、私钥、`.crx`、`*.log`、`*.cjs`；保留 `.env.example` 模板与技能目录。\n- **⚠️ 收件人还需自备 codebuddy CLI**：本项目不随包分发该 CLI（见「前置依赖」一节）。对方机器若没有 WorkBuddy，需 `npm i -g @tencent-ai/codebuddy-code` 并确保在 `PATH` 上，否则后端连不上（仅 `WEBCHAT_DEMO=1` 演示模式可跑）。\n- **正式广分发**：上架 Chrome / Edge 应用商店，发商店链接。\n- **打包清单**\n  - ✅ 带：`SKILL.md`（技能入口，根目录）、`extension/`（**不含 icons png，加载前由 deploy / gen-icons 自动生成**）、`backend/` 源码（`server.js` `launcher.mjs` `patch-sdk.mjs` `package.json` `package-lock.json` `.env.example`）、`scripts/`（部署脚手架，含内联生成 launcher.vbs + 图标生成）、`references/`（排错表）、`assets/`（技能资源）、`README.md`、`gen-icons.mjs`\n  - ❌ 不带：`backend/node_modules/`（让收件人 `npm install` 即可）、`backend/.env`（含真实 Key）、`extension.pem`/`extension.crx`、**`*.png`（图标不进包，由 agent 部署时生成）**、`*.log`、`*.cjs` 测试草稿、**`launcher.vbs` / `webchat-protocol.reg.example` / `.gitignore`（不随分享包分发；launcher.vbs 由部署脚本自动生成、协议由部署自动注册）**\n  - 这些由打包脚本按 `.gitignore` + 硬性禁止列表排除，打包前确认没混进去。\n\n---\n\n## 七、已知限制 / 注意\n\n- **后端必须本地运行**：插件通过 `http://localhost:3000` 调后端。关掉后端，对话连不上（面板提示连接失败）。\n- **跨域**：后端已开 `CORS *`，开发期够用。上线公网需改具体来源并部署后端。\n- **side_panel**：本方案用「网页内注入浮层（iframe）」而非浏览器侧边栏，兼容性最好。\n- **API Key 安全**：Key 只放后端 `.env`，**绝不进前端**。\n- **真实 AI 能力**：来自 CodeBuddy Agent SDK，模型默认 `deepseek-v4-flash`，可在 `.env` 用 `CODEBUDDY_MODEL=` 改（`auto`/`hy3`/`glm-5.2`/`kimi-k2.x`/`deepseek-v4-*` 等，本账户不支持 `claude-sonnet-4`）。\n\n---\n\n## 八、出问题怎么办\n\n| 现象 | 排查 |\n|---|---|\n| 面板提示「连接后端失败」 | 确认 `cd backend && npm start` 已启动；端口是 3000 |\n| 点「🚀 启动后端」没反应 | 多半是 `webchat://` 协议未注册（见第四节）。可改用面板「📋 复制启动命令」手动 `npm start` |\n| 点图标没反应 | 多见于 `chrome://`、`edge://` 等系统页（扩展无法注入）；普通网页正常。确认扩展已加载且未被禁用 |\n| 选中文字点「添加选中文本」没反应 | 选区读取走 `chrome.scripting.executeScript(allFrames)`，正常能抓 iframe 阅读器；若阅读器是 **sandboxed iframe（无 allow-scripts）** 且屏蔽 copy，则只能手动粘贴/输入发送（发送会自动收上下文）。平台限制非 bug |\n| 收到的是演示（模拟）回复而非真实 AI | 说明设了 `WEBCHAT_DEMO=1`。删掉该变量重启即走登录模式真实 AI；若登录态失效，终端跑一次 `codebuddy` 重新登录，或在 `.env` 填 `CODEBUDDY_API_KEY` 走 Key 模式 |\n| `/api/health` 返回 `demo:true` | 说明设了 `WEBCHAT_DEMO=1`（演示模式）。想要真实 AI 请移除该变量（默认登录模式）或填 Key |\n| **真实模式一直转圈、无回答**（后端日志 `EADDRINUSE` / CLI 卡死） | 官方 CLI 的 prewarm 端口和本机 WorkBuddy 桌面应用撞车。在 `.env` 设 `SERVER__PORT=40123`（或空闲端口）并重启；若环境变量残留旧 `SERVER__PORT`，启动时用 `SERVER__PORT=40123 npm start` 显式覆盖 |\n| 后端报 `400 model [...] service info not found` | 模型名不对，把 `CODEBUDDY_MODEL` 改成 `deepseek-v4-flash`、`hy3` 或 `auto` |\n| **Windows 上每次对话 / 启动后端都弹黑框** | SDK 内部 spawn CLI 默认 `windowsHide:false`。后端 `package.json` 已加 `postinstall` 自动跑 `patch-sdk.mjs` 给 SDK 注入 `windowsHide:true`；`npm install` 后自然生效。若重装后仍弹，手动跑一次 `node backend/patch-sdk.mjs` |\n\nFile v0.1.5:_meta.json\n\n{\n  \"ownerId\": \"kn769gn5we5rgv7bfhb9ztd8j983p8qc\",\n  \"slug\": \"webchat-extension\",\n  \"version\": \"0.1.5\",\n  \"publishedAt\": 1786085680332\n}\n\nFile v0.1.5:references/deploy-guide.md\n\n# 网页划线对话 · 部署与排错指南\n\n本文件是 skill 的详细排错表，配合 `SKILL.md` 使用。扩展版本 1.5.5。\n\n## 〇、前置依赖：codebuddy CLI（外部依赖，不随包分发）\n\n后端通过 `@tencent-ai/agent-sdk` 在运行时 `spawn` 一个 `codebuddy` 子进程来真正调用 AI。`server.js` 的 `resolveCli()` 按序找它：① `CODEBUDDY_CLI_PATH` 显式指定 → ② 系统 `PATH` 上的 `codebuddy` → ③ 兜底 `~/.workbuddy/binaries/node/versions/22.22.2/node_modules/@tencent-ai/codebuddy-code/bin/codebuddy`（仅本机 WorkBuddy 托管环境有）。\n\n- **本机**（装了 WorkBuddy）：托管 Node 已自带 `codebuddy`，开箱可用。\n- **分享给别人的机器若没有 WorkBuddy**：需对方 `npm i -g @tencent-ai/codebuddy-code` 并确保 `codebuddy` 在 `PATH`，或在 `.env` 设 `CODEBUDDY_CLI_PATH` 指向 CLI。否则 `query()` 拉不起进程 → 后端连不上（登录/Key 模式都依赖该 CLI）；仅 `WEBCHAT_DEMO=1` 演示模式可跑通交互闭环。\n\n> 注意：`backend/` 目录**必须随扩展一起分享**——扩展只是 UI 外壳，AI 能力全在后端。\n\n## 一、后端启动与模式\n\n| 步骤 | 命令 | 说明 |\n|---|---|---|\n| 进入后端 | `cd <target>/backend` | — |\n| 安装依赖 | `npm install` | 仅首次；用受管 node 即可 |\n| 复制配置 | `cp .env.example .env` | 按需填 `CODEBUDDY_API_KEY` |\n| 启动 | `npm start` | 默认 `http://localhost:3000` |\n| 健康检查 | `curl http://localhost:3000/api/health` | 返回 `{\"status\":\"ok\",...}` |\n\n**三种模式**\n- 登录模式（默认，零配置）：未填 `CODEBUDDY_API_KEY` 且未设 `WEBCHAT_DEMO`，复用本机 `codebuddy` CLI 已登录凭据走**真实 AI**（首次需终端跑一次 `codebuddy` 登录）。\n- Key 模式（推荐无人值守）：填了 `CODEBUDDY_API_KEY`，用 Key 直连 CodeBuddy AI，不依赖交互登录。\n- 演示模式：显式设 `WEBCHAT_DEMO=1`，后端返回模拟流式回复，验收交互闭环用，无需账号/登录。\n\n---\n\n## 二、现象 → 排查\n\n| 现象 | 原因 / 排查 |\n|---|---|\n| 面板提示「连接后端失败」 | 确认 `cd backend && npm start` 已启动；端口 3000 |\n| 点「🚀 启动后端」没反应 | 多半是 `webchat://` 协议未注册（见第四节）。可改用面板「📋 复制启动命令」手动 `npm start` |\n| 点图标没反应 | 多见于 `chrome://`、`edge://` 等系统页（扩展无法注入）；普通网页正常。确认扩展已加载且未被禁用 |\n| 选中文字点「添加选中文本」没反应 | 选区由 `chrome.scripting.executeScript(allFrames)` 读取，正常能抓微信读书/千问 iframe。若阅读器是 **sandboxed iframe（无 allow-scripts）** 或屏蔽 copy，则只能手动粘贴/输入到输入框发送（发送自动收上下文）。属平台限制非 bug |\n| 收到的是演示（模拟）回复 | 说明设了 `WEBCHAT_DEMO=1`。删掉它重启即走登录模式真实 AI；登录态失效则终端跑一次 `codebuddy` 重登，或 `.env` 填 `CODEBUDDY_API_KEY` 走 Key 模式 |\n| `/api/health` 返回 `demo:true` | 说明设了 `WEBCHAT_DEMO=1`（演示模式）；移除该变量走默认登录模式真实 AI，或填 Key |\n| **真实模式一直转圈、面板无回答**（后端日志 `EADDRINUSE` / CLI 卡死） | 官方 CLI 的 prewarm 端口与 WorkBuddy 桌面应用撞车。在 `.env` 设 `SERVER__PORT=40123`（或空闲端口）并重启；若环境变量残留旧 `SERVER__PORT`，启动时用 `SERVER__PORT=40123 npm start` 显式覆盖 |\n| 后端报 `400 model [...] service info not found` | 模型名不对，把 `CODEBUDDY_MODEL` 改成 `deepseek-v4-flash`、`hy3` 或 `auto`（本账户不支持 `claude-sonnet-4`） |\n| 后端报 `initialize` 超时 / 永远 0 字节 | 用了 WorkBuddy 自带那份 cli（协议不匹配）。必须用官方 `@tencent-ai/codebuddy-code`；`server.js` 的 `resolveCli()` 已自动定位，必要时用 `CODEBUDDY_CLI_PATH` 显式指定 |\n| 拖拽抖动 / 跳左上角 | 扩展 V1.5.2 已修复拖拽坐标公式；若仍异常，扩展管理页「重新加载」并确认 manifest 版本 ≥ 1.5.2 |\n| **Windows 上每次对话 / 启动后端弹黑框** | SDK 内部 spawn CLI 默认 `windowsHide:false`。`package.json` 的 `postinstall` 会自动跑 `patch-sdk.mjs` 给 `@tencent-ai/agent-sdk` 的 `process-transport.js` 两处 spawn 注入 `windowsHide:true`；`npm install` 后即生效。若依赖是手动装、跳过了 postinstall，运行一次 `node backend/patch-sdk.mjs` 即可 |\n\n---\n\n## 三、端口冲突根因说明\n\n官方 `@tencent-ai/codebuddy-code` 启动时会起一个 prewarm 本地 server，端口由 `SERVER__PORT` 环境变量控制。本机 **WorkBuddy 桌面应用自身也会起同类 server 占端口**（实测占 54975 之类），两者撞车 → CLI 一绑定就 `EADDRINUSE` → SDK `query()` 永远 0 字节超时。\n\n- `server.js` 启动时会自动分配空闲端口注入 `SERVER__PORT`（兜底）。\n- 若自动分配仍冲突（极少见），在 `.env` 显式 `SERVER__PORT=40123` 并重启。\n- dotenv **不会覆盖已存在的环境变量**，所以如果当前 shell 里残留 `SERVER__PORT=旧值`，必须用 `SERVER__PORT=40123 npm start` 显式传，或在新 shell 里启动。\n\n---\n\n## 四、一键启动（webchat:// 协议注册）\n\n面板「🚀 启动后端」按钮（以及离线横幅里的启动按钮）靠自定义协议 `webchat://start` 免终端拉起后端。这要求 **Windows 已注册协议处理器**（让系统知道遇到 `webchat://` 就调用 `launcher.vbs`）。\n\n- **由 agent 按 skill 部署**：`node scripts/deploy.mjs` 在 Windows 上自动写入注册表（HKCU，无需管理员），开箱即用。非 Windows 或加了 `--no-protocol` 时跳过。\n- **手动 / 分享给别人**：二选一\n  1. 把 `webchat-protocol.reg.example` 里的 `__BACKEND_DIR__` 替换为真实 `backend` 绝对路径（反斜杠写成 `\\\\`），存为 `webchat-protocol.reg` 双击导入；\n  2. 或命令行：`reg add \"HKCU\\Software\\Classes\\webchat\\shell\\open\\command\" /ve /t REG_SZ /d \"\\\"C:\\Windows\\System32\\wscript.exe\\\" \\\"<backend路径>\\launcher.vbs\\\" \\\"%1\\\"\" /f`（并建好 `webchat` 主键与 `URL Protocol` 值，详见 .reg.example 头部注释）。\n- **注册内容**：`HKCU\\Software\\Classes\\webchat`（`URL Protocol=\"\"`）+ `shell\\open\\command` → `\"C:\\Windows\\System32\\wscript.exe\" \"<backend>\\launcher.vbs\" \"%1\"`。\n- **未注册时**：按钮点了没反应，但可用面板「📋 复制启动命令」手动 `npm start`，功能不受影响。\n\n---\n\n## 五、后端生命周期（心跳托管）\n\n后端由 `webchat://start` 协议（面板按钮）经 `launcher.vbs → launcher.mjs` 拉起。`launcher.mjs` 探测端口，未占用则以**托管模式**（`WEBCHAT_MANAGED=1`）用 `spawn(detached)` 拉起 `server.js`，随后自身退出——**后端作为独立进程运行，不与启动器绑定**。\n\n生命周期完全由「扩展心跳」驱动，**不依赖任何浏览器进程名**，因此 Chrome / Edge / 千问 / 夸克 / 任意 Chromium 内核通用：\n\n- `background.js` 用 `chrome.alarms`（约每 60s）POST `/api/heartbeat` 续命，`server.js` 记录 `lastHeartbeat`。\n- `server.js` 的看门狗每 5s 检查：若 `Date.now() - lastHeartbeat > HEARTBEAT_TTL` 则 `process.exit(0)` 自退。\n- 浏览器开着 → 心跳不断 → 后端存活；浏览器关闭 → service worker 被回收、alarms 停 → 心跳断 → 约 `HEARTBEAT_TTL`（默认 2.5min，覆盖 SW 闹钟节流）后后端自退。\n- 另有「无请求自退」兜底：连续 `IDLE_TIMEOUT_MIN`（默认 30min）无任何请求，后端自退。\n\n**想立即停**：面板「⏹ 停止后端」按钮（`POST /api/stop`）或 `curl -X POST http://localhost:3000/api/stop`。\n\n**可调项（`.env`）**\n- `HEARTBEAT_TTL`（毫秒，默认 150000）：心跳宽限，浏览器关后多久自退。\n- `IDLE_TIMEOUT_MIN`（分钟，默认 30）：空闲自退时长。\n- ⚠️ 旧的 `WEBCHAT_BROWSER_PROCS` 配置**已废弃**，心跳机制不再读取它，无需设置。\n\n---\n\n## 六、安全须知\n\n- API Key 只放后端 `.env`，**绝不进前端**。\n- 跨域：后端 `CORS *` 开发期够用；公网部署需改成具体来源。\n- 后端必须本地运行；关掉后端对话连不上（面板提示连接失败）。\n- 分享包不要带：`extension.pem`（签名私钥）、`extension.crx`、`backend/.env`（Key）、`*.log`、测试草稿 `*.cjs`（已在 `.gitignore` 忽略）。\n\nFile v0.1.5:skill-card.md\n\n## Description:\n\nDeploys a Chromium browser extension and local Express/SSE backend that let users select or copy webpage text and stream contextual answers from CodeBuddy AI.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[noaheleven](https://clawhub.ai/user/noaheleven)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and agents use this skill to deploy, configure, and package a browser-based webpage chat assistant. The deployed extension helps users carry selected or copied webpage context into CodeBuddy AI conversations.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can read and persist selected or copied webpage and clipboard text, which may include sensitive data.\n\nMitigation: Require explicit user confirmation before adding clipboard content, avoid use on sensitive pages, and review stored conversation/context data before sharing or packaging.\n\nRisk: The local AI backend uses local CodeBuddy login or API-key credentials and was flagged as lacking sufficient access control.\n\nMitigation: Bind the backend to loopback only, add backend authentication, keep API keys only in local environment files, and exclude credentials from release archives.\n\nRisk: The backend CORS and browser-panel message handling may allow unintended local access if left broad.\n\nMitigation: Restrict CORS to expected extension origins, check message sources, and keep browser permissions scoped to the extension workflow.\n\nRisk: The release depends on a local CodeBuddy CLI, a Windows protocol handler, and npm dependencies that must be trusted and current.\n\nMitigation: Install dependencies from trusted sources, update dependency versions before sensitive use, review protocol-handler registration, and verify the generated launcher path.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/noaheleven/skills/webchat-extension)\n- [Publisher profile](https://clawhub.ai/user/noaheleven)\n- [Deployment and troubleshooting guide](references/deploy-guide.md)\n- [CodeBuddy](https://www.codebuddy.cn)\n- [CodeBuddy API console](https://copilot.tencent.com)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Code, Shell commands, Configuration, Guidance]\n\n**Output Format:** [Markdown guidance with shell commands and generated project files]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Produces deployment instructions and file-generation steps for a Chromium extension and local Node.js backend.]\n\n## Skill Version(s):\n\n0.1.5 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v0.1.5:assets/backend/package-lock.json\n\n{\n  \"name\": \"webchat-backend\",\n  \"version\": \"1.0.0\",\n  \"lockfileVersion\": 3,\n  \"requires\": true,\n  \"packages\": {\n    \"\": {\n      \"name\": \"webchat-backend\",\n      \"version\": \"1.0.0\",\n      \"dependencies\": {\n        \"@tencent-ai/agent-sdk\": \"^0.3.43\",\n        \"cors\": \"^2.8.5\",\n        \"dotenv\": \"^16.4.5\",\n        \"express\": \"^4.18.2\"\n      }\n    },\n    \"node_modules/@agentclientprotocol/sdk\": {\n      \"version\": \"0.25.1\",\n      \"resolved\": \"https://registry.npmjs.org/@agentclientprotocol/sdk/-/sdk-0.25.1.tgz\",\n      \"integrity\": \"sha512-jx2rF3bdpGwZ75Q/meyEDLLbYmbtxk82Uh9hDCdxDvcEedBnNSF5hZAnL/kJR5VNz56JqwOmqnAqasC84MwwkQ==\",\n      \"license\": \"Apache-2.0\",\n      \"peerDependencies\": {\n        \"zod\": \"^3.25.0 || ^4.0.0\"\n      }\n    },\n    \"node_modules/@hono/node-server\": {\n      \"version\": \"1.19.14\",\n      \"resolved\": \"https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.14.tgz\",\n      \"integrity\": \"sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=18.14.1\"\n      },\n      \"peerDependencies\": {\n        \"hono\": \"^4\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk\": {\n      \"version\": \"1.29.0\",\n      \"resolved\": \"https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.29.0.tgz\",\n      \"integrity\": \"sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"@hono/node-server\": \"^1.19.9\",\n        \"ajv\": \"^8.17.1\",\n        \"ajv-formats\": \"^3.0.1\",\n        \"content-type\": \"^1.0.5\",\n        \"cors\": \"^2.8.5\",\n        \"cross-spawn\": \"^7.0.5\",\n        \"eventsource\": \"^3.0.2\",\n        \"eventsource-parser\": \"^3.0.0\",\n        \"express\": \"^5.2.1\",\n        \"express-rate-limit\": \"^8.2.1\",\n        \"hono\": \"^4.11.4\",\n        \"jose\": \"^6.1.3\",\n        \"json-schema-typed\": \"^8.0.2\",\n        \"pkce-challenge\": \"^5.0.0\",\n        \"raw-body\": \"^3.0.0\",\n        \"zod\": \"^3.25 || ^4.0\",\n        \"zod-to-json-schema\": \"^3.25.1\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"peerDependencies\": {\n        \"@cfworker/json-schema\": \"^4.1.1\",\n        \"zod\": \"^3.25 || ^4.0\"\n      },\n      \"peerDependenciesMeta\": {\n        \"@cfworker/json-schema\": {\n          \"optional\": true\n        },\n        \"zod\": {\n          \"optional\": false\n        }\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/accepts\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz\",\n      \"integrity\": \"sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"mime-types\": \"^3.0.0\",\n        \"negotiator\": \"^1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/body-parser\": {\n      \"version\": \"2.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz\",\n      \"integrity\": \"sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"bytes\": \"^3.1.2\",\n        \"content-type\": \"^2.0.0\",\n        \"debug\": \"^4.4.3\",\n        \"http-errors\": \"^2.0.1\",\n        \"iconv-lite\": \"^0.7.2\",\n        \"on-finished\": \"^2.4.1\",\n        \"qs\": \"^6.15.2\",\n        \"raw-body\": \"^3.0.2\",\n        \"type-is\": \"^2.1.0\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/node_modules/content-type\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz\",\n      \"integrity\": \"sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/content-disposition\": {\n      \"version\": \"1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz\",\n      \"integrity\": \"sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/cookie-signature\": {\n      \"version\": \"1.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz\",\n      \"integrity\": \"sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=6.6.0\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/debug\": {\n      \"version\": \"4.4.3\",\n      \"resolved\": \"https://registry.npmjs.org/debug/-/debug-4.4.3.tgz\",\n      \"integrity\": \"sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"ms\": \"^2.1.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6.0\"\n      },\n      \"peerDependenciesMeta\": {\n        \"supports-color\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/express\": {\n      \"version\": \"5.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/express/-/express-5.2.1.tgz\",\n      \"integrity\": \"sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"accepts\": \"^2.0.0\",\n        \"body-parser\": \"^2.2.1\",\n        \"content-disposition\": \"^1.0.0\",\n        \"content-type\": \"^1.0.5\",\n        \"cookie\": \"^0.7.1\",\n        \"cookie-signature\": \"^1.2.1\",\n        \"debug\": \"^4.4.0\",\n        \"depd\": \"^2.0.0\",\n        \"encodeurl\": \"^2.0.0\",\n        \"escape-html\": \"^1.0.3\",\n        \"etag\": \"^1.8.1\",\n        \"finalhandler\": \"^2.1.0\",\n        \"fresh\": \"^2.0.0\",\n        \"http-errors\": \"^2.0.0\",\n        \"merge-descriptors\": \"^2.0.0\",\n        \"mime-types\": \"^3.0.0\",\n        \"on-finished\": \"^2.4.1\",\n        \"once\": \"^1.4.0\",\n        \"parseurl\": \"^1.3.3\",\n        \"proxy-addr\": \"^2.0.7\",\n        \"qs\": \"^6.14.0\",\n        \"range-parser\": \"^1.2.1\",\n        \"router\": \"^2.2.0\",\n        \"send\": \"^1.1.0\",\n        \"serve-static\": \"^2.2.0\",\n        \"statuses\": \"^2.0.1\",\n        \"type-is\": \"^2.0.1\",\n        \"vary\": \"^1.1.2\"\n      },\n      \"engines\": {\n        \"node\": \">= 18\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/finalhandler\": {\n      \"version\": \"2.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz\",\n      \"integrity\": \"sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"debug\": \"^4.4.0\",\n        \"encodeurl\": \"^2.0.0\",\n        \"escape-html\": \"^1.0.3\",\n        \"on-finished\": \"^2.4.1\",\n        \"parseurl\": \"^1.3.3\",\n        \"statuses\": \"^2.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">= 18.0.0\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/fresh\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz\",\n      \"integrity\": \"sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.8\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/iconv-lite\": {\n      \"version\": \"0.7.3\",\n      \"resolved\": \"https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz\",\n      \"integrity\": \"sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"safer-buffer\": \">= 2.1.2 < 3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/media-typer\": {\n      \"version\": \"1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz\",\n      \"integrity\": \"sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.8\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/merge-descriptors\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz\",\n      \"integrity\": \"sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/mime-db\": {\n      \"version\": \"1.54.0\",\n      \"resolved\": \"https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz\",\n      \"integrity\": \"sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/mime-types\": {\n      \"version\": \"3.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz\",\n      \"integrity\": \"sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"mime-db\": \"^1.54.0\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/ms\": {\n      \"version\": \"2.1.3\",\n      \"resolved\": \"https://registry.npmjs.org/ms/-/ms-2.1.3.tgz\",\n      \"integrity\": \"sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/negotiator\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz\",\n      \"integrity\": \"sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/send\": {\n      \"version\": \"1.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/send/-/send-1.2.1.tgz\",\n      \"integrity\": \"sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"debug\": \"^4.4.3\",\n        \"encodeurl\": \"^2.0.0\",\n        \"escape-html\": \"^1.0.3\",\n        \"etag\": \"^1.8.1\",\n        \"fresh\": \"^2.0.0\",\n        \"http-errors\": \"^2.0.1\",\n        \"mime-types\": \"^3.0.2\",\n        \"ms\": \"^2.1.3\",\n        \"on-finished\": \"^2.4.1\",\n        \"range-parser\": \"^1.2.1\",\n        \"statuses\": \"^2.0.2\"\n      },\n      \"engines\": {\n        \"node\": \">= 18\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/serve-static\": {\n      \"version\": \"2.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz\",\n      \"integrity\": \"sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"encodeurl\": \"^2.0.0\",\n        \"escape-html\": \"^1.0.3\",\n        \"parseurl\": \"^1.3.3\",\n        \"send\": \"^1.2.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 18\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/type-is\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz\",\n      \"integrity\": \"sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"content-type\": \"^2.0.0\",\n        \"media-typer\": \"^1.1.0\",\n        \"mime-types\": \"^3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 18\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/type-is/node_modules/content-type\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz\",\n      \"integrity\": \"sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/@tencent-ai/agent-sdk\": {\n      \"version\": \"0.3.202\",\n      \"resolved\": \"https://registry.npmjs.org/@tencent-ai/agent-sdk/-/agent-sdk-0.3.202.tgz\",\n      \"integrity\": \"sha512-hZ9/ymDTv3RmuualZeDZ64wPQwEJXidfqEofeNaKcWhTsuzxN6quc3yeVFdsZudDnSinA6Sm+tUNWQipmFye2A==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"@agentclientprotocol/sdk\": \"^0.25.0\",\n        \"@modelcontextprotocol/sdk\": \"^1.29.0\"\n      },\n      \"peerDependencies\": {\n        \"zod\": \"^4.0.0\"\n      }\n    },\n    \"node_modules/accepts\": {\n      \"version\": \"1.3.8\",\n      \"resolved\": \"https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz\",\n      \"integrity\": \"sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"mime-types\": \"~2.1.34\",\n        \"negotiator\": \"0.6.3\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/ajv\": {\n      \"version\": \"8.20.0\",\n      \"resolved\": \"https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz\",\n      \"integrity\": \"sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"fast-deep-equal\": \"^3.1.3\",\n        \"fast-uri\": \"^3.0.1\",\n        \"json-schema-traverse\": \"^1.0.0\",\n        \"require-from-string\": \"^2.0.2\"\n      },\n      \"funding\": {\n        \"type\": \"github\",\n        \"url\": \"https://github.com/sponsors/epoberezkin\"\n      }\n    },\n    \"node_modules/ajv-formats\": {\n      \"version\": \"3.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz\",\n      \"integrity\": \"sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"ajv\": \"^8.0.0\"\n      },\n      \"peerDependencies\": {\n        \"ajv\": \"^8.0.0\"\n      },\n      \"peerDependenciesMeta\": {\n        \"ajv\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/array-flatten\": {\n      \"version\": \"1.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz\",\n      \"integrity\": \"sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/body-parser\": {\n      \"version\": \"1.20.5\",\n      \"resolved\": \"https://registry.npmjs.org/body-parser/-/body-parser-1.20.5.tgz\",\n      \"integrity\": \"sha512-3grm+/2tUOvu2cjJkvsIxrv/wVpfXQW4PsQHYm7yk4vfpu7Ekl6nEsYBoJUL6qDwZUx8wUhQ8tR2qz+ad9c9OA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"bytes\": \"~3.1.2\",\n        \"content-type\": \"~1.0.5\",\n        \"debug\": \"2.6.9\",\n        \"depd\": \"2.0.0\",\n        \"destroy\": \"~1.2.0\",\n        \"http-errors\": \"~2.0.1\",\n        \"iconv-lite\": \"~0.4.24\",\n        \"on-finished\": \"~2.4.1\",\n        \"qs\": \"~6.15.1\",\n        \"raw-body\": \"~2.5.3\",\n        \"type-is\": \"~1.6.18\",\n        \"unpipe\": \"~1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.8\",\n        \"npm\": \"1.2.8000 || >= 1.4.16\"\n      }\n    },\n    \"node_modules/body-parser/node_modules/raw-body\": {\n      \"version\": \"2.5.3\",\n      \"resolved\": \"https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz\",\n      \"integrity\": \"sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"bytes\": \"~3.1.2\",\n        \"http-errors\": \"~2.0.1\",\n        \"iconv-lite\": \"~0.4.24\",\n        \"unpipe\": \"~1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.8\"\n      }\n    },\n    \"node_modules/bytes\": {\n      \"version\": \"3.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz\",\n      \"integrity\": \"sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.8\"\n      }\n    },\n    \"node_modules/call-bind-apply-helpers\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz\",\n      \"integrity\": \"sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"es-errors\": \"^1.3.0\",\n        \"function-bind\": \"^1.1.2\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      }\n    },\n    \"node_modules/call-bound\": {\n      \"version\": \"1.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz\",\n      \"integrity\": \"sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"call-bind-apply-helpers\": \"^1.0.2\",\n        \"get-intrinsic\": \"^1.3.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/content-disposition\": {\n      \"version\": \"0.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz\",\n      \"integrity\": \"sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"safe-buffer\": \"5.2.1\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/content-type\": {\n      \"version\": \"1.0.5\",\n      \"resolved\": \"https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz\",\n      \"integrity\": \"sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/cookie\": {\n      \"version\": \"0.7.2\",\n      \"resolved\": \"https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz\",\n      \"integrity\": \"sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/cookie-signature\": {\n      \"version\": \"1.0.7\",\n      \"resolved\": \"https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz\",\n      \"integrity\": \"sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/cors\": {\n      \"version\": \"2.8.6\",\n      \"resolved\": \"https://registry.npmjs.org/cors/-/cors-2.8.6.tgz\",\n      \"integrity\": \"sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"object-assign\": \"^4\",\n        \"vary\": \"^1\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.10\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/cross-spawn\": {\n      \"version\": \"7.0.6\",\n      \"resolved\": \"https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz\",\n      \"integrity\": \"sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"path-key\": \"^3.1.0\",\n        \"shebang-command\": \"^2.0.0\",\n        \"which\": \"^2.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">= 8\"\n      }\n    },\n    \"node_modules/debug\": {\n      \"version\": \"2.6.9\",\n      \"resolved\": \"https://registry.npmjs.org/debug/-/debug-2.6.9.tgz\",\n      \"integrity\": \"sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"ms\": \"2.0.0\"\n      }\n    },\n    \"node_modules/depd\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/depd/-/depd-2.0.0.tgz\",\n      \"integrity\": \"sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.8\"\n      }\n    },\n    \"node_modules/destroy\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz\",\n      \"integrity\": \"sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.8\",\n        \"npm\": \"1.2.8000 || >= 1.4.16\"\n      }\n    },\n    \"node_modules/dotenv\": {\n      \"version\": \"16.6.1\",\n      \"resolved\": \"https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz\",\n      \"integrity\": \"sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==\",\n      \"license\": \"BSD-2-Clause\",\n      \"engines\": {\n        \"node\": \">=12\"\n      },\n      \"funding\": {\n        \"url\": \"https://dotenvx.com\"\n      }\n    },\n    \"node_modules/dunder-proto\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz\",\n      \"integrity\": \"sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"call-bind-apply-helpers\": \"^1.0.1\",\n        \"es-errors\": \"^1.3.0\",\n        \"gopd\": \"^1.2.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      }\n    },\n    \"node_modules/ee-first\": {\n      \"version\": \"1.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz\",\n      \"integrity\": \"sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/encodeurl\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz\",\n      \"integrity\": \"sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.8\"\n      }\n    },\n    \"node_modules/es-define-property\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz\",\n      \"integrity\": \"sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      }\n    },\n    \"node_modules/es-errors\": {\n      \"version\": \"1.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz\",\n      \"integrity\": \"sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      }\n    },\n    \"node_modules/es-object-atoms\": {\n      \"version\": \"1.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz\",\n      \"integrity\": \"sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"es-errors\": \"^1.3.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      }\n    },\n    \"node_modules/escape-html\": {\n      \"version\": \"1.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz\",\n      \"integrity\": \"sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/etag\": {\n      \"version\": \"1.8.1\",\n      \"resolved\": \"https://registry.npmjs.org/etag/-/etag-1.8.1.tgz\",\n      \"integrity\": \"sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/eventsource\": {\n      \"version\": \"3.0.7\",\n      \"resolved\": \"https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz\",\n      \"integrity\": \"sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"eventsource-parser\": \"^3.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">=18.0.0\"\n      }\n    },\n    \"node_modules/eventsource-parser\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.1.0.tgz\",\n      \"integrity\": \"sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=18.0.0\"\n      }\n    },\n    \"node_modules/express\": {\n      \"version\": \"4.22.2\",\n      \"resolved\": \"https://registry.npmjs.org/express/-/express-4.22.2.tgz\",\n      \"integrity\": \"sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"accepts\": \"~1.3.8\",\n        \"array-flatten\": \"1.1.1\",\n        \"body-parser\": \"~1.20.5\",\n        \"content-disposition\": \"~0.5.4\",\n        \"content-type\": \"~1.0.4\",\n        \"cookie\": \"~0.7.1\",\n        \"cookie-signature\": \"~1.0.6\",\n        \"debug\": \"2.6.9\",\n        \"depd\": \"2.0.0\",\n        \"encodeurl\": \"~2.0.0\",\n        \"escape-html\": \"~1.0.3\",\n        \"etag\": \"~1.8.1\",\n        \"finalhandler\": \"~1.3.1\",\n        \"fresh\": \"~0.5.2\",\n        \"http-errors\": \"~2.0.0\",\n        \"merge-descriptors\": \"1.0.3\",\n        \"methods\": \"~1.1.2\",\n        \"on-finished\": \"~2.4.1\",\n        \"parseurl\": \"~1.3.3\",\n        \"path-to-regexp\": \"~0.1.12\",\n        \"proxy-addr\": \"~2.0.7\",\n        \"qs\": \"~6.15.1\",\n        \"range-parser\": \"~1.2.1\",\n        \"safe-buffer\": \"5.2.1\",\n        \"send\": \"~0.19.0\",\n        \"serve-static\": \"~1.16.2\",\n        \"setprototypeof\": \"1.2.0\",\n        \"statuses\": \"~2.0.1\",\n        \"type-is\": \"~1.6.18\",\n        \"utils-merge\": \"1.0.1\",\n        \"vary\": \"~1.1.2\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.10.0\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/express-rate-limit\": {\n      \"version\": \"8.5.2\",\n      \"resolved\": \"https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.5.2.tgz\",\n      \"integrity\": \"sha512-5Kb34ipNX694DH48vN9irak1Qx30nb0PLYHXfJgw4YEjiC3ZEmZJhwOp+VfiCYwFzvFTdB9QkArYS5kXa2cx2A==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"ip-address\": \"^10.2.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 16\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/express-rate-limit\"\n      },\n      \"peerDependencies\": {\n        \"express\": \">= 4.11\"\n      }\n    },\n    \"node_modules/fast-deep-equal\": {\n      \"version\": \"3.1.3\",\n      \"resolved\": \"https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz\",\n      \"integrity\": \"sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/fast-uri\": {\n      \"version\": \"3.1.3\",\n      \"resolved\": \"https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.3.tgz\",\n      \"integrity\": \"sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg==\",\n      \"funding\": [\n        {\n          \"type\": \"github\",\n          \"url\": \"https://github.com/sponsors/fastify\"\n        },\n        {\n          \"type\": \"opencollective\",\n          \"url\": \"https://opencollective.com/fastify\"\n        }\n      ],\n      \"license\": \"BSD-3-Clause\"\n    },\n    \"node_modules/finalhandler\": {\n      \"version\": \"1.3.2\",\n      \"resolved\": \"https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz\",\n      \"integrity\": \"sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"debug\": \"2.6.9\",\n        \"encodeurl\": \"~2.0.0\",\n        \"escape-html\": \"~1.0.3\",\n        \"on-finished\": \"~2.4.1\",\n        \"parseurl\": \"~1.3.3\",\n        \"statuses\": \"~2.0.2\",\n        \"unpipe\": \"~1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.8\"\n      }\n    },\n    \"node_modules/forwarded\": {\n      \"version\": \"0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz\",\n      \"integrity\": \"sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/fresh\": {\n      \"version\": \"0.5.2\",\n      \"resolved\": \"https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz\",\n      \"integrity\": \"sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/function-bind\": {\n      \"version\": \"1.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz\",\n      \"integrity\": \"sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==\",\n      \"license\": \"MIT\",\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/get-intrinsic\": {\n      \"version\": \"1.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz\",\n      \"integrity\": \"sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"call-bind-apply-helpers\": \"^1.0.2\",\n        \"es-define-property\": \"^1.0.1\",\n        \"es-errors\": \"^1.3.0\",\n        \"es-object-atoms\": \"^1.1.1\",\n        \"function-bind\": \"^1.1.2\",\n        \"get-proto\": \"^1.0.1\",\n        \"gopd\": \"^1.2.0\",\n        \"has-symbols\": \"^1.1.0\",\n        \"hasown\": \"^2.0.2\",\n        \"math-intrinsics\": \"^1.1.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/get-proto\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz\",\n      \"integrity\": \"sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"dunder-proto\": \"^1.0.1\",\n        \"es-object-atoms\": \"^1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      }\n    },\n    \"node_modules/gopd\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz\",\n      \"integrity\": \"sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/has-symbols\": {\n      \"version\": \"1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz\",\n      \"integrity\": \"sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/hasown\": {\n      \"version\": \"2.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz\",\n      \"integrity\": \"sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"function-bind\": \"^1.1.2\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      }\n    },\n    \"node_modules/hono\": {\n      \"version\": \"4.12.28\",\n      \"resolved\": \"https://registry.npmjs.org/hono/-/hono-4.12.28.tgz\",\n      \"integrity\": \"sha512-YwUvVpSF7m1yOblFPrU3Hbo8XhPheBoiyfGuII6z19LnOr6JpDnyyp7LFNrfV56wS8tpvtBFGRISHN02pDdLOA==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=16.9.0\"\n      }\n    },\n    \"node_modules/http-errors\": {\n      \"version\": \"2.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz\",\n      \"integrity\": \"sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"depd\": \"~2.0.0\",\n        \"inherits\": \"~2.0.4\",\n        \"setprototypeof\": \"~1.2.0\",\n        \"statuses\": \"~2.0.2\",\n        \"toidentifier\": \"~1.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.8\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/iconv-lite\": {\n      \"version\": \"0.4.24\",\n      \"resolved\": \"https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz\",\n      \"integrity\": \"sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"safer-buffer\": \">= 2.1.2 < 3\"\n      },\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/inherits\": {\n      \"version\": \"2.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz\",\n      \"integrity\": \"sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==\",\n      \"license\": \"ISC\"\n    },\n    \"node_modules/ip-address\": {\n      \"version\": \"10.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz\",\n      \"integrity\": \"sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 12\"\n      }\n    },\n    \"node_modules/ipaddr.js\": {\n      \"version\": \"1.9.1\",\n      \"resolved\": \"https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz\",\n      \"integrity\": \"sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.10\"\n      }\n    },\n    \"node_modules/is-promise\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz\",\n      \"integrity\": \"sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/isexe\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz\",\n      \"integrity\": \"sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==\",\n      \"license\": \"ISC\"\n    },\n    \"node_modules/jose\": {\n      \"version\": \"6.2.3\",\n      \"resolved\": \"https://registry.npmjs.org/jose/-/jose-6.2.3.tgz\",\n      \"integrity\": \"sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==\",\n      \"license\": \"MIT\",\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/panva\"\n      }\n    },\n    \"node_modules/json-schema-traverse\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz\",\n      \"integrity\": \"sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/json-schema-typed\": {\n      \"version\": \"8.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz\",\n      \"integrity\": \"sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==\",\n      \"license\": \"BSD-2-Clause\"\n    },\n    \"node_modules/math-intrinsics\": {\n      \"version\": \"1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz\",\n      \"integrity\": \"sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      }\n    },\n    \"node_modules/media-typer\": {\n      \"version\": \"0.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz\",\n      \"integrity\": \"sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/merge-descriptors\": {\n      \"version\": \"1.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz\",\n      \"integrity\": \"sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==\",\n      \"license\": \"MIT\",\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/methods\": {\n      \"version\": \"1.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/methods/-/methods-1.1.2.tgz\",\n      \"integrity\": \"sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/mime\": {\n      \"version\": \"1.6.0\",\n      \"resolved\": \"https://registry.npmjs.org/mime/-/mime-1.6.0.tgz\",\n      \"integrity\": \"sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==\",\n      \"license\": \"MIT\",\n      \"bin\": {\n        \"mime\": \"cli.js\"\n      },\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/mime-db\": {\n      \"version\": \"1.52.0\",\n      \"resolved\": \"https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz\",\n      \"integrity\": \"sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/mime-types\": {\n      \"version\": \"2.1.35\",\n      \"resolved\": \"https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz\",\n      \"integrity\": \"sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"mime-db\": \"1.52.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/ms\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/ms/-/ms-2.0.0.tgz\",\n      \"integrity\": \"sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/negotiator\": {\n      \"version\": \"0.6.3\",\n      \"resolved\": \"https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz\",\n      \"integrity\": \"sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/object-assign\": {\n      \"version\": \"4.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz\",\n      \"integrity\": \"sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/object-inspect\": {\n      \"version\": \"1.13.4\",\n      \"resolved\": \"https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz\",\n      \"integrity\": \"sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/on-finished\": {\n      \"version\": \"2.4.1\",\n      \"resolved\": \"https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz\",\n      \"integrity\": \"sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"ee-first\": \"1.1.1\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.8\"\n      }\n    },\n    \"node_modules/once\": {\n      \"version\": \"1.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/once/-/once-1.4.0.tgz\",\n      \"integrity\": \"sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==\",\n      \"license\": \"ISC\",\n      \"dependencies\": {\n        \"wrappy\": \"1\"\n      }\n    },\n    \"node_modules/parseurl\": {\n      \"version\": \"1.3.3\",\n      \"resolved\": \"https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz\",\n      \"integrity\": \"sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.8\"\n      }\n    },\n    \"node_modules/path-key\": {\n      \"version\": \"3.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz\",\n      \"integrity\": \"sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/path-to-regexp\": {\n      \"version\": \"0.1.13\",\n      \"resolved\": \"https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz\",\n      \"integrity\": \"sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/pkce-challenge\": {\n      \"version\": \"5.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz\",\n      \"integrity\": \"sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=16.20.0\"\n      }\n    },\n    \"node_modules/proxy-addr\": {\n      \"version\": \"2.0.7\",\n      \"resolved\": \"https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz\",\n      \"integrity\": \"sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"forwarded\": \"0.2.0\",\n        \"ipaddr.js\": \"1.9.1\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.10\"\n      }\n    },\n    \"node_modules/qs\": {\n      \"version\": \"6.15.3\",\n      \"resolved\": \"https://registry.npmjs.org/qs/-/qs-6.15.3.tgz\",\n      \"integrity\": \"sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==\",\n      \"license\": \"BSD-3-Clause\",\n      \"dependencies\": {\n        \"es-define-property\": \"^1.0.1\",\n        \"side-channel\": \"^1.1.1\"\n      },\n      \"engines\": {\n        \"node\": \">=0.6\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/range-parser\": {\n      \"version\": \"1.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz\",\n      \"integrity\": \"sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/raw-body\": {\n      \"version\": \"3.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz\",\n      \"integrity\": \"sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"bytes\": \"~3.1.2\",\n        \"http-errors\": \"~2.0.1\",\n        \"iconv-lite\": \"~0.7.0\",\n        \"unpipe\": \"~1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.10\"\n      }\n    },\n    \"node_modules/raw-body/node_modules/iconv-lite\": {\n      \"version\": \"0.7.3\",\n      \"resolved\": \"https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz\",\n      \"integrity\": \"sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"safer-buffer\": \">= 2.1.2 < 3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/require-from-string\": {\n      \"version\": \"2.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz\",\n      \"integrity\": \"sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/router\": {\n      \"version\": \"2.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/router/-/router-2.2.0.tgz\",\n      \"integrity\": \"sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"debug\": \"^4.4.0\",\n        \"depd\": \"^2.0.0\",\n        \"is-promise\": \"^4.0.0\",\n        \"parseurl\": \"^1.3.3\",\n        \"path-to-regexp\": \"^8.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/router/node_modules/debug\": {\n      \"version\": \"4.4.3\",\n      \"resolved\": \"https://registry.npmjs.org/debug/-/debug-4.4.3.tgz\",\n      \"integrity\": \"sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"ms\": \"^2.1.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6.0\"\n      },\n      \"peerDependenciesMeta\": {\n        \"supports-color\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/router/node_modules/ms\": {\n      \"version\": \"2.1.3\",\n      \"resolved\": \"https://registry.npmjs.org/ms/-/ms-2.1.3.tgz\",\n      \"integrity\": \"sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/router/node_modules/path-to-regexp\": {\n      \"version\": \"8.4.2\",\n      \"resolved\": \"https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz\",\n      \"integrity\": \"sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==\",\n      \"license\": \"MIT\",\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/safe-buffer\": {\n      \"version\": \"5.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz\",\n      \"integrity\": \"sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==\",\n      \"funding\": [\n        {\n          \"type\": \"github\",\n          \"url\": \"https://github.com/sponsors/feross\"\n        },\n        {\n          \"type\": \"patreon\",\n          \"url\": \"https://www.patreon.com/feross\"\n        },\n        {\n          \"type\": \"consulting\",\n          \"url\": \"https://feross.org/support\"\n        }\n      ],\n      \"license\": \"MIT\"\n    },\n    \"node_modules/safer-buffer\": {\n      \"version\": \"2.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz\",\n      \"integrity\": \"sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/send\": {\n      \"version\": \"0.19.2\",\n      \"resolved\": \"https://registry.npmjs.org/send/-/send-0.19.2.tgz\",\n      \"integrity\": \"sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"debug\": \"2.6.9\",\n        \"depd\": \"2.0.0\",\n        \"destroy\": \"1.2.0\",\n        \"encodeurl\": \"~2.0.0\",\n        \"escape-html\": \"~1.0.3\",\n        \"etag\": \"~1.8.1\",\n        \"fresh\": \"~0.5.2\",\n        \"http-errors\": \"~2.0.1\",\n        \"mime\": \"1.6.0\",\n        \"ms\": \"2.1.3\",\n        \"on-finished\": \"~2.4.1\",\n        \"range-parser\": \"~1.2.1\",\n        \"statuses\": \"~2.0.2\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.8.0\"\n      }\n    },\n    \"node_modules/send/node_modules/ms\": {\n      \"version\": \"2.1.3\",\n      \"resolved\": \"https://registry.npmjs.org/ms/-/ms-2.1.3.tgz\",\n      \"integrity\": \"sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/serve-static\": {\n      \"version\": \"1.16.3\",\n      \"resolved\": \"https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz\",\n      \"integrity\": \"sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"encodeurl\": \"~2.0.0\",\n        \"escape-html\": \"~1.0.3\",\n        \"parseurl\": \"~1.3.3\",\n        \"send\": \"~0.19.1\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.8.0\"\n      }\n    },\n    \"node_modul\n\nFile v0.1.5:assets/backend/package.json\n\n{\n  \"name\": \"webchat-backend\",\n  \"version\": \"1.0.0\",\n  \"type\": \"module\",\n  \"private\": true,\n  \"description\": \"网页划线对话插件的 AI 后端：Express + CodeBuddy Agent SDK + SSE 流式\",\n  \"scripts\": {\n    \"start\": \"node server.js\",\n    \"dev\": \"node --watch server.js\",\n    \"postinstall\": \"node patch-sdk.mjs\"\n  },\n  \"dependencies\": {\n    \"@tencent-ai/agent-sdk\": \"^0.3.43\",\n    \"cors\": \"^2.8.5\",\n    \"express\": \"^4.18.2\",\n    \"dotenv\": \"^16.4.5\"\n  }\n}\n\nFile v0.1.5:assets/extension/manifest.json\n\n{\n  \"manifest_version\": 3,\n  \"name\": \"网页划线对话 · 小虾\",\n  \"version\": \"1.5.5\",\n  \"description\": \"点工具栏图标弹出可拖动对话浮层；读取网页选区(含 iframe/微信读书)与系统剪切板(含输入法复制)，发送时自动收进上下文，直接和 AI 对话。基于 CodeBuddy Agent SDK。\",\n  \"icons\": {\n    \"16\": \"icons/icon16.png\",\n    \"32\": \"icons/icon32.png\",\n    \"48\": \"icons/icon48.png\",\n    \"128\": \"icons/icon128.png\"\n  },\n  \"action\": {\n    \"default_title\": \"网页对话 · 小虾（点我打开）\",\n    \"default_icon\": {\n      \"16\": \"icons/icon16.png\",\n      \"32\": \"icons/icon32.png\"\n    }\n  },\n  \"background\": {\n    \"service_worker\": \"background.js\"\n  },\n  \"permissions\": [\"activeTab\", \"scripting\", \"storage\", \"clipboardRead\", \"alarms\"],\n  \"host_permissions\": [\"http://localhost/*\", \"http://127.0.0.1/*\"],\n  \"content_scripts\": [\n    {\n      \"matches\": [\"<all_urls>\"],\n      \"js\": [\"content.js\"],\n      \"run_at\": \"document_idle\"\n    }\n  ],\n  \"web_accessible_resources\": [\n    {\n      \"resources\": [\"panel.html\", \"panel.js\", \"panel.css\"],\n      \"matches\": [\"<all_urls>\"]\n    }\n  ]\n}\n\nArchive v0.1.4: 26 files, 82396 bytes\n\nFiles: assets/backend/launcher.mjs (3081b), assets/backend/package-lock.json (57090b), assets/backend/package.json (461b), assets/backend/patch-sdk.mjs (1701b), assets/backend/server.js (22537b), assets/extension/background.js (3224b), assets/extension/content.js (7247b), assets/extension/icons/icon128.png (2436b), assets/extension/icons/icon16.png (419b), assets/extension/icons/icon32.png (715b), assets/extension/icons/icon48.png (966b), assets/extension/manifest.json (1129b), assets/extension/panel.css (5252b), assets/extension/panel.html (1958b), assets/extension/panel.js (17053b), assets/root/README.md (14179b), assets/root/webchat-protocol.reg.example (1156b), gen-icons.mjs (2525b), pack.mjs (8627b), references/deploy-guide.md (8553b), scripts/deploy.mjs (9450b), scripts/gen-vbs.mjs (5512b), scripts/register-protocol.cjs (6836b), skill-card.md (2477b), SKILL.md (13494b), _meta.json (136b)\n\nFile v0.1.4:SKILL.md\n\n---\nname: webchat-extension\ndescription: 部署「网页划线对话」浏览器扩展（Chrome MV3 / 兼容 Chrome·Edge·千问·夸克 等 Chromium 内核浏览器）。在任意网页选中文字，点工具栏图标唤起可拖动对话浮层，带着网页上下文用 CodeBuddy AI 流式问答。包含本地 Express + SSE 后端（CodeBuddy Agent SDK）与前端扩展。当用户要「做一个网页划词对话插件 / 给浏览器装个网页对话工具 / 选中文字问 AI / 部署小虾网页对话扩展 / web highlight chat extension / 把网页内容丢给 AI 聊」时使用本技能。\n---\n\n# 网页划线对话 · 小虾 🦐\n\n一个浏览器扩展 + 本地 AI 后端：用户在任意网页**选中文字**或**复制文字**，点工具栏图标弹出对话浮层，带着网页上下文直接和 AI 流式对话。后端基于 **CodeBuddy Agent SDK**（官方 `@tencent-ai/codebuddy-code` CLI 做 transport）。\n\n## 什么时候用\n- 用户想要「在网页上选中一段文字，直接问 AI 这是什么 / 帮我总结 / 翻译 / 解释」。\n- 用户想把某个网页内容作为上下文和 AI 聊。\n- 用户要部署/打包一个浏览器划词对话工具。\n\n## 架构\n```\n浏览器扩展 (Chrome MV3)                本地后端 (Express + SSE)\n┌──────────────────────────┐          ┌────────────────────────────┐\n│ 点工具栏图标 → 浮层(iframe) │──fetch──▶│  /api/chat  (SSE 流式)      │\n│ content.js 注入网页          │          │  query() → codebuddy CLI    │\n│ background.js service worker│          │  (CodeBuddy Agent SDK)      │\n│ 选区经 executeScript 跨 iframe│         │  buildSystemPrompt 注入网页上下文│\n└──────────────────────────┘          └────────────────────────────┘\n```\n- 前端只请求 `http://localhost:3000`，**API Key 只在后端**。\n- 面板状态（开关/位置/上下文/对话）用 `chrome.storage` 持久化，刷新不丢。\n\n## 文件布局（本 skill 内）\n```\nwebchat-extension/\n├── SKILL.md\n├── pack.mjs                  # 发布工具：在 deploy 产物(双形态目录)下 node pack.mjs → 生成干净分享包 zip\n├── gen-icons.mjs             # 独立图标生成（零依赖）：node gen-icons.mjs [dir]\n├── scripts/\n│   ├── deploy.mjs            # 脚手架：复制 assets 源码 + npm install + 生成 icons/（Windows 部署时生成 launcher.vbs + 注册协议）\n│   ├── gen-vbs.mjs           # 唯一 source of truth：写出 backend/launcher.vbs（agent 部署时调用，不随包分发）\n│   └── register-protocol.cjs # 一键注册/修复 webchat:// 协议（协议丢失或被识别成 Store 应用时用）\n├── assets/\n│   ├── extension/            # 浏览器扩展（manifest/background/content/panel.*/icons）\n│   ├── backend/              # server.js / launcher.mjs / patch-sdk.mjs / package.json / .env.example（launcher.vbs 由 agent 在部署时用 scripts/gen-vbs.mjs 生成，不随包分发）\n│   └── root/                 # 部署到目标根目录的文档：README.md（.gitignore / 协议模板不随包分发）\n└── references/deploy-guide.md  # 详细排错表\n```\n\n> **统一原则**：本 skill 是**唯一 source of truth**。运行环境一律由 `deploy.mjs` 生成（assets → 目标目录），不要在别处手维护一份带 `extension/ backend/` 的\"双形态\"目录，以免与 skill 不同步产生歧义。deploy 产物（目标目录）本身就是双形态目录（含 `extension/ backend/ SKILL.md pack.mjs gen-icons.mjs`），可直接加载运行，也可 `node pack.mjs` 生成分享包。\n\n## 部署步骤（agent 照做）\n1. **脚手架**：运行 `node <skill_dir>/scripts/deploy.mjs <targetDir>`（不加 `[targetDir]` 默认 `./webchat-extension` 或 `~/webchat-extension`）。脚本把 `assets/` 里的扩展、后端、根文档复制到目标目录并 `npm install`；**在 Windows 上，agent 会自动用 `scripts/gen-vbs.mjs` 生成 `backend/launcher.vbs`（即使带 `--no-protocol` 也会生成），并自动注册 `webchat://start` 协议**，使面板「🚀 启动后端」按钮免终端生效。`launcher.vbs` 是部署期产物，**绝不随分享包分发/上传**——若目标目录缺失它，可随时补：`node <skill_dir>/scripts/gen-vbs.mjs <target>/backend`。加 `--no-install` 只复制不装依赖；加 `--no-protocol` 跳过协议注册（但 vbs 仍会生成）。非 Windows 或需手动注册时，按 README「四、一键启动后端」用面板「📋 复制启动命令」手动 `npm start`，或参考 README/references 手动 `reg add` 注册协议。\n2. **配置后端**：在 `<target>/backend/` 复制 `.env.example` 为 `.env`，按需填 `CODEBUDDY_API_KEY`（**不填也能跑：复用本机 `codebuddy` CLI 已登录凭据走登录模式真实 AI**；只有显式设 `WEBCHAT_DEMO=1` 才进演示模式）。确认 `CODEBUDDY_MODEL=deepseek-v4-flash`（默认，该账户不支持 `claude-sonnet-4`）。\n3. **启动后端（后台运行）**：`cd <target>/backend && npm start`。监听 `http://localhost:3000`。改代码后重启才生效。也可用面板「🚀 启动后端」按钮（需协议已注册）。\n4. **加载扩展**：浏览器（Chrome / Edge / 千问 / 夸克 等 Chromium 内核）进入**开发者模式 → 加载已解压的扩展程序**，目录选 `<target>/extension/`。（`deploy` 已自动生成 `extension/icons` 四张图标；若手动加载项目根 `extension/`，请先跑 `node gen-icons.mjs`）改了扩展代码要回扩展管理页点「重新加载」。\n5. **验证**：访问 `http://localhost:3000/api/health` 应返回 `{\"status\":\"ok\",...}`；打开任意网页 → 点工具栏「🦐 小虾」图标 → 弹出面板 → 选中网页文字点「➕ 添加选中文本」→ 提问 → 流式回答。\n\n## 发布分享包（可选，给其他人用）\ndeploy 产物（目标目录）即为双形态目录，内含 `pack.mjs`。在其中运行：\n```bash\ncd <target>            # 例如 ~/webchat-extension\nnode pack.mjs         # 在父目录生成 webchat-extension-share-YYYYMMDD.zip\n```\n`pack.mjs` 自动按 `.gitignore` + 硬性黑名单排除：`node_modules/`、`.env`、私钥 `*.pem`、`extension.crx`、协议注册表模板、所有 `*.png`（图标由收件人部署时生成）。生成的 zip 即干净分享包，可直接发给他人或推送到仓库。\n\n## CodeBuddy 认证（登录 / API Key 二选一，零配置优先）\n后端 `server.js` 通过 CodeBuddy Agent SDK 调真实模型，认证方式参考 dingtalk-auto-reply 的「Key / CLI 已登录」范式：\n- **登录模式（默认，零配置）**：未配置 `CODEBUDDY_API_KEY` 时，SDK 自动复用本机 `codebuddy` CLI 已登录凭据（与你在终端 / WorkBuddy 登录的是同一套 `~/.codebuddy/local_storage`），无需任何 Key 即可走真实 AI。首次启动前请确保 `codebuddy` 已登录（终端跑一次 `codebuddy` 完成登录）。\n- **Key 模式（推荐无人值守）**：在 `backend/.env` 填 `CODEBUDDY_API_KEY=<你的key>`（申请：https://copilot.tencent.com 控制台）→ 用 Key 直连，不依赖交互登录。\n- **演示模式**：仅当显式设 `WEBCHAT_DEMO=1` 时强制进入（返回模拟回复验收交互）；否则无 Key 也走「登录模式」真实模型，**不再降级为 demo**。\n- `CODEBUDDY_INTERNET_ENVIRONMENT`：中国版自动设为 `internal`（已在 server.js 兜底），无需手动配。\n- 自检：`/api/health` 返回 `mode`（key｜login）、`demo`；`/api/auth` 用一次极短 query 实测登录态（15s 超时兜底，不卡死），失败回退到凭据目录存在性判断并给出明确修复提示。**后端绝不代填 / 存储登录凭据**——认证动作由你本人在终端完成。\n\n> ⚠️ **进程清理绝不误杀**：后端退出（`/api/stop`、空闲超时、托管心跳断、全局退出）时只清理「自己 spawn 出来的 codebuddy CLI 子进程」——按**进程树（本进程后代）+ CLI 路径精确匹配**，绝不按端口 `netstat` 乱扫（端口子串匹配会把 `45012` 误中 `450123`，且易误杀带看门狗、会被自动重拉的进程，如 dingtalk 监控）。即使某进程有看门狗会自愈，我们也连误杀都不做；另有「监听端口 + CLI 路径二次确认」兜底，确保外来进程永不被误杀。\n\n## 关键坑（务必先读，否则部署必踩）\n- **端口冲突导致一直转圈**：官方 CLI 启动会起 prewarm 本地 server，端口由 `SERVER__PORT` 控制。若该端口被本机其他程序（**WorkBuddy 桌面应用**）占用，CLI 会 `EADDRINUSE` 卡死。解决：`.env` 设 `SERVER__PORT=40123`（空闲端口）并重启。**面板「🚀 启动后端」按钮路径**下，`launcher.mjs` 会自动从 `.env` 读取 `SERVER__PORT` 并**显式注入**子进程环境，覆盖本机可能存在的系统级 `SERVER__PORT`（dotenv 不覆盖已存在变量，故必须靠 launcher 注入）；未设置时则不注入、由 `server.js` 自动分配空闲端口。若走 `npm start` 手动启动且系统变量残留旧值，用 `SERVER__PORT=40123 npm start` 显式覆盖。\n- **模型名 400**：本账户不支持 `claude-sonnet-4`。用 `deepseek-v4-flash`（默认）、`hy3` 或 `auto`。\n- **CLI 路径**：`server.js` 通过 `resolveCli()` 自动定位官方 CLI（优先级：显式 `CODEBUDDY_CLI_PATH` → PATH 上的 `codebuddy` → 受管 node 目录固定路径）。不要用 WorkBuddy 自带的那份 cli（协议不匹配会 initialize 超时）。\n- **演示 vs 真实**：未填 `CODEBUDDY_API_KEY` 时后端走「登录模式」复用 codebuddy CLI 已登录凭据，是**真实 AI**（不是模拟回复）；只有显式设 `WEBCHAT_DEMO=1` 才进演示模式（模拟回复用来验收交互闭环）。填了 Key 则走 Key 模式，也是真实 AI。\n- **扩展不注入系统页**：`chrome://`、`edge://` 等页面扩展无法注入，点图标无反应属正常。\n- **图标由 agent 部署时生成（分享包不含任何 *.png）**：`manifest.json` 声明了 `icons/icon{16,32,48,128}.png`，加载扩展前这 4 张必须存在，否则报 `Could not load icon` 加载失败。`deploy.mjs` 复制 extension 后会**自动生成**珊瑚橙 PNG（不依赖源图标）；手动从项目根加载（不跑 deploy）时，请先跑 `node gen-icons.mjs` 生成。想换正式品牌图标，部署后替换这 4 张 png 即可。\n- **launcher.vbs 由 agent 部署时生成（绝不随包分发/上传）**：`backend/launcher.vbs` 是 Windows 隐藏启动器，用于「🚀 启动后端」按钮免终端拉起 `launcher.mjs`。它**不进分享包、不进 git**（被 `pack.mjs` 与 `.gitignore` 排除），由 agent 在部署时经 `scripts/gen-vbs.mjs` 现生成。若某次部署后按钮失效 / 报「找不到 launcher.vbs」，直接重跑 `node scripts/gen-vbs.mjs <target>/backend`（或重新 `deploy.mjs`）即可，无需手动编辑 vbs 内容。\n- **微信读书等 iframe 阅读器**：选区由 `background.js` 用 `chrome.scripting.executeScript({allFrames:true})` 直插每一帧读取，能抓到；若阅读器是 sandboxed iframe（无 allow-scripts）且屏蔽 copy，则只能手动粘贴/输入到输入框再发送（发送会自动收进上下文）。\n- **webchat:// 协议被识别成 Microsoft Store 应用（弹\"获取打开此链接的应用\"）**：这是 `HKCU\\Software\\Classes\\webchat` 注册表项丢失/损坏导致，Windows 找不到处理程序就去 Store 找 UWP 应用了。修复：运行 `node scripts/register-protocol.cjs`（自动探测 `launcher.vbs` 位置并重新注册协议，支持 `--check` 仅检查、`--force` 强制重写）。注册指向的 `launcher.vbs` 由 agent 在部署时用 `scripts/gen-vbs.mjs` 在目标目录生成，若你迁移过项目目录，用 `WEBCHAT_DIR=新目录 node scripts/register-protocol.cjs --force` 重新指向（缺失则先 `node scripts/gen-vbs.mjs <新目录>/backend` 生成）。\n\n## 使用方式（交付给用户）\n- 任意网页 → 点工具栏「🦐 小虾」图标 → 右侧弹出对话面板（高约视口 2/3，可拖动，双击标题栏复位，位置自动记住）。\n- 喂上下文：选网页文字点「➕ 添加选中文本」（同时读选区 + 系统剪切板，含输入法复制）；或直接发送（自动收剪贴板/提问文本）。\n- 上下文只显示 10~20 字摘要 + …，不可编辑；多段累加，✕ 删除。\n- 输入框回车发送，AI 逐字流式回答，多轮保持上下文。\n\n## 验证清单\n- [ ] `http://localhost:3000/api/health` 返回 ok\n- [ ] 扩展已加载、未被禁用\n- [ ] 点图标弹出面板、可拖动不抖、不跳左上角\n- [ ] 选中文字 → 添加上下文 → 提问有流式回答\n- [ ] 刷新网页后面板自动重开、上下文/对话不丢\n- [ ] 真实 AI 模式（登录模式默认零配置 / 或填 Key）回答正常；`WEBCHAT_DEMO=1` 演示模式也能跑通闭环\n\n## 参考\n- 详细排错表见 `references/deploy-guide.md`。\n- 来源项目：本地 `webchat-extension/`（本 skill 由其封装，扩展版本 1.5.5；路径随各人工作区不同，无硬编码）。\n\nFile v0.1.4:assets/root/README.md\n\n# 网页划线对话 · 小虾 🦐\n\n> 📦 仓库地址：https://github.com/NoahEleven/webchat-extension\n\n一个 **Chrome / Edge / 千问 / 夸克 等 Chromium 内核浏览器** 扩展：在任意网页上**选中或复制文字**，点一下工具栏图标，就能带着这段网页上下文，直接和 AI 对话、流式得到回答。\n\n> 本质：复用 CodeBuddy Agent SDK 的 **Express + SSE 后端**，前端换成「浏览器扩展 + 网页划线交互」。\n\n---\n\n## 目录结构\n\n```\nwebchat-extension/\n├── README.md\n├── webchat-protocol.reg.example   # 仅仓库内模板，不随分享包分发（协议改由部署脚本自动注册）\n├── pack.mjs                       # 一键打包分享 zip（按 .gitignore 排除 node_modules/.env/私钥等）\n├── extension/                     # 浏览器扩展（Chrome MV3）\n│   ├── manifest.json\n│   ├── background.js              # service worker：图标点击→开关浮层；心跳 ping 后端\n│   ├── content.js                 # 注入网页：开/关浮层、读选区、状态持久化、触发协议\n│   ├── panel.html / panel.js / panel.css   # 对话浮层界面与逻辑\n│   └── icons/                     # 图标 icon16/32/48/128.png（分享包不含，由 deploy/gen-icons 自动生成）\n└── backend/                       # AI 后端（Express + CodeBuddy SDK + SSE）\n    ├── server.js                  # /api/chat(SSE) /api/health /api/heartbeat /api/stop\n    ├── launcher.mjs               # 协议触发：托管模式静默拉起 server.js\n    ├── launcher.vbs               # 隐藏窗口启动 launcher.mjs（由 agent 在部署时用 scripts/gen-vbs.mjs 生成，不随分享包分发）\n    ├── patch-sdk.mjs              # postinstall 自动给 SDK 注入 windowsHide，消除 Windows 黑框\n    ├── package.json / package-lock.json\n    └── .env.example               # 复制为 .env 后填写（含 API Key）\n```\n\n---\n\n## 前置依赖（重要）\n\n- **Node.js 18+**：后端是 Node 程序。\n- **codebuddy CLI（核心外部依赖，需收件人自备）**：后端通过 `@tencent-ai/agent-sdk` 在运行时 `spawn` 一个 `codebuddy` 子进程来真正调用 AI。`server.js` 的 `resolveCli()` 按以下顺序找它：\n  1. 环境变量 `CODEBUDDY_CLI_PATH` 显式指定；\n  2. 系统 `PATH` 上的 `codebuddy` 命令；\n  3. 兜底固定路径 `~/.workbuddy/binaries/node/versions/22.22.2/node_modules/@tencent-ai/codebuddy-code/bin/codebuddy`（**仅本机 WorkBuddy 托管环境才有**）。\n  - 本机因装了 WorkBuddy，托管 Node 已自带 `codebuddy`，所以开箱可用。\n  - **分享给别人的机器若没有 WorkBuddy**：需对方自行安装 CLI —— `npm i -g @tencent-ai/codebuddy-code`，并保证 `codebuddy` 在 `PATH` 上（或在 `.env` 设 `CODEBUDDY_CLI_PATH=绝对路径` 指向 CLI）。否则 `query()` 拉不起进程、后端连不上（登录模式和 Key 模式都依赖该 CLI）；此时仅 `WEBCHAT_DEMO=1` 演示模式可跑通交互闭环。\n\n---\n\n## 一、启动后端\n\n```bash\ncd backend\nnpm install\ncp .env.example .env        # 然后按需填写 CODEBUDDY_API_KEY\nnpm start                   # 默认监听 http://localhost:3000\n```\n\n启动后访问 `http://localhost:3000/api/health` 应返回 `{ \"status\": \"ok\", ... }`。\n\n### 三种模式\n| 模式 | 条件 | 表现 |\n|---|---|---|\n| **登录模式（默认，零配置）** | 没填 `CODEBUDDY_API_KEY` 且未设 `WEBCHAT_DEMO` | 复用本机 `codebuddy` CLI 已登录凭据，**真实 AI**（首次需在终端跑一次 `codebuddy` 完成登录） |\n| **Key 模式（推荐无人值守）** | 填了 `CODEBUDDY_API_KEY` | 用 Key 直连 CodeBuddy AI，不依赖交互登录，**真实 AI** |\n| **演示模式** | 显式设 `WEBCHAT_DEMO=1` | 后端返回模拟流式回复，用来验收「划线→对话」交互闭环（无需任何账号/登录） |\n\n---\n\n## 二、申请 CODEBUDDY_API_KEY（可选，无人值守场景才需要）\n\n> 默认**不填 Key 也是真实 AI**（登录模式，复用本机 `codebuddy` CLI 已登录凭据）。只有想脱离交互登录、无人值守直连时才需要配 Key。\n\n1. 打开 https://www.codebuddy.cn → 登录\n2. 进入「个人中心 / API 密钥」生成 Key\n3. 把 Key 填进 `backend/.env` 的 `CODEBUDDY_API_KEY=`\n4. 重启后端 `npm start`\n\n> 没 Key 也没关系——登录模式默认就是真实 AI；纯验收交互闭环可设 `WEBCHAT_DEMO=1` 进演示模式。\n\n---\n\n## 三、在浏览器加载扩展\n\n本扩展是标准 Chrome MV3，兼容一切 Chromium 内核浏览器（Chrome / Edge / 千问 / 夸克等）。**无法从 `.crx` 文件直接安装**（现代浏览器已禁止本地 `.crx` 安装），请用「加载已解压」方式：\n\n1. 浏览器进入 **扩展管理页 → 开启「开发者模式」**（`chrome://extensions` 或 `edge://extensions` 等）\n2. 点 **「加载已解压的扩展程序」**，目录选本项目的 `extension/`\n   - ⚠️ **分享包不含图标 png**：加载前请先生成图标——已跑过 `node scripts/deploy.mjs` 会自动生成；手动加载则先跑 `node gen-icons.mjs`。否则报 `Could not load icon` 加载失败。\n3. 加载成功后，图标出现在扩展栏\n4. **改了扩展代码后**，回扩展管理页点「重新加载」才能生效\n\n---\n\n## 四、一键启动后端（可选但推荐，免开终端）\n\n面板里的「🚀 启动后端」按钮靠自定义协议 `webchat://start` 自动拉起后端，需要**先注册一次协议处理器**。\n\n- **若由 agent 按本 skill 部署（推荐）**：运行 `node scripts/deploy.mjs` 会**自动注册协议**，并自动在 `backend/` 生成 `launcher.vbs` 隐藏启动器，开箱即用，无需手动操作（`launcher.vbs` 是部署期产物，绝不随分享包分发/上传；缺失时可单独 `node scripts/gen-vbs.mjs <backend目录>` 生成）。\n- **手动 / 分享给别人（无 WorkBuddy）**：\n  - **最省事**：跳过协议，面板点「📋 复制启动命令」→ 终端执行，或直接 `cd backend && npm start`。\n  - **想要协议按钮免终端**：手动注册（把下列命令里的路径改成你机器真实的 `backend` 路径）。注意命令指向 `launcher.mjs`，直接用 `node` 跑会有一个 cmd 窗口闪现；若要完全无黑框，先 `node scripts/gen-vbs.mjs <backend目录>` 生成 `launcher.vbs`（唯一 source of truth 见 `scripts/gen-vbs.mjs`，隐藏启动 `launcher.mjs`），再让命令指向该 `.vbs`：\n    ```bat\n    reg add \"HKCU\\Software\\Classes\\webchat\" /ve /t REG_SZ /d \"webchat Protocol\" /f\n    reg add \"HKCU\\Software\\Classes\\webchat\" /v \"URL Protocol\" /t REG_SZ /d \"\" /f\n    reg add \"HKCU\\Software\\Classes\\webchat\\shell\\open\\command\" /ve /t REG_SZ /d \"\\\"C:\\Windows\\System32\\wscript.exe\\\" \\\"C:\\你的路径\\webchat-extension\\backend\\launcher.mjs\\\" \\\"%1\\\"\" /f\n    ```\n\n注册后：点「🚀 启动后端」即可无感拉起（首次会问「是否允许打开 webchat 链接」，允许即可）。**后端生命周期由扩展心跳托管**：浏览器开着→后端存活；浏览器关→心跳断→约 2.5 分钟后后端自退，不常驻、无需手动停。想立即停可点面板「⏹ 停止后端」或访问 `POST /api/stop`。\n\n---\n\n## 五、怎么用\n\n1. 打开任意网页（新闻、文档、微信读书、千问等都行）\n2. **点工具栏上的「🦐 小虾」图标** → 右侧弹出对话面板（高约视口 2/3，自适应）\n3. **拖动浮层**：拖顶部标题栏移动面板（移出浮层也跟手、不抖）；**双击标题栏**复位到右上角。位置自动记住，刷新/换页后还在\n4. 喂上下文，任选：\n   - **选中网页文字** → 点 **「➕ 添加选中文本」**（同时读网页选区 + 系统剪切板：选区由 background 用 `chrome.scripting.executeScript(allFrames)` 直插每帧读取，**微信读书/千问等 iframe 阅读器也能抓到**；剪切板含输入法复制内容）\n   - **直接发送**：在输入框粘贴/输入并回车，发送时**自动把本次内容（剪贴板或提问文本）收进上下文**\n5. 上下文片段只显示 **10~20 字摘要 + …**（悬停看全文），不可直接编辑；多段累加，右侧 ✕ 单独删除\n6. 回车发送，AI 回答**逐字流式**显示，多轮保持上下文\n7. **状态持久化**：开关/位置/上下文/对话存 `chrome.storage`，刷新或换页后自动重开不丢（手动 ✕ 关闭后记住关闭状态）\n\n---\n\n## 六、分享给别人 / 打包\n\n**`backend/` 是必须的，必须一起打包。** 浏览器扩展只是「UI 外壳」——真正的 AI 能力（连接 CodeBuddy SDK、spawn `codebuddy` CLI、管理 API Key）全在后端。没有 `backend/`，扩展没有 AI 能力、连不上。**所以分享时 `extension/` + `backend/` 两个目录都要带。**\n\n- **不要**只发 `.crx`：现代 Chrome/Edge 禁止本地 `.crx` 安装，发了也装不上。\n- **正确做法**：把整个 `webchat-extension/` 文件夹发给对方 → 对方按上面步骤 `npm install` + 加载 `extension/` +（可选）注册协议。\n- **一键打包（推荐）**：在项目根目录执行 `node pack.mjs` → 自动按 `.gitignore` 在父目录生成干净的 `webchat-extension-share-YYYYMMDD.zip`。**打包出来是一个「二合一」目录 `webchat-extension/`**：\n  - `SKILL.md` 直接位于 `webchat-extension/` **根目录**（满足技能规范：SKILL.md 在根目录或一级目录）。\n  - 同时含 `extension/`、`backend/`（手动安装用）与 `scripts/`、`references/`、`assets/`（agent 技能用）。\n  - 给**不使用 WorkBuddy** 的收件人：用里面的 `extension/` + `backend/` 按上面步骤 `npm install` + 加载扩展即可。\n  - 给**用 WorkBuddy** 的收件人：把整个 `webchat-extension/` 文件夹复制到 `~/.workbuddy/skills/webchat-extension/`，agent 部署时自动注册协议、开箱即用。\n  - 脚本已自动排除 `node_modules/`、`.env`、私钥、`.crx`、`*.log`、`*.cjs`；保留 `.env.example` 模板与技能目录。\n- **⚠️ 收件人还需自备 codebuddy CLI**：本项目不随包分发该 CLI（见「前置依赖」一节）。对方机器若没有 WorkBuddy，需 `npm i -g @tencent-ai/codebuddy-code` 并确保在 `PATH` 上，否则后端连不上（仅 `WEBCHAT_DEMO=1` 演示模式可跑）。\n- **正式广分发**：上架 Chrome / Edge 应用商店，发商店链接。\n- **打包清单**\n  - ✅ 带：`SKILL.md`（技能入口，根目录）、`extension/`（**不含 icons png，加载前由 deploy / gen-icons 自动生成**）、`backend/` 源码（`server.js` `launcher.mjs` `patch-sdk.mjs` `package.json` `package-lock.json` `.env.example`）、`scripts/`（部署脚手架，含内联生成 launcher.vbs + 图标生成）、`references/`（排错表）、`assets/`（技能资源）、`README.md`、`gen-icons.mjs`\n  - ❌ 不带：`backend/node_modules/`（让收件人 `npm install` 即可）、`backend/.env`（含真实 Key）、`extension.pem`/`extension.crx`、**`*.png`（图标不进包，由 agent 部署时生成）**、`*.log`、`*.cjs` 测试草稿、**`launcher.vbs` / `webchat-protocol.reg.example` / `.gitignore`（不随分享包分发；launcher.vbs 由部署脚本自动生成、协议由部署自动注册）**\n  - 这些由打包脚本按 `.gitignore` + 硬性禁止列表排除，打包前确认没混进去。\n\n---\n\n## 七、已知限制 / 注意\n\n- **后端必须本地运行**：插件通过 `http://localhost:3000` 调后端。关掉后端，对话连不上（面板提示连接失败）。\n- **跨域**：后端已开 `CORS *`，开发期够用。上线公网需改具体来源并部署后端。\n- **side_panel**：本方案用「网页内注入浮层（iframe）」而非浏览器侧边栏，兼容性最好。\n- **API Key 安全**：Key 只放后端 `.env`，**绝不进前端**。\n- **真实 AI 能力**：来自 CodeBuddy Agent SDK，模型默认 `deepseek-v4-flash`，可在 `.env` 用 `CODEBUDDY_MODEL=` 改（`auto`/`hy3`/`glm-5.2`/`kimi-k2.x`/`deepseek-v4-*` 等，本账户不支持 `claude-sonnet-4`）。\n\n---\n\n## 八、出问题怎么办\n\n| 现象 | 排查 |\n|---|---|\n| 面板提示「连接后端失败」 | 确认 `cd backend && npm start` 已启动；端口是 3000 |\n| 点「🚀 启动后端」没反应 | 多半是 `webchat://` 协议未注册（见第四节）。可改用面板「📋 复制启动命令」手动 `npm start` |\n| 点图标没反应 | 多见于 `chrome://`、`edge://` 等系统页（扩展无法注入）；普通网页正常。确认扩展已加载且未被禁用 |\n| 选中文字点「添加选中文本」没反应 | 选区读取走 `chrome.scripting.executeScript(allFrames)`，正常能抓 iframe 阅读器；若阅读器是 **sandboxed iframe（无 allow-scripts）** 且屏蔽 copy，则只能手动粘贴/输入发送（发送会自动收上下文）。平台限制非 bug |\n| 收到的是演示（模拟）回复而非真实 AI | 说明设了 `WEBCHAT_DEMO=1`。删掉该变量重启即走登录模式真实 AI；若登录态失效，终端跑一次 `codebuddy` 重新登录，或在 `.env` 填 `CODEBUDDY_API_KEY` 走 Key 模式 |\n| `/api/health` 返回 `demo:true` | 说明设了 `WEBCHAT_DEMO=1`（演示模式）。想要真实 AI 请移除该变量（默认登录模式）或填 Key |\n| **真实模式一直转圈、无回答**（后端日志 `EADDRINUSE` / CLI 卡死） | 官方 CLI 的 prewarm 端口和本机 WorkBuddy 桌面应用撞车。在 `.env` 设 `SERVER__PORT=40123`（或空闲端口）并重启；若环境变量残留旧 `SERVER__PORT`，启动时用 `SERVER__PORT=40123 npm start` 显式覆盖 |\n| 后端报 `400 model [...] service info not found` | 模型名不对，把 `CODEBUDDY_MODEL` 改成 `deepseek-v4-flash`、`hy3` 或 `auto` |\n| **Windows 上每次对话 / 启动后端都弹黑框** | SDK 内部 spawn CLI 默认 `windowsHide:false`。后端 `package.json` 已加 `postinstall` 自动跑 `patch-sdk.mjs` 给 SDK 注入 `windowsHide:true`；`npm install` 后自然生效。若重装后仍弹，手动跑一次 `node backend/patch-sdk.mjs` |\n\nFile v0.1.4:_meta.json\n\n{\n  \"ownerId\": \"kn769gn5we5rgv7bfhb9ztd8j983p8qc\",\n  \"slug\": \"webchat-extension\",\n  \"version\": \"0.1.4\",\n  \"publishedAt\": 1786085047021\n}\n\nFile v0.1.4:references/deploy-guide.md\n\n# 网页划线对话 · 部署与排错指南\n\n本文件是 skill 的详细排错表，配合 `SKILL.md` 使用。扩展版本 1.5.5。\n\n## 〇、前置依赖：codebuddy CLI（外部依赖，不随包分发）\n\n后端通过 `@tencent-ai/agent-sdk` 在运行时 `spawn` 一个 `codebuddy` 子进程来真正调用 AI。`server.js` 的 `resolveCli()` 按序找它：① `CODEBUDDY_CLI_PATH` 显式指定 → ② 系统 `PATH` 上的 `codebuddy` → ③ 兜底 `~/.workbuddy/binaries/node/versions/22.22.2/node_modules/@tencent-ai/codebuddy-code/bin/codebuddy`（仅本机 WorkBuddy 托管环境有）。\n\n- **本机**（装了 WorkBuddy）：托管 Node 已自带 `codebuddy`，开箱可用。\n- **分享给别人的机器若没有 WorkBuddy**：需对方 `npm i -g @tencent-ai/codebuddy-code` 并确保 `codebuddy` 在 `PATH`，或在 `.env` 设 `CODEBUDDY_CLI_PATH` 指向 CLI。否则 `query()` 拉不起进程 → 后端连不上（登录/Key 模式都依赖该 CLI）；仅 `WEBCHAT_DEMO=1` 演示模式可跑通交互闭环。\n\n> 注意：`backend/` 目录**必须随扩展一起分享**——扩展只是 UI 外壳，AI 能力全在后端。\n\n## 一、后端启动与模式\n\n| 步骤 | 命令 | 说明 |\n|---|---|---|\n| 进入后端 | `cd <target>/backend` | — |\n| 安装依赖 | `npm install` | 仅首次；用受管 node 即可 |\n| 复制配置 | `cp .env.example .env` | 按需填 `CODEBUDDY_API_KEY` |\n| 启动 | `npm start` | 默认 `http://localhost:3000` |\n| 健康检查 | `curl http://localhost:3000/api/health` | 返回 `{\"status\":\"ok\",...}` |\n\n**三种模式**\n- 登录模式（默认，零配置）：未填 `CODEBUDDY_API_KEY` 且未设 `WEBCHAT_DEMO`，复用本机 `codebuddy` CLI 已登录凭据走**真实 AI**（首次需终端跑一次 `codebuddy` 登录）。\n- Key 模式（推荐无人值守）：填了 `CODEBUDDY_API_KEY`，用 Key 直连 CodeBuddy AI，不依赖交互登录。\n- 演示模式：显式设 `WEBCHAT_DEMO=1`，后端返回模拟流式回复，验收交互闭环用，无需账号/登录。\n\n---\n\n## 二、现象 → 排查\n\n| 现象 | 原因 / 排查 |\n|---|---|\n| 面板提示「连接后端失败」 | 确认 `cd backend && npm start` 已启动；端口 3000 |\n| 点「🚀 启动后端」没反应 | 多半是 `webchat://` 协议未注册（见第四节）。可改用面板「📋 复制启动命令」手动 `npm start` |\n| 点图标没反应 | 多见于 `chrome://`、`edge://` 等系统页（扩展无法注入）；普通网页正常。确认扩展已加载且未被禁用 |\n| 选中文字点「添加选中文本」没反应 | 选区由 `chrome.scripting.executeScript(allFrames)` 读取，正常能抓微信读书/千问 iframe。若阅读器是 **sandboxed iframe（无 allow-scripts）** 或屏蔽 copy，则只能手动粘贴/输入到输入框发送（发送自动收上下文）。属平台限制非 bug |\n| 收到的是演示（模拟）回复 | 说明设了 `WEBCHAT_DEMO=1`。删掉它重启即走登录模式真实 AI；登录态失效则终端跑一次 `codebuddy` 重登，或 `.env` 填 `CODEBUDDY_API_KEY` 走 Key 模式 |\n| `/api/health` 返回 `demo:true` | 说明设了 `WEBCHAT_DEMO=1`（演示模式）；移除该变量走默认登录模式真实 AI，或填 Key |\n| **真实模式一直转圈、面板无回答**（后端日志 `EADDRINUSE` / CLI 卡死） | 官方 CLI 的 prewarm 端口与 WorkBuddy 桌面应用撞车。在 `.env` 设 `SERVER__PORT=40123`（或空闲端口）并重启；若环境变量残留旧 `SERVER__PORT`，启动时用 `SERVER__PORT=40123 npm start` 显式覆盖 |\n| 后端报 `400 model [...] service info not found` | 模型名不对，把 `CODEBUDDY_MODEL` 改成 `deepseek-v4-flash`、`hy3` 或 `auto`（本账户不支持 `claude-sonnet-4`） |\n| 后端报 `initialize` 超时 / 永远 0 字节 | 用了 WorkBuddy 自带那份 cli（协议不匹配）。必须用官方 `@tencent-ai/codebuddy-code`；`server.js` 的 `resolveCli()` 已自动定位，必要时用 `CODEBUDDY_CLI_PATH` 显式指定 |\n| 拖拽抖动 / 跳左上角 | 扩展 V1.5.2 已修复拖拽坐标公式；若仍异常，扩展管理页「重新加载」并确认 manifest 版本 ≥ 1.5.2 |\n| **Windows 上每次对话 / 启动后端弹黑框** | SDK 内部 spawn CLI 默认 `windowsHide:false`。`package.json` 的 `postinstall` 会自动跑 `patch-sdk.mjs` 给 `@tencent-ai/agent-sdk` 的 `process-transport.js` 两处 spawn 注入 `windowsHide:true`；`npm install` 后即生效。若依赖是手动装、跳过了 postinstall，运行一次 `node backend/patch-sdk.mjs` 即可 |\n\n---\n\n## 三、端口冲突根因说明\n\n官方 `@tencent-ai/codebuddy-code` 启动时会起一个 prewarm 本地 server，端口由 `SERVER__PORT` 环境变量控制。本机 **WorkBuddy 桌面应用自身也会起同类 server 占端口**（实测占 54975 之类），两者撞车 → CLI 一绑定就 `EADDRINUSE` → SDK `query()` 永远 0 字节超时。\n\n- `server.js` 启动时会自动分配空闲端口注入 `SERVER__PORT`（兜底）。\n- 若自动分配仍冲突（极少见），在 `.env` 显式 `SERVER__PORT=40123` 并重启。\n- dotenv **不会覆盖已存在的环境变量**，所以如果当前 shell 里残留 `SERVER__PORT=旧值`，必须用 `SERVER__PORT=40123 npm start` 显式传，或在新 shell 里启动。\n\n---\n\n## 四、一键启动（webchat:// 协议注册）\n\n面板「🚀 启动后端」按钮（以及离线横幅里的启动按钮）靠自定义协议 `webchat://start` 免终端拉起后端。这要求 **Windows 已注册协议处理器**（让系统知道遇到 `webchat://` 就调用 `launcher.vbs`）。\n\n- **由 agent 按 skill 部署**：`node scripts/deploy.mjs` 在 Windows 上自动写入注册表（HKCU，无需管理员），开箱即用。非 Windows 或加了 `--no-protocol` 时跳过。\n- **手动 / 分享给别人**：二选一\n  1. 把 `webchat-protocol.reg.example` 里的 `__BACKEND_DIR__` 替换为真实 `backend` 绝对路径（反斜杠写成 `\\\\`），存为 `webchat-protocol.reg` 双击导入；\n  2. 或命令行：`reg add \"HKCU\\Software\\Classes\\webchat\\shell\\open\\command\" /ve /t REG_SZ /d \"\\\"C:\\Windows\\System32\\wscript.exe\\\" \\\"<backend路径>\\launcher.vbs\\\" \\\"%1\\\"\" /f`（并建好 `webchat` 主键与 `URL Protocol` 值，详见 .reg.example 头部注释）。\n- **注册内容**：`HKCU\\Software\\Classes\\webchat`（`URL Protocol=\"\"`）+ `shell\\open\\command` → `\"C:\\Windows\\System32\\wscript.exe\" \"<backend>\\launcher.vbs\" \"%1\"`。\n- **未注册时**：按钮点了没反应，但可用面板「📋 复制启动命令」手动 `npm start`，功能不受影响。\n\n---\n\n## 五、后端生命周期（心跳托管）\n\n后端由 `webchat://start` 协议（面板按钮）经 `launcher.vbs → launcher.mjs` 拉起。`launcher.mjs` 探测端口，未占用则以**托管模式**（`WEBCHAT_MANAGED=1`）用 `spawn(detached)` 拉起 `server.js`，随后自身退出——**后端作为独立进程运行，不与启动器绑定**。\n\n生命周期完全由「扩展心跳」驱动，**不依赖任何浏览器进程名**，因此 Chrome / Edge / 千问 / 夸克 / 任意 Chromium 内核通用：\n\n- `background.js` 用 `chrome.alarms`（约每 60s）POST `/api/heartbeat` 续命，`server.js` 记录 `lastHeartbeat`。\n- `server.js` 的看门狗每 5s 检查：若 `Date.now() - lastHeartbeat > HEARTBEAT_TTL` 则 `process.exit(0)` 自退。\n- 浏览器开着 → 心跳不断 → 后端存活；浏览器关闭 → service worker 被回收、alarms 停 → 心跳断 → 约 `HEARTBEAT_TTL`（默认 2.5min，覆盖 SW 闹钟节流）后后端自退。\n- 另有「无请求自退」兜底：连续 `IDLE_TIMEOUT_MIN`（默认 30min）无任何请求，后端自退。\n\n**想立即停**：面板「⏹ 停止后端」按钮（`POST /api/stop`）或 `curl -X POST http://localhost:3000/api/stop`。\n\n**可调项（`.env`）**\n- `HEARTBEAT_TTL`（毫秒，默认 150000）：心跳宽限，浏览器关后多久自退。\n- `IDLE_TIMEOUT_MIN`（分钟，默认 30）：空闲自退时长。\n- ⚠️ 旧的 `WEBCHAT_BROWSER_PROCS` 配置**已废弃**，心跳机制不再读取它，无需设置。\n\n---\n\n## 六、安全须知\n\n- API Key 只放后端 `.env`，**绝不进前端**。\n- 跨域：后端 `CORS *` 开发期够用；公网部署需改成具体来源。\n- 后端必须本地运行；关掉后端对话连不上（面板提示连接失败）。\n- 分享包不要带：`extension.pem`（签名私钥）、`extension.crx`、`backend/.env`（Key）、`*.log`、测试草稿 `*.cjs`（已在 `.gitignore` 忽略）。\n\nFile v0.1.4:skill-card.md\n\n## Description:\n\nDeploys a Chromium browser extension and local Node.js backend that let an agent help users set up page-selection chat with streaming CodeBuddy AI responses.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[noaheleven](https://clawhub.ai/user/noaheleven)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and technically oriented users use this skill to deploy a local web-selection chat tool for Chromium browsers. The skill guides setup of the extension, backend, authentication mode, startup flow, troubleshooting, and packaging steps.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The extension and local backend can access selected page text, clipboard content, stored chat history, and CodeBuddy account context.\n\nMitigation: Avoid use on pages containing secrets, private messages, customer data, or internal documents unless the user accepts that selected or copied context and chat history may be sent to the local backend and CodeBuddy AI.\n\nRisk: Local backend controls are weak for routine use.\n\nMitigation: Prefer running without protocol registration unless one-click startup is required, clear stored extension data regularly, and add origin restrictions or a local authentication token before regular use.\n\nRisk: The security scanner verdict is suspicious because the release combines broad extension access with local backend and account-context access.\n\nMitigation: Review the skill carefully before installing and scan the release before deployment.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/noaheleven/skills/webchat-extension)\n- [Deployment and troubleshooting guide](references/deploy-guide.md)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown guidance with inline shell commands, configuration values, and file paths]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May produce deployment steps for a browser extension, local backend, protocol registration, authentication mode selection, and troubleshooting.]\n\n## Skill Version(s):\n\n0.1.4 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v0.1.4:assets/backend/package-lock.json\n\n{\n  \"name\": \"webchat-backend\",\n  \"version\": \"1.0.0\",\n  \"lockfileVersion\": 3,\n  \"requires\": true,\n  \"packages\": {\n    \"\": {\n      \"name\": \"webchat-backend\",\n      \"version\": \"1.0.0\",\n      \"dependencies\": {\n        \"@tencent-ai/agent-sdk\": \"^0.3.43\",\n        \"cors\": \"^2.8.5\",\n        \"dotenv\": \"^16.4.5\",\n        \"express\": \"^4.18.2\"\n      }\n    },\n    \"node_modules/@agentclientprotocol/sdk\": {\n      \"version\": \"0.25.1\",\n      \"resolved\": \"https://registry.npmjs.org/@agentclientprotocol/sdk/-/sdk-0.25.1.tgz\",\n      \"integrity\": \"sha512-jx2rF3bdpGwZ75Q/meyEDLLbYmbtxk82Uh9hDCdxDvcEedBnNSF5hZAnL/kJR5VNz56JqwOmqnAqasC84MwwkQ==\",\n      \"license\": \"Apache-2.0\",\n      \"peerDependencies\": {\n        \"zod\": \"^3.25.0 || ^4.0.0\"\n      }\n    },\n    \"node_modules/@hono/node-server\": {\n      \"version\": \"1.19.14\",\n      \"resolved\": \"https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.14.tgz\",\n      \"integrity\": \"sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=18.14.1\"\n      },\n      \"peerDependencies\": {\n        \"hono\": \"^4\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk\": {\n      \"version\": \"1.29.0\",\n      \"resolved\": \"https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.29.0.tgz\",\n      \"integrity\": \"sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"@hono/node-server\": \"^1.19.9\",\n        \"ajv\": \"^8.17.1\",\n        \"ajv-formats\": \"^3.0.1\",\n        \"content-type\": \"^1.0.5\",\n        \"cors\": \"^2.8.5\",\n        \"cross-spawn\": \"^7.0.5\",\n        \"eventsource\": \"^3.0.2\",\n        \"eventsource-parser\": \"^3.0.0\",\n        \"express\": \"^5.2.1\",\n        \"express-rate-limit\": \"^8.2.1\",\n        \"hono\": \"^4.11.4\",\n        \"jose\": \"^6.1.3\",\n        \"json-schema-typed\": \"^8.0.2\",\n        \"pkce-challenge\": \"^5.0.0\",\n        \"raw-body\": \"^3.0.0\",\n        \"zod\": \"^3.25 || ^4.0\",\n        \"zod-to-json-schema\": \"^3.25.1\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"peerDependencies\": {\n        \"@cfworker/json-schema\": \"^4.1.1\",\n        \"zod\": \"^3.25 || ^4.0\"\n      },\n      \"peerDependenciesMeta\": {\n        \"@cfworker/json-schema\": {\n          \"optional\": true\n        },\n        \"zod\": {\n          \"optional\": false\n        }\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/accepts\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz\",\n      \"integrity\": \"sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"mime-types\": \"^3.0.0\",\n        \"negotiator\": \"^1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/body-parser\": {\n      \"version\": \"2.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz\",\n      \"integrity\": \"sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"bytes\": \"^3.1.2\",\n        \"content-type\": \"^2.0.0\",\n        \"debug\": \"^4.4.3\",\n        \"http-errors\": \"^2.0.1\",\n        \"iconv-lite\": \"^0.7.2\",\n        \"on-finished\": \"^2.4.1\",\n        \"qs\": \"^6.15.2\",\n        \"raw-body\": \"^3.0.2\",\n        \"type-is\": \"^2.1.0\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/node_modules/content-type\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz\",\n      \"integrity\": \"sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/content-disposition\": {\n      \"version\": \"1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz\",\n      \"integrity\": \"sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/cookie-signature\": {\n      \"version\": \"1.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz\",\n      \"integrity\": \"sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=6.6.0\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/debug\": {\n      \"version\": \"4.4.3\",\n      \"resolved\": \"https://registry.npmjs.org/debug/-/debug-4.4.3.tgz\",\n      \"integrity\": \"sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"ms\": \"^2.1.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6.0\"\n      },\n      \"peerDependenciesMeta\": {\n        \"supports-color\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/express\": {\n      \"version\": \"5.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/express/-/express-5.2.1.tgz\",\n      \"integrity\": \"sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"accepts\": \"^2.0.0\",\n        \"body-parser\": \"^2.2.1\",\n        \"content-disposition\": \"^1.0.0\",\n        \"content-type\": \"^1.0.5\",\n        \"cookie\": \"^0.7.1\",\n        \"cookie-signature\": \"^1.2.1\",\n        \"debug\": \"^4.4.0\",\n        \"depd\": \"^2.0.0\",\n        \"encodeurl\": \"^2.0.0\",\n        \"escape-html\": \"^1.0.3\",\n        \"etag\": \"^1.8.1\",\n        \"finalhandler\": \"^2.1.0\",\n        \"fresh\": \"^2.0.0\",\n        \"http-errors\": \"^2.0.0\",\n        \"merge-descriptors\": \"^2.0.0\",\n        \"mime-types\": \"^3.0.0\",\n        \"on-finished\": \"^2.4.1\",\n        \"once\": \"^1.4.0\",\n        \"parseurl\": \"^1.3.3\",\n        \"proxy-addr\": \"^2.0.7\",\n        \"qs\": \"^6.14.0\",\n        \"range-parser\": \"^1.2.1\",\n        \"router\": \"^2.2.0\",\n        \"send\": \"^1.1.0\",\n        \"serve-static\": \"^2.2.0\",\n        \"statuses\": \"^2.0.1\",\n        \"type-is\": \"^2.0.1\",\n        \"vary\": \"^1.1.2\"\n      },\n      \"engines\": {\n        \"node\": \">= 18\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/finalhandler\": {\n      \"version\": \"2.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz\",\n      \"integrity\": \"sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"debug\": \"^4.4.0\",\n        \"encodeurl\": \"^2.0.0\",\n        \"escape-html\": \"^1.0.3\",\n        \"on-finished\": \"^2.4.1\",\n        \"parseurl\": \"^1.3.3\",\n        \"statuses\": \"^2.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">= 18.0.0\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/fresh\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz\",\n      \"integrity\": \"sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.8\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/iconv-lite\": {\n      \"version\": \"0.7.3\",\n      \"resolved\": \"https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz\",\n      \"integrity\": \"sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"safer-buffer\": \">= 2.1.2 < 3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/media-typer\": {\n      \"version\": \"1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz\",\n      \"integrity\": \"sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.8\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/merge-descriptors\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz\",\n      \"integrity\": \"sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/mime-db\": {\n      \"version\": \"1.54.0\",\n      \"resolved\": \"https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz\",\n      \"integrity\": \"sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/mime-types\": {\n      \"version\": \"3.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz\",\n      \"integrity\": \"sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"mime-db\": \"^1.54.0\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/ms\": {\n      \"version\": \"2.1.3\",\n      \"resolved\": \"https://registry.npmjs.org/ms/-/ms-2.1.3.tgz\",\n      \"integrity\": \"sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/negotiator\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz\",\n      \"integrity\": \"sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/send\": {\n      \"version\": \"1.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/send/-/send-1.2.1.tgz\",\n      \"integrity\": \"sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"debug\": \"^4.4.3\",\n        \"encodeurl\": \"^2.0.0\",\n        \"escape-html\": \"^1.0.3\",\n        \"etag\": \"^1.8.1\",\n        \"fresh\": \"^2.0.0\",\n        \"http-errors\": \"^2.0.1\",\n        \"mime-types\": \"^3.0.2\",\n        \"ms\": \"^2.1.3\",\n        \"on-finished\": \"^2.4.1\",\n        \"range-parser\": \"^1.2.1\",\n        \"statuses\": \"^2.0.2\"\n      },\n      \"engines\": {\n        \"node\": \">= 18\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/serve-static\": {\n      \"version\": \"2.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz\",\n      \"integrity\": \"sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"encodeurl\": \"^2.0.0\",\n        \"escape-html\": \"^1.0.3\",\n        \"parseurl\": \"^1.3.3\",\n        \"send\": \"^1.2.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 18\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/type-is\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz\",\n      \"integrity\": \"sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"content-type\": \"^2.0.0\",\n        \"media-typer\": \"^1.1.0\",\n        \"mime-types\": \"^3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 18\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/@modelcontextprotocol/sdk/node_modules/type-is/node_modules/content-type\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz\",\n      \"integrity\": \"sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/@tencent-ai/agent-sdk\": {\n      \"version\": \"0.3.202\",\n      \"resolved\": \"https://registry.npmjs.org/@tencent-ai/agent-sdk/-/agent-sdk-0.3.202.tgz\",\n      \"integrity\": \"sha512-hZ9/ymDTv3RmuualZeDZ64wPQwEJXidfqEofeNaKcWhTsuzxN6quc3yeVFdsZudDnSinA6Sm+tUNWQipmFye2A==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"@agentclientprotocol/sdk\": \"^0.25.0\",\n        \"@modelcontextprotocol/sdk\": \"^1.29.0\"\n      },\n      \"peerDependencies\": {\n        \"zod\": \"^4.0.0\"\n      }\n    },\n    \"node_modules/accepts\": {\n      \"version\": \"1.3.8\",\n      \"resolved\": \"https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz\",\n      \"integrity\": \"sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"mime-types\": \"~2.1.34\",\n        \"negotiator\": \"0.6.3\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/ajv\": {\n      \"version\": \"8.20.0\",\n      \"resolved\": \"https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz\",\n      \"integrity\": \"sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"fast-deep-equal\": \"^3.1.3\",\n        \"fast-uri\": \"^3.0.1\",\n        \"json-schema-traverse\": \"^1.0.0\",\n        \"require-from-string\": \"^2.0.2\"\n      },\n      \"funding\": {\n        \"type\": \"github\",\n        \"url\": \"https://github.com/sponsors/epoberezkin\"\n      }\n    },\n    \"node_modules/ajv-formats\": {\n      \"version\": \"3.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz\",\n      \"integrity\": \"sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"ajv\": \"^8.0.0\"\n      },\n      \"peerDependencies\": {\n        \"ajv\": \"^8.0.0\"\n      },\n      \"peerDependenciesMeta\": {\n        \"ajv\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/array-flatten\": {\n      \"version\": \"1.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz\",\n      \"integrity\": \"sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/body-parser\": {\n      \"version\": \"1.20.5\",\n      \"resolved\": \"https://registry.npmjs.org/body-parser/-/body-parser-1.20.5.tgz\",\n      \"integrity\": \"sha512-3grm+/2tUOvu2cjJkvsIxrv/wVpfXQW4PsQHYm7yk4vfpu7Ekl6nEsYBoJUL6qDwZUx8wUhQ8tR2qz+ad9c9OA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"bytes\": \"~3.1.2\",\n        \"content-type\": \"~1.0.5\",\n        \"debug\": \"2.6.9\",\n        \"depd\": \"2.0.0\",\n        \"destroy\": \"~1.2.0\",\n        \"http-errors\": \"~2.0.1\",\n        \"iconv-lite\": \"~0.4.24\",\n        \"on-finished\": \"~2.4.1\",\n        \"qs\": \"~6.15.1\",\n        \"raw-body\": \"~2.5.3\",\n        \"type-is\": \"~1.6.18\",\n        \"unpipe\": \"~1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.8\",\n        \"npm\": \"1.2.8000 || >= 1.4.16\"\n      }\n    },\n    \"node_modules/body-parser/node_modules/raw-body\": {\n      \"version\": \"2.5.3\",\n      \"resolved\": \"https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz\",\n      \"integrity\": \"sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"bytes\": \"~3.1.2\",\n        \"http-errors\": \"~2.0.1\",\n        \"iconv-lite\": \"~0.4.24\",\n        \"unpipe\": \"~1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.8\"\n      }\n    },\n    \"node_modules/bytes\": {\n      \"version\": \"3.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz\",\n      \"integrity\": \"sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.8\"\n      }\n    },\n    \"node_modules/call-bind-apply-helpers\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz\",\n      \"integrity\": \"sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"es-errors\": \"^1.3.0\",\n        \"function-bind\": \"^1.1.2\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      }\n    },\n    \"node_modules/call-bound\": {\n      \"version\": \"1.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz\",\n      \"integrity\": \"sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"call-bind-apply-helpers\": \"^1.0.2\",\n        \"get-intrinsic\": \"^1.3.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/content-disposition\": {\n      \"version\": \"0.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz\",\n      \"integrity\": \"sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"safe-buffer\": \"5.2.1\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/content-type\": {\n      \"version\": \"1.0.5\",\n      \"resolved\": \"https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz\",\n      \"integrity\": \"sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/cookie\": {\n      \"version\": \"0.7.2\",\n      \"resolved\": \"https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz\",\n      \"integrity\": \"sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/cookie-signature\": {\n      \"version\": \"1.0.7\",\n      \"resolved\": \"https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz\",\n      \"integrity\": \"sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/cors\": {\n      \"version\": \"2.8.6\",\n      \"resolved\": \"https://registry.npmjs.org/cors/-/cors-2.8.6.tgz\",\n      \"integrity\": \"sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"object-assign\": \"^4\",\n        \"vary\": \"^1\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.10\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/cross-spawn\": {\n      \"version\": \"7.0.6\",\n      \"resolved\": \"https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz\",\n      \"integrity\": \"sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"path-key\": \"^3.1.0\",\n        \"shebang-command\": \"^2.0.0\",\n        \"which\": \"^2.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">= 8\"\n      }\n    },\n    \"node_modules/debug\": {\n      \"version\": \"2.6.9\",\n      \"resolved\": \"https://registry.npmjs.org/debug/-/debug-2.6.9.tgz\",\n      \"integrity\": \"sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"ms\": \"2.0.0\"\n      }\n    },\n    \"node_modules/depd\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/depd/-/depd-2.0.0.tgz\",\n      \"integrity\": \"sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.8\"\n      }\n    },\n    \"node_modules/destroy\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz\",\n      \"integrity\": \"sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.8\",\n        \"npm\": \"1.2.8000 || >= 1.4.16\"\n      }\n    },\n    \"node_modules/dotenv\": {\n      \"version\": \"16.6.1\",\n      \"resolved\": \"https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz\",\n      \"integrity\": \"sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==\",\n      \"license\": \"BSD-2-Clause\",\n      \"engines\": {\n        \"node\": \">=12\"\n      },\n      \"funding\": {\n        \"url\": \"https://dotenvx.com\"\n      }\n    },\n    \"node_modules/dunder-proto\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz\",\n      \"integrity\": \"sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"call-bind-apply-helpers\": \"^1.0.1\",\n        \"es-errors\": \"^1.3.0\",\n        \"gopd\": \"^1.2.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      }\n    },\n    \"node_modules/ee-first\": {\n      \"version\": \"1.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz\",\n      \"integrity\": \"sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/encodeurl\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz\",\n      \"integrity\": \"sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.8\"\n      }\n    },\n    \"node_modules/es-define-property\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz\",\n      \"integrity\": \"sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      }\n    },\n    \"node_modules/es-errors\": {\n      \"version\": \"1.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz\",\n      \"integrity\": \"sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      }\n    },\n    \"node_modules/es-object-atoms\": {\n      \"version\": \"1.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz\",\n      \"integrity\": \"sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"es-errors\": \"^1.3.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      }\n    },\n    \"node_modules/escape-html\": {\n      \"version\": \"1.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz\",\n      \"integrity\": \"sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/etag\": {\n      \"version\": \"1.8.1\",\n      \"resolved\": \"https://registry.npmjs.org/etag/-/etag-1.8.1.tgz\",\n      \"integrity\": \"sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/eventsource\": {\n      \"version\": \"3.0.7\",\n      \"resolved\": \"https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz\",\n      \"integrity\": \"sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"eventsource-parser\": \"^3.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">=18.0.0\"\n      }\n    },\n    \"node_modules/eventsource-parser\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.1.0.tgz\",\n      \"integrity\": \"sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=18.0.0\"\n      }\n    },\n    \"node_modules/express\": {\n      \"version\": \"4.22.2\",\n      \"resolved\": \"https://registry.npmjs.org/express/-/express-4.22.2.tgz\",\n      \"integrity\": \"sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"accepts\": \"~1.3.8\",\n        \"array-flatten\": \"1.1.1\",\n        \"body-parser\": \"~1.20.5\",\n        \"content-disposition\": \"~0.5.4\",\n        \"content-type\": \"~1.0.4\",\n        \"cookie\": \"~0.7.1\",\n        \"cookie-signature\": \"~1.0.6\",\n        \"debug\": \"2.6.9\",\n        \"depd\": \"2.0.0\",\n        \"encodeurl\": \"~2.0.0\",\n        \"escape-html\": \"~1.0.3\",\n        \"etag\": \"~1.8.1\",\n        \"finalhandler\": \"~1.3.1\",\n        \"fresh\": \"~0.5.2\",\n        \"http-errors\": \"~2.0.0\",\n        \"merge-descriptors\": \"1.0.3\",\n        \"methods\": \"~1.1.2\",\n        \"on-finished\": \"~2.4.1\",\n        \"parseurl\": \"~1.3.3\",\n        \"path-to-regexp\": \"~0.1.12\",\n        \"proxy-addr\": \"~2.0.7\",\n        \"qs\": \"~6.15.1\",\n        \"range-parser\": \"~1.2.1\",\n        \"safe-buffer\": \"5.2.1\",\n        \"send\": \"~0.19.0\",\n        \"serve-static\": \"~1.16.2\",\n        \"setprototypeof\": \"1.2.0\",\n        \"statuses\": \"~2.0.1\",\n        \"type-is\": \"~1.6.18\",\n        \"utils-merge\": \"1.0.1\",\n        \"vary\": \"~1.1.2\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.10.0\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/express-rate-limit\": {\n      \"version\": \"8.5.2\",\n      \"resolved\": \"https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.5.2.tgz\",\n      \"integrity\": \"sha512-5Kb34ipNX694DH48vN9irak1Qx30nb0PLYHXfJgw4YEjiC3ZEmZJhwOp+VfiCYwFzvFTdB9QkArYS5kXa2cx2A==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"ip-address\": \"^10.2.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 16\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/express-rate-limit\"\n      },\n      \"peerDependencies\": {\n        \"express\": \">= 4.11\"\n      }\n    },\n    \"node_modules/fast-deep-equal\": {\n      \"version\": \"3.1.3\",\n      \"resolved\": \"https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz\",\n      \"integrity\": \"sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/fast-uri\": {\n      \"version\": \"3.1.3\",\n      \"resolved\": \"https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.3.tgz\",\n      \"integrity\": \"sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg==\",\n      \"funding\": [\n        {\n          \"type\": \"github\",\n          \"url\": \"https://github.com/sponsors/fastify\"\n        },\n        {\n          \"type\": \"opencollective\",\n          \"url\": \"https://opencollective.com/fastify\"\n        }\n      ],\n      \"license\": \"BSD-3-Clause\"\n    },\n    \"node_modules/finalhandler\": {\n      \"version\": \"1.3.2\",\n      \"resolved\": \"https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz\",\n      \"integrity\": \"sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"debug\": \"2.6.9\",\n        \"encodeurl\": \"~2.0.0\",\n        \"escape-html\": \"~1.0.3\",\n        \"on-finished\": \"~2.4.1\",\n        \"parseurl\": \"~1.3.3\",\n        \"statuses\": \"~2.0.2\",\n        \"unpipe\": \"~1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.8\"\n      }\n    },\n    \"node_modules/forwarded\": {\n      \"version\": \"0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz\",\n      \"integrity\": \"sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/fresh\": {\n      \"version\": \"0.5.2\",\n      \"resolved\": \"https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz\",\n      \"integrity\": \"sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/function-bind\": {\n      \"version\": \"1.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz\",\n      \"integrity\": \"sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==\",\n      \"license\": \"MIT\",\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/get-intrinsic\": {\n      \"version\": \"1.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz\",\n      \"integrity\": \"sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"call-bind-apply-helpers\": \"^1.0.2\",\n        \"es-define-property\": \"^1.0.1\",\n        \"es-errors\": \"^1.3.0\",\n        \"es-object-atoms\": \"^1.1.1\",\n        \"function-bind\": \"^1.1.2\",\n        \"get-proto\": \"^1.0.1\",\n        \"gopd\": \"^1.2.0\",\n        \"has-symbols\": \"^1.1.0\",\n        \"hasown\": \"^2.0.2\",\n        \"math-intrinsics\": \"^1.1.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/get-proto\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz\",\n      \"integrity\": \"sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"dunder-proto\": \"^1.0.1\",\n        \"es-object-atoms\": \"^1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      }\n    },\n    \"node_modules/gopd\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz\",\n      \"integrity\": \"sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/has-symbols\": {\n      \"version\": \"1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz\",\n      \"integrity\": \"sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/hasown\": {\n      \"version\": \"2.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz\",\n      \"integrity\": \"sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"function-bind\": \"^1.1.2\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      }\n    },\n    \"node_modules/hono\": {\n      \"version\": \"4.12.28\",\n      \"resolved\": \"https://registry.npmjs.org/hono/-/hono-4.12.28.tgz\",\n      \"integrity\": \"sha512-YwUvVpSF7m1yOblFPrU3Hbo8XhPheBoiyfGuII6z19LnOr6JpDnyyp7LFNrfV56wS8tpvtBFGRISHN02pDdLOA==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=16.9.0\"\n      }\n    },\n    \"node_modules/http-errors\": {\n      \"version\": \"2.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz\",\n      \"integrity\": \"sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"depd\": \"~2.0.0\",\n        \"inherits\": \"~2.0.4\",\n        \"setprototypeof\": \"~1.2.0\",\n        \"statuses\": \"~2.0.2\",\n        \"toidentifier\": \"~1.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.8\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\n      }\n    },\n    \"node_modules/iconv-lite\": {\n      \"version\": \"0.4.24\",\n      \"resolved\": \"https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz\",\n      \"integrity\": \"sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"safer-buffer\": \">= 2.1.2 < 3\"\n      },\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/inherits\": {\n      \"version\": \"2.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz\",\n      \"integrity\": \"sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==\",\n      \"license\": \"ISC\"\n    },\n    \"node_modules/ip-address\": {\n      \"version\": \"10.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz\",\n      \"integrity\": \"sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 12\"\n      }\n    },\n    \"node_modules/ipaddr.js\": {\n      \"version\": \"1.9.1\",\n      \"resolved\": \"https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz\",\n      \"integrity\": \"sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.10\"\n      }\n    },\n    \"node_modules/is-promise\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz\",\n      \"integrity\": \"sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/isexe\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz\",\n      \"integrity\": \"sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==\",\n      \"license\": \"ISC\"\n    },\n    \"node_modules/jose\": {\n      \"version\": \"6.2.3\",\n      \"resolved\": \"https://registry.npmjs.org/jose/-/jose-6.2.3.tgz\",\n      \"integrity\": \"sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==\",\n      \"license\": \"MIT\",\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/panva\"\n      }\n    },\n    \"node_modules/json-schema-traverse\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz\",\n      \"integrity\": \"sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/json-schema-typed\": {\n      \"version\": \"8.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz\",\n      \"integrity\": \"sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==\",\n      \"license\": \"BSD-2-Clause\"\n    },\n    \"node_modules/math-intrinsics\": {\n      \"version\": \"1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz\",\n      \"integrity\": \"sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      }\n    },\n    \"node_modules/media-typer\": {\n      \"version\": \"0.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz\",\n      \"integrity\": \"sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/merge-descriptors\": {\n      \"version\": \"1.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz\",\n      \"integrity\": \"sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==\",\n      \"license\": \"MIT\",\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/methods\": {\n      \"version\": \"1.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/methods/-/methods-1.1.2.tgz\",\n      \"integrity\": \"sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/mime\": {\n      \"version\": \"1.6.0\",\n      \"resolved\": \"https://registry.npmjs.org/mime/-/mime-1.6.0.tgz\",\n      \"integrity\": \"sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==\",\n      \"license\": \"MIT\",\n      \"bin\": {\n        \"mime\": \"cli.js\"\n      },\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/mime-db\": {\n      \"version\": \"1.52.0\",\n      \"resolved\": \"https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz\",\n      \"integrity\": \"sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/mime-types\": {\n      \"version\": \"2.1.35\",\n      \"resolved\": \"https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz\",\n      \"integrity\": \"sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"mime-db\": \"1.52.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/ms\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/ms/-/ms-2.0.0.tgz\",\n      \"integrity\": \"sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/negotiator\": {\n      \"version\": \"0.6.3\",\n      \"resolved\": \"https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz\",\n      \"integrity\": \"sha512-+EUsqGPLsM+j/zdChZjsnX51g\n\nArchive v0.1.3: 3 files, 7629 bytes\n\nFiles: skill-card.md (2122b), SKILL.md (13437b), _meta.json (136b)\n\nArchive v0.1.2: 3 files, 6739 bytes\n\nFiles: skill-card.md (2417b), SKILL.md (11146b), _meta.json (136b)\n\nArchive v0.1.1: 3 files, 6690 bytes\n\nFiles: skill-card.md (2243b), SKILL.md (11146b), _meta.json (136b)\n\nArchive v0.1.0: 3 files, 5509 bytes\n\nFiles: skill-card.md (2315b), SKILL.md (8035b), _meta.json (136b)","readmeExcerpt":"Skill: webchat-extension Owner: noaheleven Summary: 部署「网页划线对话」浏览器扩展（Chrome MV3 / 兼容 Chrome·Edge·千问·夸克 等 Chromium 内核浏览器）。在任意网页选中文字，点工具栏图标唤起可拖动对话浮层，带着网页上下文用 CodeBuddy AI 流式问答。包含本地 Express + SSE 后端（CodeBuddy Agent SDK）与前端扩展。当用户要「做一个网页划词对话插件 / 给浏览器装个网页对话工具 / 选中文字问 AI / 部署小虾网页对话扩展 / web highlight chat extension / 把网页内容丢给 AI 聊」时使用本技能。 Tags: latest:0.1.5 Version history: v0.1.5 | 2026-08-07T06:54:40.332Z | user 本地最新版原样同步 v0","codeSnippets":[],"executableExamples":[{"language":"text","snippet":"浏览器扩展 (Chrome MV3)                本地后端 (Express + SSE)\n┌──────────────────────────┐          ┌────────────────────────────┐\n│ 点工具栏图标 → 浮层(iframe) │──fetch──▶│  /api/chat  (SSE 流式)      │\n│ content.js 注入网页          │          │  query() → codebuddy CLI    │\n│ background.js service worker│          │  (CodeBuddy Agent SDK)      │\n│ 选区经 executeScript 跨 iframe│         │  buildSystemPrompt 注入网页上下文│\n└──────────────────────────┘          └────────────────────────────┘"},{"language":"text","snippet":"webchat-extension/\n├── SKILL.md\n├── pack.mjs                  # 发布工具：在 deploy 产物(双形态目录)下 node pack.mjs → 生成干净分享包 zip\n├── gen-icons.mjs             # 独立图标生成（零依赖）：node gen-icons.mjs [dir]\n├── scripts/\n│   ├── deploy.mjs            # 脚手架：复制 assets 源码 + npm install + 生成 icons/（Windows 部署时生成 launcher.vbs + 注册协议）\n│   ├── gen-vbs.mjs           # 唯一 source of truth：写出 backend/launcher.vbs（agent 部署时调用，不随包分发）\n│   └── register-protocol.cjs # 一键注册/修复 webchat:// 协议（协议丢失或被识别成 Store 应用时用）\n├── assets/\n│   ├── extension/            # 浏览器扩展（manifest/background/content/panel.*/icons）\n│   ├── backend/              # server.js / launcher.mjs / patch-sdk.mjs / package.json / .env.example（launcher.vbs 由 agent 在部署时用 scripts/gen-vbs.mjs 生成，不随包分发）\n│   └── root/                 # 部署到目标根目录的文档：README.md（.gitignore / 协议模板不随包分发）\n└── references/deploy-guide.md  # 详细排错表"},{"language":"bash","snippet":"cd <target>            # 例如 ~/webchat-extension\nnode pack.mjs         # 在父目录生成 webchat-extension-share-YYYYMMDD.zip"},{"language":"text","snippet":"webchat-extension/\n├── README.md\n├── webchat-protocol.reg.example   # 仅仓库内模板，不随分享包分发（协议改由部署脚本自动注册）\n├── pack.mjs                       # 一键打包分享 zip（按 .gitignore 排除 node_modules/.env/私钥等）\n├── extension/                     # 浏览器扩展（Chrome MV3）\n│   ├── manifest.json\n│   ├── background.js              # service worker：图标点击→开关浮层；心跳 ping 后端\n│   ├── content.js                 # 注入网页：开/关浮层、读选区、状态持久化、触发协议\n│   ├── panel.html / panel.js / panel.css   # 对话浮层界面与逻辑\n│   └── icons/                     # 图标 icon16/32/48/128.png（分享包不含，由 deploy/gen-icons 自动生成）\n└── backend/                       # AI 后端（Express + CodeBuddy SDK + SSE）\n    ├── server.js                  # /api/chat(SSE) /api/health /api/heartbeat /api/stop\n    ├── launcher.mjs               # 协议触发：托管模式静默拉起 server.js\n    ├── launcher.vbs               # 隐藏窗口启动 launcher.mjs（由 agent 在部署时用 scripts/gen-vbs.mjs 生成，不随分享包分发）\n    ├── patch-sdk.mjs              # postinstall 自动给 SDK 注入 windowsHide，消除 Windows 黑框\n    ├── package.json / package-lock.json\n    └── .env.example               # 复制为 .env 后填写（含 API Key）"},{"language":"bash","snippet":"cd backend\nnpm install\ncp .env.example .env        # 然后按需填写 CODEBUDDY_API_KEY\nnpm start                   # 默认监听 http://localhost:3000"},{"language":"bat","snippet":"reg add \"HKCU\\Software\\Classes\\webchat\" /ve /t REG_SZ /d \"webchat Protocol\" /f\n    reg add \"HKCU\\Software\\Classes\\webchat\" /v \"URL Protocol\" /t REG_SZ /d \"\" /f\n    reg add \"HKCU\\Software\\Classes\\webchat\\shell\\open\\command\" /ve /t REG_SZ /d \"\\\"C:\\Windows\\System32\\wscript.exe\\\" \\\"C:\\你的路径\\webchat-extension\\backend\\launcher.mjs\\\" \\\"%1\\\"\" /f"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: webchat-extension\ndescription: 部署「网页划线对话」浏览器扩展（Chrome MV3 / 兼容 Chrome·Edge·千问·夸克 等 Chromium 内核浏览器）。在任意网页选中文字，点工具栏图标唤起可拖动对话浮层，带着网页上下文用 CodeBuddy AI 流式问答。包含本地 Express + SSE 后端（CodeBuddy Agent SDK）与前端扩展。当用户要「做一个网页划词对话插件 / 给浏览器装个网页对话工具 / 选中文字问 AI / 部署小虾网页对话扩展 / web highlight chat extension / 把网页内容丢给 AI 聊」时使用本技能。\n---\n\n# 网页划线对话 · 小虾 🦐\n\n一个浏览器扩展 + 本地 AI 后端：用户在任意网页**选中文字**或**复制文字**，点工具栏图标弹出对话浮层，带着网页上下文直接和 AI 流式对话。后端基于 **CodeBuddy Agent SDK**（官方 `@tencent-ai/codebuddy-code` CLI 做 transport）。\n\n## 什么时候用\n- 用户想要「在网页上选中一段文字，直接问 AI 这是什么 / 帮我总结 / 翻译 / 解释」。\n- 用户想把某个网页内容作为上下文和 AI 聊。\n- 用户要部署/打包一个浏览器划词对话工具。\n\n## 架构\n```\n浏览器扩展 (Chrome MV3)                本地后端 (Express + SSE)\n┌──────────────────────────┐          ┌────────────────────────────┐\n│ 点工具栏图标 → 浮层(iframe) │──fetch──▶│  /api/chat  (SSE 流式)      │\n│ content.js 注入网页          │          │  query() → codebuddy CLI    │\n│ background.js service worker│          │  (CodeBuddy Agent SDK)      │\n│ 选区经 executeScript 跨 iframe│         │  buildSystemPrompt 注入网页上下文│\n└──────────────────────────┘          └────────────────────────────┘\n```\n- 前端只请求 `http://localhost:3000`，**API Key 只在后端**。\n- 面板状态（开关/位置/上下文/对话）用 `chrome.storage` 持久化，刷新不丢。\n\n## 文件布局（本 skill 内）\n```\nwebchat-extension/\n├── SKILL.md\n├── pack.mjs                  # 发布工具：在 deploy 产物(双形态目录)下 node pack.mjs → 生成干净分享包 zip\n├── gen-icons.mjs             # 独立图标生成（零依赖）：node gen-icons.mjs [dir]\n├── scripts/\n│   ├── deploy.mjs            # 脚手架：复制 assets 源码 + npm install + 生成 icons/（Windows 部署时生成 launcher.vbs + 注册协议）\n│   ├── gen-vbs.mjs           # 唯一 source of truth：写出 backend/launcher.vbs（agent 部署时调用，不随包分发）\n│   └── register-protocol.cjs # 一键注册/修复 webchat:// 协议（协议丢失或被识别成 Store 应用时用）\n├── assets/\n│   ├── extension/            # 浏览器扩展（manifest/background/content/panel.*/icons）\n│   ├── backend/              # server.js / launcher.mjs / patch-sdk.mjs / package.json / .env.example（launcher.vbs 由 agent 在部署时用 scripts/gen-vbs.mjs 生成，不随包分发）\n│   └── root/                 # 部署到目标根目录的文档：README.md（.gitignore / 协议模板不随包分发）\n└── references/deploy-guide.md  # 详细排错表\n```\n\n> **统一原则**：本 skill 是**唯一 source of truth**。运行环境一律由 `deploy.mjs` 生成（assets → 目标目录），不要在别处手维护一份带 `extension/ backend/` 的\"双形态\"目录，以免与 skill 不同步产生歧义。deploy 产物（目标目录）本身就是双形态目录（含 `extension/ backend/ SKILL.md pack.mjs gen-icons.mjs`），可直接加载运行，也可 `node pack.mjs` 生成分享包。\n\n## 部署步骤（agent 照做）\n1. **脚手架**：运行 `node <skill_dir>/scripts/deploy.mjs <targetDir>`（不加 `[targetDir]` 默认 `./webchat-extension` 或 `~/webchat-extension`）。脚本把 `assets/` 里的扩展、后端、根文档复制到目标目录并 `npm install`；**在 Windows 上，agent 会自动用 `scripts/gen-vbs.mjs` 生成 `backend/launcher.vbs`（即使带 `--no-protocol` 也会生成），并自动注册 `webchat://start` 协议**，使面板「🚀 启动后端」按钮免终端生效。`launcher.vbs` 是部署期产物，**绝不随分享包分发/上传**——若目标目录缺失它，可随时补：`node <skill_dir>/scripts/gen-vbs.mjs <target>/backend`。加 `--no-install` 只复制不装依赖；加 `--no-protocol` 跳过协议注册（但 vbs 仍会生成）。非 Windows 或需手动注册时，按 README「四、一键启动后端」用面板「📋 复制启动命令」手动 `npm start`，或参考 README/references 手动 `reg add` 注册协议。\n2. **配置后端**：在 `<target>/backend/` 复制 `.env.example` 为"},{"path":"assets/root/README.md","content":"# 网页划线对话 · 小虾 🦐\n\n> 📦 仓库地址：https://github.com/NoahEleven/webchat-extension\n\n一个 **Chrome / Edge / 千问 / 夸克 等 Chromium 内核浏览器** 扩展：在任意网页上**选中或复制文字**，点一下工具栏图标，就能带着这段网页上下文，直接和 AI 对话、流式得到回答。\n\n> 本质：复用 CodeBuddy Agent SDK 的 **Express + SSE 后端**，前端换成「浏览器扩展 + 网页划线交互」。\n\n---\n\n## 目录结构\n\n```\nwebchat-extension/\n├── README.md\n├── webchat-protocol.reg.example   # 仅仓库内模板，不随分享包分发（协议改由部署脚本自动注册）\n├── pack.mjs                       # 一键打包分享 zip（按 .gitignore 排除 node_modules/.env/私钥等）\n├── extension/                     # 浏览器扩展（Chrome MV3）\n│   ├── manifest.json\n│   ├── background.js              # service worker：图标点击→开关浮层；心跳 ping 后端\n│   ├── content.js                 # 注入网页：开/关浮层、读选区、状态持久化、触发协议\n│   ├── panel.html / panel.js / panel.css   # 对话浮层界面与逻辑\n│   └── icons/                     # 图标 icon16/32/48/128.png（分享包不含，由 deploy/gen-icons 自动生成）\n└── backend/                       # AI 后端（Express + CodeBuddy SDK + SSE）\n    ├── server.js                  # /api/chat(SSE) /api/health /api/heartbeat /api/stop\n    ├── launcher.mjs               # 协议触发：托管模式静默拉起 server.js\n    ├── launcher.vbs               # 隐藏窗口启动 launcher.mjs（由 agent 在部署时用 scripts/gen-vbs.mjs 生成，不随分享包分发）\n    ├── patch-sdk.mjs              # postinstall 自动给 SDK 注入 windowsHide，消除 Windows 黑框\n    ├── package.json / package-lock.json\n    └── .env.example               # 复制为 .env 后填写（含 API Key）\n```\n\n---\n\n## 前置依赖（重要）\n\n- **Node.js 18+**：后端是 Node 程序。\n- **codebuddy CLI（核心外部依赖，需收件人自备）**：后端通过 `@tencent-ai/agent-sdk` 在运行时 `spawn` 一个 `codebuddy` 子进程来真正调用 AI。`server.js` 的 `resolveCli()` 按以下顺序找它：\n  1. 环境变量 `CODEBUDDY_CLI_PATH` 显式指定；\n  2. 系统 `PATH` 上的 `codebuddy` 命令；\n  3. 兜底固定路径 `~/.workbuddy/binaries/node/versions/22.22.2/node_modules/@tencent-ai/codebuddy-code/bin/codebuddy`（**仅本机 WorkBuddy 托管环境才有**）。\n  - 本机因装了 WorkBuddy，托管 Node 已自带 `codebuddy`，所以开箱可用。\n  - **分享给别人的机器若没有 WorkBuddy**：需对方自行安装 CLI —— `npm i -g @tencent-ai/codebuddy-code`，并保证 `codebuddy` 在 `PATH` 上（或在 `.env` 设 `CODEBUDDY_CLI_PATH=绝对路径` 指向 CLI）。否则 `query()` 拉不起进程、后端连不上（登录模式和 Key 模式都依赖该 CLI）；此时仅 `WEBCHAT_DEMO=1` 演示模式可跑通交互闭环。\n\n---\n\n## 一、启动后端\n\n```bash\ncd backend\nnpm install\ncp .env.example .env        # 然后按需填写 CODEBUDDY_API_KEY\nnpm start                   # 默认监听 http://localhost:3000\n```\n\n启动后访问 `http://localhost:3000/api/health` 应返回 `{ \"status\": \"ok\", ... }`。\n\n### 三种模式\n| 模式 | 条件 | 表现 |\n|---|---|---|\n| **登录模式（默认，零配置）** | 没填 `CODEBUDDY_API_KEY` 且未设 `WEBCHAT_DEMO` | 复用本机 `codebuddy` CLI 已登录凭据，**真实 AI**（首次需在终端跑一次 `codebuddy` 完成登录） |\n| **Key 模式（推荐无人值守）** | 填了 `CODEBUDDY_API_KEY` | 用 Key 直连 CodeBuddy AI，不依赖交互登录，**真实 AI** |\n| **演示模式** | 显式设 `WEBCHAT_DEMO=1` | 后端返回模拟流式回复，用来验收「划线→对话」交互闭环（无需任何账号/登录） |\n\n---\n\n## 二、申请 CODEBUDDY_API_KEY（可选，无人值守场景才需要）\n\n> 默认**不填 Key 也是真实 AI**（登录模式，复用本机 `codebuddy` CLI 已登录凭据）。只有想脱离交互登录、无人值守直连时才需要配 Key。\n\n1. 打开 https://www.codebuddy.cn → 登录\n2. 进入「个人中心 / API 密钥」生成 Key\n3. 把 Key 填进 `backend/.env` 的 `CODEBUDDY_API_KEY=`\n4. 重启后端 `npm start`\n\n> 没 Key 也没关系——登录模式默认就是真实 AI；纯验收交互闭环可设 `WEBCHAT_DEMO=1` 进演示模式。\n\n---\n\n## 三、在浏览器加载扩展\n\n本扩展是标准 Chrome MV3，兼容一切 Chromium 内核浏览器（Chr"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn769gn5we5rgv7bfhb9ztd8j983p8qc\",\n  \"slug\": \"webchat-extension\",\n  \"version\": \"0.1.5\",\n  \"publishedAt\": 1786085680332\n}"},{"path":"references/deploy-guide.md","content":"# 网页划线对话 · 部署与排错指南\n\n本文件是 skill 的详细排错表，配合 `SKILL.md` 使用。扩展版本 1.5.5。\n\n## 〇、前置依赖：codebuddy CLI（外部依赖，不随包分发）\n\n后端通过 `@tencent-ai/agent-sdk` 在运行时 `spawn` 一个 `codebuddy` 子进程来真正调用 AI。`server.js` 的 `resolveCli()` 按序找它：① `CODEBUDDY_CLI_PATH` 显式指定 → ② 系统 `PATH` 上的 `codebuddy` → ③ 兜底 `~/.workbuddy/binaries/node/versions/22.22.2/node_modules/@tencent-ai/codebuddy-code/bin/codebuddy`（仅本机 WorkBuddy 托管环境有）。\n\n- **本机**（装了 WorkBuddy）：托管 Node 已自带 `codebuddy`，开箱可用。\n- **分享给别人的机器若没有 WorkBuddy**：需对方 `npm i -g @tencent-ai/codebuddy-code` 并确保 `codebuddy` 在 `PATH`，或在 `.env` 设 `CODEBUDDY_CLI_PATH` 指向 CLI。否则 `query()` 拉不起进程 → 后端连不上（登录/Key 模式都依赖该 CLI）；仅 `WEBCHAT_DEMO=1` 演示模式可跑通交互闭环。\n\n> 注意：`backend/` 目录**必须随扩展一起分享**——扩展只是 UI 外壳，AI 能力全在后端。\n\n## 一、后端启动与模式\n\n| 步骤 | 命令 | 说明 |\n|---|---|---|\n| 进入后端 | `cd <target>/backend` | — |\n| 安装依赖 | `npm install` | 仅首次；用受管 node 即可 |\n| 复制配置 | `cp .env.example .env` | 按需填 `CODEBUDDY_API_KEY` |\n| 启动 | `npm start` | 默认 `http://localhost:3000` |\n| 健康检查 | `curl http://localhost:3000/api/health` | 返回 `{\"status\":\"ok\",...}` |\n\n**三种模式**\n- 登录模式（默认，零配置）：未填 `CODEBUDDY_API_KEY` 且未设 `WEBCHAT_DEMO`，复用本机 `codebuddy` CLI 已登录凭据走**真实 AI**（首次需终端跑一次 `codebuddy` 登录）。\n- Key 模式（推荐无人值守）：填了 `CODEBUDDY_API_KEY`，用 Key 直连 CodeBuddy AI，不依赖交互登录。\n- 演示模式：显式设 `WEBCHAT_DEMO=1`，后端返回模拟流式回复，验收交互闭环用，无需账号/登录。\n\n---\n\n## 二、现象 → 排查\n\n| 现象 | 原因 / 排查 |\n|---|---|\n| 面板提示「连接后端失败」 | 确认 `cd backend && npm start` 已启动；端口 3000 |\n| 点「🚀 启动后端」没反应 | 多半是 `webchat://` 协议未注册（见第四节）。可改用面板「📋 复制启动命令」手动 `npm start` |\n| 点图标没反应 | 多见于 `chrome://`、`edge://` 等系统页（扩展无法注入）；普通网页正常。确认扩展已加载且未被禁用 |\n| 选中文字点「添加选中文本」没反应 | 选区由 `chrome.scripting.executeScript(allFrames)` 读取，正常能抓微信读书/千问 iframe。若阅读器是 **sandboxed iframe（无 allow-scripts）** 或屏蔽 copy，则只能手动粘贴/输入到输入框发送（发送自动收上下文）。属平台限制非 bug |\n| 收到的是演示（模拟）回复 | 说明设了 `WEBCHAT_DEMO=1`。删掉它重启即走登录模式真实 AI；登录态失效则终端跑一次 `codebuddy` 重登，或 `.env` 填 `CODEBUDDY_API_KEY` 走 Key 模式 |\n| `/api/health` 返回 `demo:true` | 说明设了 `WEBCHAT_DEMO=1`（演示模式）；移除该变量走默认登录模式真实 AI，或填 Key |\n| **真实模式一直转圈、面板无回答**（后端日志 `EADDRINUSE` / CLI 卡死） | 官方 CLI 的 prewarm 端口与 WorkBuddy 桌面应用撞车。在 `.env` 设 `SERVER__PORT=40123`（或空闲端口）并重启；若环境变量残留旧 `SERVER__PORT`，启动时用 `SERVER__PORT=40123 npm start` 显式覆盖 |\n| 后端报 `400 model [...] service info not found` | 模型名不对，把 `CODEBUDDY_MODEL` 改成 `deepseek-v4-flash`、`hy3` 或 `auto`（本账户不支持 `claude-sonnet-4`） |\n| 后端报 `initialize` 超时 / 永远 0 字节 | 用了 WorkBuddy 自带那份 cli（协议不匹配）。必须用官方 `@tencent-ai/codebuddy-code`；`server.js` 的 `resolveCli()` 已自动定位，必要时用 `CODEBUDDY_CLI_PATH` 显式指定 |\n| 拖拽抖动 / 跳左上角 | 扩展 V1.5.2 已修复拖拽坐标公式；若仍异常，扩展管理页「重新加载」并确认 manifest 版本 ≥ 1.5.2 |\n| **Windows 上每次对话 / 启动后端弹黑框** | SDK 内部 spawn CLI 默认 `windowsHide:false`。`package.json` 的 `postinstall` 会自动跑 `patch-sdk.mjs` 给 `@tencent-ai/agent-sdk` 的 `process-transport.js` 两处 spawn 注入 `windowsHide:true`；`npm install` 后即生效。若依赖是手动装、跳过了 postinstall，运行一次 `node backend/patch-sdk.mjs` 即可 |\n\n---\n\n## 三、端口冲突根因说明\n\n官方 `@tencent-ai/codebuddy-code` 启动时会起一个 prewarm 本地 server，端口由 `SERVER__PORT` 环境变量控制。本机 **WorkBuddy 桌面应用自身也会起同类 server 占端口**（实测占 54975 之类），两者撞车 → CLI 一绑定就 `EADDRINUS"},{"path":"skill-card.md","content":"## Description:\n\nDeploys a Chromium browser extension and local Express/SSE backend that let users select or copy webpage text and stream contextual answers from CodeBuddy AI.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[noaheleven](https://clawhub.ai/user/noaheleven)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and agents use this skill to deploy, configure, and package a browser-based webpage chat assistant. The deployed extension helps users carry selected or copied webpage context into CodeBuddy AI conversations.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can read and persist selected or copied webpage and clipboard text, which may include sensitive data.\n\nMitigation: Require explicit user confirmation before adding clipboard content, avoid use on sensitive pages, and review stored conversation/context data before sharing or packaging.\n\nRisk: The local AI backend uses local CodeBuddy login or API-key credentials and was flagged as lacking sufficient access control.\n\nMitigation: Bind the backend to loopback only, add backend authentication, keep API keys only in local environment files, and exclude credentials from release archives.\n\nRisk: The backend CORS and browser-panel message handling may allow unintended local access if left broad.\n\nMitigation: Restrict CORS to expected extension origins, check message sources, and keep browser permissions scoped to the extension workflow.\n\nRisk: The release depends on a local CodeBuddy CLI, a Windows protocol handler, and npm dependencies that must be trusted and current.\n\nMitigation: Install dependencies from trusted sources, update dependency versions before sensitive use, review protocol-handler registration, and verify the generated launcher path.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/noaheleven/skills/webchat-extension)\n- [Publisher profile](https://clawhub.ai/user/noaheleven)\n- [Deployment and troubleshooting guide](references/deploy-guide.md)\n- [CodeBuddy](https://www.codebuddy.cn)\n- [CodeBuddy API console](https://copilot.tencent.com)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Code, Shell commands, Configuration, Guidance]\n\n**Output Format:** [Markdown guidance with shell commands and generated project files]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Produces deployment instructions and file-generation steps for a Chromium extension and local Node.js backend.]\n\n## Skill Version(s):\n\n0.1.5 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment."}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":null,"editorialQuality":{"score":100,"threshold":65,"status":"thin","wordCount":1267,"uniquenessScore":43,"reasons":["uniqueness-below-45"]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-11T18:50:44.017Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-11T18:50:44.017Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-11T21:52:12.280Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}