Back to home

bkMoon1024

dsh-ci-cd-bot

No description

Stars
3
Language
JavaScript
Created
Aug 15, 2026
Updated
Aug 15, 2026

Introduction

dsh-ci-cd-bot

dsh-ci-cd-bot

DSH Web UI plugin — watches GitHub issues/PRs across your account's repositories, auto-fixes issues whose repos are checked out locally, and turns PRs, feature requests, and other items into a review-and-run queue with one-click agent execution and push.

GitHub stars MIT license
TypeScript esbuild shipped plugin

English · 中文


What it does

ItemHandling
Bug issue, repo checked out locallyFully automatic: an agent fixes the issue in the local checkout and self-tests → the plugin commits and pushes (optionally opens a PR) → replies to the issue
Feature requestEnters the board queue → click Run → agent implements → push → reply to the issue
Other issue (question / maintenance)Enters the board queue → implements and pushes when a local checkout exists; otherwise the agent drafts a reply and the plugin posts it as a comment
Pull requestEnters the board queue → click Review → fetch the diff → agent reviews → submits APPROVE / REQUEST_CHANGES / COMMENT according to the verdict, auto-merges on approve (configurable)

Every run is a real agent session (kept in the session list so you can watch the full transcript). All git plumbing — branch, commit, push — is done by the plugin itself, deterministically; the push policy can be set to auto or confirm in the board.


How it works

The host half polls GitHub every N minutes (configurable): it lists the account's repositories, fetches recently updated issues/PRs per repo with a watermark (first poll backfills only the last few days), classifies them by label rules plus title/body keywords, and matches repositories to local checkouts found under the configured scan roots and DSH workspaces. New local bug issues are auto-enqueued; everything else waits in the board for a user choice.

Agent runs use the official headless pattern — ctx.agents.create({ meta: { cwd } }) + followup + whenIdle, with success/failure decided by the turn/end reason in the session log. The agent only edits code and self-tests (git is forbidden in the prompt); the plugin then runs fetch → checkout ghbot/#<n>-<slug> → add → commit → push and writes back to GitHub (comment, PR, review, merge).

