dsh-mc-art-panel 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/build.mjs +42 -2
  2. package/cordis.patch.yml +23 -2
  3. package/package.json +4 -2
  4. package/preset/mc-studio/agent.cordis.yml +298 -0
  5. package/preset/mc-studio/preset.yml +2 -0
  6. package/preset/mc-studio/skills/mc-art/README.md +69 -0
  7. package/preset/mc-studio/skills/mc-art/SKILL.md +618 -0
  8. package/preset/mc-studio/skills/mc-art/bin/mc-art +14 -0
  9. package/preset/mc-studio/skills/mc-art/examples/block_pack.json +58 -0
  10. package/preset/mc-studio/skills/mc-art/examples/bow_standby.plan.json +307 -0
  11. package/preset/mc-studio/skills/mc-art/layouts/vanilla_1_12_armor_layer_1_64.json +116 -0
  12. package/preset/mc-studio/skills/mc-art/layouts/vanilla_1_12_armor_layer_2_64.json +53 -0
  13. package/preset/mc-studio/skills/mc-art/layouts/vanilla_1_12_cow_64.json +141 -0
  14. package/preset/mc-studio/skills/mc-art/layouts/vanilla_1_12_sheep_64.json +84 -0
  15. package/preset/mc-studio/skills/mc-art/layouts/vanilla_1_12_sheep_wool_64.json +84 -0
  16. package/preset/mc-studio/skills/mc-art/layouts/vanilla_1_12_villager_64.json +146 -0
  17. package/preset/mc-studio/skills/mc-art/layouts/vanilla_block_all_16.json +13 -0
  18. package/preset/mc-studio/skills/mc-art/mc_art/__init__.py +5 -0
  19. package/preset/mc-studio/skills/mc-art/mc_art/__main__.py +6 -0
  20. package/preset/mc-studio/skills/mc-art/mc_art/appearance.py +1689 -0
  21. package/preset/mc-studio/skills/mc-art/mc_art/asset_groups.py +633 -0
  22. package/preset/mc-studio/skills/mc-art/mc_art/box_model.py +313 -0
  23. package/preset/mc-studio/skills/mc-art/mc_art/cli.py +956 -0
  24. package/preset/mc-studio/skills/mc-art/mc_art/contracts.py +696 -0
  25. package/preset/mc-studio/skills/mc-art/mc_art/entity.py +313 -0
  26. package/preset/mc-studio/skills/mc-art/mc_art/evidence.py +54 -0
  27. package/preset/mc-studio/skills/mc-art/mc_art/family.py +346 -0
  28. package/preset/mc-studio/skills/mc-art/mc_art/geometry.py +661 -0
  29. package/preset/mc-studio/skills/mc-art/mc_art/group_index.py +271 -0
  30. package/preset/mc-studio/skills/mc-art/mc_art/ingame.py +718 -0
  31. package/preset/mc-studio/skills/mc-art/mc_art/metrics.py +241 -0
  32. package/preset/mc-studio/skills/mc-art/mc_art/minecraft_assets.py +82 -0
  33. package/preset/mc-studio/skills/mc-art/mc_art/modjava.py +213 -0
  34. package/preset/mc-studio/skills/mc-art/mc_art/pack.py +192 -0
  35. package/preset/mc-studio/skills/mc-art/mc_art/packaging.py +217 -0
  36. package/preset/mc-studio/skills/mc-art/mc_art/pipeline.py +1647 -0
  37. package/preset/mc-studio/skills/mc-art/mc_art/planfile.py +562 -0
  38. package/preset/mc-studio/skills/mc-art/mc_art/project_settings.py +430 -0
  39. package/preset/mc-studio/skills/mc-art/mc_art/reference_geometry.py +426 -0
  40. package/preset/mc-studio/skills/mc-art/mc_art/reference_index.py +467 -0
  41. package/preset/mc-studio/skills/mc-art/mc_art/reference_retrieval.py +418 -0
  42. package/preset/mc-studio/skills/mc-art/mc_art/references.py +342 -0
  43. package/preset/mc-studio/skills/mc-art/mc_art/text_cache.py +102 -0
  44. package/preset/mc-studio/skills/mc-art/mc_art/uv_layout.py +290 -0
  45. package/preset/mc-studio/skills/mc-art/mc_art/uv_tools.py +163 -0
  46. package/preset/mc-studio/skills/mc-art/mc_art/validation.py +436 -0
  47. package/preset/mc-studio/skills/mc-art/mc_art/vanilla_model.py +821 -0
  48. package/preset/mc-studio/skills/mc-art/scripts/continuity.py +85 -0
  49. package/preset/mc-studio/skills/mc-art/scripts/magnify.py +51 -0
  50. package/preset/mc-studio/skills/mc-art/scripts/review_family.py +107 -0
  51. package/preset/mc-studio/skills/mc-art/tests/asset_tree.py +86 -0
  52. package/preset/mc-studio/skills/mc-art/tests/conftest.py +14 -0
  53. package/preset/mc-studio/skills/mc-art/tests/fixtures/javap_cow_bpn.txt +159 -0
  54. package/preset/mc-studio/skills/mc-art/tests/fixtures/javap_renderer_brs.txt +717 -0
  55. package/preset/mc-studio/skills/mc-art/tests/fixtures/javap_sheep_bqm.txt +351 -0
  56. package/preset/mc-studio/skills/mc-art/tests/fixtures/javap_sheep_bqo.txt +203 -0
  57. package/preset/mc-studio/skills/mc-art/tests/fixtures/javap_sheep_bqp.txt +105 -0
  58. package/preset/mc-studio/skills/mc-art/tests/test_alpha_contract.py +185 -0
  59. package/preset/mc-studio/skills/mc-art/tests/test_asset_groups.py +100 -0
  60. package/preset/mc-studio/skills/mc-art/tests/test_box_model.py +89 -0
  61. package/preset/mc-studio/skills/mc-art/tests/test_box_offsets.py +113 -0
  62. package/preset/mc-studio/skills/mc-art/tests/test_cli_args.py +11 -0
  63. package/preset/mc-studio/skills/mc-art/tests/test_entity.py +159 -0
  64. package/preset/mc-studio/skills/mc-art/tests/test_entity_uv_paint_plan.py +95 -0
  65. package/preset/mc-studio/skills/mc-art/tests/test_family.py +84 -0
  66. package/preset/mc-studio/skills/mc-art/tests/test_ingame.py +115 -0
  67. package/preset/mc-studio/skills/mc-art/tests/test_layouts.py +45 -0
  68. package/preset/mc-studio/skills/mc-art/tests/test_modjava.py +93 -0
  69. package/preset/mc-studio/skills/mc-art/tests/test_pack.py +120 -0
  70. package/preset/mc-studio/skills/mc-art/tests/test_project_settings.py +264 -0
  71. package/preset/mc-studio/skills/mc-art/tests/test_reference_transfer.py +136 -0
  72. package/preset/mc-studio/skills/mc-art/tests/test_shape_lock.py +418 -0
  73. package/preset/mc-studio/skills/mc-art/tests/test_uv_tools.py +147 -0
  74. package/preset/mc-studio/skills/mc-art/tests/test_vanilla_model.py +150 -0
  75. package/preset/mc-studio/skills/mc-art/tests/test_wire_robustness.py +37 -0
  76. package/preset/mc-studio/skills/mc-mod/SKILL.md +113 -0
  77. package/preset/mc-studio/skills/mc-mod/references/contracts.md +118 -0
  78. package/preset/mc-studio/skills/mc-mod/references/gametest.md +162 -0
  79. package/preset/mc-studio/skills/mc-mod/references/panel.md +124 -0
  80. package/preset/mc-studio/skills/mc-mod/references/traps.md +95 -0
  81. package/preset/mc-studio/skills/mc-mod/references/versions.md +78 -0
  82. package/preset/mc-studio/skills/mc-mod/references/workflow.md +118 -0
