dsh-gitea-search:在 DSH 里跨仓库检索自建 Gitea/Forgejo 代码

前言

在 DeepSeek Harness(DSH)里让模型查代码,常见做法是连 GitHub、读单个仓库,或依赖托管方自带的搜索 API。自建 Gitea 或 Forgejo 时,服务端代码索引往往默认关闭,Web 界面和 API 都无法按文件内容搜索。若代码都在私有实例上,智能体很难像对待公开 Git 托管那样「先搜再读」。

下面介绍社区插件 dsh-gitea-search(维护者 offzen,分类:客户端)。它把 token 能读到的仓库同步到本机 bare mirror,在镜像上用 git grep 跨仓库、跨分支检索,并通过 MCP 把结果交给 DSH;搜索与读文件不访问网络。插件在 SkillHub 目录 登记,源码与文档在 GitHub。

这是什么

dsh-gitea-search 面向「本地有一份 Gitea/Forgejo 镜像」的场景:唯一需要联网的步骤是 sync(拉取/更新镜像);之后模型侧调用的是三个 MCP 工具(在 DSH 中表现为 mcp__gitea_search__*):

  • search_gitea — 在全部已镜像仓库与分支中搜文件内容、路径或提交说明
  • read_gitea_file — 从镜像读取单个文件,无需再 clone
  • list_gitea_repos — 列出镜像中的仓库,可按条件过滤

匹配方式本质是 grep(默认字面、可大小写不敏感,也可按需正则),不是语义或向量检索。npm 包当前版本为 0.1.1,许可证 MIT。

环境与依赖

安装与运行前需满足 README 中的要求:

  • DeepSeek Harness 0.2.x(维护者在多种 0.2.x 预发布版本上做过兼容性验证,见仓库 README 表格)
  • Node ^22.19.0 || >=24.0.0,以及系统里的 git
  • 可访问的自建 Gitea / Forgejo 实例
  • 用于同步的只读 API Token(Gitea scope:read:repository、read:user);私有实例同步时必需
  • 磁盘空间与你要镜像的仓库体量相当

插件随 DSH profile 启动 MCP 服务时,以当前 dsh 进程 的权限与环境运行;安装前建议阅读源码与许可证,并按自己的安全策略保管 Token。

安装与启用

官方安装命令如下(--profile 必填):

dsh plugin --profile <profile> add dsh-gitea-search

包声明了 dsh.bundle.patch,因此 dsh plugin add 会安装依赖、把 bundle 写入 profile,并插入 MCP 客户端行,一般无需手写 YAML。若 profile 不支持配置热重载,安装后需重启 dsh,工具才会以 mcp__gitea_search__search_gitea、mcp__gitea_search__read_gitea_file、mcp__gitea_search__list_gitea_repos 等形式出现。

Bundle 通过 npx -y dsh-gitea-search mcp 启动 MCP(npm 预构建分发,通常不需要额外 build 权限)。

配置

MCP 客户端在拉起子进程前会清空继承的环境变量,bundle 通过 patch 显式把下列变量从 dsh 进程环境 传入(例如在 systemd 的 Environment= 或启动 dsh 的 shell 里 export):

变量 默认值 含义
GITEA_MIRROR_DIR ~/.local/share/gitea-search/mirror bare 镜像目录
GITEA_BASE_URL — Gitea/Forgejo 根 URL,sync 必需
GITEA_TOKEN — 只读 Token,私有实例 sync 必需
GITEA_OWNER 全部可读仓库 逗号分隔的 user/org,限制镜像范围
GITEA_MAX_RESULTS 200 search_gitea 返回条数上限(最大 1000)
GITEA_MAX_SEARCH_BYTES 131072 单次搜索总输出预算
GITEA_MAX_LINE_BYTES 2000 单行上限,超出会截断并标记
GITEA_MAX_READ_BYTES 60000 单文件读取上限
GITEA_JOBS / GITEA_SYNC_JOBS 6 搜索 / 同步时的并行仓库数
GITEA_TIMEOUT_MS 120000 单次 git 调用超时

若日后要改配置,可为 dsh 进程 export 变量,或在自有 profile 的 cordis.patch.yml 里按 id(gitea-search)覆盖 MCP 行;注意覆盖会替换整个 config 对象,需把仍要保留的键一并写上。

建立并更新本地镜像

镜像不会由插件自动刷新,需要你先 sync,再用 cron 或 systemd timer 保持更新(示例见仓库 docs/MANUAL.md)。

export GITEA_BASE_URL=https://gitea.example.com
export GITEA_TOKEN=...            # 只读 token
npx -y dsh-gitea-search sync      # 首次同步,之后定期执行

sync 通过 Gitea HTTP API 枚举 token 可读仓库,对每个仓库执行 git clone --mirror,再用 git remote update --prune 更新。目录结构为 <mirror>/<owner>/<repo>.git;若只镜像单个 owner,也可能是扁平的 <mirror>/<repo>.git。

典型用法

在 DSH 里

完成安装、配置环境变量并完成至少一次 sync 后,在对话中由模型调用上述 MCP 工具即可;bundle 已将 toolCallTimeoutMs 设为 120000,以减轻大镜像上首次冷搜索超过默认 60s 的问题。可先缩小 repo 范围,或用 mode: "path" / files_only 探路。

命令行(同一套引擎)

不经过 DSH 也可直接用 CLI 调试镜像与检索:

dsh-gitea-search search <pattern> [-p|-m|-E|-s|-w|-l|-c] [-r repo] [-b branch] [-A] [-n N] [--json]
dsh-gitea-search repos
dsh-gitea-search read <repo> <path> [--ref]
dsh-gitea-search sync [--transport https|ssh]
dsh-gitea-search mirror

完整选项见 dsh-gitea-search --help。

适用场景与边界

适合:代码托管在自建 Gitea/Forgejo、需要 DSH 智能体跨多仓库 grep、且能接受「先同步镜像、再本地搜」 的团队。与依赖托管方全文索引或语义搜索的方案相比,这里明确是本地 mirror + git grep,延迟与新鲜度取决于你的 sync 节奏。

务必知晓的边界(来自官方 README):

  1. 可搜范围仅限已推送到服务器的内容,未推送的本地修改不在镜像里。
  2. 插件不会在搜索时触发 sync;结果是否过时,取决于你上次同步时间。
  3. 为保护模型上下文,单次搜索、单行、单文件读取都有上限;极大单行或压缩产物会被截断或限流。
  4. 仅 sync 走网络;Token 经 API Authorization 与 GIT_ASKPASS 使用,不会出现在命令行;搜索与读文件只读本地镜像。

卸载:

dsh plugin --profile <profile> remove dsh-gitea-search

之后可删除镜像目录并吊销 Token。

故障排查(摘要)

  • 工具不出现:查 dsh 日志中的 gitea-search;常见原因包括 npx 无法访问 registry,或 Windows 上需将命令写成 npx.cmd。
  • 提示镜像下没有仓库:未 sync 或 GITEA_MIRROR_DIR 指向错误;可先 sync,再执行 dsh-gitea-search mirror 核对。
  • 首次搜索很慢:缩小仓库范围或改用路径模式;必要时再调并行与超时相关环境变量。

结尾

dsh-gitea-search 把自建 Gitea/Forgejo 的「无法全文搜」补成「本地镜像 + 跨库 grep + MCP」,让 DSH 在私有代码托管上也能走「列举 → 搜索 → 读文件」的固定路径。社区目录页:https://www.skillhub.cn/plugins/offzen/dsh-gitea-search;源码与完整说明:https://github.com/offzen/dsh-gitea-search。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