sumulige-claude 1.0.11 → 1.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.
@@ -1,20 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * TODO Manager - AI 自动任务管理系统
3
+ * TODO Manager - AI 自动任务管理系统 (v2.0)
4
4
  *
5
5
  * 功能:
6
- * - 自动追踪项目任务
7
- * - 生成可点击的任务索引
6
+ * - 支持 Research → Develop → Test 生命周期
7
+ * - 自动任务状态流转
8
+ * - 智能任务创建建议
8
9
  * - 维护任务状态流转
9
- * - 静默运行,不打扰工作流
10
10
  *
11
- * 目录结构:
12
- * development/todos/
13
- * ├── INDEX.md # 任务总览
14
- * ├── active/ # 进行中的任务
15
- * ├── completed/ # 已完成的任务
16
- * ├── backlog/ # 待办任务
17
- * └── archived/ # 已归档任务
11
+ * 生命周期:
12
+ * Research (研究) → Develop (开发) → Test (测试) → Done (完成)
18
13
  */
19
14
 
20
15
  const fs = require('fs');
@@ -25,55 +20,81 @@ const TODOS_DIR = path.join(PROJECT_DIR, 'development', 'todos');
25
20
  const INDEX_FILE = path.join(TODOS_DIR, 'INDEX.md');
26
21
  const STATE_FILE = path.join(TODOS_DIR, '.state.json');
27
22
 
