@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.
- package/README.md +156 -106
- package/bin/nodesign.js +0 -0
- package/package.json +1 -1
- package/server/api/README.md +45 -45
- package/server/api/_guard.js +75 -75
- package/server/api/admin.js +187 -187
- package/server/api/assets/docx-page.js +103 -103
- package/server/api/assets/helpers.js +42 -22
- package/server/api/assets/notes.js +194 -144
- package/server/api/assets.js +891 -896
- package/server/api/board.js +134 -57
- package/server/api/browse.js +138 -138
- package/server/api/canvas.js +444 -444
- package/server/api/chatai.js +324 -324
- package/server/api/exports/build-standalone.js +980 -980
- package/server/api/exports/cards.js +118 -118
- package/server/api/exports/docx-pdf.js +46 -46
- package/server/api/exports/export-page.js +142 -142
- package/server/api/exports/handoff.js +147 -147
- package/server/api/exports.js +690 -690
- package/server/api/instruction.js +75 -75
- package/server/api/me.js +116 -116
- package/server/api/memory.js +185 -185
- package/server/api/pending-changes.js +366 -366
- package/server/api/plugins.js +164 -164
- package/server/api/projects.js +220 -220
- package/server/api/publish.js +64 -64
- package/server/api/recent.js +73 -73
- package/server/api/sessions.js +589 -589
- package/server/api/skills.js +77 -77
- package/server/api/standalone-fit.js +168 -168
- package/server/api/turn-compose.js +180 -180
- package/server/api/turn-inflight.js +44 -44
- package/server/auth/README.md +17 -17
- package/server/auth/middleware.js +138 -138
- package/server/auth/origin-guard.js +71 -71
- package/server/auth/session.js +108 -108
- package/server/auth/tier.js +113 -113
- package/server/auth/users-store.js +348 -348
- package/server/edit/README.md +29 -29
- package/server/engine/README.md +113 -113
- package/server/engine/agent/agent-shared.js +550 -550
- package/server/engine/agent/auto-mode-default-hard-deny.txt +4 -4
- package/server/engine/agent/auto-mode-rules.js +78 -78
- package/server/engine/agent/context.js +418 -418
- package/server/engine/agent/events.js +465 -464
- package/server/engine/agent/hooks/canvas-validate.js +199 -199
- package/server/engine/agent/hooks/failure.js +120 -120
- package/server/engine/agent/hooks/file-events.js +75 -75
- package/server/engine/agent/hooks/lifecycle.js +233 -233
- package/server/engine/agent/hooks/post-canvas-focus.js +80 -80
- package/server/engine/agent/hooks/post-guidance.js +206 -206
- package/server/engine/agent/hooks/post-subagent-report.js +104 -104
- package/server/engine/agent/hooks/post-trim.js +58 -58
- package/server/engine/agent/hooks/pre-board-neighborhood.js +34 -34
- package/server/engine/agent/hooks/pre-defaults.js +84 -84
- package/server/engine/agent/hooks/pre-injectors.js +277 -277
- package/server/engine/agent/hooks/pre-performance-log-guard.js +78 -78
- package/server/engine/agent/hooks/pre-starter-files.js +61 -61
- package/server/engine/agent/hooks/pre-workspace-scope-guard.js +78 -78
- package/server/engine/agent/hooks/site-validate.js +94 -94
- package/server/engine/agent/hooks/tool-prompts.js +31 -31
- package/server/engine/agent/hooks/turn-state-memory.js +56 -56
- package/server/engine/agent/hooks/user-prompt-submit.js +258 -215
- package/server/engine/agent/hooks.js +354 -354
- package/server/engine/agent/init-contract.js +69 -69
- package/server/engine/agent/isolation.js +159 -159
- package/server/engine/agent/model-table.js +292 -292
- package/server/engine/agent/plugin-loader.js +266 -266
- package/server/engine/agent/prompts/nodesign-prelude.md +388 -336
- package/server/engine/agent/prompts/tools/ask-user-question-protocol.md +71 -71
- package/server/engine/agent/prompts/tools/direct-edit-protocol.md +98 -98
- package/server/engine/agent/prompts/tools/generate-image-cookbook.gemini-gateway.md +583 -583
- package/server/engine/agent/prompts/tools/generate-image-cookbook.md +483 -483
- package/server/engine/agent/prompts/tools/hybrid-reference.md +100 -100
- package/server/engine/agent/prompts/tools/paint-still-cookbook.md +270 -270
- package/server/engine/agent/prompts/tools/roll-film-cookbook.md +70 -70
- package/server/engine/agent/prompts/tools/site-reference.md +106 -106
- package/server/engine/agent/prompts/tools/tweaks-syntax.md +125 -125
- package/server/engine/agent/prompts/tools/vision-checker-dispatch.md +48 -48
- package/server/engine/agent/session-loop.js +1035 -1024
- package/server/engine/agent/session-model.js +164 -164
- package/server/engine/agent/skill.js +204 -204
- package/server/engine/agent/task-events.js +78 -78
- package/server/engine/agents/ds-extractor.md +132 -132
- package/server/engine/agents/explorer.md +190 -190
- package/server/engine/agents/index.js +230 -230
- package/server/engine/agents/schemas/design-system.json +156 -156
- package/server/engine/agents/schemas/tweak-schema.json +113 -113
- package/server/engine/agents/tweak-proposer.md +127 -127
- package/server/engine/agents/vision-checker.md +254 -254
- package/server/engine/browse/capture.js +422 -422
- package/server/engine/browse/card.js +137 -137
- package/server/engine/browse/handover.js +59 -59
- package/server/engine/browse/page-digest.js +119 -119
- package/server/engine/browse/refs.js +196 -196
- package/server/engine/browse/registry.js +307 -307
- package/server/engine/browse/screencast.js +170 -170
- package/server/engine/browse/state.js +121 -121
- package/server/engine/chatai/chat-log.js +79 -79
- package/server/engine/chatai/index.js +193 -193
- package/server/engine/chatai/openai-compat.js +152 -152
- package/server/engine/chatai/orchestrate.js +309 -309
- package/server/engine/chatai/perform.js +40 -40
- package/server/engine/chatai/summarize.js +79 -79
- package/server/engine/mcp/capability-gate.js +52 -52
- package/server/engine/mcp/index.js +351 -339
- package/server/engine/mcp/param-sanitizer.js +142 -142
- package/server/engine/mcp/tools/arrange-on-board.js +124 -124
- package/server/engine/mcp/tools/artifact-session.js +278 -278
- package/server/engine/mcp/tools/browse-computer.js +421 -421
- package/server/engine/mcp/tools/browse-find-batch.js +183 -183
- package/server/engine/mcp/tools/browse-screenshot.js +157 -157
- package/server/engine/mcp/tools/browse.js +480 -480
- package/server/engine/mcp/tools/build-docx.js +101 -101
- package/server/engine/mcp/tools/clear-pending-changes.js +99 -99
- package/server/engine/mcp/tools/create-on-board.js +152 -155
- package/server/engine/mcp/tools/crystallize-skill.js +168 -168
- package/server/engine/mcp/tools/edit-sketch.js +167 -0
- package/server/engine/mcp/tools/explain-style.js +237 -237
- package/server/engine/mcp/tools/export-handoff.js +133 -133
- package/server/engine/mcp/tools/expose-tweaks.js +149 -149
- package/server/engine/mcp/tools/generate-image.js +842 -842
- package/server/engine/mcp/tools/get-computed-styles.js +164 -164
- package/server/engine/mcp/tools/get-pending-changes.js +205 -205
- package/server/engine/mcp/tools/h3box-ssh.js +84 -84
- package/server/engine/mcp/tools/helpers/acquire-page.js +82 -82
- package/server/engine/mcp/tools/helpers/motion-lab.js +554 -554
- package/server/engine/mcp/tools/helpers/motion-scroll.js +112 -112
- package/server/engine/mcp/tools/helpers/perception-page.js +215 -215
- package/server/engine/mcp/tools/helpers/reference-download.js +103 -103
- package/server/engine/mcp/tools/helpers/rembg-bridge.py +80 -80
- package/server/engine/mcp/tools/helpers/shot-pipeline.js +280 -280
- package/server/engine/mcp/tools/highlight.js +68 -68
- package/server/engine/mcp/tools/list-pages.js +222 -222
- package/server/engine/mcp/tools/look-at-board.js +124 -0
- package/server/engine/mcp/tools/lookup-tags.js +59 -59
- package/server/engine/mcp/tools/navigate-to-page.js +60 -60
- package/server/engine/mcp/tools/organize-board.js +64 -64
- package/server/engine/mcp/tools/paint-still.js +434 -434
- package/server/engine/mcp/tools/pin-to-board.js +130 -130
- package/server/engine/mcp/tools/preview-deck.js +130 -130
- package/server/engine/mcp/tools/profile-scroll.js +305 -305
- package/server/engine/mcp/tools/publish-site.js +102 -102
- package/server/engine/mcp/tools/query-elements.js +195 -195
- package/server/engine/mcp/tools/read-board.js +190 -103
- package/server/engine/mcp/tools/read-document.js +93 -93
- package/server/engine/mcp/tools/read-page.js +264 -264
- package/server/engine/mcp/tools/read-tavern-json.js +143 -143
- package/server/engine/mcp/tools/read-user-view.js +59 -0
- package/server/engine/mcp/tools/record-decision.js +140 -140
- package/server/engine/mcp/tools/relate-on-board.js +112 -110
- package/server/engine/mcp/tools/report-issue.js +115 -115
- package/server/engine/mcp/tools/roll-film.js +266 -266
- package/server/engine/mcp/tools/screenshot-docx.js +138 -138
- package/server/engine/mcp/tools/screenshot-url.js +195 -195
- package/server/engine/mcp/tools/screenshot.js +583 -583
- package/server/engine/mcp/tools/sketch-on-board.js +337 -0
- package/server/engine/mcp/tools/tier-gate.js +96 -96
- package/server/engine/mcp/tools/trace-motion.js +215 -215
- package/server/engine/mcp/tools/web-search.js +548 -548
- package/server/engine/mcp/tools/write-on-board.js +130 -0
- package/server/engine/motion/inventory.js +349 -349
- package/server/engine/perception/session.js +235 -235
- package/server/engine/plugins/nodesign/.claude-plugin/plugin.json +5 -5
- package/server/engine/plugins/nodesign/skills/deskskill-engine-mini/SKILL.md +199 -192
- package/server/engine/plugins/nodesign/skills/deskskill-engine-mini/canvas.template.html +667 -667
- package/server/engine/plugins/nodesign/skills/deskskill-engine-mini/patterns/hybrid-grid.md +22 -22
- package/server/engine/plugins/nodesign/skills/deskskill-engine-mini/patterns/image-led-cover.md +25 -25
- package/server/engine/plugins/nodesign/skills/deskskill-engine-mini/patterns/portrait.md +23 -23
- package/server/engine/plugins/nodesign/skills/deskskill-engine-mini/patterns/quote-backdrop.md +21 -21
- package/server/engine/plugins/nodesign/skills/deskskill-engine-mini/patterns/section-divider.md +23 -23
- package/server/engine/plugins/nodesign/skills/deskskill-engine-mini/patterns/text-led.md +21 -21
- package/server/engine/plugins/nodesign/skills/docx-craft/SKILL.md +169 -162
- package/server/engine/plugins/nodesign/skills/docx-craft/references/token-schema.md +407 -407
- package/server/engine/plugins/nodesign/skills/docx-craft//346/226/207/346/241/243.template.json +80 -80
- package/server/engine/plugins/nodesign/skills/rp-craft/SKILL.md +235 -228
- 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
- package/server/engine/plugins/nodesign/skills/rp-craft//346/274/224/345/207/272.template.js +268 -268
- package/server/engine/plugins/nodesign/skills/site-craft/SKILL.md +330 -323
- package/server/engine/plugins/nodesign/skills/site-craft/patterns/build-lane.md +134 -134
- package/server/engine/plugins/nodesign/skills/site-craft/patterns/cutout-collage.md +61 -61
- package/server/engine/plugins/nodesign/skills/site-craft/patterns/mock-app.md +163 -163
- package/server/engine/plugins/nodesign/skills/site-craft/patterns/page-transitions.md +86 -86
- package/server/engine/runs/active-runs.js +698 -698
- package/server/engine/runs/board-tasklist.js +130 -0
- package/server/engine/runs/live-turn.js +252 -252
- package/server/engine/runs/store.js +364 -364
- package/server/engine/runs/turn-relay.js +217 -217
- package/server/engine/runtime/workspace.js +164 -164
- package/server/index.js +3 -0
- package/server/lib/artifact-file-path.js +80 -80
- package/server/lib/artifact-target.js +284 -284
- package/server/lib/asset-refs.js +239 -239
- package/server/lib/async-queue.js +104 -104
- package/server/lib/auto-relations.js +130 -130
- package/server/lib/binding-types.js +72 -60
- package/server/lib/board-graph-export.js +191 -0
- package/server/lib/board-groups.js +167 -0
- package/server/lib/board-hero.js +76 -0
- package/server/lib/board-kind-sizes.js +85 -62
- package/server/lib/board-relations.js +133 -133
- package/server/lib/browse-proxy.js +180 -180
- package/server/lib/canvas-id.js +36 -36
- package/server/lib/chalk.js +121 -0
- package/server/lib/cover.js +227 -227
- package/server/lib/danbooru-tags.js +291 -291
- package/server/lib/doc-extract.js +156 -156
- package/server/lib/docx/build-from-source.js +260 -260
- package/server/lib/docx/build.js +490 -490
- package/server/lib/docx/dump-styles.js +287 -287
- package/server/lib/docx/fonts/nodesign-cjk.conf +164 -164
- package/server/lib/docx/merge-runs.js +129 -129
- package/server/lib/docx/numbering.js +218 -218
- package/server/lib/docx/order.js +152 -152
- package/server/lib/docx/rawzip.js +172 -172
- package/server/lib/docx/render.js +92 -92
- package/server/lib/docx/text-lint.js +225 -225
- package/server/lib/docx/tokens.js +335 -335
- package/server/lib/docx/units.js +29 -29
- package/server/lib/docx/xml.js +291 -291
- package/server/lib/docx-pages.js +187 -187
- package/server/lib/export-collect.js +289 -289
- package/server/lib/export-package.js +210 -210
- package/server/lib/html-srcset.js +145 -145
- package/server/lib/image-variant.js +460 -460
- package/server/lib/ingress/forward-openai-chat.js +305 -305
- package/server/lib/ingress/openai-chat.js +491 -491
- package/server/lib/ingress/session-notice.js +66 -66
- package/server/lib/ingress/session-routes.js +68 -68
- package/server/lib/ingress/slot-probe.js +130 -130
- package/server/lib/ingress/upstream-billing.js +52 -52
- package/server/lib/ingress/upstream-fail-streak.js +72 -72
- package/server/lib/ingress/upstream-truncation.js +48 -48
- package/server/lib/issues-store.js +182 -182
- package/server/lib/kinds/deck.js +72 -72
- package/server/lib/kinds/docx.js +283 -283
- package/server/lib/kinds/file-kinds.js +113 -113
- package/server/lib/kinds/index.js +202 -202
- package/server/lib/kinds/site.js +161 -161
- package/server/lib/model-ingress.js +543 -543
- package/server/lib/moderation.js +255 -255
- package/server/lib/notice-store.js +103 -103
- package/server/lib/plugin-install.js +104 -104
- package/server/lib/plugin-validator.js +721 -721
- package/server/lib/publish-store.js +115 -115
- package/server/lib/quick-summary.js +52 -52
- package/server/lib/quota.js +270 -270
- package/server/lib/rate-window.js +29 -29
- package/server/lib/reference-assets.js +92 -92
- package/server/lib/region-shot.js +135 -135
- package/server/lib/safe-path.js +73 -73
- package/server/lib/sdk-session.js +33 -33
- package/server/lib/showcase-store.js +92 -92
- package/server/lib/site-publish.js +465 -465
- package/server/lib/sketch-layout.js +277 -0
- package/server/lib/ssrf-guard.js +432 -432
- package/server/lib/task-scan.js +158 -158
- package/server/lib/tavern-json.js +154 -154
- package/server/lib/video-variant.js +237 -237
- package/server/lib/workspace-path.js +33 -33
- package/server/ops/fix-sdk-musl.mjs +40 -40
- package/server/ops/install-macos-fonts.sh +114 -114
- package/server/ops/macos-fonts.conf +336 -336
- package/server/ops/sandbox-shim/bwrap +57 -57
- package/server/projects/assets-summary.js +119 -119
- package/server/projects/auto-name.js +53 -53
- package/server/projects/board-limits.js +12 -0
- package/server/projects/board-sanitize.js +252 -0
- package/server/projects/board-store.js +507 -640
- package/server/projects/move-entry.js +103 -103
- package/server/projects/store.js +270 -270
- package/server/projects/ui-config.js +60 -54
- package/server/projects/viewpoint-store.js +78 -0
- package/server/projects/workspace-templates.js +53 -53
- package/server/projects/workspace.js +1025 -1025
- package/server/runtime/local-config.js +177 -177
- package/server/runtime/profile.js +72 -72
- package/server/services/rembg-service.py +334 -334
- package/server/shared/README.md +25 -25
- package/server/shared/deck.js +54 -54
- package/server/shared/time.js +49 -49
- package/server/style-pipeline/README.md +53 -53
- package/server/ws/broker.js +39 -36
- package/server/ws/browse-channel.js +177 -177
- package/server/ws/index.js +386 -386
- package/web/README.md +89 -89
- package/web/dist/assets/BrowserWindow-P_vIdh-G.js +11 -0
- package/web/dist/assets/{DeckWindow-4G0xX7P3.js → DeckWindow-BpLv5082.js} +3 -3
- package/web/dist/assets/{DocxWindow-BXQsoPkh.js → DocxWindow-DSAU1-tD.js} +4 -4
- package/web/dist/assets/MermaidBlock-DR1GikCv.js +313 -0
- package/web/dist/assets/SiteWindow-92uBuRRR.js +18 -0
- package/web/dist/assets/abnfDiagram-VCTEODGH-uA8Esix4.js +1 -0
- package/web/dist/assets/arc-D_khH_xN.js +1 -0
- package/web/dist/assets/architectureDiagram-5GKGNRK7-DydJHqOt.js +36 -0
- package/web/dist/assets/blockDiagram-NRAW4CY4-B7wBbKiW.js +129 -0
- package/web/dist/assets/c4Diagram-UCG6FXSJ-6mrH0x7Y.js +38 -0
- package/web/dist/assets/channel-DGkccMO1.js +1 -0
- package/web/dist/assets/chunk-2Q5K7J3B-Cuikho5Q.js +1 -0
- package/web/dist/assets/chunk-5VM5RSS4-3-KZ5AUz.js +15 -0
- package/web/dist/assets/chunk-F27PBJKO-Bkwq2gGU.js +1 -0
- package/web/dist/assets/chunk-G27WJ6UU-BLyQzdGE.js +231 -0
- package/web/dist/assets/chunk-JWPE2WC7-B7HxxQds.js +1 -0
- package/web/dist/assets/chunk-LCL6LL3I-CtXrnUwF.js +206 -0
- package/web/dist/assets/chunk-POPQ4Y6H-dxddZlXt.js +1 -0
- package/web/dist/assets/chunk-SVP7TREG-DpkmrgHn.js +88 -0
- package/web/dist/assets/chunk-XXDRQBXY-BwZ7RbpQ.js +1 -0
- package/web/dist/assets/classDiagram-DTDB5LWJ-BGscw3OD.js +1 -0
- package/web/dist/assets/classDiagram-v2-JRS7N3AN-BGscw3OD.js +1 -0
- package/web/dist/assets/cose-bilkent-JH36ORCC-DGFOsMUt.js +1 -0
- package/web/dist/assets/cynefin-OW5HDTMX-DUwn3ehS.js +178 -0
- package/web/dist/assets/cynefinDiagram-5FMLGOSQ-DlLAOZ9x.js +62 -0
- package/web/dist/assets/cytoscape.esm-BjAbmLdb.js +331 -0
- package/web/dist/assets/dagre-3AP2YEHR-CyourLfz.js +4 -0
- package/web/dist/assets/defaultLocale-DX6XiGOO.js +1 -0
- package/web/dist/assets/diagram-S7CK7UJ4-BTMbx2np.js +30 -0
- package/web/dist/assets/diagram-UQ7AKVKN-UK94_1-P.js +41 -0
- package/web/dist/assets/diagram-VSXAHHWV-C7zS-v9v.js +3 -0
- package/web/dist/assets/diagram-VX7I27RA-DKJRa6CK.js +24 -0
- package/web/dist/assets/diagram-Z3DM3KII-kUbAfGAp.js +24 -0
- package/web/dist/assets/ebnfDiagram-PWID7BFC-CVW16_vb.js +1 -0
- package/web/dist/assets/erDiagram-SSCWMZ5O-BRQMFQ5y.js +99 -0
- package/web/dist/assets/flowDiagram-A5DVABFB-S34LpLtK.js +168 -0
- package/web/dist/assets/ganttDiagram-EL5Y4UJY-BFiqk1-G.js +292 -0
- package/web/dist/assets/gitGraphDiagram-WWUBYQGX-LZsrdyyv.js +106 -0
- package/web/dist/assets/index-GAamh1p4.js +2152 -0
- package/web/dist/assets/infoDiagram-RXCK75RN-0DvN6KIp.js +2 -0
- package/web/dist/assets/init-Gi6I4Gst.js +1 -0
- package/web/dist/assets/ishikawaDiagram-5VMMS53U-CaY3A-Bx.js +70 -0
- package/web/dist/assets/journeyDiagram-EYS64GPL-BBeiaCrj.js +139 -0
- package/web/dist/assets/kanban-definition-3QL26DDD-ux42DRXQ.js +89 -0
- package/web/dist/assets/layout-CnXiF_NB.js +1 -0
- package/web/dist/assets/linear-BMW0u6G6.js +1 -0
- package/web/dist/assets/mindmap-definition-FBJOCRG2-hUxSpdKn.js +96 -0
- package/web/dist/assets/ordinal-Cboi1Yqb.js +1 -0
- package/web/dist/assets/pegDiagram-XKGWAZYB-aCaQPH0w.js +1 -0
- package/web/dist/assets/{pending-edit-apply-DTjo2geW.js → pending-edit-apply-AcdOQ9Ij.js} +6 -6
- package/web/dist/assets/pieDiagram-E7YTZNPT-CmOEZ8zg.js +39 -0
- package/web/dist/assets/quadrantDiagram-AXDQQJYC-VW6fAhsV.js +7 -0
- package/web/dist/assets/railroadDiagram-O6MQD6OU-CKJ7Ba5K.js +1 -0
- package/web/dist/assets/requirementDiagram-EFPCY7ZU-pNGkq9Vw.js +84 -0
- package/web/dist/assets/{rotate-cw-LMT3x1Zj.js → rotate-cw-KAfChbGV.js} +1 -1
- package/web/dist/assets/sankeyDiagram-P5KCCOFB-BIMmDTfZ.js +40 -0
- package/web/dist/assets/sequenceDiagram-WJ2MYXX4-BBW7wzKY.js +162 -0
- package/web/dist/assets/sizeCapture-X5ZJPWSS-DdkXmLYR.js +1 -0
- package/web/dist/assets/{square-dashed-mouse-pointer-CBoAkfhi.js → square-dashed-mouse-pointer-CDUlhUP7.js} +1 -1
- package/web/dist/assets/stateDiagram-HBIQ2CUA-W313Uz16.js +1 -0
- package/web/dist/assets/stateDiagram-v2-4QOOHH4V-DDhJBZzf.js +1 -0
- package/web/dist/assets/swimlanes-XN3QIQJK-C29TL26K.js +1 -0
- package/web/dist/assets/swimlanesDiagram-VK2B7HYN-BfN-Xdmu.js +8 -0
- package/web/dist/assets/timeline-definition-24CTP7MA-CF0JMObX.js +120 -0
- package/web/dist/assets/vennDiagram-4TSXK5OY-DrDFsaH3.js +34 -0
- package/web/dist/assets/wardleyDiagram-VM6X3IG4-CVrnRIS_.js +78 -0
- package/web/dist/assets/xychartDiagram-S5SC5T6Z-BvkN1zsT.js +7 -0
- package/web/dist/index.html +17 -17
- package/web/dist/assets/BrowserWindow-Dc7J7CYc.js +0 -11
- package/web/dist/assets/SiteWindow-D6eS-2gM.js +0 -18
- package/web/dist/assets/index-Cbl3ATvp.js +0 -2125
|
@@ -1,120 +1,120 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PostToolUseFailure handler — 工具失败时给 agent 恢复建议。
|
|
3
|
-
* (2026-08-14 可维护性行动:从 hooks.js 原样迁出,语义零改动)
|
|
4
|
-
*
|
|
5
|
-
* input: PostToolUseFailureHookInput (sdk.d.ts:1908)
|
|
6
|
-
* - tool_name: string
|
|
7
|
-
* - tool_input: unknown
|
|
8
|
-
* - tool_use_id: string
|
|
9
|
-
* - error: string
|
|
10
|
-
* - is_interrupt?: boolean
|
|
11
|
-
* - duration_ms?: number
|
|
12
|
-
*
|
|
13
|
-
* output: PostToolUseFailureHookSpecificOutput (sdk.d.ts:1921)
|
|
14
|
-
* - additionalContext?: string
|
|
15
|
-
*/
|
|
16
|
-
import { Events } from '../events.js';
|
|
17
|
-
import { recordIssue, signatureOf } from '../../../lib/issues-store.js';
|
|
18
|
-
|
|
19
|
-
export function makePostToolUseFailureHandler({ ctx, projectId, sessionId }) {
|
|
20
|
-
return async (input, _toolUseId, _options) => {
|
|
21
|
-
const tool = input?.tool_name || 'unknown';
|
|
22
|
-
const error = String(input?.error || '').slice(0, 500);
|
|
23
|
-
const isInterrupt = Boolean(input?.is_interrupt);
|
|
24
|
-
|
|
25
|
-
try {
|
|
26
|
-
ctx.emit(Events.toolFailure(tool, error));
|
|
27
|
-
} catch { /* ignore */ }
|
|
28
|
-
|
|
29
|
-
// is_interrupt: 用户中断 → 不注入建议(agent 应该停下,不是恢复)
|
|
30
|
-
if (isInterrupt) return {};
|
|
31
|
-
|
|
32
|
-
// 自动层问题记录(2026-07-30):每次真失败按"错误类"累加计数。
|
|
33
|
-
// 这层不依赖 agent 自觉 —— 它太会兜底了,工具坏了换个姿势就绕过去,
|
|
34
|
-
// 表面上活儿还是干完的,于是"某个工具本周失败 40 次"没人知道。
|
|
35
|
-
// fail-soft:记录本身绝不能变成新的故障源。
|
|
36
|
-
try {
|
|
37
|
-
recordIssue({
|
|
38
|
-
source: 'auto',
|
|
39
|
-
toolName: tool,
|
|
40
|
-
summary: `${tool} 失败:${error.slice(0, 120)}`,
|
|
41
|
-
detail: error,
|
|
42
|
-
projectId,
|
|
43
|
-
sessionId,
|
|
44
|
-
signature: signatureOf(`${tool}|${error}`),
|
|
45
|
-
});
|
|
46
|
-
} catch { /* ignore */ }
|
|
47
|
-
|
|
48
|
-
let advice;
|
|
49
|
-
if (tool === 'mcp__nodesign__screenshot_canvas') {
|
|
50
|
-
advice =
|
|
51
|
-
'截图失败。常见原因:\n'
|
|
52
|
-
+ ' 1. 产物文件还没创建 → 先 Write 创建首版\n'
|
|
53
|
-
+ ' 2. playwright spawn 慢 / 失败 → 换 Read 产物文件让用户看代码\n'
|
|
54
|
-
+ ' 3. fullPage 截图太大 → 换 fullPage:false 截视口';
|
|
55
|
-
} else if (tool === 'Bash' && /apply-seccomp|unshare\(CLONE_NEWUSER\)/.test(error)) {
|
|
56
|
-
// 沙盒启动自身的偶发(2026-08-15 实测约 1-2/14):seccomp 那步的 unshare
|
|
57
|
-
// 跟运行时起线程抢跑,EINVAL。跟命令本身、跟权限都没关系 —— **原样重跑
|
|
58
|
-
// 一次就过**。必须点破:08-15 真会话里 agent 把它误判成"隔离闸拦住了",
|
|
59
|
-
// 拿一个假结论去回答用户。
|
|
60
|
-
// 上游 issue:https://github.com/anthropics/claude-code/issues/86928
|
|
61
|
-
// 现在 ops/sandbox-shim/bwrap 那个垫片已经把它治住了,这条留着兜底:
|
|
62
|
-
// 垫片靠识别 SDK 内部命令前缀工作,SDK 升级后失配就会静默退回偶发。
|
|
63
|
-
advice =
|
|
64
|
-
'这不是你的命令有问题,也不是权限拦截 —— 是沙盒启动时的已知偶发'
|
|
65
|
-
+ '(apply-seccomp / unshare EINVAL,约十几分之一的概率)。\n'
|
|
66
|
-
+ '**把刚才那条命令原样再跑一次就行**,别改写命令,也别据此推断"某个东西被拦了"。';
|
|
67
|
-
} else if (tool === 'Bash') {
|
|
68
|
-
advice =
|
|
69
|
-
'Bash 命令失败。常见:\n'
|
|
70
|
-
+ ' 1. sandbox 拦截(命令访问越界文件 / 不允许的网络)→ 换 Read / Glob / Grep / MCP 工具\n'
|
|
71
|
-
+ ' 2. cwd 越界 → 路径相对 workspace\n'
|
|
72
|
-
+ ' 3. 命令本身错(参数 / 文件不存在)→ 检查 stderr';
|
|
73
|
-
} else if (tool === 'Write' || tool === 'Edit') {
|
|
74
|
-
advice =
|
|
75
|
-
`${tool} 失败。检查:\n`
|
|
76
|
-
+ ' 1. 路径相对 workspace 还是绝对路径\n'
|
|
77
|
-
+ ' 2. Edit 的 old_string 是否完整匹配(含空格/缩进)\n'
|
|
78
|
-
+ ' 3. 文件是否存在(不存在用 Write 创建)';
|
|
79
|
-
} else if (tool === 'Read') {
|
|
80
|
-
advice = `Read 失败:${error}\n 1. 确认路径相对 workspace\n 2. 用 Glob 找文件确认存在`;
|
|
81
|
-
} else if (tool === 'mcp__nodesign__generate_image') {
|
|
82
|
-
// 按错因分流恢复建议(多数 generate_image 失败可恢复,**默认应重试不是放弃**)
|
|
83
|
-
const errLower = error.toLowerCase();
|
|
84
|
-
let cause;
|
|
85
|
-
if (/http 429|rate.?limit|too many request/.test(errLower)) {
|
|
86
|
-
cause = '网关限流(429)→ 等 3-5 秒**直接重试**,不必改 prompt。短时间内连续生图触发的,过会儿就 OK';
|
|
87
|
-
} else if (/http 5\d\d|timeout|gateway|econnreset|socket/.test(errLower)) {
|
|
88
|
-
cause = '网关 / 上游临时故障(5xx / 网络抖动)→ **直接重试 1-2 次**,多数情况下第二次就成;连续 3 次同错才考虑改思路';
|
|
89
|
-
} else if (/no parts|no image|safety|blocked|policy/.test(errLower)) {
|
|
90
|
-
cause = '模型拒生(安全过滤 / 内容策略)→ 调 prompt:换更具体的视觉词(流派 / 镜头 / 灯光),去掉可能触发安全过滤的人物 / 暴力 / 品牌侵权描述,重试';
|
|
91
|
-
} else if (/http 400|invalid|bad request/.test(errLower)) {
|
|
92
|
-
cause = 'Prompt 或参数问题(400)→ 检查:去掉否定描述("no cars" → "empty street")/ 加风格锚("Saul Bass minimalist" / "Fujifilm color science")/ aspectRatio + imageSize 组合是否合法,重试';
|
|
93
|
-
} else if (/path|reference|enoent|not.?found/.test(errLower)) {
|
|
94
|
-
cause = 'referenceImages 路径错 → 用 Glob 确认文件存在;只接 workspace 相对路径(assets/...),不接 http url;选 1-2 张最切题的不要全 14 张';
|
|
95
|
-
} else if (/quota|budget|limit/.test(errLower)) {
|
|
96
|
-
cause = '配额 / 预算限制 → 看 PM2 日志确认;非紧急情况下告诉用户,等用户决定';
|
|
97
|
-
} else {
|
|
98
|
-
cause = '错因未知 → **先重试 1 次**(多数是网络抖动);同错重现再调 prompt 关键参数(5 元素公式 / 风格锚 / 文字带引号)。不要第一次失败就放弃';
|
|
99
|
-
}
|
|
100
|
-
advice =
|
|
101
|
-
`generate_image 失败:${error}\n\n`
|
|
102
|
-
+ `→ ${cause}\n\n`
|
|
103
|
-
+ `**重要**:generate_image 多数失败是可恢复的(网关抖动 / prompt 微调)。第一次失败就放弃 = 用户没图用,跟"agent 不会生图"体感一样差。**默认应重试 1-2 次**,连续 3 次同错才考虑换思路 / 询问用户。`;
|
|
104
|
-
} else {
|
|
105
|
-
advice =
|
|
106
|
-
`${tool} 失败:${error}\n`
|
|
107
|
-
+ '常见恢复:\n'
|
|
108
|
-
+ ' 1. 先重试 1 次(网络抖动 / 临时上游故障多数情况下二次成功)\n'
|
|
109
|
-
+ ' 2. 同错重现 → 分析错因调整参数 / 换工具\n'
|
|
110
|
-
+ ' 3. 仅当连续失败且阻塞主线 → 在 chat 里跟用户说当前卡点 + 你打算怎么绕过';
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return {
|
|
114
|
-
hookSpecificOutput: {
|
|
115
|
-
hookEventName: 'PostToolUseFailure',
|
|
116
|
-
additionalContext: `[工具失败恢复建议]\n${advice}`,
|
|
117
|
-
},
|
|
118
|
-
};
|
|
119
|
-
};
|
|
120
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* PostToolUseFailure handler — 工具失败时给 agent 恢复建议。
|
|
3
|
+
* (2026-08-14 可维护性行动:从 hooks.js 原样迁出,语义零改动)
|
|
4
|
+
*
|
|
5
|
+
* input: PostToolUseFailureHookInput (sdk.d.ts:1908)
|
|
6
|
+
* - tool_name: string
|
|
7
|
+
* - tool_input: unknown
|
|
8
|
+
* - tool_use_id: string
|
|
9
|
+
* - error: string
|
|
10
|
+
* - is_interrupt?: boolean
|
|
11
|
+
* - duration_ms?: number
|
|
12
|
+
*
|
|
13
|
+
* output: PostToolUseFailureHookSpecificOutput (sdk.d.ts:1921)
|
|
14
|
+
* - additionalContext?: string
|
|
15
|
+
*/
|
|
16
|
+
import { Events } from '../events.js';
|
|
17
|
+
import { recordIssue, signatureOf } from '../../../lib/issues-store.js';
|
|
18
|
+
|
|
19
|
+
export function makePostToolUseFailureHandler({ ctx, projectId, sessionId }) {
|
|
20
|
+
return async (input, _toolUseId, _options) => {
|
|
21
|
+
const tool = input?.tool_name || 'unknown';
|
|
22
|
+
const error = String(input?.error || '').slice(0, 500);
|
|
23
|
+
const isInterrupt = Boolean(input?.is_interrupt);
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
ctx.emit(Events.toolFailure(tool, error));
|
|
27
|
+
} catch { /* ignore */ }
|
|
28
|
+
|
|
29
|
+
// is_interrupt: 用户中断 → 不注入建议(agent 应该停下,不是恢复)
|
|
30
|
+
if (isInterrupt) return {};
|
|
31
|
+
|
|
32
|
+
// 自动层问题记录(2026-07-30):每次真失败按"错误类"累加计数。
|
|
33
|
+
// 这层不依赖 agent 自觉 —— 它太会兜底了,工具坏了换个姿势就绕过去,
|
|
34
|
+
// 表面上活儿还是干完的,于是"某个工具本周失败 40 次"没人知道。
|
|
35
|
+
// fail-soft:记录本身绝不能变成新的故障源。
|
|
36
|
+
try {
|
|
37
|
+
recordIssue({
|
|
38
|
+
source: 'auto',
|
|
39
|
+
toolName: tool,
|
|
40
|
+
summary: `${tool} 失败:${error.slice(0, 120)}`,
|
|
41
|
+
detail: error,
|
|
42
|
+
projectId,
|
|
43
|
+
sessionId,
|
|
44
|
+
signature: signatureOf(`${tool}|${error}`),
|
|
45
|
+
});
|
|
46
|
+
} catch { /* ignore */ }
|
|
47
|
+
|
|
48
|
+
let advice;
|
|
49
|
+
if (tool === 'mcp__nodesign__screenshot_canvas') {
|
|
50
|
+
advice =
|
|
51
|
+
'截图失败。常见原因:\n'
|
|
52
|
+
+ ' 1. 产物文件还没创建 → 先 Write 创建首版\n'
|
|
53
|
+
+ ' 2. playwright spawn 慢 / 失败 → 换 Read 产物文件让用户看代码\n'
|
|
54
|
+
+ ' 3. fullPage 截图太大 → 换 fullPage:false 截视口';
|
|
55
|
+
} else if (tool === 'Bash' && /apply-seccomp|unshare\(CLONE_NEWUSER\)/.test(error)) {
|
|
56
|
+
// 沙盒启动自身的偶发(2026-08-15 实测约 1-2/14):seccomp 那步的 unshare
|
|
57
|
+
// 跟运行时起线程抢跑,EINVAL。跟命令本身、跟权限都没关系 —— **原样重跑
|
|
58
|
+
// 一次就过**。必须点破:08-15 真会话里 agent 把它误判成"隔离闸拦住了",
|
|
59
|
+
// 拿一个假结论去回答用户。
|
|
60
|
+
// 上游 issue:https://github.com/anthropics/claude-code/issues/86928
|
|
61
|
+
// 现在 ops/sandbox-shim/bwrap 那个垫片已经把它治住了,这条留着兜底:
|
|
62
|
+
// 垫片靠识别 SDK 内部命令前缀工作,SDK 升级后失配就会静默退回偶发。
|
|
63
|
+
advice =
|
|
64
|
+
'这不是你的命令有问题,也不是权限拦截 —— 是沙盒启动时的已知偶发'
|
|
65
|
+
+ '(apply-seccomp / unshare EINVAL,约十几分之一的概率)。\n'
|
|
66
|
+
+ '**把刚才那条命令原样再跑一次就行**,别改写命令,也别据此推断"某个东西被拦了"。';
|
|
67
|
+
} else if (tool === 'Bash') {
|
|
68
|
+
advice =
|
|
69
|
+
'Bash 命令失败。常见:\n'
|
|
70
|
+
+ ' 1. sandbox 拦截(命令访问越界文件 / 不允许的网络)→ 换 Read / Glob / Grep / MCP 工具\n'
|
|
71
|
+
+ ' 2. cwd 越界 → 路径相对 workspace\n'
|
|
72
|
+
+ ' 3. 命令本身错(参数 / 文件不存在)→ 检查 stderr';
|
|
73
|
+
} else if (tool === 'Write' || tool === 'Edit') {
|
|
74
|
+
advice =
|
|
75
|
+
`${tool} 失败。检查:\n`
|
|
76
|
+
+ ' 1. 路径相对 workspace 还是绝对路径\n'
|
|
77
|
+
+ ' 2. Edit 的 old_string 是否完整匹配(含空格/缩进)\n'
|
|
78
|
+
+ ' 3. 文件是否存在(不存在用 Write 创建)';
|
|
79
|
+
} else if (tool === 'Read') {
|
|
80
|
+
advice = `Read 失败:${error}\n 1. 确认路径相对 workspace\n 2. 用 Glob 找文件确认存在`;
|
|
81
|
+
} else if (tool === 'mcp__nodesign__generate_image') {
|
|
82
|
+
// 按错因分流恢复建议(多数 generate_image 失败可恢复,**默认应重试不是放弃**)
|
|
83
|
+
const errLower = error.toLowerCase();
|
|
84
|
+
let cause;
|
|
85
|
+
if (/http 429|rate.?limit|too many request/.test(errLower)) {
|
|
86
|
+
cause = '网关限流(429)→ 等 3-5 秒**直接重试**,不必改 prompt。短时间内连续生图触发的,过会儿就 OK';
|
|
87
|
+
} else if (/http 5\d\d|timeout|gateway|econnreset|socket/.test(errLower)) {
|
|
88
|
+
cause = '网关 / 上游临时故障(5xx / 网络抖动)→ **直接重试 1-2 次**,多数情况下第二次就成;连续 3 次同错才考虑改思路';
|
|
89
|
+
} else if (/no parts|no image|safety|blocked|policy/.test(errLower)) {
|
|
90
|
+
cause = '模型拒生(安全过滤 / 内容策略)→ 调 prompt:换更具体的视觉词(流派 / 镜头 / 灯光),去掉可能触发安全过滤的人物 / 暴力 / 品牌侵权描述,重试';
|
|
91
|
+
} else if (/http 400|invalid|bad request/.test(errLower)) {
|
|
92
|
+
cause = 'Prompt 或参数问题(400)→ 检查:去掉否定描述("no cars" → "empty street")/ 加风格锚("Saul Bass minimalist" / "Fujifilm color science")/ aspectRatio + imageSize 组合是否合法,重试';
|
|
93
|
+
} else if (/path|reference|enoent|not.?found/.test(errLower)) {
|
|
94
|
+
cause = 'referenceImages 路径错 → 用 Glob 确认文件存在;只接 workspace 相对路径(assets/...),不接 http url;选 1-2 张最切题的不要全 14 张';
|
|
95
|
+
} else if (/quota|budget|limit/.test(errLower)) {
|
|
96
|
+
cause = '配额 / 预算限制 → 看 PM2 日志确认;非紧急情况下告诉用户,等用户决定';
|
|
97
|
+
} else {
|
|
98
|
+
cause = '错因未知 → **先重试 1 次**(多数是网络抖动);同错重现再调 prompt 关键参数(5 元素公式 / 风格锚 / 文字带引号)。不要第一次失败就放弃';
|
|
99
|
+
}
|
|
100
|
+
advice =
|
|
101
|
+
`generate_image 失败:${error}\n\n`
|
|
102
|
+
+ `→ ${cause}\n\n`
|
|
103
|
+
+ `**重要**:generate_image 多数失败是可恢复的(网关抖动 / prompt 微调)。第一次失败就放弃 = 用户没图用,跟"agent 不会生图"体感一样差。**默认应重试 1-2 次**,连续 3 次同错才考虑换思路 / 询问用户。`;
|
|
104
|
+
} else {
|
|
105
|
+
advice =
|
|
106
|
+
`${tool} 失败:${error}\n`
|
|
107
|
+
+ '常见恢复:\n'
|
|
108
|
+
+ ' 1. 先重试 1 次(网络抖动 / 临时上游故障多数情况下二次成功)\n'
|
|
109
|
+
+ ' 2. 同错重现 → 分析错因调整参数 / 换工具\n'
|
|
110
|
+
+ ' 3. 仅当连续失败且阻塞主线 → 在 chat 里跟用户说当前卡点 + 你打算怎么绕过';
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
hookSpecificOutput: {
|
|
115
|
+
hookEventName: 'PostToolUseFailure',
|
|
116
|
+
additionalContext: `[工具失败恢复建议]\n${advice}`,
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
}
|
|
@@ -1,75 +1,75 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 文件改动 → 前端刷新 的两条通路(2026-08-14 可维护性行动:从 hooks.js 原样迁出)。
|
|
3
|
-
*
|
|
4
|
-
* ⚠️ `toWorkspaceRel` 2026-08-13 提到 `server/lib/workspace-path.js`:
|
|
5
|
-
* 发给前端当物件寻址依据的路径全都要过它,而那些 emit 不只在这个文件里
|
|
6
|
-
* (agent-shared 的流式 tool_input 也发 filePath)。
|
|
7
|
-
*
|
|
8
|
-
* (这里曾经有「任务 → 会话」的认领机制(2026-07-28 ~ 08-07):会话第一次往
|
|
9
|
-
* `tasks/<任务>/` 写东西时落一个 `.nd-task.json` 记住是谁的家,还配了一个
|
|
10
|
-
* PostToolUse(Bash) 钩子扫命令行里的 `tasks/<名>`。整套随任务层一起退役 ——
|
|
11
|
-
* 产物属于项目,不属于任何一次对话。)
|
|
12
|
-
*/
|
|
13
|
-
import { Events } from '../events.js';
|
|
14
|
-
import { toWorkspaceRel } from '../../../lib/workspace-path.js';
|
|
15
|
-
import { setActiveArtifact } from '../../../lib/artifact-target.js';
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* FileChanged handler(P0+ s1 C4):agent 写文件后 SDK 触发,转发给 EventBus。
|
|
19
|
-
*
|
|
20
|
-
* input: FileChangedHookInput (sdk.d.ts:557)
|
|
21
|
-
* - file_path: string 绝对路径或相对 cwd
|
|
22
|
-
* - event: 'change' | 'add' | 'unlink'
|
|
23
|
-
*
|
|
24
|
-
* 不在这里做 .html 过滤 —— 全部转发让前端按需消费(C18 ContextUsageBar /
|
|
25
|
-
* C20 file changes 列表都可能用)。前端 Project.jsx 只对 canvas.html bump reloadToken。
|
|
26
|
-
*
|
|
27
|
-
* 返回 {}:不干预 SDK,不影响 agent loop。
|
|
28
|
-
*/
|
|
29
|
-
export function makeFileChangedHandler({ ctx, workspaceRoot }) {
|
|
30
|
-
// eslint-disable-next-line no-unused-vars
|
|
31
|
-
return async (input, _toolUseId, _options) => {
|
|
32
|
-
try {
|
|
33
|
-
// 同下 emitter:发工作区相对路径,前端拿它直接当物件 id 的路径部分
|
|
34
|
-
ctx.emit(Events.fileChanged(toWorkspaceRel(input.file_path, workspaceRoot), input.event));
|
|
35
|
-
} catch (err) {
|
|
36
|
-
console.warn(`[hooks/FileChanged] handler threw:`, err.message);
|
|
37
|
-
}
|
|
38
|
-
return {};
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* PostToolUse(写文件系工具) → 直发 run.file_changed(2026-07-28)。
|
|
44
|
-
*
|
|
45
|
-
* SDK 的 FileChanged hook 是 watcher 型(要先声明 watchPaths 才启动),实测从未
|
|
46
|
-
* 触发。这里走确定性路径:Write/Edit/MultiEdit/NotebookEdit 成功完成即从入参拿
|
|
47
|
-
* 路径发事件 —— agent 每写完一笔,前端立刻 reload iframe / 刷产物墙 / 打角标,
|
|
48
|
-
* 不再等 run.done。PostToolUse 只在工具成功后触发(失败走 PostToolUseFailure),
|
|
49
|
-
* 不会把写坏的半成品刷给用户。
|
|
50
|
-
*/
|
|
51
|
-
export function makePostToolUseFileChangedEmitter({ ctx, workspaceRoot, sharedRoot, sessionId }) {
|
|
52
|
-
// eslint-disable-next-line no-unused-vars
|
|
53
|
-
return async (input, _toolUseId, _options) => {
|
|
54
|
-
try {
|
|
55
|
-
const t = input?.tool_input;
|
|
56
|
-
const filePath = typeof t?.file_path === 'string' ? t.file_path
|
|
57
|
-
: typeof t?.notebook_path === 'string' ? t.notebook_path : null;
|
|
58
|
-
if (filePath) {
|
|
59
|
-
// 刚写的这份 html 就是"当前产物"——list_pages / screenshot / read_page
|
|
60
|
-
// 不给 path 时默认打它,子代理不必知道任务目录长什么样(artifact-target.js)。
|
|
61
|
-
// 形态(deck / site)不在这里定:resolveArtifactTarget 每次解析都按任务现状
|
|
62
|
-
// 重算,免得"先写 index.html 记成 site、后来目录变了"这种陈旧状态。
|
|
63
|
-
const rel = toWorkspaceRel(filePath, workspaceRoot);
|
|
64
|
-
setActiveArtifact(sessionId, rel);
|
|
65
|
-
// 发**工作区相对路径**:画布物件的 id 就是这个字符串。以前发绝对路径,
|
|
66
|
-
// 前端靠 `tasks/<任务>/` 这个特征段把相对部分抠出来 —— 那一层拆掉之后
|
|
67
|
-
// 绝对路径里再没有可锚定的标志,寻址静默失败(舞台卡掉 dock)。
|
|
68
|
-
ctx.emit(Events.fileChanged(rel, 'change'));
|
|
69
|
-
}
|
|
70
|
-
} catch (err) {
|
|
71
|
-
console.warn('[hooks/PostToolUse:file-changed] emit failed:', err.message);
|
|
72
|
-
}
|
|
73
|
-
return {};
|
|
74
|
-
};
|
|
75
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* 文件改动 → 前端刷新 的两条通路(2026-08-14 可维护性行动:从 hooks.js 原样迁出)。
|
|
3
|
+
*
|
|
4
|
+
* ⚠️ `toWorkspaceRel` 2026-08-13 提到 `server/lib/workspace-path.js`:
|
|
5
|
+
* 发给前端当物件寻址依据的路径全都要过它,而那些 emit 不只在这个文件里
|
|
6
|
+
* (agent-shared 的流式 tool_input 也发 filePath)。
|
|
7
|
+
*
|
|
8
|
+
* (这里曾经有「任务 → 会话」的认领机制(2026-07-28 ~ 08-07):会话第一次往
|
|
9
|
+
* `tasks/<任务>/` 写东西时落一个 `.nd-task.json` 记住是谁的家,还配了一个
|
|
10
|
+
* PostToolUse(Bash) 钩子扫命令行里的 `tasks/<名>`。整套随任务层一起退役 ——
|
|
11
|
+
* 产物属于项目,不属于任何一次对话。)
|
|
12
|
+
*/
|
|
13
|
+
import { Events } from '../events.js';
|
|
14
|
+
import { toWorkspaceRel } from '../../../lib/workspace-path.js';
|
|
15
|
+
import { setActiveArtifact } from '../../../lib/artifact-target.js';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* FileChanged handler(P0+ s1 C4):agent 写文件后 SDK 触发,转发给 EventBus。
|
|
19
|
+
*
|
|
20
|
+
* input: FileChangedHookInput (sdk.d.ts:557)
|
|
21
|
+
* - file_path: string 绝对路径或相对 cwd
|
|
22
|
+
* - event: 'change' | 'add' | 'unlink'
|
|
23
|
+
*
|
|
24
|
+
* 不在这里做 .html 过滤 —— 全部转发让前端按需消费(C18 ContextUsageBar /
|
|
25
|
+
* C20 file changes 列表都可能用)。前端 Project.jsx 只对 canvas.html bump reloadToken。
|
|
26
|
+
*
|
|
27
|
+
* 返回 {}:不干预 SDK,不影响 agent loop。
|
|
28
|
+
*/
|
|
29
|
+
export function makeFileChangedHandler({ ctx, workspaceRoot }) {
|
|
30
|
+
// eslint-disable-next-line no-unused-vars
|
|
31
|
+
return async (input, _toolUseId, _options) => {
|
|
32
|
+
try {
|
|
33
|
+
// 同下 emitter:发工作区相对路径,前端拿它直接当物件 id 的路径部分
|
|
34
|
+
ctx.emit(Events.fileChanged(toWorkspaceRel(input.file_path, workspaceRoot), input.event));
|
|
35
|
+
} catch (err) {
|
|
36
|
+
console.warn(`[hooks/FileChanged] handler threw:`, err.message);
|
|
37
|
+
}
|
|
38
|
+
return {};
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* PostToolUse(写文件系工具) → 直发 run.file_changed(2026-07-28)。
|
|
44
|
+
*
|
|
45
|
+
* SDK 的 FileChanged hook 是 watcher 型(要先声明 watchPaths 才启动),实测从未
|
|
46
|
+
* 触发。这里走确定性路径:Write/Edit/MultiEdit/NotebookEdit 成功完成即从入参拿
|
|
47
|
+
* 路径发事件 —— agent 每写完一笔,前端立刻 reload iframe / 刷产物墙 / 打角标,
|
|
48
|
+
* 不再等 run.done。PostToolUse 只在工具成功后触发(失败走 PostToolUseFailure),
|
|
49
|
+
* 不会把写坏的半成品刷给用户。
|
|
50
|
+
*/
|
|
51
|
+
export function makePostToolUseFileChangedEmitter({ ctx, workspaceRoot, sharedRoot, sessionId }) {
|
|
52
|
+
// eslint-disable-next-line no-unused-vars
|
|
53
|
+
return async (input, _toolUseId, _options) => {
|
|
54
|
+
try {
|
|
55
|
+
const t = input?.tool_input;
|
|
56
|
+
const filePath = typeof t?.file_path === 'string' ? t.file_path
|
|
57
|
+
: typeof t?.notebook_path === 'string' ? t.notebook_path : null;
|
|
58
|
+
if (filePath) {
|
|
59
|
+
// 刚写的这份 html 就是"当前产物"——list_pages / screenshot / read_page
|
|
60
|
+
// 不给 path 时默认打它,子代理不必知道任务目录长什么样(artifact-target.js)。
|
|
61
|
+
// 形态(deck / site)不在这里定:resolveArtifactTarget 每次解析都按任务现状
|
|
62
|
+
// 重算,免得"先写 index.html 记成 site、后来目录变了"这种陈旧状态。
|
|
63
|
+
const rel = toWorkspaceRel(filePath, workspaceRoot);
|
|
64
|
+
setActiveArtifact(sessionId, rel);
|
|
65
|
+
// 发**工作区相对路径**:画布物件的 id 就是这个字符串。以前发绝对路径,
|
|
66
|
+
// 前端靠 `tasks/<任务>/` 这个特征段把相对部分抠出来 —— 那一层拆掉之后
|
|
67
|
+
// 绝对路径里再没有可锚定的标志,寻址静默失败(舞台卡掉 dock)。
|
|
68
|
+
ctx.emit(Events.fileChanged(rel, 'change'));
|
|
69
|
+
}
|
|
70
|
+
} catch (err) {
|
|
71
|
+
console.warn('[hooks/PostToolUse:file-changed] emit failed:', err.message);
|
|
72
|
+
}
|
|
73
|
+
return {};
|
|
74
|
+
};
|
|
75
|
+
}
|