yuan-source-666/dsh-github-manager

dsh-github-manager

GitHub 仓库 AI 自动管理通道插件 (DeepSeek Harness community bundle): 27 个工具(仓库/Issue/PR/分支/文件/标签/话题/Tags/Releases/搜索)+ Web 设置卡片 + dry-run 防护 + secret 令牌。

Uncategorizedai-agentdeepseek-harnessdsh-bundle

dsh-github-manager

中文 | English

A DeepSeek Harness plugin that gives AI agents a GitHub repository auto-management channel. It registers a suite of tools so an agent can manage repositories, issues, pull requests, branches, files, labels, topics, tags, releases, and search through the GitHub REST API.

Distributed per the DSH community plugin spec: bundle (dsh.bundle.patch) + Web settings card (dsh.client). The repository is tagged with the dsh-plugin topic so the community can find it.

Tools

ToolScopeDescription
github_pingConnectivityVerify the channel and token; reports the current user and remaining quota
github_list_reposReposList repos for the authenticated user or a named owner
github_get_repoReposDetailed metadata for one repository
github_create_repoReposCreate a new repository (user or organization)
github_list_issuesIssuesList issues, filtered by state / labels / assignee
github_create_issueIssuesOpen a new issue
github_update_issueIssuesUpdate an issue (title / body / state / labels / assignees)
github_comment_issueIssuesComment on an issue or pull request
github_list_pullsPRsList pull requests
github_get_pullPRsFull metadata for one pull request
github_create_pullPRsOpen a pull request
github_merge_pullPRsMerge a pull request (merge / squash / rebase)
github_list_branchesBranchesList branches
github_read_fileFilesRead a text file from a repository
github_write_fileFilesCreate or update a file (versioned via the commits API)
github_delete_fileFilesDelete a file
github_list_labelsLabelsList repository labels
github_create_labelLabelsCreate a label
github_get_topicsTopicsGet the repository topic list
github_update_topicsTopicsReplace all repository topics in one write
github_list_tagsTagsList git tags with their commit SHAs
github_list_releasesReleasesList releases, newest first
github_get_latest_releaseReleasesGet the latest published release
github_create_releaseReleasesCreate a release (creates the tag when missing)
github_update_releaseReleasesUpdate a release (title / notes / draft / prerelease)
github_search_codeSearchCode search across GitHub
github_search_issuesSearchSearch issues and pull requests

All mutating tools describe the action instead of performing it when dryRun: true — safe for reviewing or staging agent workflows.

Installation

The plugin ships as a bundle. Install it into a DSH profile:

# from a local directory
dsh plugin --profile demo add ./dsh-github-manager

# from GitHub (pinning a commit is safer)
dsh plugin --profile demo add github:yuan-source-666/dsh-github-manager#<sha>

Installing from git pulls sources and the prepare script compiles lib/. pnpm >= 10 requires explicitly allowing builds in the profile's pnpm-workspace.yaml:

allowBuilds:
  dsh-github-manager: true

Only authorize packages whose sources you trust. See the DSH packaging & installation docs.

Verify the installation:

dsh --profile demo --dump-config   # shows the "# == dsh-github-manager" layer
dsh --profile demo

Web settings

After installing, open http://127.0.0.1:3080 -> Settings -> Plugins -> Configurable and you will find the "GitHub repository management" card:

  • Master switch: turning it off instantly unregisters all 27 GitHub tools from the model's tool surface; turning it back on restores them — no restart.
  • Access token: a write-only password field; the stored value never travels back over the wire and never appears in read results. Leave it empty to fall back to the GH_TOKEN / GITHUB_TOKEN environment variables.
  • API / web roots, request timeout, dry-run: edit and save per field; "overridden" markers show which fields live in your user layer, and "reset" makes a field inherit the bundle layer again.

Saves go through the DSH settings namespace dsh-github-manager (revision-fenced writes); the token is registered with the secret role and redacted on reads. Changes take effect immediately: the next tool call uses the new token / timeout / dry-run state.

