DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

heavenJiang /

heavenJiang/dsh-switchboard

Verified

掌上指挥台 Switchboard: command DeepSeek Harness agents from Telegram and Feishu (Lark) — streamed replies, approvals, files, voice, per-person rights.

★ 1 Stars2 Forks3 IssuesN/A Community rating0 Confirmed installs
View on GitHubProject homepage
READMESource: main@c32c4ec5

Switchboard (dsh-switchboard)

English | 中文

Command DeepSeek Harness Agents from your phone through Telegram and Feishu (Lark) bots: send the Agent text, photos, files, and voice notes, watch replies arrive as they are written, answer tool approvals and the Agent's questions, follow long tasks for completion notices, and browse every chat in the Web UI, where any Session can be linked to a chat.

The bots are other clients of the Web host. They create and prompt Sessions through ctx.sessionController, the same path the Web UI uses, so chat Sessions appear in the Web sidebar and Web Sessions can be taken over or followed. Sessions a bot creates go into the Web Workspace for their working directory (created on first use).

Switchboard overview

Lines

A line is one bot on one chat platform plus the people allowed to use it. Configure as many as you need, for example Telegram for yourself and Feishu for your team; each line has its own credentials, allowed users and chats, and default working directory. One Session can be linked to chats on several lines at once, and replies, approvals, and questions go to each of them. Chats are keyed line:chat id (for example feishu:oc_xxx); the original Telegram line (telegram) keeps bare ids, so bindings and history from earlier releases carry over. Supported: Telegram and Feishu / Lark.

Quick start

  1. Install into a Web profile: Plugins → Add plugin with dsh-switchboard, or dsh plugin --profile web add dsh-switchboard.
  2. Open Plugins → Installed → Switchboard (or Plugin settings in the sidebar panel), add a line under Lines, fill in its credentials and Allowed users (send /whoami to the bot for your id), set the Default working directory, and Save. Changes apply immediately.

Telegram line: create a bot with @BotFather (/newbot), then + Telegram line and paste the token. Allowed users are Telegram ids or @usernames.

Feishu line: Feishu delivers events over the Open Platform's persistent connection, so no public URL is needed.

By QR (recommended): + Feishu line → Create a Feishu app by QR, scan with the Feishu app (or Open in browser on this computer), and confirm. The bot, permissions, the im.message.receive_v1 event, and the card.action.trigger callback are filled in; the Host stores the App Secret in the credentials store (it never reaches the browser), the scanner is added to the allowed users, and the line is saved and connects. For an existing app, Complete permissions adds what is missing the same way.

By hand:

  1. On the Feishu Open Platform (or Lark) create a self-built app and add the Bot capability.
  2. Grant im:message.p2p_msg:readonly, im:message.group_at_msg:readonly, im:message:send_as_bot, and im:resource; optionally contact:user.base:readonly (names) and im:chat:readonly (group names).
  3. Add + Feishu line with the App ID (cli_…) and App Secret and save: Feishu lets you pick the persistent connection only while a client is connected.
  4. Under Events and callbacks, choose Receive events through persistent connection and add the event im.message.receive_v1; do the same for callbacks and add card.action.trigger (buttons need it).
  5. Publish a version, message the bot /whoami, and add the open_id it replies with (ou_…, per app; user_id and union_id also match) to the line's allowed users.

Feishu has no typing indicator or command menu; everything else matches Telegram. Replies, drafts, tool activity, and messages with buttons are interactive cards updated in place; notices are text messages.

In the chat

