@xiaobuyu/nodesign 0.0.1 → 0.0.3

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 (358) hide show
  1. package/README.md +156 -106
  2. package/bin/nodesign.js +0 -0
  3. package/package.json +1 -1
  4. package/server/api/README.md +45 -45
  5. package/server/api/_guard.js +75 -75
  6. package/server/api/admin.js +187 -187
  7. package/server/api/assets/docx-page.js +103 -103
  8. package/server/api/assets/helpers.js +42 -22
  9. package/server/api/assets/notes.js +194 -144
  10. package/server/api/assets.js +891 -896
  11. package/server/api/board.js +134 -57
  12. package/server/api/browse.js +138 -138
  13. package/server/api/canvas.js +444 -444
  14. package/server/api/chatai.js +324 -324
  15. package/server/api/exports/build-standalone.js +980 -980
  16. package/server/api/exports/cards.js +118 -118
  17. package/server/api/exports/docx-pdf.js +46 -46
  18. package/server/api/exports/export-page.js +142 -142
  19. package/server/api/exports/handoff.js +147 -147
  20. package/server/api/exports.js +690 -690
  21. package/server/api/instruction.js +75 -75
  22. package/server/api/me.js +116 -116
  23. package/server/api/memory.js +185 -185
  24. package/server/api/pending-changes.js +366 -366
  25. package/server/api/plugins.js +164 -164
  26. package/server/api/projects.js +220 -220
  27. package/server/api/publish.js +64 -64
  28. package/server/api/recent.js +73 -73
  29. package/server/api/sessions.js +589 -589
  30. package/server/api/skills.js +77 -77
  31. package/server/api/standalone-fit.js +168 -168
  32. package/server/api/turn-compose.js +180 -180
  33. package/server/api/turn-inflight.js +44 -44
  34. package/server/auth/README.md +17 -17
  35. package/server/auth/middleware.js +138 -138
  36. package/server/auth/origin-guard.js +71 -71
  37. package/server/auth/session.js +108 -108
  38. package/server/auth/tier.js +113 -113
  39. package/server/auth/users-store.js +348 -348
  40. package/server/edit/README.md +29 -29
  41. package/server/engine/README.md +113 -113
  42. package/server/engine/agent/agent-shared.js +550 -550
  43. package/server/engine/agent/auto-mode-default-hard-deny.txt +4 -4
  44. package/server/engine/agent/auto-mode-rules.js +78 -78
  45. package/server/engine/agent/context.js +418 -418
  46. package/server/engine/agent/events.js +465 -464
  47. package/server/engine/agent/hooks/canvas-validate.js +199 -199
  48. package/server/engine/agent/hooks/failure.js +120 -120
  49. package/server/engine/agent/hooks/file-events.js +75 -75
  50. package/server/engine/agent/hooks/lifecycle.js +233 -233
  51. package/server/engine/agent/hooks/post-canvas-focus.js +80 -80
  52. package/server/engine/agent/hooks/post-guidance.js +206 -206
  53. package/server/engine/agent/hooks/post-subagent-report.js +104 -104
  54. package/server/engine/agent/hooks/post-trim.js +58 -58
  55. package/server/engine/agent/hooks/pre-board-neighborhood.js +34 -34
  56. package/server/engine/agent/hooks/pre-defaults.js +84 -84
  57. package/server/engine/agent/hooks/pre-injectors.js +277 -277
  58. package/server/engine/agent/hooks/pre-performance-log-guard.js +78 -78
  59. package/server/engine/agent/hooks/pre-starter-files.js +61 -61
  60. package/server/engine/agent/hooks/pre-workspace-scope-guard.js +78 -78
  61. package/server/engine/agent/hooks/site-validate.js +94 -94
  62. package/server/engine/agent/hooks/tool-prompts.js +31 -31
  63. package/server/engine/agent/hooks/turn-state-memory.js +56 -56
  64. package/server/engine/agent/hooks/user-prompt-submit.js +258 -215
  65. package/server/engine/agent/hooks.js +354 -354
  66. package/server/engine/agent/init-contract.js +69 -69
  67. package/server/engine/agent/isolation.js +159 -159
  68. package/server/engine/agent/model-table.js +292 -292
  69. package/server/engine/agent/plugin-loader.js +266 -266
  70. package/server/engine/agent/prompts/nodesign-prelude.md +388 -336
  71. package/server/engine/agent/prompts/tools/ask-user-question-protocol.md +71 -71
  72. package/server/engine/agent/prompts/tools/direct-edit-protocol.md +98 -98
  73. package/server/engine/agent/prompts/tools/generate-image-cookbook.gemini-gateway.md +583 -583
  74. package/server/engine/agent/prompts/tools/generate-image-cookbook.md +483 -483
  75. package/server/engine/agent/prompts/tools/hybrid-reference.md +100 -100
  76. package/server/engine/agent/prompts/tools/paint-still-cookbook.md +270 -270
  77. package/server/engine/agent/prompts/tools/roll-film-cookbook.md +70 -70
  78. package/server/engine/agent/prompts/tools/site-reference.md +106 -106
  79. package/server/engine/agent/prompts/tools/tweaks-syntax.md +125 -125
  80. package/server/engine/agent/prompts/tools/vision-checker-dispatch.md +48 -48
  81. package/server/engine/agent/session-loop.js +1035 -1024
  82. package/server/engine/agent/session-model.js +164 -164
  83. package/server/engine/agent/skill.js +204 -204
  84. package/server/engine/agent/task-events.js +78 -78
  85. package/server/engine/agents/ds-extractor.md +132 -132
  86. package/server/engine/agents/explorer.md +190 -190
  87. package/server/engine/agents/index.js +230 -230
  88. package/server/engine/agents/schemas/design-system.json +156 -156
  89. package/server/engine/agents/schemas/tweak-schema.json +113 -113
  90. package/server/engine/agents/tweak-proposer.md +127 -127
  91. package/server/engine/agents/vision-checker.md +254 -254
  92. package/server/engine/browse/capture.js +422 -422
  93. package/server/engine/browse/card.js +137 -137
  94. package/server/engine/browse/handover.js +59 -59
  95. package/server/engine/browse/page-digest.js +119 -119
  96. package/server/engine/browse/refs.js +196 -196
  97. package/server/engine/browse/registry.js +307 -307
  98. package/server/engine/browse/screencast.js +170 -170
  99. package/server/engine/browse/state.js +121 -121
  100. package/server/engine/chatai/chat-log.js +79 -79
  101. package/server/engine/chatai/index.js +193 -193
  102. package/server/engine/chatai/openai-compat.js +152 -152
  103. package/server/engine/chatai/orchestrate.js +309 -309
  104. package/server/engine/chatai/perform.js +40 -40
  105. package/server/engine/chatai/summarize.js +79 -79
  106. package/server/engine/mcp/capability-gate.js +52 -52
  107. package/server/engine/mcp/index.js +351 -339
  108. package/server/engine/mcp/param-sanitizer.js +142 -142
  109. package/server/engine/mcp/tools/arrange-on-board.js +124 -124
  110. package/server/engine/mcp/tools/artifact-session.js +278 -278
  111. package/server/engine/mcp/tools/browse-computer.js +421 -421
  112. package/server/engine/mcp/tools/browse-find-batch.js +183 -183
  113. package/server/engine/mcp/tools/browse-screenshot.js +157 -157
  114. package/server/engine/mcp/tools/browse.js +480 -480
  115. package/server/engine/mcp/tools/build-docx.js +101 -101
  116. package/server/engine/mcp/tools/clear-pending-changes.js +99 -99
  117. package/server/engine/mcp/tools/create-on-board.js +152 -155
  118. package/server/engine/mcp/tools/crystallize-skill.js +168 -168
  119. package/server/engine/mcp/tools/edit-sketch.js +167 -0
  120. package/server/engine/mcp/tools/explain-style.js +237 -237
  121. package/server/engine/mcp/tools/export-handoff.js +133 -133
  122. package/server/engine/mcp/tools/expose-tweaks.js +149 -149
  123. package/server/engine/mcp/tools/generate-image.js +842 -842
  124. package/server/engine/mcp/tools/get-computed-styles.js +164 -164
  125. package/server/engine/mcp/tools/get-pending-changes.js +205 -205
  126. package/server/engine/mcp/tools/h3box-ssh.js +84 -84
  127. package/server/engine/mcp/tools/helpers/acquire-page.js +82 -82
  128. package/server/engine/mcp/tools/helpers/motion-lab.js +554 -554
  129. package/server/engine/mcp/tools/helpers/motion-scroll.js +112 -112
  130. package/server/engine/mcp/tools/helpers/perception-page.js +215 -215
  131. package/server/engine/mcp/tools/helpers/reference-download.js +103 -103
  132. package/server/engine/mcp/tools/helpers/rembg-bridge.py +80 -80
  133. package/server/engine/mcp/tools/helpers/shot-pipeline.js +280 -280
  134. package/server/engine/mcp/tools/highlight.js +68 -68
  135. package/server/engine/mcp/tools/list-pages.js +222 -222
  136. package/server/engine/mcp/tools/look-at-board.js +124 -0
  137. package/server/engine/mcp/tools/lookup-tags.js +59 -59
  138. package/server/engine/mcp/tools/navigate-to-page.js +60 -60
  139. package/server/engine/mcp/tools/organize-board.js +64 -64
  140. package/server/engine/mcp/tools/paint-still.js +434 -434
  141. package/server/engine/mcp/tools/pin-to-board.js +130 -130
  142. package/server/engine/mcp/tools/preview-deck.js +130 -130
  143. package/server/engine/mcp/tools/profile-scroll.js +305 -305
  144. package/server/engine/mcp/tools/publish-site.js +102 -102
  145. package/server/engine/mcp/tools/query-elements.js +195 -195
  146. package/server/engine/mcp/tools/read-board.js +190 -103
  147. package/server/engine/mcp/tools/read-document.js +93 -93
  148. package/server/engine/mcp/tools/read-page.js +264 -264
  149. package/server/engine/mcp/tools/read-tavern-json.js +143 -143
  150. package/server/engine/mcp/tools/read-user-view.js +59 -0
  151. package/server/engine/mcp/tools/record-decision.js +140 -140
  152. package/server/engine/mcp/tools/relate-on-board.js +112 -110
  153. package/server/engine/mcp/tools/report-issue.js +115 -115
  154. package/server/engine/mcp/tools/roll-film.js +266 -266
  155. package/server/engine/mcp/tools/screenshot-docx.js +138 -138
  156. package/server/engine/mcp/tools/screenshot-url.js +195 -195
  157. package/server/engine/mcp/tools/screenshot.js +583 -583
  158. package/server/engine/mcp/tools/sketch-on-board.js +337 -0
  159. package/server/engine/mcp/tools/tier-gate.js +96 -96
  160. package/server/engine/mcp/tools/trace-motion.js +215 -215
  161. package/server/engine/mcp/tools/web-search.js +548 -548
  162. package/server/engine/mcp/tools/write-on-board.js +130 -0
  163. package/server/engine/motion/inventory.js +349 -349
  164. package/server/engine/perception/session.js +235 -235
  165. package/server/engine/plugins/nodesign/.claude-plugin/plugin.json +5 -5
  166. package/server/engine/plugins/nodesign/skills/deskskill-engine-mini/SKILL.md +199 -192
  167. package/server/engine/plugins/nodesign/skills/deskskill-engine-mini/canvas.template.html +667 -667
  168. package/server/engine/plugins/nodesign/skills/deskskill-engine-mini/patterns/hybrid-grid.md +22 -22
  169. package/server/engine/plugins/nodesign/skills/deskskill-engine-mini/patterns/image-led-cover.md +25 -25
  170. package/server/engine/plugins/nodesign/skills/deskskill-engine-mini/patterns/portrait.md +23 -23
  171. package/server/engine/plugins/nodesign/skills/deskskill-engine-mini/patterns/quote-backdrop.md +21 -21
  172. package/server/engine/plugins/nodesign/skills/deskskill-engine-mini/patterns/section-divider.md +23 -23
  173. package/server/engine/plugins/nodesign/skills/deskskill-engine-mini/patterns/text-led.md +21 -21
  174. package/server/engine/plugins/nodesign/skills/docx-craft/SKILL.md +169 -162
  175. package/server/engine/plugins/nodesign/skills/docx-craft/references/token-schema.md +407 -407
  176. package/server/engine/plugins/nodesign/skills/docx-craft//346/226/207/346/241/243.template.json +80 -80
  177. package/server/engine/plugins/nodesign/skills/rp-craft/SKILL.md +235 -228
  178. package/server/engine/plugins/nodesign/skills/rp-craft/patterns//346/274/224/345/207/272/351/241/265-/346/234/200/345/260/217/345/256/236/347/216/260.html +78 -78
  179. package/server/engine/plugins/nodesign/skills/rp-craft//346/274/224/345/207/272.template.js +268 -268
  180. package/server/engine/plugins/nodesign/skills/site-craft/SKILL.md +330 -323
  181. package/server/engine/plugins/nodesign/skills/site-craft/patterns/build-lane.md +134 -134
  182. package/server/engine/plugins/nodesign/skills/site-craft/patterns/cutout-collage.md +61 -61
  183. package/server/engine/plugins/nodesign/skills/site-craft/patterns/mock-app.md +163 -163
  184. package/server/engine/plugins/nodesign/skills/site-craft/patterns/page-transitions.md +86 -86
  185. package/server/engine/runs/active-runs.js +698 -698
  186. package/server/engine/runs/board-tasklist.js +130 -0
  187. package/server/engine/runs/live-turn.js +252 -252
  188. package/server/engine/runs/store.js +364 -364
  189. package/server/engine/runs/turn-relay.js +217 -217
  190. package/server/engine/runtime/workspace.js +164 -164
  191. package/server/index.js +3 -0
  192. package/server/lib/artifact-file-path.js +80 -80
  193. package/server/lib/artifact-target.js +284 -284
  194. package/server/lib/asset-refs.js +239 -239
  195. package/server/lib/async-queue.js +104 -104
  196. package/server/lib/auto-relations.js +130 -130
  197. package/server/lib/binding-types.js +72 -60
  198. package/server/lib/board-graph-export.js +191 -0
  199. package/server/lib/board-groups.js +167 -0
  200. package/server/lib/board-hero.js +76 -0
  201. package/server/lib/board-kind-sizes.js +85 -62
  202. package/server/lib/board-relations.js +133 -133
  203. package/server/lib/browse-proxy.js +180 -180
  204. package/server/lib/canvas-id.js +36 -36
  205. package/server/lib/chalk.js +121 -0
  206. package/server/lib/cover.js +227 -227
  207. package/server/lib/danbooru-tags.js +291 -291
  208. package/server/lib/doc-extract.js +156 -156
  209. package/server/lib/docx/build-from-source.js +260 -260
  210. package/server/lib/docx/build.js +490 -490
  211. package/server/lib/docx/dump-styles.js +287 -287
  212. package/server/lib/docx/fonts/nodesign-cjk.conf +164 -164
  213. package/server/lib/docx/merge-runs.js +129 -129
  214. package/server/lib/docx/numbering.js +218 -218
  215. package/server/lib/docx/order.js +152 -152
  216. package/server/lib/docx/rawzip.js +172 -172
  217. package/server/lib/docx/render.js +92 -92
  218. package/server/lib/docx/text-lint.js +225 -225
  219. package/server/lib/docx/tokens.js +335 -335
  220. package/server/lib/docx/units.js +29 -29
  221. package/server/lib/docx/xml.js +291 -291
  222. package/server/lib/docx-pages.js +187 -187
  223. package/server/lib/export-collect.js +289 -289
  224. package/server/lib/export-package.js +210 -210
  225. package/server/lib/html-srcset.js +145 -145
  226. package/server/lib/image-variant.js +460 -460
  227. package/server/lib/ingress/forward-openai-chat.js +305 -305
  228. package/server/lib/ingress/openai-chat.js +491 -491
  229. package/server/lib/ingress/session-notice.js +66 -66
  230. package/server/lib/ingress/session-routes.js +68 -68
  231. package/server/lib/ingress/slot-probe.js +130 -130
  232. package/server/lib/ingress/upstream-billing.js +52 -52
  233. package/server/lib/ingress/upstream-fail-streak.js +72 -72
  234. package/server/lib/ingress/upstream-truncation.js +48 -48
  235. package/server/lib/issues-store.js +182 -182
  236. package/server/lib/kinds/deck.js +72 -72
  237. package/server/lib/kinds/docx.js +283 -283
  238. package/server/lib/kinds/file-kinds.js +113 -113
  239. package/server/lib/kinds/index.js +202 -202
  240. package/server/lib/kinds/site.js +161 -161
  241. package/server/lib/model-ingress.js +543 -543
  242. package/server/lib/moderation.js +255 -255
  243. package/server/lib/notice-store.js +103 -103
  244. package/server/lib/plugin-install.js +104 -104
  245. package/server/lib/plugin-validator.js +721 -721
  246. package/server/lib/publish-store.js +115 -115
  247. package/server/lib/quick-summary.js +52 -52
  248. package/server/lib/quota.js +270 -270
  249. package/server/lib/rate-window.js +29 -29
  250. package/server/lib/reference-assets.js +92 -92
  251. package/server/lib/region-shot.js +135 -135
  252. package/server/lib/safe-path.js +73 -73
  253. package/server/lib/sdk-session.js +33 -33
  254. package/server/lib/showcase-store.js +92 -92
  255. package/server/lib/site-publish.js +465 -465
  256. package/server/lib/sketch-layout.js +277 -0
  257. package/server/lib/ssrf-guard.js +432 -432
  258. package/server/lib/task-scan.js +158 -158
  259. package/server/lib/tavern-json.js +154 -154
  260. package/server/lib/video-variant.js +237 -237
  261. package/server/lib/workspace-path.js +33 -33
  262. package/server/ops/fix-sdk-musl.mjs +40 -40
  263. package/server/ops/install-macos-fonts.sh +114 -114
  264. package/server/ops/macos-fonts.conf +336 -336
  265. package/server/ops/sandbox-shim/bwrap +57 -57
  266. package/server/projects/assets-summary.js +119 -119
  267. package/server/projects/auto-name.js +53 -53
  268. package/server/projects/board-limits.js +12 -0
  269. package/server/projects/board-sanitize.js +252 -0
  270. package/server/projects/board-store.js +507 -640
  271. package/server/projects/move-entry.js +103 -103
  272. package/server/projects/store.js +270 -270
  273. package/server/projects/ui-config.js +60 -54
  274. package/server/projects/viewpoint-store.js +78 -0
  275. package/server/projects/workspace-templates.js +53 -53
  276. package/server/projects/workspace.js +1025 -1025
  277. package/server/runtime/local-config.js +177 -177
  278. package/server/runtime/profile.js +72 -72
  279. package/server/services/rembg-service.py +334 -334
  280. package/server/shared/README.md +25 -25
  281. package/server/shared/deck.js +54 -54
  282. package/server/shared/time.js +49 -49
  283. package/server/style-pipeline/README.md +53 -53
  284. package/server/ws/broker.js +39 -36
  285. package/server/ws/browse-channel.js +177 -177
  286. package/server/ws/index.js +386 -386
  287. package/web/README.md +89 -89
  288. package/web/dist/assets/BrowserWindow-P_vIdh-G.js +11 -0
  289. package/web/dist/assets/{DeckWindow-4G0xX7P3.js → DeckWindow-BpLv5082.js} +3 -3
  290. package/web/dist/assets/{DocxWindow-BXQsoPkh.js → DocxWindow-DSAU1-tD.js} +4 -4
  291. package/web/dist/assets/MermaidBlock-DR1GikCv.js +313 -0
  292. package/web/dist/assets/SiteWindow-92uBuRRR.js +18 -0
  293. package/web/dist/assets/abnfDiagram-VCTEODGH-uA8Esix4.js +1 -0
  294. package/web/dist/assets/arc-D_khH_xN.js +1 -0
  295. package/web/dist/assets/architectureDiagram-5GKGNRK7-DydJHqOt.js +36 -0
  296. package/web/dist/assets/blockDiagram-NRAW4CY4-B7wBbKiW.js +129 -0
  297. package/web/dist/assets/c4Diagram-UCG6FXSJ-6mrH0x7Y.js +38 -0
  298. package/web/dist/assets/channel-DGkccMO1.js +1 -0
  299. package/web/dist/assets/chunk-2Q5K7J3B-Cuikho5Q.js +1 -0
  300. package/web/dist/assets/chunk-5VM5RSS4-3-KZ5AUz.js +15 -0
  301. package/web/dist/assets/chunk-F27PBJKO-Bkwq2gGU.js +1 -0
  302. package/web/dist/assets/chunk-G27WJ6UU-BLyQzdGE.js +231 -0
  303. package/web/dist/assets/chunk-JWPE2WC7-B7HxxQds.js +1 -0
  304. package/web/dist/assets/chunk-LCL6LL3I-CtXrnUwF.js +206 -0
  305. package/web/dist/assets/chunk-POPQ4Y6H-dxddZlXt.js +1 -0
  306. package/web/dist/assets/chunk-SVP7TREG-DpkmrgHn.js +88 -0
  307. package/web/dist/assets/chunk-XXDRQBXY-BwZ7RbpQ.js +1 -0
  308. package/web/dist/assets/classDiagram-DTDB5LWJ-BGscw3OD.js +1 -0
  309. package/web/dist/assets/classDiagram-v2-JRS7N3AN-BGscw3OD.js +1 -0
  310. package/web/dist/assets/cose-bilkent-JH36ORCC-DGFOsMUt.js +1 -0
  311. package/web/dist/assets/cynefin-OW5HDTMX-DUwn3ehS.js +178 -0
  312. package/web/dist/assets/cynefinDiagram-5FMLGOSQ-DlLAOZ9x.js +62 -0
  313. package/web/dist/assets/cytoscape.esm-BjAbmLdb.js +331 -0
  314. package/web/dist/assets/dagre-3AP2YEHR-CyourLfz.js +4 -0
  315. package/web/dist/assets/defaultLocale-DX6XiGOO.js +1 -0
  316. package/web/dist/assets/diagram-S7CK7UJ4-BTMbx2np.js +30 -0
  317. package/web/dist/assets/diagram-UQ7AKVKN-UK94_1-P.js +41 -0
  318. package/web/dist/assets/diagram-VSXAHHWV-C7zS-v9v.js +3 -0
  319. package/web/dist/assets/diagram-VX7I27RA-DKJRa6CK.js +24 -0
  320. package/web/dist/assets/diagram-Z3DM3KII-kUbAfGAp.js +24 -0
  321. package/web/dist/assets/ebnfDiagram-PWID7BFC-CVW16_vb.js +1 -0
  322. package/web/dist/assets/erDiagram-SSCWMZ5O-BRQMFQ5y.js +99 -0
  323. package/web/dist/assets/flowDiagram-A5DVABFB-S34LpLtK.js +168 -0
  324. package/web/dist/assets/ganttDiagram-EL5Y4UJY-BFiqk1-G.js +292 -0
  325. package/web/dist/assets/gitGraphDiagram-WWUBYQGX-LZsrdyyv.js +106 -0
  326. package/web/dist/assets/index-GAamh1p4.js +2152 -0
  327. package/web/dist/assets/infoDiagram-RXCK75RN-0DvN6KIp.js +2 -0
  328. package/web/dist/assets/init-Gi6I4Gst.js +1 -0
  329. package/web/dist/assets/ishikawaDiagram-5VMMS53U-CaY3A-Bx.js +70 -0
  330. package/web/dist/assets/journeyDiagram-EYS64GPL-BBeiaCrj.js +139 -0
  331. package/web/dist/assets/kanban-definition-3QL26DDD-ux42DRXQ.js +89 -0
  332. package/web/dist/assets/layout-CnXiF_NB.js +1 -0
  333. package/web/dist/assets/linear-BMW0u6G6.js +1 -0
  334. package/web/dist/assets/mindmap-definition-FBJOCRG2-hUxSpdKn.js +96 -0
  335. package/web/dist/assets/ordinal-Cboi1Yqb.js +1 -0
  336. package/web/dist/assets/pegDiagram-XKGWAZYB-aCaQPH0w.js +1 -0
  337. package/web/dist/assets/{pending-edit-apply-DTjo2geW.js → pending-edit-apply-AcdOQ9Ij.js} +6 -6
  338. package/web/dist/assets/pieDiagram-E7YTZNPT-CmOEZ8zg.js +39 -0
  339. package/web/dist/assets/quadrantDiagram-AXDQQJYC-VW6fAhsV.js +7 -0
  340. package/web/dist/assets/railroadDiagram-O6MQD6OU-CKJ7Ba5K.js +1 -0
  341. package/web/dist/assets/requirementDiagram-EFPCY7ZU-pNGkq9Vw.js +84 -0
  342. package/web/dist/assets/{rotate-cw-LMT3x1Zj.js → rotate-cw-KAfChbGV.js} +1 -1
  343. package/web/dist/assets/sankeyDiagram-P5KCCOFB-BIMmDTfZ.js +40 -0
  344. package/web/dist/assets/sequenceDiagram-WJ2MYXX4-BBW7wzKY.js +162 -0
  345. package/web/dist/assets/sizeCapture-X5ZJPWSS-DdkXmLYR.js +1 -0
  346. package/web/dist/assets/{square-dashed-mouse-pointer-CBoAkfhi.js → square-dashed-mouse-pointer-CDUlhUP7.js} +1 -1
  347. package/web/dist/assets/stateDiagram-HBIQ2CUA-W313Uz16.js +1 -0
  348. package/web/dist/assets/stateDiagram-v2-4QOOHH4V-DDhJBZzf.js +1 -0
  349. package/web/dist/assets/swimlanes-XN3QIQJK-C29TL26K.js +1 -0
  350. package/web/dist/assets/swimlanesDiagram-VK2B7HYN-BfN-Xdmu.js +8 -0
  351. package/web/dist/assets/timeline-definition-24CTP7MA-CF0JMObX.js +120 -0
  352. package/web/dist/assets/vennDiagram-4TSXK5OY-DrDFsaH3.js +34 -0
  353. package/web/dist/assets/wardleyDiagram-VM6X3IG4-CVrnRIS_.js +78 -0
  354. package/web/dist/assets/xychartDiagram-S5SC5T6Z-BvkN1zsT.js +7 -0
  355. package/web/dist/index.html +17 -17
  356. package/web/dist/assets/BrowserWindow-Dc7J7CYc.js +0 -11
  357. package/web/dist/assets/SiteWindow-D6eS-2gM.js +0 -18
  358. package/web/dist/assets/index-Cbl3ATvp.js +0 -2125
