@deepstorm/cli 0.10.2 → 0.11.1

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 (124) hide show
  1. package/README.md +8 -8
  2. package/dist/build-registry.js +11 -5
  3. package/dist/cli.js +1256 -634
  4. package/dist/mcp/code-hosting/github.json +14 -1
  5. package/dist/mcp/docs-reference/context7.json +1 -10
  6. package/dist/mcp-skills/deepstorm-mcp-feishu-wiki-read/SKILL.md +8 -5
  7. package/dist/mcp-skills/deepstorm-mcp-feishu-wiki-write/SKILL.md +10 -8
  8. package/dist/mcp-skills/deepstorm-mcp-figma-read/SKILL.md +21 -20
  9. package/dist/mcp-skills/deepstorm-mcp-github-read/SKILL.md +17 -17
  10. package/dist/mcp-skills/deepstorm-mcp-github-write/SKILL.md +20 -20
  11. package/dist/mcp-skills/deepstorm-mcp-jira-read/SKILL.md +8 -8
  12. package/dist/mcp-skills/deepstorm-mcp-jira-write/SKILL.md +13 -12
  13. package/dist/mcp-skills/deepstorm-mcp-playwright-read/SKILL.md +10 -10
  14. package/dist/registry.json +10 -0
  15. package/dist/skills/atoll-ops/SKILL.md +4 -0
  16. package/dist/skills/reef-commit/SKILL.md +9 -5
  17. package/dist/skills/reef-commit/scripts/branch-check.mjs +5 -11
  18. package/dist/skills/reef-commit/scripts/check-openspec-status.mjs +6 -12
  19. package/dist/skills/reef-commit/scripts/collect-git-context.mjs +13 -11
  20. package/dist/skills/reef-gen-backend/variants/java/steps.md +7 -7
  21. package/dist/skills/reef-gen-backend/variants/nodejs/steps.md +7 -7
  22. package/dist/skills/reef-gen-backend/variants/python/steps.md +7 -7
  23. package/dist/skills/reef-gen-frontend/variants/angular/steps.md +5 -5
  24. package/dist/skills/reef-gen-frontend/variants/react/steps.md +6 -6
  25. package/dist/skills/reef-gen-frontend/variants/vue/steps.md +6 -6
  26. package/dist/skills/reef-harden/EXAMPLES.md +12 -10
  27. package/dist/skills/reef-harden/SKILL.md +6 -0
  28. package/dist/skills/reef-harden/scripts/find-change-dir.mjs +13 -13
  29. package/dist/skills/reef-pr/SKILL.md +7 -0
  30. package/dist/skills/reef-pr/scripts/create-pr.mjs +31 -29
  31. package/dist/skills/reef-scope/SKILL.md +6 -6
  32. package/dist/skills/reef-start/references/jira-start-subagent.md +7 -7
  33. package/dist/skills/reef-start/references/risk-routing-card.md +28 -25
  34. package/dist/skills/reef-start/references/stage-4-implementation.md +33 -21
  35. package/dist/skills/reef-start/references/superpowers-gate.md +9 -9
  36. package/dist/skills/reef-style-backend/fragments/java/ai/spring-ai/examples/structured-output.md +2 -2
  37. package/dist/skills/reef-style-backend/fragments/java/ai/spring-ai/quick-reference.md +11 -0
  38. package/dist/skills/reef-style-backend/fragments/java/api-spec/jackson-polymorphism.md +36 -40
  39. package/dist/skills/reef-style-backend/fragments/java/api-spec/quick-reference.md +11 -10
  40. package/dist/skills/reef-style-backend/fragments/java/db-migration/liquibase/examples/database-migration.md +7 -7
  41. package/dist/skills/reef-style-backend/fragments/java/dependency-management/quick-reference.md +24 -21
  42. package/dist/skills/reef-style-backend/fragments/java/exception-handling/examples/error-code-enum.md +7 -7
  43. package/dist/skills/reef-style-backend/fragments/java/exception-handling/quick-reference.md +10 -8
  44. package/dist/skills/reef-style-backend/fragments/java/framework/spring-boot/examples/dto-mapper.md +2 -2
  45. package/dist/skills/reef-style-backend/fragments/java/framework/spring-boot/examples/service-entity.md +5 -5
  46. package/dist/skills/reef-style-backend/fragments/java/framework/spring-boot/examples/testing.md +1 -0
  47. package/dist/skills/reef-style-backend/fragments/java/framework/spring-boot/quick-reference.md +12 -12
  48. package/dist/skills/reef-style-backend/fragments/java/orm/hibernate/quick-reference.md +13 -12
  49. package/dist/skills/reef-style-backend/fragments/java/security-redlines/quick-reference.md +11 -9
  50. package/dist/skills/reef-style-backend/fragments/java/test/data-jpa-test/quick-reference.md +7 -7
  51. package/dist/skills/reef-style-backend/fragments/java/test/junit5/quick-reference.md +6 -6
  52. package/dist/skills/reef-style-backend/fragments/java/test/spring-mvc-test/quick-reference.md +8 -8
  53. package/dist/skills/reef-style-backend/fragments/java/test/spring-service-test/quick-reference.md +8 -7
  54. package/dist/skills/reef-style-backend/fragments/nodejs/eslint-config.json +1 -4
  55. package/dist/skills/reef-style-backend/fragments/nodejs/nestjs-structure.md +9 -9
  56. package/dist/skills/reef-style-backend/fragments/python/alembic-migration/quick-reference.md +2 -1
  57. package/dist/skills/reef-style-backend/fragments/python/api-spec/quick-reference.md +10 -10
  58. package/dist/skills/reef-style-backend/fragments/python/dependency-management/quick-reference.md +24 -22
  59. package/dist/skills/reef-style-backend/fragments/python/exception-handling/quick-reference.md +10 -9
  60. package/dist/skills/reef-style-backend/fragments/python/fastapi-quick-reference/quick-reference.md +3 -0
  61. package/dist/skills/reef-style-backend/fragments/python/langchain/quick-reference.md +10 -7
  62. package/dist/skills/reef-style-backend/fragments/python/pytest-testing/quick-reference.md +2 -0
  63. package/dist/skills/reef-style-backend/fragments/python/ruff-mypy-toolchain/quick-reference.md +2 -0
  64. package/dist/skills/reef-style-backend/fragments/python/security-redlines/quick-reference.md +11 -9
  65. package/dist/skills/reef-style-backend/fragments/python/sqlalchemy-orm/quick-reference.md +3 -0
  66. package/dist/skills/reef-style-backend/variants/java/examples/code-wrapping.md +3 -4
  67. package/dist/skills/reef-style-backend/variants/java/quick-reference.md +31 -29
  68. package/dist/skills/reef-style-backend/variants/nodejs/examples/module-example.md +2 -8
  69. package/dist/skills/reef-style-backend/variants/nodejs/quick-reference.md +35 -36
  70. package/dist/skills/reef-style-backend/variants/python/quick-reference.md +32 -31
  71. package/dist/skills/reef-style-frontend/fragments/css/tailwind/quick-reference.md +9 -7
  72. package/dist/skills/reef-style-frontend/fragments/test/vitest/examples/testing.md +9 -4
  73. package/dist/skills/reef-style-frontend/fragments/test/vitest/quick-reference.md +4 -4
  74. package/dist/skills/reef-style-frontend/fragments/test/vitest-react/examples/testing.md +135 -140
  75. package/dist/skills/reef-style-frontend/fragments/test/vitest-react/quick-reference.md +32 -32
  76. package/dist/skills/reef-style-frontend/fragments/test/vitest-vue/examples/testing.md +161 -162
  77. package/dist/skills/reef-style-frontend/fragments/test/vitest-vue/quick-reference.md +42 -42
  78. package/dist/skills/reef-style-frontend/fragments/ts-config/strict/quick-reference.md +16 -10
  79. package/dist/skills/reef-style-frontend/fragments/ui-lib/antd/examples/ui-components.md +72 -87
  80. package/dist/skills/reef-style-frontend/fragments/ui-lib/antd/quick-reference.md +14 -10
  81. package/dist/skills/reef-style-frontend/fragments/ui-lib/antd-vue/examples/ui-components.md +93 -111
  82. package/dist/skills/reef-style-frontend/fragments/ui-lib/antd-vue/quick-reference.md +29 -33
  83. package/dist/skills/reef-style-frontend/fragments/ui-lib/primeng/examples/ui-components.md +14 -23
  84. package/dist/skills/reef-style-frontend/variants/angular/examples/code-wrapping.md +15 -17
  85. package/dist/skills/reef-style-frontend/variants/angular/examples/component-types-pipes.md +22 -5
  86. package/dist/skills/reef-style-frontend/variants/angular/examples/entity-types.md +52 -22
  87. package/dist/skills/reef-style-frontend/variants/angular/examples/forms-layer.md +17 -20
  88. package/dist/skills/reef-style-frontend/variants/angular/examples/service-routing.md +8 -11
  89. package/dist/skills/reef-style-frontend/variants/angular/quick-reference.md +27 -27
  90. package/dist/skills/reef-style-frontend/variants/react/examples/code-wrapping.md +14 -27
  91. package/dist/skills/reef-style-frontend/variants/react/examples/component-types-pipes.md +45 -52
  92. package/dist/skills/reef-style-frontend/variants/react/examples/entity-types.md +44 -44
  93. package/dist/skills/reef-style-frontend/variants/react/examples/forms-layer.md +56 -85
  94. package/dist/skills/reef-style-frontend/variants/react/examples/service-routing.md +114 -88
  95. package/dist/skills/reef-style-frontend/variants/react/quick-reference.md +48 -42
  96. package/dist/skills/reef-style-frontend/variants/vue/examples/code-wrapping.md +24 -43
  97. package/dist/skills/reef-style-frontend/variants/vue/examples/component-types-pipes.md +48 -49
  98. package/dist/skills/reef-style-frontend/variants/vue/examples/entity-types.md +45 -45
  99. package/dist/skills/reef-style-frontend/variants/vue/examples/forms-layer.md +64 -68
  100. package/dist/skills/reef-style-frontend/variants/vue/examples/service-routing.md +85 -84
  101. package/dist/skills/reef-style-frontend/variants/vue/quick-reference.md +46 -51
  102. package/dist/skills/reef-testcase/SKILL.md +19 -19
  103. package/dist/skills/reef-testcase/references/coverage-dimensions.md +8 -0
  104. package/dist/skills/reef-testcase/references/test-case-template.md +16 -16
  105. package/dist/skills/sweep-explore/SKILL.md +824 -0
  106. package/dist/skills/sweep-explore/references/explore-flow-template.md +61 -0
  107. package/dist/skills/sweep-init/SKILL.md +4 -0
  108. package/dist/skills/sweep-init/scripts/flow-selector.mjs +6 -11
  109. package/dist/skills/sweep-init/scripts/init-project.mjs +68 -51
  110. package/dist/skills/sweep-plan/references/test-flow-template.md +12 -6
  111. package/dist/skills/sweep-record/SKILL.md +358 -0
  112. package/dist/skills/sweep-run/SKILL.md +59 -50
  113. package/dist/skills/sweep-run/scripts/env-manager.mjs +4 -5
  114. package/dist/skills/sweep-run/scripts/flow-parser.mjs +7 -6
  115. package/dist/skills/sweep-run/scripts/flow-selector.mjs +4 -15
  116. package/dist/skills/sweep-run/scripts/generate-report.mjs +1 -2
  117. package/dist/skills/sweep-run/scripts/mcp-manager.mjs +107 -14
  118. package/dist/skills/sweep-run/scripts/spec-compiler.mjs +19 -9
  119. package/dist/skills/tide-discuss/references/checklists.md +32 -32
  120. package/dist/skills/tide-discuss/references/data-format.md +85 -77
  121. package/dist/skills/tide-discuss/references/prd-template.md +21 -19
  122. package/dist/skills/tide-discuss/references/publish-flow.md +30 -11
  123. package/dist/skills/tide-discuss/references/role-prompts.md +5 -5
  124. package/package.json +5 -3
