@dianzhong/create-harness-app 0.1.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.
Files changed (95) hide show
  1. package/dist/index.mjs +412 -0
  2. package/package.json +29 -0
  3. package/templates/axios/.env.example +2 -0
  4. package/templates/axios/src/api/auth.ts +19 -0
  5. package/templates/axios/src/api/request.ts +61 -0
  6. package/templates/axios/src/types/api.ts +26 -0
  7. package/templates/axios/src/utils/auth.ts +5 -0
  8. package/templates/axios/src/utils/storage.ts +17 -0
  9. package/templates/harness/full/.agents/skills/find-skills/SKILL.md +143 -0
  10. package/templates/harness/full/.agents/skills/vue-best-practices/LICENSE.md +21 -0
  11. package/templates/harness/full/.agents/skills/vue-best-practices/SKILL.md +155 -0
  12. package/templates/harness/full/.agents/skills/vue-best-practices/SYNC.md +5 -0
  13. package/templates/harness/full/.agents/skills/vue-best-practices/references/animation-class-based-technique.md +258 -0
  14. package/templates/harness/full/.agents/skills/vue-best-practices/references/animation-state-driven-technique.md +287 -0
  15. package/templates/harness/full/.agents/skills/vue-best-practices/references/component-async.md +99 -0
  16. package/templates/harness/full/.agents/skills/vue-best-practices/references/component-data-flow.md +313 -0
  17. package/templates/harness/full/.agents/skills/vue-best-practices/references/component-fallthrough-attrs.md +179 -0
  18. package/templates/harness/full/.agents/skills/vue-best-practices/references/component-keep-alive.md +139 -0
  19. package/templates/harness/full/.agents/skills/vue-best-practices/references/component-slots.md +226 -0
  20. package/templates/harness/full/.agents/skills/vue-best-practices/references/component-suspense.md +231 -0
  21. package/templates/harness/full/.agents/skills/vue-best-practices/references/component-teleport.md +110 -0
  22. package/templates/harness/full/.agents/skills/vue-best-practices/references/component-transition-group.md +131 -0
  23. package/templates/harness/full/.agents/skills/vue-best-practices/references/component-transition.md +135 -0
  24. package/templates/harness/full/.agents/skills/vue-best-practices/references/composables.md +303 -0
  25. package/templates/harness/full/.agents/skills/vue-best-practices/references/directives.md +168 -0
  26. package/templates/harness/full/.agents/skills/vue-best-practices/references/perf-avoid-component-abstraction-in-lists.md +177 -0
  27. package/templates/harness/full/.agents/skills/vue-best-practices/references/perf-v-once-v-memo-directives.md +185 -0
  28. package/templates/harness/full/.agents/skills/vue-best-practices/references/perf-virtualize-large-lists.md +182 -0
  29. package/templates/harness/full/.agents/skills/vue-best-practices/references/plugins.md +178 -0
  30. package/templates/harness/full/.agents/skills/vue-best-practices/references/reactivity.md +371 -0
  31. package/templates/harness/full/.agents/skills/vue-best-practices/references/render-functions.md +227 -0
  32. package/templates/harness/full/.agents/skills/vue-best-practices/references/sfc.md +355 -0
  33. package/templates/harness/full/.agents/skills/vue-best-practices/references/state-management.md +138 -0
  34. package/templates/harness/full/.agents/skills/vue-best-practices/references/updated-hook-performance.md +193 -0
  35. package/templates/harness/full/.claude/agents/code-reviewer.md +109 -0
  36. package/templates/harness/full/.claude/agents/harness-reviewer.md +51 -0
  37. package/templates/harness/full/.claude/hooks/guard-tool.cjs +234 -0
  38. package/templates/harness/full/.claude/hooks/notify.cjs +168 -0
  39. package/templates/harness/full/.claude/hooks/quality-gate.cjs +135 -0
  40. package/templates/harness/full/.claude/rules/delivery.md +66 -0
  41. package/templates/harness/full/.claude/rules/formatting.md +7 -0
  42. package/templates/harness/full/.claude/rules/git.md +8 -0
  43. package/templates/harness/full/.claude/rules/skills-mcp.md +13 -0
  44. package/templates/harness/full/.claude/rules/vue.md +227 -0
  45. package/templates/harness/full/.claude/settings.json +123 -0
  46. package/templates/harness/full/.claude/skills/find-skills/SKILL.md +143 -0
  47. package/templates/harness/full/.claude/skills/vue-best-practices/LICENSE.md +21 -0
  48. package/templates/harness/full/.claude/skills/vue-best-practices/SKILL.md +155 -0
  49. package/templates/harness/full/.claude/skills/vue-best-practices/SYNC.md +5 -0
  50. package/templates/harness/full/.claude/skills/vue-best-practices/references/animation-class-based-technique.md +258 -0
  51. package/templates/harness/full/.claude/skills/vue-best-practices/references/animation-state-driven-technique.md +287 -0
  52. package/templates/harness/full/.claude/skills/vue-best-practices/references/component-async.md +99 -0
  53. package/templates/harness/full/.claude/skills/vue-best-practices/references/component-data-flow.md +313 -0
  54. package/templates/harness/full/.claude/skills/vue-best-practices/references/component-fallthrough-attrs.md +179 -0
  55. package/templates/harness/full/.claude/skills/vue-best-practices/references/component-keep-alive.md +139 -0
  56. package/templates/harness/full/.claude/skills/vue-best-practices/references/component-slots.md +226 -0
  57. package/templates/harness/full/.claude/skills/vue-best-practices/references/component-suspense.md +231 -0
  58. package/templates/harness/full/.claude/skills/vue-best-practices/references/component-teleport.md +110 -0
  59. package/templates/harness/full/.claude/skills/vue-best-practices/references/component-transition-group.md +131 -0
  60. package/templates/harness/full/.claude/skills/vue-best-practices/references/component-transition.md +135 -0
  61. package/templates/harness/full/.claude/skills/vue-best-practices/references/composables.md +303 -0
  62. package/templates/harness/full/.claude/skills/vue-best-practices/references/directives.md +168 -0
  63. package/templates/harness/full/.claude/skills/vue-best-practices/references/perf-avoid-component-abstraction-in-lists.md +177 -0
  64. package/templates/harness/full/.claude/skills/vue-best-practices/references/perf-v-once-v-memo-directives.md +185 -0
  65. package/templates/harness/full/.claude/skills/vue-best-practices/references/perf-virtualize-large-lists.md +182 -0
  66. package/templates/harness/full/.claude/skills/vue-best-practices/references/plugins.md +178 -0
  67. package/templates/harness/full/.claude/skills/vue-best-practices/references/reactivity.md +371 -0
  68. package/templates/harness/full/.claude/skills/vue-best-practices/references/render-functions.md +227 -0
  69. package/templates/harness/full/.claude/skills/vue-best-practices/references/sfc.md +355 -0
  70. package/templates/harness/full/.claude/skills/vue-best-practices/references/state-management.md +138 -0
  71. package/templates/harness/full/.claude/skills/vue-best-practices/references/updated-hook-performance.md +193 -0
  72. package/templates/harness/full/.editorconfig +8 -0
  73. package/templates/harness/full/.husky/commit-msg +1 -0
  74. package/templates/harness/full/.husky/pre-commit +1 -0
  75. package/templates/harness/full/.lintstagedrc.json +4 -0
  76. package/templates/harness/full/.nvmrc +1 -0
  77. package/templates/harness/full/.oxlintrc.json +11 -0
  78. package/templates/harness/full/.prettierrc.json +6 -0
  79. package/templates/harness/full/AGENTS.md +3 -0
  80. package/templates/harness/full/CLAUDE.md +28 -0
  81. package/templates/harness/full/GEMINI.md +3 -0
  82. package/templates/harness/full/commitlint.config.ts +3 -0
  83. package/templates/harness/full/docs/ai-harness.md +77 -0
  84. package/templates/harness/full/docs/delivery-template.md +66 -0
  85. package/templates/harness/full/docs/git.md +24 -0
  86. package/templates/harness/full/docs/harness-quick-reference.md +89 -0
  87. package/templates/harness/full/docs/review-checklist.md +49 -0
  88. package/templates/harness/full/scripts/harness-hooks.test.mjs +218 -0
  89. package/templates/harness/full/scripts/verify-skills.mjs +248 -0
  90. package/templates/harness/full/scripts/verify-skills.test.mjs +72 -0
  91. package/templates/harness/full/skills-lock.json +50 -0
  92. package/templates/harness/minimal/.claude/hooks/guard-tool.cjs +234 -0
  93. package/templates/harness/minimal/.claude/hooks/quality-gate.cjs +135 -0
  94. package/templates/harness/minimal/.claude/settings.json +27 -0
  95. package/templates/harness/minimal/CLAUDE.md +12 -0
