AngelosZou/dsh-github-router

插件Plugin 原生Native ⭐ 2 MIT cat_label.dsh-pluginscat_label.dsh-plugins

项目介绍Project Overview

dsh-github-router 是 DSH 插件,提供五个只读 GitHub 工具,经 API、gh、git、页面 HTML、镜像等内部路由读取 PR、issue、文件与接口数据。适合沙箱内 TLS/代理受限或需稳定拉取 GitHub 内容时使用。注意:仅支持 GET/读取,不能写入或评论,需 Node ≥20.18 并重启后端。

dsh-github-router is a DSH plugin providing five read-only GitHub tools. It fetches PRs, issues, files, and API data through internal routes: GitHub API, gh CLI, git protocol, page HTML, and mirrors. Use it when sandbox TLS or proxy issues block GitHub reads, or when agents need structured repository data without shell retries. It is read-only by design, so it cannot write, comment, or push; Node.js ≥20.18 and a backend restart are required.

或使用命令行安装(适合开发者)Or use CLI install (for developers)

命令行安装CLI Install

dsh plugin --profile web add dsh-github-router

AngelosZou/dsh-github-router 加入你的 DSH 配置(web profile)即可启用。

READMEREADME

dsh-github-router

English | 中文

Read-only GitHub access for a DeepSeek Harness project — load PRs, issues, files, and API data through tools that route internally (API, gh CLI, git protocol, page HTML, mirrors), so an agent never burns turns fighting shell-side TLS or proxy failures.

License: MIT Node.js >= 20.18 npm version