@@ -4,82 +4,86 @@
4
4
 
5
5
  ```typescript
6
6
  // composables/useUsers.ts
7
- import { ref, computed, watch } from 'vue'
8
- import type { User, PageResponse } from '@/shared/types/user'
7
+ import { ref, computed, watch } from 'vue';
8
+ import type { User, PageResponse } from '@/shared/types/user';
9
9
 
10
10
  interface UseUsersOptions {
11
- page?: number
12
- size?: number
13
- search?: string
14
- role?: string
11
+ page?: number;
12
+ size?: number;
13
+ search?: string;
14
+ role?: string;
15
15
  }
16
16
 
17
17
  // 使用 URLSearchParams 构建查询参数
18
18
  function buildQuery(params: UseUsersOptions): string {
19
- const searchParams = new URLSearchParams()
20
- if (params.page !== undefined) searchParams.set('page', String(params.page))
21
- if (params.size !== undefined) searchParams.set('size', String(params.size))
22
- if (params.search) searchParams.set('search', params.search)
23
- if (params.role) searchParams.set('role', params.role)
24
- const qs = searchParams.toString()
25
- return qs ? `?${qs}` : ''
19
+ const searchParams = new URLSearchParams();
20
+ if (params.page !== undefined) searchParams.set('page', String(params.page));
21
+ if (params.size !== undefined) searchParams.set('size', String(params.size));
22
+ if (params.search) searchParams.set('search', params.search);
23
+ if (params.role) searchParams.set('role', params.role);
24
+ const qs = searchParams.toString();
25
+ return qs ? `?${qs}` : '';
26
26
  }
27
27
 
28
28
  export function useUsers(options: UseUsersOptions = {}) {
29
- const users = ref<User[]>([])
30
- const total = ref(0)
31
- const loading = ref(true)
32
- const error = ref<Error | null>(null)
33
- const refreshKey = ref(0)
29
+ const users = ref<User[]>([]);
30
+ const total = ref(0);
31
+ const loading = ref(true);
32
+ const error = ref<Error | null>(null);
33
+ const refreshKey = ref(0);
34
34
 
35
35
  async function fetchUsers() {
36
- loading.value = true
37
- error.value = null
36
+ loading.value = true;
37
+ error.value = null;
38
38
 
39
39
  try {
40
- const res = await fetch(`/api/v1/users${buildQuery(options)}`)
41
- if (!res.ok) throw new Error(`HTTP ${res.status}`)
42
- const data: PageResponse<User> = await res.json()
43
- users.value = data.content
44
- total.value = data.totalElements
40
+ const res = await fetch(`/api/v1/users${buildQuery(options)}`);
41
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
42
+ const data: PageResponse<User> = await res.json();
43
+ users.value = data.content;
44
+ total.value = data.totalElements;
45
45
  } catch (e) {
46
- error.value = e as Error
46
+ error.value = e as Error;
47
47
  } finally {
48
- loading.value = false
48
+ loading.value = false;
49
49
  }
50
50
  }
51
51
 
52
- watch([() => options.page, () => options.size, () => options.search, () => options.role, refreshKey], () => {
53
- fetchUsers()
54
- }, { immediate: true })
52
+ watch(
53
+ [() => options.page, () => options.size, () => options.search, () => options.role, refreshKey],
54
+ () => {
55
+ fetchUsers();
56
+ },
57
+ { immediate: true },
58
+ );
55
59
 
56
60
  function refresh() {
57
- refreshKey.value++
61
+ refreshKey.value++;
58
62
  }
59
63
 
60
- return { users, total, loading, error, refresh }
64
+ return { users, total, loading, error, refresh };
61
65
  }
62
66
 
63
67
  // 写操作组合式函数
64
68
  export function useCreateUser() {
65
- const loading = ref(false)
69
+ const loading = ref(false);
66
70
 
67
71
  async function create(data: CreateUserRequest): Promise<User> {
68
- loading.value = true
72
+ loading.value = true;
69
73
  try {
70
74
  const res = await fetch('/api/v1/users', {
71
75
  method: 'POST',
72
76
  headers: { 'Content-Type': 'application/json' },
73
77
  body: JSON.stringify(data),
74
- })
75
- if (!res.ok) throw new Error(`HTTP ${res.status}`)
76
- return await res.json()
78
+ });
79
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
80
+ return await res.json();
77
81
  } finally {
78
- loading.value = false
82
+ loading.value = false;
79
83
  }
80
84
  }
81
85
 
82
- return { create, loading }
86
+ return { create, loading };
83
87
  }
84
88
  ```
