dsh-companion
开发工具 活跃维护

dsh-companion

leonardoxr/dsh-companion

适配原生客户端的只读工作区与会话JSON API插件,支持拉取结构化的工作区、会话数据,只读权限保障源数据安全,部署后原生客户端可直接调用接口获取格式化内容,无需额外适配

1
Stars 标星
0
Forks 分支
1
Watchers 关注
0
Open Issues
TypeScript
主要语言
MIT
开源协议
227 KB
仓库大小
1 个月前
最后推送
一键安装扩展 / 插件指令
dsh plugin --profile web add github:leonardoxr/dsh-companion
git clone https://github.com/leonardoxr/dsh-companion.git
git clone git@github.com:leonardoxr/dsh-companion.git
README.md main

dsh-companion

English | 简体中文

CI
License: MIT

A small DeepSeek Harness plugin that gives native clients a read-only JSON view of DSH workspaces and live sessions, a configurable notification event feed, and a Web settings card.

It is designed for client shells such as dsh-native that need project and session metadata without loading or scraping the Harness web UI.

[!IMPORTANT]
This project is not the unscoped dsh-companion package on npm. That name belongs to an unrelated project. Install this plugin from this repository or one of its GitHub Release archives.

What it provides

  • Three small, cache-free JSON endpoints for workspaces and live sessions.
  • A unified Workspace browser in the Harness left sidebar when the page runs inside DSH Native, combining local and saved-server workspaces without replacing the shell, New Session control, or Settings footer.
  • A reconnectable server-sent-event feed for native completion, failure, question, and approval alerts.
  • A Settings → Plugins → DSH Companion notifications card that filters alert kinds and subagent events at the source.
  • An optional Images tab for the dsh-better-sidebar workbench: every image in the conversation — attachments, assistant images, and images the model reads — as a clickable gallery.
  • Explicit field projection: internal Harness objects are never serialized wholesale.
  • DSH trusted-host and same-origin checks on every request.
  • An installable DSH bundle with compiled JavaScript and a small settings-schema dependency.
  • Clean unloading: all registered routes are removed with the plugin.

Install

From a GitHub Release (recommended)

Download dsh-companion-<version>.tgz from the latest release, then add it to the Web profile:

dsh plugin --profile web add ./dsh-companion-<version>.tgz
dsh web

Each release also includes SHA256SUMS.txt so the archive can be verified before installation.

Directly from GitHub

For the newest revision on main:

dsh plugin --profile web add github:leonardoxr/dsh-companion
dsh web

A local checkout can be linked in place while developing:

dsh plugin --profile web add /absolute/path/to/dsh-companion
dsh web

Verify the plugin after DSH starts:

curl http://127.0.0.1:3080/api/companion/workspaces

DSH Native workspace sidebar

DSH Native exposes a read-only, origin-checked workspace bridge to its managed local DSH page and saved DSH servers. When that bridge is present, Companion shadows only the core sidebar.workspaces region with the same cross-server Workspace model used by Native's Workspace Home. The normal Harness Workspace browser remains unchanged in ordinary browsers and automatically returns if Companion unloads.

Workspace rows show their owning server and Session counts. Current-server Session rows open directly; choosing a Workspace or Session owned by another saved server switches DSH Native to that server. No host-management, filesystem, credential, or arbitrary IPC capability is exposed to page scripts.

API

Route Response
GET /api/companion/workspaces { workspaces: [...] } — durable workspaces and their member session IDs
GET /api/companion/sessions { sessions: [...] } — live sessions and their latest folded titles
GET /api/companion/session/<id> One live-session summary, or a JSON 404
GET /api/companion/notifications text/event-stream feed of configured native alerts

Example session-list response:

{
  "sessions": [
    {
      "id": "session-1",
      "title": "Implement native navigation",
      "cwd": "/work/dsh-native",
      "createdAt": 1787356800000
    }
  ]
}

JSON responses use Content-Type: application/json and all routes use Cache-Control: no-store. The notification route uses SSE, emits 15-second heartbeats, accepts a prior cursor in Last-Event-ID or ?since=, and keeps a bounded in-memory replay window. A fresh connection starts at the live tail but receives interactions that are still waiting for a question answer or approval. Non-GET requests return 405.

Notification settings

Open Settings → Plugins → DSH Companion notifications in the Harness Web UI to configure:

Setting Default Alert
completed on Successful turn/end events
blocked on Blocked turns
errors on Failed turns and live agent errors
maxTokens on Turns that reach the output-token limit
aborted off Cancelled or aborted turns
questions on Pending ask_user_question interactions
approvals on Pending tool approvals
subagents off Include events from sessions marked as subagents

Changes are persisted through the Harness settings service and apply immediately to subsequent events without restarting the companion feed. Reset defaults clears the user overrides and restores the values above.

Each notification payload is versioned and contains only a stable key, kind, session ID/title, short body, and timestamp. Raw messages, tool arguments, commands, icons, and click-through URLs are never forwarded.

Images tab (optional)

When dsh-better-sidebar is installed, the client plugin registers an Images tab in its + menu. It scans the current session's folded timeline for durable image references — user attachments, assistant image blocks, and image blocks inside tool results (for example a read_image tool output) — resolves them through the Harness session attachment route, and renders them as a thumbnail gallery with a full-size lightbox.

The integration is a soft dependency:

  • Without better-sidebar, nothing changes — no tab, no styles, no host routes.
  • The client never imports better-sidebar code; it restates the small registration contract locally, so either plugin can load, unload, or hot-reload independently.
  • Images are fetched lazily while the tab is visible and cached as object URLs for the lifetime of the view.

Security model

The endpoints expose workspace paths, session IDs, titles, timestamps, session lineage, and—when enabled—short question, approval, and error text. They enforce the Harness web runtime's trustedHosts policy and reject cross-site browser requests, but this is a network trust boundary, not user authentication.

Do not expose the DSH server to networks whose clients should not read that metadata. See SECURITY.md for private vulnerability reporting.

How it works

The package is a Cordis host module with name, Config, inject, and apply exports plus a small Web client plugin. The host declares webServer, webRuntime, apiProxy, settings, sessions, sessionTitle, and workspaceRegistry as required services, registers a durable notification-settings namespace, then consumes the existing event streams when the bundle loads.

The host entry point is emitted to dist/index.js; the settings card is bundled to client/client.js and injected into the standard plugin-settings slot. Unloading or reconfiguring the host plugin aborts event subscriptions, closes SSE clients, and removes every route.

Compatibility

DeepSeek Harness is currently in developer preview, so its plugin service contracts may change. This version targets the service contracts in the DSH 0.1.1 release-candidate line and requires Node.js 22 or newer. CI covers Node.js 22 and 24.

Development

npm ci
npm test
npm pack --dry-run

npm test rebuilds dist/ before running tests against the compiled entry point. The committed dist/ directory is intentional: GitHub dependencies are installed under node_modules, where Node does not strip TypeScript syntax at runtime.

If a source change alters generated output, include the updated dist/ files in the same pull request.

Contributing and releases

Contributions are welcome. Read CONTRIBUTING.md for the local workflow and pull-request expectations, and follow the Code of Conduct.

Successful CI runs publish a short-lived, installable package artifact. Version tags such as v0.1.1 publish the same compiled .tgz plus its checksum as a permanent GitHub Release. Maintainers can follow docs/RELEASING.md.

License

MIT