DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

Bluebubbles — DSH Plugin for DeepSeek Harness
DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins
B

dsh-bluebubbles

Bluebubbles

BlueBubbles (iMessage) bridge plugin for DeepSeek Harness: REST tools + webhook push routed into bound workspaces.

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add github:vINyLogY/dsh-bluebubbles#754f7abe497eb7251320bc263813f3be96cf886c
READMECompatibilityVersions

Compatibility and provenance

Bluebubbles is published as dsh-bluebubbles and currently resolves to version 0.1.0. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
any
Release source
github
Registry updated
8/27/2026

Versions

0.1.0stable
8/27/2026

Related plugins

Loading related plugins…

Latest
0.1.0
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
Unavailable
Files
Unavailable
Surface
any
License
MIT
Source
github
GitHub
★ 0
Weekly downloads
0
Last push
9/15/2026
View source ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue

Related plugins

More verified plugins in integrations-communication.

Acp App@deepseek-ai/dsh-acp-appThe dsh ACP profile bundle: automation-only JSON-RPC stdio and process lifecycle over dsh-baseIm@xmanrui/dsh-im把十一种 IM 渠道和公网 AI Office 接入本机 DeepSeek Harness。 Connect eleven IM channels and a public AI Office to a local DeepSeek Harness.Pocketdsh-pocketPut DeepSeek Harness in your pocket: one package, one settings page, and scan a QR code on your phone to access DSH on your computer in sync (LAN + public network, real-time screen mirroring).DSCODE@toddzheng024/dscode-bundleA complete DeepSeek coding agent with persistent shell, Ultra collaboration and automatic permission review.

README

dsh-bluebubbles

Bridges a local BlueBubbles server (the macOS iMessage bridge) into DeepSeek Harness.

Design principle (Unix philosophy): the host plugin keeps only passive capabilities (webhook receive + binding resolution + message injection) and two high-frequency model tools (send text / send attachment); everything else converges into the bb-channel CLI — agents call it via bash, humans and automation scripts use it directly.

Components

ComponentLocationRole
bluebubbles-bridgesrc/index.tswebhook route + message injection + 2 send tools + the bluebubbles service
dsh-heartbeatsrc/heartbeat.tsgeneric periodic wake-up (reads heartbeat-targets.json)
dsh-cronsrc/cron.tscron-time tasks (reads cron-jobs.json)
bb-channelbin/bb-channel.mjsCLI: chats/messages/send/bind/contacts/webhook/configure…

Model tools (deliberately only two)

ToolRole
bluebubbles_send_textsend a text message
bluebubbles_send_attachmentsend an attachment (image/file)

Everything else goes through the CLI (agents call it via bash — equivalent capability):

~/.local/bin/bb-channel chats [--limit N] [--all]      # list chats (placeholder/pairing-code noise hidden by default)
~/.local/bin/bb-channel messages <chatGuid> [--limit N] # read history (with sender display names)
~/.local/bin/bb-channel send <chatGuid> <text...>       # send text
~/.local/bin/bb-channel send-attachment <chatGuid> <file>
~/.local/bin/bb-channel attachment <guid> [--dir D]     # download an attachment
~/.local/bin/bb-channel bind <chatGuid> (--workspace PATH | --session ID)
~/.local/bin/bb-channel unbind <chatGuid>
~/.local/bin/bb-channel bindings                        # show the binding table
~/.local/bin/bb-channel contacts / set-contact <address> <name>
~/.local/bin/bb-channel webhook [--url URL]             # check/self-register the webhook
~/.local/bin/bb-channel ping / configure                # connectivity / write ~/.dsh/.env
  • Output is always pretty JSON (jq-friendly); errors go to stderr with exit 1.
  • Credential chain matches the plugin: process.env → ~/.dsh/.env → ~/.zshenv; nothing to fill in by hand.
  • The CLI edits ~/.dsh/bluebubbles-bindings.json / bluebubbles-contacts.json directly; the plugin hot re-reads both files before every inbound message — edits take effect immediately, no reload.

Push path (webhook)

BlueBubbles server (new message)
   │  POST {type:"new-message", data:{...}}
   ▼
DSH webServer route  /bluebubbles/webhook  (loopback only)
   │  hot re-read bindings/contacts → look up chatGuid → workspacePath/sessionId
   ▼
workspace.sessionIds[0] → agents.get(sessionId).send(userMessage, 'next-step', true)
   ▼
The workspace's model wakes up and sees a message annotated
"📱 iMessage · <chat name> · 来自 <name> (<number>)"

