@xiaobuyu/nodesign 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +22 -22
- package/server/api/assets/notes.js +144 -144
- package/server/api/assets.js +896 -896
- package/server/api/board.js +57 -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 +464 -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 +215 -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 +336 -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 +1024 -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 +339 -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 +155 -155
- package/server/engine/mcp/tools/crystallize-skill.js +168 -168
- 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/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 +103 -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/record-decision.js +140 -140
- package/server/engine/mcp/tools/relate-on-board.js +110 -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/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/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 +192 -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 +162 -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 +228 -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 +323 -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/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/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 +60 -60
- package/server/lib/board-kind-sizes.js +62 -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/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/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-store.js +640 -640
- package/server/projects/move-entry.js +103 -103
- package/server/projects/store.js +270 -270
- package/server/projects/ui-config.js +54 -54
- 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 +36 -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-BYCgizHw.js +11 -0
- package/web/dist/assets/{DeckWindow-4G0xX7P3.js → DeckWindow-pNydEM4L.js} +1 -1
- package/web/dist/assets/{DocxWindow-BXQsoPkh.js → DocxWindow-PPgzh3Gq.js} +1 -1
- package/web/dist/assets/{SiteWindow-D6eS-2gM.js → SiteWindow-DM0LQPCO.js} +1 -1
- package/web/dist/assets/{index-Cbl3ATvp.js → index-BHTBJlpY.js} +32 -32
- package/web/dist/assets/{pending-edit-apply-DTjo2geW.js → pending-edit-apply-C0I13CbD.js} +1 -1
- package/web/dist/assets/{rotate-cw-LMT3x1Zj.js → rotate-cw-B1UQ8Hld.js} +1 -1
- package/web/dist/assets/{square-dashed-mouse-pointer-CBoAkfhi.js → square-dashed-mouse-pointer-8lrgqmfv.js} +1 -1
- package/web/dist/index.html +17 -17
- package/web/dist/assets/BrowserWindow-Dc7J7CYc.js +0 -11
package/web/README.md
CHANGED
|
@@ -1,89 +1,89 @@
|
|
|
1
|
-
# Nodesign Web — P1 前端骨架
|
|
2
|
-
|
|
3
|
-
Nodesign 工作台前端。三栏布局:chat / canvas / context。
|
|
4
|
-
|
|
5
|
-
## 当前阶段:P1(前端骨架)
|
|
6
|
-
|
|
7
|
-
参考 plan:`/Users/edy/.claude/plans/plan-parallel-harbor.md`
|
|
8
|
-
|
|
9
|
-
## 跑起来
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
cd Nodesign/web
|
|
13
|
-
npm install
|
|
14
|
-
npm run dev # 起在 5174(避开 dev/ 的 5173)
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
打开 `http://localhost:5174/`。
|
|
18
|
-
|
|
19
|
-
## P1 验证清单
|
|
20
|
-
|
|
21
|
-
打开浏览器后逐项确认:
|
|
22
|
-
|
|
23
|
-
1. ✅ Home 页(`/`)显示 5 个 mock 项目 + 两个入口卡片(自由创作 / 参照模式)
|
|
24
|
-
2. ✅ 点项目进入 `/projects/proj-002`("Nodesign 内部介绍")三栏页
|
|
25
|
-
3. ✅ 三栏布局:左 360px chat / 中 auto canvas / 右 340px context panel
|
|
26
|
-
4. ✅ 顶栏:亮黑系 + 项目名 breadcrumb + Share/Export/⋯ 按钮
|
|
27
|
-
5. ✅ Canvas iframe 加载 `/mock/deck.html`(5 页 DeskSkill 风格 self-contained HTML)
|
|
28
|
-
6. ✅ Canvas Toolbar 三模式切换(Edit / Preview / Code)
|
|
29
|
-
7. ✅ **Edit 模式下双击 iframe 内的文字** → 进入 contenteditable,blur 后控制台 log 出 patch
|
|
30
|
-
8. ✅ Preview 模式下不能编辑(双击无效)
|
|
31
|
-
9. ✅ Code 模式下 Monaco 显示 HTML 源码(只读)
|
|
32
|
-
10. ✅ Inputs tab:拖文件 / 点击选文件 / 粘贴 URL(FileReader 本地预览,不发请求)
|
|
33
|
-
11. ✅ SystemTab 显示 mock spec 摘要(metaphor / intent / outline 列表)
|
|
34
|
-
12. ✅ ChatPanel:mock 6 条对话历史,输消息 + 发送(800ms 后伪 mock 回执)
|
|
35
|
-
13. ✅ 视觉跟 dev/ 完全一致(亮黑按钮 / 深棕标题 / cubic-bezier 入退场)
|
|
36
|
-
14. ✅ 路由:Home ↔ Project ↔ DesignSystemList 占位 ↔ SkillList 占位 切换流畅
|
|
37
|
-
|
|
38
|
-
## 目录结构
|
|
39
|
-
|
|
40
|
-
```
|
|
41
|
-
src/
|
|
42
|
-
├── main.jsx # ReactDOM 入口
|
|
43
|
-
├── App.jsx # 路由根(react-router-dom 7 createBrowserRouter)
|
|
44
|
-
├── routes/
|
|
45
|
-
│ ├── Home.jsx
|
|
46
|
-
│ ├── Project.jsx # ★ 三栏组装
|
|
47
|
-
│ ├── DesignSystemList.jsx # 占位
|
|
48
|
-
│ └── SkillList.jsx # 占位
|
|
49
|
-
├── components/
|
|
50
|
-
│ ├── layout/ # AppShell / TopBar / ThreeColumnLayout
|
|
51
|
-
│ ├── chat/ # ChatPanel / MessageList / Message / ChatComposer
|
|
52
|
-
│ ├── canvas/ # CanvasFrame / Toolbar / HtmlIframe / EditOverlay / DirectEditBridge / CodeCanvas
|
|
53
|
-
│ ├── context-panel/ # ContextPanel / InputsTab / SystemTab
|
|
54
|
-
│ └── ui/ # 12+ 从 dev/src/components/ui copy 来的通用组件
|
|
55
|
-
├── lib/
|
|
56
|
-
│ ├── theme.js # ← 从 dev/src/constants/theme.js copy(COLOR / GAP / FONT_SIZE / cubic-bezier)
|
|
57
|
-
│ ├── html-utils.js # serializeAnchor / findElementByAnchor / ensureNodeId
|
|
58
|
-
│ └── helpers.js # newId / formatDate / timeAgo
|
|
59
|
-
├── hooks/ # (P2 加:useEngineRun / useHtmlArtifact / useIframeBridge)
|
|
60
|
-
├── stores/globalStore.js # zustand:toast / canvas mode / selectedAnchor
|
|
61
|
-
├── mock/
|
|
62
|
-
│ ├── deck-spec.js # mock DeckSpec
|
|
63
|
-
│ └── projects.js # mock 5 个项目
|
|
64
|
-
└── styles/globals.css # 极小 reset
|
|
65
|
-
|
|
66
|
-
public/
|
|
67
|
-
└── mock/
|
|
68
|
-
└── deck.html # ★ 5 页 self-contained HTML(DeskSkill 风格)
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
## 设计原则(来自 plan-parallel-harbor)
|
|
72
|
-
|
|
73
|
-
1. **不污染**:v0.7.5 是参考不是约束
|
|
74
|
-
2. **探索 → 反向优化**:Nodesign 反向给 skill 提需求
|
|
75
|
-
3. **spec 与 HTML 角色分离**:
|
|
76
|
-
- spec:agent 生成阶段的 commitment device + 上下文记忆,**用户不直接编辑**
|
|
77
|
-
- HTML:产物 + 用户局部交互的修改对象(comment / direct edit / slider / 未来 CAD 都改 HTML)
|
|
78
|
-
4. **视觉沿用 DeskSkill**:亮黑 #2d2418 / 深棕 #3a2a18 / F9F8F6 / cubic-bezier(0.25, 1, 0.5, 1)
|
|
79
|
-
5. **复用 dev/src**:12+ UI 组件直接搬
|
|
80
|
-
|
|
81
|
-
## 下一阶段:P2 前端交互层
|
|
82
|
-
|
|
83
|
-
- inline comment UI(点元素弹气泡 + 评论列表)
|
|
84
|
-
- inputs tab 上传后真预览(FileReader 显示截图缩略图)
|
|
85
|
-
- Code mode 改 HTML(本地 state,blur 触发 iframe reload)
|
|
86
|
-
- tweak slider UI 占位(mock schema)
|
|
87
|
-
- 项目 CRUD(localStorage 持久化)
|
|
88
|
-
|
|
89
|
-
P3 起接后端 WS。
|
|
1
|
+
# Nodesign Web — P1 前端骨架
|
|
2
|
+
|
|
3
|
+
Nodesign 工作台前端。三栏布局:chat / canvas / context。
|
|
4
|
+
|
|
5
|
+
## 当前阶段:P1(前端骨架)
|
|
6
|
+
|
|
7
|
+
参考 plan:`/Users/edy/.claude/plans/plan-parallel-harbor.md`
|
|
8
|
+
|
|
9
|
+
## 跑起来
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
cd Nodesign/web
|
|
13
|
+
npm install
|
|
14
|
+
npm run dev # 起在 5174(避开 dev/ 的 5173)
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
打开 `http://localhost:5174/`。
|
|
18
|
+
|
|
19
|
+
## P1 验证清单
|
|
20
|
+
|
|
21
|
+
打开浏览器后逐项确认:
|
|
22
|
+
|
|
23
|
+
1. ✅ Home 页(`/`)显示 5 个 mock 项目 + 两个入口卡片(自由创作 / 参照模式)
|
|
24
|
+
2. ✅ 点项目进入 `/projects/proj-002`("Nodesign 内部介绍")三栏页
|
|
25
|
+
3. ✅ 三栏布局:左 360px chat / 中 auto canvas / 右 340px context panel
|
|
26
|
+
4. ✅ 顶栏:亮黑系 + 项目名 breadcrumb + Share/Export/⋯ 按钮
|
|
27
|
+
5. ✅ Canvas iframe 加载 `/mock/deck.html`(5 页 DeskSkill 风格 self-contained HTML)
|
|
28
|
+
6. ✅ Canvas Toolbar 三模式切换(Edit / Preview / Code)
|
|
29
|
+
7. ✅ **Edit 模式下双击 iframe 内的文字** → 进入 contenteditable,blur 后控制台 log 出 patch
|
|
30
|
+
8. ✅ Preview 模式下不能编辑(双击无效)
|
|
31
|
+
9. ✅ Code 模式下 Monaco 显示 HTML 源码(只读)
|
|
32
|
+
10. ✅ Inputs tab:拖文件 / 点击选文件 / 粘贴 URL(FileReader 本地预览,不发请求)
|
|
33
|
+
11. ✅ SystemTab 显示 mock spec 摘要(metaphor / intent / outline 列表)
|
|
34
|
+
12. ✅ ChatPanel:mock 6 条对话历史,输消息 + 发送(800ms 后伪 mock 回执)
|
|
35
|
+
13. ✅ 视觉跟 dev/ 完全一致(亮黑按钮 / 深棕标题 / cubic-bezier 入退场)
|
|
36
|
+
14. ✅ 路由:Home ↔ Project ↔ DesignSystemList 占位 ↔ SkillList 占位 切换流畅
|
|
37
|
+
|
|
38
|
+
## 目录结构
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
src/
|
|
42
|
+
├── main.jsx # ReactDOM 入口
|
|
43
|
+
├── App.jsx # 路由根(react-router-dom 7 createBrowserRouter)
|
|
44
|
+
├── routes/
|
|
45
|
+
│ ├── Home.jsx
|
|
46
|
+
│ ├── Project.jsx # ★ 三栏组装
|
|
47
|
+
│ ├── DesignSystemList.jsx # 占位
|
|
48
|
+
│ └── SkillList.jsx # 占位
|
|
49
|
+
├── components/
|
|
50
|
+
│ ├── layout/ # AppShell / TopBar / ThreeColumnLayout
|
|
51
|
+
│ ├── chat/ # ChatPanel / MessageList / Message / ChatComposer
|
|
52
|
+
│ ├── canvas/ # CanvasFrame / Toolbar / HtmlIframe / EditOverlay / DirectEditBridge / CodeCanvas
|
|
53
|
+
│ ├── context-panel/ # ContextPanel / InputsTab / SystemTab
|
|
54
|
+
│ └── ui/ # 12+ 从 dev/src/components/ui copy 来的通用组件
|
|
55
|
+
├── lib/
|
|
56
|
+
│ ├── theme.js # ← 从 dev/src/constants/theme.js copy(COLOR / GAP / FONT_SIZE / cubic-bezier)
|
|
57
|
+
│ ├── html-utils.js # serializeAnchor / findElementByAnchor / ensureNodeId
|
|
58
|
+
│ └── helpers.js # newId / formatDate / timeAgo
|
|
59
|
+
├── hooks/ # (P2 加:useEngineRun / useHtmlArtifact / useIframeBridge)
|
|
60
|
+
├── stores/globalStore.js # zustand:toast / canvas mode / selectedAnchor
|
|
61
|
+
├── mock/
|
|
62
|
+
│ ├── deck-spec.js # mock DeckSpec
|
|
63
|
+
│ └── projects.js # mock 5 个项目
|
|
64
|
+
└── styles/globals.css # 极小 reset
|
|
65
|
+
|
|
66
|
+
public/
|
|
67
|
+
└── mock/
|
|
68
|
+
└── deck.html # ★ 5 页 self-contained HTML(DeskSkill 风格)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## 设计原则(来自 plan-parallel-harbor)
|
|
72
|
+
|
|
73
|
+
1. **不污染**:v0.7.5 是参考不是约束
|
|
74
|
+
2. **探索 → 反向优化**:Nodesign 反向给 skill 提需求
|
|
75
|
+
3. **spec 与 HTML 角色分离**:
|
|
76
|
+
- spec:agent 生成阶段的 commitment device + 上下文记忆,**用户不直接编辑**
|
|
77
|
+
- HTML:产物 + 用户局部交互的修改对象(comment / direct edit / slider / 未来 CAD 都改 HTML)
|
|
78
|
+
4. **视觉沿用 DeskSkill**:亮黑 #2d2418 / 深棕 #3a2a18 / F9F8F6 / cubic-bezier(0.25, 1, 0.5, 1)
|
|
79
|
+
5. **复用 dev/src**:12+ UI 组件直接搬
|
|
80
|
+
|
|
81
|
+
## 下一阶段:P2 前端交互层
|
|
82
|
+
|
|
83
|
+
- inline comment UI(点元素弹气泡 + 评论列表)
|
|
84
|
+
- inputs tab 上传后真预览(FileReader 显示截图缩略图)
|
|
85
|
+
- Code mode 改 HTML(本地 state,blur 触发 iframe reload)
|
|
86
|
+
- tweak slider UI 占位(mock schema)
|
|
87
|
+
- 项目 CRUD(localStorage 持久化)
|
|
88
|
+
|
|
89
|
+
P3 起接后端 WS。
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import{c as G,r as i,au as L,av as ee,j as t,a0 as te,F as y,b as $,G as u,aw as ne,Z as ie,at as N,C as c,e as j,a2 as I,ax as se,ay as re,a7 as oe}from"./index-BHTBJlpY.js";import{A as ae,R as le}from"./rotate-cw-B1UQ8Hld.js";/**
|
|
2
|
+
* @license lucide-react v0.468.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const U=G("Play",[["polygon",{points:"6 3 20 12 6 21 6 3",key:"1oa8hb"}]]);/**
|
|
7
|
+
* @license lucide-react v0.468.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const ce=G("PowerOff",[["path",{d:"M18.36 6.64A9 9 0 0 1 20.77 15",key:"dxknvb"}],["path",{d:"M6.16 6.16a9 9 0 1 0 12.68 12.68",key:"1x7qb5"}],["path",{d:"M12 2v4",key:"3427ic"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]]);function de(o){try{return decodeURI(o)}catch{return o}}function _(o,x){const h=o.getBoundingClientRect();return{rx:Math.min(1,Math.max(0,(x.clientX-h.left)/h.width)),ry:Math.min(1,Math.max(0,(x.clientY-h.top)/h.height))}}function fe({projectId:o,url:x,help:h,onClose:w,onToolbarGroups:J}){const[v,d]=i.useState("connecting"),[A,g]=i.useState(null),[b,O]=i.useState(x||""),[a,M]=i.useState(!1),[H,X]=i.useState(!1),[T,B]=i.useState(null),[k,D]=i.useState(!1),[C,K]=i.useState([]),[F,V]=i.useState(null),[E,Y]=i.useState(!0),R=i.useRef(null),z=i.useRef(null),Z=i.useRef(!1);Z.current=a;const l=i.useCallback(e=>{const n=z.current;n&&n.readyState===1&&n.send(JSON.stringify(e))},[]),q=i.useCallback(async()=>{D(!0),g(null);try{const e=await L.open(o);O(e.url||""),d("connecting"),l({type:"subscribe"})}catch(e){d("error"),g((e==null?void 0:e.message)||"打不开")}finally{D(!1)}},[o,l]);i.useEffect(()=>{const e=window.location.protocol==="https:"?"wss:":"ws:",n=new WebSocket(`${e}//${window.location.host}/ws/projects/${encodeURIComponent(o)}/browser`);n.binaryType="arraybuffer",z.current=n,n.onopen=()=>{d("connecting"),n.send(JSON.stringify({type:"subscribe"}))},n.onclose=p=>{d(p.code===4401?"error":"closed"),p.code===4401&&g("没有权限")},n.onerror=()=>d("error"),n.onmessage=async p=>{var r,W;if(typeof p.data!="string"){const m=R.current;if(!m)return;try{const f=await createImageBitmap(new Blob([p.data],{type:"image/jpeg"}));(m.width!==f.width||m.height!==f.height)&&(m.width=f.width,m.height=f.height),(r=m.getContext("2d"))==null||r.drawImage(f,0,0),(W=f.close)==null||W.call(f),X(!0),d("live")}catch{}return}let s;try{s=JSON.parse(p.data)}catch{return}s.type==="subscribed"&&(d("live"),s.url&&O(s.url)),s.type==="hello"&&s.help&&B(s.help),s.type==="released"&&B(null),s.type==="idle"&&(d("idle"),g(s.reason)),s.type==="error"&&(d("error"),g(s.reason)),s.type==="closed"&&(d("closed"),g(s.reason)),s.type==="url"&&O(s.url||"")};const S=()=>l({type:document.hidden?"unsubscribe":"subscribe"});return document.addEventListener("visibilitychange",S),()=>{document.removeEventListener("visibilitychange",S);try{n.send(JSON.stringify({type:"unsubscribe"}))}catch{}n.close(),z.current=null}},[o,l]),i.useEffect(()=>{x&&O(x)},[x]),i.useEffect(()=>{let e=!0;return L.state(o).then(n=>{e&&K(Array.isArray(n==null?void 0:n.sites)?n.sites:[])}).catch(()=>{}),()=>{e=!1}},[o]),i.useEffect(()=>{var s;if(!a)return;const e=R.current;if(!e)return;const n=r=>{r.preventDefault(),l({type:"input",kind:"click",..._(e,r)})},S=r=>{r.preventDefault(),l({type:"input",kind:"wheel",..._(e,r),dx:r.deltaX,dy:r.deltaY})},p=r=>{if(!r.isComposing){if(r.key.length===1){r.preventDefault(),l({type:"input",kind:"key",text:r.key});return}["Enter","Backspace","Tab","Escape","ArrowUp","ArrowDown","ArrowLeft","ArrowRight"].includes(r.key)&&(r.preventDefault(),l({type:"input",kind:"key",key:r.key}))}};return e.addEventListener("click",n),e.addEventListener("wheel",S,{passive:!1}),e.addEventListener("keydown",p),(s=e.focus)==null||s.call(e),()=>{e.removeEventListener("click",n),e.removeEventListener("wheel",S),e.removeEventListener("keydown",p)}},[a,l]);const Q=i.useMemo(()=>[{id:"addr",node:t.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:6,padding:`0 ${u.sm}px`,maxWidth:420,fontFamily:$,fontSize:y.xs,color:te.text,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis",userSelect:"text"},title:b||"",children:[t.jsx(ne,{size:12,style:{flexShrink:0,opacity:.6}}),b?de(b):"(还没打开页面)"]})},{id:"nav",items:[{id:"back",icon:ae,title:"后退",onClick:()=>l({type:"nav",action:"back"})},{id:"reload",icon:le,title:"刷新",onClick:()=>l({type:"nav",action:"reload"})}]},{id:"end",items:[{id:"end",icon:ce,title:"不逛了 —— 关掉浏览器并把桌面上那张卡收走(在站点上的登录留着)",onClick:async()=>{try{await L.end(o)}catch{}w==null||w()}}]},{id:"takeover",items:[{id:"hand",icon:a?U:ee,title:a?"好了继续 —— 把控制权交回 agent(它正等着)":"我来接手 —— 点击/滚动/打字会直接发到那个浏览器里",active:a,onClick:()=>{a?(l({type:"release"}),M(!1)):M(!0)}}]}],[b,a,l,o,w]),P={connecting:"连接中…",live:null,idle:A||"agent 还没开始浏览",error:A||"出错了",closed:A||"浏览器已经关了"}[v];return t.jsxs(ie,{kind:"browse",title:"agent 的浏览器",subtitle:a?"你在接手":v==="live"?"实时":null,onClose:w,groups:Q,onToolbarGroups:J,banner:h||T?t.jsxs("span",{children:[t.jsx("b",{children:"agent 需要你帮个手"}),":",h||T,"—— 点工具栏上的",t.jsx("b",{children:"手形按钮"}),"接手,弄完再点一次(变成 ▶)把控制权交回去。 它正停在那儿等你。"]}):null,contentStyle:{background:N.paper},children:[t.jsxs("div",{style:{flex:1,minHeight:0,width:"100%",display:"flex",alignItems:"center",justifyContent:"center",padding:u.md,boxSizing:"border-box",position:"relative"},children:[t.jsx("canvas",{ref:R,tabIndex:a?0:-1,title:a?"接手中:点一下这块画面再打字(键盘只在这里生效)":void 0,style:{maxWidth:"100%",maxHeight:"100%",display:H?"block":"none",background:"#fff",borderRadius:2,boxShadow:"0 2px 12px rgba(43,39,35,.18)",cursor:a?"pointer":"default",outline:a?`2px solid ${c.accent||"#8a4b2d"}`:"none",outlineOffset:3}}),(!H||P)&&t.jsxs("div",{style:{position:"absolute",inset:0,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:u.sm,fontFamily:j,fontSize:y.sm,color:c.text2,textAlign:"center"},children:[v==="connecting"&&t.jsx(I,{size:16,style:{animation:"spin 1s linear infinite"}}),t.jsx("span",{children:P||"等第一帧…"}),(v==="idle"||v==="closed")&&t.jsxs(t.Fragment,{children:[b&&t.jsxs("button",{type:"button",disabled:k,onClick:q,style:{display:"inline-flex",alignItems:"center",gap:6,padding:`${u.xs}px ${u.md}px`,cursor:k?"default":"pointer",fontFamily:j,fontSize:y.sm,color:c.text,background:N.paper,border:`1px solid ${c.border}`,borderRadius:3,opacity:k?.6:1},children:[k?t.jsx(I,{size:13,style:{animation:"spin 1s linear infinite"}}):t.jsx(U,{size:13}),k?"正在打开…":"打开上次那一页"]}),t.jsxs("span",{style:{color:c.sub,fontSize:y.xs,maxWidth:360,lineHeight:1.7},children:[b?"浏览器空闲 5 分钟会自己休息(登录态留着)。打开之后你可以直接接手操作,agent 下次也接着用这一页。":"让 agent 去看一个站(它有 browser_navigate),这里就会亮起来。",t.jsx("br",{}),"静止的页面不会一直传帧 —— 画面不动是正常的,不是卡住了。"]})]})]})]}),!!C.length&&t.jsxs("div",{style:{flexShrink:0,borderTop:`1px solid ${c.border}`,background:c.bgCard,maxHeight:E?220:30,overflow:"hidden",transition:"max-height .18s ease"},children:[t.jsxs("button",{type:"button",onClick:()=>Y(e=>!e),style:{display:"flex",alignItems:"center",gap:6,width:"100%",padding:`4px ${u.md}px`,cursor:"pointer",background:"transparent",border:0,color:c.text2,fontFamily:j,fontSize:y.xs},children:[t.jsx(se,{size:12}),"采到的东西 · ",C.length," 个站 · ",C.reduce((e,n)=>e+n.count,0)," 件",t.jsx(re,{size:12,style:{marginLeft:"auto",opacity:.6,transform:E?"none":"rotate(-90deg)",transition:"transform .18s ease"}})]}),E&&t.jsx("div",{style:{display:"flex",gap:u.sm,padding:`0 ${u.md}px ${u.sm}px`,overflowX:"auto"},children:C.map(e=>t.jsxs("div",{style:{flexShrink:0,width:150},children:[t.jsxs("button",{type:"button",title:`${e.dir}(${e.count} 件)`,onClick:()=>V(F===e.site?null:e.site),style:{display:"block",width:"100%",padding:0,cursor:"pointer",background:N.paper,border:`1px solid ${F===e.site?c.text:c.border}`,borderRadius:2,overflow:"hidden"},children:[e.cover?t.jsx("img",{alt:"",loading:"lazy",src:oe.artifactFileUrl(o,e.cover),style:{width:"100%",height:84,objectFit:"cover",objectPosition:"top center",display:"block"}}):t.jsx("div",{style:{height:84,display:"flex",alignItems:"center",justifyContent:"center",color:c.sub,fontFamily:j,fontSize:y.xxs},children:"没有截图"}),t.jsx("div",{style:{padding:"3px 5px",textAlign:"left",fontFamily:$,fontSize:y.xxs,color:c.text2,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},children:e.site})]}),F===e.site&&t.jsxs("div",{style:{paddingTop:3,fontFamily:j,fontSize:y.xxs,color:c.sub,lineHeight:1.6},children:[t.jsxs("span",{style:{fontFamily:$},children:[e.dir,"/"]}),t.jsx("br",{}),e.count," 件(截图 / 调色板 / 字体 / 结构 / CSS,类别在文件名里)"]})]},e.site))})]})]})}export{fe as default};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as et,r as o,j as e,C as r,G as t,a as Ht,R as $,F as p,b as E,P as tt,u as N,X as ue,d as nt,e as z,f as st,T as Dt,g as _t,h as ke,B as It,i as rt,k as ze,U as Nt,l as it,S as qt,H as Ut,m as Gt,n as lt,o as Kt,p as Vt,q as Xt,s as ot,t as at,v as dt,w as Yt,x as Zt,y as ct,z as Ct,A as Jt,E as ut,D as Qt,I as en,J as Ke,K as tn,M as nn,L as sn,N as rn,O as ln,Q as on,V as an,W as dn,Y as cn,Z as un}from"./index-
|
|
1
|
+
import{c as et,r as o,j as e,C as r,G as t,a as Ht,R as $,F as p,b as E,P as tt,u as N,X as ue,d as nt,e as z,f as st,T as Dt,g as _t,h as ke,B as It,i as rt,k as ze,U as Nt,l as it,S as qt,H as Ut,m as Gt,n as lt,o as Kt,p as Vt,q as Xt,s as ot,t as at,v as dt,w as Yt,x as Zt,y as ct,z as Ct,A as Jt,E as ut,D as Qt,I as en,J as Ke,K as tn,M as nn,L as sn,N as rn,O as ln,Q as on,V as an,W as dn,Y as cn,Z as un}from"./index-BHTBJlpY.js";import{d as Ve,a as Xe,M as xn,o as pn,t as gn,E as fn,C as hn,G as mn,p as yn,D as bn,b as wn,c as vn,P as kn,I as jn,R as Sn,e as zn}from"./pending-edit-apply-C0I13CbD.js";import{E as $n,S as En}from"./square-dashed-mouse-pointer-8lrgqmfv.js";/**
|
|
2
2
|
* @license lucide-react v0.468.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as K,r as n,j as e,R as N,C as c,G as g,k as Q,F as k,e as W,a2 as tt,A as ct,X as dt,b as q,aq as ut,a7 as _,Q as ht,a0 as G,ar as pt,a3 as Z,x as ft,as as xt,s as gt,Y as yt,Z as bt,at as vt}from"./index-
|
|
1
|
+
import{c as K,r as n,j as e,R as N,C as c,G as g,k as Q,F as k,e as W,a2 as tt,A as ct,X as dt,b as q,aq as ut,a7 as _,Q as ht,a0 as G,ar as pt,a3 as Z,x as ft,as as xt,s as gt,Y as yt,Z as bt,at as vt}from"./index-BHTBJlpY.js";import{S as wt,E as kt}from"./square-dashed-mouse-pointer-8lrgqmfv.js";/**
|
|
2
2
|
* @license lucide-react v0.468.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as De,j as c,_ as Et,v as we,u as Rt,r,$ as Oe,a0 as Ie,a1 as Tt,a2 as $t,a3 as I,a4 as Je,G as T,R as se,b as Ot,a5 as et,a6 as Dt,d as At,a7 as ae,a8 as tt,a9 as jt,aa as Pt,ab as be,ac as Mt,ad as Xe,ae as Ze,af as Ft,M as Nt,ag as zt,ah as Ye,Y as Lt,Z as Wt,ai as Bt,C as B,F as ye,e as ve,k as Ut}from"./index-
|
|
1
|
+
import{c as De,j as c,_ as Et,v as we,u as Rt,r,$ as Oe,a0 as Ie,a1 as Tt,a2 as $t,a3 as I,a4 as Je,G as T,R as se,b as Ot,a5 as et,a6 as Dt,d as At,a7 as ae,a8 as tt,a9 as jt,aa as Pt,ab as be,ac as Mt,ad as Xe,ae as Ze,af as Ft,M as Nt,ag as zt,ah as Ye,Y as Lt,Z as Wt,ai as Bt,C as B,F as ye,e as ve,k as Ut}from"./index-BHTBJlpY.js";import{c as _t,b as Ht,a as Gt,d as Kt,E as Vt,C as qt,I as It,G as Jt,p as Xt,D as Zt,P as Yt,R as Qt,e as er}from"./pending-edit-apply-C0I13CbD.js";import{E as tr,S as rr}from"./square-dashed-mouse-pointer-8lrgqmfv.js";import{A as nr,R as sr}from"./rotate-cw-B1UQ8Hld.js";/**
|
|
2
2
|
* @license lucide-react v0.468.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|