dsh-project-panel
Deepseek Harness 插件
- Stars
- 0
- Language
- JavaScript
- Created
- Oct 7, 2026
- Updated
- Oct 11, 2026
Introduction
dsh-project-panel · 工程面板
DeepSeek Harness Web 端的低代码工程面板:把 MagicalCoder 风格的工程目录搬进会话侧栏 —— 文件树、推送状态、源码编辑、推送前校验、工程脚本,一处看全。
MagicalCoder 风格的工程是一套约定目录:页面由 page.json + index.html + page.js 三件套组成,接口是 meta.json,工程脚本叫 source-*.js,页面里必须有 magicalDragScene 容器,调平台接口要走 /magical_lowcode/ 前缀……这些约定在普通编辑器里全靠记性和手工核对。
这个插件把它们变成看得见、点得动的东西。
- 看得见的工程树 —— 一层目录一层文件,就地读写、改名、移动、删除
- 推送状态账本 —— 哪些页面 / 接口已经同步到平台,哪些改过还没同步
- 推送前静态校验 —— 把踩过的坑变成规则,推之前先跑一遍
- 源码页签 —— 树里点一下就开,带高亮和多标签,改完直接写回
- 工程脚本入口 —— 工作区根目录下那批
source-*.js,在面板里点着跑 - 空白目录也能开局 —— 服务器地址 / 账号 / 项目由面板维护,不依赖工作区里事先有
.env
一、安装
从插件市场装(推荐):
在 DSH 插件市场里搜「工程面板」或 dsh-project-panel
命令行装:
dsh plugin --profile web add github:lzqzm/dsh-project-panel
本地开发(link: 安装,装的是你正在改的那份源码):
dsh plugin --profile web add D:\path\to\dsh-project-panel
装完重启 dsh web。
改了代码怎么生效
| 改了哪 | 要做什么 |
|---|---|
lib/client.js | 刷新页面 |
lib/index.js(host 半边) | 重启 dsh web |
src/editor.js | npm run build:editor,再刷新页面 |
二、入口在哪
先打开一个工作区的会话然后点击左侧栏底部的 「工程」 按钮,或者右侧栏的 工程 页签。打开后占用中栏,会话与输入框保持原样。
面板顶部是搜索框,下面四个页签:
| 页签 | 干什么 |
|---|---|
| 文件树 | 工程目录的总览 + 推送状态 |
| 源码 | 打开的文件,多标签,可编辑 |
| 校验 | 推送前静态校验的结果清单 |
| 脚本 | 连接配置 + 工程脚本的运行面板 |
三、文件树
徽章怎么读
目录和文件右侧的小标:
| 徽章 | 意思 |
|---|---|
✔ 已推送 | 内容和平台上的一致 |
● 待推送 | 本地改过,还没同步到平台 |
✗ 定位不到 | 这个目录既没有 page.json 的 uuid、也没有 meta.json 的 id,入不了账 |
校验 ✗3 | 这一片有 3 个错误(警告不占徽章,去「校验」页签看) |
推送状态是账本:登记每个页面 / 接口在你上次推送时各文件的 mtime,之后 mtime 变了就算「改过」。所以:
- 徽章回答的是「本地有没有平台上还没有的改动」;
- 从服务器拉取之后,插件会把这一片的账删掉再重扫 —— 内容刚和服务器对齐,不该显示成待推送。
右键菜单
在树里任意一行点右键:
| 菜单项 | 作用 |
|---|---|
| 📄 新建文件 / 📁 新建文件夹 | 在当前位置新建(新建页面类目录会自动带模板) |
| 🔗 引用 | 把该文件的 @ 引用插进输入框 |
| 🔍 推送前校验 | 对这一片跑静态校验,结果落到「校验」页签 |
| ✏ 重命名 / 📦 移动到… / 🗑 删除 | 常规文件操作(只动磁盘,不改 page.json / meta.json) |
| 🏷 修改备注 | 只在工作区根那层的项目目录上出现,代替「重命名」(见下) |
| ⬆️ 推送这个页面 / ⬇️ 拉取这个页面 | 只跑这一个单元 |
| ✅ 标记已推送 | 手工记账,不改文件 |
| 🔄 刷新推送状态 | 只重扫,不重算账 |
| ♻️ 重置推送状态 | 把整个工作区的账本清掉,下次扫描全部重新登记 |
| ✔️ 确认推送 / ✖️ 取消 | 这条单元正有别的任务在跑,先确认要走哪一步 |
推一个目录 = 连里面的子页面一起推。 平台的
source-page-push.js拿到目录 uuid 时走的是「推该目录及目录下的所有页面」。所以推完目录,插件会把整棵子树的账一起更新 —— 不会出现「父目录绿了、子页面还挂着待推送」。
工作区根那层的 uuid 目录不给「重命名」。 那个目录名就是项目在服务器上的 uuid(32 位十六进制),推送 / 拉取靠它认项目,改掉就对不上号了。这一层改成右键修改备注(或按 F2):填过的备注显示在文件树里,和「脚本」页签的项目下拉用同一份(挂在服务器档案的项目清单上)。留空 = 清空备注,这一层显示回 uuid。真实 uuid 想确认时把鼠标停在那一行上,提示里就是完整路径。
没选服务器档案时这项是灰的 —— 备注挂在档案名下,没档案就没处放。
项目目录里的结构层(
apis/databases/pages,以及databases底下的库和表)也不给重命名。 这几个名字是平台认的,改了推送 / 拉取就对不上号。这一层右键里的「重命名」是灰的,鼠标停上去会说明原因;apis和pages里面的接口目录、页面目录不受影响 —— 它们的身份记在meta.json的id/page.json的uuid上,目录名只是显示用的。
点项目页面里的
index.html是去平台看,不在面板里渲染。 本地这份index.html只是平台导出的镜像,mc-*/el-*那些组件在这儿跑不起来。点这一行,会在新标签页打开平台自己的预览页:<服务器>/youyaboot-admin/magicalcoder/editor/publish.html?pid=<项目 uuid>&id=<页面 uuid>。 地址取工作区.env的SERVER_URL,没有就退回当前服务器档案填的那个。想看代码照样点行尾的 源码;page.css/page.js不受影响,还是本地看。开过去之前插件会替你在浏览器里登录一次平台,这样新标签里是预览页而不是登录页。
这里有个容易踩的坑:平台有三套登录接口,谁都换不来谁 —— 设计器登录(
server/web/login,拉取 / 推送脚本在用)、后台管理登录(manager/web/login,要租户名)、以及预览页认的那套(web_user/login)。三者下发的 cookie 同名,后登的顶掉先登的,所以只能登对的那一条。插件登的就是预览页认的那条,凭据用设计器账号优先、后台账号兜底(两套实测都能过;设计器账号必填,后台那套可以以后补)。两套都没填时点头会提示你去补,插件不会替你猜。会话按服务器算:同一台服务器登过一次,之后点它下面任何项目的
index.html都直接进,不会再登;换一台服务器就各登各的 —— 凭据取当前工作区绑的那个档案,cookie 也按域存,互不顶替。平台的登录 cookie 30 分钟过期:过了半小时再点,插件会重新替你登一次;30 分钟内连点几个页面只登第一次。但浏览器要是不肯收插件的跨站 cookie(Chrome 的「阻止第三方 Cookie」等),这次自动登录就白登 —— 预览页会自己跳平台登录页,在那儿登一次即可,之后 30 分钟内照样畅通。
代价是这一次请求会把密码经过页面一遍(用完即弃,插件自己不存)。后台那套收在「脚本」页签的服务器档案里:点档案的**「编辑」**,表单最后三行是「后台租户」/「后台账号」/「后台密码」。
后台登录(脚本调业务接口用的那条)还要一个租户名,留空就是平台约定的
admin。要连别的租户,填档案里的「后台租户」;也可以在工作区.env里加一行TENANT_NAME=<租户名>(档案里填了就以档案为准,admin这个默认值是平台约定、不是谁的凭据)。
键盘
树里有键盘导航:上下移动、左右展开收起、回车打开。首屏如果一直「读取中」,点一下「刷新」。
四、源码
树里右键文件名选择查看源码,或者点行尾的 源码 按钮,就在「源码」页签里打开(多标签常驻)。用 CodeMirror 6,按扩展名选语言高亮。改完 Ctrl+S(或点写回)保存,写回后自动重扫这一片的校验与推送状态。
五、校验
「校验」页签列出推送前静态校验的结果,按文件分组,点一条直接跳到源码页签的对应行。
规则是踩过的坑固化的(V1.01 ~ V1.06 那一批):js-syntax、css-brace、attr-mustache、sys-zone-modified、uuid-missing、no-scene、bare-mustache、api-url、no-merge-loop、no-return。
分级:
- error —— 会占树上的徽章(
✗N),因为平台真的会因此出问题; - warn —— 只在页签里列,不占徽章。比如
no-return(接口脚本里return '成功'平台其实能吃),一个真实工程里能有一千多条,标出来只会让人学会忽略徽章。
六、脚本
工作区根目录下那一层的 source-*.js 会被列成卡片,点「运行」就跑(用 DSH 自己的 node,不依赖系统 PATH)。
内置认识的七个,其中三个「整片推送」的入口默认不摆到面板上:
| 脚本 | 说明 | 面板 |
|---|---|---|
source-push.js | 推送整个项目 | 已隐藏 |
source-api-push.js | 推送全部接口 | 已隐藏 |
source-page-push.js | 推送全部页面 | 已隐藏 |
source-clone.js | 克隆整个项目 | 显示 |
source-api-pull.js | 拉取全部接口 | 显示 |
source-page-pull.js | 拉取全部页面 | 显示 |
source-db-pull.js | 拉取数据库 | 显示 |
收起来的就是「一整片推上去」那几个按钮 —— 动静太大,误点一次不好收场。单个页面 / 接口的推送不受影响,走文件树右键菜单的「推送这个页面」即可。脚本本身照样躺在工作区根目录下,真要全量推的时候开个终端 node source-push.js 手动跑就行。
不认识的 source-*.js 也会列出来(标「未登记」),一样能跑。
外网地址一律二次确认
.env 里的 SERVER_URL 只要不是本机,推送和拉取都要先确认一次:
拉取看着「只是把东西取回来」,实际是拿服务器上的状态覆盖本地文件;
source-clone.js还会一路建目录。破坏性和推送一个级别。
判据是真实主机名,不是某个「环境名」。面板里没有本地 / 线上的环境之分 —— 一条 ENV=local 配一个外网地址,脚本照样往外面推,按环境名判断只会更危险。
跑起来之后下面是输出控制台,可以随时「停止」(Windows 上连子孙进程一起杀)。推送动辄几分钟,所以是「起进程 + 增量取输出」,不是干等。
连接配置(页签顶部那一块)
服务器地址 / 账号 / 密码由面板维护,不要求工作区里事先有 .env:
| 按钮 | 作用 |
|---|---|
| 新建档案 | 存一个「服务器」(名称 / 地址 / 设计器账号 / 设计器密码 / 后台租户 / 后台账号 / 后台密码) |
| 铺脚手架 | 把插件自带的 source-*.js / utils.js / package.json 和三份说明(AGENTS.md / project-rules.md / help.md)铺到当前目录 |
| 写入 .env | 把选中的档案合并写进工作区的 .env |
| 装依赖 | 装模板要用的 npm 包(只在缺的时候出现) |
一个档案里有两套账号密码,别混(平台那边其实是三套登录接口,这儿能维护的是其中两套):
- 设计器账号 / 设计器密码 —— 写进工作区
.env的USERNAME/PASSWORD。①scaffold/source-*.js拉取 / 推送用它登录;② 点index.html去平台预览页之前,插件在浏览器里替你做的那次登录优先用它(两套账号实测都能过那条接口,而它必填)。也是「这个工作区对应谁」的凭据。 - 后台账号 / 后台密码 —— ① 预览页那次登录的兜底(设计器账号没填时才用);② 脚本调 openapi / crud / local-export 这类业务接口时,只有后台会话认。写进
.env的ADMIN_USERNAME/ADMIN_PASSWORD/ADMIN_TENANT/ADMIN_LOGIN_PID。旁边的后台租户是登录时的租户名,留空即admin(平台约定),一般的库不用填。
后台密码为什么会落进
.env:平台把「项目包同步」和「业务接口」拆成了两套鉴权,后者只认后台会话。若只在跑脚本时注入环境变量、不落盘,你在终端手动node source-*.js就会悄悄退回设计器登录,表现是登录明明成功、接口却报「请重新登录」 —— 这种半好不坏的状态最难查。所以宁可多落一处盘(.env,project-env-backups的备份里也会带上)。设计器密码本来就是同样待遇。
下面那行写着当前 .env 的现状(地址 / 账号 / 密码 / 项目)。.env 里的地址和选中档案对不上时,「写入 .env」会变红提醒。
项目清单也能手动维护:选好服务器后点「+ 项目」录一条(uuid + 名字),选中的那条可以「改名」「删除」。清单挂在服务器档案上,不挂文件树 —— 同一个服务器下的项目是同一批。另外 .env 注释里那批项目 uuid 会被自动捡出来当候选,两边在界面上合并显示。
全局开发规范(给 AI 看的)
除了往工作区里铺那三份说明,插件还能把一份全局版装到 <DSH_HOME>/AGENTS.md:
| 按钮 | 作用 |
|---|---|
| 安装 | 把插件自带的低代码平台规范装成全局指令。文件已存在就一个字节都不动,只说一句「已经存在,没有覆盖它」 |
| 移除 | 只删内容与插件模板逐字节相同的那一份;用户改过、或本来就是用户自己的内容,就不动 |
为什么需要它:低代码工程的工作区往往没有 .git,dsh-agent-instructions 一路向上找不到项目根,会把「会话工作目录」当成项目根 —— 项目根于是落在某个 <projectUuid>/ 子目录上,铺在工作区根的那份 AGENTS.md 反而读不到。装在 DSH_HOME 下的这份是每个会话的注入基线,与工作目录在哪论关。
文件树页签顶上,没装的时候会挂一条提示条,点「安装」即可。
七、空白目录从零开局
新建一个空文件夹、注册成工作区,然后:
- 新建档案 —— 填服务器地址 / 设计器账号 / 设计器密码(后台租户 / 后台账号 / 后台密码可以以后补,什么时候点
index.html什么时候提示你) - 铺脚手架 —— 把模板脚本铺进来(已存在的文件不会被改动)
- 写入 .env —— 落盘;原来没有
.env就新建一个 - 装依赖 —— 装
axios/archiver/form-data/unzipper
之后脚本卡片就长出来了,选个项目点「克隆整个项目」即可。
依赖只装一次,装在插件自己目录里,跑脚本时用 NODE_PATH 复用 —— 不必给每个新目录各来一次 npm install。目标目录自带 node_modules 时优先用它。
八、数据存在哪
| 路径 | 内容 |
|---|---|
<DSH_HOME>/project-config.json | 服务器档案(含密码明文)、每个工作区绑定的服务器与项目 |
<DSH_HOME>/project-push-state.json | 推送状态账本 |
<DSH_HOME>/project-env-backups/ | 写 .env 前的备份,只留最近 10 份 |
<DSH_HOME>/AGENTS.md | 全局开发规范(点「安装」才会创建;已存在则不动) |
DSH_HOME 默认是 ~/.dsh,可用环境变量覆盖。
写 .env 有两条规矩:注释行一行不动(平台爱把备选项目、备选地址注释着堆在同一份文件里,那是用户唯一的人肉清单),内容没变化就一个字节都不碰(否则跑一次脚本留一份一模一样的备份,10 份上限很快被垃圾挤满)。
面板的能力边界:所有带路径参数的 RPC 都要求路径落在已注册的工作区内,否则拒掉;跑脚本时只认工作区根目录下那一层的 source-[a-z0-9-]+\.js。全局规范那两个 RPC 是例外 —— 它读写的是 <DSH_HOME>/AGENTS.md,跟工作区论关,也没有路径参数可传。
九、更新插件
从市场装的(github: 源):市场会比对「已安装的 commit」和「仓库 HEAD」,有新的就出现更新按钮,点一下重跑安装,不用卸载重装。
本地 link: 装的:市场不会给更新入口(设计如此:link: 是开发工作区,永远不参与在线更新)。但你也不需要 —— 装的就是你正在改的那份源码,改完刷新页面(client)或重启 dsh web(host)即可。
所以:想用「市场一键更新」,就用仓库地址装;想改代码即时生效,就用本地路径装。
十、常见问题
树上一片全变「待推送」了 账本记的是本地文件 mtime。删掉目录再从服务器拉回来,文件全是新写的、mtime 全新,旧记录自然条条对不上。现在拉取类脚本跑完会自动把对应分区的账清掉重扫;如果之前留下的脏状态还在,右键「重置推送状态」再刷新一次。
推了父目录,子页面还显示待推送 已经修了:推一个目录会把整棵子树的账一起更新。如果徽章还是旧的,右键「刷新推送状态」。
首屏一直「读取中」 点「刷新」。扫描有 mtime 快照缓存,第二次进同一目录会快很多。
目录上是 ✗ 定位不到
这个目录里既没有 page.json(要 uuid)也没有 meta.json(要 id),账本认不出它是谁。多半是新建了目录还没建页面。
.env 里的 ENV 是什么
只决定脚本打印什么文案,不决定请求打到哪里。面板里没有这一项,恒写 local;真正连哪个地址看 SERVER_URL。
点 index.html 提示「登录失败:用户名或密码错误」
先看档案里的账号密码对不对(预览页那次登录用设计器账号,没填就用后台账号)。注意平台有三套登录接口,互相换不来 —— 拿设计器账号去登后台那条、或反过来,都会得到「用户名或密码错误」,早期版本的插件正是登错了接口,症状就是「密码明明没错却进不去」。真正的密码错误当然也有可能;改了档案以后记得重启 dsh web,浏览器端登录这一步走的是 host 半边。
点 index.html 打开的平台页面报「登录信息已超时,请重新登录」
预览页认的是第三套登录(web_user/login),跟后台管理、设计器那两套都换不来 —— 以前插件登的是后台那条,所以怎么都进不去,这是插件自己的 bug。若升级后还出现,先刷新页面、重启 dsh web,再确认档案里的账号密码对不对。
如果登录接口明明回了成功、预览页还是这句话,那是浏览器把平台的 cookie 丢了(Chrome 的「阻止第三方 Cookie」等策略会拦下跨站 fetch 收到的 Set-Cookie)。插件没法分辨这一种:平台的 SESSION 带 SameSite=Lax,插件页面发的请求都是跨站,这个 cookie 本来就带不出来,所以「查一下会话在不在」得到的「没会话」既可能是真的、也可能只是带不出来。插件的做法是:查一次(命中就省掉登录)→ 未命中就登一次 → 无论成败都把预览页开出来,让平台自己判断 —— 会话在就直接进;不在,预览页会自己跳平台登录页(webuser/index.html?from=…),在那儿登一次,登完跳回预览页,之后 30 分钟内都畅通。
想让它全自动,得让平台和插件页同站:
SameSite=Lax看的是站点(eTLD+1)而不是端口,所以dsh web也走平台那台机器的域名 / IP(例如同域反代到:3080)时,插件的请求就成了同站请求,cookie 照带,登录、判断、预览页全自动。用127.0.0.1:3080访问做不到这一点。
这一整段的前因后果(为什么手动登行、自动登不行,以及三套登录接口各自认谁)整理成了独立文档:平台预览页登录说明.md。
脚本登录明明成功,接口却报「请重新登录」
说明这次用的是设计器会话。业务接口(openapi / crud / local-export)只认后台会话:去服务器档案里补上后台账号 / 后台密码,再点一次「写入 .env」,.env 里应当出现 ADMIN_USERNAME / ADMIN_PASSWORD 等四个键。终端手动 node source-*.js 也一样要看这四个键。
脚本打印的服务器地址是 (undefined),USERNAME 变成了 Windows 账户名
.env 的换行是 CRLF(Windows 记事本默认),旧版解析会整行匹配失败、所有值退化成 undefined,而 USERNAME 会掉进 Windows 自己的同名环境变量。已修(现在自动剥 BOM、兼容 CRLF);工作区里的 utils.js 若还是旧的,重新点一次「铺脚手架」。
十一、开发
dsh-project-panel/
package.json 依赖只有给脚手架用的那 4 个(axios / archiver / form-data / unzipper)
cordis.patch.yml insert: dsh-project-panel
lib/index.js host 半边:desktopProject/* RPC
lib/client.js client 半边:手写 ESM,改了刷新即生效
lib/client.editor.js ⚠ 构建产物(CodeMirror 6)—— 不要手改
src/editor.js 编辑器分片的源码,npm run build:editor 生成上面那个
scaffold/ 自带的工程脚本模板 + 规范说明(source-*.js / utils.js / package.json / AGENTS.md / AGENTS.global.md / project-rules.md / help.md)
NOTES.md 开发笔记:每个设计决定和踩过的坑
npm run build:editor # 重新打包编辑器分片
npm run watch:editor # 边改边打
link: 安装不装传递依赖,所以两个半边都不许 import 第三方包,也不许 import @deepseek-ai/*(Node 从插件真实路径向上解析,够不到 profile/node_modules)。顶层 import 失败会打挂整个 profile。
设计取舍、性能数字、验证手法都记在 NOTES.md。
License
MIT