28
- // 任务状态
29
- const STATUS = {
23
+ // 任务类型和状态
24
+ const TASK_TYPES = {
25
+ RESEARCH: 'research',
26
+ DEVELOP: 'develop',
27
+ TEST: 'test'
28
+ };
29
+
30
+ const TASK_STAGES = {
30
31
  ACTIVE: 'active',
31
32
  COMPLETED: 'completed',
32
33
  BACKLOG: 'backlog',
33
34
  ARCHIVED: 'archived'
34
35
  };
35
36
 
37
+ // 图标映射
38
+ const ICONS = {
39
+ research: '📊',
40
+ develop: '💻',
41
+ test: '🧪'
42
+ };
43
+
36
44
  // 确保目录存在
37
45
  function ensureDirectories() {
38
- [TODOS_DIR, STATUS.ACTIVE, STATUS.COMPLETED, STATUS.BACKLOG, STATUS.ARCHIVED].forEach(dir => {
39
- const fullPath = dir.startsWith('/') ? dir : path.join(TODOS_DIR, dir);
40
- try { fs.mkdirSync(fullPath, { recursive: true }); } catch (e) {}
46
+ const dirs = [TODOS_DIR];
47
+
48
+ // 为每个阶段创建类型子目录
49
+ for (const stage of Object.values(TASK_STAGES)) {
50
+ dirs.push(path.join(TODOS_DIR, stage));
51
+ for (const type of Object.values(TASK_TYPES)) {
52
+ dirs.push(path.join(TODOS_DIR, stage, type));
53
+ }
54
+ }
55
+
56
+ dirs.forEach(dir => {
57
+ try { fs.mkdirSync(dir, { recursive: true }); } catch (e) {}
41
58
  });
42
59
  }
43
60
 
44
61
  // 扫描任务文件
45
62
  function scanTasks() {
46
63
  const tasks = {
47
- active: [],
48
- completed: [],
49
- backlog: [],
50
- archived: []
64
+ active: { research: [], develop: [], test: [] },
65
+ completed: { research: [], develop: [], test: [] },
66
+ backlog: { research: [], develop: [], test: [] },
67
+ archived: { research: [], develop: [], test: [] }
51
68
  };
52
69
 
53
- for (const [key, dirName] of Object.entries(STATUS)) {
54
- const dir = path.join(TODOS_DIR, dirName);
55
- if (!fs.existsSync(dir)) continue;
56
-
57
- const files = fs.readdirSync(dir)
58
- .filter(f => f.endsWith('.md') && f !== '_README.md');
59
-
60
- tasks[dirName] = files.map(f => {
61
- const filePath = path.join(dir, f);
62
- const content = fs.readFileSync(filePath, 'utf-8');
63
- const titleMatch = content.match(/^#\s+(.+)$/m);
64
- const statusMatch = content.match(/\*\*状态\*\*:\s*([\u{1F300}-\u{1F9FF}\s]+)/u);
65
- const priorityMatch = content.match(/\*\*优先级\*\*:\s*(P[0-3])/);
66
- const branchMatch = content.match(/\*\*分支\*\*:\s*`([^`]+)`/);
67
-
68
- return {
69
- file: f,
70
- title: titleMatch ? titleMatch[1] : path.basename(f, '.md'),
71
- status: statusMatch ? statusMatch[1].trim() : '🚧 进行中',
72
- priority: priorityMatch ? priorityMatch[1] : 'P2',
73
- branch: branchMatch ? branchMatch[1] : null,
74
- path: `${dirName}/${f}`
75
- };
76
- });
70
+ for (const [stage, types] of Object.entries(tasks)) {
71
+ for (const [type, _] of Object.entries(types)) {
72
+ const dir = path.join(TODOS_DIR, stage, type);
73
+ if (!fs.existsSync(dir)) continue;
74
+
75
+ const files = fs.readdirSync(dir)
76
+ .filter(f => f.endsWith('.md') && f !== '_README.md');
77
+
78
+ tasks[stage][type] = files.map(f => {
79
+ const filePath = path.join(dir, f);
80
+ const content = fs.readFileSync(filePath, 'utf-8');
81
+ const titleMatch = content.match(/^#\s+(.+)$/m);
82
+ const statusMatch = content.match(/\*\*状态\*\*:\s*([✅🚧📋])/);
83
+ const priorityMatch = content.match(/\*\*优先级\*\*:\s*(P[0-3])/);
84
+ const typeMatch = content.match(/\*\*类型\*\*:\s*([📊💻🧪])\s*(\w+)/);
85
+
86
+ return {
87
+ file: f,
88
+ title: titleMatch ? titleMatch[1] : path.basename(f, '.md'),
89
+ status: statusMatch ? statusMatch[1] : '🚧',
90
+ priority: priorityMatch ? priorityMatch[1] : 'P2',
91
+ taskType: typeMatch ? typeMatch[1] : type,
92
+ icon: typeMatch ? typeMatch[2] : ICONS[type] || '📄',
93
+ path: `${stage}/${type}/${f}`,
94
+ stage: stage
95
+ };
96
+ });
97
+ }
77
98
  }
78
99
 
79
100
  return tasks;
@@ -83,138 +104,211 @@ function scanTasks() {
83
104
  function generateIndex(tasks) {
84
105
  const now = new Date().toISOString().split('T')[0];
85
106
 
107
+ // 计算总数
108
+ const activeCount = tasks.active.research.length + tasks.active.develop.length + tasks.active.test.length;
109
+ const completedCount = tasks.completed.research.length + tasks.completed.develop.length + tasks.completed.test.length;
110
+ const backlogCount = tasks.backlog.research.length + tasks.backlog.develop.length + tasks.backlog.test.length;
111
+
86
112
  let md = `# 项目任务追踪系统
87
113
 
88
- > 本目录由 AI 自动维护,记录项目开发任务和进度
114
+ > **统一管理**: 研究 → 开发 → 测试
115
+ > **最后更新**: ${now}
116
+
117
+ @version: 2.0.0
118
+
119
+ ---
120
+
121
+ ## 📊 项目进度
122
+
123
+ | 阶段 | 进度 | 状态 |
124
+ |------|------|------|
125
+ | Phase 1: MVP 智能监控 | 80% | 🚧 进行中 |
126
+ | Phase 2: V1.5 动态调整 | 0% | 📋 待规划 |
127
+ | Phase 3: V2.0 AI 教练 | 0% | 📋 待规划 |
128
+
129
+ ---
89
130
 
90
- **最后更新**: ${now}
131
+ ## 🔄 任务生命周期
91
132
 
92
- @version: 1.0.0
133
+ \`\`\`
134
+ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
135
+ │ RESEARCH │ → │ DEVELOP │ → │ TEST │
136
+ │ 📊 研究 │ │ 💻 开发 │ │ 🧪 测试 │
137
+ └─────────────┘ └─────────────┘ └─────────────┘
138
+ \`\`\`
93
139
 
94
- ## 目录结构
140
+ ---
141
+
142
+ ## 📁 目录结构
95
143
 
96
144
  \`\`\`
97
145
  development/todos/
98
146
  ├── INDEX.md # 本文件 - 任务总览
99
- ├── active/ # 进行中的任务 (${tasks.active.length})
100
- ├── completed/ # 已完成的任务 (${tasks.completed.length})
101
- ├── backlog/ # 待规划的任务 (${tasks.backlog.length})
102
- └── archived/ # 已归档的任务 (${tasks.archived.length})
147
+ ├── _templates/ # 任务模板
148
+ ├── active/ # 进行中的任务 (${activeCount})
149
+ ├── research/ # 📊 研究中 (${tasks.active.research.length})
150
+ │ ├── develop/ # 💻 开发中 (${tasks.active.develop.length})
151
+ │ └── test/ # 🧪 测试中 (${tasks.active.test.length})
152
+ ├── completed/ # 已完成的任务 (${completedCount})
153
+ │ ├── research/
154
+ │ ├── develop/
155
+ │ └── test/
156
+ ├── backlog/ # 待规划的任务 (${backlogCount})
157
+ └── archived/ # 已归档的任务
103
158
  \`\`\`
104
159
 
105
- ## 快速跳转
160
+ ---
161
+
162
+ ## 🚧 当前进行中的任务
106
163
 
164
+ ### 📊 研究任务
107
165
  `;
108
166
 
109
- // 进行中的任务
110
- md += `## 🚧 进行中的任务 (${tasks.active.length})\n\n`;
111
- if (tasks.active.length > 0) {
112
- tasks.active.forEach(t => {
113
- md += `- [${t.priority}] [${t.title}](./${t.path}) - ${t.status}${t.branch ? ` \`branch: ${t.branch}\`` : ''}\n`;
167
+ // 研究任务
168
+ if (tasks.active.research.length > 0) {
169
+ tasks.active.research.forEach(t => {
170
+ md += `- [${t.priority}] [${t.title}](./${t.path}) - ${t.status}\n`;
114
171
  });
115
172
  } else {
116
- md += `*暂无进行中的任务*\n`;
173
+ md += `暂无\n`;
117
174
  }
118
- md += `\n`;
119
-
120
- // 最近完成的任务(最多5个)
121
- md += `## 最近完成的任务\n\n`;
122
- const recentCompleted = tasks.completed.slice(0, 5);
123
- if (recentCompleted.length > 0) {
124
- recentCompleted.forEach(t => {
125
- md += `- [${t.title}](./${t.path})\n`;
175
+ md += `\n### 💻 开发任务\n`;
176
+
177
+ // 开发任务
178
+ if (tasks.active.develop.length > 0) {
179
+ tasks.active.develop.forEach(t => {
180
+ md += `- [${t.priority}] [${t.title}](./${t.path}) - ${t.status}\n`;
126
181
  });
127
- if (tasks.completed.length > 5) {
128
- md += `- ...还有 ${tasks.completed.length - 5} 个已完成任务\n`;
129
- }
130
182
  } else {
131
- md += `*暂无已完成的任务*\n`;
183
+ md += `暂无\n`;
132
184
  }
133
- md += `\n`;
185
+ md += `\n### 🧪 测试任务\n`;
134
186
 
135
- // 待办任务
136
- md += `## 📋 待办任务 (${tasks.backlog.length})\n\n`;
137
- if (tasks.backlog.length > 0) {
138
- tasks.backlog.slice(0, 10).forEach(t => {
139
- md += `- [${t.priority}] [${t.title}](./${t.path})\n`;
187
+ // 测试任务
188
+ if (tasks.active.test.length > 0) {
189
+ tasks.active.test.forEach(t => {
190
+ md += `- [${t.priority}] [${t.title}](./${t.path}) - ${t.status}\n`;
191
+ });
192
+ } else {
193
+ md += `暂无\n`;
194
+ }
195
+
196
+ md += `\n---\n\n## ✅ 最近完成的任务\n\n### 💻 开发任务\n`;
197
+
198
+ // 最近完成的开发任务
199
+ if (tasks.completed.develop.length > 0) {
200
+ tasks.completed.develop.slice(0, 5).forEach(t => {
201
+ md += `- [${t.title}](./${t.path}) ${t.status}\n`;
140
202
  });
141
- if (tasks.backlog.length > 10) {
142
- md += `- ...还有 ${tasks.backlog.length - 10} 个待办任务\n`;
143
- }
144
203
  } else {
145
- md += `*暂无待办任务*\n`;
204
+ md += `暂无\n`;
146
205
  }
147
- md += `\n`;
148
-
149
- // 全部目录链接
150
- md += `## 全部目录\n\n`;
151
- md += `- [🚧 所有进行中的任务](./active/) - 当前开发重点\n`;
152
- md += `- [✅ 所有已完成的任务](./completed/) - 完整历史\n`;
153
- md += `- [📋 所有待办任务](./backlog/) - 待规划\n`;
154
- md += `- [📦 所有已归档任务](./archived/) - 历史记录\n`;
155
- md += `\n`;
156
-
157
- // 使用说明
158
- md += `## 使用方式\n\n`;
159
- md += `### 查看任务\n`;
160
- md += `点击上方链接跳转到对应目录,或使用:\n`;
161
- md += `\`\`\`bash\n`;
162
- md += `# 查看进行中的任务\n`;
163
- md += `cat development/todos/active/*.md\n\n`;
164
- md += `# 查看特定任务\n`;
165
- md += `cat development/todos/active/feature-name.md\n`;
206
+
207
+ md += `\n### 🧪 测试任务\n`;
208
+
209
+ // 最近完成的测试任务
210
+ if (tasks.completed.test.length > 0) {
211
+ tasks.completed.test.slice(0, 3).forEach(t => {
212
+ md += `- [${t.title}](./${t.path}) ${t.status}\n`;
213
+ });
214
+ } else {
215
+ md += `暂无\n`;
216
+ }
217
+
218
+ md += `\n---\n\n## 📋 待办任务\n\n`;
219
+ md += `暂无\n`;
220
+
221
+ md += `\n---\n\n## 🎯 使用方式\n\n`;
222
+ md += `### 查看任务\n\`\`\`bash\n`;
223
+ md += `# 按类型查看\n`;
224
+ md += `ls development/todos/active/research/ # 研究任务\n`;
225
+ md += `ls development/todos/active/develop/ # 开发任务\n`;
226
+ md += `ls development/todos/active/test/ # 测试任务\n`;
166
227
  md += `\`\`\`\n\n`;
228
+
167
229
  md += `### 创建新任务\n`;
168
- md += `在 Claude Code 中:\n`;
169
- md += `\`\`\`\n`;
170
- md += `创建一个新任务:实现用户登录功能\n`;
171
- md += `\`\`\`\n\n`;
172
- md += `AI 会自动在 \`active/\` 目录创建对应的任务文件。\n\n`;
173
- md += `### 更新任务状态\n`;
174
- md += `\`\`\`\n`;
175
- md += `将 [任务名] 标记为完成\n`;
176
- md += `\`\`\`\n\n`;
177
- md += `AI 会自动将任务移动到 \`completed/\` 目录。\n\n`;
230
+ md += `在 Claude Code 中:\n\`\`\`\n`;
231
+ md += `创建一个新任务:\n`;
232
+ md += `- 类型:测试\n`;
233
+ md += `- 标题:Dashboard 功能测试\n\`\`\`\n\n`;
178
234
 
179
- md += `---\n\n`;
180
- md += `> **维护说明**: 本系统由 AI 自动维护,请勿手动编辑(除非你知道自己在做什么)\n`;
235
+ md += `### 更新任务状态\n\`\`\`\n`;
236
+ md += `将 [任务名] 标记为完成\n\`\`\`\n\n`;
237
+
238
+ md += `---\n\n> **维护说明**: 本系统由 AI 自动维护\n`;
181
239
 
182
240
  return md;
183
241
  }
184
242
 
243
+ // 加载和保存状态
244
+ function loadState() {
245
+ if (fs.existsSync(STATE_FILE)) {
246
+ try {
247
+ return JSON.parse(fs.readFileSync(STATE_FILE, 'utf-8'));
248
+ } catch (e) {
249
+ return { tasks: {}, transitions: [] };
250
+ }
251
+ }
252
+ return { tasks: {}, transitions: [] };
253
+ }
254
+
255
+ function saveState(state) {
256
+ fs.writeFileSync(STATE_FILE, JSON.stringify(state, null, 2));
257
+ }
258
+
259
+ // 检查是否需要自动流转
260
+ function checkAutoTransition(tasks, state) {
261
+ const suggestions = [];
262
+
263
+ // 检查刚完成的开发任务,建议创建测试任务
264
+ const completedDevelop = tasks.completed.develop.filter(t => {
265
+ const key = `completed_develop_${t.file}`;
266
+ return !state.tasks[key]; // 首次完成
267
+ });
268
+
269
+ completedDevelop.forEach(t => {
270
+ const testTaskName = t.file.replace('.md', '-test.md');
271
+ const testPath = path.join(TODOS_DIR, 'active', 'test', testTaskName);
272
+
273
+ if (!fs.existsSync(testPath)) {
274
+ suggestions.push({
275
+ type: 'create_test',
276
+ message: `💡 建议为 "${t.title}" 创建测试任务`,
277
+ developTask: t,
278
+ testTask: testTaskName,
279
+ template: `_templates/test.md`
280
+ });
281
+ }
282
+
283
+ // 标记已处理
284
+ const key = `completed_develop_${t.file}`;
285
+ state.tasks[key] = { completed: true, notified: true };
286
+ });
287
+
288
+ return { suggestions, state };
289
+ }
290
+
185
291
  // 更新索引
186
292
  function updateIndex() {
187
293
  try {
188
294
  ensureDirectories();
189
295
  const tasks = scanTasks();
190
- const index = generateIndex(tasks);
296
+ const state = loadState();
191
297
 
192
- // 检查是否需要更新 - 比较任务总数
193
- let needsUpdate = true;
194
- if (fs.existsSync(INDEX_FILE)) {
195
- const existing = fs.readFileSync(INDEX_FILE, 'utf-8');
196
- // 从现有索引中提取任务数量
197
- const activeMatch = existing.match(/## 🚧 进行中的任务 \((\d+)\)/);
198
- const completedMatch = existing.match(/## ✅ 最近完成的任务/);
199
- const existingActive = activeMatch ? parseInt(activeMatch[1], 10) : 0;
200
- const newActive = tasks.active.length;
201
-
202
- // 如果活跃任务数量相同且没有完成任务内容变化,则不更新
203
- if (existingActive === newActive && tasks.completed.length === 0) {
204
- // 检查现有索引是否已有完成任务
205
- const hasCompletedInExisting = existing.includes('[completed/') || existing.includes('./completed/');
206
- const hasCompletedNow = tasks.completed.length > 0;
207
- needsUpdate = hasCompletedInExisting !== hasCompletedNow;
208
- }
209
- }
298
+ // 检查自动流转
299
+ const { suggestions, state: newState } = checkAutoTransition(tasks, state);
210
300
 
211
- if (needsUpdate) {
212
- fs.writeFileSync(INDEX_FILE, index);
213
- }
301
+ // 生成索引
302
+ const index = generateIndex(tasks);
303
+ fs.writeFileSync(INDEX_FILE, index);
214
304
 
215
- return { tasks, updated: needsUpdate };
305
+ // 保存状态
306
+ saveState(newState);
307
+
308
+ return { tasks, suggestions, updated: true };
216
309
  } catch (e) {
217
- return { tasks: { active: [], completed: [], backlog: [], archived: [] }, updated: false };
310
+ console.error('[TODO Manager] Error:', e.message);
311
+ return { tasks: { active: { research: [], develop: [], test: [] }, completed: { research: [], develop: [], test: [] } }, suggestions: [], updated: false };
218
312
  }
219
313
  }
220
314
 
@@ -222,13 +316,28 @@ function updateIndex() {
222
316
  function main() {
223
317
  const result = updateIndex();
224
318
 
225
- // 在 AgentStop 或特定事件时输出摘要
319
+ // 输出建议
320
+ if (result.suggestions && result.suggestions.length > 0) {
321
+ console.log('\n📋 [任务流转] 检测到 ' + result.suggestions.length + ' 个自动流转建议:\n');
322
+ result.suggestions.forEach((s, i) => {
323
+ console.log(` ${i + 1}. ${s.message}`);
324
+ });
325
+ console.log('');
326
+ }
327
+
328
+ // 在 AgentStop 时输出摘要
226
329
  const eventType = process.env.CLAUDE_EVENT_TYPE || '';
227
330
  if (eventType === 'AgentStop') {
228
- const { active, completed } = result.tasks;
229
- if (active.length > 0) {
230
- console.log(`\n📋 [任务追踪] ${active.length} 个进行中, ${completed.length} 个已完成`);
231
- console.log(` 查看: development/todos/INDEX.md\n`);
331
+ const active = result.tasks.active;
332
+ const activeTotal = active.research.length + active.develop.length + active.test.length;
333
+ const completed = result.tasks.completed;
334
+ const completedTotal = completed.research.length + completed.develop.length + completed.test.length;
335
+
336
+ if (activeTotal > 0 || completedTotal > 0) {
337
+ console.log(`\n📋 [任务追踪]`);
338
+ console.log(` 进行中: ${activeTotal} 个 (📊 ${active.research.length} | 💻 ${active.develop.length} | 🧪 ${active.test.length})`);
339
+ console.log(` 已完成: ${completedTotal} 个`);
340
+ console.log(` 查看: ${path.relative(PROJECT_DIR, INDEX_FILE)}\n`);
232
341
  }
233
342
  }
234
343
 
@@ -240,6 +349,18 @@ if (require.main === module) {
240
349
  if (process.argv[2] === '--force') {
241
350
  updateIndex();
242
351
  console.log('✅ Task index updated');
352
+ } else if (process.argv[2] === '--suggest') {
353
+ const result = updateIndex();
354
+ if (result.suggestions.length > 0) {
355
+ console.log('\n💡 自动流转建议:\n');
356
+ result.suggestions.forEach((s, i) => {
357
+ console.log(`${i + 1}. ${s.message}`);
358
+ console.log(` 开发任务: ${s.developTask.file}`);
359
+ console.log(` 测试任务: ${s.testTask}`);
360
+ });
361
+ } else {
362
+ console.log('✅ 无待处理的流转建议');
363
+ }
243
364
  } else {
244
365
  main();
245
366
  }
@@ -77,7 +77,17 @@
77
77
  "Bash(pkill:*)",
78
78
  "Bash(pip install:*)",
79
79
  "Bash(timeout:*)",
80
- "Bash(python3:*)"
80
+ "Bash(python3:*)",
81
+ "Bash(npm test:*)",
82
+ "Bash(npx standard-version:*)",
83
+ "Bash(openskills list:*)",
84
+ "Bash(playwright install:*)",
85
+ "Bash(npm run release:minor:*)",
86
+ "Bash(npm init:*)",
87
+ "Bash(git init:*)",
88
+ "Bash(git branch:*)",
89
+ "Bash(gh repo create:*)",
90
+ "Bash(npm view:*)"
81
91
  ]
82
92
  },
83
93
  "hooks": {
@@ -1,28 +1,39 @@
1
- # Api Tester
1
+ ---
2
+ name: api-tester
3
+ description: API testing and HTTP request validation tool for REST/GraphQL endpoints
4
+ see_also:
5
+ - mcp-builder
6
+ - webapp-testing
7
+ ---
2
8
 
3
- > 简短描述这个技能的作用(一句话)
9
+ # API Tester
4
10
 
5
- **版本**: 1.0.0
6
- **作者**: @username
7
- **标签**: [category1, category2]
8
- **难度**: 初级/中级/高级
11
+ > Test and validate REST/GraphQL APIs with automated request/response checking
12
+
13
+ **Version**: 1.0.0
14
+ **Author**: sumulige
15
+ **Tags**: [api, testing, http, rest, graphql]
16
+ **Difficulty**: 中级
9
17
 
10
18
  ---
11
19
 
12
20
  ## 概述
13
21
 
14
- 详细描述这个技能的功能和用途。
22
+ API Tester 是一个用于测试和验证 API 接口的技能。支持 REST 和 GraphQL,可以自动检查响应状态码、数据结构和性能指标。
15
23
 
16
24
  ## 适用场景
17
25
 
18
- - 场景 1
19
- - 场景 2
20
- - 场景 3
26
+ - 测试 REST API 端点
27
+ - 验证 API 响应格式
28
+ - 检查 HTTP 状态码
29
+ - 测试 API 认证
30
+ - 性能基准测试
21
31
 
22
32
  ## 触发关键词
23
33
 
24
34
  ```
25
- keyword1, keyword2, "exact phrase"
35
+ api test, "test the api", "check endpoint", http request, "validate api",
36
+ graphql query, rest api, postman, curl
26
37
  ```
27
38
 
28
39
  ## 使用方法
@@ -30,32 +41,50 @@ keyword1, keyword2, "exact phrase"
30
41
  ### 基础用法
31
42
 
32
43
  ```bash
33
- # 示例命令
34
- your-command-here
44
+ # 测试 GET 请求
45
+ curl -X GET https://api.example.com/users
46
+
47
+ # 测试 POST 请求
48
+ curl -X POST https://api.example.com/users \
49
+ -H "Content-Type: application/json" \
50
+ -d '{"name": "John"}'
35
51
  ```
36
52
 
37
- ### 高级用法
53
+ ### 验证响应
38
54
 
39
- ```yaml
40
- # 配置示例
41
- key: value
55
+ ```javascript
56
+ // 检查状态码
57
+ response.status === 200
58
+
59
+ // 验证数据结构
60
+ response.data.users.forEach(user => {
61
+ assert(user.id, 'User must have id');
62
+ assert(user.email, 'User must have email');
63
+ });
42
64
  ```
43
65
 
44
66
  ## 输出格式
45
67
 
46
- 描述这个技能的输出结果格式。
68
+ ```
69
+ ✅ GET /api/users - 200 OK (142ms)
70
+ ✅ POST /api/users - 201 Created (89ms)
71
+ ❌ GET /api/users/999 - 404 Not Found (45ms)
72
+ ```
47
73
 
48
74
  ## 注意事项
49
75
 
50
- - 注意事项 1
51
- - 注意事项 2
76
+ - 使用测试环境 API,避免生产数据修改
77
+ - 检查 API 速率限制
78
+ - 验证认证 Token 有效性
79
+ - 处理分页响应
52
80
 
53
81
  ## 相关技能
54
82
 
55
- - [related-skill](../related-skill/)
56
- - [another-skill](../another-skill/)
83
+ - [mcp-builder](../mcp-builder/) - MCP 服务器构建
84
+ - [webapp-testing](../webapp-testing/) - Web 应用测试
57
85
 
58
86
  ## 更新日志
59
87
 
60
- ### 1.0.0 (YYYY-MM-DD)
88
+ ### 1.0.0 (2026-01-15)
61
89
  - 初始版本
90
+ - 添加 REST/GraphQL 支持