deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
PROJECT README
· GitHub
GitHub Copilot sign-in and model route for DeepSeek Harness.
Sign in to GitHub via the device-code flow, store the Copilot grant through the harness credential records, and register a github-copilot LLM route backed by pi-ai's Copilot model catalog — all on official dsh seams, with no third-party OAuth base required.
Status: 0.3.0 — built and verified against dsh 0.2.0-rc.2 / pi-ai 0.87.1 (typecheck/build/14 tests green, including a compose-level catalog-resolution regression for the
modelErrorscontract). Peer ranges>=0.1.5-rc.1 <0.3.0cover both the 0.1.x and the 0.2.x host lines;npm run verify:gaterecomputes the host compatibility gate. 中文版见 README.zh-CN.md.
The current dsh-oauth release (0.2.0) is built against the 0.1.0-rc.6/rc.8 package line and its peers
are semver-incompatible with the shipped dsh 0.1.x line — npm refuses to install both in one profile.
This plugin therefore targets the official seams directly (ctx.credentials records, ctx.authorization
flows, ctx.llm adapters), which also keeps the login working when dsh-llm-pi-ai's registered Copilot
flow is present.
Published form (no clone or build needed):
dsh plugin --profile web add dsh-oauth-copilot
Restart dsh web. The package's cordis.patch.yml (llm-github-copilot) is loaded from
dsh.bundle.patch; the authorization service entry in the profile patch activates the login
machinery (see Compatibility note).
Development form (from a checkout of this repo):
npm install && npm run build
dsh plugin --profile web add /path/to/dsh-oauth-copilot
Sign-in is a human-only terminal operation; no LLM involvement, so prompt injection in a non-official model cannot start or drop an authorization.
# The CLI ships with the npm package. Either install it globally...
npm install -g dsh-oauth-copilot
dsh-copilot-auth login # prints device-code URL + code; authorize in the browser
# ...or run it through npx without installing anything:
npx -y dsh-oauth-copilot login
dsh-copilot-auth status # grant expiry + available models
dsh-copilot-auth refresh # re-fetch the account-enabled model list into the grant
dsh-copilot-auth logout # remove the local grant
Only github.com is supported (GitHub Enterprise is not; see Known limitations). Tokens are never printed; provider errors are redacted; the credential file is written atomically with 0600 perms.
The picker lists the advisory pi-ai catalog (32 Copilot models on pi-ai 0.87.1). Not every model is enabled for your
account: an unavailable pick returns HTTP 400 "model not supported". dsh-copilot-auth refresh
stores the account-enabled list (policy=enabled) into the grant, so the picker then shows only
those; a failed/empty refresh leaves the full advisory list visible — retry refresh or pick a model
from the status output.
Model-executable tools (github_copilot_login / github_copilot_status / github_copilot_logout)
are off by default and only register when the authorization service is mounted and
enableModelTools: true is set. Tool errors are redacted before they reach the model context.
- id: llm-github-copilot
config:
enableModelTools: true # opt in; default false
loginWindowMs: 180000 # how long a login tool call waits before cancelling
streamIdleTimeoutMs: 300000
proxy.individual.githubcopilot.com), and the model login tool and the CLI reject enterprise
domains explicitly. This is a security decision: a forged enterpriseUrl would redirect pi-ai's
automatic token refresh to an attacker server.@deepseek-ai/dsh-* peers are
>=0.1.5-rc.1 <0.3.0 and the pi-ai dependency is >=0.85.1 <0.88.0. The host's compatibility
gate (semver.satisfies(runtimeVersion, range, { includePrerelease: true })) rejects a bundle
whose @deepseek-ai/dsh-* peers fall outside the running dsh version, and a rejected bundle is
skipped whole — which removes the github-copilot entry from the picker. npm run verify:gate
recomputes that check against the known host versions. The modelErrors member is additive, so
hosts that do not read it ignore it.dsh-copilot-auth login/logout while another process is actively writing the
credentials file; the CLI uses atomic 0600 writes but does not take dsh's cross-process write lock.dsh-copilot-auth: command not found — install the package with npm
(npm install -g dsh-oauth-copilot) or invoke npx -y dsh-oauth-copilot login.dsh-copilot-auth refresh, then
pick a model from the status output.dsh-copilot-auth logout removes the local grant; on
GitHub, Settings → Applications → revoke the Copilot authorization.npm install -g dsh-oauth-copilot@latest && dsh plugin --profile web add dsh-oauth-copilot (or bump the version in the profile package.json), then restart dsh web.Reviewed against the community implementations (dsh-oauth / dsh-oauth-openai) with adversarial review passes; decisions in place:
src/credential-store.ts, CLI): stored payloads are schema-checked; the
proxy-ep endpoint must be the official host ONLY, and any non-empty enterpriseUrl rejects the
record — closing both the traffic-redirection and the refresh-token exfiltration paths.read:user, one authorization attempt per key.| Piece | File | Responsibility |
|---|---|---|
| Route | src/adapter.ts |
Registers github-copilot via PiAiAdapter; request-level apiKey stays undefined so pi-ai's native OAuth auth takes over |
| Grant bridge | src/credential-store.ts |
Strictly validated mapping of the harness record llm-pi-ai/github-copilot (kind grant) to a pi-ai CredentialStore + ambient AuthContext |
| Manual CLI | scripts/dsh-copilot-auth.mjs |
Human-driven device-code login/status/refresh/logout writing the same record |
| Login tools | src/login-tool.ts |
Optional model tools driving the ctx.authorization flow (opt-in only) |
npm install
npm run typecheck
npm test # unit + composition + grant validation
npm run build
npm run verify:gate # recompute the host plugin compatibility gate for the known dsh lines
# scripts/ ship with the repo, not the npm tarball: run them from a checkout
node scripts/smoke.mjs # mounts the built plugin on real seams in a temp DSH_HOME
node scripts/smoke-noauth.mjs # verifies the tree still boots without the authorization service
node scripts/verify-live.mjs # real-grant end-to-end probe (uses the real grant; sends one tiny request)
node scripts/verify-vision.mjs # opencode-go vision route probe (REASONING_EFFORT=low|high|max|off)
The model route always activates; login tools need the authorization service mounted and the
opt-in flag. The shipped dsh-base profile does not mount that service by default — the profile
patch adds it. A missing service must never take the whole plugin tree down.
MIT
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。