DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

LINinLIN-0079 /

LINinLIN-0079/godot-asset-planner-public

Verified

Godot asset & project-goal management for DeepSeek Harness: godot_* model tools, /gap REST API, and a better-sidebar UI with asset manager, scene-tree viewer and Git panel. / DeepSeek Harness 的 Godot 资产与项目目标统一管理插件:godot_* 模型工具 + /gap REST 路由 + better-sidebar 界面(资产管理器 / 场景树查看器 / Git 版本控制)。

★ 1 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHubProject homepage
READMESource: main@20a81e9e

godot-asset-planner — Godot 资产与项目目标统一管理插件

一个 DSH(DeepSeek Harness)插件,把 Godot 游戏项目的资产管理与项目目标整合到同一套工具里:注册资产、创建目标、按关键词/目标查询、生成关联状态报告。数据通过 DSH 的 storage 服务持久化到本地 JSON 文件,重启后自动加载。

作者:LINinLIN-0079 · 许可证:MIT(见 LICENSE)

截图

资产管理器(资产列表 / 拖拽上传 / 搜索筛选 / 目标看板 / 预览区) | 场景树查看器(Godot 节点树实时读取与编辑) | Git 版本控制(状态 / 提交 / 分支 / 差异)

资产管理器 场景树查看器 Git 版本控制

文件结构

文件 说明
godot-asset-planner.ts 插件源码(TypeScript,运行时零依赖):4 个工具 + /gap REST 路由 + 拖拽文件上传。包主入口(main / exports["."])
lib/client.js 浏览器 half(exports["./client"]):better-sidebar 三个 tab(资产管理器 / 场景树查看器 / Git 版本控制),window.__ModuleLoader__.load 工厂格式,只 require('react')
cordis.patch.yml bundle 补丁层(dsh.bundle.patch):插入插件行。安装后由 profile 启动自动合并
cordis.yml --patch 一次性加载用的补丁清单(同内容覆盖文件)
game-dev.yml 「游戏开发模式」覆盖文件(同 --patch 或 profile 补丁)
package.json 包清单:dsh.bundle + dsh.client 双声明(单包 = host + client),"type": "module"
tsconfig.json 编辑器类型检查(erasableSyntaxOnly + verbatimModuleSyntax)
test-plugin.mjs 功能测试:真实 json 后端 + 9 个工具 + REST 路由 + 上传 + 重启持久化 + Godot 场景桥实时测试(headless 读树/增删改回写)
test-render-client.mjs 浏览器 bundle SSR 冒烟:模块加载/工厂物化/双 tab 注册/组件渲染(含 SceneTreeView)
debug-scene-bridge.mjs 场景桥调试脚本:临时 Godot 项目 + 真实 console 二进制,打印每次 dump/编辑结果

快速开始

方式一:dsh plugin 安装(推荐,发布形态)

本插件是单包双 half:dsh.bundle 提供 host 插件(工具 + REST 路由),同一个包的 dsh.client 声明让 client-modules 自动把 lib/client.js 纳入浏览器启动清单——一条命令装好 host + client:

# 从 npm / GitHub 发布后:
dsh plugin --profile web add godot-asset-planner

# 本地开发(本仓库直接链接):
dsh plugin --profile web add link:D:\deepseek\my-plugins

安装命令会把 godot-asset-planner 追加到 profile 的 dsh.profile.bundles 层栈,profile 启动时合并包的 cordis.patch.yml 完成挂载。重启 dsh web / 桌面应用后生效。

方式二:写入 profile 补丁(--patch / 热重载)

桌面版 DeepSeek Harness 每次启动读取 C:\Users\ASUS\.dsh\profiles\web\cordis.patch.yml,且该文件支持热重载——编辑保存后,正在运行的 GUI 会重新组合。

把下面这段追加到该文件里(name 为包名,从 profile 的 node_modules 解析):

- insert:
    - id: godot-asset-planner
      name: godot-asset-planner

或在 harness 目录用命令行一次性加载:

cd D:\deepseek\DeepSeek Harness\resources\harness
D:\deepseek\DeepSeek Harness\resources\node\node.exe --import tsx/esm apps/cli/src/bin.ts web --patch D:\deepseek\my-plugins\cordis.yml

⚠️ --patch 必须放在 --host/--port 等应用参数之前:一旦出现第一个未识别的参数,其后的选项会原样透传给 web 应用。

验证补丁组合(免启动,打印组合后的完整树):

node "D:\deepseek\DeepSeek Harness\resources\harness\apps\cli\lib\bin.js" --profile web --dump-config --patch ./my-plugins/cordis.yml

注意:--dump-config 会重写 profile 根文件 cordis.yml(内容固定为空列表,幂等),需要对该目录有写权限。

工具清单

除 godot_list_projects 外,所有工具都支持可选参数 project_id(缺省为 default 项目);项目列表可用 godot_list_projects 查询。资产、目标、标签、关联、报告均按项目隔离。

