DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Web Lifecycle — DeepSeek Harness 插件(DSH Plugin)
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins
W

dsh-web-lifecycle

Web Lifecycle

DSH web 插件:侧边栏底部的“重启”和“关闭”按钮。“重启”会在同一主机和端口上重新启动 `dsh web` 服务器,使标签页自动重新连接;“关闭”会停止服务器以释放终端,然后关闭浏览器标签页。

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add github:DDA-DIGITAL/dsh-web-lifecycle#3673f12bbf2e9a53d19cccad0ebe62d26780c9c1
README兼容性版本

兼容性与来源证明

Web Lifecycle 以 dsh-web-lifecycle 发布,当前版本为 0.2.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
github
Registry 更新时间
2026/9/10

版本

0.2.0stable
2026/9/10

相关插件

正在加载相关插件…

最新版
0.2.0
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
未提供
文件数
未提供
Surface
web
许可证
MIT
发布源
github
GitHub
★ 0
周下载
0
最近提交
2026/9/10
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

相关插件

继续浏览 developer-tools 分类下经过校验的插件。

Web App@deepseek-ai/dsh-web-appdsh 浏览器界面捆绑包:位于 dsh-base 之上的 Web 补丁层,加上运行时粘合插件(提供前端 dist、Web 界面提示符、bash 运行时变量和 URL 行)Sdk Minimal@deepseek-ai/dsh-sdk-minimal独立的最小 SDK 配置包:JSON-RPC、一个 DeepSeek 适配器、持久化 Shell 和 JSONL 会话Sdk App@deepseek-ai/dsh-sdk-appdsh SDK 配置包:基于 dsh-base 提供 stdio JSON-RPC 服务和进程生命周期管理Subagent Codex@deepseek-ai/dsh-subagent-codex基于官方 app-server 协议的一次性 Codex 子代理提供程序

README

dsh-web-lifecycle

A DSH web plugin that puts two buttons in the sidebar footer:

sidebar footer  →  [ ⟳ Restart ]     stop the server, bring an identical
                                      instance back on the same host/port,
                                      and reload this page
                →  [ ⏻ Shutdown ]    stop the server for good so the terminal
                                      is free, then close this tab

Both ask for confirmation first. No more switching to a terminal several times a day to restart the harness — and nothing to clean up when you are done for the night.

  • Same port, same session. A restart pins the resolved port, so the browser cookie's authority is unchanged — you stay signed in and your open session comes back after the reload.
  • Two restart transports. Works standalone (detached relaunch), and gets faster and terminal-friendly when launched through the bundled dshweb wrapper.
  • No runtime dependencies. Only Node built-ins.
  • Inert when unsupported. No webServer / no appExit → nothing mounts, the host is never affected.

Install

# from GitHub
dsh plugin --profile web add github:DDA-DIGITAL/dsh-web-lifecycle

# from a local checkout
dsh plugin --profile web add /path/to/dsh-web-lifecycle

# from npm, once published
dsh plugin --profile web add dsh-web-lifecycle

Then restart dsh web once so the host half loads, and refresh the page for the client half:

dsh --profile web --dump-config   # the row `web-lifecycle` should be listed

Restart

Launch modeWhat happens
dshweb (supervised)Exits with code 75; the wrapper relaunches in the same terminal in about a second.
plain dsh web (detached)A coordinator in its own process session outlives the dying process, waits for the port to be released, spawns an identical dsh web, health-checks it, and logs the chain to $DSH_HOME/plugins-data/dsh-web-lifecycle/restart.log.

Either way the page waits for the origin to drop, waits for it to answer, then reloads itself.

Shutdown

Shutdown exits with code 0 — deliberately not 75 — so the wrapper's relaunch condition is false and your prompt comes back:

dshweb: dsh web stopped (exit 0); supervisor exiting

No coordinator is spawned, so nothing can bring the server back. Under plain dsh web the process simply exits (it was detached, so your terminal was already free).

About closing the tab

The plugin does try to close the tab for you (window.close()), and that works when the GUI runs as an installed PWA or app window. For an ordinary browser tab it will not work: browsers only let a page close windows that a script opened, and DSH hands the URL to your OS browser, so there is no opener.

So the tab is handled in two steps: try to close, then — if it is still there — show a full-screen card that says "dsh web has stopped", retitles the tab to dsh web stopped, and reminds you to press ⌘W / Ctrl+W. There is no auto-reload on shutdown: there is nothing left to load.

The supervisor wrapper (optional, recommended)

Mode A keeps the server attached to your terminal and makes restarts ~1 second:

install -m 0755 scripts/dshweb ~/bin/dshweb     # or /usr/local/bin
dshweb                                          # same flags as `dsh web`
dshweb --port 3080

The wrapper runs dsh web in a loop and treats exit code 75 as "relaunch me". Ctrl-C still works (SIGINT exits 130, which is not 75, so the loop stops), and a Shutdown exits 0, which also stops the loop. Without the wrapper the plugin still works — it just falls back to the detached relaunch.

Configuration

Defaults live in the plugin row (cordis.patch.yml) and are re-applied by the plugin itself:

- id: web-lifecycle
  config:
    confirm: true          # show the confirmation popover before either action
    allowShutdown: true    # false hides the Shutdown row entirely
    healthTimeoutMs: 30000 # how long a detached restart waits for the new server
    logToConsole: true     # log the plugin's decisions into the dsh web log

Override the row by id in $DSH_HOME/profiles/web/cordis.patch.yml — that file is watched live, so the change applies without a restart.

What an action costs

Both actions interrupt everything the process was running: active turns, subagents, background jobs and scheduled work. Sessions themselves are durable and reopen after a restart, but anything in flight is gone — which is why the confirmation popovers are on by default. Turn them off with confirm: false if you prefer a single click.

After a shutdown, the only way back is a terminal: dshweb or dsh web.

Troubleshooting

SymptomWhat to do
The buttons are missingCheck dsh --profile web --dump-config lists web-lifecycle, then restart dsh web and refresh the page.
Overlay says "did not come back"Read $DSH_HOME/plugins-data/dsh-web-lifecycle/restart.log; it ends with the failing startup output. Start the server manually with dsh web.
Red status dotThe channel is not answering — the host half is not mounted, or the page is stale. Refresh; if it persists, restart once from the terminal.
Restart works but the tab asks you to authenticateThe port changed. Do not start the server with --port 0, and keep the wrapper's flags identical to the original invocation.
Shutdown card stays openExpected on an ordinary tab — press ⌘W. It closes by itself in a PWA/app window.
A supervisor (launchd/systemd/pm2) keeps resurrecting the serverUnsupported: shutdown stops the process, the supervisor starts it again.

How it works

  • Host half (lib/index.js) registers a prefix route on webServer at /dsh-web-lifecycle with POST /status, POST /restart and POST /shutdown. Requests pass through the host's own browser fence (connection.requestRejection: Host/Origin trust plus the signed cookie), falling back to a loopback check.
  • Browser half (lib/client.js) is served by the client-modules host at /plugins/dsh-web-lifecycle/client.js and registers one entry into the sidebar.footer.action slot. That slot's container is a flex row, so a second entry would render beside Restart rather than under it; both rows therefore live inside one entry and are stacked by the plugin's own column container.
  • Exit codes are the protocol: 75 = relaunch me, 0 = stop. Unit tests pin both, because confusing them would turn Shutdown into a Restart.

Two host quirks are worked around deliberately, both found while building this:

  1. connection.rpc.handle is unusable in @deepseek-ai/dsh 0.1.5-rc.1 — it reaches webServer through a context that never injected it, so every call throws cannot get property "webServer" without inject. Registering the route directly is exactly what the connection plugin does for its own /api route.
  2. ctx.get("connection") returns undefined on a context that never declared it, which silently downgrades the browser fence to loopback-only. The service is therefore named in the inject list and read as a property, which is the only access shape cordis permits.

Development

npm test     # node --test: config, argv planning, waits, lifecycle policy, HTTP envelope, client bundle shape
npm run check

Layout:

lib/relaunch.js       pure helpers shared by both halves (argv planning, waits, ports, exit codes)
lib/index.js          host half: route, restart/shutdown policy, coordinator spawn
lib/restart-agent.mjs detached coordinator (detached restart only)
lib/client.js         browser half: footer rows, popovers, status card, tab close
scripts/dshweb        supervisor wrapper (exit 75 = relaunch, anything else = stop)
test/                 unit tests

License

MIT — see LICENSE.

Repository: https://github.com/DDA-DIGITAL/dsh-web-lifecycle