package/build.mjs CHANGED
@@ -20,8 +20,9 @@
20
20
  * 于是"同一份代码两种送达"不需要维护两份实现(这是这个仓库最在意的事)。
21
21
  * `lib/` 是生成物且要随包发布,所以另有 verify-build.mjs 逐字节比对,防止漂移。
22
22
  */
23
- import { readFileSync, writeFileSync, mkdirSync } from 'node:fs'
23
+ import { cpSync, existsSync, readFileSync, rmSync, writeFileSync, mkdirSync } from 'node:fs'
24
24
  import { spawnSync } from 'node:child_process'
25
+ import { homedir } from 'node:os'
25
26
  import { dirname, join } from 'node:path'
26
27
  import { fileURLToPath } from 'node:url'
27
28
 
@@ -192,17 +193,56 @@ window.__ModuleLoader__.load({
192
193
  `
193
194
  }
194
195
 
196
+ /**
197
+ * 把仓库里的「模式」和「skill」也复制进包里。
198
+ *
199
+ * 为什么:用户从 npm 拉一个包,就该同时得到面板 + 模式 + skill —— 而不是"装了面板,
200
+ * 预设还得自己拷到 ~/.dsh/.agent-presets"。面板自己的 cordis.patch.yml 会把包内
201
+ * 这两个目录注册成 agent-presets 的 root 和 skill 的 customSkillDirs(都在 profile
202
+ * 里,不往用户目录写东西)。
203
+ *
204
+ * 副本仍然是**生成物**:唯一真相是仓库里的 presets/ 与 skills/,verify-build.mjs 会
205
+ * 逐字节比对这两份拷贝,防止它们悄悄漂移。
206
+ */
207
+ export function vendored() {
208
+ // mc-art 是**独立仓库**(有自己的历史与节奏),所以它不在本仓库里:
209
+ // 这里的来源是那个仓库的本地克隆(安装器装到 ~/.dsh/skills/mc-art)。
210
+ // 发布时把它快照进包里,用户装一个包就同时拿到面板 + 模式 + 两个 skill,
211
+ // 不需要 git、不需要网络、也不往用户目录写东西。
212
+ const artSource = process.env.MC_ART_SKILL_DIR ?? join(homedir(), '.dsh', 'skills', 'mc-art')
213
+ const pairs = [
214
+ [join(HERE, '..', 'presets', 'mc-studio'), join(HERE, 'preset', 'mc-studio')],
215
+ // skill 跟着**预设**走:预设的 composition 用 baseUrl 相对定位 skills/,
216
+ // 所以它们必须落在预设目录里(和出厂 cordis 预设一样)。
217
+ [join(HERE, '..', 'skills', 'mc-mod'), join(HERE, 'preset', 'mc-studio', 'skills', 'mc-mod')],
218
+ ]
219
+ if (existsSync(join(artSource, 'SKILL.md'))) {
220
+ pairs.push([artSource, join(HERE, 'preset', 'mc-studio', 'skills', 'mc-art')])
221
+ }
222
+ else process.stdout.write(`!没找到 mc-art 的克隆(${artSource}),这一份不进包——` +
223
+ '先跑 install.mjs 拉它,或用 MC_ART_SKILL_DIR 指过去。\n')
224
+ for (const [from, to] of pairs) {
225
+ rmSync(to, { recursive: true, force: true })
226
+ mkdirSync(dirname(to), { recursive: true })
227
+ // 不要 .git(发布物里没有历史;npm 也会把它排除掉,与其不一致不如自己排除)
228
+ cpSync(from, to, { recursive: true, filter: (src) => !src.split(/[\\/]/).includes('.git') })
229
+ }
230
+ return pairs
231
+ }
232
+
195
233
  export function build() {
196
234
  const host = strip(join(SOURCES, 'host.js'))
197
235
  const client = strip(join(SOURCES, 'client.js'))
198
236
  mkdirSync(join(HERE, 'lib'), { recursive: true })
199
237
  writeFileSync(join(HERE, 'lib', 'index.js'), hostModule(host))
200
238
  writeFileSync(join(HERE, 'lib', 'client.js'), clientBundle(client))
201
- return { host, client }
239
+ const copied = vendored()
240
+ return { host, client, copied }
202
241
  }
203
242
 
204
243
  if (process.argv[1] !== undefined && process.argv[1].endsWith('build.mjs')) {
205
244
  const out = build()
206
245
  process.stdout.write(`已生成 panel/lib/index.js(宿主源码 ${out.host.length} 字符)` +
207
246
  ` 与 panel/lib/client.js(客户端源码 ${out.client.length} 字符)\n`)
247
+ for (const [from, to] of out.copied) process.stdout.write(`已复制 ${from} -> ${to}\n`)
208
248
  }
package/cordis.patch.yml CHANGED
@@ -1,5 +1,26 @@
1
- # 把面板挂进 web profile 的宿主组合:就一行,自己。
2
- # 这是"装完就在"的那一步——`dsh plugin --profile <名> add` 会读这个 patch。
1
+ # 面板随包带来的三样东西:面板自己 + 一个 agent preset(模式)+ 一个 skill。
2
+ #
3
+ # 为什么用 root 而不是"往 ~/.dsh 里拷文件":
4
+ # ① 不往用户目录写任何东西(用户装一个包,不该在别处留副本);
5
+ # ② 没有副本就没有漂移/重名——曾经因为手工拷过一份,名单里出现过两个同名模式;
6
+ # ③ 包一升级,模式与 skill 跟着升级,不需要再跑一次安装器。
7
+ #
8
+ # 路径怎么算出来的:`!!js` 的求值作用是 `with (ctx) { return eval(expr) }`,
9
+ # 而 **`baseUrl` 就是 profile 目录**(实测:file:///…/.dsh/profiles/<profile>/),
10
+ # `require` 在那个作用域里是 undefined,所以只能靠 baseUrl 拼:
11
+ # node_modules/dsh-mc-art-panel/preset → <profile>/node_modules/dsh-mc-art-panel/preset
12
+ # replace 那一刀是给 Windows 的:URL.pathname 会给出 `/C:/Users/…`,去掉盘符前那个斜杠。
13
+
3
14
  - insert:
4
15
  - id: mcart-panel
5
16
  name: 'dsh-mc-art-panel'
17
+
18
+ # 「MC 模组工作室」模式:作为 agent-presets 的一个 root(trust: system = 只读、随包走)。
19
+ # 根按顺序扫描:shipped → 本行配置的 roots → 用户目录;先出现的赢同名 id,
20
+ # 所以就算用户以前手工装过同名模式,也不会出现两个。
21
+ - id: agent-presets
22
+ config:
23
+ default: standard
24
+ roots:
25
+ - path: !!js 'decodeURIComponent(new URL("node_modules/dsh-mc-art-panel/preset", baseUrl).pathname).replace(/^\/([A-Za-z]:\/)/, "$1")'
26
+ trust: system
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dsh-mc-art-panel",
3
- "version": "0.1.0",
4
- "description": "MC 资产面板:3D+物品栏、像素/结构编辑器、@ 提意见;配套 mc-mod / mc-art 两个 skill 与 GameTest 判定闭环",
3
+ "version": "0.1.2",
4
+ "description": "MC 资产面板 + 「MC 模组工作室」模式 + mc-mod skill:3D+物品栏、像素/结构编辑器、@ 提意见、GameTest 判定闭环",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
7
7
  "exports": {
@@ -11,6 +11,8 @@
11
11
  },
12
12
  "files": [
13
13
  "lib",
14
+ "preset",
15
+ "skill",
14
16
  "cordis.patch.yml",
15
17
  "build.mjs",
16
18
  "README.md"
@@ -0,0 +1,298 @@
1
+ # The `cordis` agent preset: the standard coding agent, plus the ability to
2
+ # read and write the runtime it is running in.
3
+ #
4
+ # It exists so a person can ask an agent to author another agent. Everything in
5
+ # `standard` is here unchanged; what is added is the self-referential Cordis
6
+ # toolset, a skill that teaches composition authoring, and a persona that says
7
+ # which of the two planes an edit belongs to.
8
+ #
9
+ # TRUST: `cordis_mount` evaluates model-written JavaScript against the live
10
+ # runtime, and a composition this agent writes becomes a preset other sessions
11
+ # mount. Treat a session on this preset as shell access — the toolset's own
12
+ # documentation makes the same statement.
13
+
14
+
15
+ # The preset's own persona, shadowing the deployment default for this agent.
16
+ # `{{model}}` and `{{cwd}}` resolve from the agent's own route and workspace.
17
+ - id: persona
18
+ name: '@deepseek-ai/dsh-persona'
19
+ config:
20
+ suffix: Your working directory is {{cwd}}.
21
+ prefix: |-
22
+ You are a coding agent powered by the {{model}} model, running on the DeepSeek Harness.
23
+
24
+ You can read and modify the harness you run on. Its composition is Cordis: every capability is a plugin row in a `cordis.yml`, and an agent preset is one such file mounted for a single session.
25
+
26
+ Two planes decide where an edit belongs. The HOST composition holds the registries and anything shared across sessions — persistence, the sandbox and approval stack, the model route, the subagent registry and its backends. An AGENT PRESET holds what one session contributes to those registries: its tools, its persona, its prompt sections. A row that publishes a service belongs in the host composition, or inside an `isolate` realm if the preset genuinely owns that service and nothing outside one agent reads it.
27
+
28
+ Presets you author live one directory per preset under `${DSH_HOME:-$HOME/.dsh}/.agent-presets/<id>/`; the roster reports each preset's real path, so take the one you edit from there. NEVER edit or delete the shipped preset install (the `agent-presets` directory beside the deployment's own config): it belongs to the deployment, an upgrade overwrites it, and corrupting the `cordis` preset would disable this very mode. To change what a shipped preset does, copy its composition into a new preset directory and edit the copy.
29
+
30
+ Load the `editing-cordis-compositions` skill before writing or changing a composition.
31
+
32
+ ── MC 模组工作室(这个模式把整条链路包在一起)──
33
+
34
+ 面板(看和改)+ 两个 skill(流程)+ 一个裁判(游戏自己判定)。头号规矩:
35
+ **抓不到错的检查不算检查**;做完要说清验证了什么、没验证什么。
36
+
37
+ - 工作区默认是这台机器上的 /home/gmh/mc-art(studio 仓库本身);若 {{cwd}} 就是它,
38
+ 直接用相对路径。相关仓库:面板与工具在本仓库;美术引擎是另一个仓库的 `mc-art` skill。
39
+ - 动手前先读 `mc-mod`(插件说明书 / 七阶段通用流程 / 版本矩阵 / 踩过的坑);
40
+ 碰像素之前先读 `mc-art`(确定性美术引擎)。
41
+ - **面板是以"装好的包"形式来的**(`dsh-mc-art-panel`,装进 profile 后每次开页面都在)。
42
+ 会话开始时先确认它在不在(右侧栏该有「MC 资产」)。不在就按顺序做两件事:
43
+ ① 让用户跑一次 `install.bat`(Windows)或 `sh install.sh`——它会顺手把面板装进 profile;
44
+ ② 或直接装发布好的包,然后重启 DSH:
45
+ `dsh plugin --profile web add dsh-mc-art-panel`
46
+ (国内加 `--registry=https://registry.npmmirror.com/`;不想依赖 npm 就用 Release 里的
47
+ tarball:https://github.com/GMH13552/dsh-mc-art/releases/latest/download/dsh-mc-art-panel.tgz )
48
+ **不要**在本模式里用 Cordis 工具动态发射面板:这个模式刻意不带 `tool-cordis`
49
+ (那个工具集会占用进程级的 Cordis inspect provider,和另一个用着它的会话直接冲突,
50
+ 冲突时是整行挂载失败)。面板源码在 tools/mcart-plugin/,装成包的那份由 panel/build.mjs 生成。
51
+ - 想改面板行为:改 `tools/mcart-plugin/{host,client}.js`(唯一的源码),跑 `node panel/build.mjs`
52
+ 重新生成 `panel/lib/`,再重装/刷新。**不要**手改 `panel/lib/` 里的生成物(有漂移门禁挡着)。
53
+ - 判定:`python tools/mcmod_gametest.py`(退出码 = 失败的必要测试数,
54
+ 服务端无窗口、跑完自动退出);改完任何检查再跑一次 `--fault`,证明它**还会说"不"**。
55
+ - 跨版本:先看 `mc-mod` 的版本矩阵——**1.12.2 没有 GameTest**,只有"能编译、服务端起来、
56
+ 日志干净";能判行为的版本从 1.17 起,Forge 要 39.0.88+。
57
+
58
+
59
+ - id: agent-instructions
60
+ name: '@deepseek-ai/dsh-agent-instructions'
61
+ config:
62
+ maxBytes: 65536
63
+
64
+ # ── shell ───────────────────────────────────────────────────────────────────
65
+
66
+ # `shell-env` stays in the HOST composition: `apps/cli/src/web.ts` injects it to
67
+ # publish `DSH_WEB_URL`/`DSH_WEB_MODE`, and a host row that injects a service is
68
+ # the criterion for host-plane ownership — injection resolves before any session
69
+ # exists, so there is no agent to key by. Behind a preset realm those variables
70
+ # never reached the model's shell at all. Both shell tools consume the host
71
+ # registry from here; their executors (`bash-sandbox`/`pwsh-sandbox`) are
72
+ # host-plane too.
73
+ - id: tool-bash
74
+ name: '@deepseek-ai/dsh-tool-bash'
75
+ disabled: !!js process.platform === 'win32'
76
+
77
+ - id: tool-pwsh
78
+ name: '@deepseek-ai/dsh-tool-pwsh'
79
+ disabled: !!js process.platform !== 'win32'
80
+
81
+ # ── filesystem ──────────────────────────────────────────────────────────────
82
+
83
+ # Both register into the host `tools` registry and provide nothing, so
84
+ # they need no realm. The `fs` service and its policy stay in the host.
85
+ - id: tool-fs
86
+ name: '@deepseek-ai/dsh-tool-fs'
87
+
88
+ - id: tool-fs-search
89
+ name: '@deepseek-ai/dsh-tool-fs-search'
90
+ config:
91
+ sampleOverCapGlobResults: false
92
+
93
+ # ── background jobs ────────────────────────────────────────────────────────
94
+
95
+ # Only the model-facing controls. The task REGISTRY stays on the host plane:
96
+ # its producers sit outside any realm this file could put it in — `tool-bash`
97
+ # above resolves it with `ctx.get`, and an entry-local realm here is invisible
98
+ # to every sibling row, so `run_in_background` would answer "background jobs
99
+ # unavailable" while these controls sat in the catalog. The registry is keyed by
100
+ # owning agent anyway, so one host instance serves every session. What a preset
101
+ # chooses is whether its agent can collect and stop background work at all.
102
+ - id: tool-jobs
103
+ name: '@deepseek-ai/dsh-tool-jobs'
104
+
105
+ # ── goals ───────────────────────────────────────────────────────────────────
106
+
107
+ # The goal service and session driver stay on the host plane, where the Gateway
108
+ # can resolve them. The human command and model-facing tool register into this
109
+ # preset's scoped layers.
110
+ - id: command-goal
111
+ name: '@deepseek-ai/dsh-command-goal'
112
+
113
+ - id: tool-goal
114
+ name: '@deepseek-ai/dsh-tool-goal'
115
+
116
+ # ── plan mode ───────────────────────────────────────────────────────────────
117
+
118
+ # Plan state is per-agent by nature, so an entry-local realm is not a
119
+ # workaround here — it is the correct lifetime.
120
+ - id: planning
121
+ name: cordis:group
122
+ group: true
123
+ isolate:
124
+ planMode: true
125
+ config:
126
+ - id: plan-mode
127
+ name: '@deepseek-ai/dsh-plan-mode'
128
+ config:
129
+ section: |
130
+ You are in plan mode. Stay in plan mode until exit_plan_mode succeeds or the user switches the session mode. Imperative language to implement changes means plan the implementation, not execute it. A user's conversational agreement — including an answer confirming something you asked — approves nothing and does not end plan mode; fold the confirmed decision into the plan and submit it through exit_plan_mode.
131
+
132
+ Explore first. Use non-mutating reads, searches, static analysis, and checks to ground the plan in the actual repository. Do not edit or write files, change configuration, run formatters or code generation that rewrites tracked files, commit, or otherwise carry out the plan. Prefer existing functions and patterns over new machinery.
133
+
134
+ The tool catalog stays the same across modes for request-cache stability. These plan-mode rules override any later tool description or guidance that suggests using mutation tools; those tools remain listed to keep the tool catalog unchanged. Do not use todo_write to track this planning phase: it tracks implementation after an approved plan, while the plan itself belongs in exit_plan_mode.
135
+
136
+ Resolve discoverable facts by inspection. Use ask_user_question only for user-owned choices or material ambiguity that inspection cannot answer. Do not ask the user where code lives or how current behavior works when you can find out.
137
+
138
+ Make the plan decision-complete: state the goal and success criteria; group implementation changes by subsystem; identify public API, schema, and data-flow changes; cover edge cases, failure modes, tests, acceptance criteria, and explicit assumptions. Keep it concise enough to review but detailed enough that another engineer can implement it without making design decisions.
139
+
140
+ When ready, call exit_plan_mode with the complete plan markdown, starting with a # title. Make exit_plan_mode the only and final tool call in that assistant response: it presents the plan for approval, and implementation begins only in a later step after approval. Do not paste the final plan as a plain reply or ask "should I proceed?" through prose or ask_user_question. If review rejects it, incorporate the feedback and present again. If the review channel is unavailable or aborted, stay in plan mode and ask the user to switch modes manually; do not proceed with implementation.
141
+
142
+ # ── compaction ──────────────────────────────────────────────────────────────
143
+
144
+ # `compaction-basic` reads `toolResultPrune` through `ctx.get`, so the pruner must
145
+ # share this realm rather than sit outside it.
146
+ #
147
+ # `tokenMeter` is deliberately NOT in this realm: the meter stays on the HOST
148
+ # plane, and the rows here resolve that one instance. It takes no configuration,
149
+ # keys every fold by Session, and owns the context-meter projection units the
150
+ # browser reads for every session — behind a realm those units would come and go
151
+ # with whichever presets happen to be mounted. What a preset chooses is whether
152
+ # its agent compacts at all, which is `compaction-basic` below.
153
+ - id: compaction
154
+ name: cordis:group
155
+ group: true
156
+ isolate:
157
+ compaction: true
158
+ toolResultPruner: true
159
+ config:
160
+ - id: compaction-basic
161
+ name: '@deepseek-ai/dsh-compaction-basic'
162
+
163
+ - id: command-compact
164
+ name: '@deepseek-ai/dsh-command-compact'
165
+
166
+ - id: tool-result-pruner
167
+ name: '@deepseek-ai/dsh-compaction-tool-result-pruner'
168
+ config:
169
+ thresholdChars: 8192
170
+ headChars: 4096
171
+ tailChars: 1024
172
+
173
+ # ── delegation and workflows ────────────────────────────────────────────────
174
+
175
+ # The `subagents` registry and its spawn/fork backends live in the HOST
176
+ # composition: the registry is a process singleton whose cross-session queries
177
+ # the api-proxy serves to the browser, and a provider name may only be
178
+ # registered once. This preset contributes the delegation TOOLS, which resolve
179
+ # that host registry.
180
+ #
181
+ # `workflows` is different — nothing outside an agent reads it — so every row
182
+ # that reaches it shares one entry-local realm here, and a consumer left
183
+ # outside would resolve a host registry this preset does not populate.
184
+ - id: delegation
185
+ name: cordis:group
186
+ group: true
187
+ isolate:
188
+ workflowEngine: true
189
+ config:
190
+ - id: tool-subagent-control
191
+ name: '@deepseek-ai/dsh-tool-subagent-control'
192
+
193
+ - id: tool-subagent-list-agents
194
+ name: '@deepseek-ai/dsh-tool-subagent-control/list-agents'
195
+
196
+ - id: tool-subagent
197
+ name: '@deepseek-ai/dsh-tool-subagent'
198
+ config:
199
+ provider: spawn
200
+ toolName: subagent
201
+ modelSelectionSettings: true
202
+ backgroundMode: continuable
203
+
204
+ # Fork omits model selection so provider/model stay equal to the parent and
205
+ # the inherited history remains eligible for KV Cache reuse. This preset
206
+ # keeps fork continuable; parent and child inherit the same messaging tool,
207
+ # while the parent id and return guidance follow the inherited history.
208
+ - id: tool-subagent-fork
209
+ name: '@deepseek-ai/dsh-tool-subagent'
210
+ config:
211
+ provider: fork
212
+ toolName: subagent_fork
213
+ backgroundMode: continuable
214
+
215
+ # Production dsh does not install these optional providers. Install the
216
+ # matching Bundle in this Profile and restart the Host, then copy this
217
+ # preset and remove `disabled` from the matching tool row. Host availability
218
+ # alone grants no tool.
219
+ - id: tool-subagent-codex
220
+ name: '@deepseek-ai/dsh-tool-subagent'
221
+ disabled: true
222
+ config:
223
+ provider: codex
224
+ toolName: subagent_codex
225
+ backgroundMode: one-shot
226
+ maxDepth: provider-managed
227
+
228
+ - id: tool-subagent-claude-code
229
+ name: '@deepseek-ai/dsh-tool-subagent'
230
+ disabled: true
231
+ config:
232
+ provider: claude-code
233
+ toolName: subagent_claude_code
234
+ backgroundMode: one-shot
235
+ maxDepth: provider-managed
236
+
237
+ - id: workflow-ptc
238
+ name: '@deepseek-ai/dsh-workflow-ptc'
239
+ config:
240
+ provider: spawn
241
+
242
+ - id: tool-workflow
243
+ name: '@deepseek-ai/dsh-tool-workflow'
244
+
245
+ # Off by default with the base row it mirrors: the tool description
246
+ # restricts `ralph` to runs the human explicitly asked for, and completion
247
+ # is a worker self-report, not an independent evaluation. Preset files take
248
+ # no patches, so a session that wants it duplicates this preset under a new
249
+ # id and drops `disabled`; the shipped root shadows a copy that reuses this
250
+ # id.
251
+ - id: tool-ralph
252
+ name: '@deepseek-ai/dsh-tool-ralph'
253
+ disabled: true
254
+ config:
255
+ subagentProvider: spawn
256
+ maxRounds: 64
257
+
258
+ # ── remaining model-facing rows ─────────────────────────────────────────────
259
+
260
+ - id: tool-ask-user
261
+ name: '@deepseek-ai/dsh-tool-ask-user'
262
+
263
+ - id: tool-todo
264
+ name: '@deepseek-ai/dsh-tool-todo'
265
+ config:
266
+ allowParallelInProgress: true
267
+
268
+ # The `web` service and its search provider stay in the host composition; only
269
+ # the model-facing tool is per-session.
270
+ - id: tool-web
271
+ name: '@deepseek-ai/dsh-tool-web'
272
+ config:
273
+ fetch: true
274
+ searchTimeoutMs: 60000
275
+
276
+ # ── self-modification ───────────────────────────────────────────────────────
277
+
278
+ # 这里**没有** tool-cordis:那个工具集注册的 Host Cordis inspect provider 是**进程级**的,
279
+ # 与另一个已经用着它的会话(比如 cordis 模式那个)不能共存——真撞过:
280
+ # failed to apply loader entry tool-cordis: Host Cordis inspect provider "Service" is already registered
281
+ # 撞了就是整行挂载失败。面板不需要它:面板是装进 profile 的真包(见人格里那一段)。
282
+
283
+ # 这个模式**自带** skill:`mc-mod` 与 `mc-art` 就放在本预设目录的 `skills/` 下
284
+ # (随 npm 包一起发;build.mjs 从仓库的 skills/ 与 mc-art 仓库的克隆复制过来)。
285
+ # `baseUrl` 是**预设自己的目录**,所以这条路径装到哪都成立——出厂 cordis 预设
286
+ # 就是这么带它那两份 composition skill 的。全局 skill 根(~/.dsh/skills)照旧生效。
287
+ - id: skill-filesystem
288
+ name: '@deepseek-ai/dsh-skill-filesystem'
289
+ config:
290
+ customSkillDirs:
291
+ - !!js "process.getBuiltinModule('node:url').fileURLToPath(new URL('skills/', baseUrl))"
292
+
293
+ # `tool-skill` 是加载 skill 的工具本身。
294
+ - id: tool-skill
295
+ name: '@deepseek-ai/dsh-tool-skill'
296
+
297
+ - id: present
298
+ name: '@deepseek-ai/dsh-tool-present'
@@ -0,0 +1,2 @@
1
+ name: MC 模组工作室
2
+ description: 做 Minecraft 模组的一体化模式:mcart 面板(3D+物品栏、像素编辑器、结构编辑器、@ 提意见)+ mc-mod / mc-art 两个 skill + GameTestServer 判定闭环。适合"从描述直接产出并验证 mod"。
@@ -0,0 +1,69 @@
1
+ # mc-art
2
+
3
+ A skill that lets a **text-only or multimodal model generate Minecraft art
4
+ assets**.
5
+
6
+ There is no model baked in. The engine scans asset roots, turns pixels into
7
+ evidence, rasterises a plan the model writes, and measures the result.
8
+ Everything needing judgement — what the asset should look like, which existing
9
+ art anchors it, whether the render is any good — belongs to the model, which
10
+ iterates in about a second per attempt with no API cost.
11
+
12
+ ## Install
13
+
14
+ Drop this directory (or symlink it) into a skills root:
15
+
16
+ ```bash
17
+ ln -s "$PWD" ~/.dsh/skills/mc-art
18
+ ```
19
+
20
+ ## Use
21
+
22
+ ```bash
23
+ M=bin/mc-art
24
+ JAR=<vanilla jar | mod jar | directory containing assets/>
25
+
26
+ $M list-groups --source "$JAR" --filter bow # what logical names exist
27
+ $M list-groups --source "$JAR" --extract minecraft:item/bow --to /tmp/refs
28
+ $M evidence --source "$JAR" --name bow --member bow_standby
29
+ $M render --plan my.plan.json --out outputs/mine
30
+ $M measure a.png b.png --baseline src.png
31
+ ```
32
+
33
+ `evidence` materialises the reference textures into `references/` (gitignored:
34
+ they are Mojang's, and content-addressed, so the same jar reproduces the same
35
+ paths).
36
+
37
+ ## What is here
38
+
39
+ | path | |
40
+ |---|---|
41
+ | `SKILL.md` | the procedure the model follows, and the plan contract |
42
+ | `bin/mc-art` | the whole tool surface: scan / evidence / render / pack / measure / model / entity / ingame |
43
+ | `mc_art/` | the engine — 20 modules, Pillow + stdlib, never touches a network |
44
+ | `examples/` | a working plan whose contour came out pixel-identical to vanilla |
45
+ | `layouts/` | worked examples. `mc-art model --emit-spec` reads any mob from any jar, so these are references to compare against rather than tables to reach for |
46
+ | `scripts/` | magnify / review_family / continuity |
47
+ | `tests/` | 123 tests over the engine |
48
+
49
+ Three modules are worth calling out. `vanilla_model` reads an entity model out of
50
+ compiled, usually obfuscated bytecode, because a 1.12 asset root has no entity
51
+ model files at all. `ingame` renders a block or entity model the way the game
52
+ does — same axes, same lighting, same UV corner order — so a delivery can be
53
+ looked at in the game's own view before it ships, with the vanilla cow, sheep and
54
+ slime shipped as controls that have to come out right first. `entity` and `modjava` are the other half: when the mob is one you are making, they turn a single box description into the atlas rectangles and the mod Java model class, so the texture and the code cannot drift.
55
+
56
+ ## Why there is no model inside
57
+
58
+ The predecessor of this skill (`mc-art-pipeline`) drove its own API calls for
59
+ routing, planning, drawing and review. Measured on that path:
60
+
61
+ - ~10 model calls per asset member at 45–90 s each, dominated by thinking
62
+ tokens (11k–33k per call, 2.7x spread on identical input);
63
+ - a vision "blind reviewer" that read a 16x16 bow as *trident* and a clock as
64
+ *music disc*, then drove repair loops chasing that noise;
65
+ - two whole family members lost to a completion budget exhausted by reasoning
66
+ before any output, and one to a truncated JSON body.
67
+
68
+ Replacing the model with the calling agent removes all of it, and lets the
69
+ agent look at the actual pixels instead of a summary of them.