85
89
 
@@ -87,54 +91,54 @@ export function useCreateUser() {
87
91
 
88
92
  ```typescript
89
93
  // stores/auth.ts
90
- import { defineStore } from 'pinia'
91
- import { ref, computed } from 'vue'
92
- import type { User } from '@/shared/types/user'
94
+ import { defineStore } from 'pinia';
95
+ import { ref, computed } from 'vue';
96
+ import type { User } from '@/shared/types/user';
93
97
 
94
98
  export const useAuthStore = defineStore('auth', () => {
95
99
  // state
96
- const user = ref<User | null>(null)
97
- const token = ref<string | null>(localStorage.getItem('auth_token'))
98
- const loading = ref(false)
100
+ const user = ref<User | null>(null);
101
+ const token = ref<string | null>(localStorage.getItem('auth_token'));
102
+ const loading = ref(false);
99
103
 
100
104
  // getters
101
- const isAuthenticated = computed(() => !!token.value)
102
- const isAdmin = computed(() => user.value?.role === 'ADMIN')
105
+ const isAuthenticated = computed(() => !!token.value);
106
+ const isAdmin = computed(() => user.value?.role === 'ADMIN');
103
107
 
104
108
  // actions
105
109
  async function login(username: string, password: string) {
106
- loading.value = true
110
+ loading.value = true;
107
111
  try {
108
112
  const res = await fetch('/api/v1/auth/login', {
109
113
  method: 'POST',
110
114
  headers: { 'Content-Type': 'application/json' },
111
115
  body: JSON.stringify({ username, password }),
112
- })
113
- const data = await res.json()
114
- token.value = data.token
115
- user.value = data.user
116
- localStorage.setItem('auth_token', data.token)
116
+ });
117
+ const data = await res.json();
118
+ token.value = data.token;
119
+ user.value = data.user;
120
+ localStorage.setItem('auth_token', data.token);
117
121
  } finally {
118
- loading.value = false
122
+ loading.value = false;
119
123
  }
120
124
  }
121
125
 
122
126
  function logout() {
123
- user.value = null
124
- token.value = null
125
- localStorage.removeItem('auth_token')
127
+ user.value = null;
128
+ token.value = null;
129
+ localStorage.removeItem('auth_token');
126
130
  }
127
131
 
128
- return { user, token, loading, isAuthenticated, isAdmin, login, logout }
129
- })
132
+ return { user, token, loading, isAuthenticated, isAdmin, login, logout };
133
+ });
130
134
  ```
131
135
 
132
136
  ## 路由配置
133
137
 
134
138
  ```typescript
135
139
  // router/index.ts
136
- import { createRouter, createWebHistory } from 'vue-router'
137
- import { useAuthStore } from '@/stores/auth'
140
+ import { createRouter, createWebHistory } from 'vue-router';
141
+ import { useAuthStore } from '@/stores/auth';
138
142
 
139
143
  const router = createRouter({
140
144
  history: createWebHistory(import.meta.env.BASE_URL),
@@ -174,17 +178,17 @@ const router = createRouter({
174
178
  component: () => import('@/views/NotFound.vue'),
175
179
  },
176
180
  ],
177
- })
181
+ });
178
182
 
179
183
  // 导航守卫
180
184
  router.beforeEach((to, from) => {
181
- const auth = useAuthStore()
185
+ const auth = useAuthStore();
182
186
  if (to.meta.requiresAuth && !auth.isAuthenticated) {
183
- return { name: 'login', query: { redirect: to.fullPath } }
187
+ return { name: 'login', query: { redirect: to.fullPath } };
184
188
  }
185
- })
189
+ });
186
190
 
187
- export default router
191
+ export default router;
188
192
  ```
189
193
 
190
194
  ## 主应用入口
@@ -192,19 +196,16 @@ export default router
192
196
  ```vue
193
197
  <!-- App.vue -->
194
198
  <script setup lang="ts">
195
- import { ConfigProvider } from 'ant-design-vue'
196
- import zhCN from 'ant-design-vue/es/locale/zh_CN'
197
- import dayjs from 'dayjs'
198
- import 'dayjs/locale/zh-cn'
199
+ import { ConfigProvider } from 'ant-design-vue';
200
+ import zhCN from 'ant-design-vue/es/locale/zh_CN';
201
+ import dayjs from 'dayjs';
202
+ import 'dayjs/locale/zh-cn';
199
203
 
200
- dayjs.locale('zh-cn')
204
+ dayjs.locale('zh-cn');
201
205
  </script>
202
206
 
203
207
  <template>
204
- <ConfigProvider
205
- :locale="zhCN"
206
- :theme="{ token: { colorPrimary: '#1677ff', borderRadius: 6 } }"
207
- >
208
+ <ConfigProvider :locale="zhCN" :theme="{ token: { colorPrimary: '#1677ff', borderRadius: 6 } }">
208
209
  <RouterView />
209
210
  </ConfigProvider>
210
211
  </template>
@@ -212,13 +213,13 @@ dayjs.locale('zh-cn')
212
213
 
213
214
  ```typescript
214
215
  // main.ts
215
- import { createApp } from 'vue'
216
- import { createPinia } from 'pinia'
217
- import App from './App.vue'
218
- import router from './router'
219
-
220
- const app = createApp(App)
221
- app.use(createPinia())
222
- app.use(router)
223
- app.mount('#app')
216
+ import { createApp } from 'vue';
217
+ import { createPinia } from 'pinia';
218
+ import App from './App.vue';
219
+ import router from './router';
220
+
221
+ const app = createApp(App);
222
+ app.use(createPinia());
223
+ app.use(router);
224
+ app.mount('#app');
224
225
  ```
@@ -6,51 +6,46 @@
6
6
 
7
7
  ## 速查
8
8
 
9
- | 场景 | 决策 |
10
- | --- | --- |
11
- | 新建组件 | `<script setup lang="ts">` + `defineProps<Props>()` + 组合式 API |
12
- | 新建表单 | Ant Design Vue `<a-form>` + `v-model` + `:rules` 校验 |
13
- | 读数据 | 组合式函数(`useUsers`)封装 fetch/axios |
14
- | 写数据 | 组合式函数 + `ref()` loading/error/data 三态 |
15
- | 组合式函数职责 | 只负责业务逻辑和数据获取,不管理 UI 渲染 |
16
- | 路由 | 动态 `import()` + `createRouter` 懒加载 |
9
+ | 场景 | 决策 |
10
+ | -------------- | ---------------------------------------------------------------- |
11
+ | 新建组件 | `<script setup lang="ts">` + `defineProps<Props>()` + 组合式 API |
12
+ | 新建表单 | Ant Design Vue `<a-form>` + `v-model` + `:rules` 校验 |
13
+ | 读数据 | 组合式函数(`useUsers`)封装 fetch/axios |
14
+ | 写数据 | 组合式函数 + `ref()` loading/error/data 三态 |
15
+ | 组合式函数职责 | 只负责业务逻辑和数据获取,不管理 UI 渲染 |
16
+ | 路由 | 动态 `import()` + `createRouter` 懒加载 |
17
17
 
18
18
  ## 新建组件
19
19
 
20
20
  ```vue
21
21
  <script setup lang="ts">
22
22
  interface UserTableProps {
23
- users: User[]
24
- loading?: boolean
25
- onSelect?: (user: User) => void
23
+ users: User[];
24
+ loading?: boolean;
25
+ onSelect?: (user: User) => void;
26
26
  }
27
27
 
28
- const props = defineProps<UserTableProps>()
28
+ const props = defineProps<UserTableProps>();
29
29
  const emit = defineEmits<{
30
- select: [user: User]
31
- }>()
30
+ select: [user: User];
31
+ }>();
32
32
 