Command Effect
text, photo, file, voice Goes to the current Session; one is started in the default directory if needed
/menu Buttons for common actions (new session, sessions, model, mode, stop, compact, status, help); the easiest way in Feishu
/new [dir] New Session; without a directory, pick the default or a recent one
/cwd <dir> Working directory for this chat's new Sessions
/sessions Recent Sessions with titles, as buttons that switch
/use <n|sessionId> Switch to an existing Session (Web ones too)
/watch [n|sessionId] Follow a Session's completions and approvals; no argument lists them
/unwatch <n|sessionId|all> Stop following
/stop Stop current work
/steer <text> Steer the running turn
/queue, /cancel <n|all> Show or drop queued messages
/model [name] Show or switch the Session's model (buttons, fuzzy match; the Web default is untouched)
/mode [mode] Show or switch the Session's permission mode
/get <path> Fetch a file or list a directory inside the working directory (symlinks cannot escape it)
/fork Branch from the latest finished turn into a new Session; the original stays
/status Session, model, directory, run state, line, context use, this turn's time, goal, todos, subagents, and queue
Reply to a notice or reply Goes to the Session that message belongs to, without /use; the chat's own Session stays, and that turn's replies come back here
/digest Roundup of followed Sessions over 24 hours: finished, failed, waiting for you, and running. Set Daily digest of followed Sessions to get it once a day instead of a notice per turn; failures, approvals, and questions still arrive at once
/board, /board off Live board: one message that keeps showing every Session's state, with buttons to switch; close it
/away [duration|off] Away mode: approvals and questions wait for you instead of going to the Web UI, with a report when you are back. Durations like 30m, 2h, 1d
/schedule, /schedule add … Manage scheduled tasks (admins); see below
/link <code> Take over a Web Session; the code is on its Switchboard tab
/whoami Your user and chat id (anyone)
Harness commands /compact, /plan, /goal, /permission, /export, … run on the Host exactly as in the Web composer; a slow one shows its progress with a Cancel button; /help lists them
other /xxx Not a command: sent to the Agent as text
  • Rendering: Markdown becomes Telegram HTML (with a plain-text fallback) or a Feishu card's Markdown, split safely.
  • One progress message: while a turn runs, a single "⏳ Working · time · N tool calls" message shows the latest tool calls and the reply being written, with a ⏹ Stop button, and steps aside when the reply arrives as a new message at the bottom (so it notifies): deleted on Telegram, shrunk to a one-line summary on Feishu; a stop or failure is told there too.
  • Acknowledged at once: your message gets 👀 (Feishu: OnIt) while it is worked on, cleared when done; a message sent during a running turn gets a "Queued" notice with Steer now and Cancel.
  • Buttons under the reply: Continue, Retry, Show changes (the turn's changes as a diff file, new files included), and New session; they move to the next reply.
  • Turn summaries: duration, tool calls, and changed files after long turns (configurable).
  • Context and long content: replying to (quoting) a message sends its text along. Replies over Long reply as a file (6000 characters) arrive as a preview plus a Markdown file; Feishu cards fold code blocks over 15 lines.
  • Approvals and questions: Allow once / Reject buttons, with a diff for file edits; the Agent's questions get option buttons, and plain text while a question waits becomes the answer. Unanswered ones go to the Web UI after the timeout.
  • Approval readings: a moment after a command's approval appears, the Session's own model adds a sentence on what it would do and whether that can be undone. Advice only: it never answers the approval, the command stays on screen, and a slow or failed call changes nothing. File edits are left out, since they come with a diff. Turn it off with approvalRiskHint.
  • Live board: /board keeps one message up to date, with what waits for you first, then failures, running work, and the chat's idle Sessions. Buttons switch to a Session. It is pinned on Telegram (Feishu has no pin) and shows only what the person who opened it may see.
  • Away mode: normally an unanswered approval goes to the Web UI, and with nobody there the step does not run. After /away 2h it keeps waiting, with reminders further and further apart (at most hourly), and the task stays on hold at that step. When the time is up or you send /away off, waits return to normal and you get a report of what finished, failed, and still waits.
  • The Agent reaches you: Sessions linked to a chat get a notify_phone tool for milestones and urgent news mid-turn, at most once every 30 seconds per Session. Reply to such a message to answer that Session. Turn it off with agentNotify.
  • Other plugins reach you: the optional phonePush service lets another plugin, such as a news feed, post Markdown to the schedule chats (scheduleChats) with no Session or model in between, so nothing rewrites or drops it. Posts render like replies, go as a file when long, wait in the outbox while a line is down, and are limited to one every 10 seconds. Inject it with ctx.inject(['phonePush'], …) and call available() and send(text, { source }), which returns { delivered, reason? }. Neither side needs the other. Turn it off with pluginPush.
  • Scheduled tasks (admins, when the Harness has them): /schedule lists every Host task, with buttons to run, pause, resume, delete (two presses), and choose whether it reports to this chat. /schedule add daily 09:00 <instruction>, every 30m, in 2h, or cron 0 9 * * 1-5 creates one, in Host time; it uses the chat's working directory and one Session of its own, and reports back here, approvals included.
  • Media: photos and files are staged through ctx.fileUploads; images reach the model as images. Voice notes are transcribed by the Harness speech service via ffmpeg. Files the Agent presents are sent back.
  • Nothing lost: replies, turn notices, and presented files that cannot be sent (line down, or a send that certainly failed) wait in an outbox and go out, marked late, once the line is back; sends with an unknown outcome are not repeated. After a plugin restart, the final reply of each turn that ended meanwhile is sent (up to 3 per Session). A line down longer than Outage alert after (5 min) is reported to the Line outage alert chats through another line.
  • Per-person rights (console → Members): admins do everything; members get their own permission preset (workspace-write by default) and directories, and cannot change the mode or run permission-related Harness commands; guests are read-only and cannot answer approvals. Listed people start as admins, people allowed from the Members page as members; directory limits apply to new Sessions, /cwd, /sessions, /use, /watch, and buttons (checked against whoever pressed).
  • Groups: by default only commands, @mentions, and replies to the bot are answered. Authorize users or whole chats per line. The Agent is told who said what with a line like [group chat | role: member | from: Ann @ann]; names are cleaned so they cannot forge a role.
  • Security: only a line's allowed users (or members of its allowed chats) can use its bot. Secrets live in the Harness credentials store (TELEGRAM_BOT_TOKEN, FEISHU_APP_SECRET, or environment variables of those names), never in the profile file or the browser.

In the Web UI

  • Switchboard console (sidebar), four tabs: Chats (every line's chats, an overview with a 14-day chart, full threads with Open Session); Lines (one-line summaries that open for editing, Feishu added by QR); Members (people waiting for approval, allowed with one click and told so, and everyone allowed per line); Settings (common options first, the rest under Advanced).
  • Switchboard tab in every Session: linked chats on any line, bind or follow another chat, send as the bot, and the Session's chat activity. Continue on your phone shows a QR code: scan it and that chat takes over the Session, or send the bot /link <code>. A code works once, for 10 minutes, and only for a line's allowed users. On Feishu the QR only opens the bot, so send the code there.
  • /switchboard in the composer: bind, watch, unbind, and send for the open Session.
  • Channel note: Sessions bound to a chat get a short note asking for phone-friendly replies.

Chat thread

Lines

Members and rights

Models

A /model choice for the Session > the plugin page's Bot default model for Sessions a bot creates > the Web default. Neither changes the Web default.

Configuration

See the full tables in README.zh.md. lines holds the lines; while it is empty, the Telegram fields of earlier releases (botTokenRef, allowedUsers, …) run as the telegram line, and the plugin page writes them to lines on its next save. pollTimeoutSec and stateFile live in the profile's cordis.patch.yml. Set HTTPS_PROXY before launching dsh if the platforms are not directly reachable. Migrating from dsh-telegram-bridge: see docs/PUBLISHING.md.

Adding a channel

Implement the Channel interface in src/channels/types.ts, register the type in lines.ts and in startLine in bridge.ts, and give it credential fields in the settings page's line editor.

Development

Type-checking and the Loader composition test use a built sibling checkout at ../deepseek-harness.

pnpm install && pnpm typecheck && pnpm test && pnpm build

See docs/PUBLISHING.md for npm publishing and CHANGELOG.md for changes.

—/ 5

No ratings yet

Verified DSH bundle

Commit c32c4ec55a8f

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout