deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
PROJECT README
English: A local service control deck for DeepSeek Harness. One global registry (
~/.dsh/service-registry.json) arbitrates ports across all your projects; the Web UI gains a sidebar "服务" button with a floating panel for one-click start / stop / restart per service, expandable logs, and a "current project" tab that auto-follows the session you have selected (no manual workspace picking; new projects are auto-detected and registered). The same engine is exposed as 7 agent tools (service_list / detect / register / start / stop / restart / status), so the agent never guesses start commands again.Install (persistent profile bundle, per the official DSH plugin spec —
dsh.bundle.patch+dsh.client):dsh plugin --profile web add github:realpkuasule/dsh-launch-pad # then restart DSH and hard-refresh the pagePackage name:
dsh-launch-pad(与仓库同名)。 Source of the plugin package:./.
统一的本地服务管理方案:任何项目类型的启动命令归一化 + 全局 registry 防端口冲突 + DSH 界面一键启动/停止/重启 + agent 工具双通道 + 自动跟随会话自动登记。
解决痛点:每个项目启动命令不一样、agent 靠猜命令给出错误信息、多个服务互相端口冲突、人工启动要记路径和命令、每次切换项目都要手动探测登记。
| 组成 | 形态 | 状态 |
|---|---|---|
| 插件(Host + Client) | 持久化 profile bundle:~/.dsh/profiles/web 的 dsh.profile.bundles 里有 dsh-launch-pad,link 到本仓库根 dsh-launch-pad/ |
✅ DSH 每次启动自动加载 |
| SKILL.md | ~/.agents/skills/service-deck/SKILL.md |
✅ 已安装,本仓库 skill/ 有副本 |
| registry / 日志 | ~/.dsh/service-registry.json、~/.dsh/services/logs/ |
持久,跨重启保留 |
.
├── README.md ← 本文件(双语)
├── package.json ← ★ 插件包即仓库根(包名 dsh-launch-pad,官方 git 安装要求包在仓库根)
├── cordis.patch.yml ← bundle 行声明(- insert: id/name)
├── LICENSE ← MIT
├── lib/
│ ├── index.js ← Host:registry/进程/端口仲裁/探测/自动跟随/HTTP RPC/tools
│ └── client.js ← Client:侧边栏按钮 + 悬浮面板(ModuleLoader factory + fetch RPC)
├── plugin/ ← 动态插件备选载荷(无 profile 环境时用 cordis_define 粘贴)
│ ├── host.js
│ └── client.js
├── skill/SKILL.md ← agent 行为规范(与已安装副本一致)
└── .dsh-services.yml.example ← 项目内配置示例
# 本地开发安装(已执行)
dsh plugin --profile web add link:/Users/zhichao/DSH/dsh-launch-pad
# 从 GitHub 安装(规范安装方式)
dsh plugin --profile web add github:realpkuasule/dsh-launch-pad
# 源码改动后重装(link 安装改源码即可,无需重装;改 package.json 结构才需重跑)
# 然后重启 DSH 生效
dsh plugin add 会自动把包名写入 ~/.dsh/profiles/web/package.json 的 dependencies 和 dsh.profile.bundles。验证装载:dsh --profile web --dump-config | grep -A2 dsh-launch-pad。
.dsh-services.yml(权威)> package.json(dev>start>serve,自动识别 npm/pnpm/yarn/bun)> docker-compose.yml > Makefile > justfile > manage.py/pyproject.toml(django/fastapi/flask)> go.mod~/.dsh/service-registry.json,跨所有项目共享,同 (projectPath, name) upsertportMode=auto 冲突时自动分配最近空闲端口并按模板注入(--port N / PORT=N / uvicorn / next / flask / django 专用写法);portMode=fixed 冲突报错service_list/detect/register/start/stop/restart/status)useSessions 钩子的 state.current),每 3 秒上报 Host 解析为项目目录——点选即跟随,无需打字,且不受后台会话事件洪流干扰;agent/created 与 user/message 事件仅作面板未打开时的兜底~/.dsh/services/logs/<id>.log,面板展开可见滚动尾部{
"version": 1,
"services": [
{
"id": "myapp:web", // basename(projectPath):name,冲突自动加 -2
"name": "web",
"projectPath": "/abs/path",
"command": "npm run dev",
"cwd": ".",
"port": 5173, // 期望端口
"portMode": "auto", // auto | fixed
"persist": true,
"template": "npm", // npm|uvicorn|django|flask|docker|make|just|go|custom
"env": {},
"pid": 12345, // 运行时字段
"actualPort": 5173,
"startedAt": 1720000000000
}
]
}
services:
web:
command: npm run dev
cwd: .
port: 5173
portMode: auto
persist: true
template: npm
env:
FOO: bar
POST /service-deck/rpc,header 带 per-process 随机 token(Host 通过 webServer.tapIndex 注入 window.__DSH_SERVICE_DECK_TOKEN__,与 dsh-archive-panel 同款 loopback 守卫)window.__ModuleLoader__.load({ id: 'dsh-launch-pad', factory }) 工厂格式,require('react'),注入 ['slots','timer']ctx.tools.register,parameters 为原始 JSON Schema 子集(type/properties/required/additionalProperties/items/enum/const + description/title/default/examples 注释键;type:'json' 在原始 schema 中非法,宽松输出用空对象 {})useSessions((state) => state.current) 选中的会话 id(最高优先级,随每次 list 轮询上报);兜底为 agent/created 与 user/message 事件(面板未打开时)shell.run 永不返回 → spawn 配方必须加 < /dev/null(实测返回 0.002s)nohup cmd & 的 $!(外层 bash 子壳)与实际服务进程分属不同进程组,kill -TERM -$! 杀不净 → 停止改为「stored pid + 端口监听者 + 递归 pgrep -P 子进程」三路目标useWorkspaces((s) => ...));shell.overlay 无 hook 上下文 → 钩子改在 sidebar.footer.action 的 Trigger 里调用,经模块级状态共享给面板harness.handle/defineTool 是沙箱专用;真实插件用 ctx.webServer.register + token 路由和 ctx.tools.register(原始 JSON Schema,type:'json' 非法,宽松 schema 用 {})shell.run 的 stdout/stderr 是 {text, truncated} 结构,取 .textsession/event 的 assistant/chunk 洪流 + 后台会话注入的 user/message 会让"最后事件赢"永远落在噪声会话上 → 改为客户端上报 UI 选中的会话 id(state.current),事件只作兜底;session/event 事件参数里混有 Scoped 包装体,读 .header 会扑空,需按 id 查 sessions 存储取真实 Session${变量} 形式的 compose 端口解析为 nullpnpm --filter apps/web dev)需手写 .dsh-services.yml 或让 agent 用 service_register 登记PORT 环境变量,个别工具不认时需把 --port 写进 commandpython3(setsid 包装)、lsof、pgrep(macOS/Linux 均有);Windows 未适配CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。