33
33
  function handleClick(user: User) {
34
- emit('select', user)
34
+ emit('select', user);
35
35
  }
36
36
  </script>
37
37
 
38
38
  <template>
39
- <a-table
40
- :data-source="props.users"
41
- :loading="props.loading"
42
- row-key="id"
43
- @click="handleClick"
44
- />
39
+ <a-table :data-source="props.users" :loading="props.loading" row-key="id" @click="handleClick" />
45
40
  </template>
46
41
  ```
47
42
 
48
- | 规则 | 要求 |
49
- | --- | --- |
50
- | `<script setup lang="ts">` | 禁止 Options API,使用组合式 API |
51
- | `defineProps<Type>()` | 使用泛型语法定义 Props,`type` 定义联合类型 |
52
- | 状态提升 | 组件间共享状态提升到最近公共父组件,或使用 Pinia |
53
- | 默认导出 | 页面级组件使用 `export default`(路由组件),通用组件使用具名导出 |
43
+ | 规则 | 要求 |
44
+ | -------------------------- | ----------------------------------------------------------------- |
45
+ | `<script setup lang="ts">` | 禁止 Options API,使用组合式 API |
46
+ | `defineProps<Type>()` | 使用泛型语法定义 Props,`type` 定义联合类型 |
47
+ | 状态提升 | 组件间共享状态提升到最近公共父组件,或使用 Pinia |
48
+ | 默认导出 | 页面级组件使用 `export default`(路由组件),通用组件使用具名导出 |
54
49
 
55
50
  ## 组合式 API 规则
56
51
 
@@ -61,22 +56,22 @@ function handleClick(user: User) {
61
56
 
62
57
  ```vue