工具 输入参数 功能
godot_list_projects 无 列出全部规划项目(id + 名称,可选 Godot 目录路径),供其它工具指定 project_id
godot_register_asset asset_name(必填), asset_type(model/sound/scene/script/image/other, 必填), file_path(必填), linked_goal(可选), tags(可选数组), project_id(可选) 注册游戏资产;可关联到已存在的目标;可带初始标签;名称重复或关联不存在的目标会失败
godot_create_goal goal_name(必填), goal_description(必填), due_date(可选) 创建项目里程碑/目标;名称重复会失败
godot_query_assets keyword(可选), linked_goal(可选) 按大小写不敏感关键词(匹配名称/路径/类型/关联目标)和/或目标名查询资产;都不给则返回全部;两者为 AND 关系
godot_asset_report format(text/markdown, 必填) 生成全部目标及其关联资产、未关联资产清单和统计的状态报告,按格式渲染
godot_add_asset_tag / godot_remove_asset_tag asset_name(必填), tag(必填, ≤40 字符) 给资产添加/移除用户标签;重复添加/移除不存在标签为无操作
godot_link_asset_to_goal / godot_unlink_asset_from_goal asset_name(必填), goal_name(必填/可选) 建立/解除资产与目标的关联;解除时传错目标名会失败
godot_set_asset_done asset_name(必填), done(布尔, 必填) 标记资产完成状态——目标的进度条由关联资产中 done 的比例驱动
godot_delete_asset asset_name(必填) 永久删除资产记录(仅移除规划器记录,磁盘文件不受影响);资产不存在会失败
godot_update_asset asset_name(必填), file_path/asset_type/linked_goal/tags/done(均可选) 更新资产字段(只改提供的字段);linked_goal 传空串清除关联;tags 传数组整体替换(去重、每项 ≤40 字符);资产不存在/非法类型/未知目标会失败

数据持久化

  • 存储服务:DSH storage 服务(inject: ['tools', 'storage'])。
  • 后端:@deepseek-ai/dsh-storage-json(web profile 已挂载,根目录 $DSH_HOME/storages/,即 C:\Users\ASUS\.dsh\storages\)。
  • 单元:KV 单元 godot_asset_planner(文件 godot_asset_planner.json),内含 assets 与 goals 两张表,每条资产/目标记录独立原子落盘。
  • 可通过 cordis.yml 的 config.unitName 指定其它单元名(须匹配 ^[a-z][a-z0-9_]*$)。
  • 插件卸载/重载时会关闭单元;进程退出由后端统一收尾。