Anti-loop (two layers, v22+):

  1. pendingSent queue: the plugin records (chatGuid, normalized text) before every send; webhook echoes with isFromMe=true matching an entry are dropped (60s TTL, unicode NFC-normalized comparison);
  2. seenGuids: after a successful send the real guid returned by the API joins a dedup set (BlueBubbles occasionally pushes the same event twice — second-layer backstop).

A blanket isFromMe drop is not an option: phones on the same Apple ID also produce isFromMe=true in a self-chat DM, and dropping all of them would kill real user messages.

Sender display name: payload.handle.displayName → ~/.dsh/bluebubbles-contacts.json (address→name, maintained via bb-channel set-contact) → bare number.

Relay auto-delivery (same mode for inbound and cron)

With relay: true on a binding, the bridge registers a reply trigger for the woken session (persisted to bluebubbles-relay-state.json, 10min TTL, cleared on turn/end; an exact NO_REPLY reply suppresses delivery). During that turn, every assistant message containing text parts is sent back to the chat immediately — thinking and tool results are never delivered.

When dsh-cron fires a job whose target session has a relay: true binding, it arms the same mechanism through the bluebubbles service's armRelay. Cron task prompts must not tell the model to call send tools itself — that would double-send.

Configuration

Credentials

MethodTakes effect
bb-channel configure --password <pw> (writes ~/.dsh/.env)after DSH restart or bridge reload
env var BLUEBUBBLES_PASSWORD (optionally BLUEBUBBLES_BASE_URL)after DSH restart

Never put DSH_-prefixed variables in .env — the DSH bootstrap refuses to start. That is why heartbeat/cron config keys are HEARTBEAT_INTERVAL / HEARTBEAT_TARGETS / CRON_JOBS.

State files ($DSH_HOME, default ~/.dsh)

PathContentWriter
bluebubbles-bindings.json{ "chat:<guid>": { workspacePath | sessionId } }bb-channel bind/unbind
bluebubbles-contacts.json{ "address": "display name" }bb-channel set-contact
bluebubbles-media/inbound attachments (<guid>-<filename>)bridge auto-download
heartbeat-targets.jsonheartbeat targetshand-edited
cron-jobs.jsoncron jobshand-edited

Session resolution chain: sessionId direct → otherwise workspacePath → that workspace's sessionIds[0] (most recent session) → verify a live agent. With no live agent the message is dropped and logged (no fallback, no queue).

Updating the code

  1. Edit src/*.ts → npm run typecheck → git commit
  2. In ~/.dsh/profiles/web/cordis.patch.yml, bump the corresponding row's ?v=N by 1 and save
  3. In-process HMR does not reliably hot-replace the bridge module (stale fiber routes survive), so restarting DSH is the reliable load path; verify the version marker with curl -X POST -d '{}' http://127.0.0.1:3080/bluebubbles/webhook (ok-vN).

Diagnostics

With BLUEBUBBLES_DEBUG=1 (env or .env), inbound events and drop reasons go to ~/.dsh/bluebubbles-debug.log (serialized appends, no lost lines).

Security

  • The webhook route only accepts loopback sources; BlueBubbles webhooks have no signing mechanism.
  • Injected content is plain text messages and triggers no tools; outbound sends always happen through explicit model tool calls.
  • Neither the repository nor the patch file contains credentials.

Installation

As a profile bundle (consumers):

dsh plugin --profile web add github:vINyLogY/dsh-bluebubbles

dsh plugin add forwards to pnpm and, because this package declares dsh.bundle.patch, automatically joins the profile's bundle stack — the shipped cordis.patch.yml inserts rows for all three plugins (bluebubbles-bridge, dsh-heartbeat, dsh-cron, resolved through the package exports map). A DSH restart loads them. The bb-channel CLI lands on the profile's node_modules/.bin via the package bin entry.

For local development, insert absolute-path rows with a ?v=N cache-buster into the profile's own cordis.patch.yml instead (see below).

Tech stack

  • TypeScript (erasable syntax only), types from @deepseek-ai/dsh-* devDeps (0.1.0-rc.7 / cordis 4.0.1).
  • Zero build: Node ≥ 23.6 native type stripping; composition rows point straight at src/index.ts.
  • The CLI is plain Node ESM (bin/bb-channel.mjs), zero dependencies, global fetch/FormData — deliberately .mjs so it runs on any modern Node and stays ESM wherever it is symlinked.
  • Bootstrap: npm install --cache ./.npm-cache && npm run typecheck.