{"id":"18a012e6-3b73-4daf-82b9-eee756198024","entityType":"agent","slug":"clawhub-54lynnn-knowledge-rag","name":"Knowledge Rag","canonicalUrl":"https://www.xpersona.co/agent/clawhub-54lynnn-knowledge-rag","canonicalPath":"/agent/clawhub-54lynnn-knowledge-rag","generatedAt":"2026-10-10T21:43:02.307Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-10T18:51:10.809Z","emptyReason":null},"description":"个人知识库：存笔记、搜内容。用自然语言搜本地文档，不用记文件名。跟 AI 说'把这段存到知识库'自动保存并建索引。推荐搭配 Bilibili Auto Transcript：视频转录自动入库，转完即搜。 Skill: Knowledge Rag Owner: 54lynnn Summary: 个人知识库：存笔记、搜内容。用自然语言搜本地文档，不用记文件名。跟 AI 说'把这段存到知识库'自动保存并建索引。推荐搭配 Bilibili Auto Transcript：视频转录自动入库，转完即搜。 Tags: 54lynnn:1.1.0, chinese:1.5.4, knowledge:1.5.4, latest:1.6.1, rag:1.5.4, search:1.5.4 Version history: v1.6.1 | 2026-06-03T08:51:06.513Z | auto **Virtual environment support and installation process improvement** - Added virtual environment (.venv) support; all depend","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.3K downloads reported by the source. Last updated 10/10/2026.","installCommand":"clawhub skill install s17eg5gndg4q9p16rk2nqbpje183gv2k:knowledge-rag","sourceUrl":"https://clawhub.ai/54lynnn/knowledge-rag","homepage":"https://clawhub.ai/54lynnn/skills/knowledge-rag","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/54lynnn/knowledge-rag","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/54lynnn/skills/knowledge-rag","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":62,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"个人知识库：存笔记、搜内容。用自然语言搜本地文档，不用记文件名。跟 AI 说'把这段存到知识库'自动保存并建索引。推荐搭配 Bilibili Auto Transcript：视频转录自动入库，转完即搜。 Skill: Knowledge Rag Owner: 54lynnn Summary: 个人知识库：存笔记、搜内容"},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-10T18:51:10.809Z","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-10T18:51:10.809Z","emptyReason":null},"stars":null,"forks":null,"downloads":1290,"packageName":null,"latestVersion":"1.6.1","tractionLabel":"1.3K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T18:51:10.809Z","emptyReason":null},"lastUpdatedAt":"2026-10-10T18:51:10.809Z","lastCrawledAt":"2026-10-10T18:51:10.809Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-11T18:51:10.809Z","lastVerifiedAt":null,"highlights":[{"version":"1.6.1","createdAt":"2026-06-03T08:51:06.513Z","changelog":"**Virtual environment support and installation process improvement** - Added virtual environment (.venv) support; all dependencies now installed into a dedicated environment. - Updated installation commands and documentation to use .venv/bin/python3 and .venv/bin/pip. - Modified all scripts and documentation to match the new environment setup. - Removed the old skill-card.md file and added a new README.md. - Improved installation reliability and isolated dependency management.","fileCount":13,"zipByteSize":47190},{"version":"1.6.0","createdAt":"2026-06-01T03:33:41.245Z","changelog":"SQLite存储引擎升级 + 混合打分优化 + 8B默认模型","fileCount":12,"zipByteSize":44059},{"version":"1.5.7","createdAt":"2026-06-01T01:31:03.742Z","changelog":"默认模型降回0.6B(CPU友好)，8B改为进阶选项/ 标题智能提取+关键词加分","fileCount":12,"zipByteSize":42768},{"version":"1.5.6","createdAt":"2026-06-01T01:29:41.252Z","changelog":"标题智能提取(H1)→可读标题 / 关键词搜索加成+0.15→精准匹配天然靠前","fileCount":12,"zipByteSize":42803},{"version":"1.5.5","createdAt":"2026-05-31T18:13:19.937Z","changelog":"添加GitHub开源链接、QQ群信息，文档更新","fileCount":12,"zipByteSize":41249},{"version":"1.5.4","createdAt":"2026-05-31T02:47:29.854Z","changelog":"新增自动索引功能文档+安装指引（可选）。别再说'半小时内自动扫描'这种skill没有的功能了。","fileCount":12,"zipByteSize":41204},{"version":"1.5.3","createdAt":"2026-05-31T02:28:58.187Z","changelog":"解耦两个skill：移除转录脚本中的索引调用；新增定时自动扫描（每30分钟），发现新文件自动索引，无变化不操作","fileCount":12,"zipByteSize":40930},{"version":"1.5.2","createdAt":"2026-05-31T01:19:09.090Z","changelog":"文档优化","fileCount":12,"zipByteSize":40903}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s17eg5gndg4q9p16rk2nqbpje183gv2k:knowledge-rag","setupComplexity":"low","setupSteps":["Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"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-54lynnn-knowledge-rag/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-54lynnn-knowledge-rag/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-54lynnn-knowledge-rag/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-54lynnn-knowledge-rag/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-54lynnn-knowledge-rag/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-54lynnn-knowledge-rag/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-10T21:43:02.304Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-54lynnn-knowledge-rag/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-54lynnn-knowledge-rag/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-54lynnn-knowledge-rag/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-54lynnn-knowledge-rag/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":"high","updatedAt":"2026-10-10T18:51:10.809Z","emptyReason":null},"readme":"Skill: Knowledge Rag\n\nOwner: 54lynnn\n\nSummary: 个人知识库：存笔记、搜内容。用自然语言搜本地文档，不用记文件名。跟 AI 说'把这段存到知识库'自动保存并建索引。推荐搭配 Bilibili Auto Transcript：视频转录自动入库，转完即搜。\n\nTags: 54lynnn:1.1.0, chinese:1.5.4, knowledge:1.5.4, latest:1.6.1, rag:1.5.4, search:1.5.4\n\nVersion history:\n\nv1.6.1 | 2026-06-03T08:51:06.513Z | auto\n\n**Virtual environment support and installation process improvement**\n\n- Added virtual environment (.venv) support; all dependencies now installed into a dedicated environment.\n- Updated installation commands and documentation to use .venv/bin/python3 and .venv/bin/pip.\n- Modified all scripts and documentation to match the new environment setup.\n- Removed the old skill-card.md file and added a new README.md.\n- Improved installation reliability and isolated dependency management.\n\nv1.6.0 | 2026-06-01T03:33:41.245Z | user\n\nSQLite存储引擎升级 + 混合打分优化 + 8B默认模型\n\nv1.5.7 | 2026-06-01T01:31:03.742Z | user\n\n默认模型降回0.6B(CPU友好)，8B改为进阶选项/ 标题智能提取+关键词加分\n\nv1.5.6 | 2026-06-01T01:29:41.252Z | user\n\n标题智能提取(H1)→可读标题 / 关键词搜索加成+0.15→精准匹配天然靠前\n\nv1.5.5 | 2026-05-31T18:13:19.937Z | user\n\n添加GitHub开源链接、QQ群信息，文档更新\n\nv1.5.4 | 2026-05-31T02:47:29.854Z | user\n\n新增自动索引功能文档+安装指引（可选）。别再说'半小时内自动扫描'这种skill没有的功能了。\n\nv1.5.3 | 2026-05-31T02:28:58.187Z | user\n\n解耦两个skill：移除转录脚本中的索引调用；新增定时自动扫描（每30分钟），发现新文件自动索引，无变化不操作\n\nv1.5.2 | 2026-05-31T01:19:09.090Z | user\n\n文档优化\n\nv1.5.1 | 2026-05-31T01:11:54.085Z | user\n\n小版本修复\n\nv1.5.0 | 2026-05-31T00:46:07.527Z | user\n\n架构重构：FastAPI + TypeScript Express 替代 http.server；混合搜索（向量+关键词）；新增千问3 Embedding 模型支持；统一启动器 start.py；网页界面全面升级；保存知识规范流程。\n\nv1.2.0 | 2026-05-30T12:35:22.965Z | user\n\n新增「保存知识的规范流程」，描述更新为存搜一体。任何 agent 按 SKILL.md 指引即可完成'把这段存到知识库'操作。\n\nv1.1.2 | 2026-05-29T23:44:08.287Z | user\n\n描述更新：推荐搭配 Bilibili Auto Transcript 使用。\n\nv1.1.1 | 2026-05-29T23:43:08.351Z | user\n\n还原干净显示名称。\n\nv1.1.0 | 2026-05-29T23:34:30.795Z | user\n\n品牌更新：显示名称加入 54Lynnn 个人标识；推荐搭配 bilibili-auto-transcript。\n\nv1.0.0 | 2026-05-29T23:29:12.414Z | user\n\n首个版本：个人知识库搜索与管理系统，支持语义搜索、网页管理界面、自动索引。\n\nArchive index:\n\nArchive v1.6.1: 13 files, 47190 bytes\n\nFiles: README.md (6679b), scripts/index_knowledge.py (18634b), scripts/knowledge_api.py (11039b), scripts/query_knowledge.py (10076b), skill-card.md (2022b), SKILL.md (6244b), start.py (9838b), web/package-lock.json (49574b), web/package.json (498b), web/public/index.html (27213b), web/src/server.ts (7781b), web/tsconfig.json (451b), _meta.json (132b)\n\nFile v1.6.1:SKILL.md\n\n---\nname: knowledge-rag\nversion: \"1.6.0\"\ndescription: \"个人知识库：存笔记、搜内容。用自然语言搜本地文档，不用记文件名。跟 AI 说'把这段存到知识库'自动保存并建索引。推荐搭配 Bilibili Auto Transcript：视频转录自动入库，转完即搜。\"\nmetadata:\n  openclaw:\n    emoji: \"📖\"\n    requires:\n      bins: [\"python3\", \"ollama\"]\n    install:\n      - id: \"ollama\"\n        kind: \"system\"\n        label: \"安装 Ollama（向量引擎）\"\n        url: \"https://ollama.com/download\"\n      - id: \"embed-model\"\n        kind: \"shell\"\n        label: \"下载推荐向量模型（千问3 Embedding 8B，约 4.7GB）\"\n        command: \"ollama pull qwen3-embedding:8b\"\n      - id: \"pip-deps\"\n        kind: \"shell\"\n        label: \"创建虚拟环境并安装 Python 依赖\"\n        command: \"cd {{SKILL_DIR}} && python3 -m venv .venv && .venv/bin/pip install numpy requests fastapi pydantic uvicorn PyPDF2 pdfplumber python-docx\"\n      - id: \"auto-index-cron\"\n        kind: \"shell\"\n        optional: true\n        label: \"（可选）开启自动索引——每30分钟扫描新文件\"\n        command: \"echo '提示：安装后可运行 openclaw cron add 定时运行 index_knowledge.py 实现自动索引'\"\n---\n\n# 📖 Knowledge RAG\n\n用自然语言搜索你的笔记和文档，像问 ChatGPT 一样问你的私人知识库。\n\n---\n\n## 🚀 安装启动\n\n```bash\n# 1. 安装 Ollama\ncurl -fsSL https://ollama.com/install.sh | sh\n\n# 2. 拉取推荐模型（千问3 Embedding，中文最优）\nollama pull qwen3-embedding:8b\n\n# 3. 创建虚拟环境并安装依赖\npython3 -m venv .venv\n.venv/bin/pip install numpy requests fastapi pydantic uvicorn PyPDF2 pdfplumber python-docx\n\n# 4. 启动\n.venv/bin/python3 start.py\n```\n\n打开 `http://localhost:5777` → 文件丢到 `~/workspace/knowledge/` → 管理页点「重新索引」→ 搜索页开搜。\n\n### 可选：开启自动索引\n新增文件后不用每次都手动点重新索引，设个定时任务每30分钟自动扫描：\n```bash\nopenclaw cron add \\\n  --name \"knowledge-rag 自动索引\" \\\n  --every 1800000 \\\n  --message \"运行索引检查：cd ~/.openclaw/workspace/skills/knowledge-rag && .venv/bin/python3 scripts/index_knowledge.py\" \\\n  --silent\n```\n\n---\n\n## 📂 知识库目录\n\n```\n~/workspace/knowledge/\n  ├── notes/            ← 技术笔记、读书笔记\n  ├── bilibili/         ← B站转录\n  ├── wechat-articles/  ← 公众号文章\n  ├── other/            ← 其他文档\n  └── （可建任意子目录，去设置页添加）\n```\n\n支持 `.txt` / `.md` / `.pdf`（文字版）/ `.docx` 文件。\n\n---\n\n## 🔍 搜索方式\n\n### 直接问我\n> \"帮我搜笔记里关于 Docker 的部分\"  \n> \"知识库里有没有讲 Transformer 的文章？\"\n\n我会自动调搜索，带原文回答。\n\n### 命令行\n```bash\n.venv/bin/python3 scripts/query_knowledge.py \"你的问题\"\n.venv/bin/python3 scripts/query_knowledge.py \"微服务\" --source bilibili --top 5\n.venv/bin/python3 scripts/query_knowledge.py --stats\n```\n\n新增文件后运行索引即可：\n```bash\n.venv/bin/python3 scripts/index_knowledge.py          # 增量\n.venv/bin/python3 scripts/index_knowledge.py --force  # 全量重建\n```\n\n---\n\n## 📝 Agent 存知识规范\n\n当用户说\"把这段存到知识库\"，按以下规则操作：\n\n| 内容类型 | 存放目录 | 文件名 |\n|---------|---------|--------|\n| 技术笔记、概念解释 | `notes/` | 中文描述.md |\n| B站视频转录 | `bilibili/` | 自动处理 |\n| 公众号、网页文章 | `wechat-articles/` | 文章标题.md |\n| 其他 | `other/` | 内容摘要.md |\n\n保存后运行 `.venv/bin/python3 scripts/index_knowledge.py` 更新索引。\n\n---\n\n## 🔧 切换模型\n\n在设置页修改 `embed_model` 字段：\n\n| 场景 | 模型 | 大小 |\n|------|------|------|\n| ✅ 推荐（质量最高） | `qwen3-embedding:8b` | 4.7GB | 中文优秀，检索质量最高 |\n| 轻量（CPU友好） | `qwen3-embedding:0.6b` | 640MB | 对 CPU 友好，中文不错 |\n| 多语言 | `bge-m3` | 1.2GB |\n| 最小体积 | `nomic-embed-text` | 274MB |\n\n改完后点「重新索引」，系统自动检测并全量重建。\n\n---\n\n## 🧑‍💻 环境检测（给 AI 助手的指引）\n\n用户首次使用或出问题时，按顺序排查：\n\n1. **Ollama 是否安装？** → `ollama --version`，否则引导去 https://ollama.com/download\n2. **千问3 模型是否下载？** → `ollama list | grep qwen3-embedding`，否则 `ollama pull qwen3-embedding:8b`\n3. **索引模型是否匹配？** → 读 `~/workspace/knowledge/.rag_data/model_meta.json`，不匹配则提示重建\n\n快速诊断：\n```bash\ncurl -s http://localhost:8768/api/stats | .venv/bin/python3 -c \"\nimport sys,json; d=json.load(sys.stdin)\nem = d.get('embed_model',{})\nprint(f'配置: {em.get(\\\"current\\\",\\\"?\\\")} | 索引: {em.get(\\\"stored\\\",\\\"?\\\")} ({em.get(\\\"stored_dim\\\",\\\"?\\\")}维)')\nprint(f'状态: {\\\"✅ 正常\\\" if not em.get(\\\"mismatch\\\") else \\\"❌ 不匹配\\\"}')\"\n```\n\n---\n\n## ⚠️ 注意事项\n\n- 依赖 Ollama，首次下载模型约 640MB 需联网\n- PDF 支持**文字版** PDF（PyPDF2 优先提取，失败自动降级到 pdfplumber），纯图像版 PDF 暂不支持\n- DOCX 支持通过 python-docx 提取段落文字和表格内容\n- PDF/DOCX 解析需先创建虚拟环境：`python3 -m venv .venv && .venv/bin/pip install PyPDF2 pdfplumber python-docx`\n- 仅支持纯文本内容，不支持图片和 PDF 中的图像\n- 删除文件后运行「重新索引」即可从搜索结果移除（增量索引自动清理已删除文件，无需 --force）\n- 数据全部在 `~/workspace/knowledge/`，卸载不丢\n\n## 🎯 推荐搭配\n\n**Bilibili Auto Transcript** — 装了这个 skill 后，B站视频转录完自动存到知识库，不用手动操作：\n\n```bash\nclawhub install bilibili-auto-transcript\n```\n\n转录的文件自动进 `~/workspace/knowledge/bilibili/`，转完即搜。\n\n---\n\n## 📦 开源 & 交流\n\n- **GitHub**：[github.com/54Lynnn/knowledge-rag](https://github.com/54Lynnn/knowledge-rag)（⭐️ Star 支持）\n- **ClawHub**：[clawhub.ai/54lynnn/knowledge-rag](https://clawhub.ai/54lynnn/knowledge-rag)\n- **QQ 群**：120363664（欢迎扫码加入交流）\n\nFile v1.6.1:README.md\n\n<p align=\"center\">\n  <h1 align=\"center\">📖 Knowledge RAG</h1>\n  <p align=\"center\">把你的笔记和文档变成 AI 知识库，像聊天一样搜索</p>\n  <p align=\"center\">\n    <a href=\"https://clawhub.ai/54lynnn/knowledge-rag\"><img src=\"https://img.shields.io/badge/ClawHub-knowledge--rag-6c5ce7\" alt=\"ClawHub\"></a>\n    <a href=\"https://github.com/54Lynnn/knowledge-rag\"><img src=\"https://img.shields.io/github/stars/54Lynnn/knowledge-rag\" alt=\"GitHub Stars\"></a>\n  </p>\n</p>\n\n---\n\n## 这是什么\n\n一个**本地运行的 RAG（检索增强生成）知识库系统**。把你的 `.txt` / `.md` / `.pdf` / `.docx` 文件丢进来，用自然语言搜索，像问 ChatGPT 一样问你的私人知识库。\n\n**跟大多数 RAG 工具不同：**\n\n- **极简部署** — 不需要 Docker，不需要数据库，一台机器一个 Ollama 就够了\n- **Trae/OpenClaw Agent 集成** — 在 IDE 里直接让 AI 搜你的知识库并带原文回答\n- **B站转录自动入库** — 配合 bilibili-auto-transcript，视频转录完自动进知识库\n\n---\n\n## 快速开始\n\n```bash\n# 1. 安装 Ollama\ncurl -fsSL https://ollama.com/install.sh | sh\n\n# 2. 拉取推荐模型（千问3 Embedding 8B）\nollama pull qwen3-embedding:8b\n\n# 3. 创建虚拟环境并安装依赖\npython3 -m venv .venv\n.venv/bin/pip install numpy requests fastapi pydantic uvicorn PyPDF2 pdfplumber python-docx\n\n# 4. 启动\n.venv/bin/python3 start.py\n```\n\n打开 `http://localhost:5777` → 把文件丢到 `~/workspace/knowledge/` → 点「重新索引」→ 开搜。\n\n---\n\n## 架构\n\n```\n┌─────────────────────────────────────────────────┐\n│                 浏览器 (index.html)              │\n└──────────────────┬──────────────────────────────┘\n                   │ HTTP\n┌──────────────────▼──────────────────────────────┐\n│         TypeScript Express (server.ts)           │\n│   Web 层：静态文件、配置读写、请求路由            │\n└──────────────────┬──────────────────────────────┘\n                   │ HTTP Proxy\n┌──────────────────▼──────────────────────────────┐\n│          Python FastAPI (knowledge_api.py)       │\n│   RAG 层：搜索、索引、管理、统计 API             │\n└──────┬─────────────────────────────┬────────────┘\n       │                             │\n┌──────▼──────┐            ┌────────▼──────────┐\n│ index_      │            │ query_            │\n│ knowledge.py│            │ knowledge.py      │\n│ 索引构建    │            │ 向量搜索+混合打分  │\n└──────┬──────┘            └────────┬──────────┘\n       │                            │\n       └──────────┬─────────────────┘\n                  │ SQLite\n       ┌──────────▼──────────┐\n       │  chunks.db          │\n       │  (文本 + 向量 BLOB) │\n       └─────────────────────┘\n```\n\n## 知识库目录结构\n\n```\n~/workspace/knowledge/\n  ├── notes/            ← 技术笔记、读书笔记\n  ├── bilibili/         ← B站转录（配合 bilibili-auto-transcript）\n  ├── wechat-articles/  ← 公众号文章\n  ├── other/            ← 其他文档\n  └── （可建任意子目录，去设置页添加）\n```\n\n支持的文件格式：`.txt` / `.md` / `.pdf`（文字版）/ `.docx`\n\n---\n\n## 核心特性\n\n| 特性 | 说明 |\n|------|------|\n| **SQLite 存储** | 文本 + 向量存同一张表，原子写入，不会崩溃后数据不一致 |\n| **增量索引** | hash 比对 + mtime 快速跳过，只处理变更文件，删除的文件自动清理 |\n| **混合搜索** | 向量余弦相似度 + 查询扩展 + 标题/文本关键词加成 |\n| **标题提取** | Markdown H1、PDF/DOCX 首行自动识别为标题，提高匹配精度 |\n| **文件解析** | PDF（PyPDF2 + pdfplumber 降级）、DOCX（含表格内容） |\n| **删除单条** | API 支持按文件名删除索引，无需全量重建 |\n| **Web 界面** | 搜索 + 管理（统计、索引、配置）一体 |\n| **多模型支持** | 可切换 embedding 模型，切换后自动全量重建 |\n\n---\n\n## 切换模型\n\n在 `~/workspace/knowledge/.knowledge-config.json` 中修改 `embed_model` 字段：\n\n| 场景 | 模型 | 大小 |\n|------|------|------|\n| 推荐（质量最高） | `qwen3-embedding:8b` | 4.7GB |\n| 轻量（CPU 友好） | `qwen3-embedding:0.6b` | 640MB |\n| 多语言 | `bge-m3` | 1.2GB |\n| 最小体积 | `nomic-embed-text` | 274MB |\n\n改完后重新索引，系统自动检测并全量重建。\n\n---\n\n## CLI 用法\n\n```bash\n# 索引\n.venv/bin/python3 scripts/index_knowledge.py          # 增量更新\n.venv/bin/python3 scripts/index_knowledge.py --force  # 全量重建\n\n# 搜索\n.venv/bin/python3 scripts/query_knowledge.py \"你的问题\"\n.venv/bin/python3 scripts/query_knowledge.py \"微服务\" --source bilibili --top 5\n.venv/bin/python3 scripts/query_knowledge.py --stats\n```\n\n---\n\n## 在 OpenClaw/Trae 中使用\n\n本项目同时也是 **OpenClaw 生态的 Skill**。如果你在用 OpenClaw 或 Trae IDE：\n\n```bash\n# 直接从 ClawHub 安装\nclawhub install knowledge-rag\n```\n\n安装后，你的 AI Agent 会自动获得「搜索知识库」的能力，还可以配合 bilibili-auto-transcript 实现「转录完自动入库」。\n\n---\n\n## 注意事项\n\n- 依赖 [Ollama](https://ollama.com/download)，首次下载模型约 4.7GB（8B）或 640MB（0.6B）需联网\n- PDF 支持**文字版** PDF，纯图像版 PDF 暂不支持\n- PDF/DOCX 解析需先创建虚拟环境：`python3 -m venv .venv && .venv/bin/pip install PyPDF2 pdfplumber python-docx`\n- 数据全部在 `~/workspace/knowledge/`，卸载不丢\n\n---\n\n## 交流\n\n- [GitHub Issues](https://github.com/54Lynnn/knowledge-rag/issues) — 反馈问题\n- QQ 群：120363664\n\n如果这个项目对你有帮助，欢迎 ⭐️ Star 支持！\n\nFile v1.6.1:_meta.json\n\n{\n  \"ownerId\": \"kn742cdrc476d1kbhpsvnrnznx81x4r7\",\n  \"slug\": \"knowledge-rag\",\n  \"version\": \"1.6.1\",\n  \"publishedAt\": 1780476666513\n}\n\nFile v1.6.1:skill-card.md\n\n## Description:\n\nPersonal knowledge base skill for saving notes, indexing local documents, and searching them with natural-language queries.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[54lynnn](https://clawhub.ai/user/54lynnn)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers, agents, and individual users use this skill to create a local searchable knowledge base from notes and documents, then retrieve relevant source text through chat-style prompts or CLI commands.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Private document search and admin APIs may be exposed too broadly.\n\nMitigation: Run only on a trusted single-user machine and do not expose ports 5777 or 8768 to a LAN or untrusted browser context.\n\nRisk: The skill can browse or index outside the intended knowledge folder.\n\nMitigation: Avoid placing sensitive documents in reachable paths until API binding, authentication, and path limits are fixed.\n\nRisk: Installation depends on external Ollama and package installation steps.\n\nMitigation: Use verified Ollama and package sources before installing or pulling embedding models.\n\n## Reference(s):\n\n- [ClawHub Skill Page](https://clawhub.ai/54lynnn/skills/knowledge-rag)\n- [Ollama Download](https://ollama.com/download)\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 and local API or CLI outputs]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Produces local search guidance and retrieval results backed by a local SQLite index and Ollama embeddings.]\n\n## Skill Version(s):\n\n1.6.1 (source: server release metadata)\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 v1.6.1:web/package-lock.json\n\n{\n  \"name\": \"knowledge-server-ts\",\n  \"version\": \"1.0.0\",\n  \"lockfileVersion\": 3,\n  \"requires\": true,\n  \"packages\": {\n    \"\": {\n      \"name\": \"knowledge-server-ts\",\n      \"version\": \"1.0.0\",\n      \"dependencies\": {\n        \"express\": \"^5.1.0\"\n      },\n      \"devDependencies\": {\n        \"@types/express\": \"^5.0.1\",\n        \"@types/node\": \"^22.14.1\",\n        \"tsx\": \"^4.19.4\",\n        \"typescript\": \"^5.8.3\"\n      }\n    },\n    \"node_modules/@esbuild/aix-ppc64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz\",\n      \"integrity\": \"sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==\",\n      \"cpu\": [\n        \"ppc64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"aix\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/android-arm\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz\",\n      \"integrity\": \"sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==\",\n      \"cpu\": [\n        \"arm\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"android\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/android-arm64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz\",\n      \"integrity\": \"sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"android\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/android-x64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz\",\n      \"integrity\": \"sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"android\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/darwin-arm64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz\",\n      \"integrity\": \"sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/darwin-x64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz\",\n      \"integrity\": \"sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/freebsd-arm64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz\",\n      \"integrity\": \"sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"freebsd\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/freebsd-x64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz\",\n      \"integrity\": \"sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"freebsd\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-arm\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz\",\n      \"integrity\": \"sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==\",\n      \"cpu\": [\n        \"arm\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-arm64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz\",\n      \"integrity\": \"sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-ia32\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz\",\n      \"integrity\": \"sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==\",\n      \"cpu\": [\n        \"ia32\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-loong64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz\",\n      \"integrity\": \"sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==\",\n      \"cpu\": [\n        \"loong64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-mips64el\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz\",\n      \"integrity\": \"sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==\",\n      \"cpu\": [\n        \"mips64el\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-ppc64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz\",\n      \"integrity\": \"sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==\",\n      \"cpu\": [\n        \"ppc64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-riscv64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz\",\n      \"integrity\": \"sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==\",\n      \"cpu\": [\n        \"riscv64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-s390x\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz\",\n      \"integrity\": \"sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==\",\n      \"cpu\": [\n        \"s390x\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-x64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz\",\n      \"integrity\": \"sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/netbsd-arm64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz\",\n      \"integrity\": \"sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"netbsd\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/netbsd-x64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz\",\n      \"integrity\": \"sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"netbsd\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/openbsd-arm64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz\",\n      \"integrity\": \"sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"openbsd\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/openbsd-x64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz\",\n      \"integrity\": \"sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"openbsd\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/openharmony-arm64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz\",\n      \"integrity\": \"sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"openharmony\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/sunos-x64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz\",\n      \"integrity\": \"sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"sunos\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/win32-arm64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz\",\n      \"integrity\": \"sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/win32-ia32\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz\",\n      \"integrity\": \"sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==\",\n      \"cpu\": [\n        \"ia32\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/win32-x64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz\",\n      \"integrity\": \"sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@types/body-parser\": {\n      \"version\": \"1.19.6\",\n      \"resolved\": \"https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz\",\n      \"integrity\": \"sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==\",\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"@types/connect\": \"*\",\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/connect\": {\n      \"version\": \"3.4.38\",\n      \"resolved\": \"https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz\",\n      \"integrity\": \"sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==\",\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/express\": {\n      \"version\": \"5.0.6\",\n      \"resolved\": \"https://registry.npmjs.org/@types/express/-/express-5.0.6.tgz\",\n      \"integrity\": \"sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==\",\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"@types/body-parser\": \"*\",\n        \"@types/express-serve-static-core\": \"^5.0.0\",\n        \"@types/serve-static\": \"^2\"\n      }\n    },\n    \"node_modules/@types/express-serve-static-core\": {\n      \"version\": \"5.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.1.tgz\",\n      \"integrity\": \"sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A==\",\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"@types/node\": \"*\",\n        \"@types/qs\": \"*\",\n        \"@types/range-parser\": \"*\",\n        \"@types/send\": \"*\"\n      }\n    },\n    \"node_modules/@types/http-errors\": {\n      \"version\": \"2.0.5\",\n      \"resolved\": \"https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz\",\n      \"integrity\": \"sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==\",\n      \"dev\": true,\n      \"license\": \"MIT\"\n    },\n    \"node_modules/@types/node\": {\n      \"version\": \"22.19.19\",\n      \"resolved\": \"https://registry.npmjs.org/@types/node/-/node-22.19.19.tgz\",\n      \"integrity\": \"sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew==\",\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"undici-types\": \"~6.21.0\"\n      }\n    },\n    \"node_modules/@types/qs\": {\n      \"version\": \"6.15.1\",\n      \"resolved\": \"https://registry.npmjs.org/@types/qs/-/qs-6.15.1.tgz\",\n      \"integrity\": \"sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw==\",\n      \"dev\": true,\n      \"license\": \"MIT\"\n    },\n    \"node_modules/@types/range-parser\": {\n      \"version\": \"1.2.7\",\n      \"resolved\": \"https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz\",\n      \"integrity\": \"sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==\",\n      \"dev\": true,\n      \"license\": \"MIT\"\n    },\n    \"node_modules/@types/send\": {\n      \"version\": \"1.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz\",\n      \"integrity\": \"sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==\",\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/serve-static\": {\n      \"version\": \"2.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/@types/serve-static/-/serve-static-2.2.0.tgz\",\n      \"integrity\": \"sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==\",\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"@types/http-errors\": \"*\",\n        \"@types/node\": \"*\"\n      }\n    },\n    \"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/body-parser\": {\n      \"version\": \"2.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz\",\n      \"integrity\": \"sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"bytes\": \"^3.1.2\",\n        \"content-type\": \"^1.0.5\",\n        \"debug\": \"^4.4.3\",\n        \"http-errors\": \"^2.0.0\",\n        \"iconv-lite\": \"^0.7.0\",\n        \"on-finished\": \"^2.4.1\",\n        \"qs\": \"^6.14.1\",\n        \"raw-body\": \"^3.0.1\",\n        \"type-is\": \"^2.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\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\": \"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/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.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/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/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/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/esbuild\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz\",\n      \"integrity\": \"sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==\",\n      \"dev\": true,\n      \"hasInstallScript\": true,\n      \"license\": \"MIT\",\n      \"bin\": {\n        \"esbuild\": \"bin/esbuild\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"optionalDependencies\": {\n        \"@esbuild/aix-ppc64\": \"0.28.0\",\n        \"@esbuild/android-arm\": \"0.28.0\",\n        \"@esbuild/android-arm64\": \"0.28.0\",\n        \"@esbuild/android-x64\": \"0.28.0\",\n        \"@esbuild/darwin-arm64\": \"0.28.0\",\n        \"@esbuild/darwin-x64\": \"0.28.0\",\n        \"@esbuild/freebsd-arm64\": \"0.28.0\",\n        \"@esbuild/freebsd-x64\": \"0.28.0\",\n        \"@esbuild/linux-arm\": \"0.28.0\",\n        \"@esbuild/linux-arm64\": \"0.28.0\",\n        \"@esbuild/linux-ia32\": \"0.28.0\",\n        \"@esbuild/linux-loong64\": \"0.28.0\",\n        \"@esbuild/linux-mips64el\": \"0.28.0\",\n        \"@esbuild/linux-ppc64\": \"0.28.0\",\n        \"@esbuild/linux-riscv64\": \"0.28.0\",\n        \"@esbuild/linux-s390x\": \"0.28.0\",\n        \"@esbuild/linux-x64\": \"0.28.0\",\n        \"@esbuild/netbsd-arm64\": \"0.28.0\",\n        \"@esbuild/netbsd-x64\": \"0.28.0\",\n        \"@esbuild/openbsd-arm64\": \"0.28.0\",\n        \"@esbuild/openbsd-x64\": \"0.28.0\",\n        \"@esbuild/openharmony-arm64\": \"0.28.0\",\n        \"@esbuild/sunos-x64\": \"0.28.0\",\n        \"@esbuild/win32-arm64\": \"0.28.0\",\n        \"@esbuild/win32-ia32\": \"0.28.0\",\n        \"@esbuild/win32-x64\": \"0.28.0\"\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/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/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/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\": \"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/fsevents\": {\n      \"version\": \"2.3.3\",\n      \"resolved\": \"https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz\",\n      \"integrity\": \"sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==\",\n      \"dev\": true,\n      \"hasInstallScript\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \"^8.16.0 || ^10.6.0 || >=11.0.0\"\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/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.7.2\",\n      \"resolved\": \"https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz\",\n      \"integrity\": \"sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==\",\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/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/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/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\": \"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/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/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/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/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/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/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-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/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.2\",\n      \"resolved\": \"https://registry.npmjs.org/qs/-/qs-6.15.2.tgz\",\n      \"integrity\": \"sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==\",\n      \"license\": \"BSD-3-Clause\",\n      \"dependencies\": {\n        \"side-channel\": \"^1.1.0\"\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/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/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\": \"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/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/setprototypeof\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz\",\n      \"integrity\": \"sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==\",\n      \"license\": \"ISC\"\n    },\n    \"node_modules/side-channel\": {\n      \"version\": \"1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz\",\n      \"integrity\": \"sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"es-errors\": \"^1.3.0\",\n        \"object-inspect\": \"^1.13.3\",\n        \"side-channel-list\": \"^1.0.0\",\n        \"side-channel-map\": \"^1.0.1\",\n        \"side-channel-weakmap\": \"^1.0.2\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/side-channel-list\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz\",\n      \"integrity\": \"sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"es-errors\": \"^1.3.0\",\n        \"object-inspect\": \"^1.13.4\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/side-channel-map\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz\",\n      \"integrity\": \"sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"call-bound\": \"^1.0.2\",\n        \"es-errors\": \"^1.3.0\",\n        \"get-intrinsic\": \"^1.2.5\",\n        \"object-inspect\": \"^1.13.3\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/side-channel-weakmap\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz\",\n      \"integrity\": \"sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"call-bound\": \"^1.0.2\",\n        \"es-errors\": \"^1.3.0\",\n        \"get-intrinsic\": \"^1.2.5\",\n        \"object-inspect\": \"^1.13.3\",\n        \"side-channel-map\": \"^1.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/statuses\": {\n      \"version\": \"2.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz\",\n      \"integrity\": \"sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.8\"\n      }\n    },\n    \"node_modules/toidentifier\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz\",\n      \"integrity\": \"sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=0.6\"\n      }\n    },\n    \"node_modules/tsx\": {\n      \"version\": \"4.22.3\",\n      \"resolved\": \"https://registry.npmjs.org/tsx/-/tsx-4.22.3.tgz\",\n      \"integrity\": \"sha512-mdoNxBC/cSQObGGVQ5Bpn5i+yv7j68gk3Nfm3wFjcJg3Z0Mix9jzAFfP12prmm5eVGmDKtp0yyArrs0Q+8gZHg==\",\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"esbuild\": \"~0.28.0\"\n      },\n      \"bin\": {\n        \"tsx\": \"dist/cli.mjs\"\n      },\n      \"engines\": {\n        \"node\": \">=18.0.0\"\n      },\n      \"optionalDependencies\": {\n        \"fsevents\": \"~2.3.3\"\n      }\n    },\n    \"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/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/typescript\": {\n      \"version\": \"5.9.3\",\n      \"resolved\": \"https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz\",\n      \"integrity\": \"sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==\",\n      \"dev\": true,\n      \"license\": \"Apache-2.0\",\n      \"bin\": {\n        \"tsc\": \"bin/tsc\",\n        \"tsserver\": \"bin/tsserver\"\n      },\n      \"engines\": {\n        \"node\": \">=14.17\"\n      }\n    },\n    \"node_modules/undici-types\": {\n      \"version\": \"6.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz\",\n      \"integrity\": \"sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==\",\n      \"dev\": true,\n      \"license\": \"MIT\"\n    },\n    \"node_modules/unpipe\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz\",\n      \"integrity\": \"sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.8\"\n      }\n    },\n    \"node_modules/vary\": {\n      \"version\": \"1.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/vary/-/vary-1.1.2.tgz\",\n      \"integrity\": \"sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.8\"\n      }\n    },\n    \"node_modules/wrappy\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz\",\n      \"integrity\": \"sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==\",\n      \"license\": \"ISC\"\n    }\n  }\n}\n\nFile v1.6.1:web/package.json\n\n{\n  \"name\": \"knowledge-server-ts\",\n  \"version\": \"1.0.0\",\n  \"private\": true,\n  \"description\": \"知识仓库搜索界面（TypeScript 版）\",\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"tsx watch src/server.ts\",\n    \"start\": \"tsx src/server.ts\",\n    \"build\": \"tsc\",\n    \"serve\": \"node dist/server.js\"\n  },\n  \"dependencies\": {\n    \"express\": \"^5.1.0\"\n  },\n  \"devDependencies\": {\n    \"@types/express\": \"^5.0.1\",\n    \"@types/node\": \"^22.14.1\",\n    \"tsx\": \"^4.19.4\",\n    \"typescript\": \"^5.8.3\"\n  }\n}\n\nFile v1.6.1:web/tsconfig.json\n\n{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"bundler\",\n    \"outDir\": \"dist\",\n    \"rootDir\": \"src\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"resolveJsonModule\": true,\n    \"declaration\": true,\n    \"declarationMap\": true,\n    \"sourceMap\": true\n  },\n  \"include\": [\"src/**/*\"],\n  \"exclude\": [\"node_modules\", \"dist\"]\n}\n\nArchive v1.6.0: 12 files, 44059 bytes\n\nFiles: scripts/index_knowledge.py (18549b), scripts/knowledge_api.py (10981b), scripts/query_knowledge.py (9896b), skill-card.md (2232b), SKILL.md (5916b), start.py (9592b), web/package-lock.json (49574b), web/package.json (498b), web/public/index.html (27213b), web/src/server.ts (7781b), web/tsconfig.json (451b), _meta.json (132b)\n\nFile v1.6.0:SKILL.md\n\n---\nname: knowledge-rag\nversion: \"1.5.5\"\ndescription: \"个人知识库：存笔记、搜内容。用自然语言搜本地文档，不用记文件名。跟 AI 说'把这段存到知识库'自动保存并建索引。推荐搭配 Bilibili Auto Transcript：视频转录自动入库，转完即搜。\"\nmetadata:\n  openclaw:\n    emoji: \"📖\"\n    requires:\n      bins: [\"python3\", \"ollama\"]\n    install:\n      - id: \"ollama\"\n        kind: \"system\"\n        label: \"安装 Ollama（向量引擎）\"\n        url: \"https://ollama.com/download\"\n      - id: \"embed-model\"\n        kind: \"shell\"\n        label: \"下载推荐向量模型（千问3 Embedding 8B，约 4.7GB）\"\n        command: \"ollama pull qwen3-embedding:8b\"\n      - id: \"pip-deps\"\n        kind: \"shell\"\n        label: \"安装 PDF/DOCX 解析依赖\"\n        command: \"pip install --break-system-packages PyPDF2 pdfplumber python-docx\"\n      - id: \"auto-index-cron\"\n        kind: \"shell\"\n        optional: true\n        label: \"（可选）开启自动索引——每30分钟扫描新文件\"\n        command: \"echo '提示：安装后可运行 openclaw cron add 定时运行 index_knowledge.py 实现自动索引'\"\n---\n\n# 📖 Knowledge RAG\n\n用自然语言搜索你的笔记和文档，像问 ChatGPT 一样问你的私人知识库。\n\n---\n\n## 🚀 安装启动\n\n```bash\n# 1. 安装 Ollama\ncurl -fsSL https://ollama.com/install.sh | sh\n\n# 2. 拉取推荐模型（千问3 Embedding，中文最优）\nollama pull qwen3-embedding:8b\n\n# 3. 启动（自动完成环境检测、依赖安装、打开浏览器）\npython3 start.py\n```\n\n打开 `http://localhost:5777` → 文件丢到 `~/workspace/knowledge/` → 管理页点「重新索引」→ 搜索页开搜。\n\n### 可选：开启自动索引\n新增文件后不用每次都手动点重新索引，设个定时任务每30分钟自动扫描：\n```bash\nopenclaw cron add \\\n  --name \"knowledge-rag 自动索引\" \\\n  --every 1800000 \\\n  --message \"运行索引检查：python3 scripts/index_knowledge.py\" \\\n  --silent\n```\n\n---\n\n## 📂 知识库目录\n\n```\n~/workspace/knowledge/\n  ├── notes/            ← 技术笔记、读书笔记\n  ├── bilibili/         ← B站转录\n  ├── wechat-articles/  ← 公众号文章\n  ├── other/            ← 其他文档\n  └── （可建任意子目录，去设置页添加）\n```\n\n支持 `.txt` / `.md` / `.pdf`（文字版）/ `.docx` 文件。\n\n---\n\n## 🔍 搜索方式\n\n### 直接问我\n> \"帮我搜笔记里关于 Docker 的部分\"  \n> \"知识库里有没有讲 Transformer 的文章？\"\n\n我会自动调搜索，带原文回答。\n\n### 命令行\n```bash\npython3 scripts/query_knowledge.py \"你的问题\"\npython3 scripts/query_knowledge.py \"微服务\" --source bilibili --top 5\npython3 scripts/query_knowledge.py --stats\n```\n\n新增文件后运行索引即可：\n```bash\npython3 scripts/index_knowledge.py          # 增量\npython3 scripts/index_knowledge.py --force  # 全量重建\n```\n\n---\n\n## 📝 Agent 存知识规范\n\n当用户说\"把这段存到知识库\"，按以下规则操作：\n\n| 内容类型 | 存放目录 | 文件名 |\n|---------|---------|--------|\n| 技术笔记、概念解释 | `notes/` | 中文描述.md |\n| B站视频转录 | `bilibili/` | 自动处理 |\n| 公众号、网页文章 | `wechat-articles/` | 文章标题.md |\n| 其他 | `other/` | 内容摘要.md |\n\n保存后运行 `python3 scripts/index_knowledge.py` 更新索引。\n\n---\n\n## 🔧 切换模型\n\n在设置页修改 `embed_model` 字段：\n\n| 场景 | 模型 | 大小 |\n|------|------|------|\n| ✅ 推荐（质量最高） | `qwen3-embedding:8b` | 4.7GB | 中文优秀，检索质量最高 |\n| 轻量（CPU友好） | `qwen3-embedding:0.6b` | 640MB | 对 CPU 友好，中文不错 |\n| 多语言 | `bge-m3` | 1.2GB |\n| 最小体积 | `nomic-embed-text` | 274MB |\n\n改完后点「重新索引」，系统自动检测并全量重建。\n\n---\n\n## 🧑‍💻 环境检测（给 AI 助手的指引）\n\n用户首次使用或出问题时，按顺序排查：\n\n1. **Ollama 是否安装？** → `ollama --version`，否则引导去 https://ollama.com/download\n2. **千问3 模型是否下载？** → `ollama list | grep qwen3-embedding`，否则 `ollama pull qwen3-embedding:8b`\n3. **索引模型是否匹配？** → 读 `~/workspace/knowledge/.rag_data/model_meta.json`，不匹配则提示重建\n\n快速诊断：\n```bash\ncurl -s http://localhost:8768/api/stats | python3 -c \"\nimport sys,json; d=json.load(sys.stdin)\nem = d.get('embed_model',{})\nprint(f'配置: {em.get(\\\"current\\\",\\\"?\\\")} | 索引: {em.get(\\\"stored\\\",\\\"?\\\")} ({em.get(\\\"stored_dim\\\",\\\"?\\\")}维)')\nprint(f'状态: {\\\"✅ 正常\\\" if not em.get(\\\"mismatch\\\") else \\\"❌ 不匹配\\\"}')\"\n```\n\n---\n\n## ⚠️ 注意事项\n\n- 依赖 Ollama，首次下载模型约 640MB 需联网\n- PDF 支持**文字版** PDF（PyPDF2 优先提取，失败自动降级到 pdfplumber），纯图像版 PDF 暂不支持\n- DOCX 支持通过 python-docx 提取段落文字和表格内容\n- PDF/DOCX 解析需安装额外依赖：`pip install --break-system-packages PyPDF2 pdfplumber python-docx`\n- 仅支持纯文本内容，不支持图片和 PDF 中的图像\n- 删除文件后运行「重新索引」即可从搜索结果移除（增量索引自动清理已删除文件，无需 --force）\n- 数据全部在 `~/workspace/knowledge/`，卸载不丢\n\n## 🎯 推荐搭配\n\n**Bilibili Auto Transcript** — 装了这个 skill 后，B站视频转录完自动存到知识库，不用手动操作：\n\n```bash\nclawhub install bilibili-auto-transcript\n```\n\n转录的文件自动进 `~/workspace/knowledge/bilibili/`，转完即搜。\n\n---\n\n## 📦 开源 & 交流\n\n- **GitHub**：[github.com/54Lynnn/knowledge-rag](https://github.com/54Lynnn/knowledge-rag)（⭐️ Star 支持）\n- **ClawHub**：[clawhub.ai/54lynnn/knowledge-rag](https://clawhub.ai/54lynnn/knowledge-rag)\n- **QQ 群**：120363664（欢迎扫码加入交流）\n\nFile v1.6.0:_meta.json\n\n{\n  \"ownerId\": \"kn742cdrc476d1kbhpsvnrnznx81x4r7\",\n  \"slug\": \"knowledge-rag\",\n  \"version\": \"1.6.0\",\n  \"publishedAt\": 1780284821245\n}\n\nFile v1.6.0:skill-card.md\n\n## Description: <br>\nKnowledge Rag helps an agent save, index, and search a user's local notes and documents with natural-language queries. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[54lynnn](https://clawhub.ai/user/54lynnn) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nExternal users and developers use this skill to build a local personal knowledge base, index text, Markdown, PDF, and DOCX files, and retrieve relevant passages through a web UI, CLI commands, or agent-guided search. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: Unauthenticated local services can browse and reconfigure access to local folders. <br>\nMitigation: Run the services only on a trusted local network and avoid exposing the web or API ports beyond the local machine. <br>\nRisk: The knowledge directory may include private notes, PDFs, or documents. <br>\nMitigation: Do not configure broad locations such as the home directory, and confirm before saving or indexing sensitive content. <br>\nRisk: Installation uses local packages and Ollama model setup. <br>\nMitigation: Prefer verified Ollama and package installations over curl-to-shell commands. <br>\n\n\n## Reference(s): <br>\n- [ClawHub Skill Page](https://clawhub.ai/54lynnn/knowledge-rag) <br>\n- [Publisher Profile](https://clawhub.ai/user/54lynnn) <br>\n- [Ollama Download](https://ollama.com/download) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance] <br>\n**Output Format:** [Markdown guidance with shell commands, local configuration, and search results from indexed documents.] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Uses local Ollama embeddings and stores index data under the configured local knowledge directory.] <br>\n\n## Skill Version(s): <br>\n1.6.0 (source: server release evidence) <br>\n\n## Ethical Considerations: <br>\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. <br>\n\nFile v1.6.0:web/package-lock.json\n\n{\n  \"name\": \"knowledge-server-ts\",\n  \"version\": \"1.0.0\",\n  \"lockfileVersion\": 3,\n  \"requires\": true,\n  \"packages\": {\n    \"\": {\n      \"name\": \"knowledge-server-ts\",\n      \"version\": \"1.0.0\",\n      \"dependencies\": {\n        \"express\": \"^5.1.0\"\n      },\n      \"devDependencies\": {\n        \"@types/express\": \"^5.0.1\",\n        \"@types/node\": \"^22.14.1\",\n        \"tsx\": \"^4.19.4\",\n        \"typescript\": \"^5.8.3\"\n      }\n    },\n    \"node_modules/@esbuild/aix-ppc64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz\",\n      \"integrity\": \"sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==\",\n      \"cpu\": [\n        \"ppc64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"aix\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/android-arm\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz\",\n      \"integrity\": \"sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==\",\n      \"cpu\": [\n        \"arm\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"android\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/android-arm64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz\",\n      \"integrity\": \"sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"android\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/android-x64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz\",\n      \"integrity\": \"sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"android\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/darwin-arm64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz\",\n      \"integrity\": \"sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/darwin-x64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz\",\n      \"integrity\": \"sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/freebsd-arm64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz\",\n      \"integrity\": \"sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"freebsd\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/freebsd-x64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz\",\n      \"integrity\": \"sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"freebsd\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-arm\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz\",\n      \"integrity\": \"sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==\",\n      \"cpu\": [\n        \"arm\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-arm64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz\",\n      \"integrity\": \"sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-ia32\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz\",\n      \"integrity\": \"sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==\",\n      \"cpu\": [\n        \"ia32\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-loong64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz\",\n      \"integrity\": \"sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==\",\n      \"cpu\": [\n        \"loong64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-mips64el\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz\",\n      \"integrity\": \"sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==\",\n      \"cpu\": [\n        \"mips64el\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-ppc64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz\",\n      \"integrity\": \"sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==\",\n      \"cpu\": [\n        \"ppc64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-riscv64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz\",\n      \"integrity\": \"sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==\",\n      \"cpu\": [\n        \"riscv64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-s390x\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz\",\n      \"integrity\": \"sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==\",\n      \"cpu\": [\n        \"s390x\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-x64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz\",\n      \"integrity\": \"sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/netbsd-arm64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz\",\n      \"integrity\": \"sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"netbsd\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/netbsd-x64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz\",\n      \"integrity\": \"sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"netbsd\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/openbsd-arm64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz\",\n      \"integrity\": \"sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"openbsd\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/openbsd-x64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz\",\n      \"integrity\": \"sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"openbsd\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/openharmony-arm64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz\",\n      \"integrity\": \"sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"openharmony\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/sunos-x64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz\",\n      \"integrity\": \"sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"sunos\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/win32-arm64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz\",\n      \"integrity\": \"sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/win32-ia32\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz\",\n      \"integrity\": \"sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==\",\n      \"cpu\": [\n        \"ia32\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/win32-x64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz\",\n      \"integrity\": \"sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@types/body-parser\": {\n      \"version\": \"1.19.6\",\n      \"resolved\": \"https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz\",\n      \"integrity\": \"sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==\",\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"@types/connect\": \"*\",\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/connect\": {\n      \"version\": \"3.4.38\",\n      \"resolved\": \"https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz\",\n      \"integrity\": \"sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==\",\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/express\": {\n      \"version\": \"5.0.6\",\n      \"resolved\": \"https://registry.npmjs.org/@types/express/-/express-5.0.6.tgz\",\n      \"integrity\": \"sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==\",\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"@types/body-parser\": \"*\",\n        \"@types/express-serve-static-core\": \"^5.0.0\",\n        \"@types/serve-static\": \"^2\"\n      }\n    },\n    \"node_modules/@types/express-serve-static-core\": {\n      \"version\": \"5.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.1.tgz\",\n      \"integrity\": \"sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A==\",\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"@types/node\": \"*\",\n        \"@types/qs\": \"*\",\n        \"@types/range-parser\": \"*\",\n        \"@types/send\": \"*\"\n      }\n    },\n    \"node_modules/@types/http-errors\": {\n      \"version\": \"2.0.5\",\n      \"resolved\": \"https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz\",\n      \"integrity\": \"sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==\",\n      \"dev\": true,\n      \"license\": \"MIT\"\n    },\n    \"node_modules/@types/node\": {\n      \"version\": \"22.19.19\",\n      \"resolved\": \"https://registry.npmjs.org/@types/node/-/node-22.19.19.tgz\",\n      \"integrity\": \"sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew==\",\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"undici-types\": \"~6.21.0\"\n      }\n    },\n    \"node_modules/@types/qs\": {\n      \"version\": \"6.15.1\",\n      \"resolved\": \"https://registry.npmjs.org/@types/qs/-/qs-6.15.1.tgz\",\n      \"integrity\": \"sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw==\",\n      \"dev\": true,\n      \"license\": \"MIT\"\n    },\n    \"node_modules/@types/range-parser\": {\n      \"version\": \"1.2.7\",\n      \"resolved\": \"https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz\",\n      \"integrity\": \"sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==\",\n      \"dev\": true,\n      \"license\": \"MIT\"\n    },\n    \"node_modules/@types/send\": {\n      \"version\": \"1.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz\",\n      \"integrity\": \"sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==\",\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/serve-static\": {\n      \"version\": \"2.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/@types/serve-static/-/serve-static-2.2.0.tgz\",\n      \"integrity\": \"sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==\",\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"@types/http-errors\": \"*\",\n        \"@types/node\": \"*\"\n      }\n    },\n    \"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/body-parser\": {\n      \"version\": \"2.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz\",\n      \"integrity\": \"sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"bytes\": \"^3.1.2\",\n        \"content-type\": \"^1.0.5\",\n        \"debug\": \"^4.4.3\",\n        \"http-errors\": \"^2.0.0\",\n        \"iconv-lite\": \"^0.7.0\",\n        \"on-finished\": \"^2.4.1\",\n        \"qs\": \"^6.14.1\",\n        \"raw-body\": \"^3.0.1\",\n        \"type-is\": \"^2.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/express\"\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\": \"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/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.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/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/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/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/esbuild\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz\",\n      \"integrity\": \"sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==\",\n      \"dev\": true,\n      \"hasInstallScript\": true,\n      \"license\": \"MIT\",\n      \"bin\": {\n        \"esbuild\": \"bin/esbuild\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"optionalDependencies\": {\n        \"@esbuild/aix-ppc64\": \"0.28.0\",\n        \"@esbuild/android-arm\": \"0.28.0\",\n        \"@esbuild/android-arm64\": \"0.28.0\",\n        \"@esbuild/android-x64\": \"0.28.0\",\n        \"@esbuild/darwin-arm64\": \"0.28.0\",\n        \"@esbuild/darwin-x64\": \"0.28.0\",\n        \"@esbuild/freebsd-arm64\": \"0.28.0\",\n        \"@esbuild/freebsd-x64\": \"0.28.0\",\n        \"@esbuild/linux-arm\": \"0.28.0\",\n        \"@esbuild/linux-arm64\": \"0.28.0\",\n        \"@esbuild/linux-ia32\": \"0.28.0\",\n        \"@esbuild/linux-loong64\": \"0.28.0\",\n        \"@esbuild/linux-mips64el\": \"0.28.0\",\n        \"@esbuild/linux-ppc64\": \"0.28.0\",\n        \"@esbuild/linux-riscv64\": \"0.28.0\",\n        \"@esbuild/linux-s390x\": \"0.28.0\",\n        \"@esbuild/linux-x64\": \"0.28.0\",\n        \"@esbuild/netbsd-arm64\": \"0.28.0\",\n        \"@esbuild/netbsd-x64\": \"0.28.0\",\n        \"@esbuild/openbsd-arm64\": \"0.28.0\",\n        \"@esbuild/openbsd-x64\": \"0.28.0\",\n        \"@esbuild/openharmony-arm64\": \"0.28.0\",\n        \"@esbuild/sunos-x64\": \"0.28.0\",\n        \"@esbuild/win32-arm64\": \"0.28.0\",\n        \"@esbuild/win32-ia32\": \"0.28.0\",\n        \"@esbuild/win32-x64\": \"0.28.0\"\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/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/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/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\": \"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/fsevents\": {\n      \"version\": \"2.3.3\",\n      \"resolved\": \"https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz\",\n      \"integrity\": \"sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==\",\n      \"dev\": true,\n      \"hasInstallScript\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \"^8.16.0 || ^10.6.0 || >=11.0.0\"\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/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.7.2\",\n      \"resolved\": \"https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz\",\n      \"integrity\": \"sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==\",\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/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/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/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\": \"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/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/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/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/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/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/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-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/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.2\",\n      \"resolved\": \"https://registry.npmjs.org/qs/-/qs-6.15.2.tgz\",\n      \"integrity\": \"sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==\",\n      \"license\": \"BSD-3-Clause\",\n      \"dependencies\": {\n        \"side-channel\": \"^1.1.0\"\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/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/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\": \"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/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/setprototypeof\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz\",\n      \"integrity\": \"sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==\",\n      \"license\": \"ISC\"\n    },\n    \"node_modules/side-channel\": {\n      \"version\": \"1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz\",\n      \"integrity\": \"sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"es-errors\": \"^1.3.0\",\n        \"object-inspect\": \"^1.13.3\",\n        \"side-channel-list\": \"^1.0.0\",\n        \"side-channel-map\": \"^1.0.1\",\n        \"side-channel-weakmap\": \"^1.0.2\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/side-channel-list\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz\",\n      \"integrity\": \"sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"es-errors\": \"^1.3.0\",\n        \"object-inspect\": \"^1.13.4\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/side-channel-map\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz\",\n      \"integrity\": \"sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"call-bound\": \"^1.0.2\",\n        \"es-errors\": \"^1.3.0\",\n        \"get-intrinsic\": \"^1.2.5\",\n        \"object-inspect\": \"^1.13.3\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/side-channel-weakmap\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz\",\n      \"integrity\": \"sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"call-bound\": \"^1.0.2\",\n        \"es-errors\": \"^1.3.0\",\n        \"get-intrinsic\": \"^1.2.5\",\n        \"object-inspect\": \"^1.13.3\",\n        \"side-channel-map\": \"^1.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/statuses\": {\n      \"version\": \"2.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz\",\n      \"integrity\": \"sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.8\"\n      }\n    },\n    \"node_modules/toidentifier\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz\",\n      \"integrity\": \"sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=0.6\"\n      }\n    },\n    \"node_modules/tsx\": {\n      \"version\": \"4.22.3\",\n      \"resolved\": \"https://registry.npmjs.org/tsx/-/tsx-4.22.3.tgz\",\n      \"integrity\": \"sha512-mdoNxBC/cSQObGGVQ5Bpn5i+yv7j68gk3Nfm3wFjcJg3Z0Mix9jzAFfP12prmm5eVGmDKtp0yyArrs0Q+8gZHg==\",\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"esbuild\": \"~0.28.0\"\n      },\n      \"bin\": {\n        \"tsx\": \"dist/cli.mjs\"\n      },\n      \"engines\": {\n        \"node\": \">=18.0.0\"\n      },\n      \"optionalDependencies\": {\n        \"fsevents\": \"~2.3.3\"\n      }\n    },\n    \"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/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/typescript\": {\n      \"version\": \"5.9.3\",\n      \"resolved\": \"https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz\",\n      \"integrity\": \"sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==\",\n      \"dev\": true,\n      \"license\": \"Apache-2.0\",\n      \"bin\": {\n        \"tsc\": \"bin/tsc\",\n        \"tsserver\": \"bin/tsserver\"\n      },\n      \"engines\": {\n        \"node\": \">=14.17\"\n      }\n    },\n    \"node_modules/undici-types\": {\n      \"version\": \"6.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz\",\n      \"integrity\": \"sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==\",\n      \"dev\": true,\n      \"license\": \"MIT\"\n    },\n    \"node_modules/unpipe\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz\",\n      \"integrity\": \"sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.8\"\n      }\n    },\n    \"node_modules/vary\": {\n      \"version\": \"1.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/vary/-/vary-1.1.2.tgz\",\n      \"integrity\": \"sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">= 0.8\"\n      }\n    },\n    \"node_modules/wrappy\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz\",\n      \"integrity\": \"sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==\",\n      \"license\": \"ISC\"\n    }\n  }\n}\n\nFile v1.6.0:web/package.json\n\n{\n  \"name\": \"knowledge-server-ts\",\n  \"version\": \"1.0.0\",\n  \"private\": true,\n  \"description\": \"知识仓库搜索界面（TypeScript 版）\",\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"tsx watch src/server.ts\",\n    \"start\": \"tsx src/server.ts\",\n    \"build\": \"tsc\",\n    \"serve\": \"node dist/server.js\"\n  },\n  \"dependencies\": {\n    \"express\": \"^5.1.0\"\n  },\n  \"devDependencies\": {\n    \"@types/express\": \"^5.0.1\",\n    \"@types/node\": \"^22.14.1\",\n    \"tsx\": \"^4.19.4\",\n    \"typescript\": \"^5.8.3\"\n  }\n}\n\nFile v1.6.0:web/tsconfig.json\n\n{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"bundler\",\n    \"outDir\": \"dist\",\n    \"rootDir\": \"src\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"resolveJsonModule\": true,\n    \"declaration\": true,\n    \"declarationMap\": true,\n    \"sourceMap\": true\n  },\n  \"include\": [\"src/**/*\"],\n  \"exclude\": [\"node_modules\", \"dist\"]\n}\n\nArchive v1.5.7: 12 files, 42768 bytes\n\nFiles: scripts/index_knowledge.py (16056b), scripts/knowledge_api.py (10332b), scripts/query_knowledge.py (8550b), skill-card.md (2228b), SKILL.md (5854b), start.py (9594b), web/package-lock.json (49574b), web/package.json (498b), web/public/index.html (27213b), web/src/server.ts (7643b), web/tsconfig.json (451b), _meta.json (132b)\n\nFile v1.5.7:SKILL.md\n\n---\nname: knowledge-rag\nversion: \"1.5.5\"\ndescription: \"个人知识库：存笔记、搜内容。用自然语言搜本地文档，不用记文件名。跟 AI 说'把这段存到知识库'自动保存并建索引。推荐搭配 Bilibili Auto Transcript：视频转录自动入库，转完即搜。\"\nmetadata:\n  openclaw:\n    emoji: \"📖\"\n    requires:\n      bins: [\"python3\", \"ollama\"]\n    install:\n      - id: \"ollama\"\n        kind: \"system\"\n        label: \"安装 Ollama（向量引擎）\"\n        url: \"https://ollama.com/download\"\n      - id: \"embed-model\"\n        kind: \"shell\"\n        label: \"下载推荐向量模型（千问3 Embedding 0.6B，约 640MB）\"\n        command: \"ollama pull qwen3-embedding:0.6b\"\n      - id: \"pip-deps\"\n        kind: \"shell\"\n        label: \"安装 PDF/DOCX 解析依赖\"\n        command: \"pip install --break-system-packages PyPDF2 pdfplumber python-docx\"\n      - id: \"auto-index-cron\"\n        kind: \"shell\"\n        optional: true\n        label: \"（可选）开启自动索引——每30分钟扫描新文件\"\n        command: \"echo '提示：安装后可运行 openclaw cron add 定时运行 index_knowledge.py 实现自动索引'\"\n---\n\n# 📖 Knowledge RAG\n\n用自然语言搜索你的笔记和文档，像问 ChatGPT 一样问你的私人知识库。\n\n---\n\n## 🚀 安装启动\n\n```bash\n# 1. 安装 Ollama\ncurl -fsSL https://ollama.com/install.sh | sh\n\n# 2. 拉取推荐模型（千问3 Embedding，中文最优）\nollama pull qwen3-embedding:0.6b\n\n# 3. 启动（自动完成环境检测、依赖安装、打开浏览器）\npython3 start.py\n```\n\n打开 `http://localhost:5777` → 文件丢到 `~/workspace/knowledge/` → 管理页点「重新索引」→ 搜索页开搜。\n\n### 可选：开启自动索引\n新增文件后不用每次都手动点重新索引，设个定时任务每30分钟自动扫描：\n```bash\nopenclaw cron add \\\n  --name \"knowledge-rag 自动索引\" \\\n  --every 1800000 \\\n  --message \"运行索引检查：python3 scripts/index_knowledge.py\" \\\n  --silent\n```\n\n---\n\n## 📂 知识库目录\n\n```\n~/workspace/knowledge/\n  ├── notes/            ← 技术笔记、读书笔记\n  ├── bilibili/         ← B站转录\n  ├── wechat-articles/  ← 公众号文章\n  ├── other/            ← 其他文档\n  └── （可建任意子目录，去设置页添加）\n```\n\n支持 `.txt` / `.md` / `.pdf`（文字版）/ `.docx` 文件。\n\n---\n\n## 🔍 搜索方式\n\n### 直接问我\n> \"帮我搜笔记里关于 Docker 的部分\"  \n> \"知识库里有没有讲 Transformer 的文章？\"\n\n我会自动调搜索，带原文回答。\n\n### 命令行\n```bash\npython3 scripts/query_knowledge.py \"你的问题\"\npython3 scripts/query_knowledge.py \"微服务\" --source bilibili --top 5\npython3 scripts/query_knowledge.py --stats\n```\n\n新增文件后运行索引即可：\n```bash\npython3 scripts/index_knowledge.py          # 增量\npython3 scripts/index_knowledge.py --force  # 全量重建\n```\n\n---\n\n## 📝 Agent 存知识规范\n\n当用户说\"把这段存到知识库\"，按以下规则操作：\n\n| 内容类型 | 存放目录 | 文件名 |\n|---------|---------|--------|\n| 技术笔记、概念解释 | `notes/` | 中文描述.md |\n| B站视频转录 | `bilibili/` | 自动处理 |\n| 公众号、网页文章 | `wechat-articles/` | 文章标题.md |\n| 其他 | `other/` | 内容摘要.md |\n\n保存后运行 `python3 scripts/index_knowledge.py` 更新索引。\n\n---\n\n## 🔧 切换模型\n\n在设置页修改 `embed_model` 字段：\n\n| 场景 | 模型 | 大小 |\n|------|------|------|\n| ✅ 推荐（CPU友好） | `qwen3-embedding:0.6b` | 640MB | 中文最优，CPU 流畅\n| 进阶（需 GPU） | `qwen3-embedding:8b` | 4.7GB | 质量最高 |\n| 多语言 | `bge-m3` | 1.2GB |\n| 最小体积 | `nomic-embed-text` | 274MB |\n\n改完后点「重新索引」，系统自动检测并全量重建。\n\n---\n\n## 🧑‍💻 环境检测（给 AI 助手的指引）\n\n用户首次使用或出问题时，按顺序排查：\n\n1. **Ollama 是否安装？** → `ollama --version`，否则引导去 https://ollama.com/download\n2. **千问3 模型是否下载？** → `ollama list | grep qwen3-embedding`，否则 `ollama pull qwen3-embedding:0.6b`（如有独显可升级到 8b）\n3. **索引模型是否匹配？** → 读 `~/workspace/knowledge/.rag_data/model_meta.json`，不匹配则提示重建\n\n快速诊断：\n```bash\ncurl -s http://localhost:8768/api/stats | python3 -c \"\nimport sys,json; d=json.load(sys.stdin)\nem = d.get('embed_model',{})\nprint(f'配置: {em.get(\\\"current\\\",\\\"?\\\")} | 索引: {em.get(\\\"stored\\\",\\\"?\\\")} ({em.get(\\\"stored_dim\\\",\\\"?\\\")}维)')\nprint(f'状态: {\\\"✅ 正常\\\" if not em.get(\\\"mismatch\\\") else \\\"❌ 不匹配\\\"}')\"\n```\n\n---\n\n## ⚠️ 注意事项\n\n- 依赖 Ollama，首次下载模型约 640MB 需联网\n- PDF 支持**文字版** PDF（PyPDF2 优先提取，失败自动降级到 pdfplumber），纯图像版 PDF 暂不支持\n- DOCX 支持通过 python-docx 提取段落文字和表格内容\n- PDF/DOCX 解析需安装额外依赖：`pip install --break-system-packages PyPDF2 pdfplumber python-docx`\n- 仅支持纯文本内容，不支持图片和 PDF 中的图像\n- 删除文件后需重新索引才能从搜索结果移除\n- 数据全部在 `~/workspace/knowledge/`，卸载不丢\n\n## 🎯 推荐搭配\n\n**Bilibili Auto Transcript** — 装了这个 skill 后，B站视频转录完自动存到知识库，不用手动操作：\n\n```bash\nclawhub install bilibili-auto-transcript\n```\n\n转录的文件自动进 `~/workspace/knowledge/bilibili/`，转完即搜。\n\n---\n\n## 📦 开源 & 交流\n\n- **GitHub**：[github.com/54Lynnn/knowledge-rag](https://github.com/54Lynnn/knowledge-rag)（⭐️ Star 支持）\n- **ClawHub**：[clawhub.ai/54lynnn/knowledge-rag](https://clawhub.ai/54lynnn/knowledge-rag)\n- **QQ 群**：120363664（欢迎扫码加入交流）\n\nFile v1.5.7:_meta.json\n\n{\n  \"ownerId\": \"kn742cdrc476d1kbhpsvnrnznx81x4r7\",\n  \"slug\": \"knowledge-rag\",\n  \"version\": \"1.5.7\",\n  \"publishedAt\": 1780277463742\n}\n\nFile v1.5.7:skill-card.md\n\n## Description: <br>\nKnowledge Rag helps agents store notes and local documents, index supported text-based files, and search a private knowledge base with natural-language queries. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[54lynnn](https://clawhub.ai/user/54lynnn) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nExternal users, developers, and agent operators use this skill to maintain a local personal knowledge base, save new notes into organized folders, reindex content, and retrieve source text through a local web UI or command-line workflow. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The local web services expose filesystem browsing, knowledge-base settings, reindexing, and search over private indexed content. <br>\nMitigation: Run the service only on trusted machines and networks, stop it when not in use, and review folder selection before indexing. <br>\nRisk: Sensitive files placed in the configured knowledge directory may be indexed and returned in search results. <br>\nMitigation: Avoid storing secrets in the knowledge directory and review indexed folders before use. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill listing](https://clawhub.ai/54lynnn/knowledge-rag) <br>\n- [ClawHub publisher profile](https://clawhub.ai/user/54lynnn) <br>\n- [Ollama download](https://ollama.com/download) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [Text, Markdown, Shell commands, Configuration, Guidance] <br>\n**Output Format:** [Markdown guidance with inline shell commands and local search result text] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Requires Python 3, Ollama, a local embedding model, and local knowledge files under the configured knowledge directory.] <br>\n\n## Skill Version(s): <br>\n1.5.7 (source: server release evidence; artifact frontmatter reports 1.5.5) <br>\n\n## Ethical Considerations: <br>\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. <br>\n\nFile v1.5.7:web/package-lock.json\n\n{\n  \"name\": \"knowledge-server-ts\",\n  \"version\": \"1.0.0\",\n  \"lockfileVersion\": 3,\n  \"requires\": true,\n  \"packages\": {\n    \"\": {\n      \"name\": \"knowledge-server-ts\",\n      \"version\": \"1.0.0\",\n      \"dependencies\": {\n        \"express\": \"^5.1.0\"\n      },\n      \"devDependencies\": {\n        \"@types/express\": \"^5.0.1\",\n        \"@types/node\": \"^22.14.1\",\n        \"tsx\": \"^4.19.4\",\n        \"typescript\": \"^5.8.3\"\n      }\n    },\n    \"node_modules/@esbuild/aix-ppc64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz\",\n      \"integrity\": \"sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==\",\n      \"cpu\": [\n        \"ppc64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"aix\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/android-arm\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz\",\n      \"integrity\": \"sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==\",\n      \"cpu\": [\n        \"arm\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"android\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/android-arm64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz\",\n      \"integrity\": \"sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"android\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/android-x64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz\",\n      \"integrity\": \"sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"android\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/darwin-arm64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz\",\n      \"integrity\": \"sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/darwin-x64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz\",\n      \"integrity\": \"sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/freebsd-arm64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz\",\n      \"integrity\": \"sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"freebsd\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/freebsd-x64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz\",\n      \"integrity\": \"sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"freebsd\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-arm\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz\",\n      \"integrity\": \"sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==\",\n      \"cpu\": [\n        \"arm\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-arm64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz\",\n      \"integrity\": \"sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-ia32\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz\",\n      \"integrity\": \"sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==\",\n      \"cpu\": [\n        \"ia32\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-loong64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz\",\n      \"integrity\": \"sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==\",\n      \"cpu\": [\n        \"loong64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-mips64el\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz\",\n      \"integrity\": \"sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==\",\n      \"cpu\": [\n        \"mips64el\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-ppc64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz\",\n      \"integrity\": \"sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==\",\n      \"cpu\": [\n        \"ppc64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-riscv64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz\",\n      \"integrity\": \"sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==\",\n      \"cpu\": [\n        \"riscv64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-s390x\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz\",\n      \"integrity\": \"sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==\",\n      \"cpu\": [\n        \"s390x\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/linux-x64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz\",\n      \"integrity\": \"sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/netbsd-arm64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz\",\n      \"integrity\": \"sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"netbsd\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/netbsd-x64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz\",\n      \"integrity\": \"sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"netbsd\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/openbsd-arm64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz\",\n      \"integrity\": \"sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"openbsd\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/openbsd-x64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz\",\n      \"integrity\": \"sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"openbsd\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/openharmony-arm64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz\",\n      \"integrity\": \"sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"openharmony\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/sunos-x64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz\",\n      \"integrity\": \"sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"sunos\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/win32-arm64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz\",\n      \"integrity\": \"sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/win32-ia32\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz\",\n      \"integrity\": \"sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==\",\n      \"cpu\": [\n        \"ia32\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/win32-x64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz\",\n      \"integrity\": \"sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@types/body-parser\": {\n      \"version\": \"1.19.6\",\n      \"resolved\": \"https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz\",\n      \"integrity\": \"sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==\",\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"@types/connect\": \"*\",\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/connect\": {\n      \"version\": \"3.4.38\",\n      \"resolved\": \"https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz\",\n      \"integrity\": \"sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==\",\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/express\": {\n      \"version\": \"5.0.6\",\n      \"resolved\": \"https://registry.npmjs.org/@types/express/-/express-5.0.6.tgz\",\n      \"integrity\": \"sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==\",\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"@types/body-parser\": \"*\",\n        \"@types/express-serve-static-core\": \"^5.0.0\",\n        \"@types/serve-static\": \"^2\"\n      }\n    },\n    \"node_modules/@types/express-serve-static-core\": {\n      \"version\": \"5.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.1.tgz\",\n      \"integrity\": \"sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A==\",\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"@types/node\": \"*\",\n        \"@types/qs\": \"*\",\n        \"@types/range-parser\": \"*\",\n        \"@types/send\": \"*\"\n      }\n    },\n    \"node_modules/@types/http-errors\": {\n      \"version\": \"2.0.5\",\n      \"resolved\": \"https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz\",\n      \"integrity\": \"sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==\",\n      \"dev\": true,\n      \"license\": \"MIT\"\n    },\n    \"node_modules/@types/node\": {\n      \"version\": \"22.19.19\",\n      \"resolved\": \"https://registry.npmjs.org/@types/node/-/node-22.19.19.tgz\",\n      \"integrity\": \"sha512-dyh/xO2Fh5bYrfWa\n\nArchive v1.5.6: 12 files, 42803 bytes\n\nFiles: scripts/index_knowledge.py (16054b), scripts/knowledge_api.py (10332b), scripts/query_knowledge.py (8548b), skill-card.md (2407b), SKILL.md (5776b), start.py (9592b), web/package-lock.json (49574b), web/package.json (498b), web/public/index.html (27213b), web/src/server.ts (7641b), web/tsconfig.json (451b), _meta.json (132b)\n\nArchive v1.5.5: 12 files, 41249 bytes\n\nFiles: scripts/index_knowledge.py (12606b), scripts/knowledge_api.py (10477b), scripts/query_knowledge.py (7654b), skill-card.md (2175b), SKILL.md (5215b), start.py (9558b), web/package-lock.json (49574b), web/package.json (498b), web/public/index.html (27213b), web/src/server.ts (7643b), web/tsconfig.json (451b), _meta.json (132b)\n\nArchive v1.5.4: 12 files, 41204 bytes\n\nFiles: scripts/index_knowledge.py (12606b), scripts/knowledge_api.py (10477b), scripts/query_knowledge.py (7654b), skill-card.md (2424b), SKILL.md (4920b), start.py (9558b), web/package-lock.json (49574b), web/package.json (498b), web/public/index.html (27213b), web/src/server.ts (7643b), web/tsconfig.json (451b), _meta.json (132b)\n\nArchive v1.5.3: 12 files, 40930 bytes\n\nFiles: scripts/index_knowledge.py (12606b), scripts/knowledge_api.py (10477b), scripts/query_knowledge.py (7654b), skill-card.md (2258b), SKILL.md (4335b), start.py (9558b), web/package-lock.json (49574b), web/package.json (498b), web/public/index.html (27213b), web/src/server.ts (7643b), web/tsconfig.json (451b), _meta.json (132b)\n\nArchive v1.5.2: 12 files, 40903 bytes\n\nFiles: scripts/index_knowledge.py (12606b), scripts/knowledge_api.py (10477b), scripts/query_knowledge.py (7654b), skill-card.md (2188b), SKILL.md (4335b), start.py (9558b), web/package-lock.json (49574b), web/package.json (498b), web/public/index.html (27213b), web/src/server.ts (7643b), web/tsconfig.json (451b), _meta.json (132b)\n\nArchive v1.5.1: 12 files, 40959 bytes\n\nFiles: scripts/index_knowledge.py (12606b), scripts/knowledge_api.py (10477b), scripts/query_knowledge.py (7654b), skill-card.md (2330b), SKILL.md (4335b), start.py (9558b), web/package-lock.json (49574b), web/package.json (498b), web/public/index.html (27213b), web/src/server.ts (7643b), web/tsconfig.json (451b), _meta.json (132b)\n\nArchive v1.5.0: 13 files, 51927 bytes\n\nFiles: scripts/index_knowledge.py (12606b), scripts/knowledge_api.py (10477b), scripts/knowledge_server.py (35612b), scripts/query_knowledge.py (7654b), skill-card.md (2588b), SKILL.md (4335b), start.py (9558b), web/package-lock.json (49574b), web/package.json (498b), web/public/index.html (27213b), web/src/server.ts (7643b), web/tsconfig.json (451b), _meta.json (132b)","readmeExcerpt":"Skill: Knowledge Rag Owner: 54lynnn Summary: 个人知识库：存笔记、搜内容。用自然语言搜本地文档，不用记文件名。跟 AI 说'把这段存到知识库'自动保存并建索引。推荐搭配 Bilibili Auto Transcript：视频转录自动入库，转完即搜。 Tags: 54lynnn:1.1.0, chinese:1.5.4, knowledge:1.5.4, latest:1.6.1, rag:1.5.4, search:1.5.4 Version history: v1.6.1 | 2026-06-03T08:51:06.513Z | auto **Virtual environment support and installation process improvement** - Added virtual environment (.venv) support; all depend","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"curl -fsSL https://ollama.com/install.sh | sh"},{"language":"bash","snippet":"# 1. 安装 Ollama\ncurl -fsSL https://ollama.com/install.sh | sh\n\n# 2. 拉取推荐模型（千问3 Embedding，中文最优）\nollama pull qwen3-embedding:8b\n\n# 3. 创建虚拟环境并安装依赖\npython3 -m venv .venv\n.venv/bin/pip install numpy requests fastapi pydantic uvicorn PyPDF2 pdfplumber python-docx\n\n# 4. 启动\n.venv/bin/python3 start.py"},{"language":"bash","snippet":"openclaw cron add \\\n  --name \"knowledge-rag 自动索引\" \\\n  --every 1800000 \\\n  --message \"运行索引检查：cd ~/.openclaw/workspace/skills/knowledge-rag && .venv/bin/python3 scripts/index_knowledge.py\" \\\n  --silent"},{"language":"text","snippet":"~/workspace/knowledge/\n  ├── notes/            ← 技术笔记、读书笔记\n  ├── bilibili/         ← B站转录\n  ├── wechat-articles/  ← 公众号文章\n  ├── other/            ← 其他文档\n  └── （可建任意子目录，去设置页添加）"},{"language":"bash","snippet":".venv/bin/python3 scripts/query_knowledge.py \"你的问题\"\n.venv/bin/python3 scripts/query_knowledge.py \"微服务\" --source bilibili --top 5\n.venv/bin/python3 scripts/query_knowledge.py --stats"},{"language":"bash","snippet":".venv/bin/python3 scripts/index_knowledge.py          # 增量\n.venv/bin/python3 scripts/index_knowledge.py --force  # 全量重建"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: knowledge-rag\nversion: \"1.6.0\"\ndescription: \"个人知识库：存笔记、搜内容。用自然语言搜本地文档，不用记文件名。跟 AI 说'把这段存到知识库'自动保存并建索引。推荐搭配 Bilibili Auto Transcript：视频转录自动入库，转完即搜。\"\nmetadata:\n  openclaw:\n    emoji: \"📖\"\n    requires:\n      bins: [\"python3\", \"ollama\"]\n    install:\n      - id: \"ollama\"\n        kind: \"system\"\n        label: \"安装 Ollama（向量引擎）\"\n        url: \"https://ollama.com/download\"\n      - id: \"embed-model\"\n        kind: \"shell\"\n        label: \"下载推荐向量模型（千问3 Embedding 8B，约 4.7GB）\"\n        command: \"ollama pull qwen3-embedding:8b\"\n      - id: \"pip-deps\"\n        kind: \"shell\"\n        label: \"创建虚拟环境并安装 Python 依赖\"\n        command: \"cd {{SKILL_DIR}} && python3 -m venv .venv && .venv/bin/pip install numpy requests fastapi pydantic uvicorn PyPDF2 pdfplumber python-docx\"\n      - id: \"auto-index-cron\"\n        kind: \"shell\"\n        optional: true\n        label: \"（可选）开启自动索引——每30分钟扫描新文件\"\n        command: \"echo '提示：安装后可运行 openclaw cron add 定时运行 index_knowledge.py 实现自动索引'\"\n---\n\n# 📖 Knowledge RAG\n\n用自然语言搜索你的笔记和文档，像问 ChatGPT 一样问你的私人知识库。\n\n---\n\n## 🚀 安装启动\n\n```bash\n# 1. 安装 Ollama\ncurl -fsSL https://ollama.com/install.sh | sh\n\n# 2. 拉取推荐模型（千问3 Embedding，中文最优）\nollama pull qwen3-embedding:8b\n\n# 3. 创建虚拟环境并安装依赖\npython3 -m venv .venv\n.venv/bin/pip install numpy requests fastapi pydantic uvicorn PyPDF2 pdfplumber python-docx\n\n# 4. 启动\n.venv/bin/python3 start.py\n```\n\n打开 `http://localhost:5777` → 文件丢到 `~/workspace/knowledge/` → 管理页点「重新索引」→ 搜索页开搜。\n\n### 可选：开启自动索引\n新增文件后不用每次都手动点重新索引，设个定时任务每30分钟自动扫描：\n```bash\nopenclaw cron add \\\n  --name \"knowledge-rag 自动索引\" \\\n  --every 1800000 \\\n  --message \"运行索引检查：cd ~/.openclaw/workspace/skills/knowledge-rag && .venv/bin/python3 scripts/index_knowledge.py\" \\\n  --silent\n```\n\n---\n\n## 📂 知识库目录\n\n```\n~/workspace/knowledge/\n  ├── notes/            ← 技术笔记、读书笔记\n  ├── bilibili/         ← B站转录\n  ├── wechat-articles/  ← 公众号文章\n  ├── other/            ← 其他文档\n  └── （可建任意子目录，去设置页添加）\n```\n\n支持 `.txt` / `.md` / `.pdf`（文字版）/ `.docx` 文件。\n\n---\n\n## 🔍 搜索方式\n\n### 直接问我\n> \"帮我搜笔记里关于 Docker 的部分\"  \n> \"知识库里有没有讲 Transformer 的文章？\"\n\n我会自动调搜索，带原文回答。\n\n### 命令行\n```bash\n.venv/bin/python3 scripts/query_knowledge.py \"你的问题\"\n.venv/bin/python3 scripts/query_knowledge.py \"微服务\" --source bilibili --top 5\n.venv/bin/python3 scripts/query_knowledge.py --stats\n```\n\n新增文件后运行索引即可：\n```bash\n.venv/bin/python3 scripts/index_knowledge.py          # 增量\n.venv/bin/python3 scripts/index_knowledge.py --force  # 全量重建\n```\n\n---\n\n## 📝 Agent 存知识规范\n\n当用户说\"把这段存到知识库\"，按以下规则操作：\n\n| 内容类型 | 存放目录 | 文件名 |\n|---------|---------|--------|\n| 技术笔记、概念解释 | `notes/` | 中文描述.md |\n| B站视频转录 | `bilibili/` | 自动处理 |\n| 公众号、网页文章 | `wechat-articles/` | 文章标题.md |\n| 其他 | `other/` | 内容摘要.md |\n\n保存后运行 `.venv/bin/python3 scripts/index_knowledge.py` 更新索引。\n\n---\n\n## 🔧 切换模型\n\n在设置页修改 `embed_model` 字段：\n\n| 场景 | 模型 | 大小 |\n|------|------|------|\n| ✅ 推荐（质量最高） | `qwen3-embedding:8b` | 4.7GB | 中文优秀，检索质量最高 |\n| 轻量（CPU友好） | `qwen3-embedding:0.6b` | 640MB | 对 CPU 友好，中文不错 |\n| 多语言 | `bge-m3` | 1.2GB |\n| 最小体积 | `nomic-embed-text` | 274MB |\n\n改完后点「重新索引」，系统自动检测并全量重建。\n\n---\n\n## \ud83e"},{"path":"README.md","content":"<p align=\"center\">\n  <h1 align=\"center\">📖 Knowledge RAG</h1>\n  <p align=\"center\">把你的笔记和文档变成 AI 知识库，像聊天一样搜索</p>\n  <p align=\"center\">\n    <a href=\"https://clawhub.ai/54lynnn/knowledge-rag\"><img src=\"https://img.shields.io/badge/ClawHub-knowledge--rag-6c5ce7\" alt=\"ClawHub\"></a>\n    <a href=\"https://github.com/54Lynnn/knowledge-rag\"><img src=\"https://img.shields.io/github/stars/54Lynnn/knowledge-rag\" alt=\"GitHub Stars\"></a>\n  </p>\n</p>\n\n---\n\n## 这是什么\n\n一个**本地运行的 RAG（检索增强生成）知识库系统**。把你的 `.txt` / `.md` / `.pdf` / `.docx` 文件丢进来，用自然语言搜索，像问 ChatGPT 一样问你的私人知识库。\n\n**跟大多数 RAG 工具不同：**\n\n- **极简部署** — 不需要 Docker，不需要数据库，一台机器一个 Ollama 就够了\n- **Trae/OpenClaw Agent 集成** — 在 IDE 里直接让 AI 搜你的知识库并带原文回答\n- **B站转录自动入库** — 配合 bilibili-auto-transcript，视频转录完自动进知识库\n\n---\n\n## 快速开始\n\n```bash\n# 1. 安装 Ollama\ncurl -fsSL https://ollama.com/install.sh | sh\n\n# 2. 拉取推荐模型（千问3 Embedding 8B）\nollama pull qwen3-embedding:8b\n\n# 3. 创建虚拟环境并安装依赖\npython3 -m venv .venv\n.venv/bin/pip install numpy requests fastapi pydantic uvicorn PyPDF2 pdfplumber python-docx\n\n# 4. 启动\n.venv/bin/python3 start.py\n```\n\n打开 `http://localhost:5777` → 把文件丢到 `~/workspace/knowledge/` → 点「重新索引」→ 开搜。\n\n---\n\n## 架构\n\n```\n┌─────────────────────────────────────────────────┐\n│                 浏览器 (index.html)              │\n└──────────────────┬──────────────────────────────┘\n                   │ HTTP\n┌──────────────────▼──────────────────────────────┐\n│         TypeScript Express (server.ts)           │\n│   Web 层：静态文件、配置读写、请求路由            │\n└──────────────────┬──────────────────────────────┘\n                   │ HTTP Proxy\n┌──────────────────▼──────────────────────────────┐\n│          Python FastAPI (knowledge_api.py)       │\n│   RAG 层：搜索、索引、管理、统计 API             │\n└──────┬─────────────────────────────┬────────────┘\n       │                             │\n┌──────▼──────┐            ┌────────▼──────────┐\n│ index_      │            │ query_            │\n│ knowledge.py│            │ knowledge.py      │\n│ 索引构建    │            │ 向量搜索+混合打分  │\n└──────┬──────┘            └────────┬──────────┘\n       │                            │\n       └──────────┬─────────────────┘\n                  │ SQLite\n       ┌──────────▼──────────┐\n       │  chunks.db          │\n       │  (文本 + 向量 BLOB) │\n       └─────────────────────┘\n```\n\n## 知识库目录结构\n\n```\n~/workspace/knowledge/\n  ├── notes/            ← 技术笔记、读书笔记\n  ├── bilibili/         ← B站转录（配合 bilibili-auto-transcript）\n  ├── wechat-articles/  ← 公众号文章\n  ├── other/            ← 其他文档\n  └── （可建任意子目录，去设置页添加）\n```\n\n支持的文件格式：`.txt` / `.md` / `.pdf`（文字版）/ `.docx`\n\n---\n\n## 核心特性\n\n| 特性 | 说明 |\n|------|------|\n| **SQLite 存储** | 文本 + 向量存同一张表，原子写入，不会崩溃后数据不一致 |\n| **增量索引** | hash 比对 + mtime 快速跳过，只处理变更文件，删除的文件自动清理 |\n| **混合搜索** | 向量余弦相似度 + 查询扩展 + 标题/文本关键词加成 |\n| **标题提取** | Markdown H1、PDF/DOCX 首行自动识别为标题，提高匹配精度 |\n| **文件解析** | PDF（PyPDF2 + pdfplumber 降级）、DOCX（含表格内容） |\n| **删除单条** | API 支持按文件名删除索引，无需全量重建 |\n| **Web 界面** | 搜索 + 管理（统计、索引、配置）一体 |\n| **多模型支持** | 可切换 embedding 模型，切换后自动全量重建 |\n\n---\n\n## 切换模型\n\n在 `~/workspace/knowledge/.knowledge-config"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn742cdrc476d1kbhpsvnrnznx81x4r7\",\n  \"slug\": \"knowledge-rag\",\n  \"version\": \"1.6.1\",\n  \"publishedAt\": 1780476666513\n}"},{"path":"skill-card.md","content":"## Description:\n\nPersonal knowledge base skill for saving notes, indexing local documents, and searching them with natural-language queries.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[54lynnn](https://clawhub.ai/user/54lynnn)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers, agents, and individual users use this skill to create a local searchable knowledge base from notes and documents, then retrieve relevant source text through chat-style prompts or CLI commands.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Private document search and admin APIs may be exposed too broadly.\n\nMitigation: Run only on a trusted single-user machine and do not expose ports 5777 or 8768 to a LAN or untrusted browser context.\n\nRisk: The skill can browse or index outside the intended knowledge folder.\n\nMitigation: Avoid placing sensitive documents in reachable paths until API binding, authentication, and path limits are fixed.\n\nRisk: Installation depends on external Ollama and package installation steps.\n\nMitigation: Use verified Ollama and package sources before installing or pulling embedding models.\n\n## Reference(s):\n\n- [ClawHub Skill Page](https://clawhub.ai/54lynnn/skills/knowledge-rag)\n- [Ollama Download](https://ollama.com/download)\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 and local API or CLI outputs]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Produces local search guidance and retrieval results backed by a local SQLite index and Ollama embeddings.]\n\n## Skill Version(s):\n\n1.6.1 (source: server release metadata)\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."},{"path":"web/package-lock.json","content":"{\n  \"name\": \"knowledge-server-ts\",\n  \"version\": \"1.0.0\",\n  \"lockfileVersion\": 3,\n  \"requires\": true,\n  \"packages\": {\n    \"\": {\n      \"name\": \"knowledge-server-ts\",\n      \"version\": \"1.0.0\",\n      \"dependencies\": {\n        \"express\": \"^5.1.0\"\n      },\n      \"devDependencies\": {\n        \"@types/express\": \"^5.0.1\",\n        \"@types/node\": \"^22.14.1\",\n        \"tsx\": \"^4.19.4\",\n        \"typescript\": \"^5.8.3\"\n      }\n    },\n    \"node_modules/@esbuild/aix-ppc64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz\",\n      \"integrity\": \"sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==\",\n      \"cpu\": [\n        \"ppc64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"aix\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/android-arm\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz\",\n      \"integrity\": \"sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==\",\n      \"cpu\": [\n        \"arm\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"android\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/android-arm64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz\",\n      \"integrity\": \"sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"android\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/android-x64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz\",\n      \"integrity\": \"sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"android\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/darwin-arm64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz\",\n      \"integrity\": \"sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@esbuild/darwin-x64\": {\n      \"version\": \"0.28.0\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0."}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"个人知识库：存笔记、搜内容。用自然语言搜本地文档，不用记文件名。跟 AI 说'把这段存到知识库'自动保存并建索引。推荐搭配 Bilibili Auto Transcript：视频转录自动入库，转完即搜。 Skill: Knowledge Rag Owner: 54lynnn Summary: 个人知识库：存笔记、搜内容。用自然语言搜本地文档，不用记文件名。跟 AI 说'把这段存到知识库'自动保存并建索引。推荐搭配 Bilibili Auto Transcript：视频转录自动入库，转完即搜。 Tags: 54lynnn:1.1.0, chinese:1.5.4, knowledge:1.5.4, latest:1.6.1, rag:1.5.4, search:1.5.4 Version history: v1.6.1 | 2026-06-03T08:51:06.513Z | auto **Virtual environment support and installation process improvement** - Added virtual environment (.venv) support; all depend","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1162,"uniquenessScore":51,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-10T18:51:10.809Z","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-10T18:51:10.809Z","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-10T21:43:02.307Z","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"}]}}}