多项目(planner projects)

  • 概念:资产/目标按「规划项目」隔离(记录带 projectId,存储 key 为 `${projectId}::${name}`);旧数据(无 projectId)自动归入常驻的 default(默认项目),无需迁移。
  • 项目管理:客户端工具栏左侧项目切换器(下拉列出全部项目 + 当前项目名),新建/重命名/删除/从 Godot 目录添加在「管理项目」弹窗完成;当前选中项目持久化(prefs 单元 currentProject),跨会话保留。
  • 切换视图:切换项目后重新拉取 /gap/state,资产列表、看板、预览、标签、关联、报告、场景树、操作日志全部显示该项目数据。
  • 删除项目:确认后连同该项目的资产与目标一并删除(不可恢复);default 项目不可删除。
  • Godot 目录发现:「管理项目 → 扫描 Godot 项目目录」把 godotScanRoot(默认 D:/Godot)下发现的含 project.godot 的目录一键加入项目列表;添加时会主动读取项目文件——宿主验证 project.godot 存在(否则拒绝)并解析 config/name 作为项目名(未提供名称时),记录其 path;创建后自动批量导入项目资源为资产(res:// 相对路径、按扩展名推断类型;跳过 project.godot 本身、.godot/.git/bin/obj/build 等缓存构建目录及无法识别的文件;重名跳过并计数,上限 3000 个防阻塞)。
  • REST:GET /gap/state?project=<id> 指定视图(缺省用当前项目);POST /gap/projects(创建)//gap/projects/rename//gap/projects/delete//gap/projects/select(持久化当前项目);GET /gap/projects/candidates(Godot 目录候选);各写路由支持 body projectId(缺省当前项目)。
  • 工具:11 个 godot_* 工具可选 project_id(缺省 default),配合 godot_list_projects 查询项目 id。

实现要点

  • 运行时零依赖:插件只用 import type(编译期类型),没有任何运行时 import——Node 的类型剥离(Node ^22.19 || >=24)直接加载 .ts 源文件,无需打包或 tsx。
  • 原始 JSON Schema 注册:工具定义直接传给 ctx.tools.register(DSH 支持 raw-schema 工具自校验参数),校验逻辑在 execute 内完成。
  • JSON Schema 子集约束:required 只能用对象级数组(如 required: ['name']),不能写在属性内部({ type: 'string', required: true } 会被真实注册器拒绝——本插件的 schema 已按此修正)。
  • 写串行化:KV 单元不保证并发写顺序,插件内部用 promise 链把变更串行化。
  • 生命周期:单元懒打开(每个后端同一单元只能有一个活句柄),通过 ctx.effect 在插件 fiber 销毁时关闭。
  • 工具与 UI 共用同一套核心操作:4 个工具与 /gap REST 路由都调用 registerAssetCore/createGoalCore/queryAssetsCore/buildReportCore,模型与界面永远看到同一份数据。
  • REST 表面按需挂载:路由通过 ctx.inject(['webServer'], ...) 注册(组合条件式),等 webserver 就绪后生效;headless 等无 web 的 profile 自动退化为纯工具插件。
  • 工具名带 godot_ 前缀,避免与其它插件的全局工具名冲突。

游戏开发模式(game-dev profile)与可视化界面

自定义模式(Agent 预设 + profile)

游戏开发模式 = Agent 预设(新建会话下拉可选)+ host 平面插件(工具/REST/UI 已在 web profile 挂载):

① Agent 预设(出现在新建会话的预设下拉里,与“标准模式”并列)

C:\Users\ASUS\.dsh\.agent-presets\game-dev\
├── preset.yml          # name: 游戏开发模式 / description / order: 2
└── agent.cordis.yml    # 游戏开发 persona + 标准模式全部工具行

新建会话时在预设下拉选择「游戏开发模式」→ 会话即被激活:Agent 以 Godot 开发助手身份工作。客户端右侧的「Godot 资产管理器」以 dsh-better-sidebar 的一个 tab 呈现(+ 菜单 → Godot 资产管理器,或侧边栏 tab 栏点击图标),所有会话可见(管理的是全局项目数据,不绑定会话)。

为什么插件行不在预设里?godot-asset-planner 打开 storage KV 单元(同一单元仅允许一个活句柄)并注册共享 webserver 路由——按会话挂载会在第二个会话冲突。因此插件挂在 host 平面(profile 补丁),预设只贡献 persona 与工具指引,两者组合即为完整模式。

② game-dev profile(命令行独立模式)

C:\Users\ASUS\.dsh\profiles\game-dev\
├── package.json        # bundles: dsh-base + dsh-web-app(即“标准模式”)+ godot-asset-planner
└── cordis.patch.yml    # 插件行(bundle 层已插入,这里可只留 config 覆盖)

启动(与桌面启动器相同的源码启动方式):

cd D:\deepseek\DeepSeek Harness\resources\harness
D:\deepseek\DeepSeek Harness\resources\node\node.exe --import tsx/esm apps/cli/src/bin.ts --profile game-dev

端口默认 3080;如需其它端口把 --host 127.0.0.1 --port 3081 追加在末尾。dsh 在 PATH 时可简写 dsh --profile game-dev。

my-plugins/game-dev.yml 是同一内容的独立覆盖文件,两种用法:

  • 覆盖到任意 web 能力 profile:dsh web --patch ./my-plugins/game-dev.yml;
  • 或把其中的 - insert: 块放进某个 profile 的 cordis.patch.yml。

⚠️ 桌面版启动器(Electron)固定启动 web profile。若日常用桌面版,把 game-dev.yml 的 insert 块放进 C:\Users\ASUS\.dsh\profiles\web\cordis.patch.yml(本机已配置好),重启桌面应用即可。

客户端界面(Godot 资产管理器,better-sidebar tab)

  • 形态:注册为 dsh-better-sidebar 的三个 tab(ctx.betterSidebar.registerTab):「Godot 资产管理器」(id godot-assets,order 60)、「场景树查看器」(id godot-scene,order 61)、「Git 版本控制」(id godot-git,order 62),均 single: true——侧边栏本身的布局(吸附左右、调宽、折叠、会话持久化)全部由 better-sidebar 提供,无需自绘。
  • 依赖:需要已安装 dsh-better-sidebar(web profile 已装 v0.12.2);插件 inject: ['betterSidebar'],better-sidebar 缺席时本插件等待该服务。
  • 主题:全部使用 DSH 主题 token(--dsw-alias-*)加中性回退色,适配亮/暗主题;图标为内联 SVG,无 emoji。
  • 功能(多面板工作区:自由拖动标题栏、拖拽边框调大小、双击最大化、关闭后从工具栏「面板」菜单重开;详见下方「多面板布局」章节。默认「默认」预设 = 资产列表(左 40%)+ 目标看板(右 60%)+ AI 助手(底部)):
    • 资产列表面板:列表(名称/类型/路径/关联目标/标签)+ 行内发送到对话按钮(插入 @名称 <res://路径>(磁盘:绝对路径) 到当前会话输入框——光标处插入,未聚焦输入框时追加到末尾,经 conversation.input.setDraft 公开服务,与 better-sidebar 的草稿插入同一路径;/gap/state 为每个资产附加 diskPath(res:// 解析到所属项目根的绝对路径,绝对路径原样),引用同时带上磁盘位置,模型可直接读取文件)+ 行内删除按钮(确认后移除记录)+ 拖拽上传(拖入后补类型与关联目标)+ 高级搜索与筛选:
      • 工具栏导入为下拉菜单(导出=↑箭头、导入=↓箭头,语义对调):导入配置备份(JSON)(合并/覆盖恢复)或 导入文件夹(两步弹窗:①弹出窗口输入文件夹完整路径 → 宿主 /gap/dir/scan 递归读取该路径下所有文件;②再弹出标签窗口,选择路径下文件夹名(候选 chips 多选)或输入自定义标签,确认后 /gap/dir/import 一次为全部文件批量注册(按扩展名推断类型、绝对路径引用、重复名计为失败);/gap/assets 与 /gap/upload 路由新增可选 tags 初始标签、重传合并标签);
      • 搜索栏(Ctrl+F 聚焦)实时过滤名称/路径/类型/标签/目标;
      • 筛选系统(筛选面板,默认收起):名称、路径(res:// 或磁盘路径均可)、标签多选、类型、关联目标、创建日期范围;带「清除筛选」;
      • 视图切换(三种):文件名(紧凑单行,仅文件名+大小提示)、双排(双列卡片:类型图标/路径/标签/目标)、表格(名称/类型/大小/标签/目标/操作列——第三种为补充);/gap/state 为资产附加 size(磁盘文件字节数,文件不存在时省略)驱动大小列与排序;
      • 排列方式切换:名称、文件大小、标签名称、创建时间、类型、目标、完成状态(补充后四项),支持升序/降序切换;
      • 点击资产行自动打开预览区面板显示详情(预览是独立面板,无需手动打开)。
    • 预览区面板:选中资产的预览(可折叠、可拖动上边缘调高 120–480px);头部显示注册路径与磁盘位置(diskPath,res:// 已解析为绝对路径,便于复制/让模型读取),并有编辑按钮(弹窗修改路径/类型/关联目标/标签/完成状态,POST /gap/assets/update,只改变更字段):
      • 图片:内联大图(GET /gap/file 服务注册资产文件),点击放大为全屏覆盖层(右上角关闭按钮 / Esc / 点击背景关闭);
      • 音效:Web Audio 播放/暂停 + 可拖动进度条(拖动 seek,显示当前/总时长)+ 音量滑块(0–100%);
      • 模型:OBJ 统计顶点/面数,GLTF 统计顶点/三角面(3D 预览为未来功能);
      • 脚本:轻量语法高亮(注释/字符串/关键字/数字);
      • 场景:节点总数 + 节点类型分布;
      • 预览区内可添加/移除标签(回车或按钮)。
    • 目标看板面板:目标以卡片展示——名称(悬停显示完整描述)、进度条(关联资产中已完成的百分比)、截止日期(过期标红)、已关联资产数;支持按截止日期/进度/创建时间排序;卡片点击展开关联资产明细(含完成勾选);顶部资产 dock 点击多选 + 拖拽到目标卡片建立关联、拖到「未关联」区解除关联(HTML5 DnD,拖拽高亮 + 自定义拖拽缩略图)。
    • 标签面板(4.2,默认关闭):全部标签列表——颜色圆点 + 标签名 + 关联资产数 + 资产名,点击即按该标签筛选资产列表。
    • 关联面板(默认关闭):按目标分组的资产清单 + 未关联资产区。
    • 报告面板(默认关闭):一键生成(text/markdown)+ 面板内预览 + Blob 下载。
    • 场景树面板:复用场景树查看器组件(headless 读树/编辑)。
    • Git 版本控制面板(默认关闭,也可从第三个 tab「Git 版本控制」打开):见下方「Git 版本控制」章节。
    • AI 助手面板:工具清单 + 当前数据摘要 + 会话提示(对话在主聊天窗口进行)。
    • Toast:所有操作成功/失败即时反馈(内容区底部,自动消失)。
  • 后端新增:资产类型扩展 image/other(上传按扩展名归类:png/jpg/svg→图片);标签工具 godot_add_asset_tag / godot_remove_asset_tag;关联工具 godot_link_asset_to_goal / godot_unlink_asset_from_goal 与完成状态 godot_set_asset_done(资产 done 标志驱动看板进度条,均持久化到 storage);路由新增 POST /gap/assets/tags、/gap/assets/link、/gap/assets/unlink、/gap/assets/done、GET /gap/file(仅服务已注册资产的文件,内容类型按扩展名、8MB 上限——预览数据通道)。
  • 通信:同源 JSON fetch 调用 host 插件的 /gap/* 路由(state/assets/goals/upload/tags/link/unlink/done/export/import/layout/file/report/git),与 9 个工具共用核心操作,持久化在 storage。
  • 打包形态:单包双 half——godot-asset-planner.ts 是 host 插件(exports["."]),lib/client.js 是浏览器 bundle(exports["./client"])。包同时声明 dsh.bundle(插入 host 行)与 dsh.client(platform: "web"),client-modules 扫描 loader 行解析到本包后自动把 lib/client.js 纳入浏览器启动清单并服务 /plugins/godot-asset-planner/client.js。浏览器 bundle 手工写成 window.__ModuleLoader__.load 工厂格式(id: 'godot-asset-planner',与包名一致),只 require('react')(seed 词),无需构建步骤。

场景树查看器(第二个 tab)

  • 形态:注册为 better-sidebar 的第二个 tab(id godot-scene,文档+节点 SVG 图标,标题「场景树查看器」,order 61)。
  • 数据来源:Godot --headless 实时读取(不依赖 GodotMCP / godot-bridge / 打开中的编辑器)。宿主把两段 GDScript(dump.gd 读树、edit.gd 写回)写入临时目录,用 Godot*_console.exe --headless --path <项目> --script <runner>.gd -- <场景路径> <ops> 运行,从 stdout 解析脚本打印的 JSON。场景必须先注册为资产(路由白名单),项目根通过配置 godotProject 或在 godotScanRoot(默认 D:/Godot)下发现解析。
  • 功能:
    • 场景选择器(列出已注册的 scene 类型资产)+ 刷新;选择记住在 localStorage,重开自动恢复;
    • 节点树:Godot 风格彩色图标(2D/3D/UI/动画/通用按类着色)+ 节点名 + 类型 + **可见性(眼睛)/可编辑(铅笔)**状态,缩进层级,展开/折叠(默认全展开,含「全部展开/全部折叠」);
    • Ctrl+Shift+F 节点搜索:匹配子串高亮 + 命中节点的祖先自动展开;「清除搜索」恢复;
    • 右键上下文菜单:添加子节点(内联名称 + 常用节点类型下拉)、重命名(内联输入,Enter 确认/Esc 取消)、复制子树、删除(弹窗确认,无法撤销)、定位(树内高亮 + 滚动,展开祖先);
    • 底部状态栏:节点总数 · 所属项目 · 场景根节点名。
    • 每次编辑都是真实的 headless Godot 运行(POST /gap/scene/edit),成功即写回 .tscn 文件并以 Toast 反馈。
  • 已知限制:「跳转到 Godot 编辑器中该节点」需要编辑器桥接(GodotMCP / godot-bridge),未安装——UI 用树内「定位」替代并在菜单里注明。
  • 新后端路由:GET /gap/scene/projects(扫描发现的项目根)、GET /gap/scene/tree?path=(dump 场景节点树,{root, nodes:[{name,path,type,visible,editable,children}]})、POST /gap/scene/edit({path, ops:[{op:'add'|'rename'|'copy'|'delete', ...}]},逐 op 执行并保存)。参数/操作类错误返回 400(ClientRouteError),Godot 不可用返回 500。
  • 桥接实现要点:--path <项目> 必须带,否则 res:// 无法解析;Windows 需 console 版 exe(GUI 版不写 stdout);脚本只用显式类型(Godot 4 把从 Variant 推断类型当作错误);操作路径与 dump 一致——根节点路径即根名(如 Root),子节点 Root/Child,_find 先剥离等于根名的首段;根节点禁止删除;copy 用 duplicate(15)(深度复制)+ 重设 owner。

面板体验增强(4.x)

  • 4.1 数据导入/导出(工具栏「导出」「导入」按钮):
    • 导出:GET /gap/export 返回 {format:'godot-asset-planner', version:1, exportedAt, goals, assets} 完整配置 → JSON.stringify + Blob + <a download> 下载为 godot-planner-backup-<日期>.json。
    • 导入:选择 JSON 文件后弹窗选择合并(追加新数据,重名跳过)或覆盖(清空两张表后重建);POST /gap/import {mode, data}。非法记录(缺 name / 非法类型等)跳过并计数,不会让整个导入失败;返回 {goalsImported, assetsImported, goalsSkipped, assetsSkipped}。
    • 宿主实现:KvUnit 增加 deleteRecord(覆盖模式先按 loadAll().tables 逐键删除);所有写入走既有写串行化链。
  • 4.2 标签系统(增强版):
    • 标签颜色:10 色预定义调色板(#FF6B6B #4ECDC4 #45B7D1 #96CEB4 #FFEAA7 #DDA0DD #F4A261 #F7DC6F #BB8FCE #85C1E9),按标签名确定性哈希取色——同名同色,无需持久化颜色字段。
    • 资产列表的标签显示为圆角色块 + 文字(renderTagChip:色点 + 半透明底色描边),点击即筛选该标签下的资产(与筛选面板联动)。
    • 「标签」视图:全部标签 + 关联资产数 + 资产名,点击跳回资产视图并筛选。
  • 4.3 最近操作记录(面板底部「操作日志」区):
    • 内存存储(模块级 store,会话期间有效,刷新即清空,不持久化);上限 100 条。
    • 记录:上传/创建目标/关联与解除/完成状态/标签增删(资产、目标 tab)+ 场景编辑(场景树 tab)——跨 tab 共享同一份日志。
    • 每条一行(溢出省略),悬停 title 显示完整内容;点击跳转:资产→打开/选中资产列表面板,目标→打开/展开目标看板面板,场景→激活场景树 tab;导出/导入类条目不可跳转。
    • 「清空」按钮清空日志。
  • 4.4 面板设置(右上角齿轮弹出):
    • 默认展开/折叠(立即开合面板)、默认宽度(滑块 280–600px,350ms 防抖保存)。
    • 自动保存到 storage(复用 /gap/ui-prefs,KV 单元 godot_asset_planner_ui);仅当用户在设置面板修改某项时才通过 props.store.reduce(better-sidebar store,panelOpen/width 字段)精确应用对应字段——store 引用存放在 ref 中保持 reducer 稳定,挂载时不覆盖 better-sidebar 自身持久化的面板几何,因此拖拽调宽、toggle 开合等 better-sidebar 原生操作永远优先,不会与之冲突。

多面板布局(自由工作区)

把资产管理器 tab 拆成可自由拖动、调整大小的子面板工作区(需求 1.x):

  • 面板清单(9 个,工具栏「面板」下拉开关):
    • 核心 5 个:资产列表(搜索/筛选/列表)、目标看板(排序/进度/拖拽关联)、场景树(复用 SceneTab 组件,headless 读树/编辑)、AI 助手(工具清单 + 当前数据摘要 + 会话提示——对话本身在主聊天窗口进行,客户端无法直接驱动 LLM)、预览区(选中资产的预览与标签编辑)。
    • 附加 4 个(默认关闭,可从面板菜单打开):Git 版本控制、关联、标签、报告。
  • 交互:
    • 拖动标题栏移动位置;拖拽 8 个边框/角手柄调整大小(最小 12%×8%);拖动中的面板显示高亮描边(拖动指示器)并置顶;
    • 关闭按钮隐藏面板(工具栏「面板」菜单勾选重新打开);
    • 双击标题栏最大化/还原(最大化时其余面板隐藏,标题栏出现「还原」按钮)。
    • 面板间 1px 边框分隔线;每个标题栏 = 图标 + 名称 + 还原 + 关闭。
  • 预设布局(工具栏下拉,3 个):默认(资产列表左 40% + 目标看板右 60%,AI 助手底部全宽)、开发(场景树左 30% + 资产列表中 40% + 预览区右 30%)、管理(目标看板全屏)。
  • 持久化:每次移动/缩放/开关/最大化/预设切换后 400ms 防抖保存到 storage(新增 GET/POST /gap/layout,存 ui-prefs 单元的 global.layout——savePrefs 改为合并写,互相不覆盖);下次打开自动恢复。
  • 技术实现:browser bundle 受「仅 require('react')、零构建」硬约束,无法引入 react-grid-layout / react-mosaic-component——改为自研轻量布局(约 250 行 PanelWorkspace:归一化 0–1 坐标 + pointer events 拖动/缩放 + ResizeObserver 测量),功能与交互完整覆盖需求;布局状态通过宿主 /gap/layout 路由持久化,面板内容以 contentOf(id) 配置注入。
  • 宿主侧:WorkspaceLayout 归一化校验(坐标 clamp 0–1、未知面板 id 丢弃、maximized 白名单);KvUnit 无新增能力(复用 setGlobal)。

Git 版本控制(第三个 tab + 工作区面板)

  • 形态:独立组件 GitPanel 被两处复用——better-sidebar 第三个 tab(id godot-git,「Git 版本控制」,Git 分支图标)+ 工作区面板(工具栏「面板」菜单打开)。
  • 目录选择:顶部下拉列出 godotScanRoot/godotProject 发现的项目根;选择记忆在 localStorage。安全白名单:所有 /gap/git/* 路由先校验目录属于已发现项目(否则 400);diff 的文件路径做穿越防护(resolve 后必须仍在项目目录内)。
  • 功能(1.1):
    • 状态查看:git status --porcelain -b(core.quotepath=false 避免中文路径转义)解析为 已修改 / 已暂存 / 未跟踪 三组 + 当前分支;非仓库返回 isRepo:false 并显示「初始化 Git 仓库」按钮(git init)。
    • 提交:多行 textarea + git add -A && git commit -F -(消息经 stdin 传入,支持多行);成功/失败即时反馈。
    • 推拉:git push / git pull(120s 超时);执行期间顶部显示进度提示("正在执行 git push…"),按钮禁用防重入。
    • 分支管理:当前分支 chip + 统计(修改/暂存/未跟踪数);切换下拉(git checkout);新建输入框 + Enter(git checkout -b,创建并切换)。
    • 文件差异:点击文件行 → git diff(已修改)/ git diff --cached(已暂存)/ 直接读文件逐行加 +(未跟踪);Diff 视图行级语法着色(+ 绿 / - 红 / @@ 蓝 / 文件头灰),点击行加载,底部面板显示,可关闭。
  • 操作反馈(1.2):每次操作写入面板底部「执行日志」(成功 ✓ / 失败 ✗,悬停看详情),失败附带详细错误 + 解决建议(宿主 gitHint:未配置身份 → 提示 git config;认证失败 → 检查凭据/SSH key;无远程 → git remote add origin;无上游 → git push -u;合并冲突 → 手动解决等);操作也记入共享操作日志(不可跳转)。
  • 宿主路由:GET /gap/git/projects(自动发现 + 用户导入目录的并集)、POST /gap/git/import-dir(导入任意存在的本地目录到白名单,持久化到 ui-prefs 单元的 global.gitDirs)、GET /gap/git/status?dir=、GET /gap/git/branches?dir=、GET /gap/git/diff?dir=&file=&status=、POST /gap/git/init|commit|push|pull|branch|checkout(gitOp 统一封装 node:child_process spawn + 120s 超时;失败返回 {ok:false, error, hint},HTTP 恒为 200 由 ok 判定)。
  • 导入目录(1.x 交互补充):目录下拉旁「导入目录」按钮弹窗输入路径(可在文件资源管理器复制路径粘贴),或直接把本地目录拖放到 Git 面板(Electron 环境 File.path 可用时);宿主校验目录存在后加入白名单并持久化,重启后仍在。

整合与启动步骤(一键到 tab)

以下示例以本机(Windows + $DSH_HOME = C:\Users\ASUS\.dsh)为例;路径请按你的环境替换。

  1. 安装插件(发布形态,一条命令装好 host + client):dsh plugin --profile web add godot-asset-planner(本地开发:dsh plugin --profile web add link:<本仓库路径>,会作为符号链接进入 profile)。
  2. 确认 profile 补丁含 config 覆盖(可选:godotProject / godotBin / uploadRoot / unitName);确认预设目录 $DSH_HOME\.agent-presets\game-dev\ 存在;确认 dsh-better-sidebar 已装(bundle 层含 better-sidebar 行)。
  3. 重启 harness 进程(bundle 层变更与新的 tab 注册需重启生效):桌面版托盘 → 退出 → 重新打开。
  4. 打开右侧边栏 → + 菜单或 tab 栏点「Godot 资产管理器」(Godot 三角图标)→ 使用多面板工作区(工具栏:项目切换器 / 布局预设下拉 / 面板开关 / 导出 / 导入 / 设置);或点「场景树查看器」(文档+节点图标)→ 选择已注册的 .tscn 场景查看/编辑节点树(需重启后宿主含场景桥路由)。
  5. 上传文件默认落在 $DSH_HOME\godot-uploads\;想直接进 Godot 工程目录,在 profile 补丁的 config 里加 uploadRoot。

测试

node my-plugins/test-plugin.mjs      # 宿主:工具 + REST + 持久化 + 多项目 + Godot 场景桥(真实 headless)
node my-plugins/test-render-client.mjs  # 客户端:SSR 渲染三 tab + 工作区 + 场景树 + Git + 项目切换器

test-plugin.mjs 覆盖:模块导出面(name/inject/apply)、12 个工具注册、目标/资产创建、全部参数校验失败路径(重复、未知目标、非法枚举、空串)、关键词/目标查询、text/markdown 报告渲染、REST 路由全流程(state/goals/assets/upload/report、400/404、base64 解码落盘、重传刷新)、"重启后数据仍在"的持久化验证(真实 @deepseek-ai/dsh-storage-json 后端 + 临时文件)、导出/导入(GET /gap/export 版本化文档、合并模式跳过重名、追加新数据、覆盖模式清表重建、非法记录跳过计数、非法 mode/data 400)、diskPath 解析(/gap/state 将 res:// 资产解析为项目根下的绝对磁盘路径、绝对路径原样)与 size 附加(磁盘文件字节数、缺失省略)、初始标签(register/upload 路由与工具支持可选 tags、重传合并标签)、文件夹批量导入(/gap/dir/scan 递归扫描 + /gap/dir/import 一次注册全部文件并按文件夹名打标签、重复名计失败不崩溃、缺失目录失败、/gap/dialog/open-directory 非 Electron 环境优雅降级)、删除资产(工具 + 路由:删除记录、状态消失、未知资产 400/拒绝)、更新资产(工具 + 路由:改路径/类型、清关联、整体替换标签去重、设 done、只改提供字段、未知资产/非法类型/超长标签/非数组标签拒绝)、工作区布局(GET/POST /gap/layout 默认值、存取、坐标 clamp、非法面板 id 丢弃、prefs 保存不抹掉 layout)、多项目(项目创建/切换/隔离/重命名/删除连带数据、?project= 视图覆盖、从 Godot 目录添加:读取 project.godot 校验与取名、自动批量导入项目资源(res:// 路径、类型推断、排除 .godot 缓存与无法识别文件))、Git 版本控制(真实 git 临时仓库:projects 发现、非仓库 isRepo:false、init、status 解析未跟踪/已修改、本地身份 commit、干净工作区、modified/untracked diff、路径穿越拒绝、分支创建/切换/列表、无远程 push 失败带建议、未知目录 400、空提交信息 400、import-dir 导入任意目录并入白名单、缺失目录失败),以及 Godot 场景桥实时测试(找到 Godot*_console.exe 时自动跑;临时项目建树 → 注册场景 → dump 树 → add/rename/copy/delete 逐 op 回写并复核新 dump 与 .tscn 内容 → 未注册场景/删根/父节点缺失/ops 非数组等 400 路径;找不到二进制则跳过并提示设置 GODOT_BIN)。

test-render-client.mjs 覆盖:bundle 执行与 window.__ModuleLoader__.load 工厂交接、require('react') 物化、apply() 注册三个 better-sidebar tab(id/标题/order/single/组件/图标)、GodotAssetTab 工具栏(布局预设下拉/面板下拉/导出/导入/设置齿轮)+ 工作区加载态 + 操作日志空态、tagColor 调色板 + renderTagChip 色块、buildAssetRef(引用含磁盘路径、路径相同时省略、缺省容忍)、KanbanView 排序/进度/逾期/focusGoal 展开、SceneTab 空态提示与搜索栏、SceneTreeView 正常/折叠/搜索自动展开/内联重命名/内联添加五种渲染路径、PanelWorkspace 面板标题/data-panel-id/内容注入/关闭按钮/最大化隐藏其余面板、GitPanel 无项目提示/刷新/导入目录/执行日志空态、无 emoji 断言。

参考

  • Smalldy/godot-bridge:DSH 插件 + cordis.patch.yml 加载模式的参考实现(通过游戏内 TCP 服务驱动 Godot 4.x)。
  • 官方工具插件示例:packages/fs/tool-fs(ctx.tools.register / defineTool / output.render 的规范写法,及 docs/cookbook/adding-a-tool.md)。

依赖与鸣谢

本插件运行在 DeepSeek Harness(deepseek-ai/DeepSeek-Harness)之上,并直接依赖以下组件:

依赖 版本 用途 来源 / 许可证
dsh-better-sidebar 0.12.2 客户端 UI 的侧边栏容器:本插件的「Godot 资产管理器 / 场景树查看器 / Git 版本控制」三个 tab 通过其 ctx.betterSidebar.registerTab 服务注册;面板几何(拖拽、调宽、折叠)由它提供 github.com/omdsh-dev/DSH-better-sidebar · MIT
@deepseek-ai/dsh-storage-json web profile 内置 数据持久化后端(KV 单元 godot_asset_planner / godot_asset_planner_ui → $DSH_HOME/storages/*.json) DeepSeek Harness 工作区包
@deepseek-ai/dsh-tools / dsh-tool-* harness 内置 宿主工具注册、shell/fs/jobs 等运行时能力 DeepSeek Harness 工作区包
Godot Engine 4.x(headless console 版) 场景树查看器/编辑器:通过 Godot*_console.exe --headless 真实读写 .tscn MIT(Godot 引擎本体)

特别鸣谢

  • omdsh-dev / DSH-better-sidebar(MIT):本插件的所有侧边栏 UI 都依赖它提供的 tab 注册服务与面板交互能力,特此鸣谢。
  • DeepSeek Harness 团队:tools / storage / webServer / 预设组合等基础设施。
  • Smalldy / godot-bridge:插件加载模式与 Godot 桥接思路的参考。

如果你在使用本插件,请一并感谢以上项目的作者。

故障排查

  • Node 版本:加载 .ts 需要 Node ^22.19 || >=24(默认类型剥离)。桌面版自带 resources\node\node.exe(v24)。
  • 移动项目后:test-plugin.mjs / debug-scene-bridge.mjs 里 file:///D:/deepseek/my-plugins/godot-asset-planner.ts 的绝对路径需同步更新(测试脚本直接加载源码,不走包解析)。
  • headless 等 profile 没有 storage:storage/storage-json/storage-domain 是 web bundle 的行;在其它 profile 使用本插件前需先补上这些行(在已有 storage 的 profile 上重复添加会报 duplicate-backend)。
  • 插件没生效:用 --dump-config --patch 确认行已进入组合树;查看启动日志中是否有 failed to apply loader entry godot-asset-planner 的报错。
—/ 5

No ratings yet

Verified DSH bundle

Commit 20a81e9ea6ab

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout