@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,57 +1,57 @@
1
- #!/bin/bash
2
- # bwrap 垫片 —— 绕开 apply-seccomp 的 unshare 竞态(2026-08-15)
3
- #
4
- # 📮 上游 issue:https://github.com/anthropics/claude-code/issues/86928
5
- # (含 strace 时序、内核源码引用、49 行 C 最小复现、三条修法建议)
6
- # ⏳ **这是临时设施**:上游修掉之后把整个目录连同 isolation.js 里的
7
- # sandboxShimEnv() 一起摘掉,别让它变成永久的一层。
8
- #
9
- # 病:SDK 沙盒每条命令都以 `ARGV0=apply-seccomp /proc/self/fd/3 <命令>` 起手 ——
10
- # 那是那个 306MB bun 二进制**自我重执行**成 seccomp helper。bun 启动时 mimalloc
11
- # 会先起一根 `mi-scavenger` 线程,helper 随即把它关掉并 join;但内核在
12
- # `mm_release()` 里唤醒 joiner 的时机**早于** `release_task` 把死线程从
13
- # thread group 摘除,于是紧接着那句 `unshare(CLONE_NEWUSER)` 撞上
14
- # `!thread_group_empty` → EINVAL。(kernel/fork.c:CLONE_NEWUSER 会被隐式加上
15
- # CLONE_THREAD,而 check_unshare_flags 对 CLONE_THREAD 要求 thread group 为空。)
16
- #
17
- # 所以它是**内核级竞态**,不是配置问题:40 行 C 能脱离 claude 复现,1 vCPU 空载
18
- # 200/200 必炸,join 后加 50µs 睡眠就 0/200。机器越闲越容易炸(joiner 抢占了
19
- # 垂死线程),多核几乎见不到 —— 这是这台单核机特有的。
20
- #
21
- # 治:把那句 racy 的 syscall 从执行路径上拿掉。`unshare -U --map-current-user
22
- # --keep-caps` 由 util-linux **单线程**先把 user namespace 建好并把能力放进
23
- # ambient set,helper 进去后第一步 `unshare(NEWNS|NEWPID)` 直接成功,**根本不会
24
- # 走到那句 CLONE_NEWUSER**。helper 在 exec 载荷之前自带 PR_CAP_AMBIENT_CLEAR_ALL,
25
- # 能力不外泄。
26
- #
27
- # 安全不变量(每条都在真会话里验过,改这个文件前重验):
28
- # Seccomp: 2(filter 仍在)· AF_UNIX socket() 仍被拒(pm2 rpc.sock 逃逸路照旧关着)
29
- # · uid 仍是 1000 · userns 嵌套层数不变 · ambient caps 在载荷 exec 前清空
30
- #
31
- # ⚠️ 这是垫在 SDK 内部实现上的补丁,**pattern 变了就自动失效**(原样透传 = 退回
32
- # 现状的偶发,不会退成"没有沙盒")。升 SDK 之后查 $NODESIGN_SHIM_LOG 里
33
- # rewrote=1 的计数还在不在涨。
34
- #
35
- # 上游修法(issue 里提的三条):对 EINVAL 做有界重试 + sched_yield(最简单,
36
- # 实测 50µs 退避就闭合窗口)/改成轮询 /proc/self/status 的 Threads: 到 1
37
- # 再 unshare/让 helper 在运行时起线程之前就把 namespace 建好。
38
-
39
- PAT='ARGV0=apply-seccomp /proc/self/fd/3 '
40
- REP='/usr/bin/unshare -U --map-current-user --keep-caps /usr/bin/env ARGV0=apply-seccomp /proc/self/fd/3 '
41
- REAL=${NODESIGN_REAL_BWRAP:-/usr/bin/bwrap}
42
-
43
- # 兜底:unshare 不在(非 util-linux 系统)→ 原样透传,退回现状
44
- [ -x /usr/bin/unshare ] || exec "$REAL" "$@"
45
-
46
- args=()
47
- hit=0
48
- for a in "$@"; do
49
- case "$a" in
50
- *"$PAT"*) hit=1; a=${a//"$PAT"/"$REP"} ;;
51
- esac
52
- args+=("$a")
53
- done
54
-
55
- [ -n "$NODESIGN_SHIM_LOG" ] && printf '%s rewrote=%d nargs=%d\n' "$(date +%s)" "$hit" "$#" >>"$NODESIGN_SHIM_LOG" 2>/dev/null
56
-
57
- exec "$REAL" "${args[@]}"
1
+ #!/bin/bash
2
+ # bwrap 垫片 —— 绕开 apply-seccomp 的 unshare 竞态(2026-08-15)
3
+ #
4
+ # 📮 上游 issue:https://github.com/anthropics/claude-code/issues/86928
5
+ # (含 strace 时序、内核源码引用、49 行 C 最小复现、三条修法建议)
6
+ # ⏳ **这是临时设施**:上游修掉之后把整个目录连同 isolation.js 里的
7
+ # sandboxShimEnv() 一起摘掉,别让它变成永久的一层。
8
+ #
9
+ # 病:SDK 沙盒每条命令都以 `ARGV0=apply-seccomp /proc/self/fd/3 <命令>` 起手 ——
10
+ # 那是那个 306MB bun 二进制**自我重执行**成 seccomp helper。bun 启动时 mimalloc
11
+ # 会先起一根 `mi-scavenger` 线程,helper 随即把它关掉并 join;但内核在
12
+ # `mm_release()` 里唤醒 joiner 的时机**早于** `release_task` 把死线程从
13
+ # thread group 摘除,于是紧接着那句 `unshare(CLONE_NEWUSER)` 撞上
14
+ # `!thread_group_empty` → EINVAL。(kernel/fork.c:CLONE_NEWUSER 会被隐式加上
15
+ # CLONE_THREAD,而 check_unshare_flags 对 CLONE_THREAD 要求 thread group 为空。)
16
+ #
17
+ # 所以它是**内核级竞态**,不是配置问题:40 行 C 能脱离 claude 复现,1 vCPU 空载
18
+ # 200/200 必炸,join 后加 50µs 睡眠就 0/200。机器越闲越容易炸(joiner 抢占了
19
+ # 垂死线程),多核几乎见不到 —— 这是这台单核机特有的。
20
+ #
21
+ # 治:把那句 racy 的 syscall 从执行路径上拿掉。`unshare -U --map-current-user
22
+ # --keep-caps` 由 util-linux **单线程**先把 user namespace 建好并把能力放进
23
+ # ambient set,helper 进去后第一步 `unshare(NEWNS|NEWPID)` 直接成功,**根本不会
24
+ # 走到那句 CLONE_NEWUSER**。helper 在 exec 载荷之前自带 PR_CAP_AMBIENT_CLEAR_ALL,
25
+ # 能力不外泄。
26
+ #
27
+ # 安全不变量(每条都在真会话里验过,改这个文件前重验):
28
+ # Seccomp: 2(filter 仍在)· AF_UNIX socket() 仍被拒(pm2 rpc.sock 逃逸路照旧关着)
29
+ # · uid 仍是 1000 · userns 嵌套层数不变 · ambient caps 在载荷 exec 前清空
30
+ #
31
+ # ⚠️ 这是垫在 SDK 内部实现上的补丁,**pattern 变了就自动失效**(原样透传 = 退回
32
+ # 现状的偶发,不会退成"没有沙盒")。升 SDK 之后查 $NODESIGN_SHIM_LOG 里
33
+ # rewrote=1 的计数还在不在涨。
34
+ #
35
+ # 上游修法(issue 里提的三条):对 EINVAL 做有界重试 + sched_yield(最简单,
36
+ # 实测 50µs 退避就闭合窗口)/改成轮询 /proc/self/status 的 Threads: 到 1
37
+ # 再 unshare/让 helper 在运行时起线程之前就把 namespace 建好。
38
+
39
+ PAT='ARGV0=apply-seccomp /proc/self/fd/3 '
40
+ REP='/usr/bin/unshare -U --map-current-user --keep-caps /usr/bin/env ARGV0=apply-seccomp /proc/self/fd/3 '
41
+ REAL=${NODESIGN_REAL_BWRAP:-/usr/bin/bwrap}
42
+
43
+ # 兜底:unshare 不在(非 util-linux 系统)→ 原样透传,退回现状
44
+ [ -x /usr/bin/unshare ] || exec "$REAL" "$@"
45
+
46
+ args=()
47
+ hit=0
48
+ for a in "$@"; do
49
+ case "$a" in
50
+ *"$PAT"*) hit=1; a=${a//"$PAT"/"$REP"} ;;
51
+ esac
52
+ args+=("$a")
53
+ done
54
+
55
+ [ -n "$NODESIGN_SHIM_LOG" ] && printf '%s rewrote=%d nargs=%d\n' "$(date +%s)" "$hit" "$#" >>"$NODESIGN_SHIM_LOG" 2>/dev/null
56
+
57
+ exec "$REAL" "${args[@]}"
@@ -1,119 +1,119 @@
1
- /**
2
- * server/projects/assets-summary.js — 工作区素材摘要(2026-08-18 从 workspace.js 拆出)
3
- *
4
- * 这条摘要进每个会话的 system 提示:告诉 agent 工作区里已经有什么素材。
5
- * 拆出来的理由是它跟"工作区生命周期"没关系 —— 它是个格式化器。
6
- *
7
- * ⚠️ 存在的意义在于:**跨会话可见的东西如果没人提,等于不存在**。
8
- * `assets/` 不随 sessionId 分桶,下个会话 Read 得到;但 agent 不会去猜有什么,
9
- * 它会重新搜一遍、重新逛一遍那个站。
10
- */
11
-
12
- import path from 'node:path';
13
- import fs from 'node:fs/promises';
14
-
15
- const IMAGE_EXT = new Set(['.png', '.jpg', '.jpeg', '.webp', '.gif', '.svg']);
16
- const TEXT_DOC_EXT = new Set(['.md', '.txt', '.json']);
17
- const BINARY_DOC_EXT = new Set(['.pdf', '.pptx', '.ppt', '.docx', '.doc', '.xlsx', '.xls']);
18
-
19
- /**
20
- * @param {string} sessionRoot - sessions/<sid>/ 绝对路径
21
- * @returns {Promise<{ count: number, summary: string, hasBinaryDocs: boolean }>}
22
- * count=0 时 summary 为空字符串,调用方据此判断是否注入提示。
23
- * hasBinaryDocs=true 时调用方追加 python 处理提醒(Read 拿不到这些的内容)。
24
- */
25
- export async function readAssetsSummary(sessionRoot) {
26
- try {
27
- const assetsLink = path.join(sessionRoot, 'assets');
28
- const stat = await fs.stat(assetsLink).catch(() => null);
29
- if (!stat) return { count: 0, summary: '', hasBinaryDocs: false };
30
-
31
- const entries = await fs.readdir(assetsLink, { withFileTypes: true }).catch(() => []);
32
- const files = entries.filter((e) => !e.name.startsWith('.') && (e.isFile() || e.isSymbolicLink()));
33
- // ⚠️ 别在这儿提前 return:顶层一个文件都没有、但 assets/references/ 下有一堆
34
- // 采集素材是**常见情形**(agent 逛过站但用户没上传过东西)。提前 return 会让
35
- // 那些素材对 agent 彻底隐形。
36
-
37
- const images = [];
38
- const textDocs = [];
39
- const binaryDocs = [];
40
- const others = [];
41
- for (const f of files) {
42
- const ext = path.extname(f.name).toLowerCase();
43
- if (IMAGE_EXT.has(ext)) images.push(f.name);
44
- else if (TEXT_DOC_EXT.has(ext)) textDocs.push(f.name);
45
- else if (BINARY_DOC_EXT.has(ext)) binaryDocs.push(f.name);
46
- else others.push(f.name);
47
- }
48
-
49
- // 摘要:种类 + 头几个文件名(避免太长)
50
- const parts = [];
51
- if (images.length > 0) {
52
- const sample = images.slice(0, 3).join('、');
53
- parts.push(`${images.length} 张图(${sample}${images.length > 3 ? ` 等` : ''})`);
54
- }
55
- if (textDocs.length > 0) {
56
- const sample = textDocs.slice(0, 3).join('、');
57
- parts.push(`${textDocs.length} 个文本文档(${sample}${textDocs.length > 3 ? ` 等` : ''})`);
58
- }
59
- if (binaryDocs.length > 0) {
60
- const sample = binaryDocs.slice(0, 3).join('、');
61
- parts.push(`${binaryDocs.length} 个 PDF/Office 文档(${sample}${binaryDocs.length > 3 ? ` 等` : ''})`);
62
- }
63
- if (others.length > 0) {
64
- parts.push(`${others.length} 个其他文件`);
65
- }
66
-
67
- // 完整文件清单(按路径列)—— 让 agent 不用再 Glob/LS 探。
68
- // (08-07 扁平化后 assets/ 是真目录,Glob 也能用;08-21 前这里还写着"symlink 别用 Glob",删了。)
69
- const allNames = [...images, ...textDocs, ...binaryDocs, ...others];
70
-
71
- // 参考素材(2026-08-18):`assets/references/**` 也要报,否则**没有任何机制
72
- // 告诉 agent 它们存在** —— 上面这遍只列顶层文件,而参考图和 browser_capture
73
- // 的采集都在子目录里。跨会话可见的东西如果没人提,等于不存在:agent 会重新
74
- // 去搜一遍、重新逛一遍那个站。
75
- // 只报数量和头几个名字(几十个文件全列会把这条 system 撑爆)。
76
- const refs = [];
77
- try {
78
- const refRoot = path.join(assetsLink, 'references');
79
- const walk = async (dir, rel, depth) => {
80
- for (const e of await fs.readdir(dir, { withFileTypes: true })) {
81
- if (e.name === '.meta' || e.name.startsWith('.')) continue;
82
- if (e.isDirectory()) { if (depth > 0) await walk(path.join(dir, e.name), `${rel}/${e.name}`, depth - 1); continue; }
83
- refs.push(`${rel}/${e.name}`);
84
- }
85
- };
86
- await walk(refRoot, 'assets/references', 2);
87
- } catch { /* 没有这个目录就没有 */ }
88
-
89
- const refLine = refs.length
90
- ? `另有 ${refs.length} 件参考素材在 assets/references/ 下(${refs.slice(0, 3).map(r => r.split('/').pop()).join('、')}`
91
- + `${refs.length > 3 ? ' 等' : ''})—— 逛站采回来的调色板/字体/结构/动效清单 json 就在这儿,`
92
- + '出处记在同目录的 .meta/<同名>.json 里。**先看有没有现成的,别重复去搜。**'
93
- : '';
94
-
95
- // ⚠️ `paths` 会被 UserPromptSubmit 首轮全量打进状态块(之后只报变化,见
96
- // hooks/user-prompt-submit.js)。refs 随每次 browser_capture 单调增长,首轮也要封顶;
97
- // `allPaths` 不封顶,给按项算变化用(不直接打进文案)。
98
- const REF_CAP = 12;
99
- const TOP_CAP = 60;
100
- const refPaths = refs.slice(0, REF_CAP);
101
- const overflow = refs.length - refPaths.length;
102
- if (overflow > 0) {
103
- // 别只是截断了不说 —— 「静默截断」读起来就是"全都在这儿了"
104
- refPaths.push(`(另有 ${overflow} 件在 assets/references/ 下,名字和出处见同目录 .meta/)`);
105
- }
106
- return {
107
- count: files.length + refs.length,
108
- summary: [
109
- files.length ? `workspace 里已有 ${files.length} 个参考素材:${parts.join('、')}` : '',
110
- refLine,
111
- ].filter(Boolean).join('\n'),
112
- hasBinaryDocs: binaryDocs.length > 0,
113
- paths: [...allNames.slice(0, TOP_CAP).map((n) => `assets/${n}`), ...refPaths],
114
- allPaths: [...allNames.map((n) => `assets/${n}`), ...refs],
115
- };
116
- } catch {
117
- return { count: 0, summary: '', hasBinaryDocs: false, paths: [], allPaths: [] };
118
- }
119
- }
1
+ /**
2
+ * server/projects/assets-summary.js — 工作区素材摘要(2026-08-18 从 workspace.js 拆出)
3
+ *
4
+ * 这条摘要进每个会话的 system 提示:告诉 agent 工作区里已经有什么素材。
5
+ * 拆出来的理由是它跟"工作区生命周期"没关系 —— 它是个格式化器。
6
+ *
7
+ * ⚠️ 存在的意义在于:**跨会话可见的东西如果没人提,等于不存在**。
8
+ * `assets/` 不随 sessionId 分桶,下个会话 Read 得到;但 agent 不会去猜有什么,
9
+ * 它会重新搜一遍、重新逛一遍那个站。
10
+ */
11
+
12
+ import path from 'node:path';
13
+ import fs from 'node:fs/promises';
14
+
15
+ const IMAGE_EXT = new Set(['.png', '.jpg', '.jpeg', '.webp', '.gif', '.svg']);
16
+ const TEXT_DOC_EXT = new Set(['.md', '.txt', '.json']);
17
+ const BINARY_DOC_EXT = new Set(['.pdf', '.pptx', '.ppt', '.docx', '.doc', '.xlsx', '.xls']);
18
+
19
+ /**
20
+ * @param {string} sessionRoot - sessions/<sid>/ 绝对路径
21
+ * @returns {Promise<{ count: number, summary: string, hasBinaryDocs: boolean }>}
22
+ * count=0 时 summary 为空字符串,调用方据此判断是否注入提示。
23
+ * hasBinaryDocs=true 时调用方追加 python 处理提醒(Read 拿不到这些的内容)。
24
+ */
25
+ export async function readAssetsSummary(sessionRoot) {
26
+ try {
27
+ const assetsLink = path.join(sessionRoot, 'assets');
28
+ const stat = await fs.stat(assetsLink).catch(() => null);
29
+ if (!stat) return { count: 0, summary: '', hasBinaryDocs: false };
30
+
31
+ const entries = await fs.readdir(assetsLink, { withFileTypes: true }).catch(() => []);
32
+ const files = entries.filter((e) => !e.name.startsWith('.') && (e.isFile() || e.isSymbolicLink()));
33
+ // ⚠️ 别在这儿提前 return:顶层一个文件都没有、但 assets/references/ 下有一堆
34
+ // 采集素材是**常见情形**(agent 逛过站但用户没上传过东西)。提前 return 会让
35
+ // 那些素材对 agent 彻底隐形。
36
+
37
+ const images = [];
38
+ const textDocs = [];
39
+ const binaryDocs = [];
40
+ const others = [];
41
+ for (const f of files) {
42
+ const ext = path.extname(f.name).toLowerCase();
43
+ if (IMAGE_EXT.has(ext)) images.push(f.name);
44
+ else if (TEXT_DOC_EXT.has(ext)) textDocs.push(f.name);
45
+ else if (BINARY_DOC_EXT.has(ext)) binaryDocs.push(f.name);
46
+ else others.push(f.name);
47
+ }
48
+
49
+ // 摘要:种类 + 头几个文件名(避免太长)
50
+ const parts = [];
51
+ if (images.length > 0) {
52
+ const sample = images.slice(0, 3).join('、');
53
+ parts.push(`${images.length} 张图(${sample}${images.length > 3 ? ` 等` : ''})`);
54
+ }
55
+ if (textDocs.length > 0) {
56
+ const sample = textDocs.slice(0, 3).join('、');
57
+ parts.push(`${textDocs.length} 个文本文档(${sample}${textDocs.length > 3 ? ` 等` : ''})`);
58
+ }
59
+ if (binaryDocs.length > 0) {
60
+ const sample = binaryDocs.slice(0, 3).join('、');
61
+ parts.push(`${binaryDocs.length} 个 PDF/Office 文档(${sample}${binaryDocs.length > 3 ? ` 等` : ''})`);
62
+ }
63
+ if (others.length > 0) {
64
+ parts.push(`${others.length} 个其他文件`);
65
+ }
66
+
67
+ // 完整文件清单(按路径列)—— 让 agent 不用再 Glob/LS 探。
68
+ // (08-07 扁平化后 assets/ 是真目录,Glob 也能用;08-21 前这里还写着"symlink 别用 Glob",删了。)
69
+ const allNames = [...images, ...textDocs, ...binaryDocs, ...others];
70
+
71
+ // 参考素材(2026-08-18):`assets/references/**` 也要报,否则**没有任何机制
72
+ // 告诉 agent 它们存在** —— 上面这遍只列顶层文件,而参考图和 browser_capture
73
+ // 的采集都在子目录里。跨会话可见的东西如果没人提,等于不存在:agent 会重新
74
+ // 去搜一遍、重新逛一遍那个站。
75
+ // 只报数量和头几个名字(几十个文件全列会把这条 system 撑爆)。
76
+ const refs = [];
77
+ try {
78
+ const refRoot = path.join(assetsLink, 'references');
79
+ const walk = async (dir, rel, depth) => {
80
+ for (const e of await fs.readdir(dir, { withFileTypes: true })) {
81
+ if (e.name === '.meta' || e.name.startsWith('.')) continue;
82
+ if (e.isDirectory()) { if (depth > 0) await walk(path.join(dir, e.name), `${rel}/${e.name}`, depth - 1); continue; }
83
+ refs.push(`${rel}/${e.name}`);
84
+ }
85
+ };
86
+ await walk(refRoot, 'assets/references', 2);
87
+ } catch { /* 没有这个目录就没有 */ }
88
+
89
+ const refLine = refs.length
90
+ ? `另有 ${refs.length} 件参考素材在 assets/references/ 下(${refs.slice(0, 3).map(r => r.split('/').pop()).join('、')}`
91
+ + `${refs.length > 3 ? ' 等' : ''})—— 逛站采回来的调色板/字体/结构/动效清单 json 就在这儿,`
92
+ + '出处记在同目录的 .meta/<同名>.json 里。**先看有没有现成的,别重复去搜。**'
93
+ : '';
94
+
95
+ // ⚠️ `paths` 会被 UserPromptSubmit 首轮全量打进状态块(之后只报变化,见
96
+ // hooks/user-prompt-submit.js)。refs 随每次 browser_capture 单调增长,首轮也要封顶;
97
+ // `allPaths` 不封顶,给按项算变化用(不直接打进文案)。
98
+ const REF_CAP = 12;
99
+ const TOP_CAP = 60;
100
+ const refPaths = refs.slice(0, REF_CAP);
101
+ const overflow = refs.length - refPaths.length;
102
+ if (overflow > 0) {
103
+ // 别只是截断了不说 —— 「静默截断」读起来就是"全都在这儿了"
104
+ refPaths.push(`(另有 ${overflow} 件在 assets/references/ 下,名字和出处见同目录 .meta/)`);
105
+ }
106
+ return {
107
+ count: files.length + refs.length,
108
+ summary: [
109
+ files.length ? `workspace 里已有 ${files.length} 个参考素材:${parts.join('、')}` : '',
110
+ refLine,
111
+ ].filter(Boolean).join('\n'),
112
+ hasBinaryDocs: binaryDocs.length > 0,
113
+ paths: [...allNames.slice(0, TOP_CAP).map((n) => `assets/${n}`), ...refPaths],
114
+ allPaths: [...allNames.map((n) => `assets/${n}`), ...refs],
115
+ };
116
+ } catch {
117
+ return { count: 0, summary: '', hasBinaryDocs: false, paths: [], allPaths: [] };
118
+ }
119
+ }
@@ -1,53 +1,53 @@
1
- /**
2
- * server/projects/auto-name.js — 用会话摘要给项目起名(2026-07-28)
3
- *
4
- * 首页那个大输入框以前建的是"闪聊"(kind=quick),名字硬切用户第一句话前 30 字,
5
- * 而且不算正经项目。现在它直接建真项目,名字先用那句话垫着(auto_named=1),
6
- * 第一轮跑完就用 **SDK helper 写的会话摘要** 改一次名 —— 那是它本来就在写的东西
7
- * (incrementally 落进 jsonl,我们列会话时读的就是它),不额外花一次模型调用。
8
- *
9
- * 只改一次:改完清 auto_named。用户自己改过名的项目(updateProject 带 name 会
10
- * 自动清零)永远不动。
11
- */
12
-
13
- import path from 'node:path';
14
- import { getSessionInfo } from '@anthropic-ai/claude-agent-sdk';
15
- import { getProject, updateProject } from './store.js';
16
- import { getProjectWorkspace } from './workspace.js';
17
- import { withConfigDir } from '../lib/sdk-session.js';
18
- import { platform } from '../runtime/platform.js';
19
-
20
- const MAX_NAME = 40;
21
-
22
- /**
23
- * @param {string} projectId
24
- * @param {string} sessionId
25
- * @returns {Promise<string|null>} 改成了什么名字;没改返 null
26
- */
27
- export async function autoNameProjectFromSession(projectId, sessionId) {
28
- if (!projectId || !sessionId) return null;
29
- let project;
30
- try { project = getProject(projectId); } catch { return null; }
31
- if (!project || !project.autoNamed) return null;
32
-
33
- const sessionRoot = path.join(getProjectWorkspace(projectId), 'sessions', sessionId);
34
- let info;
35
- try {
36
- info = await withConfigDir(platform.claudeConfigDir, () =>
37
- getSessionInfo(sessionId, { dir: sessionRoot }),
38
- );
39
- } catch {
40
- return null; // 读不到就下轮再说,auto_named 还留着
41
- }
42
-
43
- const summary = String(info?.customTitle || info?.summary || '').trim();
44
- if (!summary) return null;
45
- const name = summary.length > MAX_NAME ? summary.slice(0, MAX_NAME) + '…' : summary;
46
- if (name === project.name) {
47
- updateProject(projectId, { autoNamed: false }); // 同名也算定了,别每轮再问
48
- return null;
49
- }
50
-
51
- updateProject(projectId, { name, autoNamed: false });
52
- return name;
53
- }
1
+ /**
2
+ * server/projects/auto-name.js — 用会话摘要给项目起名(2026-07-28)
3
+ *
4
+ * 首页那个大输入框以前建的是"闪聊"(kind=quick),名字硬切用户第一句话前 30 字,
5
+ * 而且不算正经项目。现在它直接建真项目,名字先用那句话垫着(auto_named=1),
6
+ * 第一轮跑完就用 **SDK helper 写的会话摘要** 改一次名 —— 那是它本来就在写的东西
7
+ * (incrementally 落进 jsonl,我们列会话时读的就是它),不额外花一次模型调用。
8
+ *
9
+ * 只改一次:改完清 auto_named。用户自己改过名的项目(updateProject 带 name 会
10
+ * 自动清零)永远不动。
11
+ */
12
+
13
+ import path from 'node:path';
14
+ import { getSessionInfo } from '@anthropic-ai/claude-agent-sdk';
15
+ import { getProject, updateProject } from './store.js';
16
+ import { getProjectWorkspace } from './workspace.js';
17
+ import { withConfigDir } from '../lib/sdk-session.js';
18
+ import { platform } from '../runtime/platform.js';
19
+
20
+ const MAX_NAME = 40;
21
+
22
+ /**
23
+ * @param {string} projectId
24
+ * @param {string} sessionId
25
+ * @returns {Promise<string|null>} 改成了什么名字;没改返 null
26
+ */
27
+ export async function autoNameProjectFromSession(projectId, sessionId) {
28
+ if (!projectId || !sessionId) return null;
29
+ let project;
30
+ try { project = getProject(projectId); } catch { return null; }
31
+ if (!project || !project.autoNamed) return null;
32
+
33
+ const sessionRoot = path.join(getProjectWorkspace(projectId), 'sessions', sessionId);
34
+ let info;
35
+ try {
36
+ info = await withConfigDir(platform.claudeConfigDir, () =>
37
+ getSessionInfo(sessionId, { dir: sessionRoot }),
38
+ );
39
+ } catch {
40
+ return null; // 读不到就下轮再说,auto_named 还留着
41
+ }
42
+
43
+ const summary = String(info?.customTitle || info?.summary || '').trim();
44
+ if (!summary) return null;
45
+ const name = summary.length > MAX_NAME ? summary.slice(0, MAX_NAME) + '…' : summary;
46
+ if (name === project.name) {
47
+ updateProject(projectId, { autoNamed: false }); // 同名也算定了,别每轮再问
48
+ return null;
49
+ }
50
+
51
+ updateProject(projectId, { name, autoNamed: false });
52
+ return name;
53
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * server/projects/board-limits.js — board.json 的容量常数(2026-08-23 拆出)
3
+ * board-store(写盘前查字节数)和 board-sanitize(逐类计数)都要,单独一份免循环依赖。
4
+ */
5
+ export const DEFAULT_BOARD_SIZE = { w: 4000, h: 2600 };
6
+ export const MAX_BOARD_BYTES = 512 * 1024;
7
+ export const MAX_OBJECTS = 2000;
8
+ export const MAX_ZONES = 200;
9
+ // 关系线上限。取值理由:一块板上人能看懂的线远少于这个数,1000 是防脱缰
10
+ // (agent 循环里连画)的闸门,不是设计目标。超了直接不收,不做淘汰 ——
11
+ // 静默丢最旧的会让"我明明画了"变成玄学。
12
+ export const MAX_BINDINGS = 1000;