63
58
  <script setup lang="ts">
64
- import { ref, onMounted, onUnmounted } from 'vue'
59
+ import { ref, onMounted, onUnmounted } from 'vue';
65
60
 
66
- const users = ref<User[]>([])
67
- const loading = ref(true)
68
- const error = ref<Error | null>(null)
61
+ const users = ref<User[]>([]);
62
+ const loading = ref(true);
63
+ const error = ref<Error | null>(null);
69
64
 
70
65
  onMounted(async () => {
71
66
  try {
72
- const res = await fetch('/api/v1/users')
73
- users.value = await res.json()
67
+ const res = await fetch('/api/v1/users');
68
+ users.value = await res.json();
74
69
  } catch (e) {
75
- error.value = e as Error
70
+ error.value = e as Error;
76
71
  } finally {
77
- loading.value = false
72
+ loading.value = false;
78
73
  }
79
- })
74
+ });
80
75
  </script>
81
76
  ```
82
77
 
@@ -105,7 +100,7 @@ onMounted(async () => {
105
100
 
106
101
  ```vue
107
102
  <script setup lang="ts">
108
- import { createRouter, createWebHistory } from 'vue-router'
103
+ import { createRouter, createWebHistory } from 'vue-router';
109
104
 
110
105
  const router = createRouter({
111
106
  history: createWebHistory(import.meta.env.BASE_URL),
@@ -121,7 +116,7 @@ const router = createRouter({
121
116
  component: () => import('@/views/UserDetail.vue'),
122
117
  },
123
118
  ],
124
- })
119
+ });
125
120
  </script>