@@ -0,0 +1,66 @@
1
+ # 交付与质量规则
2
+
3
+ ## 需求确认
4
+
5
+ 在以下场景,**必须先输出需求理解摘要并等待用户确认,再开始编码**:
6
+
7
+ - 创建新功能、新页面或新组件。
8
+ - 涉及 3 个及以上文件的变更。
9
+ - 用户描述存在歧义、缺少验收标准或多种理解可能。
10
+ - 涉及状态设计、路由变更、权限调整、数据库变更。
11
+ - 用户说"优化一下"、"改一下"等模糊指令。
12
+
13
+ 用户明确说"直接做"或"不需要确认"时,可跳过此环节。
14
+
15
+ ### 需求确认输出格式
16
+
17
+ 1. **需求理解**:我理解的你的需求是...
18
+ 2. **变更范围**:预计修改 X 个文件,涉及...
19
+ 3. **关键决策**:需要确认的问题(如两种方案选哪个)。
20
+ 4. **验证计划**:改完后如何验证。
21
+
22
+ ## 探索与创意工作
23
+
24
+ 遇到以下场景时,应先使用 brainstorming skill 理解需求和设计方向:
25
+
26
+ - 创建新功能、新页面或新组件。
27
+ - 对现有功能进行较大的重构或行为变更。
28
+ - 涉及多个模块或跨组件的状态设计。
29
+ - 用户需求不明确或存在多种可行方案。
30
+
31
+ ## Bug 修复
32
+
33
+ 遇到 bug、测试失败或意外行为时,应先使用 systematic-debugging skill 系统化排查根因:
34
+
35
+ - 复现问题并定位根因。
36
+ - 确认修复方案不会引入副作用。
37
+ - 验证修复后通过相同检查。
38
+
39
+ ## 声称完成的流程
40
+
41
+ 在声称任务完成前,必须完成以下步骤:
42
+
43
+ 1. 验证所有必需的检查已通过(`pnpm check` 或对应场景的检查)。
44
+ 2. 如果某些检查未运行,必须在交付说明中明确记录原因和剩余风险。
45
+ 3. 确认变更范围与需求一致,没有引入未要求的副作用。
46
+ 4. 按 `docs/delivery-template.md` 输出交接单。
47
+ 5. 确认人工复核已完成或已安排。
48
+
49
+ Code review 必须阻断 P0/P1 问题、门禁失败、安全风险、权限绕过、路由 meta 回归、未类型化状态/API 边界。低风险建议可以通过,但需在 review 备注中说明。
50
+
51
+ 使用 verification-before-completion skill(来自 superpowers 插件)作为检查清单。
52
+
53
+ ## Code Review 反馈处理
54
+
55
+ 收到 review 反馈后,应独立判断每个建议的技术合理性:
56
+
57
+ - 对每个反馈的技术准确性进行验证。
58
+ - 不盲目接受所有建议,也不无理拒绝。
59
+ - 对不接受的建议,说明技术理由并记录。
60
+ - 处理完所有阻断性问题后,重新请求 review。
61
+
62
+ 使用 receiving-code-review skill(来自 superpowers 插件)作为处理原则。
63
+
64
+ ## 人工反馈循环
65
+
66
+ 用户指出某处可能有问题、补充业务规则或确认风险后,先复述理解,再定位相关代码和规则。明确判断反馈属于 bug、需求补充、业务决策、验证遗漏还是误报;需要修复时再改代码,不修改时说明理由。处理完成后重新运行对应检查,并输出第二版交接单。
@@ -0,0 +1,7 @@
1
+ # 格式化与自动修复规则
2
+
3
+ - Prettier 负责排版统一;ESLint 和 oxlint 负责代码质量与自动修复。
4
+ - 命令清单见 `docs/harness-quick-reference.md`"格式化命令"段,不在此复述。
5
+ - 提交前的 `lint-staged` 只处理已暂存文件;不要把大范围格式整理和业务改动混在同一次提交里。
6
+ - 如无明确需求,不要对无关文件执行全仓格式化。
7
+ - `quality-gate.cjs stop` 允许在 Stop 收尾自动格式化;`lint-staged` 作为 pre-commit safety net 允许自动修复。所有 hook 和 AI 自身不得自动暂存或改写 repo-tracked 文件,详见 `docs/ai-harness.md` 维护规则。
@@ -0,0 +1,8 @@
1
+ # Git 规则(AI 操作约束)
2
+
3
+ 约束 AI agent 的 git 行为;分支命名、Conventional Commits 等团队约定见 `docs/git.md`。
4
+
5
+ - 保留用户已有的无关改动,未经允许不动其它文件。
6
+ - 未经明确允许,不执行破坏性 Git 命令(`git reset --hard`、force push、删除分支、删除 stash 等)。
7
+ - Stop 收尾的质量门禁只做质量检查和自动格式化,不自动暂存变更。除此之外也不自动暂存,不自动改写 repo-tracked 文件。
8
+ - Pre-commit 只运行 `pnpm lint-staged`;完整质量检查由交付前 `pnpm check` 和 Stop 阶段门禁执行。
@@ -0,0 +1,13 @@
1
+ # Skills 同步规则
2
+
3
+ - 不确定是否已有合适 skill 时,先查 `docs/harness-quick-reference.md`。
4
+ - 项目 skills 放在 `.claude/skills/`。
5
+ - `skills-lock.json` 必须保存每个 skill 的真实 computed hash。
6
+
7
+ 新增或修改 skill 时,必须同步以下 3 个位置:
8
+
9
+ 1. `.claude/skills/{skill}/`
10
+ 2. `.agents/skills/{skill}/`(其他 agent 的镜像)
11
+ 3. `skills-lock.json`(hash lock)
12
+
13
+ 修改任何 skill 后必须先运行 `pnpm harness:sync`,再运行 `pnpm harness:check`。
@@ -0,0 +1,227 @@
1
+ # Vue 与 Element Plus 规则
2
+
3
+ - 使用 Vue 3 Composition API 和 `<script setup lang="ts">`,SFC 顺序统一为 `<script>`、`<template>`、`<style>`。
4
+ - 路由页面作为组合层,不堆积复杂实现;较大 UI 拆到 `src/components/<feature>/`。
5
+ - 可复用的有状态逻辑放到 `src/composables/useXxx.ts`。
6
+ - props、emits、store state、route meta、类 API 数据边界必须显式类型化。
7
+ - 能用 `computed` 派生的状态不要重复存储;watcher 只用于副作用。
8
+ - 路由和菜单由后端 `/auth/menus` 菜单树动态生成;`src/router/routes.ts` 只保留布局和常量路由,`src/router/component-map.ts` 负责组件解析和隐藏路由。
9
+ - Element Plus 使用项目现有自动导入配置;全局主题覆盖放到 `src/styles/element-plus.scss`。
10
+ - 避免宽泛 `any`、重复菜单数据源、隐藏异步错误、未类型化权限字符串。
11
+
12
+ ## 弹窗组件化规范
13
+
14
+ - 路由页面只保留列表/主视图逻辑,弹窗必须拆分为独立组件。
15
+ - **页面级弹窗放到所属页面目录下的 `components/` 中**,作为该页面的私有组件;跨页面复用的弹窗才放到 `src/components/<feature>/`。
16
+ - **弹窗可见性通过 `v-model` + `defineModel` 传递**:
17
+ - 父组件:`<Dialog v-model="dialogVisible" v-if="dialogVisible" />`
18
+ - 子组件:`const visible = defineModel<boolean>({ required: true })`
19
+ - `v-if` 控制组件挂载/销毁,确保每次打开都走完整的生命周期(`onMounted` → `onUnmounted`)。
20
+ - `v-model` 负责在弹窗内部与 ElDialog 的显示状态同步。
21
+ - **弹窗 props 最小化**:只接收必要 ID(如 `userId` / `roleId`),不接收完整对象数据。
22
+ - **弹窗内部自加载**:在 `onMounted` 中根据 ID 调用 detail API 获取详情,编辑和查看场景均如此;新增场景 ID 为 undefined,直接初始化空状态。
23
+ - **禁止在弹窗内使用 watcher 监听 ID 变化来重置状态**;状态初始化只在 `onMounted` 中完成,关闭时由 `v-if` 自然销毁重置。
24
+ - **禁止在 ElDialog 上使用 `@open` 做状态重置或数据加载**。父组件通过 `v-if` 控制弹窗时,组件每次打开都会重新挂载,setup 会重新执行,状态天然重置;数据加载应放在 `onMounted` 中。`@open` 仅在父组件使用 `v-show` 时才需要,但本项目统一使用 `v-if`。
25
+ - 弹窗通过 emit `success` 通知父组件操作成功,父组件监听后刷新列表。
26
+
27
+ ## 状态枚举规范(强制)
28
+
29
+ - 除 boolean(是/否)外,所有表示业务状态的数值常量**必须**使用 TypeScript `enum`,**严禁**直接使用字面量数字做判断或赋值,例如:
30
+ - ❌ `status === 1`、`reviewType: 2`、`actionCode === 10`、`const APPROVE = 1`
31
+ - ✅ `status === ReviewResultEnum.APPROVE`、`reviewType: ReviewTypeEnum.PRODUCER`
32
+ - **常量也不够**:即便封装成 `const REVIEW_RESULT_APPROVE = 1` 这样的常量,**也不符合规范**,必须用 `enum`。
33
+ - 枚举定义放在 `src/types/` 或 `src/constants/` 中,使用 PascalCase 命名,如 `ReviewResultEnum`、`ActionCodeEnum`。
34
+ - 枚举上方必须用注释写清所有码值含义,例如 `/** 1-通过 2-驳回 */`,不依赖代码读者去猜。
35
+ - 枚举对应的标签映射使用独立常量对象,如 `REVIEW_RESULT_LABELS`,不在模板中内联三元表达式显示文案。
36
+ - **后端码值待确认时**:用 `⚠️ TODO(联调)` 注释标注,但仍然定义 enum 占位,不能用裸数字拖到联调时再改。
37
+ - **review 必须阻断**:在代码中发现裸数字比较业务状态码(`=== 1`、`=== 2` 等)视为 P1 问题,必须拒绝合并。
38
+
39
+ ## `<script setup>` 内部书写顺序(强制)
40
+
41
+ `<script setup>` 内部必须严格按以下顺序书写,**不得颠倒**:
42
+
43
+ ```
44
+ 1. import 语句
45
+ 2. defineProps / defineEmits / defineModel
46
+ 3. 常量、枚举引用(不可变的模块级常量)
47
+ 4. 按业务模块分组,每个模块内依次为 ref/reactive → computed → 函数
48
+ - 模块A(如:登录相关):ref → computed → 函数
49
+ - 模块B(如:注册相关):ref → computed → 函数
50
+ - ...
51
+ 5. watch / watchEffect(副作用监听)
52
+ 6. onMounted / onUnmounted 等生命周期钩子
53
+ 7. 接口请求初始化调用(setup 阶段直接触发,放在最末尾)
54
+ ```
55
+
56
+ **规则细则:**
57
+
58
+ - **按模块维度组织代码**:相关逻辑集中在一起(如登录相关放一起、注册相关放一起),而不是把所有 ref 拢在一起、所有 computed 拢在一起。每个模块内部保持 ref/reactive → computed → 函数的顺序。
59
+ - **同一模块的响应式数据优先使用 `reactive` 合并到一个对象中**,而不是多个独立的 `ref`。这样同一业务领域的状态天然聚合,语义更清晰,也便于按模块整体传递或重置。
60
+ - **接口请求优先在 setup 阶段直接触发**(即 `<script setup>` 顶层调用),而不是放在 `onMounted` 中。接口请求的初始化调用放在 script 最末尾,这样数据加载在 setup 阶段就开始,比等 `onMounted` 更早发起请求。
61
+ - **禁止裸 `await`**:setup 顶层不允许 `await fetchXxx()`,因为 `<script setup>` 不支持顶层 await(除非配合 `<Suspense>`)。应调用不 await 的函数触发请求,或使用 `.then()` 处理。
62
+ - `onMounted` / `onUnmounted` / `onBeforeUnmount` 等生命周期钩子放在 watch 之后、接口请求初始化之前,用于非 API 请求的初始化逻辑(如事件监听、DOM 操作等)。
63
+ - `watch` / `watchEffect` 放在所有模块分组之后、生命周期钩子之前,不允许散落在 `ref` 或 `computed` 附近。
64
+
65
+ **正确示例:**
66
+
67
+ ```ts
68
+ // ✅ 正确:按模块分组,同模块数据用 reactive 合并,接口初始化在末尾
69
+ // --- 模块:用户列表 ---
70
+ const listState = reactive({
71
+ data: [] as UserInfo[],
72
+ loading: false,
73
+ total: 0,
74
+ })
75
+
76
+ async function fetchUserList() {
77
+ listState.loading = true
78
+ const res = await getUserListAPI()
79
+ listState.data = res.data.list
80
+ listState.total = res.data.total
81
+ listState.loading = false
82
+ }
83
+
84
+ // --- 模块:弹窗操作 ---
85
+ const dialogState = reactive({
86
+ visible: false,
87
+ currentId: undefined as number | undefined,
88
+ })
89
+
90
+ function handleEdit(id: number) {
91
+ dialogState.currentId = id
92
+ dialogState.visible = true
93
+ }
94
+
95
+ // --- watch ---
96
+ watch(() => props.id, fetchUserList)
97
+
98
+ // --- 生命周期(非 API 初始化逻辑) ---
99
+ onMounted(() => {
100
+ // 仅用于非 API 请求的初始化,如事件监听
101
+ window.addEventListener('resize', handleResize)
102
+ })
103
+
104
+ onUnmounted(() => {
105
+ window.removeEventListener('resize', handleResize)
106
+ })
107
+
108
+ // --- 接口请求初始化(setup 阶段,最末尾) ---
109
+ fetchUserList()
110
+ ```
111
+
112
+ ```ts
113
+ // ❌ 错误:接口请求放在 onMounted 里
114
+ onMounted(() => {
115
+ fetchUserList() // 应直接在 setup 顶层调用
116
+ })
117
+
118
+ // ❌ 错误:同模块数据用多个独立 ref
119
+ const userList = ref([]) // 应合并为 reactive 对象
120
+ const loading = ref(false) // 同上
121
+ const total = ref(0) // 同上
122
+
123
+ // ❌ 错误:不按模块分组
124
+ const userList = ref([])
125
+ const dialogVisible = ref(false) // 弹窗状态和列表状态混在一起
126
+ const loading = ref(false)
127
+ ```
128
+
129
+ - **review 必须阻断**:发现接口请求初始化放在 `onMounted` 中(而非 setup 末尾直接调用)、或代码不按模块分组视为 P1 问题。
130
+
131
+ ## 表单校验规范(强制)
132
+
133
+ - **优先使用 Element Plus Form 的 `rules` 进行校验**,而不是在提交时手动 `if` 判断或自定义校验函数散落各处。
134
+ - 校验规则通过 `:rules` 绑定到 `el-form`,配合 `prop` 声明,利用 Element Plus 内置的异步校验和错误提示机制。
135
+ - 需要自定义校验逻辑时,使用 `rules` 中的 `validator` 字段,而非绕过 Form 直接弹提示。
136
+
137
+ **正确示例:**
138
+
139
+ ```ts
140
+ // ✅ 使用 el-form rules 校验
141
+ const rules = {
142
+ name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
143
+ phone: [
144
+ { required: true, message: '请输入手机号', trigger: 'blur' },
145
+ { pattern: PHONE_REGEX, message: '手机号格式不正确', trigger: 'blur' },
146
+ ],
147
+ }
148
+ ```
149
+
150
+ ```html
151
+ <!-- ✅ 模板中绑定 rules + prop -->
152
+ <el-form :model="form" :rules="rules" ref="formRef">
153
+ <el-form-item label="名称" prop="name">
154
+ <el-input v-model="form.name" />
155
+ </el-form-item>
156
+ </el-form>
157
+ ```
158
+
159
+ ```ts
160
+ // ❌ 错误:手动 if 校验,绕过 Form rules
161
+ async function handleSubmit() {
162
+ if (!form.name) {
163
+ ElMessage.warning('请输入名称') // 禁止
164
+ return
165
+ }
166
+ }
167
+ ```
168
+
169
+ ## 手机号校验规范
170
+
171
+ - 手机号校验统一使用正则 `/^1\d{10}$/`(1 开头的 11 位数字),定义为模块级常量复用。
172
+ - 该正则封装在项目公共位置(如 `src/utils/validators.ts` 或 `src/constants/`),各表单通过 import 引用,不在组件内重复定义。
173
+
174
+ ```ts
175
+ // ✅ 常量定义(公共位置)
176
+ /** 手机号正则:1 开头的 11 位数字 */
177
+ export const PHONE_REGEX = /^1\d{10}$/
178
+
179
+ // ✅ 在 Form rules 中使用
180
+ import { PHONE_REGEX } from '@/constants/validators'
181
+
182
+ const rules = {
183
+ phone: [
184
+ { required: true, message: '请输入手机号', trigger: 'blur' },
185
+ { pattern: PHONE_REGEX, message: '手机号格式不正确', trigger: 'blur' },
186
+ ],
187
+ }
188
+ ```
189
+
190
+ ```ts
191
+ // ❌ 错误:在组件内重复定义正则
192
+ const phoneReg = /^1[3-9]\d{9}$/ // 禁止,应复用公共常量
193
+
194
+ // ❌ 错误:手动 if 判断手机号
195
+ if (!PHONE_REGEX.test(form.phone)) {
196
+ ElMessage.warning('手机号格式不正确') // 应通过 Form rules 校验
197
+ return
198
+ }
199
+ ```
200
+
201
+ ## 列表页搜索规范
202
+
203
+ - **列表页的搜索按钮必须重置 `pageNo = 1`**,避免在翻到第 N 页后搜索导致结果为空或数据错位。
204
+ - 重置分页和发起请求统一放在搜索方法中,分页组件的 `current-change` 事件只负责翻页请求,不做搜索重置。
205
+
206
+ ```ts
207
+ // ✅ 搜索按钮:重置页码后再请求
208
+ const queryParams = reactive({ pageNo: 1, pageSize: 10, keyword: '' })
209
+
210
+ function handleSearch() {
211
+ queryParams.pageNo = 1 // 必须重置
212
+ fetchList()
213
+ }
214
+
215
+ function handlePageChange(page: number) {
216
+ queryParams.pageNo = page
217
+ fetchList()
218
+ }
219
+ ```
220
+
221
+ ```ts
222
+ // ❌ 错误:搜索时未重置页码
223
+ function handleSearch() {
224
+ // 缺少 queryParams.pageNo = 1,翻到第 3 页搜索会请求 pageNo=3
225
+ fetchList()
226
+ }
227
+ ```
@@ -0,0 +1,123 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/claude-code-settings.json",
3
+ "permissions": {
4
+ "allow": [
5
+ "Read",
6
+ "Glob",
7
+ "Grep",
8
+ "Bash(git status*)",
9
+ "Bash(git diff*)",
10
+ "Bash(git log*)",
11
+ "Bash(git show*)",
12
+ "Bash(pnpm *)",
13
+ "Bash(node *)"
14
+ ],
15
+ "deny": [
16
+ "Read(.env*)",
17
+ "Read(**/.env*)",
18
+ "Read(secrets/**)",
19
+ "Read(**/secrets/**)",
20
+ "Read(*.pem)",
21
+ "Read(**/*.pem)",
22
+ "Read(*.key)",
23
+ "Read(**/*.key)",
24
+ "Read(**/*.p12)",
25
+ "Read(**/*.pfx)",
26
+ "Read(**/*.crt)",
27
+ "Read(**/*.cer)",
28
+ "Write(.env*)",
29
+ "Write(**/.env*)",
30
+ "Write(secrets/**)",
31
+ "Write(**/secrets/**)",
32
+ "Write(*.pem)",
33
+ "Write(**/*.pem)",
34
+ "Write(*.key)",
35
+ "Write(**/*.key)",
36
+ "Write(**/*.p12)",
37
+ "Write(**/*.pfx)",
38
+ "Write(**/*.crt)",
39
+ "Write(**/*.cer)",
40
+ "Bash(git reset --hard*)",
41
+ "Bash(git push --force*)",
42
+ "Bash(git branch -D*)",
43
+ "Bash(git stash drop*)",
44
+ "Bash(git stash clear*)",
45
+ "Bash(git checkout --*)",
46
+ "Bash(git restore *)",
47
+ "Bash(git clean -fd*)",
48
+ "Bash(rm -rf*)",
49
+ "Bash(dd *)",
50
+ "Bash(git commit*)"
51
+ ]
52
+ },
53
+ "hooks": {
54
+ "PreToolUse": [
55
+ {
56
+ "matcher": "Bash|Read|Write|Edit|MultiEdit|Grep|Agent",
57
+ "hooks": [
58
+ {
59
+ "type": "command",
60
+ "command": "node .claude/hooks/guard-tool.cjs",
61
+ "timeout": 10,
62
+ "statusMessage": "Harness 安全守护"
63
+ }
64
+ ]
65
+ }
66
+ ],
67
+ "Stop": [
68
+ {
69
+ "matcher": ".*",
70
+ "hooks": [
71
+ {
72
+ "type": "command",
73
+ "command": "node .claude/hooks/quality-gate.cjs stop",
74
+ "timeout": 300,
75
+ "statusMessage": "运行 harness 质量门禁"
76
+ }
77
+ ]
78
+ },
79
+ {
80
+ "matcher": ".*",
81
+ "hooks": [
82
+ {
83
+ "type": "agent",
84
+ "prompt": "你是强制 AI harness 代码审查子 agent。审查前先运行 `git diff --name-only` 查看本次改动了哪些文件。若任一改动文件匹配 `.claude/**`、`.agents/**`、`.husky/**`、`scripts/verify-skills.mjs`、`scripts/sync-harness-docs.mjs`、`scripts/check-project-structure.mjs`、`scripts/*.test.mjs`、`skills-lock.json`、`package.json`、`CLAUDE.md`、`AGENTS.md`、`GEMINI.md`、`CONTRIBUTING.md`、`docs/ai-harness.md`、`docs/harness-quick-reference.md`、`docs/delivery-template.md`、`docs/review-checklist.md` 或 `docs/verification.md`,就读取 `.claude/agents/harness-reviewer.md` 并严格按其规则审查;否则读取 `.claude/agents/code-reviewer.md` 并严格按其规则审查。不要编辑任何文件。只返回 JSON:{\"ok\":true|false,\"reason\":\"HARNESS_REVIEW_RESULT: PASS|FAIL\\n简短总结。\"}。并提醒用户:Claude 审查不能替代人工最终复核。",
85
+ "timeout": 300,
86
+ "statusMessage": "运行强制代码审查"
87
+ }
88
+ ]
89
+ }
90
+ ],
91
+ "SubagentStop": [
92
+ {
93
+ "matcher": ".*",
94
+ "hooks": [
95
+ {
96
+ "type": "command",
97
+ "command": "node .claude/hooks/notify.cjs subagent-stop",
98
+ "timeout": 20,
99
+ "statusMessage": "发送审查完成通知"
100
+ }
101
+ ]
102
+ }
103
+ ],
104
+ "Notification": [
105
+ {
106
+ "matcher": ".*",
107
+ "hooks": [
108
+ {
109
+ "type": "command",
110
+ "command": "node .claude/hooks/notify.cjs notification",
111
+ "timeout": 20,
112
+ "statusMessage": "发送系统通知"
113
+ }
114
+ ]
115
+ }
116
+ ]
117
+ },
118
+ "enabledPlugins": {
119
+ "context7@claude-plugins-official": true,
120
+ "superpowers@claude-plugins-official": true
121
+ },
122
+ "disableBypassPermissionsMode": "disable"
123
+ }
@@ -0,0 +1,143 @@
1
+ ---
2
+ name: find-skills
3
+ description: Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.
4
+ ---
5
+
6
+ # Find Skills
7
+
8
+ This skill helps you discover and install skills from the open agent skills ecosystem.
9
+
10
+ ## When to Use This Skill
11
+
12
+ Use this skill when the user:
13
+
14
+ - Asks "how do I do X" where X might be a common task with an existing skill
15
+ - Says "find a skill for X" or "is there a skill for X"
16
+ - Asks "can you do X" where X is a specialized capability
17
+ - Expresses interest in extending agent capabilities
18
+ - Wants to search for tools, templates, or workflows
19
+ - Mentions they wish they had help with a specific domain (design, testing, deployment, etc.)
20
+
21
+ ## What is the Skills CLI?
22
+
23
+ The Skills CLI (`npx skills`) is the package manager for the open agent skills ecosystem. Skills are modular packages that extend agent capabilities with specialized knowledge, workflows, and tools.
24
+
25
+ **Key commands:**
26
+
27
+ - `npx skills find [query]` - Search for skills interactively or by keyword
28
+ - `npx skills add <package>` - Install a skill from GitHub or other sources
29
+ - `npx skills check` - Check for skill updates
30
+ - `npx skills update` - Update all installed skills
31
+
32
+ **Browse skills at:** https://skills.sh/
33
+
34
+ ## How to Help Users Find Skills
35
+
36
+ ### Step 1: Understand What They Need
37
+
38
+ When a user asks for help with something, identify:
39
+
40
+ 1. The domain (e.g., React, testing, design, deployment)
41
+ 2. The specific task (e.g., writing tests, creating animations, reviewing PRs)
42
+ 3. Whether this is a common enough task that a skill likely exists
43
+
44
+ ### Step 2: Check the Leaderboard First
45
+
46
+ Before running a CLI search, check the [skills.sh leaderboard](https://skills.sh/) to see if a well-known skill already exists for the domain. The leaderboard ranks skills by total installs, surfacing the most popular and battle-tested options.
47
+
48
+ For example, top skills for web development include:
49
+
50
+ - `vercel-labs/agent-skills` — React, Next.js, web design (100K+ installs each)
51
+ - `anthropics/skills` — Frontend design, document processing (100K+ installs)
52
+
53
+ ### Step 3: Search for Skills
54
+
55
+ If the leaderboard doesn't cover the user's need, run the find command:
56
+
57
+ ```bash
58
+ npx skills find [query]
59
+ ```
60
+
61
+ For example:
62
+
63
+ - User asks "how do I make my React app faster?" → `npx skills find react performance`
64
+ - User asks "can you help me with PR reviews?" → `npx skills find pr review`
65
+ - User asks "I need to create a changelog" → `npx skills find changelog`
66
+
67
+ ### Step 4: Verify Quality Before Recommending
68
+
69
+ **Do not recommend a skill based solely on search results.** Always verify:
70
+
71
+ 1. **Install count** — Prefer skills with 1K+ installs. Be cautious with anything under 100.
72
+ 2. **Source reputation** — Official sources (`vercel-labs`, `anthropics`, `microsoft`) are more trustworthy than unknown authors.
73
+ 3. **GitHub stars** — Check the source repository. A skill from a repo with <100 stars should be treated with skepticism.
74
+
75
+ ### Step 5: Present Options to the User
76
+
77
+ When you find relevant skills, present them to the user with:
78
+
79
+ 1. The skill name and what it does
80
+ 2. The install count and source
81
+ 3. The install command they can run
82
+ 4. A link to learn more at skills.sh
83
+
84
+ Example response:
85
+
86
+ ```
87
+ I found a skill that might help! The "react-best-practices" skill provides
88
+ React and Next.js performance optimization guidelines from Vercel Engineering.
89
+ (185K installs)
90
+
91
+ To install it:
92
+ npx skills add vercel-labs/agent-skills@react-best-practices
93
+
94
+ Learn more: https://skills.sh/vercel-labs/agent-skills/react-best-practices
95
+ ```
96
+
97
+ ### Step 6: Offer to Install
98
+
99
+ If the user wants to proceed, you can install the skill for them:
100
+
101
+ ```bash
102
+ npx skills add <owner/repo@skill> -g -y
103
+ ```
104
+
105
+ The `-g` flag installs globally (user-level) and `-y` skips confirmation prompts.
106
+
107
+ ## Common Skill Categories
108
+
109
+ When searching, consider these common categories:
110
+
111
+ | Category | Example Queries |
112
+ | --------------- | ---------------------------------------- |
113
+ | Web Development | react, nextjs, typescript, css, tailwind |
114
+ | Testing | testing, jest, playwright, e2e |
115
+ | DevOps | deploy, docker, kubernetes, ci-cd |
116
+ | Documentation | docs, readme, changelog, api-docs |
117
+ | Code Quality | review, lint, refactor, best-practices |
118
+ | Design | ui, ux, design-system, accessibility |
119
+ | Productivity | workflow, automation, git |
120
+
121
+ ## Tips for Effective Searches
122
+
123
+ 1. **Use specific keywords**: "react testing" is better than just "testing"
124
+ 2. **Try alternative terms**: If "deploy" doesn't work, try "deployment" or "ci-cd"
125
+ 3. **Check popular sources**: Many skills come from `vercel-labs/agent-skills` or `ComposioHQ/awesome-claude-skills`
126
+
127
+ ## When No Skills Are Found
128
+
129
+ If no relevant skills exist:
130
+
131
+ 1. Acknowledge that no existing skill was found
132
+ 2. Offer to help with the task directly using your general capabilities
133
+ 3. Suggest the user could create their own skill with `npx skills init`
134
+
135
+ Example:
136
+
137
+ ```
138
+ I searched for skills related to "xyz" but didn't find any matches.
139
+ I can still help you with this task directly! Would you like me to proceed?
140
+
141
+ If this is something you do often, you could create your own skill:
142
+ npx skills init my-xyz-skill
143
+ ```
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 hyf0, SerKo <https://github.com/serkodev>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.