@bovinphang/frontend-craft 2.5.0
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/.claude-plugin/marketplace.json +61 -0
- package/.claude-plugin/plugin.json +32 -0
- package/.mcp.json +44 -0
- package/CHANGELOG.md +229 -0
- package/CHANGELOG.zh-CN.md +228 -0
- package/CODE_OF_CONDUCT.md +34 -0
- package/CODE_OF_CONDUCT.zh-CN.md +34 -0
- package/CONTRIBUTING.md +356 -0
- package/CONTRIBUTING.zh-CN.md +356 -0
- package/LICENSE +21 -0
- package/README.md +467 -0
- package/README.openclaw.md +262 -0
- package/README.openclaw.zh-CN.md +262 -0
- package/README.zh-CN.md +467 -0
- package/SECURITY.md +44 -0
- package/SECURITY.zh-CN.md +44 -0
- package/agents/fec-architect.md +125 -0
- package/agents/fec-code-reviewer.md +152 -0
- package/agents/fec-debugger.md +44 -0
- package/agents/fec-design-token-mapper.md +75 -0
- package/agents/fec-doc-updater.md +30 -0
- package/agents/fec-e2e-runner.md +107 -0
- package/agents/fec-figma-implementer.md +104 -0
- package/agents/fec-performance-optimizer.md +293 -0
- package/agents/fec-refactor-cleaner.md +32 -0
- package/agents/fec-security-reviewer.md +116 -0
- package/agents/fec-test-planner.md +50 -0
- package/agents/fec-typescript-reviewer.md +142 -0
- package/agents/fec-ui-checker.md +120 -0
- package/commands/fec-debug.md +30 -0
- package/commands/fec-doc-sync.md +18 -0
- package/commands/fec-init.md +70 -0
- package/commands/fec-plan.md +94 -0
- package/commands/fec-refactor-clean.md +19 -0
- package/commands/fec-review.md +66 -0
- package/commands/fec-scaffold.md +205 -0
- package/commands/fec-tdd.md +21 -0
- package/dist/bin/frontend-craft.js +82 -0
- package/dist/hooks/fec-cleanup-claude-cache.js +4 -0
- package/dist/hooks/fec-format-changed-file.js +1 -0
- package/dist/hooks/fec-notify.js +1 -0
- package/dist/hooks/fec-run-tests.js +1 -0
- package/dist/hooks/fec-security-check.js +2 -0
- package/dist/hooks/fec-session-start.js +1 -0
- package/docs/example-prompts.md +124 -0
- package/docs/ja-JP/README.md +467 -0
- package/docs/ko-KR/README.md +467 -0
- package/docs/project-structure.md +119 -0
- package/docs/runtimes/antigravity.md +10 -0
- package/docs/runtimes/augment.md +10 -0
- package/docs/runtimes/claude.md +171 -0
- package/docs/runtimes/claude.zh-CN.md +169 -0
- package/docs/runtimes/cline.md +10 -0
- package/docs/runtimes/codebuddy.md +10 -0
- package/docs/runtimes/codex.md +10 -0
- package/docs/runtimes/copilot.md +10 -0
- package/docs/runtimes/cursor.md +10 -0
- package/docs/runtimes/gemini.md +10 -0
- package/docs/runtimes/kilo.md +10 -0
- package/docs/runtimes/openclaw.md +10 -0
- package/docs/runtimes/opencode.md +10 -0
- package/docs/runtimes/qoder.md +19 -0
- package/docs/runtimes/trae.md +10 -0
- package/docs/runtimes/windsurf.md +10 -0
- package/docs/superpowers/plans/2026-05-29-fec-debug.md +491 -0
- package/docs/superpowers/specs/2026-05-29-fec-debug-design.md +340 -0
- package/docs/zh-CN/example-prompts.md +124 -0
- package/docs/zh-CN/project-structure.md +119 -0
- package/docs/zh-TW/README.md +467 -0
- package/hooks/hooks.json +71 -0
- package/openclaw.plugin.json +26 -0
- package/package.json +101 -0
- package/skills/TEMPLATE.md +155 -0
- package/skills/eval_queries.json +890 -0
- package/skills/fec-accessibility-check/SKILL.md +39 -0
- package/skills/fec-accessibility-check/references/report-template.md +23 -0
- package/skills/fec-accessibility-check/references/screen-reader-testing.md +33 -0
- package/skills/fec-api-integration/SKILL.md +78 -0
- package/skills/fec-api-integration/references/integration-patterns.md +80 -0
- package/skills/fec-browser-storage/SKILL.md +34 -0
- package/skills/fec-browser-storage/references/storage-patterns.md +65 -0
- package/skills/fec-canvas-threejs/SKILL.md +66 -0
- package/skills/fec-canvas-threejs/references/rendering-patterns.md +67 -0
- package/skills/fec-canvas-threejs/references/shader-webgl-patterns.md +67 -0
- package/skills/fec-code-review/SKILL.md +135 -0
- package/skills/fec-code-review/references/report-template.md +29 -0
- package/skills/fec-component-testing/SKILL.md +119 -0
- package/skills/fec-data-fetching/SKILL.md +62 -0
- package/skills/fec-data-fetching/references/query-patterns.md +77 -0
- package/skills/fec-debug-framework/SKILL.md +162 -0
- package/skills/fec-dependency-upgrade/SKILL.md +34 -0
- package/skills/fec-dependency-upgrade/references/dependency-upgrade-workflow.md +56 -0
- package/skills/fec-doc-sync/SKILL.md +37 -0
- package/skills/fec-e2e-testing/SKILL.md +40 -0
- package/skills/fec-e2e-testing/references/e2e-advanced.md +176 -0
- package/skills/fec-e2e-testing/references/playwright-patterns.md +95 -0
- package/skills/fec-form-handling/SKILL.md +76 -0
- package/skills/fec-form-handling/references/advanced-form-patterns.md +72 -0
- package/skills/fec-implement-from-design/SKILL.md +122 -0
- package/skills/fec-implement-from-design/references/design-plan-template.md +36 -0
- package/skills/fec-legacy-to-modern-migration/SKILL.md +180 -0
- package/skills/fec-legacy-to-modern-migration/references/migration-report-template.md +41 -0
- package/skills/fec-legacy-web-standard/SKILL.md +35 -0
- package/skills/fec-legacy-web-standard/references/legacy-patterns.md +85 -0
- package/skills/fec-list-virtualization/SKILL.md +34 -0
- package/skills/fec-list-virtualization/references/virtualization-patterns.md +52 -0
- package/skills/fec-monorepo-project-standard/SKILL.md +142 -0
- package/skills/fec-motion-interaction/SKILL.md +66 -0
- package/skills/fec-motion-interaction/references/motion-patterns.md +112 -0
- package/skills/fec-nextjs-project-standard/SKILL.md +117 -0
- package/skills/fec-nuxt-project-standard/SKILL.md +122 -0
- package/skills/fec-performance-optimization/SKILL.md +72 -0
- package/skills/fec-pwa-implementation/SKILL.md +36 -0
- package/skills/fec-pwa-implementation/references/manifest-and-icons.md +53 -0
- package/skills/fec-pwa-implementation/references/service-worker-workbox.md +68 -0
- package/skills/fec-react-project-standard/SKILL.md +83 -0
- package/skills/fec-react-project-standard/references/react-project-details.md +642 -0
- package/skills/fec-refactor-clean/SKILL.md +48 -0
- package/skills/fec-responsive-layout/SKILL.md +34 -0
- package/skills/fec-responsive-layout/references/responsive-layout-patterns.md +59 -0
- package/skills/fec-route-protection/SKILL.md +135 -0
- package/skills/fec-security-review/SKILL.md +38 -0
- package/skills/fec-security-review/references/report-template.md +27 -0
- package/skills/fec-security-review/references/security-checklist.md +64 -0
- package/skills/fec-source-driven-development/SKILL.md +61 -0
- package/skills/fec-state-management/SKILL.md +140 -0
- package/skills/fec-state-management/references/state-patterns.md +109 -0
- package/skills/fec-storybook-component-doc/SKILL.md +37 -0
- package/skills/fec-storybook-component-doc/references/story-patterns.md +118 -0
- package/skills/fec-svg-animation/SKILL.md +148 -0
- package/skills/fec-tailwind-design-system/SKILL.md +34 -0
- package/skills/fec-tailwind-design-system/references/tailwind-system-patterns.md +55 -0
- package/skills/fec-tdd-workflow/SKILL.md +52 -0
- package/skills/fec-testing-strategy/SKILL.md +45 -0
- package/skills/fec-typescript-type-safety/SKILL.md +157 -0
- package/skills/fec-typescript-type-safety/references/type-safety-patterns.md +102 -0
- package/skills/fec-ui-design/SKILL.md +90 -0
- package/skills/fec-ui-design/data/product-rules.json +110 -0
- package/skills/fec-ui-design/data/stack-ui-rules.json +14 -0
- package/skills/fec-ui-design/data/style-archetypes.json +74 -0
- package/skills/fec-ui-design/data/ux-quality-rules.json +56 -0
- package/skills/fec-ui-design/references/design-intelligence.md +37 -0
- package/skills/fec-ui-design/references/master-page-overrides.md +30 -0
- package/skills/fec-ui-design/references/pre-delivery-checklist.md +33 -0
- package/skills/fec-ui-design/scripts/design-system.mjs +530 -0
- package/skills/fec-validation-fix/SKILL.md +48 -0
- package/skills/fec-vite-project-standard/SKILL.md +83 -0
- package/skills/fec-vue3-project-standard/SKILL.md +49 -0
- package/skills/fec-vue3-project-standard/references/vue3-project-details.md +547 -0
- package/skills/fec-web-workers/SKILL.md +36 -0
- package/skills/fec-web-workers/references/advanced-workers.md +54 -0
- package/skills/fec-web-workers/references/basic-worker.md +67 -0
- package/skills/metadata.json +1422 -0
- package/skills/relations.json +644 -0
- package/templates/claude/CLAUDE.md +106 -0
- package/templates/claude/settings.json +62 -0
- package/templates/codex/AGENTS.md +105 -0
- package/templates/codex/config.toml +32 -0
- package/templates/openclaw/AGENTS.md +101 -0
- package/templates/openclaw/OPENCLAW-CONFIG.md +12 -0
- package/templates/shared/rules/fec-agent-workflow.md +54 -0
- package/templates/shared/rules/fec-api-layer.md +99 -0
- package/templates/shared/rules/fec-ci-cd.md +128 -0
- package/templates/shared/rules/fec-code-comments.md +33 -0
- package/templates/shared/rules/fec-design-system.md +248 -0
- package/templates/shared/rules/fec-error-handling.md +200 -0
- package/templates/shared/rules/fec-git-conventions.md +73 -0
- package/templates/shared/rules/fec-i18n.md +112 -0
- package/templates/shared/rules/fec-naming-conventions.md +120 -0
- package/templates/shared/rules/fec-performance.md +101 -0
- package/templates/shared/rules/fec-react.md +82 -0
- package/templates/shared/rules/fec-refactoring.md +43 -0
- package/templates/shared/rules/fec-rendering-patterns.md +183 -0
- package/templates/shared/rules/fec-responsive-design.md +227 -0
- package/templates/shared/rules/fec-source-driven-development.md +31 -0
- package/templates/shared/rules/fec-state-management.md +163 -0
- package/templates/shared/rules/fec-testing.md +98 -0
- package/templates/shared/rules/fec-typescript.md +355 -0
- package/templates/shared/rules/fec-vue.md +64 -0
- package/templates/shared/rules/fec-working-modes.md +50 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fec-accessibility-check
|
|
3
|
+
description: Use when reviewing or improving frontend accessibility, semantic structure, keyboard support, focus management, ARIA labels, screen reader behavior, WCAG 2.2 issues, touch accessibility, or assistive-technology regressions; Chinese triggers include 无障碍, accessibility, a11y, WCAG, 屏幕阅读器.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 无障碍实现规范(WCAG 2.2 AA)
|
|
7
|
+
|
|
8
|
+
## Purpose
|
|
9
|
+
|
|
10
|
+
确保前端 UI 对残障用户可访问,满足 WCAG 2.2 AA 的核心要求,并能被键盘、屏幕阅读器、触控和缩放用户稳定使用。
|
|
11
|
+
|
|
12
|
+
## Procedure
|
|
13
|
+
|
|
14
|
+
1. 检查语义结构:landmark、标题层级、表单 label、按钮/链接可访问名称、表格语义和图片 alt。
|
|
15
|
+
2. 检查键盘路径:Tab 顺序、Enter/Space/Esc 行为、焦点可见、关闭后焦点恢复。
|
|
16
|
+
3. 检查复杂组件:对话框、菜单、标签页、树、抽屉、表格和自定义控件的 ARIA 状态。
|
|
17
|
+
4. 检查动态状态:loading、empty、error、toast 和异步更新需要被屏幕阅读器感知。
|
|
18
|
+
5. 检查视觉与触控可读性:文本/背景对比、focus ring、缩放到 200%、减少动效偏好、触摸目标尺寸和移动端虚拟键盘行为。
|
|
19
|
+
6. 用真实键盘路径复核关键流程,必要时补充屏幕阅读器或浏览器无障碍树观察;屏幕阅读器流程见 [references/screen-reader-testing.md](references/screen-reader-testing.md)。
|
|
20
|
+
7. 复核 WCAG 2.2 新增高频风险:可见焦点不被遮挡、拖拽操作有替代路径、目标尺寸过小、帮助入口和认证流程不依赖记忆负担。
|
|
21
|
+
8. 输出分级报告;报告格式见 [references/report-template.md](references/report-template.md)。
|
|
22
|
+
|
|
23
|
+
## Detailed References
|
|
24
|
+
|
|
25
|
+
撰写无障碍审查报告时,加载 [references/report-template.md](references/report-template.md)。需要验证屏幕阅读器公告、焦点读法和动态区域时,加载 [references/screen-reader-testing.md](references/screen-reader-testing.md)。
|
|
26
|
+
|
|
27
|
+
## Constraints
|
|
28
|
+
|
|
29
|
+
- 优先使用语义化 HTML,而不是 ARIA。
|
|
30
|
+
- `role` 不应覆盖原生语义。
|
|
31
|
+
- 交互元素必须可键盘访问。
|
|
32
|
+
- 表单错误必须与字段关联。
|
|
33
|
+
- 颜色对比度风险需要指出具体文本/背景组合。
|
|
34
|
+
- 不用 ARIA 弥补可以用原生 HTML 解决的问题。
|
|
35
|
+
- 不把浏览器自动可访问树当作最终结论;关键路径需要用键盘和至少一种辅助技术或等价检查验证。
|
|
36
|
+
|
|
37
|
+
## Expected Output
|
|
38
|
+
|
|
39
|
+
交互元素可键盘访问,语义和 ARIA 使用正确,焦点管理稳定;无障碍检查报告保存为 `reports/accessibility-review-YYYY-MM-DD-HHmmss.md`。
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# 无障碍检查报告模板
|
|
2
|
+
|
|
3
|
+
```markdown
|
|
4
|
+
# 无障碍检查报告
|
|
5
|
+
|
|
6
|
+
> 生成时间: YYYY-MM-DD HH:mm
|
|
7
|
+
> 评审工具: frontend-craft
|
|
8
|
+
> 标准: WCAG 2.2 AA
|
|
9
|
+
|
|
10
|
+
## 必须修复 (N项)
|
|
11
|
+
- **[文件:行号]** 问题描述 -> 建议修改
|
|
12
|
+
|
|
13
|
+
## 建议改进 (N项)
|
|
14
|
+
- **[文件:行号]** 问题描述 -> 建议修改
|
|
15
|
+
|
|
16
|
+
## 已通过项
|
|
17
|
+
- ...
|
|
18
|
+
|
|
19
|
+
## 建议的代码修改
|
|
20
|
+
- ...
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
检查完成后,将报告保存到 `reports/accessibility-review-YYYY-MM-DD-HHmmss.md`,并告知用户报告路径。
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# 屏幕阅读器测试
|
|
2
|
+
|
|
3
|
+
## 何时测试
|
|
4
|
+
|
|
5
|
+
以下场景需要使用屏幕阅读器或浏览器无障碍树进行检查:
|
|
6
|
+
|
|
7
|
+
- 对话框、抽屉、菜单、标签页、组合框、树形控件和自定义控件。
|
|
8
|
+
- 异步状态更新、toast 通知、校验错误和 loading 区域。
|
|
9
|
+
- 表格、虚拟列表、图表、dashboard 和数据密集型控件。
|
|
10
|
+
- 触摸探索、虚拟键盘或焦点顺序可能与桌面不同的移动端流程。
|
|
11
|
+
|
|
12
|
+
## 最小流程
|
|
13
|
+
|
|
14
|
+
1. 先只用键盘操作:Tab、Shift+Tab、Enter、Space、Esc,以及适用场景下的方向键。
|
|
15
|
+
2. 在浏览器开发者工具中检查可访问名称、角色、状态和元素关系。
|
|
16
|
+
3. 条件允许时至少跑一轮辅助技术验证:NVDA/Firefox、JAWS/Chrome、VoiceOver/Safari 或 TalkBack/Chrome。
|
|
17
|
+
4. 验证路由变化、校验错误、加载完成和破坏性确认是否有正确公告。
|
|
18
|
+
5. 记录具体用户影响、期望读法、实际读法和建议修复方式。
|
|
19
|
+
|
|
20
|
+
## 动态内容
|
|
21
|
+
|
|
22
|
+
- 非阻塞状态更新使用 `aria-live="polite"`。
|
|
23
|
+
- 紧急错误可谨慎使用 `role="alert"`,不要滥用。
|
|
24
|
+
- 只有当用户任务上下文发生变化时才移动焦点,例如打开弹窗或提交后跳转。
|
|
25
|
+
- 关闭浮层后,将焦点恢复到触发控件。
|
|
26
|
+
|
|
27
|
+
## 常见问题
|
|
28
|
+
|
|
29
|
+
- 纯图标按钮没有可访问名称。
|
|
30
|
+
- 对话框内容先于标题被朗读,或缺少模态边界。
|
|
31
|
+
- 表单错误只在视觉上展示,没有用 `aria-describedby` 与字段关联。
|
|
32
|
+
- Toast 消失太快,屏幕阅读器用户来不及理解。
|
|
33
|
+
- 虚拟列表行丢失行位置、表格语义或键盘连续性。
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fec-api-integration
|
|
3
|
+
description: Use when designing, implementing, or reviewing frontend-to-backend API integration, typed API clients, REST/tRPC/OpenAPI client choices, auth refresh, API error mapping, upload flows, SSE/WebSocket/polling choices, CORS-facing frontend behavior, or cross-boundary loading/error states. Do not use for backend-only service architecture or TanStack Query cache policy alone; Chinese triggers include API 集成, 前后端联调, typed API client, 接口错误处理, SSE, WebSocket.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# API 集成
|
|
7
|
+
|
|
8
|
+
适用于前端与后端边界的类型、错误、鉴权、上传、实时通信和用户状态设计。需要具体代码模式时加载 [integration-patterns.md](references/integration-patterns.md)。
|
|
9
|
+
|
|
10
|
+
## Purpose
|
|
11
|
+
|
|
12
|
+
规范前端 API 集成边界,让请求、错误、鉴权和实时数据可维护。
|
|
13
|
+
|
|
14
|
+
## Procedure
|
|
15
|
+
|
|
16
|
+
1. 明确接口所有权
|
|
17
|
+
- 同团队 TypeScript 全栈可考虑 tRPC 或共享 schema。
|
|
18
|
+
- 多语言或多消费者 API 优先 OpenAPI/GraphQL codegen。
|
|
19
|
+
- 小型内部应用可用 typed fetch wrapper,但类型必须集中维护。
|
|
20
|
+
- 不在组件里散落 `fetch`、URL、header、错误解析和 token 逻辑。
|
|
21
|
+
- 公共接口需要明确版本、兼容窗口、废弃字段策略和调用方范围。
|
|
22
|
+
|
|
23
|
+
2. 建立客户端边界
|
|
24
|
+
- 用一个 API client 处理 base URL、credentials、JSON 解析、超时、取消和统一错误。
|
|
25
|
+
- 环境变量只读取公开前缀,私密 token 不进入客户端 bundle。
|
|
26
|
+
- 组件只消费 domain 函数或 query/mutation hook,不直接拼接接口路径。
|
|
27
|
+
- 204、空响应、非 JSON 错误和网络断开要有明确行为。
|
|
28
|
+
- TypeScript contract 必须覆盖请求、响应、错误形状和分页/游标元数据。
|
|
29
|
+
|
|
30
|
+
3. 映射用户可理解的错误
|
|
31
|
+
- 401:刷新失败后引导登录。
|
|
32
|
+
- 403:说明权限不足,不重复重试。
|
|
33
|
+
- 404:展示缺失状态或返回上级入口。
|
|
34
|
+
- 409:提示冲突和下一步操作。
|
|
35
|
+
- 422:映射字段级错误。
|
|
36
|
+
- 429/5xx/网络错误:允许退避重试或展示稍后再试。
|
|
37
|
+
- 未识别错误要落到统一 fallback,不把原始后端异常暴露给用户。
|
|
38
|
+
- 所有错误都应归一到用户可恢复动作:重试、重新登录、修改输入、返回上级、联系支持或稍后再试。
|
|
39
|
+
- 错误对象要保留面向日志的 trace id / request id,但 UI 不暴露内部堆栈、SQL、服务名或敏感字段。
|
|
40
|
+
|
|
41
|
+
4. 管理接口演进
|
|
42
|
+
- 兼容新增字段;删除或改名字段必须走迁移期、适配层或双写/双读策略。
|
|
43
|
+
- 用 schema、类型生成物或 contract test 捕捉破坏性变更。
|
|
44
|
+
- 对前后端协作项记录状态码、错误码、幂等性、重试语义和时区/金额/枚举规则。
|
|
45
|
+
|
|
46
|
+
5. 处理鉴权刷新
|
|
47
|
+
- Access token 生命周期短,refresh 优先放在 httpOnly cookie 或服务端会话。
|
|
48
|
+
- 401 后只允许单次刷新队列,避免多个请求同时刷新。
|
|
49
|
+
- 刷新失败要清理本地身份状态并跳转登录。
|
|
50
|
+
- 不把 bearer token 放在 URL、localStorage 或日志里。
|
|
51
|
+
|
|
52
|
+
6. 选择上传与实时方案
|
|
53
|
+
- 小文件可用 multipart;大文件优先预签名直传或分片上传。
|
|
54
|
+
- 只需要服务端推送时用 SSE;双向协作、聊天或多人状态用 WebSocket。
|
|
55
|
+
- 简单状态刷新、低频任务进度可用 polling,并设置停止条件。
|
|
56
|
+
- 上传和实时连接都需要取消、重连、超时和错误 UI。
|
|
57
|
+
|
|
58
|
+
7. 验证集成质量
|
|
59
|
+
- 检查 loading、empty、error、unauthorized、offline、retrying 状态。
|
|
60
|
+
- 用浏览器网络面板确认 base URL、credentials、CORS 和状态码行为。
|
|
61
|
+
- 用 mock 或测试服务覆盖 401、403、422、500、断网和取消请求。
|
|
62
|
+
- 确认客户端 bundle 不包含私密环境变量、服务端密钥或内部地址。
|
|
63
|
+
- 对关键 API client 行为补最小测试,证明超时、取消、错误映射和刷新队列可预期。
|
|
64
|
+
- 验证错误边界与请求层协作:渲染异常进 Error Boundary,请求失败进可恢复 UI,不互相吞掉。
|
|
65
|
+
|
|
66
|
+
## Constraints
|
|
67
|
+
|
|
68
|
+
- 不在页面组件中直接管理 token refresh、错误格式解析或重试策略。
|
|
69
|
+
- 不对 4xx 业务错误做盲目自动重试。
|
|
70
|
+
- 不把后端异常栈、内部错误码或原始 SQL/服务名暴露给用户。
|
|
71
|
+
- 不用 localStorage 存储高价值 token;若遗留系统无法避免,必须联动安全审查。
|
|
72
|
+
- 不用 WebSocket 替代简单轮询,也不用轮询实现高频双向协作。
|
|
73
|
+
- 不让上传经过 API 服务器转发大文件,除非有明确合规或扫描需求。
|
|
74
|
+
- 不在公共接口里直接暴露临时字段、数据库字段名或后端内部错误结构。
|
|
75
|
+
|
|
76
|
+
## Expected Output
|
|
77
|
+
|
|
78
|
+
输出应包含 API client 边界、接口类型来源、错误映射、鉴权刷新策略、上传/实时方案和验证结果。完成后组件不散落请求细节,用户状态完整,失败场景可恢复,客户端不会泄露服务端密钥。
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# API 集成实现模式
|
|
2
|
+
|
|
3
|
+
## 类型化 Fetch 客户端
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
export class ApiError extends Error {
|
|
7
|
+
constructor(
|
|
8
|
+
public readonly status: number,
|
|
9
|
+
public readonly body: unknown,
|
|
10
|
+
) {
|
|
11
|
+
super(`API 请求失败,状态码 ${status}`);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export async function requestJson<T>(
|
|
16
|
+
path: string,
|
|
17
|
+
init: RequestInit = {},
|
|
18
|
+
): Promise<T> {
|
|
19
|
+
const response = await fetch(`${import.meta.env.VITE_API_URL}${path}`, {
|
|
20
|
+
...init,
|
|
21
|
+
headers: {
|
|
22
|
+
Accept: "application/json",
|
|
23
|
+
"Content-Type": "application/json",
|
|
24
|
+
...init.headers,
|
|
25
|
+
},
|
|
26
|
+
credentials: "include",
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
if (!response.ok) {
|
|
30
|
+
const body = await response.json().catch(() => null);
|
|
31
|
+
throw new ApiError(response.status, body);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (response.status === 204) return undefined as T;
|
|
35
|
+
return response.json() as Promise<T>;
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## 用户端错误映射
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
export function getApiMessage(error: unknown): string {
|
|
43
|
+
if (!(error instanceof ApiError)) return "操作失败,请稍后重试。";
|
|
44
|
+
|
|
45
|
+
if (error.status === 401) return "请重新登录。";
|
|
46
|
+
if (error.status === 403) return "您没有权限执行此操作。";
|
|
47
|
+
if (error.status === 404) return "请求的资源已不存在。";
|
|
48
|
+
if (error.status === 409) return "此变更与最新数据冲突。";
|
|
49
|
+
if (error.status === 422) return "请检查标红字段。";
|
|
50
|
+
if (error.status === 429) return "请求过于频繁,请稍后再试。";
|
|
51
|
+
|
|
52
|
+
return "服务暂不可用,请稍后重试。";
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## 上传选型
|
|
57
|
+
|
|
58
|
+
| 需求 | 推荐方案 |
|
|
59
|
+
| ---------------- | ----------------------------- |
|
|
60
|
+
| 小头像或 CSV | Multipart 请求 |
|
|
61
|
+
| 大视频或归档文件 | 预签名直传 |
|
|
62
|
+
| 弱网环境大文件 | 分片断点续传 |
|
|
63
|
+
| 入库前合规扫描 | 经 API 中介上传(含大小限制) |
|
|
64
|
+
|
|
65
|
+
## 实时通信选型
|
|
66
|
+
|
|
67
|
+
| 需求 | 推荐方案 |
|
|
68
|
+
| -------------------- | ------------------------- |
|
|
69
|
+
| 任务进度或通知 | SSE(Server-Sent Events) |
|
|
70
|
+
| 聊天、在线状态、协作 | WebSocket |
|
|
71
|
+
| 数秒一次的状态轮询 | 定时轮询(Polling) |
|
|
72
|
+
| 服务端 AI Token 流 | SSE 或 fetch 流式响应 |
|
|
73
|
+
|
|
74
|
+
## 审查清单
|
|
75
|
+
|
|
76
|
+
- API 地址和凭证集中管理。
|
|
77
|
+
- 客户端需处理 204、非 JSON 错误、取消和离线状态。
|
|
78
|
+
- Token 刷新机制不能引发请求风暴。
|
|
79
|
+
- 组件应消费 hooks/领域函数,而非直接调用原始 fetch。
|
|
80
|
+
- 上传和实时流需暴露进度、取消、失败和重试状态。
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fec-browser-storage
|
|
3
|
+
description: Use when choosing, implementing, or reviewing browser storage such as localStorage, sessionStorage, IndexedDB, cookies, client persistence, offline data, secure storage, or cleanup strategy; Chinese triggers include 浏览器存储, 客户端持久化.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 浏览器存储
|
|
7
|
+
|
|
8
|
+
## Purpose
|
|
9
|
+
|
|
10
|
+
根据数据大小、安全要求和生命周期选择合适的客户端存储方案。
|
|
11
|
+
|
|
12
|
+
## Procedure
|
|
13
|
+
|
|
14
|
+
1. 先判断数据敏感度、体积、生命周期、是否需要跨 Tab、是否需要随请求发送。
|
|
15
|
+
2. 小量非敏感偏好用 localStorage;Tab 级临时数据用 sessionStorage;大量结构化数据或离线缓存用 IndexedDB;认证态优先 httpOnly cookie。
|
|
16
|
+
3. 封装统一 key 前缀、JSON parse/stringify、异常处理、过期清理和 quota 兜底。
|
|
17
|
+
4. 敏感数据按安全规则处理,不把明文 token、密码、信用卡信息放进可被 JS 读取的存储。
|
|
18
|
+
5. 审查隐私模式、存储配额、清理策略和跨浏览器兼容性。
|
|
19
|
+
|
|
20
|
+
## Detailed References
|
|
21
|
+
|
|
22
|
+
涉及存储选型表、localStorage/sessionStorage 封装、IndexedDB 示例、Cookie 辅助方法和敏感数据规则时,加载 [references/storage-patterns.md](references/storage-patterns.md)。
|
|
23
|
+
|
|
24
|
+
## Constraints
|
|
25
|
+
|
|
26
|
+
- localStorage/sessionStorage 是同步 API,大数据读写会阻塞主线程。
|
|
27
|
+
- 除 httpOnly cookie 外,客户端存储都可被 XSS 读取。
|
|
28
|
+
- Cookie 每次请求自动携带,不适合大数据。
|
|
29
|
+
- IndexedDB 配额和隐私模式行为有浏览器差异。
|
|
30
|
+
- URL 中不要传 token 或敏感数据。
|
|
31
|
+
|
|
32
|
+
## Expected Output
|
|
33
|
+
|
|
34
|
+
产出统一的 storage/cookie/db 封装,key 有命名空间,数据有过期或清理策略,敏感数据只进入合适的安全边界。
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# 浏览器存储模式
|
|
2
|
+
|
|
3
|
+
## 选型表
|
|
4
|
+
|
|
5
|
+
| 存储 | 容量 | API | 是否发送服务端 | 适用场景 | 安全性 |
|
|
6
|
+
| --- | --- | --- | --- | --- | --- |
|
|
7
|
+
| LocalStorage | ~5MB | 同步 | 否 | 用户偏好、非敏感持久数据 | XSS 可读取 |
|
|
8
|
+
| SessionStorage | ~5MB | 同步 | 否 | Tab 级临时数据 | XSS 可读取 |
|
|
9
|
+
| IndexedDB | 大 | 异步 | 否 | 大数据、文件、离线缓存 | XSS 可读取 |
|
|
10
|
+
| Cookie | ~4KB | 同步 | 是 | 认证 Session/httpOnly token | httpOnly 可防 JS 读取 |
|
|
11
|
+
|
|
12
|
+
## localStorage 封装
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
const STORAGE_PREFIX = "app:";
|
|
16
|
+
|
|
17
|
+
export const storage = {
|
|
18
|
+
get<T>(key: string): T | null {
|
|
19
|
+
try {
|
|
20
|
+
const raw = localStorage.getItem(STORAGE_PREFIX + key);
|
|
21
|
+
return raw ? JSON.parse(raw) : null;
|
|
22
|
+
} catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
set<T>(key: string, value: T): void {
|
|
27
|
+
localStorage.setItem(STORAGE_PREFIX + key, JSON.stringify(value));
|
|
28
|
+
},
|
|
29
|
+
remove(key: string): void {
|
|
30
|
+
localStorage.removeItem(STORAGE_PREFIX + key);
|
|
31
|
+
},
|
|
32
|
+
clear(): void {
|
|
33
|
+
Object.keys(localStorage)
|
|
34
|
+
.filter((key) => key.startsWith(STORAGE_PREFIX))
|
|
35
|
+
.forEach((key) => localStorage.removeItem(key));
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## IndexedDB
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
import { openDB } from "idb";
|
|
44
|
+
|
|
45
|
+
export const db = openDB("app-offline-db", 1, {
|
|
46
|
+
upgrade(database) {
|
|
47
|
+
if (!database.objectStoreNames.contains("requests")) {
|
|
48
|
+
database.createObjectStore("requests", { keyPath: "id" });
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Cookie
|
|
55
|
+
|
|
56
|
+
- httpOnly 只能由服务端设置。
|
|
57
|
+
- 认证 Cookie 使用 `Secure`、`SameSite=Lax/Strict`。
|
|
58
|
+
- 需要跨站点嵌入时才考虑 `SameSite=None; Secure`。
|
|
59
|
+
|
|
60
|
+
## 敏感数据规则
|
|
61
|
+
|
|
62
|
+
- 认证 token、刷新 token、Session ID:优先 httpOnly cookie。
|
|
63
|
+
- 用户偏好:localStorage。
|
|
64
|
+
- 表单草稿:sessionStorage 或 IndexedDB,避免敏感字段。
|
|
65
|
+
- 离线数据:IndexedDB,但不要缓存隐私或高价值敏感数据。
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fec-canvas-threejs
|
|
3
|
+
description: Use when building or reviewing Canvas 2D, Three.js/WebGL, React Three Fiber, GLSL shaders, ShaderToy-to-WebGL adaptation, 2D/3D visualization, game rendering, animation loops, GPU resource cleanup, or rendering performance. Do not use for standard DOM UI, charts already covered by a chart library, or non-graphical performance work; Chinese triggers include Canvas, Three.js, WebGL, GLSL, Shader, 3D, 数据可视化, 游戏.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Canvas 与 Three.js
|
|
7
|
+
|
|
8
|
+
## Purpose
|
|
9
|
+
|
|
10
|
+
在浏览器中实现高性能 2D/3D 图形渲染。
|
|
11
|
+
|
|
12
|
+
## Procedure
|
|
13
|
+
|
|
14
|
+
1. 先选渲染层:标准 UI 用 DOM;简单 2D 图形/签名/粒子用 Canvas 2D;3D 模型、空间交互和复杂粒子用 Three.js/WebGL;React 项目中的声明式 3D 用 React Three Fiber。
|
|
15
|
+
2. 为渲染容器定义稳定尺寸、DPI 适配和 resize 行为;Canvas 不会自动随 CSS 清晰缩放。
|
|
16
|
+
3. 动画循环使用 `requestAnimationFrame`,不可见或无变化时暂停,卸载时取消。
|
|
17
|
+
4. Three.js 必须释放 geometry/material/texture/renderer,并移除事件监听和 observer。
|
|
18
|
+
5. Shader/WebGL 任务先识别是 SDF、ray marching、noise、particle、post-processing、multipass 还是调试问题,再决定是否需要原生 WebGL2、Three.js ShaderMaterial 或 R3F。
|
|
19
|
+
6. WebGL2 适配时检查 GLSL 版本、入口函数、varying/in-out、texture API、uniform 使用和函数声明顺序,避免白屏只留控制台错误。
|
|
20
|
+
7. 对不可访问的图形内容提供 `aria-label`、替代文本或 DOM 版摘要;交互式图形要有键盘兜底。
|
|
21
|
+
|
|
22
|
+
## Core Patterns
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
const dpr = Math.min(window.devicePixelRatio || 1, 2);
|
|
26
|
+
canvas.width = width * dpr;
|
|
27
|
+
canvas.height = height * dpr;
|
|
28
|
+
canvas.style.width = `${width}px`;
|
|
29
|
+
canvas.style.height = `${height}px`;
|
|
30
|
+
ctx.scale(dpr, dpr);
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
let animationId = 0;
|
|
35
|
+
function animate() {
|
|
36
|
+
animationId = requestAnimationFrame(animate);
|
|
37
|
+
renderer.render(scene, camera);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return () => {
|
|
41
|
+
cancelAnimationFrame(animationId);
|
|
42
|
+
geometry.dispose();
|
|
43
|
+
material.dispose();
|
|
44
|
+
renderer.dispose();
|
|
45
|
+
};
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Detailed References
|
|
49
|
+
|
|
50
|
+
涉及 Canvas 2D 绘图、动画循环、Three.js 场景搭建、React Three Fiber、InstancedMesh 和性能清理时,加载 [references/rendering-patterns.md](references/rendering-patterns.md)。
|
|
51
|
+
|
|
52
|
+
涉及着色器路由、WebGL2 适配、GLSL 调试、多 pass 预算和视觉验证时,加载 [references/shader-webgl-patterns.md](references/shader-webgl-patterns.md)。
|
|
53
|
+
|
|
54
|
+
## Constraints
|
|
55
|
+
|
|
56
|
+
- Canvas/WebGL 内容对屏幕阅读器不可见,必须提供替代语义。
|
|
57
|
+
- WebGL 消耗 GPU,低端设备需限制像素比、面数和纹理大小。
|
|
58
|
+
- Three.js 资源不会自动释放,遗漏 `dispose()` 会造成 GPU 内存泄漏。
|
|
59
|
+
- Canvas 响应式必须同步 CSS 尺寸、绘图尺寸和相机/viewport。
|
|
60
|
+
- 复杂布局/路径规划可联用后台线程 workflow,但渲染本身仍在主线程/渲染线程协调。
|
|
61
|
+
- Shader 主循环、采样层数和多 pass 数量必须有预算;低端设备上要降低 DPR、步数、粒子数或禁用重后处理。
|
|
62
|
+
- 交付前必须确认 canvas 非空、尺寸正确、resize 后不拉伸、控制台无 shader compile/link 错误。
|
|
63
|
+
|
|
64
|
+
## Expected Output
|
|
65
|
+
|
|
66
|
+
2D/3D 场景清晰、响应式、可清理,关键设备上接近 60fps;用户能通过替代文本或键盘路径理解/操作核心内容。
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Canvas、Three.js 与 R3F 模式
|
|
2
|
+
|
|
3
|
+
## Canvas 2D
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
const canvas = document.getElementById("chart") as HTMLCanvasElement;
|
|
7
|
+
const ctx = canvas.getContext("2d");
|
|
8
|
+
if (!ctx) throw new Error("Canvas 2D is unavailable");
|
|
9
|
+
|
|
10
|
+
ctx.fillStyle = "#3b82f6";
|
|
11
|
+
ctx.fillRect(10, 10, 50, 50);
|
|
12
|
+
ctx.beginPath();
|
|
13
|
+
ctx.arc(100, 100, 30, 0, Math.PI * 2);
|
|
14
|
+
ctx.fill();
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## 动画循环
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
let animationId = 0;
|
|
21
|
+
|
|
22
|
+
function animate() {
|
|
23
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
24
|
+
updateParticles();
|
|
25
|
+
drawParticles(ctx);
|
|
26
|
+
animationId = requestAnimationFrame(animate);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
animate();
|
|
30
|
+
return () => cancelAnimationFrame(animationId);
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Three.js 基础场景
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
const scene = new THREE.Scene();
|
|
37
|
+
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
|
|
38
|
+
const renderer = new THREE.WebGLRenderer({ antialias: true });
|
|
39
|
+
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
|
|
40
|
+
|
|
41
|
+
const geometry = new THREE.BoxGeometry(1, 1, 1);
|
|
42
|
+
const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
|
|
43
|
+
const cube = new THREE.Mesh(geometry, material);
|
|
44
|
+
scene.add(cube);
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## React Three Fiber
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
<Canvas camera={{ position: [0, 0, 5], fov: 75 }} role="img" aria-label="3D 产品预览">
|
|
51
|
+
<ambientLight intensity={0.5} />
|
|
52
|
+
<directionalLight position={[5, 5, 5]} />
|
|
53
|
+
<mesh>
|
|
54
|
+
<boxGeometry />
|
|
55
|
+
<meshStandardMaterial color="hotpink" />
|
|
56
|
+
</mesh>
|
|
57
|
+
<OrbitControls />
|
|
58
|
+
</Canvas>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## 性能与清理
|
|
62
|
+
|
|
63
|
+
- 纹理尽量压缩并限制尺寸,常规上限先按 2048px 评估。
|
|
64
|
+
- 重复几何体用 `InstancedMesh`。
|
|
65
|
+
- 不需要持续重绘时暂停 animation loop。
|
|
66
|
+
- 卸载时释放 geometry、material、texture、renderer、controls。
|
|
67
|
+
- ResizeObserver 更新相机 aspect 和 renderer size。
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Shader 与 WebGL 模式
|
|
2
|
+
|
|
3
|
+
## 技术选型参考
|
|
4
|
+
|
|
5
|
+
| 目标 | 推荐起点 | 注意事项 |
|
|
6
|
+
| ------------------ | ------------------ | ------------------------------ |
|
|
7
|
+
| 数学几何 3D 形态 | SDF + 光线步进 | 步数上限、法线质量、软阴影开销 |
|
|
8
|
+
| 有机运动效果 | 噪声 + 域扭曲 | 过度绘制、重复噪声调用 |
|
|
9
|
+
| 粒子效果 | 实例化或着色器粒子 | 移动端粒子数量上限、混合开销 |
|
|
10
|
+
| 泛光/故障/色彩调整 | 后处理通道 | 额外帧缓冲区显存 |
|
|
11
|
+
| 持续模拟 | 乒乓帧缓冲区 | 纹理格式支持 |
|
|
12
|
+
| 白屏调试 | 编译/链接日志 | 函数顺序、被优化掉的 uniform |
|
|
13
|
+
|
|
14
|
+
## WebGL2 适配清单
|
|
15
|
+
|
|
16
|
+
- 片元着色器以 `#version 300 es` 开头。
|
|
17
|
+
- 添加 `precision highp float;` 和 `out vec4 fragColor;`。
|
|
18
|
+
- 用 `in`/`out` 替代旧版 `varying`。
|
|
19
|
+
- 用 `texture()` 替代 `texture2D()`。
|
|
20
|
+
- 将 ShaderToy 风格的 `mainImage` 包装为标准 `main`。
|
|
21
|
+
- 使用 `gl_FragCoord.xy` 获取片元坐标。
|
|
22
|
+
- 辅助函数必须在被调用前声明。
|
|
23
|
+
- 预计算常量,不要在宏定义中放函数调用。
|
|
24
|
+
|
|
25
|
+
## 运行时骨架
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
const gl = canvas.getContext("webgl2");
|
|
29
|
+
if (!gl) throw new Error("WebGL2 is unavailable");
|
|
30
|
+
|
|
31
|
+
function compile(type: number, source: string) {
|
|
32
|
+
const shader = gl.createShader(type);
|
|
33
|
+
if (!shader) throw new Error("Cannot create shader");
|
|
34
|
+
gl.shaderSource(shader, source.trim());
|
|
35
|
+
gl.compileShader(shader);
|
|
36
|
+
|
|
37
|
+
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
38
|
+
throw new Error(gl.getShaderInfoLog(shader) ?? "Shader compile failed");
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return shader;
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## 性能预算
|
|
46
|
+
|
|
47
|
+
- 光线步进步数:从 64 起步,仅在出现伪影且证明必要时再提升。
|
|
48
|
+
- 体积采样:桌面端每条射线 16-24 次,移动端酌情降低。
|
|
49
|
+
- FBM 倍频:从 4 开始;避免在光线循环内嵌套 FBM。
|
|
50
|
+
- DPR:桌面端上限 2,移动端重度场景上限 1.5。
|
|
51
|
+
- 纹理尺寸:使用压缩或缩放资源;不要假设 4K 纹理是安全的。
|
|
52
|
+
|
|
53
|
+
## 调试视图
|
|
54
|
+
|
|
55
|
+
- 法线:输出归一化后的法线,映射到 0-1 范围。
|
|
56
|
+
- 步数:输出当前步数除以最大步数。
|
|
57
|
+
- 距离/深度:以灰度输出命中距离。
|
|
58
|
+
- UV:映射后输出 `vec3(uv, 0.0)`。
|
|
59
|
+
- 材质 ID:将 ID 映射到少量固定调色板。
|
|
60
|
+
|
|
61
|
+
## 视觉验证
|
|
62
|
+
|
|
63
|
+
- 桌面端和移动端尺寸下 Canvas 不为空白。
|
|
64
|
+
- 缩放时更新绘制缓冲区、视口、相机纵横比和 uniform。
|
|
65
|
+
- 低功耗模式下仍能响应,或有静态降级方案。
|
|
66
|
+
- 控制台无着色器编译/链接错误。
|
|
67
|
+
- 卸载或场景隐藏时停止动画。
|