126
121
  ```
127
122
 
@@ -135,19 +130,19 @@ const router = createRouter({
135
130
 
136
131
  ## 注释规则
137
132
 
138
- | 文件类型 | 注释要求 |
139
- |---------|---------|
140
- | **类型定义** | 复杂类型加行内注释说明字段含义 |
141
- | **组合式函数** | 简要说明该函数的功能和返回值 |
142
- | **组件** | 关键组件加注释说明用途;复杂逻辑行内注释 |
133
+ | 文件类型 | 注释要求 |
134
+ | -------------- | ---------------------------------------- |
135
+ | **类型定义** | 复杂类型加行内注释说明字段含义 |
136
+ | **组合式函数** | 简要说明该函数的功能和返回值 |
137
+ | **组件** | 关键组件加注释说明用途;复杂逻辑行内注释 |
143
138
 
144
139
  ## 常见坑
145
140
 
146
- | 场景 | 问题 | 正确做法 |
147
- |------|------|---------|
148
- | `reactive` 整体赋值 | 直接 `state = newVal` 破坏响应式 | 使用 `Object.assign()` 或改用 `ref()` |
149
- | `v-for` 缺少 `:key` | 列表渲染异常/性能下降 | 绑定唯一 `:key="item.id"` |
150
- | 响应式解构丢失 | `const { name } = reactive(obj)` 解构后 `name` 失去响应性 | 使用 `toRefs()` 或保持 `obj.name` 访问 |
151
- | 生命周期清理遗漏 | 事件监听/定时器在组件卸载后仍然运行 | `onUnmounted` 中清理 |
152
- | `watch` 旧值误用 | 以为 `watch` 第一个回调参数是新值 | 签名是 `watch(source, (newVal, oldVal) => ...)` |
153
- | Ant Design Vue 手动导入遗漏 | `message` / `Modal` 等程序化 API 未导入 | 从 `ant-design-vue` 包手动导入 |
141
+ | 场景 | 问题 | 正确做法 |
142
+ | --------------------------- | --------------------------------------------------------- | ----------------------------------------------- |
143
+ | `reactive` 整体赋值 | 直接 `state = newVal` 破坏响应式 | 使用 `Object.assign()` 或改用 `ref()` |
144
+ | `v-for` 缺少 `:key` | 列表渲染异常/性能下降 | 绑定唯一 `:key="item.id"` |
145
+ | 响应式解构丢失 | `const { name } = reactive(obj)` 解构后 `name` 失去响应性 | 使用 `toRefs()` 或保持 `obj.name` 访问 |
146
+ | 生命周期清理遗漏 | 事件监听/定时器在组件卸载后仍然运行 | `onUnmounted` 中清理 |
147
+ | `watch` 旧值误用 | 以为 `watch` 第一个回调参数是新值 | 签名是 `watch(source, (newVal, oldVal) => ...)` |
148
+ | Ant Design Vue 手动导入遗漏 | `message` / `Modal` 等程序化 API 未导入 | 从 `ant-design-vue` 包手动导入 |
@@ -29,11 +29,11 @@ flowchart LR
29
29
 
30
30
  ## 使用方式
31
31
 
32
- | 方式 | 说明 | 示例 |
33
- |------|------|------|
34
- | **提供功能描述**(推荐) | 直接描述功能,自动解析生成 | "帮我生成注册功能的测试用例:邮箱+密码+验证码注册" |
35
- | **Jira + PRD** | 附上 PRD 链接获取更全面覆盖 | "Jira LC-1234:用户注册。PRD 说支持国际手机号,验证码 5 分钟有效" |
36
- | **Jira ID 参考** | 仅提 ID,引导补充描述 | "为 LC-1234 生成测试用例"(需用户补充描述) |
32
+ | 方式 | 说明 | 示例 |
33
+ | ------------------------ | --------------------------- | ----------------------------------------------------------------- |
34
+ | **提供功能描述**(推荐) | 直接描述功能,自动解析生成 | "帮我生成注册功能的测试用例:邮箱+密码+验证码注册" |
35
+ | **Jira + PRD** | 附上 PRD 链接获取更全面覆盖 | "Jira LC-1234:用户注册。PRD 说支持国际手机号,验证码 5 分钟有效" |
36
+ | **Jira ID 参考** | 仅提 ID,引导补充描述 | "为 LC-1234 生成测试用例"(需用户补充描述) |
37
37
 
38
38
  ---
39
39
 
@@ -59,12 +59,12 @@ flowchart LR
59
59
 
60
60
  基于收集到的输入,按以下四个维度分析测试覆盖:
61
61
 
62
- | 维度 | 分析目标 | 来源 |
63
- |------|---------|------|
64
- | **正常流程** | 用户按预期操作的完整成功路径 | Jira 功能描述中的主要用户场景 |
65
- | **边界条件** | 输入值、状态或数据的极限条件 | 规格中的限制、约束、最大/最小值 |
66
- | **异常场景** | 出错的路径、故障、非预期操作 | 错误处理、网络超时、权限不足、数据不存在 |
67
- | **验收标准验证** | 逐条验证定义的验收条件 | PRD/Jira 中的 AC 列表 |
62
+ | 维度 | 分析目标 | 来源 |
63
+ | ---------------- | ---------------------------- | ---------------------------------------- |
64
+ | **正常流程** | 用户按预期操作的完整成功路径 | Jira 功能描述中的主要用户场景 |
65
+ | **边界条件** | 输入值、状态或数据的极限条件 | 规格中的限制、约束、最大/最小值 |
66
+ | **异常场景** | 出错的路径、故障、非预期操作 | 错误处理、网络超时、权限不足、数据不存在 |
67
+ | **验收标准验证** | 逐条验证定义的验收条件 | PRD/Jira 中的 AC 列表 |
68
68
 
69
69
  **覆盖度要求:** 至少覆盖三个维度(必须包含"正常流程"和"验收标准")。
70
70
 
@@ -76,14 +76,14 @@ flowchart LR
76
76
 
77
77
  每个测试用例包含以下字段:
78
78
 
79
- | 字段 | 必填 | 说明 |
80
- |------|------|------|
81
- | `ID` | 是 | 唯一标识,格式 `TC-{feature}-{seq}` |
82
- | `类型` | 是 | 正常流程 / 边界条件 / 异常场景 / 验收标准 |
83
- | `前置条件` | 是 | 测试所需的前置状态或数据 |
84
- | `测试步骤` | 是 | 清晰的操作步骤描述 |
85
- | `预期结果` | 是 | 期望的行为或输出 |
86
- | `关联验收标准` | 否 | 对应 PRD 或 Jira 中的验收标准编号 |
79
+ | 字段 | 必填 | 说明 |
80
+ | -------------- | ---- | ----------------------------------------- |
81
+ | `ID` | 是 | 唯一标识,格式 `TC-{feature}-{seq}` |
82
+ | `类型` | 是 | 正常流程 / 边界条件 / 异常场景 / 验收标准 |
83
+ | `前置条件` | 是 | 测试所需的前置状态或数据 |
84
+ | `测试步骤` | 是 | 清晰的操作步骤描述 |
85
+ | `预期结果` | 是 | 期望的行为或输出 |
86
+ | `关联验收标准` | 否 | 对应 PRD 或 Jira 中的验收标准编号 |
87
87
 
88
88
  #### 3.2 输出结构
89
89
 
@@ -11,11 +11,13 @@
11
11
  覆盖功能的预期使用路径,即 "Happy Path"。
12
12
 
13
13
  **关键问题:**
14
+
14
15
  - 用户按预期操作时会发生什么?
15
16
  - 最常见的成功路径是什么?
16
17
  - 输入有效数据时系统如何响应?
17
18
 
18
19
  **示例:**
20
+
19
21
  ```