A DeepSeek Harness plugin bundle that gives agents GitHub reads without shell retries:

  • Five read-only toolsgithub_probe, github_pr, github_issue, github_file, github_api — plus the github-router skill and a system-prompt guidance section. No write, push, comment, or mutation capability exists anywhere in the package.
  • In-tool routing — every request runs host-side (outside the sandbox's TLS/proxy restrictions) and falls through a route ladder: api.github.com (direct → proxy) → gh CLI (read-only subcommands) → git protocol (plugin fetch cache, or a local clone read with log/diff/show only) → PR/issue page HTML (strict JSON island extraction) → user-configured raw mirrors.
  • One call, structured outcome — PRs come back with metadata, discussion, reviews, commits, changed files, and the diff, each part annotated with the route that served it; failures return a route matrix instead of a dozen retried shell commands.
  • Connectivity probegithub_probe reports which routes are live from the host in one call, with timings and a recommended route chain.
  • Zero runtime dependencies — peers resolve from the DSH profile; proxied requests travel through the plugin's own CONNECT tunnel (no third-party HTTP stack), so the package installs fully offline.
  • Settings page — an independent Settings entry ("GitHub Router", like the 通知 section): the dsh-github-router settings namespace (secret token, proxy, route switches, cache TTLs, byte caps) with staged edits, save/discard, and override badges.
  • Context efficiency — response caching with per-kind TTLs, byte caps everywhere, list caps with truncation notes, and rate-limit surfacing.

Requirements

  • Node.js >= 20.18
  • A DSH profile composed from @deepseek-ai/dsh-base (it provides the tools, subprocess, skills, settings, and credentials services the plugin uses)
  • Optional: the gh CLI (authenticated) for the gh route; git for the git route

Install

From npm:

dsh plugin --profile web add dsh-github-router

From a local checkout (development):

dsh plugin --profile web add link:<absolute-path-to-this-repo>

From a git host:

dsh plugin --profile web add github:<owner>/dsh-github-router

Then restart the DSH backend — the host composition loads at process start. The tools appear in new sessions: github_probe, github_pr, github_issue, github_file, github_api, plus the github-router skill.

Usage

Agent side:

Tool What it does
github_probe One-shot connectivity matrix (api direct/proxy, gh installed/authed, git ls-remote, page direct/proxy, mirrors, token presence) with timings and a recommended route chain. Call first when access fails or is slow.
github_pr Full PR view: metadata, description, discussion (issue + inline review comments), reviews, commits, changed files, and the unified diff, each with route attribution. Parts toggle (includeDiscussion/includeReviews/includeCommits/includeFiles/includeDiff) and cap (maxDiffBytes/maxItems). localRepo (or session-cwd auto-detection) reads commits/diff from a local clone with zero network.
github_issue Issue metadata, body, labels, and comments, with route attribution.
github_file File content (or directory listing) at a branch/tag/sha via api contents → raw → mirrors → git; returns size, truncation state, and the serving route.
github_api Validated GET-only escape hatch for any api.github.com endpoint; query values sanitized, responses cached, rate-limit headers surfaced, errors carry stable codes.
github_probe                                                  # which routes are live right now
github_pr { owner: "o", repo: "r", number: 12 }               # full PR view
github_pr { owner: "o", repo: "r", number: 12, localRepo: "C:/src/r" }  # commits/diff from a local clone
github_issue { owner: "o", repo: "r", number: 34 }
github_file { owner: "o", repo: "r", path: "src/index.js", ref: "main" }
github_api { path: "/repos/o/r/commits", query: { per_page: 5 } }

Behavior notes:

  • Route order is fixed per part type: API first (direct then proxy), then gh, then page HTML (proxy-first — machines with reset direct TLS usually reach pages through the proxy), then git, then mirrors. Each part records the route that served it.
  • Anonymous API use is rate-limited (60 requests/hour per IP); configure a token (Settings or GITHUB_TOKEN) for 5000/hour. Responses are cached to save quota; forceRefresh bypasses the cache.
  • Mirrors are off by default — they are third parties that see requested paths; enable them in settings only if you accept that.
  • The git route never writes to user repositories: local clones are read with git log/diff/show only, and fetches happen exclusively in the plugin-owned cache under <DSH_HOME>/storages/dsh-github-router/.

Configuration

Settings → Plugins shows the GitHub Router card on the configurable tab (the framework's settings.plugin.item card slot keyed by the settings namespace; requires DSH ≥ 0.1.0-rc.7): edits are staged locally and written only on save, fields overridden by the user are badged, and blank fields fall back to the defaults below. The token is a write-only field — a blank save clears a configured token. The same values can be set in the composition (profile cordis.patch.yml) as the plugin's base config; the Settings UI overrides per user.

Field Default Meaning
token Literal GitHub token (secret; redacted on the wire, write-only input). Prefer tokenEnv.
tokenEnv GITHUB_TOKEN Environment variable / credential ref naming the token.
proxy '' Proxy URL for proxy attempts. '' inherits ambient HTTP(S)_PROXY; direct never proxies.
directTimeoutMs / proxyTimeoutMs 8000 / 15000 Per-attempt timeouts.
retries 1 Retries for idempotent GETs on 429/5xx (honors Retry-After).
routesApi / routesGh / routesGit / routesHtml / routesMirror on / on / on / on / off Route switches (the card shows them as checkboxes).
mirrors [] Raw-content mirror bases, e.g. ["https://ghproxy.net"].
cacheTtlMeta / cacheTtlContent 300 / 86400 Response cache TTLs (PR/issue metadata vs immutable-ish content), in seconds.
maxBytes 1048576 Byte cap for every response body read by the plugin.
repos [] Local repositories granted for read-only git-route reads.
gitCacheDir '' Plugin fetch-cache dir; '' = <DSH_HOME>/storages/dsh-github-router/git.

How it works

  • Host-side execution — plugin code runs in the host process, so the sandbox's TLS credential resets and proxy misrouting never apply. The unrestricted token is compensated by the confinement model in SECURITY.md — not by weakening the sandbox.
  • Explicit proxy decisions — global fetch does not inherit ambient proxy env; each attempt gets an explicit direct/proxy choice, and proxied requests use a zero-dependency CONNECT tunnel (node:http/node:tls) with target-hostname TLS validation and accept-encoding: identity.
  • Strict parsing — the page-HTML route extracts only react-app.embeddedData JSON islands and runs JSON.parse (never evaluated); a bounded BFS copies a whitelist of fields, so CSRF tokens and the raw payload never reach the model.
  • Argv-only subprocesses — every gh/git invocation is an argv array with fixed flag lists; user input reaches argv only after regex validation, and nothing is shell-interpolated.
  • Tool contract — canonical values are lossless JSON (arrays carry no side properties), byte-capped, and rendered as compact text with route attribution.
  • Skill & guidance — the github-router skill teaches tool-first usage and the "never escalate for GitHub reads" rule; one system-prompt section (dsh-github-router:guidance, order 118) reminds every session that the github_* tools are the sanctioned path.

Project layout

Path Purpose
cordis.patch.yml Profile patch layer inserting the dsh-github-router row
lib/index.js Host plugin: settings namespace, five tools, skill, guidance
lib/client.js Browser half: the settings card (hand-written factory bundle, no build step)
lib/config.js Settings schema, defaults, runtime option resolution
lib/net.js, lib/tunnel.js Route-aware HTTP layer; zero-dependency CONNECT proxy tunnel
lib/routes/ One module per route: api (GET-only REST), gh (CLI), git (protocol), html (page parse), mirror (raw mirrors)
lib/core/ Per-call runtime assembly and the pr/issue/file/probe aggregators
lib/tools/ The five model tools
lib/cache.js, lib/render.js, lib/util.js TTL cache, text renderers, guards and shaping
lib/skill.js, lib/guidance.js Skill content and prompt-injection section
test/ Runtime-free behavior tests (see Development)
docs/ Design and analysis documents

Development

No build step: the plugin is plain ESM and the tests run with Node directly (a mock ctx stands in for the DSH services; the real defineTool validates every schema):

npm test
# or: node --test --test-isolation=none "test/*.test.js"

The tests are fully offline — they cover JSON-island extraction, input guards, URL builders, the TTL cache, commit-log parsing, the tunnel request head, and the apply() wiring. See CONTRIBUTING.md for the development loop, including offline peer resolution.

Security

Read-only by construction: no write verb exists, tokens attach only to api.github.com and are redacted on every boundary, page payloads are whitelist-extracted, and the only disk writes are the two plugin-owned caches under <DSH_HOME>/storages/dsh-github-router/. See SECURITY.md for the complete threat model and mitigation list.

Documentation

License

MIT

上一个 Prev dsh-mission 下一个 Next dsh-github