dsh-feishu-only
中文 | English
A DeepSeek Harness bundle that brings a Feishu / Lark bot to a running DSH profile. It reproduces the im2agent Feishu interaction model: slash commands, interactive cards, per-user current task, live progress, private approvals and questions, staged images, and file previews. The reference specification is kept locally and is not redistributed in this repository.
Feishu is only the front end. Every prompt is executed by DSH on the host machine through the public ctx.agents / session/event / approval/request / user-questions/request extension points; the plugin never reimplements an agent loop.
DSH is a developer preview with breaking changes. This bundle pins
engines.dsh: ">=0.2.0-rc.2 <0.3.0"and uses only documented seams.
Install
From a plugin index (Discover tab)
In DSH, open Plugins → Experimental plugins → Custom plugin indexes and turn it on.
Open Discover → Add index source and enter:
https://raw.githubusercontent.com/qdog2012/dsh-feishu-only/main/site/index.jsonA GitHub Pages mirror is available once Pages is enabled for this repo:
https://qdog2012.github.io/dsh-feishu-only/index.json.Select Feishu bridge and confirm the version. The confirmation shows the exact Git URL and commit DSH will install.
The index is a self-contained format 1 JSON file with an inline SVG icon. DSH does not ship any built-in index source; every index is third-party content, so check the source in the confirmation dialog.
Common mistake: do not paste the repository URL into "Add index source". Entering
https://github.com/qdog2012/dsh-feishu-only.gitproducesCould not fetch https://github.com/qdog2012/dsh-feishu-only.git: fetch failed: unexpected redirect. GitHub answers 301 for the.gitweb URL, while DSH requires an index URL to return JSON with 2xx and no redirects (it fetches withredirect: 'error'). Remove that entry under Manage index sources… and use thesite/index.jsonURL above. To skip the marketplace entirely, usedsh plugin add github:...below instead of adding it as an index source.
Directly from Git
dsh plugin --profile demo add github:qdog2012/dsh-feishu-only
# or pin a commit (recommended)
dsh plugin --profile demo add github:qdog2012/dsh-feishu-only#<sha>
The package ships plain ESM JavaScript with no build step, so a Git install needs no prepare script and no allowBuilds allowance.
Configure
export FEISHU_APP_ID=cli_xxx
export FEISHU_APP_SECRET=xxx
The Feishu app needs bot capability, im:message:send_as_bot, im:message.p2p_msg:readonly, im:message.group_at_msg:readonly, im:resource, and the im.message.receive_v1 + card.action.trigger subscriptions.
Override defaults in the profile's cordis.patch.yml (a patch replaces the whole config of the row):
- id: feishu-bridge
name: dsh-feishu-only
config:
transport: webhook # websocket | webhook
webhookPort: 3900
webhookPath: /feishu/events
defaultCwd: /absolute/path/to/workspace
requireMentionInGroup: true
projects:
- name: demo
path: /absolute/path/to/demo
All options are declared with a Schemastery schema in src/config.js. websocket is convenient but some tenants do not push card callbacks over a long connection; use webhook for reliable buttons.
See docs/DETAIL.md for the full setup and interaction guide.
Commands
| Group | Commands |
|---|---|
| Tasks | /task, /task page N, /task N, /task create 标题, /task current, /task search 关键词, /task search page N |
| Projects | /project, /project page N, /project N, /project create 名称 路径 |
| History | /history, /history page N, /last |
| Settings | /model, /reasoning, /permission, /mode, /plugin, /goal, /goal set …, /goal clear |
| Runtime | /compact, /stop, /status, /update, /restart |
| Help | /help |
/model, /reasoning, /permission and /goal are mapped to native DSH seams (agent.model.select(), ctx.approval.setPolicy(), ctx.goals.create()/clear()) rather than simulated with prompts. /mode is display-only because plan mode is host-owned. /restart is explicitly refused: a plugin must not restart its host. /update only checks this plugin's release; it never replaces the DSH runtime.
What maps to what
| im2agent concept | DSH implementation here |
|---|---|
| Task | A persisted DSH Session (ctx.sessionPersistence.list() / ctx.agents.resume()) |
| Current task per Feishu user | $DSH_HOME/feishu-only/state.json |
| Submit a request | agent.followup(); agent.steer() for supplementary input while running |
/stop |
agent.cancel({ kind: 'user' }) plus cancellation of capacity retries |
| Progress card | session/event + agent/assistant-stream → one card updated in place |
| Final reply | Independent card + generated images + preview buttons |
| Approval card | approval/request waterfall → private card → ApprovalOutcome |
| Question card | user-questions/request waterfall → private card → AskUserQuestionAnswer |
| Capacity retry | agent/request-error-style detection on events → fixed 10 s re-submit, no cap |
/last, /history |
Replay of durable session events (user/message, assistant/message, turn/end) |
| Compaction | ctx.compaction.compactNow() when the host provides the seam |
Deliberate gaps
Some im2agent features belong to the Codex desktop app and have no DSH equivalent. They are not faked:
- SSH remote tasks,
/new,/pause,/goal pause, history branching, and Codex permission presets. - Online self-upgrade of the background service and desktop-app restart.
- Bundled portable Office converter. PDF/Office/URL previews use an optional host
preview.command; without it the bot returns a path explanation. - Automatic upload of non-image result files as Feishu attachments (preview is a screenshot/formatted card, not a download).
Unknown slash commands are never forwarded to the model. Group messages require @bot by default. Every card validates its operator.
Publishing and verification (maintainers)
The index source is served over static HTTPS and has been verified to return 200 with no redirects:
curl -I https://raw.githubusercontent.com/qdog2012/dsh-feishu-only/main/site/index.json
npm run validate:index # validate the local site/index.json
node scripts/validate-index.mjs <path> # or validate a downloaded index snapshot
Release flow: change code → commit → npm run build:index to regenerate site/index.json (source.commit is pinned to the commit that contains the plugin package) → npm run validate:index → push main. DSH has no central upload API; each user adds the index source under Discover → Add index source. site/index.json currently pins cda0408a5257a8ce56ab1df56dc97c73aff4c6a1, tagged v0.1.0.
All repository-side enhancements are in place and verified:
| Item | Status |
|---|---|
dsh-plugin repository topic |
Added, so the repo shows up in topic search |
| Pages mirror | Switched to GitHub Actions; .github/workflows/pages.yml deploys site/ as the site root. https://qdog2012.github.io/dsh-feishu-only/index.json returns 200 and is byte-identical to the raw index |
v0.1.0 Release |
Created from the existing tag; /releases/latest returns v0.1.0 and /update sees 0.1.0 |
For a future release: update version and source.commit in site/index.json and push (pages.yml redeploys the mirror automatically), then create a Release for the new tag.
Development
npm install
npm test # node:test, no network and no Feishu credentials required
npm run check # bundle manifest + exports + package files
npm run validate:index
Layout:
| Path | Role |
|---|---|
cordis.patch.yml |
Bundle layer inserted into the profile |
src/index.js |
Cordis plugin (name / inject / Config / apply) |
src/app.js |
Orchestrator: inbound messages and card actions |
src/commands.js |
Slash command router |
src/tasks.js |
Session/task bridge |
src/events.js |
Progress card, final reply, capacity retries |
src/interactions.js |
Approval and question waterfalls |
src/cards.js |
Feishu card 2.0 builders |
src/preview.js |
File citation parsing and preview delivery |
src/attachments.js |
Image staging and attachment download |
src/feishu.js |
Official SDK Channel wrapper |
src/state.js |
Durable per-user state |
site/index.json |
Plugin market index |
The package has no @deepseek-ai/* runtime peer dependency and no build step; it creates DSH user messages with the plain runtime shape, which keeps Git installs portable across 0.2.x releases.
License
MIT
No comments yet. Be the first to write one.