20
22
  ID: TC-login-001 | 类型: 正常流程
21
23
  前置条件: 用户已注册且账号正常
@@ -30,6 +32,7 @@ ID: TC-login-001 | 类型: 正常流程
30
32
  覆盖输入值、状态或数据在极限条件下的行为。
31
33
 
32
34
  **关键问题:**
35
+
33
36
  - 输入允许的最大值/最小值?
34
37
  - 字符串为空或达到最大长度?
35
38
  - 列表为空的边界?
@@ -37,6 +40,7 @@ ID: TC-login-001 | 类型: 正常流程
37
40
  - 时间边界(过去/未来/并发)?
38
41
 
39
42
  **示例:**
43
+
40
44
  ```
41
45
  ID: TC-login-002 | 类型: 边界条件
42
46
  前置条件: 用户已注册
@@ -51,6 +55,7 @@ ID: TC-login-002 | 类型: 边界条件
51
55
  覆盖可能出错的路径、系统故障或非预期操作。
52
56
 
53
57
  **关键问题:**
58
+
54
59
  - 网络中断或超时?
55
60
  - 数据不存在或已被删除?
56
61
  - 权限不足?
@@ -59,6 +64,7 @@ ID: TC-login-002 | 类型: 边界条件
59
64
  - 第三方服务不可用?
60
65
 
61
66
  **示例:**
67
+
62
68
  ```
