Back to home@tkwkeven

dsh-lark

Feishu/Lark channel for DeepSeek Harness: prefix-created task sessions, thread routing, streaming thinking cards, interactive questions, media delivery, lifecycle notices, runtime policies, web mirror

Stars
0
Language
JavaScript
Created
Aug 20, 2026
Updated
Aug 22, 2026

Introduction

dsh-lark

English · 中文

License GitHub stars GitHub forks Last commit DSH plugin

Feishu/Lark channel for DeepSeek Harness (DSH), built on the deepseek-harness-lark bridge. Adds task-oriented workflows on top of the stock bridge: prefix-created task sessions with thread routing, streaming thinking cards, interactive questions, media delivery, lifecycle notices, runtime policies, and a Web UI mirror.

This is the open-source release of a plugin previously maintained as three separate packages (dsh-lark-tasks + dsh-lark-policies + dsh-lark-mirror), merged into one.

Features

AreaDescription
Task sessionsCreate a task session from a main-chat prefix: ptc任务: / 标准任务: / 极简任务: / 创造任务: / 任务: (preset mapping configurable). One task = one durable DSH session, managed exactly like web sessions
Thread routingEvery message inside a task's thread is delivered to that task's session — no prefix needed inside the thread
Streaming cardsWhile a task runs, thinking is streamed into an interactive card inside the thread (event-driven + per-second heartbeat). Each round gets a fresh card; finished cards freeze at their final state
Task reportsThe final answer is sent as a separate message in the same thread, with a fixed-format prefix (✅[dsh] [YYYY-MM-DD-任务-N], daily sequence number)
Interactive questionsask_user_question is redirected to Feishu card buttons (with text-reply fallback) instead of an invisible web prompt
Media deliverylark_send_media (image/file/audio/video, ≤30 MB), lark_send_bigfile (>30 MB → cloud drive + link, view permission granted to the sender), lark_create_doc (markdown → Feishu docx)
Lifecycle notices🔴 shutdown / 🟢 recovery notices delivered to the user's DM (auto-learned or configured)
Runtime policiesExact restartCommandText (default 重启进程) restarts the DSH process; single-turn hard time limit (default 6 h); global Chinese-output prompt section
Web mirrorOne-way sync of task sessions into the Web GUI: /lark-mirror/* read-only routes + "飞书任务" sidebar panel; task sessions grouped into a "飞书" workspace

Install

The stock lark-channel from deepseek-harness-lark is disabled and replaced by this plugin. Place the package under a DSH profile (plugins/ or node_modules/), then in cordis.patch.yml:

- id: lark-channel
  disabled: true
- insert:
    - id: lark
      name: dsh-lark
      config:
        appId: <your feishu app id>
        appSecretRef: LARK_APP_SECRET
        cwd: !!js process.env.DSH_LARK_CWD ?? process.cwd()
        lifecycleChatId: <optional: DM chat id for lifecycle notices>
        restartCommandText: 重启进程
        turnHardLimitHours: 6

Credentials are resolved through the DSH credential store (appSecretRef names an env var / credential entry — never put the secret in the patch file).

Configuration

The config is the union of the three merged plugins' keys. Highlights:

KeyDefaultDescription
appId / appSecretRefFeishu app credentials (required)
taskPresetsptc→code, standard→standard, minimal→minimal, creation→cordisPrefix → agent preset mapping
taskPermissiondanger-full-accessPermission preset pinned on new task sessions ('' disables; Feishu has no interactive approval surface)
registryPath~/.dsh/lark/registry.jsonTask registry persistence (override to keep historical data from older layouts)
reportSymbol / reportIdentity / reportTaskLabel / dsh / 任务Task report prefix parts
restartCommandText重启进程Exact user message that restarts DSH
turnHardLimitHours6Single-turn hard cap in hours (0 disables)
questionEnable / questionTimeoutMstrue / 30 minFeishu interactive question behavior
lifecycleChatIdauto-learnedDM chat id for 🔴/🟢 notices

Known upstream issue

Long markdown/text replies are chunked by the official SDK, and only the first chunk carries replyTo — pages 2+ land in the main chat instead of the thread (affects long task reports). Root cause is in @larksuiteoapi/node-sdk's OutboundSender:

  • larksuite/node-sdk#205
  • sliverp/DeepSeek-harness-lark#1

Until an upstream fix ships, patch the bundled SDK code in dist/index.js (two lines):

-          replyTo: i === 0 ? opts.replyTo : void 0,
+          replyTo: opts.replyTo,

(sendMarkdown and sendText — 2 occurrences; verified in production: all chunked pages stay in the thread, mentions still only on page 1.)

Development

node --check lib/*.js
node test/self-test.mjs

License

MIT