DeepSeek Harness plugin

dsh-feishu-0x010101

Feishu (Lark) long-connection channel plugin for DeepSeek Harness (dsh) — zero npm dependencies

Jump to install

Source facts

Repository
0x0101010/dsh-feishu
Latest update
Aug 19, 2026
Category
Remote & Mobile
GitHub stars
0
Format
plugin
Catalog evidence
Upstream dsh.bundle evidence
Evidence path
package.json#dsh.bundle
Checked against
0.1.0-rc.8
Upstream check date
2026-08-20

This evidence comes from the upstream catalog. This site has not installed, run, or security-reviewed the plugin.

Install

Start with a prompt that asks an agent to review the GitHub repository and source. Switch to the command if you want to install it yourself.

Copy this prompt into DSH, Codex, or another agent and ask it to review the GitHub repository and source first.

Do not install or run any commands yet. Read this plugin's GitHub repository, README, and relevant source code. Then answer the questions below clearly and directly so I can decide whether it fits my needs:

1. What is this plugin, and what problem does it solve?
2. Who is it for, and what are its typical use cases?
3. How is it used after installation? Include one minimal example.
4. What known limitations or privacy, security, compatibility, or maintenance risks does it have?
5. Give a clear recommendation: recommend, conditionally recommend, or do not recommend, with reasons.

Distinguish statements documented by the repository, inferences from source code, and unknowns. If evidence is insufficient, say so explicitly. Do not guess or simply repeat the README.

GitHub: https://github.com/0x0101010/dsh-feishu
Plugin: dsh-feishu-0x010101
Author: 0x0101010

Check the source files

Read the README and other files from this plugin directory before installing.

File explorer4 files
README.mdSource · read only
README language

dsh-feishu

中文 | English

A Feishu (Lark) long-connection channel plugin for DeepSeek Harness (dsh): bridges a dsh agent to a Feishu bot, so you can dispatch tasks, receive results, and approve permissions right in chat.

Zero npm dependencies — built on Node >= 22's native WebSocket plus a hand-written protobuf Frame codec (field numbers match the official oapi-sdk-go WS module). The whole plugin is a single index.js.

Features

  • WebSocket long connection: uses Feishu's official WebSocket callback (callback/ws/endpoint) — no public IP, no port forwarding, no callback server needed
  • One agent per chat: each conversation gets an isolated context; idle sessions are recycled automatically (default 30 min)
  • Approvals as interactive cards: dsh approval requests become Feishu card buttons (✅ allow / ❌ deny); click or reply y/n; the card updates in place once handled
  • Mid-turn steering: send a message while a task is running and it's injected into the current turn at the next step boundary — no interruption; /stop is the hard interrupt
  • Mode switching: /mode switches agent presets (minimal / standard / PTC / creative), orthogonal to permission presets
  • Command bridge: all dsh built-in commands (/permission /plan /compact /goal /export …) work in chat
  • Auto-reconnect (5s after close), heartbeat keepalive, event ack (prevents Feishu redelivery), seq-based dedup after resume

Requirements

  • Node >= 22 (native WebSocket; developed on 23)
  • A working dsh deployment (npx @deepseek-ai/dsh)
  • A Feishu Open Platform app (a self-built enterprise app is fine) with:

- Events & Callbacks → long-connection (WebSocket) mode - Bot capability enabled - Scopes: im:message (send/receive), etc.

Install

npx @deepseek-ai/dsh plugin --profile feishu add /path/to/dsh-feishu

Credentials never go into config files — they come from environment variables (put them in the profile's .env, or global ~/.dsh/.env):

FEISHU_APP_ID=cli_xxxxxxxx
FEISHU_APP_SECRET=xxxxxxxx
# optional: agent working directory
DSH_FEISHU_CWD=/your/workspace

Verify the composed config and start:

npx @deepseek-ai/dsh --profile feishu --dump-config   # verify
npx @deepseek-ai/dsh --profile feishu                  # start

Configuration (cordis.patch.yml)

KeyDefaultDescription
appIdrequiredFeishu App ID (FEISHU_APP_ID)
appSecretrequiredFeishu App Secret (FEISHU_APP_SECRET)
domainhttps://open.feishu.cnAPI domain; use https://open.larksuite.com for the international version
cwdprocess.cwd()Agent working directory
allowUsers[]open_id allowlist; empty = no restriction — set this in production
allowChats[]chat_id allowlist; empty = no restriction
sessionTimeoutMs1800000Idle session recycle timeout
defaultModestandardDefault agent preset for new sessions
modeAliasessee patchMode aliases (defaults include Chinese aliases)

> Security note: when allowUsers/allowChats are empty, anyone who can talk to the bot can drive your agent (executing tasks on your machine). Configure them before sharing publicly.

Slash commands

Native commands (handled by this plugin)

CommandArgsBehavior
/newDispose the current session: context cleared, agent destroyed, next message gets a brand-new agent. Use after /mode on a session with history, or to start a fresh task.
/modeList all agent presets with descriptions and mark the current one (). Also shows whether any preset is broken (e.g. code needs a host runtime not present in the base bundle).
/mode <preset>id or aliasSwitch the chat's agent preset: minimal (极简) / standard (标准) / code (ptc) / cordis (创造). Blank session → takes effect immediately. Session with history → the choice is recorded (📌) and applies after /new (presets lock at agent creation). Unknown names list the valid ids.
/statusCurrent model (provider/model), active mode, chat id, agent status (running/idle), minutes since last activity, idle-recycle countdown, pending-approval indicator.
/stopHard-interrupt the running turn: cancels in-flight work and clears any queued inputs. If nothing is running, replies "agent idle".
/helpBuilt-in help text.

Approval answers (not slash commands)

When an approval card is pending, a bare y = allow, n = deny (case-insensitive). Clicking the card buttons does the same; the card is updated in place either way.

Bridged dsh commands

Everything else starting with / is forwarded to dsh's command service, so all built-in commands work in chat. Common ones:

CommandBehavior
/permissionShow the current permission preset
/permission <preset>Switch: read-only (files read-only, no approval needed) / workspace-write (workspace writable, out-of-bounds needs approval — default) / danger-full-access (full access, no approval)
/planToggle plan mode: agent plans first, executes after you approve
/compactCompress session history to reclaim context
/goalSet/view a long-running task goal
/exportExport the session log
/feedbackRecord feedback

Unknown commands reply with the full list of what's available.

Plain messages (no slash)

  • Task running → the message is steered into the current turn: acknowledged with 📌, takes effect at the next step boundary, task keeps running. Use /stop to abort instead.
  • Agent idle → starts a new turn as usual.

In group chats, @mention the bot to trigger any of the above.

Development

node test.mjs    # offline unit tests: protobuf codec roundtrip + config validation
node debug.mjs   # debug frame encoding bytes

test.mjs extracts the pure-function blocks from index.js and roundtrips them — no dsh startup, no real credentials needed.

Protocol notes

Feishu WebSocket long-connection protocol (from larksuite/oapi-sdk-go v3 ws module):

1. POST /callback/ws/endpoint (body carries AppID/AppSecret) returns a WS URL + PingInterval 2. Binary frames = protobuf Frame: 1=SeqID 2=LogID 3=service 4=method(0 control/1 data) 5=headers 8=payload 3. Heartbeat: send method=0 + headers[{type:ping}] every PingInterval 4. Data frames have header type=event; payload is event JSON (core: im.message.receive_v1) 5. Every event must be acked (original headers + biz_rt + {"code":200}) or Feishu will redeliver

The codec is hand-written at the top of index.js (encodeFrame/decodeFrame) — no protobufjs dependency.

License

MIT