Getting a GitHub token (quick guide)

  1. Open https://github.com/settings/tokens (for Enterprise, use your site root — the card's "open token page" link follows the web root you set in the card).
  2. Generate new token -> fine-grained recommended (permissions can be locked to specific repos), or classic.
  3. Grant what you need on the target repos: Contents (file read/write), Issues, Pull requests; creating repos additionally needs Administration; read-only search/metadata only needs Metadata.
  4. Copy the token, paste it into the card's token field and save — written once, never echoed. Remove the entry any time and the plugin falls back to GH_TOKEN / GITHUB_TOKEN.

Configuration (headless deployments)

CLI or headless setups can override defaults directly in the profile's cordis.patch.yml (no need to touch the package):

- id: dsh-github-manager
  name: dsh-github-manager
  config:
    enabled: true          # master switch: false registers no tools at all
    # do NOT put the token in a file - use the settings card or environment
    baseUrl: 'https://api.github.com'
    webUrl: 'https://github.com'
    timeoutMs: 30000
    dryRun: false
FieldDefaultDescription
enabledtrueMaster switch; off unregisters all 27 tools from the model surface
token(none)Personal access token; settings-card value wins, empty reads GH_TOKEN / GITHUB_TOKEN
baseUrlhttps://api.github.comREST API root (change for GitHub Enterprise)
webUrlhttps://github.comWeb root for human-facing links
timeoutMs30000Per-request timeout in milliseconds
dryRunfalseWhen true, mutating tools describe actions instead of executing

Required GitHub permissions

For a fine-grained token, grant as needed:

  • Repo metadata: Contents: read (all read tools)
  • Repositories: Administration: write (github_create_repo)
  • Issues: Issues: write (github_create_issue, github_update_issue, github_comment_issue)
  • PRs: Pull requests: write (github_create_pull, github_merge_pull)
  • Files: Contents: write (github_write_file, github_delete_file)
  • Labels: Issues: write, or Metadata: read + repo admin (github_create_label)
  • Topics: Topics: write (github_update_topics; reading needs only Metadata: read)
  • Releases: Contents: write (github_create_release, github_update_release; listing tags/releases needs only Metadata: read)

Development

# 1) typecheck + build (emits lib/*.js and lib/types/*.d.ts)
pnpm install
pnpm run build

# 2) runtime smoke tests (stub ctx + mocked fetch; no network, no keys; path-independent)
node tests/smoke-test.mjs
node tests/client-smoke.mjs
# or: pnpm run test

# 3) load from TypeScript source inside DeepSeek Harness (absolute-path patch, no build)
cd /path/to/deepseek-harness
pnpm dsh web --patch <this-dir>/load.dev.patch.yml

Once http://127.0.0.1:3080 is up, try telling the model: "use github_ping to check the GitHub channel" or "list open issues of deepseek-harness/deepseek-harness and comment Triage on each unassigned bug-labeled one".

Architecture

The plugin follows DSH conventions:

  • Function-form plugin; inject = ['tools'] declares the dependency on the tools registry; the settings namespace binds via installSettingsSection and pairs with the browser card half by the same namespace.
  • Settings card pair (Web): the host half registers the namespace dsh-github-manager; the browser half registers the card into the settings.plugin.item keyed slot (key = the same namespace string), and the settings UI pairs them automatically. The switch is live: flipping enabled triggers unregister/re-register without restarting the process.
  • Config defined as a Schemastery schema — every tunable is a config field with its default in the schema, never hardcoded; the token carries the secret role (redacted on read, write-only).
  • Every tool uses defineTool: parameters is derived from the DSL and validates args; execute returns the canonical value declared by output.schema; output.render turns it into model-facing text.
  • Everything registered through ctx is cleaned up automatically on unload (HMR friendly).
  • A single shared GitHub REST client under the hood: unified auth, pagination, and error normalization; settings commits update its identity in place, so token rotation takes effect on the very next request.

License

MIT