← Back to home@lzqzm

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.jsnpm 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 下的这份是每个会话的注入基线,与工作目录在哪论关。

文件树页签顶上,没装的时候会挂一条提示条,点「安装」即可。


七、空白目录从零开局

新建一个空文件夹、注册成工作区,然后:

  1. 新建档案 —— 填服务器地址 / 设计器账号 / 设计器密码(后台租户 / 后台账号 / 后台密码可以以后补,什么时候点 index.html 什么时候提示你)
  2. 铺脚手架 —— 把模板脚本铺进来(已存在的文件不会被改动)
  3. 写入 .env —— 落盘;原来没有 .env 就新建一个
  4. 装依赖 —— 装 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