63
69
  ID: TC-login-003 | 类型: 异常场景
64
70
  前置条件: 用户已注册但账号被锁定
@@ -73,11 +79,13 @@ ID: TC-login-003 | 类型: 异常场景
73
79
  逐条验证 PRD 或 Jira 中定义的验收标准(Acceptance Criteria)是否满足。
74
80
 
75
81
  **关键问题:**
82
+
76
83
  - Jira Issue 中列出了哪些 AC?
77
84
  - PRD 中有哪些功能验收点?
78
85
  - 每条 AC 是否有对应的测试用例验证?
79
86
 
80
87
  **示例:**
88
+
81
89
  ```
82
90
  ID: TC-login-004 | 类型: 验收标准
83
91
  前置条件: 用户已注册
@@ -4,28 +4,28 @@
4
4
 
5
5
  每个测试用例包含以下字段:
6
6
 
7
- | 字段 | 必填 | 说明 |
8
- |------|------|------|
9
- | `ID` | 是 | 唯一标识,格式 `TC-{feature}-{seq}` |
10
- | `类型` | 是 | 正常流程 / 边界条件 / 异常场景 / 验收标准 |
11
- | `前置条件` | 是 | 测试所需的前置状态或数据 |
12
- | `测试步骤` | 是 | 清晰的操作步骤描述 |
13
- | `预期结果` | 是 | 期望的行为或输出 |
14
- | `关联验收标准` | 否 | 对应 PRD 或 Jira 中的验收标准编号 |
7
+ | 字段 | 必填 | 说明 |
8
+ | -------------- | ---- | ----------------------------------------- |
9
+ | `ID` | 是 | 唯一标识,格式 `TC-{feature}-{seq}` |
10
+ | `类型` | 是 | 正常流程 / 边界条件 / 异常场景 / 验收标准 |
11
+ | `前置条件` | 是 | 测试所需的前置状态或数据 |
12
+ | `测试步骤` | 是 | 清晰的操作步骤描述 |
13
+ | `预期结果` | 是 | 期望的行为或输出 |
14
+ | `关联验收标准` | 否 | 对应 PRD 或 Jira 中的验收标准编号 |
15
15
 
16
16
  ## 模板示例
17
17
 
18
18
  ```markdown
19
19
  ### TC-{feature}-001
20
20
 
21
- | 字段 | 内容 |
22
- |------|------|
23
- | **ID** | TC-{feature}-001 |
24
- | **类型** | 正常流程 |
25
- | **前置条件** | {测试所需的前置状态或数据} |
26
- | **测试步骤** | 1. {步骤一}<br>2. {步骤二}<br>3. {步骤三} |
27
- | **预期结果** | {期望的行为或输出} |
28
- | **关联验收标准** | AC-{id}(可选) |
21
+ | 字段 | 内容 |
22
+ | ---------------- | ----------------------------------------- |
23
+ | **ID** | TC-{feature}-001 |
24
+ | **类型** | 正常流程 |
25
+ | **前置条件** | {测试所需的前置状态或数据} |
26
+ | **测试步骤** | 1. {步骤一}<br>2. {步骤二}<br>3. {步骤三} |
27
+ | **预期结果** | {期望的行为或输出} |
28
+ | **关联验收标准** | AC-{id}(可选) |
29
29
  ```
30
30
 
31
31
  ## 输出结构