@@ -1,339 +1,351 @@
1
- /**
2
- * server/engine/mcp/index.js — Nodesign 内置 MCP server
3
- *
4
- * 暴露给 agent 的自定义工具集(in-process,via SDK 的 createSdkMcpServer):
5
- *
6
- * 感知层(playwright headless 跑出真实渲染元数据):
7
- * screenshot_canvas / list_pages / read_page / query_elements / get_computed_styles
8
- * 控制层(emit 事件让前端同步):
9
- * navigate_to_page / highlight / preview_deck
10
- * 反馈层(用户在 canvas 上的直接编辑 + 评论 buffer):
11
- * get_pending_changes / clear_pending_changes
12
- * 产物层(NoDesign 差异化能力):
13
- * expose_tweaks / export_handoff / record_decision
14
- * 研究层:
15
- * web_search(4 provider,CJK auto baidu)
16
- *
17
- * 调用约定(SDK 自动给 tool name 加前缀):
18
- * tool 名在 agent 端是 mcp__nodesign__<tool>,比如 mcp__nodesign__screenshot_canvas
19
- *
20
- * 实例化策略:
21
- * 每个 runAgent 创建一个新的 MCP server 实例(through createNodesignMcpServer)。
22
- * 开销小(in-process,没起 process),但能让 deps(workspaceRoot / projectId / ctx)
23
- * 绑死到当前 turn 的上下文,避免 cross-talk。
24
- *
25
- * 安全:
26
- * tool handler 在 SDK 进程内(本服务器进程)跑,不通过 stdio/sse/http。
27
- * handler 自己不做沙盒,由 PreToolUse hook + workspace cwd 隔离兜底。
28
- */
29
-
30
- import { createSdkMcpServer } from '@anthropic-ai/claude-agent-sdk';
31
- import { withParamSanitizer } from './param-sanitizer.js';
32
- import { withCapabilityGate } from './capability-gate.js';
33
- import { makeScreenshotCanvasTool } from './tools/screenshot.js';
34
- import { makeScreenshotUrlTool } from './tools/screenshot-url.js';
35
- import { makeExportHandoffTool } from './tools/export-handoff.js';
36
- import { makeRecordDecisionTool } from './tools/record-decision.js';
37
- import { makeWebSearchTool } from './tools/web-search.js';
38
- import { withTierGate } from './tools/tier-gate.js'; // 档位闸包装器(auth/tier.js;按项目 owner)
39
- import { makeReadPageTool } from './tools/read-page.js';
40
- import { makeListPagesTool } from './tools/list-pages.js';
41
- import { makeQueryElementsTool } from './tools/query-elements.js';
42
- import { makeProfileScrollTool } from './tools/profile-scroll.js';
43
- import { makeExplainStyleTool } from './tools/explain-style.js';
44
- import { makeTraceMotionTool } from './tools/trace-motion.js';
45
- import {
46
- makeBrowserNavigateTool, makeBrowserReadTool, makeBrowserClickTool,
47
- makeBrowserRequestHelpTool, makeBrowserCaptureTool,
48
- } from './tools/browse.js';
49
- import { makeBrowserScreenshotTool } from './tools/browse-screenshot.js';
50
- import { makeBrowserComputerTool } from './tools/browse-computer.js';
51
- import { makeBrowserFindTool, makeBrowserBatchTool } from './tools/browse-find-batch.js';
52
- import { makeArtifactOpenTool, makeArtifactComputerTool, makeArtifactFindTool, makeArtifactMotionTool, makeArtifactBatchTool } from './tools/artifact-session.js';
53
- import { makeGetComputedStylesTool } from './tools/get-computed-styles.js';
54
- import { makeNavigateToPageTool } from './tools/navigate-to-page.js';
55
- import { makeHighlightTool } from './tools/highlight.js';
56
- import { makePreviewDeckTool } from './tools/preview-deck.js';
57
- import { makeBuildDocxTool } from './tools/build-docx.js';
58
- import { makeExposeTweaksTool } from './tools/expose-tweaks.js';
59
- import { makeGetPendingChangesTool } from './tools/get-pending-changes.js';
60
- import { makeClearPendingChangesTool } from './tools/clear-pending-changes.js';
61
- import { makeGenerateImageTool } from './tools/generate-image.js';
62
- import { makeRemoveBackgroundTool } from './tools/remove-background.js';
63
- import { makePinToBoardTool } from './tools/pin-to-board.js';
64
- import { makeRelateOnBoardTool } from './tools/relate-on-board.js';
65
- import { makeReadBoardTool } from './tools/read-board.js';
66
- import { makeArrangeOnBoardTool } from './tools/arrange-on-board.js';
67
- import { makeCreateOnBoardTool } from './tools/create-on-board.js';
68
- import { makeOrganizeBoardTool } from './tools/organize-board.js';
69
- import { makeReadDocumentTool } from './tools/read-document.js';
70
- import { makeReadTavernJsonTool } from './tools/read-tavern-json.js';
71
- import { makeDeliverFilesTool } from './tools/deliver-files.js';
72
- import { makeCrystallizeSkillTool } from './tools/crystallize-skill.js';
73
- import { makePublishSiteTool } from './tools/publish-site.js';
74
- import { makeReportIssueTool } from './tools/report-issue.js';
75
- import { makeRollFilmTool } from './tools/roll-film.js';
76
- import { makePaintStillTool } from './tools/paint-still.js';
77
- import { makeLookupTagsTool } from './tools/lookup-tags.js';
78
-
79
- /**
80
- * 创建 Nodesign MCP server,绑定当前 run 的依赖。
81
- *
82
- * @param {object} deps
83
- * @param {string} deps.workspaceRoot 绝对路径,project workspace(sessions/<sid>/)
84
- * @param {string} [deps.sharedRoot] project shared/ 根(跨 session 共享 assets / .claude)
85
- * @param {string} [deps.projectId]
86
- * @param {string} [deps.sessionId] NoDesign sessionId(活跃产物指针 / 会话级锁 / 出处记账用)
87
- * @param {import('../agent/context.js').AgentContext} [deps.ctx] EventBus 入口
88
- * @returns SDK MCP server config(喂给 query options.mcpServers)
89
- */
90
- // 常驻 schema 白名单(2026-07-23 订阅模式 token 瘦身):
91
- // 高频 + schema 小的工具第一 turn 就注入 prompt;不在名单里的走 SDK 默认
92
- // deferred —— system prompt 只留工具名,agent ToolSearch 按需拉 schema
93
- // (需要 ENABLE_TOOL_SEARCH=true + allowlist ToolSearch,见 session-loop)。
94
- // 实测 defer 掉 generate_image/web_search/remove_background 等 6 个胖工具
95
- // ~80k 字符常驻 schema。prelude 的工具速查表仍列全部工具名 + 一句话用途,
96
- // agent 知道存在什么、需要时先 ToolSearch("select:mcp__nodesign__<tool>")。
97
- // (kimi 时代曾全局 alwaysLoad —— kimi 不认 ToolSearch;claude 系模型原生受训,可放心 defer)
98
- const ALWAYS_LOAD_TOOLS = new Set([
99
- 'screenshot_canvas', 'read_page', 'list_pages', 'query_elements',
100
- 'get_computed_styles', 'navigate_to_page', 'highlight', 'preview_deck',
101
- 'record_decision', 'get_pending_changes', 'clear_pending_changes',
102
- // screenshot_url 常驻:explorer 显式 tools 列表没有 ToolSearchdefer 了它就
103
- // 永远拉不到 schema;schema 本身很小(4 字段),常驻成本可忽略
104
- 'screenshot_url',
105
- // 浏览通道六件(2026-08-18 当天从 deferred 改常驻;08-21 加到九件,见下)。
106
- //
107
- // 它们最初跟着「新工具默认 deferred」的习惯走,而那条习惯的依据是**成本**:
108
- // defer 掉的是 expose_tweaks / paint_still / roll_film 那种十万字符级的胖子。
109
- // 这六个实测 description 合计 4980 字符、连参数区 ≈ 6.9k —— 比那几个小
110
- // 30~100 倍,塞进被缓存的 system prompt 每轮增量约等于零。
111
- //
112
- // deferred 的代价是具体的:agent 只看得到**名字**。`browser_capture`
113
- // 这个名字一个字都没说它能带回调色板、字体、命中的 CSS 规则和结构三数 ——
114
- // 于是它不会去搜这个 schema,做 deck / 做文档的会话里整条浏览通道等于不存在
115
- // (只有加载了 site-craft skill 才会被点名)。**名字自解释的工具可以 defer,
116
- // 卖点藏在描述里的不能。**
117
- 'browser_navigate', 'browser_read', 'browser_click', 'browser_screenshot',
118
- 'browser_request_help', 'browser_capture',
119
- // 08-21 加的三件(坐标/引用级操作 + 词法找元 + 一次往返跑一串)。同一条理由:
120
- // browser_batch 的卖点"省掉模型往返"和 browser_find 的"ref 比像素稳"都在描述里,
121
- // 名字本身不卖;三件描述合计 ≈ 5.5k 字符,缓存里每轮增量约等于零。
122
- 'browser_computer', 'browser_find', 'browser_batch',
123
- // 08-21 产物会话五件:成品检查的交互半边(状态跨调用留着)。artifact_batch 的卖点
124
- // "一趟跑完 + 结尾截图"和 live:true 的存在都只在描述里说,常驻。
125
- 'artifact_open', 'artifact_computer', 'artifact_find', 'artifact_batch', 'artifact_motion',
126
- ]);
127
-
128
- export function createNodesignMcpServer({ workspaceRoot, sharedRoot, projectId, sessionId, ctx } = {}) {
129
- // 浏览通道里能被 browser_batch 串起来的七件:先建一次,batch 拿**同一批实例**
130
- // (projectId/ctx 绑在 handler 里,不能再造第二份)。只有 request_help 不进
131
- // batch(它阻塞等人);capture 在里面 —— 逐页采 token 正是 batch 要省的那种回合。
132
- const browseBatchable = [
133
- makeBrowserNavigateTool({ projectId, ctx }),
134
- makeBrowserReadTool({ projectId }),
135
- makeBrowserClickTool({ projectId }),
136
- makeBrowserScreenshotTool({ projectId, workspaceRoot }),
137
- // 采集:把可复用的东西(调色板/字体/CSS/结构骨架/截图)落进
138
- // assets/references/web/ + 出处 sidecar —— 下个会话还在
139
- makeBrowserCaptureTool({ projectId, workspaceRoot, sessionId, ctx }),
140
- // 坐标/引用级指针与键盘 + 词法找元(08-21,形状照 browser_toolset_20260801)
141
- makeBrowserComputerTool({ projectId, ctx }),
142
- makeBrowserFindTool({ projectId }),
143
- ];
144
- // 五个能骑到产物会话上(live:true)的量具:先建一次,artifact_batch 拿同一批实例
145
- const screenshotCanvas = makeScreenshotCanvasTool({ workspaceRoot, projectId, sessionId, ctx });
146
- const queryElements = makeQueryElementsTool({ workspaceRoot, projectId, sessionId, ctx });
147
- const getComputedStyles = makeGetComputedStylesTool({ workspaceRoot, projectId, sessionId, ctx });
148
- const explainStyle = makeExplainStyleTool({ workspaceRoot, projectId, sessionId });
149
- const traceMotion = makeTraceMotionTool({ workspaceRoot, projectId, sessionId });
150
- // 产物会话四件(engine/perception/session.js):artifact_open / computer / find / motion
151
- const artifactSessionTools = [
152
- makeArtifactOpenTool({ projectId, workspaceRoot, sessionId }),
153
- makeArtifactComputerTool({ projectId }),
154
- makeArtifactFindTool({ projectId }),
155
- // 自己的产物靠什么在动:跟 browser_capture motion 同一份引擎(engine/motion/inventory.js)
156
- makeArtifactMotionTool({ projectId, workspaceRoot, sessionId }),
157
- ];
158
- const tools = [
159
- // C9 screenshot_canvas — playwright headless 截图 → image content block
160
- screenshotCanvas,
161
-
162
- // screenshot_url — 外部 URL 截图(2026-07-29)。explorer 找视觉参考不再
163
- // 只能 WebFetch 文本转述;主 agent 也能直接看参考站。http/https only。
164
- makeScreenshotUrlTool({ projectId, ctx }),
165
-
166
- // deliver_files — agent 挑好的产物直接进用户浏览器下载列表(emit run.download_ready)
167
- makeDeliverFilesTool({ workspaceRoot, projectId, sessionId, ctx }),
168
-
169
- // read_document Word / Excel / PowerPoint 的读取口(2026-08-07)。
170
- // 普通 Read 读这三种只会拿到二进制乱码**而且不报错**,agent 会拿着空气
171
- // 往下干。PDF 不在此列:Read 原生支持,真跑验过。
172
- makeReadDocumentTool({ workspaceRoot, sharedRoot }),
173
-
174
- // 酒馆 JSON 读取口:预设/角色卡/世界书先摘要再取正文(Read 会被 460KB 预设撑爆)
175
- makeReadTavernJsonTool({ workspaceRoot, sharedRoot }),
176
-
177
- // C10 export_handoff — 复用 exports.js 的 buildHandoffZip,写到 workspace/exports/
178
- makeExportHandoffTool({ workspaceRoot, sharedRoot, projectId, sessionId, ctx }),
179
-
180
- // C11 record_decision — 写入 spec.json decisions[] 设计意图档案
181
- makeRecordDecisionTool({ workspaceRoot, sessionId, ctx }),
182
-
183
- // crystallize_skill 把探索出来的方法论固化成用户自己的 skill + 作品进橱窗
184
- // (2026-07-30)。用户明确要求才调;写的是判断依据不是成品 HTML。
185
- makeCrystallizeSkillTool({ projectId, sessionId, ctx }),
186
-
187
- // publish_site — 站点一键上线 Cloudflare Pages(2026-08-02)。用户明确要求
188
- // 才调(发公网是外发动作);额度按项目 owner 算,与站点窗按钮共用一套闸门。
189
- makePublishSiteTool({ projectId }),
190
-
191
- // roll_film — 自部署 MiniMax-H3 视频产线(2026-08-08)。默认走站主 5090
192
- // 盒子(h3box over SSH;Modal 余额告急降备用档,NODESIGN_FILM_BACKEND=modal
193
- // 显式才走,绝不自动回退烧余额);配方恒定 Turbo8步 ≤12.25s;试用号拒
194
- // (owner 闸门同 publish_site)。视觉 QC 归用户,工具只回文本路径。
195
- makeRollFilmTool({ workspaceRoot, sharedRoot, projectId, sessionId, ctx }),
196
-
197
- // paint_still 站主本地 GPU 盒子生图(NoobAI/Anima,2026-08-08)。盒子
198
- // 在线才可用(NODESIGN_H3BOX_SSH);动漫向/视频关键帧首选,通用生图仍走
199
- // generate_image。视觉 QC 归用户。
200
- makePaintStillTool({ workspaceRoot, sharedRoot, projectId, sessionId, ctx }),
201
-
202
- // lookup_tagsdanbooru 标签画前查询(2026-08-20)。paint_still 画完的体检
203
- // 只能事后说"这批图别信";这个把查的动作挪到画前,配手册的起手纪律
204
- // (先理解用户要什么 想候选标签 → 查 → 再画)。薄壳,逻辑与体检共用
205
- // lib/danbooru-tags.js。deferred:名字自解释,且 paint_still 描述里点了名。
206
- makeLookupTagsTool(),
207
-
208
- // report_issue — agent 给维护者写信(08-02 由 report_friction 扩容改名):
209
- // bug / friction / idea 三类走同一张 issues 表。跟 PostToolUseFailure 的
210
- // 自动记录分工:自动层记"发生了什么",这层补"为什么难受、期望怎样"
211
- makeReportIssueTool({ projectId, sessionId, ctx }),
212
-
213
- // web_search4 provider 联网搜索(baidu/tavily/exa/zhipu,CJK auto route to baidu)
214
- // 移植自 ~/.deskclaw/skills/deskclaw-search-pro/scripts/search.py,0 外部依赖。
215
- // WebFetch 不在这里 — 用 SDK 内置(session-loop.js DEFAULT_TOOL_ALLOWLIST 启用),
216
- // 它自带 LLM summarize 能控制上下文,不需要自实现。
217
- withTierGate(makeWebSearchTool({ workspaceRoot, sharedRoot, ctx }), 'webSearch', projectId), // basic 档有日上限
218
-
219
- // S1c canvas 焕新升级 — read_page 让 agent 精确读 canvas.html 任意页
220
- // (`<section data-page="N">` 一段),不必 Read 整文件 + Grep + offset/limit。
221
- // 2026-05-02 用户观察"agent 只看第一页"痛点。
222
- makeReadPageTool({ workspaceRoot, sessionId, ctx }),
223
-
224
- // ── Canvas 焕新 C1(2026-05-02):完整 agent "感知 + 操作" 工具链 ──
225
- // 感知层:list_pages / query_elements / get_computed_styles —— playwright
226
- // headless 跑出来真实 render 后的元数据,agent 不再盲改
227
- makeListPagesTool({ workspaceRoot, projectId, sessionId, ctx }),
228
- queryElements,
229
-
230
- // profile_scroll 滚动性能量具(2026-08-18)。用户说"一顿一顿"时 agent
231
- // 以前手里零工具,只能自己起 http server 手搓 rAF 采样。不进常驻工具表
232
- // (deferred,用得上时自然搜到),schema 不白占每轮上下文。
233
- makeProfileScrollTool({ workspaceRoot, projectId, sessionId }),
234
-
235
- // explain_styleCSS 级联诊断(2026-08-18)。computed 只给结果不给原因,
236
- // agent 手里没有 devtools Styles 面板。同样走 deferred。
237
- explainStyle,
238
-
239
- // trace_motion — 动画数值示波器(2026-08-19,iss_mszv782a_toab)。缓动/过冲/
240
- // 硬切从"看静帧猜"变成逐帧采样量出来。deferred:名字自解释,且常驻的
241
- // screenshot_canvas 描述里点了名(胶片条管看、这个管量)。
242
- traceMotion,
243
-
244
- // ── 浏览通道(2026-08-18):agent 真的会用浏览器 ──
245
- // 常驻一个 chromium(按项目键、带持久 profile),所以能点链接、翻子页、
246
- // 留住登录态。跟 screenshot_url 的分工:那个是一次性一张图,这组是有会话的逛。
247
- // ⭐ 每个请求都过 lib/ssrf-guard.js 的出网闸(含跳转每一跳、iframe、子资源),
248
- // 闸在工具实现体里,agent 关不掉。**全部常驻**(理由见 ALWAYS_LOAD_TOOLS)。
249
- //
250
- // ⚠️ 刻意**没给 explorer 子代理**:registry 按 projectId 键 = 主 agent 和
251
- // 子代理共用同一只浏览器、同一个 page。mutex 保证不撕裂,但保证不了不抢 ——
252
- // 子代理一导航就把主 agent 正在看的那一页带走了,症状是"我刚打开的页面
253
- // 自己变了"。要给的话得先有"借用后还原"(存 URL、用完 goto 回去),
254
- // 或者第二个常驻名额;1 vCPU 上后者不成立。
255
- ...browseBatchable,
256
- // 一次往返跑一串(串行、遇错即停、结尾补截图)—— 省的是模型回合数
257
- makeBrowserBatchTool({ tools: browseBatchable }),
258
- // ── 产物会话(2026-08-21):成品检查的交互半边 ──
259
- // artifact_open 把产物开进常驻会话,artifact_computer/find 对着它点、敲、找;
260
- // 五个量具 live:true 就量会话里现在这一页;artifact_batch 一趟跑一串。
261
- ...artifactSessionTools,
262
- makeArtifactBatchTool({ tools: [...artifactSessionTools, screenshotCanvas, queryElements, getComputedStyles, explainStyle, traceMotion] }),
263
- // 撞验证墙时举手叫人(阻塞等,默认 120 秒超时 —— 人可能就走了)
264
- makeBrowserRequestHelpTool({ projectId, ctx }),
265
- getComputedStyles,
266
-
267
- // 控制层:emit 反向事件给前端,server 主动操作 canvas UI
268
- makeNavigateToPageTool({ ctx }),
269
- makeHighlightTool({ ctx }),
270
- // 把 deck 摊到用户眼前(= 用户双击那张卡):收起态→内嵌渲染,展开态→最大化窗
271
- makePreviewDeckTool({ ctx, sessionId, workspaceRoot }),
272
-
273
- // word 形态的构建道:token JSON(真相源)→ .docx(产物)。
274
- // agent 拿到的是一条命令不是一个构建系统 —— 写 JSON、调它、再 screenshot 看。
275
- makeBuildDocxTool({ workspaceRoot, sessionId, ctx }),
276
-
277
- // 反馈层:用户在 canvas 上的直接编辑 + 评论 buffer
278
- // 前端在 chat 时由 turn.js 注入 system 提示,agent 主动调下面两个工具读 + 清
279
- makeGetPendingChangesTool({ workspaceRoot, ctx }),
280
- makeClearPendingChangesTool({ workspaceRoot, ctx }),
281
-
282
- // Tweaks 协议:agent 暴露 deck 专属可调参数 schema → 前端按 schema 渲染控件
283
- makeExposeTweaksTool({ workspaceRoot, ctx }),
284
-
285
- // 图片生成(gemini-3.1-flash-image-preview / Nano Banana 2,via NoDesk passthrough)
286
- // 落档优先 sharedRoot/assets/generated/,fallback workspaceRoot/assets/generated/。
287
- // session 共享靠 sessions/<sid>/assets softlinkshared/assets。
288
- withTierGate(makeGenerateImageTool({ workspaceRoot, sharedRoot, ctx }), 'imageGen', projectId, ctx), // 先过日限,出图记 $0.20/张
289
-
290
- // 抠图(rembg U²-Net,server spawn .venv-rembg python subprocess
291
- // 任何 workspace 里的图都能抠,输出 RGBA PNG 到 assets/generated/<name>.png。
292
- // generate_image 解耦:generate_image 只生图,想透明叠加单独调本工具。
293
- makeRemoveBackgroundTool({ workspaceRoot, sharedRoot, projectId, ctx }),
294
-
295
- // 工作台分区画布(2026-07-27):agent 协助摆放 —— 把产物/文档/deck 钉进
296
- // session 的工作区。写 board.json(board-store 单锁)+ 广播 board.updated
297
- makePinToBoardTool({ sharedRoot, projectId, ctx }),
298
-
299
- // 关系线(2026-08-07):agent 把「这版改自那版」「这两个是对照」这类
300
- // **只有它知道**的关系画到画布上。画布知道每个产物是什么,但不知道它们
301
- // 之间是什么关系 —— 那是北极星(排出有版面感的布局)真正缺的那一块。
302
- makeRelateOnBoardTool({ projectId, ctx }),
303
- // agent 摆位四件(2026-08-14):看版面 / 语义摆位·立主角 / 落手写便签 / 归纳收纳
304
- makeReadBoardTool({ projectId }),
305
- makeArrangeOnBoardTool({ projectId, ctx }),
306
- makeCreateOnBoardTool({ projectId, ctx }),
307
- makeOrganizeBoardTool({ projectId, ctx }),
308
-
309
- // 注:Phase Image-2 的 request_image_approval 工具已废弃(2026-05-06)。
310
- // generate_image CallToolResult 已返 image content block,前端自动渲染;
311
- // agent caption / 自然回话邀请反馈,下一轮用户 chat 即天然 gate。
312
- ].map((t) => (
313
- // SDK _meta['anthropic/alwaysLoad'] 标记常驻(tool() 5 参的等价物,
314
- // 集中在这打标避免改 16 个工具文件)
315
- ALWAYS_LOAD_TOOLS.has(t.name)
316
- ? { ...t, _meta: { ...t._meta, 'anthropic/alwaysLoad': true } }
317
- : t
318
- )).map((t) => (
319
- // 本机能力闸(08-22):缺 chromium / LibreOffice / 钥匙 的工具,描述前缀「不可用 + 装法」、调用期拦住。
320
- // 对照表在 capability-gate.js 一份;没探过(单测)原样放行
321
- withCapabilityGate(t)
322
- )).map((t) => (
323
- // 参数标签泄漏消毒(2026-08-19):上游偶发把下一个参数吞进上一个字符串参数
324
- // (</rationale><parameter name="scope">… 原样落进 tool_use.input,会话
325
- // 008fe16c 4/4 实锤)。挂在出口包全部工具 —— 哪个工具中招看 recordIssue。
326
- withParamSanitizer(t, { projectId, sessionId })
327
- ));
328
-
329
- const server = createSdkMcpServer({
330
- name: 'nodesign',
331
- version: '0.1.0',
332
- tools,
333
- });
334
- // 开局契约自检用(2026-08-14 灭门案第 3 层):预期工具名从构造本 server 的
335
- // 同一份 tools 数组上取,不另立第二份清单 —— 第二真相源会漂移。session-loop
336
- // 收到 system:init 时拿它跟 SDK 实际注册进会话的工具对账。
337
- server.toolNames = tools.map((t) => t.name);
338
- return server;
339
- }
1
+ /**
2
+ * server/engine/mcp/index.js — Nodesign 内置 MCP server
3
+ *
4
+ * 暴露给 agent 的自定义工具集(in-process,via SDK 的 createSdkMcpServer):
5
+ *
6
+ * 感知层(playwright headless 跑出真实渲染元数据):
7
+ * screenshot_canvas / list_pages / read_page / query_elements / get_computed_styles
8
+ * 控制层(emit 事件让前端同步):
9
+ * navigate_to_page / highlight / preview_deck
10
+ * 反馈层(用户在 canvas 上的直接编辑 + 评论 buffer):
11
+ * get_pending_changes / clear_pending_changes
12
+ * 产物层(NoDesign 差异化能力):
13
+ * expose_tweaks / export_handoff / record_decision
14
+ * 研究层:
15
+ * web_search(4 provider,CJK auto baidu)
16
+ *
17
+ * 调用约定(SDK 自动给 tool name 加前缀):
18
+ * tool 名在 agent 端是 mcp__nodesign__<tool>,比如 mcp__nodesign__screenshot_canvas
19
+ *
20
+ * 实例化策略:
21
+ * 每个 runAgent 创建一个新的 MCP server 实例(through createNodesignMcpServer)。
22
+ * 开销小(in-process,没起 process),但能让 deps(workspaceRoot / projectId / ctx)
23
+ * 绑死到当前 turn 的上下文,避免 cross-talk。
24
+ *
25
+ * 安全:
26
+ * tool handler 在 SDK 进程内(本服务器进程)跑,不通过 stdio/sse/http。
27
+ * handler 自己不做沙盒,由 PreToolUse hook + workspace cwd 隔离兜底。
28
+ */
29
+
30
+ import { createSdkMcpServer } from '@anthropic-ai/claude-agent-sdk';
31
+ import { withParamSanitizer } from './param-sanitizer.js';
32
+ import { withCapabilityGate } from './capability-gate.js';
33
+ import { makeScreenshotCanvasTool } from './tools/screenshot.js';
34
+ import { makeScreenshotUrlTool } from './tools/screenshot-url.js';
35
+ import { makeExportHandoffTool } from './tools/export-handoff.js';
36
+ import { makeRecordDecisionTool } from './tools/record-decision.js';
37
+ import { makeWebSearchTool } from './tools/web-search.js';
38
+ import { withTierGate } from './tools/tier-gate.js'; // 档位闸包装器(auth/tier.js;按项目 owner)
39
+ import { makeReadPageTool } from './tools/read-page.js';
40
+ import { makeListPagesTool } from './tools/list-pages.js';
41
+ import { makeQueryElementsTool } from './tools/query-elements.js';
42
+ import { makeProfileScrollTool } from './tools/profile-scroll.js';
43
+ import { makeExplainStyleTool } from './tools/explain-style.js';
44
+ import { makeTraceMotionTool } from './tools/trace-motion.js';
45
+ import {
46
+ makeBrowserNavigateTool, makeBrowserReadTool, makeBrowserClickTool,
47
+ makeBrowserRequestHelpTool, makeBrowserCaptureTool,
48
+ } from './tools/browse.js';
49
+ import { makeBrowserScreenshotTool } from './tools/browse-screenshot.js';
50
+ import { makeBrowserComputerTool } from './tools/browse-computer.js';
51
+ import { makeBrowserFindTool, makeBrowserBatchTool } from './tools/browse-find-batch.js';
52
+ import { makeArtifactOpenTool, makeArtifactComputerTool, makeArtifactFindTool, makeArtifactMotionTool, makeArtifactBatchTool } from './tools/artifact-session.js';
53
+ import { makeGetComputedStylesTool } from './tools/get-computed-styles.js';
54
+ import { makeNavigateToPageTool } from './tools/navigate-to-page.js';
55
+ import { makeHighlightTool } from './tools/highlight.js';
56
+ import { makePreviewDeckTool } from './tools/preview-deck.js';
57
+ import { makeBuildDocxTool } from './tools/build-docx.js';
58
+ import { makeExposeTweaksTool } from './tools/expose-tweaks.js';
59
+ import { makeGetPendingChangesTool } from './tools/get-pending-changes.js';
60
+ import { makeClearPendingChangesTool } from './tools/clear-pending-changes.js';
61
+ import { makeGenerateImageTool } from './tools/generate-image.js';
62
+ import { makeRemoveBackgroundTool } from './tools/remove-background.js';
63
+ import { makePinToBoardTool } from './tools/pin-to-board.js';
64
+ import { makeRelateOnBoardTool } from './tools/relate-on-board.js';
65
+ import { makeReadBoardTool } from './tools/read-board.js';
66
+ import { makeArrangeOnBoardTool } from './tools/arrange-on-board.js';
67
+ import { makeCreateOnBoardTool } from './tools/create-on-board.js';
68
+ import { makeSketchOnBoardTool, makeFinishSketchTool } from './tools/sketch-on-board.js';
69
+ import { makeEditSketchTool } from './tools/edit-sketch.js';
70
+ import { makeWriteOnBoardTool } from './tools/write-on-board.js';
71
+ import { makeLookAtBoardTool } from './tools/look-at-board.js';
72
+ import { makeReadUserViewTool } from './tools/read-user-view.js';
73
+ import { makeOrganizeBoardTool } from './tools/organize-board.js';
74
+ import { makeReadDocumentTool } from './tools/read-document.js';
75
+ import { makeReadTavernJsonTool } from './tools/read-tavern-json.js';
76
+ import { makeDeliverFilesTool } from './tools/deliver-files.js';
77
+ import { makeCrystallizeSkillTool } from './tools/crystallize-skill.js';
78
+ import { makePublishSiteTool } from './tools/publish-site.js';
79
+ import { makeReportIssueTool } from './tools/report-issue.js';
80
+ import { makeRollFilmTool } from './tools/roll-film.js';
81
+ import { makePaintStillTool } from './tools/paint-still.js';
82
+ import { makeLookupTagsTool } from './tools/lookup-tags.js';
83
+
84
+ /**
85
+ * 创建 Nodesign 的 MCP server,绑定当前 run 的依赖。
86
+ *
87
+ * @param {object} deps
88
+ * @param {string} deps.workspaceRoot 绝对路径,project workspace(sessions/<sid>/)
89
+ * @param {string} [deps.sharedRoot] project shared/ 根(跨 session 共享 assets / .claude)
90
+ * @param {string} [deps.projectId]
91
+ * @param {string} [deps.sessionId] NoDesign sessionId(活跃产物指针 / 会话级锁 / 出处记账用)
92
+ * @param {import('../agent/context.js').AgentContext} [deps.ctx] EventBus 入口
93
+ * @returns SDK MCP server config(喂给 query options.mcpServers)
94
+ */
95
+ // 常驻 schema 白名单(2026-07-23 订阅模式 token 瘦身):
96
+ // 高频 + schema 小的工具第一 turn 就注入 prompt;不在名单里的走 SDK 默认
97
+ // deferred —— system prompt 只留工具名,agent ToolSearch 按需拉 schema
98
+ // (需要 ENABLE_TOOL_SEARCH=true + allowlist 含 ToolSearch,见 session-loop)。
99
+ // 实测 defer 掉 generate_image/web_search/remove_background 等 6 个胖工具
100
+ // ~80k 字符常驻 schema。prelude 的工具速查表仍列全部工具名 + 一句话用途,
101
+ // agent 知道存在什么、需要时先 ToolSearch("select:mcp__nodesign__<tool>")。
102
+ // (kimi 时代曾全局 alwaysLoad —— kimi 不认 ToolSearch;claude 系模型原生受训,可放心 defer
103
+ const ALWAYS_LOAD_TOOLS = new Set([
104
+ 'screenshot_canvas', 'read_page', 'list_pages', 'query_elements',
105
+ 'get_computed_styles', 'navigate_to_page', 'highlight', 'preview_deck',
106
+ 'record_decision', 'get_pending_changes', 'clear_pending_changes',
107
+ // screenshot_url 常驻:explorer 显式 tools 列表没有 ToolSearch,defer 了它就
108
+ // 永远拉不到 schema;schema 本身很小(4 字段),常驻成本可忽略
109
+ 'screenshot_url',
110
+ // 浏览通道六件(2026-08-18 当天从 deferred 改常驻;08-21 加到九件,见下)。
111
+ //
112
+ // 它们最初跟着「新工具默认 deferred」的习惯走,而那条习惯的依据是**成本**:
113
+ // defer 掉的是 expose_tweaks / paint_still / roll_film 那种十万字符级的胖子。
114
+ // 这六个实测 description 合计 4980 字符、连参数区 ≈ 6.9k —— 比那几个小
115
+ // 30~100 倍,塞进被缓存的 system prompt 每轮增量约等于零。
116
+ //
117
+ // deferred 的代价是具体的:agent 只看得到**名字**。`browser_capture`
118
+ // 这个名字一个字都没说它能带回调色板、字体、命中的 CSS 规则和结构三数 ——
119
+ // 于是它不会去搜这个 schema,做 deck / 做文档的会话里整条浏览通道等于不存在
120
+ // (只有加载了 site-craft skill 才会被点名)。**名字自解释的工具可以 defer,
121
+ // 卖点藏在描述里的不能。**
122
+ 'browser_navigate', 'browser_read', 'browser_click', 'browser_screenshot',
123
+ 'browser_request_help', 'browser_capture',
124
+ // 08-21 加的三件(坐标/引用级操作 + 词法找元 + 一次往返跑一串)。同一条理由:
125
+ // browser_batch 的卖点"省掉模型往返"和 browser_find 的"ref 比像素稳"都在描述里,
126
+ // 名字本身不卖;三件描述合计 ≈ 5.5k 字符,缓存里每轮增量约等于零。
127
+ 'browser_computer', 'browser_find', 'browser_batch',
128
+ // 08-21 产物会话五件:成品检查的交互半边(状态跨调用留着)。artifact_batch 的卖点
129
+ // "一趟跑完 + 结尾截图"和 live:true 的存在都只在描述里说,常驻。
130
+ 'artifact_open', 'artifact_computer', 'artifact_find', 'artifact_batch', 'artifact_motion',
131
+ ]);
132
+
133
+ export function createNodesignMcpServer({ workspaceRoot, sharedRoot, projectId, sessionId, ctx } = {}) {
134
+ // 浏览通道里能被 browser_batch 串起来的七件:先建一次,batch 拿**同一批实例**
135
+ // projectId/ctx 绑在 handler 里,不能再造第二份)。只有 request_help 不进
136
+ // batch(它阻塞等人);capture 在里面 —— 逐页采 token 正是 batch 要省的那种回合。
137
+ const browseBatchable = [
138
+ makeBrowserNavigateTool({ projectId, ctx }),
139
+ makeBrowserReadTool({ projectId }),
140
+ makeBrowserClickTool({ projectId }),
141
+ makeBrowserScreenshotTool({ projectId, workspaceRoot }),
142
+ // 采集:把可复用的东西(调色板/字体/CSS/结构骨架/截图)落进
143
+ // assets/references/web/ + 出处 sidecar —— 下个会话还在
144
+ makeBrowserCaptureTool({ projectId, workspaceRoot, sessionId, ctx }),
145
+ // 坐标/引用级指针与键盘 + 词法找元(08-21,形状照 browser_toolset_20260801)
146
+ makeBrowserComputerTool({ projectId, ctx }),
147
+ makeBrowserFindTool({ projectId }),
148
+ ];
149
+ // 五个能骑到产物会话上(live:true)的量具:先建一次,artifact_batch 拿同一批实例
150
+ const screenshotCanvas = makeScreenshotCanvasTool({ workspaceRoot, projectId, sessionId, ctx });
151
+ const queryElements = makeQueryElementsTool({ workspaceRoot, projectId, sessionId, ctx });
152
+ const getComputedStyles = makeGetComputedStylesTool({ workspaceRoot, projectId, sessionId, ctx });
153
+ const explainStyle = makeExplainStyleTool({ workspaceRoot, projectId, sessionId });
154
+ const traceMotion = makeTraceMotionTool({ workspaceRoot, projectId, sessionId });
155
+ // 产物会话四件(engine/perception/session.js):artifact_open / computer / find / motion
156
+ const artifactSessionTools = [
157
+ makeArtifactOpenTool({ projectId, workspaceRoot, sessionId }),
158
+ makeArtifactComputerTool({ projectId }),
159
+ makeArtifactFindTool({ projectId }),
160
+ // 自己的产物靠什么在动:跟 browser_capture motion 同一份引擎(engine/motion/inventory.js)
161
+ makeArtifactMotionTool({ projectId, workspaceRoot, sessionId }),
162
+ ];
163
+ const tools = [
164
+ // C9 screenshot_canvas — playwright headless 截图 → image content block
165
+ screenshotCanvas,
166
+
167
+ // screenshot_url 外部 URL 截图(2026-07-29)。explorer 找视觉参考不再
168
+ // 只能 WebFetch 文本转述;主 agent 也能直接看参考站。http/https only。
169
+ makeScreenshotUrlTool({ projectId, ctx }),
170
+
171
+ // deliver_files agent 挑好的产物直接进用户浏览器下载列表(emit run.download_ready)
172
+ makeDeliverFilesTool({ workspaceRoot, projectId, sessionId, ctx }),
173
+
174
+ // read_document Word / Excel / PowerPoint 的读取口(2026-08-07)。
175
+ // 普通 Read 读这三种只会拿到二进制乱码**而且不报错**,agent 会拿着空气
176
+ // 往下干。PDF 不在此列:Read 原生支持,真跑验过。
177
+ makeReadDocumentTool({ workspaceRoot, sharedRoot }),
178
+
179
+ // 酒馆 JSON 读取口:预设/角色卡/世界书先摘要再取正文(Read 会被 460KB 预设撑爆)
180
+ makeReadTavernJsonTool({ workspaceRoot, sharedRoot }),
181
+
182
+ // C10 export_handoff — 复用 exports.js 的 buildHandoffZip,写到 workspace/exports/
183
+ makeExportHandoffTool({ workspaceRoot, sharedRoot, projectId, sessionId, ctx }),
184
+
185
+ // C11 record_decision 写入 spec.json decisions[] 设计意图档案
186
+ makeRecordDecisionTool({ workspaceRoot, sessionId, ctx }),
187
+
188
+ // crystallize_skill 把探索出来的方法论固化成用户自己的 skill + 作品进橱窗
189
+ // (2026-07-30)。用户明确要求才调;写的是判断依据不是成品 HTML。
190
+ makeCrystallizeSkillTool({ projectId, sessionId, ctx }),
191
+
192
+ // publish_site 站点一键上线 Cloudflare Pages(2026-08-02)。用户明确要求
193
+ // 才调(发公网是外发动作);额度按项目 owner 算,与站点窗按钮共用一套闸门。
194
+ makePublishSiteTool({ projectId }),
195
+
196
+ // roll_film — 自部署 MiniMax-H3 视频产线(2026-08-08)。默认走站主 5090
197
+ // 盒子(h3box over SSH;Modal 余额告急降备用档,NODESIGN_FILM_BACKEND=modal
198
+ // 显式才走,绝不自动回退烧余额);配方恒定 Turbo8步 ≤12.25s;试用号拒
199
+ // (owner 闸门同 publish_site)。视觉 QC 归用户,工具只回文本路径。
200
+ makeRollFilmTool({ workspaceRoot, sharedRoot, projectId, sessionId, ctx }),
201
+
202
+ // paint_still站主本地 GPU 盒子生图(NoobAI/Anima,2026-08-08)。盒子
203
+ // 在线才可用(NODESIGN_H3BOX_SSH);动漫向/视频关键帧首选,通用生图仍走
204
+ // generate_image。视觉 QC 归用户。
205
+ makePaintStillTool({ workspaceRoot, sharedRoot, projectId, sessionId, ctx }),
206
+
207
+ // lookup_tags — danbooru 标签画前查询(2026-08-20)。paint_still 画完的体检
208
+ // 只能事后说"这批图别信";这个把查的动作挪到画前,配手册的起手纪律
209
+ // (先理解用户要什么 想候选标签 再画)。薄壳,逻辑与体检共用
210
+ // lib/danbooru-tags.jsdeferred:名字自解释,且 paint_still 描述里点了名。
211
+ makeLookupTagsTool(),
212
+
213
+ // report_issueagent 给维护者写信(08-02 report_friction 扩容改名):
214
+ // bug / friction / idea 三类走同一张 issues 表。跟 PostToolUseFailure 的
215
+ // 自动记录分工:自动层记"发生了什么",这层补"为什么难受、期望怎样"。
216
+ makeReportIssueTool({ projectId, sessionId, ctx }),
217
+
218
+ // web_search — 4 provider 联网搜索(baidu/tavily/exa/zhipu,CJK auto route to baidu)
219
+ // 移植自 ~/.deskclaw/skills/deskclaw-search-pro/scripts/search.py,0 外部依赖。
220
+ // WebFetch 不在这里 SDK 内置(session-loop.js DEFAULT_TOOL_ALLOWLIST 启用),
221
+ // 它自带 LLM summarize 能控制上下文,不需要自实现。
222
+ withTierGate(makeWebSearchTool({ workspaceRoot, sharedRoot, ctx }), 'webSearch', projectId), // basic 档有日上限
223
+
224
+ // S1c canvas 焕新升级 read_page agent 精确读 canvas.html 任意页
225
+ // (`<section data-page="N">` 一段),不必 Read 整文件 + Grep + offset/limit。
226
+ // 2026-05-02 用户观察"agent 只看第一页"痛点。
227
+ makeReadPageTool({ workspaceRoot, sessionId, ctx }),
228
+
229
+ // ── Canvas 焕新 C1(2026-05-02):完整 agent "感知 + 操作" 工具链 ──
230
+ // 感知层:list_pages / query_elements / get_computed_styles —— playwright
231
+ // headless 跑出来真实 render 后的元数据,agent 不再盲改
232
+ makeListPagesTool({ workspaceRoot, projectId, sessionId, ctx }),
233
+ queryElements,
234
+
235
+ // profile_scroll滚动性能量具(2026-08-18)。用户说"一顿一顿"时 agent
236
+ // 以前手里零工具,只能自己起 http server 手搓 rAF 采样。不进常驻工具表
237
+ // (deferred,用得上时自然搜到),schema 不白占每轮上下文。
238
+ makeProfileScrollTool({ workspaceRoot, projectId, sessionId }),
239
+
240
+ // explain_style — CSS 级联诊断(2026-08-18)。computed 只给结果不给原因,
241
+ // agent 手里没有 devtools 的 Styles 面板。同样走 deferred。
242
+ explainStyle,
243
+
244
+ // trace_motion — 动画数值示波器(2026-08-19,iss_mszv782a_toab)。缓动/过冲/
245
+ // 硬切从"看静帧猜"变成逐帧采样量出来。deferred:名字自解释,且常驻的
246
+ // screenshot_canvas 描述里点了名(胶片条管看、这个管量)。
247
+ traceMotion,
248
+
249
+ // ── 浏览通道(2026-08-18):agent 真的会用浏览器 ──
250
+ // 常驻一个 chromium(按项目键、带持久 profile),所以能点链接、翻子页、
251
+ // 留住登录态。跟 screenshot_url 的分工:那个是一次性一张图,这组是有会话的逛。
252
+ // 每个请求都过 lib/ssrf-guard.js 的出网闸(含跳转每一跳、iframe、子资源),
253
+ // 闸在工具实现体里,agent 关不掉。**全部常驻**(理由见 ALWAYS_LOAD_TOOLS)。
254
+ //
255
+ // ⚠️ 刻意**没给 explorer 子代理**:registry 按 projectId 键 = 主 agent 和
256
+ // 子代理共用同一只浏览器、同一个 page。mutex 保证不撕裂,但保证不了不抢 ——
257
+ // 子代理一导航就把主 agent 正在看的那一页带走了,症状是"我刚打开的页面
258
+ // 自己变了"。要给的话得先有"借用后还原"(存 URL、用完 goto 回去),
259
+ // 或者第二个常驻名额;1 vCPU 上后者不成立。
260
+ ...browseBatchable,
261
+ // 一次往返跑一串(串行、遇错即停、结尾补截图)—— 省的是模型回合数
262
+ makeBrowserBatchTool({ tools: browseBatchable }),
263
+ // ── 产物会话(2026-08-21):成品检查的交互半边 ──
264
+ // artifact_open 把产物开进常驻会话,artifact_computer/find 对着它点、敲、找;
265
+ // 五个量具 live:true 就量会话里现在这一页;artifact_batch 一趟跑一串。
266
+ ...artifactSessionTools,
267
+ makeArtifactBatchTool({ tools: [...artifactSessionTools, screenshotCanvas, queryElements, getComputedStyles, explainStyle, traceMotion] }),
268
+ // 撞验证墙时举手叫人(阻塞等,默认 120 秒超时 —— 人可能就走了)
269
+ makeBrowserRequestHelpTool({ projectId, ctx }),
270
+ getComputedStyles,
271
+
272
+ // 控制层:emit 反向事件给前端,server 主动操作 canvas UI
273
+ makeNavigateToPageTool({ ctx }),
274
+ makeHighlightTool({ ctx }),
275
+ // deck 摊到用户眼前(= 用户双击那张卡):收起态→内嵌渲染,展开态→最大化窗
276
+ makePreviewDeckTool({ ctx, sessionId, workspaceRoot }),
277
+
278
+ // word 形态的构建道:token JSON(真相源)→ .docx(产物)。
279
+ // agent 拿到的是一条命令不是一个构建系统 —— 写 JSON、调它、再 screenshot 看。
280
+ makeBuildDocxTool({ workspaceRoot, sessionId, ctx }),
281
+
282
+ // 反馈层:用户在 canvas 上的直接编辑 + 评论 buffer
283
+ // 前端在 chat 时由 turn.js 注入 system 提示,agent 主动调下面两个工具读 + 清
284
+ makeGetPendingChangesTool({ workspaceRoot, ctx }),
285
+ makeClearPendingChangesTool({ workspaceRoot, ctx }),
286
+
287
+ // Tweaks 协议:agent 暴露 deck 专属可调参数 schema 前端按 schema 渲染控件
288
+ makeExposeTweaksTool({ workspaceRoot, ctx }),
289
+
290
+ // 图片生成(gemini-3.1-flash-image-preview / Nano Banana 2,via NoDesk passthrough
291
+ // 落档优先 sharedRoot/assets/generated/,fallback workspaceRoot/assets/generated/。
292
+ // session 共享靠 sessions/<sid>/assets softlink → shared/assets。
293
+ withTierGate(makeGenerateImageTool({ workspaceRoot, sharedRoot, ctx }), 'imageGen', projectId, ctx), // 先过日限,出图记 $0.20/张
294
+
295
+ // 抠图(rembg U²-Net,server spawn .venv-rembg python subprocess)
296
+ // 任何 workspace 里的图都能抠,输出 RGBA PNG assets/generated/<name>.png
297
+ // generate_image 解耦:generate_image 只生图,想透明叠加单独调本工具。
298
+ makeRemoveBackgroundTool({ workspaceRoot, sharedRoot, projectId, ctx }),
299
+
300
+ // 工作台分区画布(2026-07-27):agent 协助摆放 —— 把产物/文档/deck 钉进
301
+ // session 的工作区。写 board.json(board-store 单锁)+ 广播 board.updated。
302
+ makePinToBoardTool({ sharedRoot, projectId, ctx }),
303
+
304
+ // 关系线(2026-08-07):agent 把「这版改自那版」「这两个是对照」这类
305
+ // **只有它知道**的关系画到画布上。画布知道每个产物是什么,但不知道它们
306
+ // 之间是什么关系 —— 那是北极星(排出有版面感的布局)真正缺的那一块。
307
+ makeRelateOnBoardTool({ projectId, ctx }),
308
+ // agent 摆位四件(2026-08-14):看版面 / 语义摆位·立主角 / 落手写便签 / 归纳收纳
309
+ makeReadBoardTool({ projectId }),
310
+ makeArrangeOnBoardTool({ projectId, ctx }),
311
+ makeCreateOnBoardTool({ projectId, ctx }),
312
+ makeOrganizeBoardTool({ projectId, ctx }),
313
+ // 黑板(2026-08-23):一次落一整张草图 / 落定或擦掉 / 看一眼 / 用户在看哪
314
+ makeSketchOnBoardTool({ projectId, ctx }),
315
+ makeFinishSketchTool({ projectId, ctx }),
316
+ makeEditSketchTool({ projectId, ctx }),
317
+ makeWriteOnBoardTool({ projectId, sharedRoot: workspaceRoot || sharedRoot, sessionId, ctx }),
318
+ makeLookAtBoardTool({ projectId, ctx }),
319
+ makeReadUserViewTool({ projectId }),
320
+
321
+ // 注:Phase Image-2 的 request_image_approval 工具已废弃(2026-05-06)。
322
+ // generate_image 的 CallToolResult 已返 image content block,前端自动渲染;
323
+ // agent 在 caption / 自然回话邀请反馈,下一轮用户 chat 即天然 gate。
324
+ ].map((t) => (
325
+ // SDK 用 _meta['anthropic/alwaysLoad'] 标记常驻(tool() 5 参的等价物,
326
+ // 集中在这打标避免改 16 个工具文件)
327
+ ALWAYS_LOAD_TOOLS.has(t.name)
328
+ ? { ...t, _meta: { ...t._meta, 'anthropic/alwaysLoad': true } }
329
+ : t
330
+ )).map((t) => (
331
+ // 本机能力闸(08-22):缺 chromium / LibreOffice / 钥匙 的工具,描述前缀「不可用 + 装法」、调用期拦住。
332
+ // 对照表在 capability-gate.js 一份;没探过(单测)原样放行
333
+ withCapabilityGate(t)
334
+ )).map((t) => (
335
+ // 参数标签泄漏消毒(2026-08-19):上游偶发把下一个参数吞进上一个字符串参数
336
+ // (</rationale><parameter name="scope">… 原样落进 tool_use.input,会话
337
+ // 008fe16c 4/4 实锤)。挂在出口包全部工具 —— 哪个工具中招看 recordIssue。
338
+ withParamSanitizer(t, { projectId, sessionId })
339
+ ));
340
+
341
+ const server = createSdkMcpServer({
342
+ name: 'nodesign',
343
+ version: '0.1.0',
344
+ tools,
345
+ });
346
+ // 开局契约自检用(2026-08-14 灭门案第 3 层):预期工具名从构造本 server 的
347
+ // 同一份 tools 数组上取,不另立第二份清单 —— 第二真相源会漂移。session-loop
348
+ // 收到 system:init 时拿它跟 SDK 实际注册进会话的工具对账。
349
+ server.toolNames = tools.map((t) => t.name);
350
+ return server;
351
+ }