
Security News
Happy Birthday, Shai-Hulud
It has been one year since Shai-Hulud made its first appearance on npm.
dsh-github-router
Advanced tools
DeepSeek Harness plugin: read-only GitHub access for agents (github_probe / github_pr / github_issue / github_file / github_api). Routes every request inside the tool — api.github.com (direct or proxy), gh CLI, git protocol (plugin-owned fetch cache plus
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.
A DeepSeek Harness plugin bundle that gives agents GitHub reads without shell retries:
github_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.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.github_probe reports which routes are live from the host in one call, with timings and a recommended route chain.dsh-github-router settings namespace (secret token, proxy, route switches, cache TTLs, byte caps) with staged edits, save/discard, and override badges.@deepseek-ai/dsh-base (it provides the tools, subprocess, skills, settings, and credentials services the plugin uses)gh CLI (authenticated) for the gh route; git for the git routeFrom 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.
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:
GITHUB_TOKEN) for 5000/hour. Responses are cached to save quota; forceRefresh bypasses the cache.git log/diff/show only, and fetches happen exclusively in the plugin-owned cache under <DSH_HOME>/storages/dsh-github-router/.Settings → GitHub Router opens an independent settings page (a nav
entry registered into settings.section, the same mechanism as the 通知
section): 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 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. |
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.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.gh/git invocation is an argv array with fixed flag lists; user input reaches argv only after regex validation, and nothing is shell-interpolated.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.| Path | Purpose |
|---|---|
cordis.patch.yml | Profile patch layer inserting the dsh-github-router row |
lib/index.js | Host plugin: settings section, five tools, skill, guidance |
lib/client.js | Browser half: the independent Settings page (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 |
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.
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.
MIT
FAQs
DeepSeek Harness plugin: read-only GitHub access for agents (github_probe / github_pr / github_issue / github_file / github_api). Routes every request inside the tool — api.github.com (direct or proxy), gh CLI, git protocol (plugin-owned fetch cache plus
The npm package dsh-github-router receives a total of 104 weekly downloads. As such, dsh-github-router popularity was classified as not popular.
We found that dsh-github-router demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
It has been one year since Shai-Hulud made its first appearance on npm.

Research
/Security News
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.

Security News
GitHub Actions now supports cache-mode, a least-privilege control on the Actions cache aimed at the cache poisoning technique behind recent compromises.