@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,204 +1,204 @@
1
- /**
2
- * skill.js — Skill 加载器(YAML frontmatter + Markdown body)
3
- *
4
- * 目录结构(2026-05-18 起,对齐 Claude Code plugin convention):
5
- * server/engine/plugins/nodesign/
6
- * .claude-plugin/plugin.json — plugin 元数据
7
- * skills/<skill-id>/SKILL.md — 各 skill
8
- * skills/<skill-id>/<其他起手文件>
9
- *
10
- * SKILL.md 格式(YAML frontmatter + body):
11
- * ---
12
- * name: deskskill-engine-mini
13
- * version: 0.0.1
14
- * description: 给 LLM 看的"什么时候用我"的描述
15
- * ---
16
- *
17
- * # System Prompt
18
- *
19
- * 你是一个 deck 设计 agent...(任意 markdown)
20
- *
21
- * 本模块职责:
22
- * - 解析 SKILL.md 的 YAML frontmatter + body(loadSkill)
23
- * - 把 skill 起手文件(canvas.template.html 等)拷进 session cwd(ensureSkillStarterFiles)
24
- *
25
- * 注:批量扫 plugin 下所有 skill 走 plugin-loader.js `listInstalledPluginsDetailed`,
26
- * 不在本模块(API 层 server/api/skills.js 用那个)。
27
- *
28
- * SDK 集成(在 session-loop.js):
29
- * - plugins: [{ type: 'local', path: PLUGIN_ROOT }] → 让 SDK 识别本 plugin
30
- * - skills: [<skill-id>] → 让 SDK 把 description 注入 system prompt
31
- * - SKILL.md body 通过 SDK 内置 Skill 工具按需加载(不再走 systemPrompt.append 恒驻)
32
- */
33
-
34
- import { promises as fs } from 'fs';
35
- import path from 'path';
36
- import { fileURLToPath } from 'url';
37
-
38
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
39
-
40
- /** Plugin 根目录(含 .claude-plugin/plugin.json + skills/)*/
41
- export const PLUGIN_ROOT = path.resolve(
42
- process.env.NODESIGN_PLUGIN_DIR || path.join(__dirname, '../plugins/nodesign')
43
- );
44
-
45
- /** Skills 子目录(plugin convention:<plugin>/skills/<skill-id>/SKILL.md)*/
46
- export const SKILLS_ROOT = path.resolve(
47
- process.env.NODESIGN_SKILLS_DIR || path.join(PLUGIN_ROOT, 'skills')
48
- );
49
-
50
- /**
51
- * 加载一个 skill。返回 { id, name, version, description, systemPrompt, raw }。
52
- * 找不到时抛 Error(code='SKILL_NOT_FOUND')。
53
- */
54
- export async function loadSkill(skillId) {
55
- if (!skillId || typeof skillId !== 'string') {
56
- throw Object.assign(new Error('loadSkill: skillId required'), { code: 'INVALID_SKILL_ID' });
57
- }
58
-
59
- const skillDir = path.join(SKILLS_ROOT, skillId);
60
- const skillFile = path.join(skillDir, 'SKILL.md');
61
-
62
- let raw;
63
- try {
64
- raw = await fs.readFile(skillFile, 'utf8');
65
- } catch (err) {
66
- if (err.code === 'ENOENT') {
67
- throw Object.assign(
68
- new Error(`skill not found: ${skillId} (expected at ${skillFile})`),
69
- { code: 'SKILL_NOT_FOUND' }
70
- );
71
- }
72
- throw err;
73
- }
74
-
75
- const { frontmatter, body } = parseFrontmatter(raw);
76
-
77
- return {
78
- id: skillId,
79
- name: frontmatter.name || skillId,
80
- version: frontmatter.version || '0.0.0',
81
- description: frontmatter.description || '',
82
- systemPrompt: body.trim(),
83
- frontmatter,
84
- raw,
85
- };
86
- }
87
-
88
- /**
89
- * 把 skill 自带的工作区起手文件(目前主要是 canvas.template.html)拷贝
90
- * 进 session cwd,让 agent 能直接 `Read canvas.template.html` 而不必去
91
- * 仓库相对路径找(agent 看不到 server/engine/plugins/nodesign/skills/)。
92
- *
93
- * **拷贝不软链**:
94
- * - 跨平台稳(Windows symlink 要 admin / Linux bwrap 不解析 symlink)
95
- * - 防 agent 误 Edit 改源模板(影响其他 session)
96
- * - session 是一次性沙盒,拷贝快照语义合理
97
- *
98
- * **幂等**:文件已存在就不覆盖(agent 改过的、或上次 session init 拷过的不动)。
99
- *
100
- * **起手文件是自动发现的**(2026-07-28 从硬编码 `['canvas.template.html']` 改来):
101
- * skill 目录里凡是文件名带 `.template.` 的都算起手文件。加第二个 skill
102
- * (站点)时不必再回来改这里 —— 硬编码一个文件名意味着新 skill 的模板永远
103
- * 拷不出来,而且是静默的:agent 只会 `Read` 失败然后凭空写。
104
- *
105
- * @param {string} sessionRoot - sessions/<sid>/ 绝对路径
106
- * @param {string} skillId - 同 loadSkill 的 skillId
107
- * @returns {Promise<{ copied: string[], skipped: string[] }>}
108
- */
109
- /** 内置 plugin 里现有的 skill id(目录名即 id) */
110
- export async function listSkillIds() {
111
- try {
112
- const entries = await fs.readdir(SKILLS_ROOT, { withFileTypes: true });
113
- return entries.filter(e => e.isDirectory() && !e.name.startsWith('.')).map(e => e.name);
114
- } catch { return []; }
115
- }
116
-
117
- export async function listSkillStarterFiles(skillId) {
118
- if (!skillId) return [];
119
- try {
120
- const entries = await fs.readdir(path.join(SKILLS_ROOT, skillId), { withFileTypes: true });
121
- return entries
122
- .filter(e => e.isFile() && e.name.includes('.template.'))
123
- .map(e => e.name)
124
- .sort();
125
- } catch { return []; }
126
- }
127
-
128
- export async function ensureSkillStarterFiles(sessionRoot, skillId) {
129
- const result = { copied: [], skipped: [] };
130
- if (!sessionRoot || !skillId) return result;
131
-
132
- const skillDir = path.join(SKILLS_ROOT, skillId);
133
- const starterFiles = await listSkillStarterFiles(skillId);
134
-
135
- for (const name of starterFiles) {
136
- const src = path.join(skillDir, name);
137
- const dst = path.join(sessionRoot, name);
138
-
139
- let srcExists = false;
140
- try {
141
- await fs.access(src);
142
- srcExists = true;
143
- } catch { /* skill 没这个起手文件 */ }
144
- if (!srcExists) continue;
145
-
146
- let dstExists = false;
147
- try {
148
- await fs.access(dst);
149
- dstExists = true;
150
- } catch { /* dst 不存在,需要拷 */ }
151
- if (dstExists) {
152
- result.skipped.push(name);
153
- continue;
154
- }
155
-
156
- try {
157
- await fs.copyFile(src, dst);
158
- result.copied.push(name);
159
- } catch (err) {
160
- console.warn(
161
- `[skill] copy ${name} failed (${err.code || err.message}); `
162
- + `agent will not have it in cwd`,
163
- );
164
- }
165
- }
166
-
167
- return result;
168
- }
169
-
170
- // ── frontmatter 解析(极简 YAML:只支持 key: value)──
171
-
172
- const FRONTMATTER_RE = /^---\s*\n([\s\S]*?)\n---\s*\n?([\s\S]*)$/;
173
-
174
- /**
175
- * 解析 SKILL.md 的 frontmatter + body。
176
- * 不支持嵌套 / 多行 / list — 只接受 `key: value` 形态。
177
- *
178
- * 没 frontmatter 的文件:返回 { frontmatter: {}, body: <整个文件> }
179
- */
180
- function parseFrontmatter(raw) {
181
- const m = FRONTMATTER_RE.exec(raw);
182
- if (!m) return { frontmatter: {}, body: raw };
183
-
184
- const [, yamlText, body] = m;
185
- const frontmatter = {};
186
- for (const line of yamlText.split('\n')) {
187
- const trimmed = line.trim();
188
- if (!trimmed || trimmed.startsWith('#')) continue;
189
- const colonIdx = trimmed.indexOf(':');
190
- if (colonIdx < 1) continue;
191
- const key = trimmed.slice(0, colonIdx).trim();
192
- let value = trimmed.slice(colonIdx + 1).trim();
193
- // 去掉成对引号
194
- if ((value.startsWith('"') && value.endsWith('"')) ||
195
- (value.startsWith("'") && value.endsWith("'"))) {
196
- value = value.slice(1, -1);
197
- }
198
- frontmatter[key] = value;
199
- }
200
- return { frontmatter, body: body || '' };
201
- }
202
-
203
- // 暴露供单测
204
- export { parseFrontmatter };
1
+ /**
2
+ * skill.js — Skill 加载器(YAML frontmatter + Markdown body)
3
+ *
4
+ * 目录结构(2026-05-18 起,对齐 Claude Code plugin convention):
5
+ * server/engine/plugins/nodesign/
6
+ * .claude-plugin/plugin.json — plugin 元数据
7
+ * skills/<skill-id>/SKILL.md — 各 skill
8
+ * skills/<skill-id>/<其他起手文件>
9
+ *
10
+ * SKILL.md 格式(YAML frontmatter + body):
11
+ * ---
12
+ * name: deskskill-engine-mini
13
+ * version: 0.0.1
14
+ * description: 给 LLM 看的"什么时候用我"的描述
15
+ * ---
16
+ *
17
+ * # System Prompt
18
+ *
19
+ * 你是一个 deck 设计 agent...(任意 markdown)
20
+ *
21
+ * 本模块职责:
22
+ * - 解析 SKILL.md 的 YAML frontmatter + body(loadSkill)
23
+ * - 把 skill 起手文件(canvas.template.html 等)拷进 session cwd(ensureSkillStarterFiles)
24
+ *
25
+ * 注:批量扫 plugin 下所有 skill 走 plugin-loader.js `listInstalledPluginsDetailed`,
26
+ * 不在本模块(API 层 server/api/skills.js 用那个)。
27
+ *
28
+ * SDK 集成(在 session-loop.js):
29
+ * - plugins: [{ type: 'local', path: PLUGIN_ROOT }] → 让 SDK 识别本 plugin
30
+ * - skills: [<skill-id>] → 让 SDK 把 description 注入 system prompt
31
+ * - SKILL.md body 通过 SDK 内置 Skill 工具按需加载(不再走 systemPrompt.append 恒驻)
32
+ */
33
+
34
+ import { promises as fs } from 'fs';
35
+ import path from 'path';
36
+ import { fileURLToPath } from 'url';
37
+
38
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
39
+
40
+ /** Plugin 根目录(含 .claude-plugin/plugin.json + skills/)*/
41
+ export const PLUGIN_ROOT = path.resolve(
42
+ process.env.NODESIGN_PLUGIN_DIR || path.join(__dirname, '../plugins/nodesign')
43
+ );
44
+
45
+ /** Skills 子目录(plugin convention:<plugin>/skills/<skill-id>/SKILL.md)*/
46
+ export const SKILLS_ROOT = path.resolve(
47
+ process.env.NODESIGN_SKILLS_DIR || path.join(PLUGIN_ROOT, 'skills')
48
+ );
49
+
50
+ /**
51
+ * 加载一个 skill。返回 { id, name, version, description, systemPrompt, raw }。
52
+ * 找不到时抛 Error(code='SKILL_NOT_FOUND')。
53
+ */
54
+ export async function loadSkill(skillId) {
55
+ if (!skillId || typeof skillId !== 'string') {
56
+ throw Object.assign(new Error('loadSkill: skillId required'), { code: 'INVALID_SKILL_ID' });
57
+ }
58
+
59
+ const skillDir = path.join(SKILLS_ROOT, skillId);
60
+ const skillFile = path.join(skillDir, 'SKILL.md');
61
+
62
+ let raw;
63
+ try {
64
+ raw = await fs.readFile(skillFile, 'utf8');
65
+ } catch (err) {
66
+ if (err.code === 'ENOENT') {
67
+ throw Object.assign(
68
+ new Error(`skill not found: ${skillId} (expected at ${skillFile})`),
69
+ { code: 'SKILL_NOT_FOUND' }
70
+ );
71
+ }
72
+ throw err;
73
+ }
74
+
75
+ const { frontmatter, body } = parseFrontmatter(raw);
76
+
77
+ return {
78
+ id: skillId,
79
+ name: frontmatter.name || skillId,
80
+ version: frontmatter.version || '0.0.0',
81
+ description: frontmatter.description || '',
82
+ systemPrompt: body.trim(),
83
+ frontmatter,
84
+ raw,
85
+ };
86
+ }
87
+
88
+ /**
89
+ * 把 skill 自带的工作区起手文件(目前主要是 canvas.template.html)拷贝
90
+ * 进 session cwd,让 agent 能直接 `Read canvas.template.html` 而不必去
91
+ * 仓库相对路径找(agent 看不到 server/engine/plugins/nodesign/skills/)。
92
+ *
93
+ * **拷贝不软链**:
94
+ * - 跨平台稳(Windows symlink 要 admin / Linux bwrap 不解析 symlink)
95
+ * - 防 agent 误 Edit 改源模板(影响其他 session)
96
+ * - session 是一次性沙盒,拷贝快照语义合理
97
+ *
98
+ * **幂等**:文件已存在就不覆盖(agent 改过的、或上次 session init 拷过的不动)。
99
+ *
100
+ * **起手文件是自动发现的**(2026-07-28 从硬编码 `['canvas.template.html']` 改来):
101
+ * skill 目录里凡是文件名带 `.template.` 的都算起手文件。加第二个 skill
102
+ * (站点)时不必再回来改这里 —— 硬编码一个文件名意味着新 skill 的模板永远
103
+ * 拷不出来,而且是静默的:agent 只会 `Read` 失败然后凭空写。
104
+ *
105
+ * @param {string} sessionRoot - sessions/<sid>/ 绝对路径
106
+ * @param {string} skillId - 同 loadSkill 的 skillId
107
+ * @returns {Promise<{ copied: string[], skipped: string[] }>}
108
+ */
109
+ /** 内置 plugin 里现有的 skill id(目录名即 id) */
110
+ export async function listSkillIds() {
111
+ try {
112
+ const entries = await fs.readdir(SKILLS_ROOT, { withFileTypes: true });
113
+ return entries.filter(e => e.isDirectory() && !e.name.startsWith('.')).map(e => e.name);
114
+ } catch { return []; }
115
+ }
116
+
117
+ export async function listSkillStarterFiles(skillId) {
118
+ if (!skillId) return [];
119
+ try {
120
+ const entries = await fs.readdir(path.join(SKILLS_ROOT, skillId), { withFileTypes: true });
121
+ return entries
122
+ .filter(e => e.isFile() && e.name.includes('.template.'))
123
+ .map(e => e.name)
124
+ .sort();
125
+ } catch { return []; }
126
+ }
127
+
128
+ export async function ensureSkillStarterFiles(sessionRoot, skillId) {
129
+ const result = { copied: [], skipped: [] };
130
+ if (!sessionRoot || !skillId) return result;
131
+
132
+ const skillDir = path.join(SKILLS_ROOT, skillId);
133
+ const starterFiles = await listSkillStarterFiles(skillId);
134
+
135
+ for (const name of starterFiles) {
136
+ const src = path.join(skillDir, name);
137
+ const dst = path.join(sessionRoot, name);
138
+
139
+ let srcExists = false;
140
+ try {
141
+ await fs.access(src);
142
+ srcExists = true;
143
+ } catch { /* skill 没这个起手文件 */ }
144
+ if (!srcExists) continue;
145
+
146
+ let dstExists = false;
147
+ try {
148
+ await fs.access(dst);
149
+ dstExists = true;
150
+ } catch { /* dst 不存在,需要拷 */ }
151
+ if (dstExists) {
152
+ result.skipped.push(name);
153
+ continue;
154
+ }
155
+
156
+ try {
157
+ await fs.copyFile(src, dst);
158
+ result.copied.push(name);
159
+ } catch (err) {
160
+ console.warn(
161
+ `[skill] copy ${name} failed (${err.code || err.message}); `
162
+ + `agent will not have it in cwd`,
163
+ );
164
+ }
165
+ }
166
+
167
+ return result;
168
+ }
169
+
170
+ // ── frontmatter 解析(极简 YAML:只支持 key: value)──
171
+
172
+ const FRONTMATTER_RE = /^---\s*\n([\s\S]*?)\n---\s*\n?([\s\S]*)$/;
173
+
174
+ /**
175
+ * 解析 SKILL.md 的 frontmatter + body。
176
+ * 不支持嵌套 / 多行 / list — 只接受 `key: value` 形态。
177
+ *
178
+ * 没 frontmatter 的文件:返回 { frontmatter: {}, body: <整个文件> }
179
+ */
180
+ function parseFrontmatter(raw) {
181
+ const m = FRONTMATTER_RE.exec(raw);
182
+ if (!m) return { frontmatter: {}, body: raw };
183
+
184
+ const [, yamlText, body] = m;
185
+ const frontmatter = {};
186
+ for (const line of yamlText.split('\n')) {
187
+ const trimmed = line.trim();
188
+ if (!trimmed || trimmed.startsWith('#')) continue;
189
+ const colonIdx = trimmed.indexOf(':');
190
+ if (colonIdx < 1) continue;
191
+ const key = trimmed.slice(0, colonIdx).trim();
192
+ let value = trimmed.slice(colonIdx + 1).trim();
193
+ // 去掉成对引号
194
+ if ((value.startsWith('"') && value.endsWith('"')) ||
195
+ (value.startsWith("'") && value.endsWith("'"))) {
196
+ value = value.slice(1, -1);
197
+ }
198
+ frontmatter[key] = value;
199
+ }
200
+ return { frontmatter, body: body || '' };
201
+ }
202
+
203
+ // 暴露供单测
204
+ export { parseFrontmatter };
@@ -1,78 +1,78 @@
1
- /**
2
- * task-events.js — SDK 统一任务消息族(task_*)的收口翻译(2026-08-18,
3
- * 从 agent-shared.js handleSystemMessage 拆出)
4
- *
5
- * SDK 0.3.x 起「任务」统一化:task_* 消息不再只代表 Task 子代理 —— 后台
6
- * Bash(task_type 'local_bash')、Workflow('local_workflow')等也走同一条。
7
- * 我们 run.task.* 事件的语义是「子代理」,在这个咽喉点收口:只放真子代理
8
- * 过去,其余不进事件流。不收口的话每条 bash 命令都会在前端顶着「子代理」
9
- * 的名头出现(舞台便利贴/在场徽记/侧栏状态位全线噪音,2026-08-18 事故)。
10
- */
11
-
12
- import { Events } from './events.js';
13
- import { recordTaskNotification } from './hooks/post-subagent-report.js';
14
-
15
- /**
16
- * 这条 task_* 消息说的是不是真子代理(Task 工具)。靠 subagent_type /
17
- * task_type 区分;skip_transcript 是 SDK 标的 ambient/housekeeping 任务,
18
- * 按 SDK 约定对用户隐藏。
19
- */
20
- export function isSubagentTask(msg) {
21
- if (msg.skip_transcript) return false;
22
- return !!msg.subagent_type || msg.task_type === 'local_agent';
23
- }
24
-
25
- /**
26
- * 本轮已放行的子代理 task_id —— task_progress / task_notification 不带
27
- * subagent_type,靠它过滤非子代理任务。挂在 ctx 上惰性建:task_* 消息
28
- * 不带 parent_tool_use_id,进来的恒是真 ctx(不是子代理的派生 ctx),
29
- * own property 不会写丢。
30
- */
31
- function subagentTaskIds(ctx) {
32
- if (!ctx._subagentTaskIds) ctx._subagentTaskIds = new Set();
33
- return ctx._subagentTaskIds;
34
- }
35
-
36
- /** handleSystemMessage 的 task_* 四兄弟统一入口 */
37
- export function handleTaskMessage(ctx, msg) {
38
- switch (msg.subtype) {
39
- case 'task_started':
40
- if (!isSubagentTask(msg)) return;
41
- subagentTaskIds(ctx).add(msg.task_id);
42
- ctx.emit(Events.taskStarted(
43
- msg.task_id, msg.description, msg.subagent_type, msg.task_type, msg.prompt, msg.tool_use_id,
44
- ));
45
- return;
46
-
47
- case 'task_progress':
48
- // agentProgressSummaries: true 时每 ~30s 一次:"正在调整字号节奏" 之类
49
- if (!subagentTaskIds(ctx).has(msg.task_id)) return;
50
- ctx.emit(Events.taskProgress(
51
- msg.task_id, msg.description, msg.summary, msg.last_tool_name, msg.usage, msg.tool_use_id,
52
- ));
53
- return;
54
-
55
- case 'task_updated':
56
- if (!subagentTaskIds(ctx).has(msg.task_id)) return;
57
- ctx.emit(Events.taskUpdated(msg.task_id, msg.patch, msg.tool_use_id));
58
- return;
59
-
60
- case 'task_notification':
61
- // 收尾用量记账不分任务类型(进 metadata 可观测,不进主 token 列 ——
62
- // 防止与 result.usage 双重计数,详见 context.absorbSubagentUsage):
63
- // 将来若接 workflow 之类带真用量的本地任务,账也不能漏。
64
- ctx.absorbSubagentUsage?.(msg.usage);
65
- // 报告丢失的兜底也在闸**前**:把 output_file 记下来,PostToolUse(Agent)
66
- // 的 handler 在报告看起来是空的时候把转录路径递给主 agent(见
67
- // hooks/post-subagent-report.js)。它按 tool_use_id 查、只被 Agent 工具
68
- // 问到,多记非子代理任务无害;安全网不该依赖过滤闸的状态(存储有界 200 条)。
69
- recordTaskNotification(msg);
70
- if (!subagentTaskIds(ctx).has(msg.task_id)) return;
71
- ctx.emit(Events.taskNotification(
72
- msg.task_id, msg.status, msg.summary, msg.usage, msg.tool_use_id,
73
- ));
74
- return;
75
-
76
- default:
77
- }
78
- }
1
+ /**
2
+ * task-events.js — SDK 统一任务消息族(task_*)的收口翻译(2026-08-18,
3
+ * 从 agent-shared.js handleSystemMessage 拆出)
4
+ *
5
+ * SDK 0.3.x 起「任务」统一化:task_* 消息不再只代表 Task 子代理 —— 后台
6
+ * Bash(task_type 'local_bash')、Workflow('local_workflow')等也走同一条。
7
+ * 我们 run.task.* 事件的语义是「子代理」,在这个咽喉点收口:只放真子代理
8
+ * 过去,其余不进事件流。不收口的话每条 bash 命令都会在前端顶着「子代理」
9
+ * 的名头出现(舞台便利贴/在场徽记/侧栏状态位全线噪音,2026-08-18 事故)。
10
+ */
11
+
12
+ import { Events } from './events.js';
13
+ import { recordTaskNotification } from './hooks/post-subagent-report.js';
14
+
15
+ /**
16
+ * 这条 task_* 消息说的是不是真子代理(Task 工具)。靠 subagent_type /
17
+ * task_type 区分;skip_transcript 是 SDK 标的 ambient/housekeeping 任务,
18
+ * 按 SDK 约定对用户隐藏。
19
+ */
20
+ export function isSubagentTask(msg) {
21
+ if (msg.skip_transcript) return false;
22
+ return !!msg.subagent_type || msg.task_type === 'local_agent';
23
+ }
24
+
25
+ /**
26
+ * 本轮已放行的子代理 task_id —— task_progress / task_notification 不带
27
+ * subagent_type,靠它过滤非子代理任务。挂在 ctx 上惰性建:task_* 消息
28
+ * 不带 parent_tool_use_id,进来的恒是真 ctx(不是子代理的派生 ctx),
29
+ * own property 不会写丢。
30
+ */
31
+ function subagentTaskIds(ctx) {
32
+ if (!ctx._subagentTaskIds) ctx._subagentTaskIds = new Set();
33
+ return ctx._subagentTaskIds;
34
+ }
35
+
36
+ /** handleSystemMessage 的 task_* 四兄弟统一入口 */
37
+ export function handleTaskMessage(ctx, msg) {
38
+ switch (msg.subtype) {
39
+ case 'task_started':
40
+ if (!isSubagentTask(msg)) return;
41
+ subagentTaskIds(ctx).add(msg.task_id);
42
+ ctx.emit(Events.taskStarted(
43
+ msg.task_id, msg.description, msg.subagent_type, msg.task_type, msg.prompt, msg.tool_use_id,
44
+ ));
45
+ return;
46
+
47
+ case 'task_progress':
48
+ // agentProgressSummaries: true 时每 ~30s 一次:"正在调整字号节奏" 之类
49
+ if (!subagentTaskIds(ctx).has(msg.task_id)) return;
50
+ ctx.emit(Events.taskProgress(
51
+ msg.task_id, msg.description, msg.summary, msg.last_tool_name, msg.usage, msg.tool_use_id,
52
+ ));
53
+ return;
54
+
55
+ case 'task_updated':
56
+ if (!subagentTaskIds(ctx).has(msg.task_id)) return;
57
+ ctx.emit(Events.taskUpdated(msg.task_id, msg.patch, msg.tool_use_id));
58
+ return;
59
+
60
+ case 'task_notification':
61
+ // 收尾用量记账不分任务类型(进 metadata 可观测,不进主 token 列 ——
62
+ // 防止与 result.usage 双重计数,详见 context.absorbSubagentUsage):
63
+ // 将来若接 workflow 之类带真用量的本地任务,账也不能漏。
64
+ ctx.absorbSubagentUsage?.(msg.usage);
65
+ // 报告丢失的兜底也在闸**前**:把 output_file 记下来,PostToolUse(Agent)
66
+ // 的 handler 在报告看起来是空的时候把转录路径递给主 agent(见
67
+ // hooks/post-subagent-report.js)。它按 tool_use_id 查、只被 Agent 工具
68
+ // 问到,多记非子代理任务无害;安全网不该依赖过滤闸的状态(存储有界 200 条)。
69
+ recordTaskNotification(msg);
70
+ if (!subagentTaskIds(ctx).has(msg.task_id)) return;
71
+ ctx.emit(Events.taskNotification(
72
+ msg.task_id, msg.status, msg.summary, msg.usage, msg.tool_use_id,
73
+ ));
74
+ return;
75
+
76
+ default:
77
+ }
78
+ }