Feishu/Lark bridge for DeepSeek Harness: scan-to-connect PersonalAgent binding, streaming cards, git-worktree project workspaces, parallel per-scope tasks, multi-role agents, cross-session notify, in-chat model/key management, and a safety-net guardian that still answers in Feishu after dsh crashes.
Install
# from npm (prebuilt)
dsh plugin --profile web add dsh-lark-bot
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:PlutoKeating/dsh-lark-bot
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time. Only install sources you trust, and pin a commit (github:owner/repo#sha).
README
Turn DeepSeek Harness (dsh) into a member of your Feishu / Lark workspace — drive your local coding agent from mobile, group chats and topics, and fold conversations, tasks, cards and project workspaces into one collaborative flow.
⚠️ Official channels only: The only official repository is PlutoKeating/dsh-lark-bot; the only official npm packages are
dsh-lark-bot(with the twin packagedsh-feishu-bot, maintainerplutokeating). This project never ships Windows executables (.exe) or any "download-and-run" installer. Any page, repository, or third-party channel offering executables under this project's name is a counterfeit / malicious source — do not download or run anything from it. The only official install command:npx dsh-lark-bot@latest setup --profile dsh-lark. Evidence and the full statement live in the "Impostor Repository Warning" section below and docs/security/2026-08-17-impostor-repo-evidence/.
The Problem
Tired of being chained to your desk to drive DeepSeek Harness? dsh runs on your local machine, so checking progress and adjusting tasks means going back to your computer; once you leave your desk, a run can stall, drift, or dsh itself can crash without you ever hearing about it — until you come back and find you wasted hours.
dsh-lark-bot puts the remote control in your Feishu: drive your local dsh coding agent from DMs, group chats and topics, with streaming cards showing reasoning and tool calls in real time; get proactive notifications pushed to any chat you're in with @mentions when tasks finish; and even when dsh crashes, Feishu still answers — send /safemode to enter core-only safe mode and locate the problem and restart the engine right from the chat. It is the only bridge where you never lose contact when dsh goes down.
Who it is for: developers and teams who drive a local dsh coding agent from Feishu / Lark (DMs, groups, topics) — especially those needing multi-project isolation, role-based collaboration, parallel tasks and session archival.
What you get
Core:
- Drive your local dsh coding agent from private chats, group chats and threads; images / text files can be sent straight to the bot;
- Streaming cards showing reasoning, tool calls and results in real time, with interactive buttons (stop / approval / question cards);
- Automatic session archival and retention policies; per-session isolated git worktrees inside Git repositories, so multiple projects never interfere with each other.
Six exclusive capabilities:
- 🆘 Guardian safety net — "always reachable": Feishu still replies after dsh crashes;
/safemodeenters core-only safe mode to locate the problem and restart directly. - 👥 Multi-role agents — "one bot, a whole team": switch or assign PM / dev / docs roles with
/role; each role has its own persona, model preference and rules. - ⚡ Parallel tasks — "no queueing": run multiple tasks in the same chat simultaneously with isolated sessions; other solutions serialize everything.
- 🗂 Session archival & cleanup — "your session list never rots": archive old tasks with
/archiveand configure auto-retention with/retention. - 📣 Cross-session proactive notifications + @mentions — "it comes to you when done": after a task in chat A finishes, push a report to chat B / DMs and @mention you.
- 🔑 In-chat model & key management — "never leave Feishu":
/providers/provider/keyto view, switch vendors and hot-update keys.
Quick Start
Prerequisites (install the engine first, then the remote):
- DeepSeek Harness (
dsh) installed withDEEPSEEK_API_KEYconfigured — dsh-lark-bot is a dsh plugin; dsh is the local agent engine and cannot be skipped; - Node.js ≥ 22.19 (see
enginesinpackage.json) and a Feishu / Lark account.
Three steps:
# ① One-command install (no prior global install; installs into a dsh profile and installs the safety-net guardian by default)
npx dsh-lark-bot@latest setup --profile dsh-lark
# ② Start
dsh --profile dsh-lark
③ On first boot the terminal prints a QR code → scan it with the Feishu / Lark app to create or choose a PersonalAgent app → after binding, DM the bot directly or use @bot in groups/topics.
setup automatically: locates your local dsh → pre-approves pnpm's build policy (protobufjs) → runs the standard dsh plugin --profile dsh-lark add dsh-lark-bot@<version> (pinned to the running package) → installs the safety-net guardian system service. One command installs everything.
No public IP / domain / server / tunneling required (Feishu outbound WebSocket long connection); works on Linux / macOS / Windows. With an existing PersonalAgent app you can skip the QR step (see Configuration):
DSH_LARK_APP_ID=cli_xxx DSH_LARK_APP_SECRET=<secret> DSH_LARK_TENANT=feishu dsh --profile dsh-larkUpgrading is also one command:npx dsh-lark-bot@latest upgrade --profile dsh-lark --yes
Full usage
Common commands
Send a normal message to the bot in Feishu to get started. Common commands:
| Command | Description |
|---|---|
/new /reset |
Start a new session |
/newg <group name> |
Auto-create a group chat (with you invited) and start a fresh session there; the current session is untouched |
/cd <path> |
Change working directory and reset the session |
/ws list |
List named workspaces |
/ws save <name> |
Save the current workspace |
/ws use <name> |
Switch to a named workspace |
/ws remove <name> |
Remove a named workspace |
/status |
Show current status |
/resume |
Show the session's recent context |
/stop |
Stop the current task |
/timeout [N|off|default] |
View or set the current session run timeout |
/concurrency [N|default] |
View or set the concurrent-run limit for this scope (default 2) |
/role list、/role show <id> |
List roles / show a role |
/role set <id>、/role clear |
Bind / unbind a role for this scope |
/role save <id> <name> [--persona text] [--model <id>] [--tools <csv>] [--rules text] |
Create / update a role (admin) |
/role remove <id> |
Remove a role (admin) |
/notify <scope|chatId> <text> |
Push a cross-session notification (admin) |
/notify list |
List scopes known to the bridge |
/retention [N|default] |
View or set the live message retention window (overflow is archived) |
/archive [note]、/archive list [N]、/archive clean |
Archive / list / clean session transcripts |
/density [compact|standard|detailed] |
View or set card density |
/model、/providers、/provider、/key |
Open the interactive management hub (BotFather-style multi-turn wizard: tap-button selections, card text inputs, confirm-before-write) |
/model use <id> |
Hot-switch the current session model (effective next message, no restart) |
/model default <id> |
Write the dsh default model agent-default-model (admin) |
/model add|remove <provider> <modelId> |
Add / remove a provider model (admin) |
/provider add|update|remove <id> |
Manage providers (admin; deepseek-official and custom pi-ai) |
/key set|remove|list <ref> |
Manage dsh credentials (set / remove require admin) |
/ask <question> |
Send a Q&A card; the answer is written back to session context |
/invite user|admin|group <id>、/invite list、/invite remove user|group <id> |
Manage the access allowlist (mutating commands require admin) |
/help |
Show help |
Images in Feishu messages are downloaded to the local media directory and passed to dsh; text files are read and their content is injected into the task context.
/newg <group name>: auto-creates a private group, invites the sender and replies with a group link — chatting in the new group starts a fresh scope/session while the current session is untouched. Requires the im:chat and im:chat.members:write_only scopes.
Each scope (DM / group / topic) runs up to 2 tasks in parallel by default (adjust with DSH_LARK_SCOPE_CONCURRENCY or /concurrency): successive messages become independent runs, each with its own dsh session and run id. /status lists every active run and /stop interrupts them all.
Multi-role agents: admins define roles (PM / dev / docs / …) with /role save <id> <name> --persona <text> [--model <id>] [--tools <csv>] [--rules <text>] and bind one to the current scope with /role set <id>; every run carries the role instructions, and the role model wins below the per-session /model use override. Role definitions persist in ~/.dsh-lark/profiles/<profile>/roles.json.
Outbound mentions & cross-session notify: /notify <scope|chatId> <text> pushes a report to another session (admin); the agent also gets a built-in lark_notify dsh tool (wired into both SDK and ACP runtime profiles) to push messages to other groups/topics and @mention members after a task finishes. The callback runs on 127.0.0.1 with a random per-boot token — nothing is exposed to the public network.
Mid-task questions (question cards): when the agent needs a decision, confirmation, or missing information, it sends a question card via the lark_ask_user tool (single choice / multi choice / free text) and resumes automatically once you answer; the run-timeout watchdog pauses while a card is waiting. (The opposite direction of /ask, where you ask the agent.)
Safety-net guardian: a minimal system-level resident process (systemd / LaunchAgent / Windows startup), independent of the dsh process and installed by default with setup. Silent while dsh runs, it takes over the Feishu channel when dsh goes down or fails to boot (e.g. a third-party plugin breaks the profile composition), so you can self-heal without touching the command line:
/safemode: enter core-only safe mode (only the officialdsh-base+dsh-headlessbundles, no third-party plugins) — prefers the SDK streaming engine, falls back to headless, and lets you locate / fix / disable the offending plugin right from the chat;/safemode plugins: list the plugins installed into the broken profile;/safemode status: show state;/safemode stop: interrupt the current safe-mode task (or tap ⏹ on the card);/safemode exit: relaunch the full profile and hand the channel back.
Safe-mode tasks are bounded by an idle timeout (DSH_LARK_GUARDIAN_SAFE_TIMEOUT_MS, default 10 minutes, stopping only after a task has been silent the whole window); timeouts and failures always surface a clear terminal state. Install:
# Installed by default with setup (no extra flag); can also be installed / refreshed later:
dsh-lark-bot guardian install --dsh-profile dsh-lark
Skip it with setup --no-guardian; remove it later with dsh-lark-bot guardian uninstall.
Models / Providers / Credentials
Configuration is persisted the official dsh way (the same storage protocol as the dsh Web Settings → Models page); changes take effect on the next request without restarting the bot:
- Interactive management hub:
/providers(or bare/provider,/model,/key) opens a management card. BotFather-style multi-turn wizards cover add/update/remove flows — pick options (API protocol, provider, model, credential ref) with buttons, type values (ID, Base URL, model list, key value) into card inputs, review on a confirm card, and cancel any time. /model use <id>: hot-switch the model for this session (effective next message);/model default <id>: write the dsh default model./providers: show providers, models and credential status;/provider add|update|remove: manage custom providers (needs--api/--base-url/ at least one--model, matching the official schema) ordeepseek-official./key set|remove|list: read / write~/.dsh/.credentials.yaml(0600); settings keep onlyapiKeyEnvreferences — literal keys never enter settings or chat history.- Hot reload: before each run the bridge resolves the model into a
provider + modelroute and passes it to the dsh runtime; the SDK adapter re-spawns the runtime automatically when the route changes (effective on the next message). A bare pi-ai Base URL (e.g.https://www.kingapi.xyz) is completed with/v1automatically.
Security note: typing a key in a Feishu conversation exposes it to everyone who can see that chat; prefer private chats or --api-key-env references to environment variables. The bot never echoes key values in any reply.
Upgrade, Disable & Uninstall
Upgrade
Recommended: one-command full upgrade (new in v0.12.0, issue #10)
npx dsh-lark-bot@latest upgrade --profile dsh-lark --yes
upgrade detects the installed / running / npm-latest versions, upgrades the package (dsh plugin add <name>@<latest>), idempotently reinstalls and restarts the guardian service, then runs doctor verification. Running instances are handled safely:
- By default the running dsh profile is never interrupted — you only get the restart command (config / sessions / credentials are untouched);
--restart: also restarts the guardian service and (managed/detached) dsh profile processes;--check: report versions and running state only, no changes;--rollback: reinstall the version recorded before the last upgrade (~/.dsh-lark/upgrade-state.json);--force: reinstall the running version when npm is unreachable (offline);--no-guardian: skip the guardian upgrade;- Runtime-profile consistency repair: after upgrading, the own-package links of
dsh-lark-sdk/dsh-lark-acpare re-pointed to the new version (avoiding re-provisioning on the next start).
Pass --yes to skip the interactive confirmation (non-interactive runs fail closed without it). Alternatives:
- Plugin: re-run
setup(ordsh plugin --profile <name> add dsh-lark-bot) to pull the latest npm release. - Safety-net guardian: installed / upgraded together with
upgrade/setup(idempotent), or standalone viadsh-lark-bot guardian install. - CLI tool (optional):
npm i -g dsh-lark-bot@latest; not needed when usingnpx. - Restart the profile after upgrading (when not using
--restart):dsh --profile dsh-lark.
Disable
Keep the plugin loaded but stop the bridge engine: export DSH_LARK_DISABLED=1 before booting the profile. For full removal see the next subsection.
Uninstall
dsh plugin --profile dsh-lark remove dsh-lark-bot
Removal unloads the plugin from the profile. Local state (config / sessions / archives / roles) stays in ~/.dsh-lark; back it up before deleting it.
See docs/QUICK_START.md for installation details, state directories, logs and troubleshooting.
FAQ (use cases & common questions)
Typical use cases
Q: Can I drive my local DeepSeek Harness from my phone?
A: Yes. After the one-command install and a QR scan, message the bot from the Feishu mobile app to drive your local dsh coding agent; tasks can also push cross-session notifications with @mentions when done. Install: npx dsh-lark-bot@latest setup --profile dsh-lark → dsh --profile dsh-lark → scan → start chatting.
Q: How do I isolate projects and split work across a team?
A: Each session automatically lands in an isolated git worktree with project-level AGENTS.md injected; admins define and bind roles with /role and manage the allowlist with /invite; up to 2 tasks run in parallel per chat by default (/concurrency to adjust), with /archive + /retention controlling archival and retention.
Q: Does the bot still work if dsh crashes or goes offline?
A: Yes. setup installs the safety-net guardian by default: when dsh crashes, the guardian takes over the Feishu channel and first tries to relaunch the full profile; if that still fails, send /safemode to enter core-only safe mode, fix the problem from the chat, and /safemode exit restores the full profile. No command line is needed.
Common questions
Q: How do I connect DeepSeek Harness to Feishu?
A: Install Node.js ≥ 22 and DeepSeek Harness (with DEEPSEEK_API_KEY configured), run npx dsh-lark-bot@latest setup --profile dsh-lark, then dsh --profile dsh-lark and scan to bind. DM the bot directly, or use @bot in groups/topics.
Q: Do I need a public IP, domain or server?
A: No. The Feishu channel uses an outbound WebSocket long connection, so it works behind NAT — no public server, domain or tunneling required.
Q: How is dsh-lark-bot different from other DeepSeek Harness Feishu plugins (e.g. harness-lark)?
A: The most complete feature set: safety-net guardian, multi-role agents, parallel tasks, session archival, cross-session proactive notifications, and in-chat model/key management — all in one. It ships as a standard dsh profile bundle installed with a single npx dsh-lark-bot@latest setup command — no separate Docker / background service.
Q: Where do I download the project? Are there impostors?
A: The only official repository is github.com/PlutoKeating/dsh-lark-bot and the only official npm packages are dsh-lark-bot / dsh-feishu-bot (maintainer plutokeating). This project never ships .exe or "download-and-run" installers; any repository or page distributing executables under the project's name is an impostor — do not run anything from it (see the "Impostor Repository Warning" at the end).
Keywords
dsh · deepseek · deepseek harness · feishu · lark · bridge · bot ·
chatbot · messaging · qrcode · typescript · feishu-bot · lark-bot ·
dsh-plugin · deepseek-harness · im-bridge · ai-agent · workspace · self-healing
Compatibility
- DeepSeek Harness (
dsh): verified against dsh 0.1.0-rc.6 (last verified 2026-08-15: SDK JSON-RPC / ACP runtime handshake + real streaming task verification), connected through the official@deepseek-ai/dsh-sdk-client/@deepseek-ai/dsh-acp; seedocs/COMPATIBILITY.mdfor pinned versions, the upgrade policy and automated probing, anddocs/adapter-notes.mdfor adapter details. - Runtime: Node.js ≥ 22.19 (see
enginesinpackage.json). - Platform: Linux / macOS / Windows (Feishu outbound WebSocket long connection; no public server, domain or tunneling required).
- The default adapter is the official
@deepseek-ai/dsh-sdk-client(SDK JSON-RPC runtime with native session continuation and token-level streaming events);DSH_LARK_ADAPTER=acpswitches to the official ACP server (approval cards);headlesskeeps the legacy subprocess fallback;DSH_LARK_ADAPTER=webdrives the local dsh web agent (session.prompt+/api/events.mux— the web agent becomes the single writer, eliminating multi-writer session-log corruption at the root). On first start the bot creates the runtime profile at~/.dsh/profiles/dsh-lark-sdk(ordsh-lark-acp).
Known limitations
- ACP sessions are always fresh (an upstream limit); the SDK protocol has no mid-turn cancel, so
/stopcloses and recreates the runtime. - The engine runs in-process as a dsh plugin; agent execution uses the official dsh SDK runtime subprocess — a deliberate nested-runtime design for per-workspace runtime pools and parallel runs. The one process-level exception is the safety-net guardian installed by default — a minimal resident process independent of dsh / Cordis that only takes over the Feishu channel after dsh goes down and stays silent otherwise.
- Feishu doc comments and rich-text replies are planned, not yet implemented.
- pnpm ≥ 10 build policy is handled by
setup; when installing manually andERR_PNPM_IGNORED_BUILDSappears, addallowBuilds: { protobufjs: true }to the profile'spnpm-workspace.yamland retry.
Configuration
- Local config:
~/.dsh-lark/config.json - The state root can be overridden with
DSH_LARK_HOME - Environment variables use the
DSH_LARK_*prefix - Template:
.env.example - Sensitive values: credentials (
DSH_LARK_APP_SECRET,DEEPSEEK_API_KEY, …) stay in local config/env only; logs and cards are redacted; only.env.exampleis committed.
When the session runs inside a Git repository, an isolated worktree is created at ~/.dsh-lark/profiles/<profile>/worktrees/<scope>/ and a project-level AGENTS.md is copied in.
Each Feishu scope keeps the last 40 conversation messages by default (adjustable with /retention or DSH_LARK_RETENTION_MSGS); messages beyond the retention window are archived to ~/.dsh-lark/profiles/<profile>/archives/ (Markdown + JSONL inside a Git repository, one commit per archive), and /archive exports the full session on demand. The SDK mode continues the native dsh session, while headless mode approximates memory by injecting history into the next prompt.
Core environment variables:
| Variable | Default | Description |
|---|---|---|
DSH_LARK_HOME |
~/.dsh-lark |
Local state root directory |
DSH_LARK_TENANT |
feishu |
feishu or lark |
DSH_LARK_WORKSPACE |
unset | Default working directory for new sessions |
DSH_LARK_DSH_COMMAND |
auto-discovered | dsh launch command; usually not needed |
DSH_LARK_DSH_ARGS |
auto-discovered | dsh launch args, comma-separated; usually not needed |
DSH_LARK_ADAPTER |
sdk |
sdk (default) / acp (approval) / headless (legacy) / web (local dsh web agent, single writer) |
DSH_LARK_PROVIDER |
deepseek-official |
Model provider |
DSH_LARK_MODEL |
deepseek-v4-flash |
Default model |
DSH_LARK_MAX_TOKENS |
unset | Per-request output token cap for SDK agents |
DSH_LARK_WEB_URL |
http://127.0.0.1:3080 |
web adapter: base URL of the local dsh web agent |
DSH_LARK_WEB_PUSH |
true |
web adapter: push web-GUI turn completions to Feishu and auto-switch the chat mapping (0 disables) |
DSH_LARK_ACCESS_DEFAULT_DENY |
false |
Reject private chats when no allowlist is configured |
DSH_LARK_EVENT_FRESHNESS_MS |
600000 |
Stale-message rejection window (0 disables) |
DSH_LARK_RUN_TIMEOUT_MS |
300000 |
Idle timeout for a single run: stops only after the run has been silent for this long |
DSH_LARK_STOP_GRACE_MS |
5000 |
Grace period after SIGTERM before SIGKILL |
DSH_LARK_SCOPE_CONCURRENCY |
2 |
Concurrent runs per scope (1 = strictly serial) |
DSH_LARK_RETENTION_MSGS |
40 |
Messages kept per scope (0 keeps everything) |
DSH_LARK_ARCHIVE_MAX |
50 |
Max archives kept per scope (0 disables pruning) |
DSH_LARK_ARCHIVE_MAX_AGE_DAYS |
90 |
Max archive age in days (0 disables pruning) |
DSH_LARK_HEARTBEAT_MS |
5000 |
Bridge heartbeat write interval (guardian liveness signal) |
DSH_LARK_GUARDIAN_DISABLED |
false |
1 keeps the safety-net guardian stopped |
DSH_LARK_GUARDIAN_PROFILE |
dsh-lark |
dsh profile the guardian watches / relaunches (persisted on install) |
DSH_LARK_GUARDIAN_BRIDGE_PROFILE |
default |
Bridge state profile providing Feishu credentials / allowlist |
DSH_LARK_GUARDIAN_POLL_MS |
2000 |
Guardian watchdog poll interval |
DSH_LARK_GUARDIAN_STALE_MS |
15000 |
Heartbeat staleness threshold before channel takeover |
DSH_LARK_GUARDIAN_ENGINE_DEAD_MS |
120000 |
Live dsh process with heartbeat stale this long is treated as engine-dead (takeover) |
DSH_LARK_GUARDIAN_SAFE_ADAPTER |
auto |
Safe-mode engine: auto tries the SDK streaming runtime then falls back to headless; sdk requires it; headless skips provisioning |
DSH_LARK_GUARDIAN_SAFE_TIMEOUT_MS |
600000 |
Safe-mode per-task idle timeout (stops the run after it has been silent this long and renders a timeout card) |
DSH_LARK_GUARDIAN_CARD_DENSITY |
detailed |
Card density for safe-mode run cards (compact / standard / detailed) |
DSH_LARK_UPGRADE_REGISTRY |
https://registry.npmjs.org |
npm registry used by upgrade to discover the latest version (mirrors supported) |
DSH_LARK_UPGRADE_CHECK |
1 |
Whether doctor / /version probe npm latest (0 disables; best-effort) |
DSH_LARK_UPGRADE_CHECK_INTERVAL_MS |
21600000 |
Bridge new-version check interval (0 disables; default 6h) |
DSH_LARK_UPGRADE_NOTIFY |
false |
Push a Feishu notification to the target chat when a newer version is found (default: log-only) |
DSH_LARK_UPGRADE_NOTIFY_CHAT |
— | Chat receiving update notifications (with DSH_LARK_UPGRADE_NOTIFY=true) |
On startup the bot auto-discovers common local @deepseek-ai/dsh installations. Set these two variables only when auto-discovery fails or a special profile is required.
Permissions & Data
This tool runs locally; before installing, be aware that it accesses:
- Feishu credentials: the PersonalAgent app
app_id/app_secret, stored in plaintext at~/.dsh-lark/config.json(file mode 600). - File system: reads / writes the working directories you choose with
/cdand/ws(including running shell commands and modifying files). - Network: an outbound WebSocket long connection to the Feishu open platform for messages, and task context sent to the DeepSeek API.
- Local callback: when the
lark_notifytool runs, the dsh runtime subprocess calls the bridge process back over a random 127.0.0.1 port with a per-boot token (loopback only). - Processes: spawns local
dshruntime subprocesses (dsh-sdk-jsonrpc-server/dsh-acpprofiles) to run agent tasks. - dsh configuration:
/model/providers/provider/keyread / write~/.dsh/settings.yamland~/.dsh/.credentials.yamlusing the official dsh storage protocol (admin-only writes; settings keep onlyapiKeyEnvreferences; credentials file mode 0600, directory 0700; literal keys never enter settings or chat history). - Safety-net guardian (installed by default with
setup): a system-level resident process reads the Feishu credentials from~/.dsh-lark/config.json; it takes over the same bot's Feishu long connection only after dsh goes down and scans local processes (command lines viapsonly, no memory access). On/safemodeit provisions a core-only dsh profile (headless or SDK JSON-RPC runtime, both without third-party plugins) and runs one task per message; the SDK engine provides real-time streaming events via the officialdsh-sdk-jsonrpc-serversubprocess.
All data flows only between this machine, Feishu and DeepSeek; nothing is collected or uploaded as telemetry. Keys are never committed to the repository (see .gitignore).
Troubleshooting
Run dsh-lark-bot doctor first; it checks the profile and working directory and performs a real availability probe for the current adapter (sdk / acp / headless runtime handshake).
Common issues:
- Silent bot / long-connection failure: check the JSONL logs on stderr, focusing on the
channelandchannel-commandcategories; the SDK reconnects automatically. - Unresponsive agent: send
/statusto view the scope, cwd and active run; send/stopto terminate the current task; the idle watchdog terminates it automatically after it has been silent forDSH_LARK_RUN_TIMEOUT_MS(active streaming work is never cut short). - First QR binding fails: make sure the local clock is accurate and the Feishu open platform is reachable; with an existing App ID/Secret you can skip scanning via
--app-id/--app-secret.
The bridge engine logs JSON Lines to stderr (captured by the dsh host; logs/bot.log is a leftover path from the 0.6.0 standalone-service era and is no longer written since 0.7.0); the dsh host uses its own logging.
Rollback: remove the plugin and reinstall a pinned version (e.g. dsh plugin --profile dsh-lark add dsh-lark-bot@0.6.0); ~/.dsh-lark state is independent of the package, so config and sessions survive upgrades / rollbacks.
Development
pnpm install
pnpm typecheck
pnpm test
pnpm build
pnpm check:publish-bundle # verifies dist matches every export & the CLI entry (release gate)
pnpm ci:local
pnpm release:check # ci:local + upstream consistency check
pnpm compat:probe # installs pinned dsh into a temp DSH_HOME and runs a real SDK handshake
pnpm dsh:upstream # compares npm upstream stable with the pinned matrix
pnpm security:monitor # impostor-repo & npm copycat monitor (recommended weekly)
See AGENTS.md for the development workflow, docs/API.md for module contracts, and docs/ARCHITECTURE.md for the architecture. See docs/COMPATIBILITY.md for the compatibility matrix, upgrade policy and automation.
Contributions are welcome via Issues and PRs; see AGENTS.md for the workflow (required reading, commit conventions, push policy) and docs/ECOSYSTEM.md for ecosystem delivery standards.
Publishing both packages (dsh-lark-bot and dsh-feishu-bot share the same dist / version / dependencies):
pnpm publish:dual:dry-run
pnpm publish:dual
scripts/publish-dual-packages.mjs generates two publish manifests from the root package.json, differing only in name / bin, so the two copies never drift. A GitHub tag v* triggers release.yml to publish both npm packages and create a Release automatically.
The same dist is also published to GitHub Packages as @plutokeating/dsh-lark-bot and @plutokeating/dsh-feishu-bot, viewable on the GitHub Packages page.
Maintenance
- Status: active. Primary maintainer: PlutoKeating.
- Bugs / feature requests: GitHub Issues; security issues via the private channel in
SECURITY.md.
See the next section for ecosystem registration status.
Author
This project is developed and maintained by PlutoKeating, who focuses on automation and developer tooling and prefers building software from real usage. It grew out of the daily need to drive DeepSeek agents from Feishu/Lark group chats, evolving into a complete bridge with guardian, self-healing, and one-command upgrade capabilities. See the author's profile: PlutoKeating.
Contributors
Thanks to the following contributors (by merge / submission time):
| Contributor | Contribution | Status |
|---|---|---|
| koprivnikarurnaa-oss | PR #9: Web single-writer adapter + self-heal v2 + guardian auto-relaunch | ✅ Merged |
| Normanyin | PR #11: /newg auto-create group chat command |
✅ Merged (cherry-pick) |
Note: GitHub's contributor graph attributes commits by author email. The commits merged via PR #9 carried a local generic identity (
dsh-user <dsh-user@local>, not linked to a GitHub account), so they are not auto-counted in the graph; this table is the repository's explicit acknowledgment. PR #11's commits are authored under the contributor's linked account and will be credited automatically once merged.
License & Security
- License: GNU Affero General Public License v3.0 (see
LICENSE). - Copyright: source is owned by the maintainers and licensed under AGPL-3.0; "DeepSeek" and "Feishu / Lark" trademarks belong to their respective owners.
- Security reports: report vulnerabilities privately via GitHub Security Advisory; do not open a public issue.
- Security model: default-deny, secret redaction, path containment, SSRF protection, stale event rejection and default-disabled interactive tools — see
SECURITY.md.
Documentation
Engineers taking over this project: read
docs/REQUIREMENTS.mdanddocs/RESEARCH.mdfirst.
| Doc | Content |
|---|---|
docs/REQUIREMENTS.md |
Complete requirements, outputs & specifications |
docs/RESEARCH.md |
Research: official status, references, feasibility |
docs/ARCHITECTURE.md |
Architecture layering & directory mapping |
docs/API.md |
Module interfaces & contracts |
docs/QUICK_START.md |
Install & quick start |
docs/COMPATIBILITY.md |
Compatibility matrix, upgrade policy & automation |
docs/MANUAL.md |
Complete user manual |
docs/adapter-notes.md |
How to plug the dsh adapter |
docs/UPGRADE.md |
Upgrade flow architecture, activation & known boundaries (issue #15) |
docs/ECOSYSTEM.md |
Ecosystem & delivery standards (for engineers) |
docs/roadmap.md |
Roadmap & milestones |
docs/PLAN.md |
Development plan & acceptance criteria |
SECURITY.md |
Security model & reporting |
AGENTS.md |
AI agent workflow spec |
Architecture
See
docs/ARCHITECTURE.mdfor details.
Feishu / Lark ──WebSocket long connection──▶ bridge/ ──▶ session/ ──▶ workspace/ ──▶ adapters/ ──▶ dsh ──▶ DeepSeek V4
The core idea: decouple the Feishu channel from the agent backend. The bridge layer follows the battle-tested lark-channel-bridge approach (WebSocket long-connection + streaming cards + session routing); the agent backend is abstracted behind an adapter, defaulting to the official DeepSeek Harness SDK (DSH_LARK_ADAPTER=sdk), with an optional ACP approval mode and the legacy headless fallback.
The safety-net guardian (src/guardian/) installed by default runs as a separate resident process: silent while dsh is up, it takes over the Feishu channel when dsh goes down, accepts /safemode control signals, runs a restricted core-only conversation (dsh-base + dsh-headless) for self-healing, and relaunches the full profile on /safemode exit.
Directory Structure
| Directory | Responsibility |
|---|---|
src/bridge/ |
Feishu channel integration |
src/onboard/ |
First-run QR onboarding |
src/session/ |
Session routing, queueing, access control |
src/workspace/ |
Project workspace, git worktree isolation & rule injection |
src/adapters/ |
Agent backend adapters (sdk / acp / headless / web single-writer) |
src/card/ |
Streaming card state & rendering |
src/bot/ |
Run registry, queueing, approval/question registries |
src/commands/ |
Slash commands |
src/cli/ |
CLI entry: setup / doctor / upgrade / hidden run |
src/upgrade/ |
One-command upgrade (issue #10): version probe, upgrade state, running-state detection, restart helpers, runtime link repair |
src/guardian/ |
Safety-net guardian: heartbeat, process watch, core-only safe profile, takeover state machine, service install |
src/config/ |
Profile, config, access & dsh config management |
src/core/ |
Structured logging |
src/media/ |
Attachment download & text injection |
src/platform/ |
Cross-platform atomic writes |
docs/ |
Architecture, roadmap & docs |
reference/ |
Cloned reference repos (not committed) |
Roadmap
See docs/roadmap.md.
References
| Project | About |
|---|---|
zarazhangrui/lark-coding-agent-bridge |
Feishu ↔ Claude Code / Codex bridge; the direct reference for this project |
deepseek-ai/deepseek-harness |
DeepSeek Harness (dsh), the agent backend |
grinev/opencode-telegram-bot |
Telegram mobile client for OpenCode; another reference |
Community Listings
Community listing & recommendation status, kept current as update requests land. As of v0.15.1 (re-verified 2026-08-17):
| Platform | Status | Notes |
|---|---|---|
| awesome-dsh-plugins | ✅ Listed · runtime-verified | Shown as ✅ 运行级可用 (agent-tested); v0.8.0 entry merged via PR #127; leaderboard sync #139 closed; v0.15.1 refresh submitted via PR #230, awaiting merge |
| awesome-dsh-plugin | 📨 Submission PR open · awaiting merge | The 7.2k+ star curated plugin list (the ecosystem traffic hub); submission PR #1408 open, status backfilled after merge |
| dshfind | ✅ Listed · detail page live | Entry name fixed (issue #2 closed); v0.15.1 refresh requested via #6 follow-up comment, awaiting maintainer; the header badge / card comes from dshfind |
| dshbase | ✅ Listed · CI-verified | Chinese plugin directory (1771+ plugins) with automated CI install verification, marked ✅ verified; the header badge comes from dshbase |
| omdsh-dev/community | ✅ Accepted · discussion active | [Plugin] submission (Discussion #11) accepted and active, latest notes v0.10.2; v0.15.1 update note prepared, paste manually (org-level discussions have no API) |
Update request status (as of 2026-08-17):
- awesome-dsh-plugins v0.8.0 entry: #127 — ✅ merged; leaderboard sync: #139 — ✅ closed
- awesome-dsh-plugin listing: #1408 — 📨 submitted (2026-08-17, v0.15.0 data; v0.15.1 follow-up comment submitted)
- dshfind name fix + v0.8.0 refresh: #2 — ✅ closed; v0.10.1 refresh: #6 — 📨 pending (v0.15.1 follow-up submitted)
- omdsh-dev/community listing: Discussion #11 — ✅ accepted, discussion active (latest notes v0.10.2); v0.15.1 update note — 📨 prepared, paste manually
- Platform refresh (v0.14.0 → v0.15.1) — ✅ resumed (2026-08-17): awesome-dsh-plugins PR #230 · dshfind #6 follow-up · omdsh note prepared
Highlights follow-ups (six exclusive capabilities & the issue #6 design):
- awesome-dsh-plugins leaderboard row sync (repo description → latest) & agent-test name anomaly: #139 — 📨 submitted (maintainer confirmed; awaiting the snapshot/render cycle)
- dshfind detail page: add the in-chat model/key management highlight: #2 follow-up — 📨 submitted
- omdsh six-exclusive-highlights summary (incl. the Guardian design): Discussion #11 highlights comment — 📨 submitted
Impostor Repository Warning
[!WARNING] On 2026-08-17 an impostor repository
tarraencompassing61/dsh-lark-botwas found: re-uploaded as a non-fork with 113/114 commits authored by PlutoKeating, all CI deleted, Issues disabled, zero Releases, and a SEO-bait README offering "Windows exe download & run". This project never ships executables — treat any such download as counterfeit / malicious.Evidence:
docs/security/2026-08-17-impostor-repo-evidence/· Official download:docs/DOWNLOAD.md· Ongoing monitor:pnpm security:monitor
Disclaimer
[!NOTE] This is an unofficial community tool, not affiliated with or endorsed by DeepSeek or ByteDance / Feishu (Lark). DeepSeek Harness, Feishu / Lark and related trademarks belong to their respective owners.
Links
More in this category
alvinunreal/openpets#dsh★ 1075
Bridges DeepSeek Harness lifecycle status, errors, and approval requests to a locally running OpenPets desktop companion.
shaobeichen/dsh-pocket★ 120
Remote phone access to the DSH Web UI: scan a QR code for LAN or public (cloudflared tunnel) access with real-time sync, a mobile-adaptive layout, and a settings tab.
omdsh-dev/dsh-notification★ 59
Desktop notifications for turn completions, with per-outcome controls and keyword rules.
omdsh-dev/dsh-open-in-vscode★ 49
Open DSH workspace directories in VS Code directly from the web GUI.
xmanrui/dsh-im★ 48
Connect IM bots to DeepSeek Harness via QR codes or bot credentials (9 channels: Feishu, WeChat, DingTalk, WeCom, QQ, Slack, Telegram, Discord, and WhatsApp).
THEWOLFWALKER/dsh-notifier★ 40
Unified notification & remote control for DSH: one `notify()` API, 25+ channels (Telegram / DingTalk / Feishu / WeCom / QQ bot / WxPusher / PushPlus / ServerChan / Bark / Discord / Slack / ntfy / webhook...), level routing (timeSensitive / active / passive) with tiered retry, multi-channel inbound approval (Telegram buttons, Feishu cards, QQ, WxPusher, WeChat iLink), official QR login for QQ/DingTalk/Feishu, a local web admin console, multi-agent routing, desktop notifications — and a mobile command center: `!status` / `!stop` / `!retry` agent control from your phone plus actionable notifications (view result / retry / logs buttons that call back into the agent). Secrets redacted, tool rate-limited, zero runtime deps — plus an open event source: other plugins can inject the notifier service (ctx.notifier) and subscribe to dsh-notifier/sent events, reusing notification without coupling — and an identity system (v0.7): pairing codes (/pair in any DM, first redeemer becomes owner), composite-key bindings, member roles, and a guided bootstrap state when the whitelist is empty.