The browser half injects a CI/CD sidebar entry and a center-column board (mutual-exclusion handshake with the sibling panels via dsh-panel-activate). Config lives in ~/.dsh/dsh-ci-cd-bot.json (0600) — the token never leaves the host, and the GUI settings page edits it through a loopback-fenced /api/dsh-ghbot/* route family.


Quick start

DSH plugins are installed into a profile (dsh web corresponds to the web profile). Requires Node.js ≥ 22 and dsh 0.1.0-rc.6.

The package is published on npm, so installing from npm is the recommended path; building from source is only needed for development/debugging.

Full installation guide — prerequisites, npm / source / manual install, verify, update, uninstall: INSTALL.md.

From npm (recommended)

dsh plugin --profile web add dsh-ci-cd-bot
dsh web

From source

git clone https://github.com/bkMoon1024/dsh-ci-cd-bot.git
cd dsh-ci-cd-bot
npm install --ignore-scripts   # the esbuild platform binary ships via optionalDependencies — no postinstall needed
npm run build
npm test                       # 11 headless behavior scenarios

# the package ships its own cordis.patch.yml (declared via dsh.bundle.patch),
# so the plugin row registers automatically
dsh plugin --profile web add link:$(pwd)

dsh web

Manual install (no pnpm / dsh plugin)

ln -sfn "$(pwd)" ~/.dsh/profiles/node_modules/dsh-ci-cd-bot
# then append to ~/.dsh/profiles/web/cordis.patch.yml:
#   - insert:
#       - id: ci-cd-bot
#         name: 'dsh-ci-cd-bot'
dsh web

Switching from a manual install to dsh plugin add? Remove the manually added insert entry first — the bundle patch registers the plugin row itself and duplicate rows conflict.

Verify & uninstall

dsh --profile web --dump-config | grep ci-cd-bot   # confirm the config layer mounted

After a restart a CI/CD entry appears in the sidebar. First use: open the board → 设置 → paste a GitHub token (repo scope), configure scan roots if needed → save.

dsh plugin --profile web remove dsh-ci-cd-bot   # npm / repo install
# or delete the symlink + insert entry           # manual install
dsh web

Configuration

Most parameters are editable in the board's settings page; changes apply immediately and persist to ~/.dsh/dsh-ci-cd-bot.json (announceToAgent is JSON / API only). Complete reference — required fields, defaults, examples, security notes: CONFIG.md.

FieldDefaultDescription
GitHub TokenGitHub PAT with repo scope; kept on the host, never sent to the browser
Poll interval (ms)300000How often the listener polls GitHub
Backfill window (days)3First-poll window for open items
Scan rootsExtra local roots scanned for git checkouts (DSH workspaces are added automatically)
Bug labelsbug,故障,defectLabels that classify an issue as a bug
Feature labelsenhancement,feature,需求Labels that classify an issue as a feature request
Auto-fix local bugsonBug issues whose repo is checked out locally run automatically
Push policyautoauto pushes immediately; confirm parks the run at a board confirmation gate
Open a PR after fixesonPush the ghbot/… branch and open a PR instead of merging directly
Reply to the issueonPost a summary comment after a run finishes
Auto-merge on approveonMerge a PR when the review verdict is approve
Run concurrency2Max concurrent agent runs
Run timeout (ms)1800000Hard timeout for one agent run
Enable listeneronMaster switch for polling + execution
Announce to agentonSystem-prompt section announcing the plugin to chat agents
Include / exclude reposowner/repo filters (empty = all account repos)

Tech stack & structure

LayerChoice
PlatformDSH Web GUI plugin — host half + browser half (shipped form, no dsh source changes)
LanguageTypeScript (host half runs in the ordinary Node process: node builtins, fetch, dsh SDK packages)
Buildesbuild platform binary invoked directly + tsc declarations (node build.mjs)
Runtime depsHost: @deepseek-ai/dsh-agent / dsh-llm / dsh-session (resolved by the dsh installation); browser: react (platform seed word)
Storage~/.dsh/dsh-ci-cd-bot.json (config) + ~/.dsh/dsh-ci-cd-bot-state.json (items / watermarks)
dsh-ci-cd-bot/
├── package.json            # plugin manifest (dsh.client / dsh.bundle)
├── cordis.patch.yml        # profile patch layer: registers the plugin row
├── INSTALL.md / CONFIG.md  # installation guide / configuration manual
├── build.mjs               # esbuild build (browser CJS wrap + host ESM)
├── tsconfig.json / tsconfig.build.json
├── src/
│   ├── index.ts            # host half: listener/runner/queue/routes/announcement
│   ├── gh.ts               # GitHub REST client (fetch, pagination, rate-limit backoff)
│   ├── listener.ts         # polling engine (watermarks, auto-enqueue local bugs)
│   ├── agent-run.ts        # ctx.agents.create({meta:{cwd}}) → followup → whenIdle
│   ├── runner.ts           # fix/implement/handle flows + git plumbing + push policy
│   ├── review.ts           # PR review flow (diff → agent → submit review / merge)
│   ├── routes.ts           # /api/dsh-ghbot/* (loopback-fenced)
│   └── client/
│       ├── index.ts        # browser half entry
│       ├── sidebar-entry.ts# DOM-injected sidebar entry (family-block convention)
│       ├── board-mount.tsx # center-column React root + panel mutual exclusion
│       ├── Board.tsx / settings-view.tsx / controller.ts / api.ts
│       └── locales.ts / board.css / styles.ts
├── tests/run.mjs           # 11 headless behavior scenarios
├── lib/                    # build output (committed, directly linkable)
└── docs/                   # banners + design notes

Known limitations

  • The sibling sidebar panels (task board, SSH) do not know the ghbot panel-activate event value; their controllers stay "open" internally while this board is visible (visual exclusivity holds, one extra click toggles back).
  • Classification is rule-based (labels + keywords, both configurable); an LLM fallback is a planned option.
  • A timed-out run is marked failed but the agent is not cancelled mid-flight.
  • github.com only (no GitHub Enterprise yet); the board refreshes by polling, not SSE.

Development

npm run typecheck   # tsc --noEmit
npm run build       # lib/client.js + lib/index.js + lib/types
npm test            # node tests/run.mjs — 11 behavior scenarios

Source must stay compatible with Node's strip-only TypeScript loader (used by the test runner): no parameter properties (constructor(readonly x)), no enum, no namespace.


Publishing

npm run build
npm publish          # publishes dsh-ci-cd-bot with the bundled cordis.patch.yml

A tag-triggered CI pipeline (verify version tag → build + test → publish → GitHub release with artifacts) can be added the same way as sibling DSH plugins.


Links


License

MIT

MIT © bkMoon1024