sumulige-claude 1.3.0 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/.claude/MEMORY.md +9 -0
  2. package/.claude/commands/audit.md +147 -0
  3. package/.claude/commands/gha.md +136 -0
  4. package/.claude/commands/handoff.md +93 -0
  5. package/.claude/handoffs/INDEX.md +21 -0
  6. package/.claude/handoffs/LATEST.md +76 -0
  7. package/.claude/handoffs/handoff_2026-01-22T13-07-04-757Z.md +76 -0
  8. package/.claude/hooks/auto-handoff.cjs +353 -0
  9. package/.claude/hooks/memory-loader.cjs +208 -0
  10. package/.claude/hooks/memory-saver.cjs +268 -0
  11. package/.claude/rag/skill-index.json +15 -34
  12. package/.claude/sessions/session_2026-01-22T13-07-26-625Z.json +23 -0
  13. package/.claude/settings.json +40 -0
  14. package/.claude/settings.local.json +10 -1
  15. package/.claude/skills/api-tester/SKILL.md +61 -0
  16. package/.claude/skills/api-tester/examples/basic.md +3 -0
  17. package/.claude/skills/api-tester/metadata.yaml +30 -0
  18. package/.claude/skills/api-tester/templates/default.md +3 -0
  19. package/.claude/skills/code-reviewer-123/SKILL.md +61 -0
  20. package/.claude/skills/code-reviewer-123/examples/basic.md +3 -0
  21. package/.claude/skills/code-reviewer-123/metadata.yaml +30 -0
  22. package/.claude/skills/code-reviewer-123/templates/default.md +3 -0
  23. package/.claude/skills/my-skill/SKILL.md +61 -0
  24. package/.claude/skills/my-skill/examples/basic.md +3 -0
  25. package/.claude/skills/my-skill/metadata.yaml +30 -0
  26. package/.claude/skills/my-skill/templates/default.md +3 -0
  27. package/.claude/skills/template/SKILL.md +6 -0
  28. package/.claude/skills/template/metadata.yaml +30 -0
  29. package/.claude/skills/test-skill-name/SKILL.md +61 -0
  30. package/.claude/skills/test-skill-name/examples/basic.md +3 -0
  31. package/.claude/skills/test-skill-name/metadata.yaml +30 -0
  32. package/.claude/skills/test-skill-name/templates/default.md +3 -0
  33. package/CHANGELOG.md +45 -0
  34. package/cli.js +4 -0
  35. package/development/todos/.state.json +3 -1
  36. package/lib/commands.js +51 -0
  37. package/lib/permission-audit.js +255 -0
  38. package/package.json +1 -1
@@ -0,0 +1,268 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Memory Saver Hook - SessionEnd Auto-Save System
4
+ *
5
+ * Claude Official Hook: SessionEnd
6
+ * Triggered: Once at the end of each session
7
+ *
8
+ * Features:
9
+ * - Auto-save session summary to MEMORY.md
10
+ * - Sync TODO state changes
11
+ * - Archive session state
12
+ * - Generate session statistics
13
+ *
14
+ * Environment Variables:
15
+ * - CLAUDE_PROJECT_DIR: Project directory path
16
+ * - CLAUDE_SESSION_ID: Unique session identifier
17
+ */
18
+
19
+ const fs = require('fs');
20
+ const path = require('path');
21
+
22
+ const PROJECT_DIR = process.env.CLAUDE_PROJECT_DIR || process.cwd();
23
+ const CLAUDE_DIR = path.join(PROJECT_DIR, '.claude');
24
+ const MEMORY_FILE = path.join(CLAUDE_DIR, 'MEMORY.md');
25
+ const SESSION_STATE_FILE = path.join(CLAUDE_DIR, '.session-state.json');
26
+ const SESSIONS_DIR = path.join(CLAUDE_DIR, 'sessions');
27
+ const STATE_FILE = path.join(PROJECT_DIR, 'development', 'todos', '.state.json');
28
+ const SESSION_ID = process.env.CLAUDE_SESSION_ID || 'unknown';
29
+
30
+ /**
31
+ * Ensure directories exist
32
+ */
33
+ function ensureDirectories() {
34
+ [CLAUDE_DIR, SESSIONS_DIR].forEach(dir => {
35
+ if (!fs.existsSync(dir)) {
36
+ fs.mkdirSync(dir, { recursive: true });
37
+ }
38
+ });
39
+ }
40
+
41
+ /**
42
+ * Load session state from SessionStart
43
+ */
44
+ function loadSessionState() {
45
+ if (!fs.existsSync(SESSION_STATE_FILE)) {
46
+ return null;
47
+ }
48
+
49
+ try {
50
+ return JSON.parse(fs.readFileSync(SESSION_STATE_FILE, 'utf-8'));
51
+ } catch (e) {
52
+ return null;
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Calculate session duration
58
+ */
59
+ function calculateDuration(startTime) {
60
+ if (!startTime) return 'unknown';
61
+
62
+ const start = new Date(startTime);
63
+ const now = new Date();
64
+ const diffMs = now - start;
65
+ const diffMins = Math.floor(diffMs / 60000);
66
+
67
+ if (diffMins < 1) return 'less than 1 minute';
68
+ if (diffMins < 60) return `${diffMins} minutes`;
69
+
70
+ const hours = Math.floor(diffMins / 60);
71
+ const mins = diffMins % 60;
72
+ return `${hours}h ${mins}m`;
73
+ }
74
+
75
+ /**
76
+ * Save session summary to MEMORY.md
77
+ */
78
+ function saveToMemory(sessionState) {
79
+ ensureDirectories();
80
+
81
+ const now = new Date();
82
+ const dateStr = now.toISOString().split('T')[0];
83
+ const duration = sessionState?.session?.startTime
84
+ ? calculateDuration(sessionState.session.startTime)
85
+ : 'unknown';
86
+
87
+ // Generate session entry
88
+ const entry = `### Session ${now.toISOString()}
89
+
90
+ - **Duration**: ${duration}
91
+ - **Project**: ${sessionState?.session?.project || 'unknown'}
92
+ - **Memory entries**: ${sessionState?.memory?.entries || 0}
93
+ - **TODOs**: ${sessionState?.todos?.active || 0} active, ${sessionState?.todos?.completed || 0} completed
94
+
95
+ `;
96
+
97
+ // Read existing memory
98
+ let content = '';
99
+ if (fs.existsSync(MEMORY_FILE)) {
100
+ content = fs.readFileSync(MEMORY_FILE, 'utf-8');
101
+ }
102
+
103
+ // Check if today's section exists
104
+ const todaySection = `## ${dateStr}`;
105
+ if (content.includes(todaySection)) {
106
+ // Append to today's section
107
+ const parts = content.split(todaySection);
108
+ const beforeToday = parts[0];
109
+ const afterHeader = parts[1];
110
+
111
+ // Find next section or end
112
+ const nextSectionMatch = afterHeader.match(/\n## \d{4}-\d{2}-\d{2}/);
113
+ if (nextSectionMatch) {
114
+ const insertPoint = nextSectionMatch.index;
115
+ const todayContent = afterHeader.slice(0, insertPoint);
116
+ const restContent = afterHeader.slice(insertPoint);
117
+ content = beforeToday + todaySection + todayContent + entry + restContent;
118
+ } else {
119
+ content = beforeToday + todaySection + afterHeader + entry;
120
+ }
121
+ } else {
122
+ // Create new day section at the top
123
+ const header = content.startsWith('#') ? '' : '# Memory\n\n<!-- Project memory updated by AI -->\n\n';
124
+ const existingContent = content.replace(/^# Memory\n+(?:<!-- [^>]+ -->\n+)?/, '');
125
+ content = header + `${todaySection}\n\n${entry}` + existingContent;
126
+ }
127
+
128
+ // Keep only last 7 days
129
+ const sections = content.split(/(?=\n## \d{4}-\d{2}-\d{2})/);
130
+ const header = sections[0];
131
+ const daySections = sections.slice(1, 8); // Keep 7 days max
132
+ content = header + daySections.join('');
133
+
134
+ fs.writeFileSync(MEMORY_FILE, content.trim() + '\n');
135
+ }
136
+
137
+ /**
138
+ * Archive session state
139
+ */
140
+ function archiveSession(sessionState) {
141
+ ensureDirectories();
142
+
143
+ const now = new Date();
144
+ const filename = `session_${now.toISOString().replace(/[:.]/g, '-')}.json`;
145
+ const filepath = path.join(SESSIONS_DIR, filename);
146
+
147
+ const archiveData = {
148
+ ...sessionState,
149
+ endTime: now.toISOString(),
150
+ duration: sessionState?.session?.startTime
151
+ ? calculateDuration(sessionState.session.startTime)
152
+ : 'unknown'
153
+ };
154
+
155
+ fs.writeFileSync(filepath, JSON.stringify(archiveData, null, 2));
156
+
157
+ // Clean up old sessions (keep last 20)
158
+ const files = fs.readdirSync(SESSIONS_DIR)
159
+ .filter(f => f.startsWith('session_') && f.endsWith('.json'))
160
+ .sort()
161
+ .reverse();
162
+
163
+ if (files.length > 20) {
164
+ files.slice(20).forEach(f => {
165
+ try {
166
+ fs.unlinkSync(path.join(SESSIONS_DIR, f));
167
+ } catch (e) {
168
+ // Ignore deletion errors
169
+ }
170
+ });
171
+ }
172
+
173
+ return filename;
174
+ }
175
+
176
+ /**
177
+ * Update TODO state sync timestamp
178
+ */
179
+ function syncTodoState() {
180
+ if (!fs.existsSync(STATE_FILE)) {
181
+ return;
182
+ }
183
+
184
+ try {
185
+ const state = JSON.parse(fs.readFileSync(STATE_FILE, 'utf-8'));
186
+ state.lastSynced = new Date().toISOString();
187
+ state.sessionId = SESSION_ID;
188
+ fs.writeFileSync(STATE_FILE, JSON.stringify(state, null, 2));
189
+ } catch (e) {
190
+ // Ignore sync errors
191
+ }
192
+ }
193
+
194
+ /**
195
+ * Clean up session state file
196
+ */
197
+ function cleanupSessionState() {
198
+ if (fs.existsSync(SESSION_STATE_FILE)) {
199
+ try {
200
+ fs.unlinkSync(SESSION_STATE_FILE);
201
+ } catch (e) {
202
+ // Ignore cleanup errors
203
+ }
204
+ }
205
+ }
206
+
207
+ /**
208
+ * Format session end summary
209
+ */
210
+ function formatEndSummary(sessionState, archiveFile) {
211
+ let summary = '';
212
+
213
+ const duration = sessionState?.session?.startTime
214
+ ? calculateDuration(sessionState.session.startTime)
215
+ : 'unknown';
216
+
217
+ summary += `\n✅ Session ended (${duration})\n`;
218
+ summary += `💾 Memory saved to MEMORY.md\n`;
219
+ summary += `📁 Archived: ${archiveFile}\n`;
220
+
221
+ return summary;
222
+ }
223
+
224
+ /**
225
+ * Main execution
226
+ */
227
+ function main() {
228
+ try {
229
+ const sessionState = loadSessionState();
230
+
231
+ if (sessionState) {
232
+ // Save to memory
233
+ saveToMemory(sessionState);
234
+
235
+ // Archive session
236
+ const archiveFile = archiveSession(sessionState);
237
+
238
+ // Sync TODO state
239
+ syncTodoState();
240
+
241
+ // Output summary
242
+ console.log(formatEndSummary(sessionState, archiveFile));
243
+ }
244
+
245
+ // Clean up
246
+ cleanupSessionState();
247
+
248
+ process.exit(0);
249
+ } catch (e) {
250
+ // Silent failure - don't interrupt session end
251
+ cleanupSessionState();
252
+ process.exit(0);
253
+ }
254
+ }
255
+
256
+ // Run
257
+ if (require.main === module) {
258
+ main();
259
+ }
260
+
261
+ module.exports = {
262
+ loadSessionState,
263
+ saveToMemory,
264
+ archiveSession,
265
+ syncTodoState,
266
+ calculateDuration,
267
+ formatEndSummary
268
+ };
@@ -1,7 +1,6 @@
1
1
  {
2
- "version": "2.0.0",
3
- "last_updated": "2026-01-22",
4
- "description": "Optimized skill index - merged 9 skills into 4 core skills",
2
+ "version": "1.0.0",
3
+ "last_updated": "2026-01-11",
5
4
  "skills": [
6
5
  {
7
6
  "name": "frontend-design",
@@ -47,7 +46,7 @@
47
46
  },
48
47
  {
49
48
  "name": "webapp-testing",
50
- "keywords": ["browser", "automation", "screenshot", "puppeteer", "scraping"],
49
+ "keywords": ["test", "testing", "playwright", "browser", "automation", "e2e", "screenshot"],
51
50
  "description": "Toolkit for interacting with and testing local web applications using Playwright",
52
51
  "trigger": "when testing frontend functionality, debugging UI behavior, or capturing browser screenshots"
53
52
  },
@@ -106,32 +105,22 @@
106
105
  "trigger": "for complex artifacts requiring state management, routing, or shadcn/ui components"
107
106
  },
108
107
  {
109
- "name": "quality-guard",
110
- "keywords": ["review", "security", "quality", "lint", "code review", "vulnerability", "owasp", "dead code", "refactor", "cleanup"],
111
- "description": "Code quality guardian - merged: code review + security check + dead code cleanup. Supports --security, --clean modes.",
112
- "trigger": "when reviewing code, checking security, or cleaning up dead code",
113
- "model": "sonnet"
108
+ "name": "dev-browser",
109
+ "keywords": ["browser", "scraping", "automation", "puppet", "playwright", "web"],
110
+ "description": "Browser automation with persistent state for testing and scraping",
111
+ "trigger": "when needing browser automation or web scraping capabilities"
114
112
  },
115
113
  {
116
- "name": "test-master",
117
- "keywords": ["test", "tdd", "e2e", "playwright", "coverage", "unit test", "jest", "vitest"],
118
- "description": "Test master - merged: TDD workflow + E2E testing. Supports --tdd, --e2e, --coverage modes.",
119
- "trigger": "when writing tests, doing TDD, running E2E tests, or checking coverage",
120
- "model": "sonnet"
114
+ "name": "zai-cli",
115
+ "keywords": ["z.ai", "vision", "search", "github", "exploration", "analysis"],
116
+ "description": "Z.AI vision, search, and GitHub exploration CLI tools",
117
+ "trigger": "when needing vision analysis, web search, or GitHub repository exploration"
121
118
  },
122
119
  {
123
- "name": "design-brain",
124
- "keywords": ["plan", "design", "architecture", "system design", "technical decision", "strategy"],
125
- "description": "Design brain - merged: planner + architect. Supports --quick (default) and --deep modes.",
126
- "trigger": "when planning implementation or making architecture decisions",
127
- "model": "opus"
128
- },
129
- {
130
- "name": "quick-fix",
131
- "keywords": ["fix", "build error", "compile error", "type error", "lint error", "tsc"],
132
- "description": "Quick fixer - fast build/lint/type error resolution using haiku model for speed and cost efficiency.",
133
- "trigger": "when build fails, type errors occur, or lint errors need fixing",
134
- "model": "haiku"
120
+ "name": "gastown",
121
+ "keywords": ["gastown", "multi-agent", "orchestrator", "coordination"],
122
+ "description": "Multi-agent orchestrator for complex task coordination",
123
+ "trigger": "when orchestrating multiple agents for complex workflows"
135
124
  }
136
125
  ],
137
126
  "auto_load": {
@@ -142,13 +131,5 @@
142
131
  "fallback": {
143
132
  "enabled": true,
144
133
  "skill": "frontend-design"
145
- },
146
- "model_strategy": {
147
- "description": "Cost-optimized model selection",
148
- "rules": [
149
- { "pattern": "quick-fix", "model": "haiku", "reason": "Fast, simple fixes" },
150
- { "pattern": "quality-guard|test-master", "model": "sonnet", "reason": "Standard tasks" },
151
- { "pattern": "design-brain", "model": "opus", "reason": "Complex architecture only" }
152
- ]
153
134
  }
154
135
  }
@@ -0,0 +1,23 @@
1
+ {
2
+ "session": {
3
+ "id": "unknown",
4
+ "startTime": "2026-01-22T13:06:23.872Z",
5
+ "project": "sumulige-claude",
6
+ "version": "1.3.1"
7
+ },
8
+ "memory": {
9
+ "loaded": true,
10
+ "entries": 4
11
+ },
12
+ "anchors": {
13
+ "loaded": true,
14
+ "modules": 0
15
+ },
16
+ "todos": {
17
+ "loaded": true,
18
+ "active": 0,
19
+ "completed": 0
20
+ },
21
+ "endTime": "2026-01-22T13:07:26.625Z",
22
+ "duration": "1 minutes"
23
+ }
@@ -1,4 +1,44 @@
1
1
  {
2
+ "env": {
3
+ "ENABLE_TOOL_SEARCH": "true",
4
+ "DISABLE_AUTOUPDATER": "1"
5
+ },
6
+ "SessionStart": [
7
+ {
8
+ "matcher": {},
9
+ "hooks": [
10
+ {
11
+ "type": "command",
12
+ "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/memory-loader.cjs",
13
+ "timeout": 2000
14
+ }
15
+ ]
16
+ }
17
+ ],
18
+ "SessionEnd": [
19
+ {
20
+ "matcher": {},
21
+ "hooks": [
22
+ {
23
+ "type": "command",
24
+ "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/memory-saver.cjs",
25
+ "timeout": 3000
26
+ }
27
+ ]
28
+ }
29
+ ],
30
+ "PreCompact": [
31
+ {
32
+ "matcher": {},
33
+ "hooks": [
34
+ {
35
+ "type": "command",
36
+ "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/auto-handoff.cjs",
37
+ "timeout": 5000
38
+ }
39
+ ]
40
+ }
41
+ ],
2
42
  "UserPromptSubmit": [
3
43
  {
4
44
  "matcher": {},
@@ -123,7 +123,16 @@
123
123
  "Bash(/opt/homebrew/Cellar/node/25.3.0/bin/node -e \"const fs=require\\(''fs''\\); let d=''''; process.stdin.on\\(''data'',c=>d+=c\\); process.stdin.on\\(''end'',\\(\\)=>{const j=JSON.parse\\(d\\); console.log\\(''Skills:'', j.skills.length\\); console.log\\(''Model strategy:'', JSON.stringify\\(j.model_strategy, null, 2\\)\\);}\\)\")",
124
124
  "Bash(/opt/homebrew/Cellar/node/25.3.0/bin/npm version 1.3.0 --no-git-tag-version)",
125
125
  "Bash(git tag:*)",
126
- "Bash(/opt/homebrew/Cellar/node/25.3.0/bin/npm publish)"
126
+ "Bash(/opt/homebrew/Cellar/node/25.3.0/bin/npm publish)",
127
+ "Bash(/opt/homebrew/Cellar/node/25.3.0/bin/npm view sumulige-claude version)",
128
+ "Bash(/opt/homebrew/Cellar/node/25.3.0/bin/npm view sumulige-claude versions --json)",
129
+ "Bash(/opt/homebrew/Cellar/node/25.3.0/bin/npx sumulige-claude@1.3.0 sync)",
130
+ "WebFetch(domain:raw.githubusercontent.com)",
131
+ "Bash(/opt/homebrew/Cellar/node/25.3.0/bin/npm version 1.3.1 --no-git-tag-version)",
132
+ "Bash(/opt/homebrew/Cellar/node/25.3.0/bin/node:*)",
133
+ "WebFetch(domain:docs.anthropic.com)",
134
+ "Bash(CLAUDE_PROJECT_DIR=\"/Users/sumulige/Documents/Antigravity/sumulige-claude\" /opt/homebrew/Cellar/node/25.3.0/bin/node:*)",
135
+ "Bash(CLAUDE_PROJECT_DIR=\"/Users/sumulige/Documents/Antigravity/sumulige-claude\" /opt/homebrew/Cellar/node/25.3.0/bin/node .claude/hooks/memory-saver.cjs)"
127
136
  ]
128
137
  },
129
138
  "hooks": {
@@ -0,0 +1,61 @@
1
+ # Api Tester
2
+
3
+ > 简短描述这个技能的作用(一句话)
4
+
5
+ **版本**: 1.0.0
6
+ **作者**: @username
7
+ **标签**: [category1, category2]
8
+ **难度**: 初级/中级/高级
9
+
10
+ ---
11
+
12
+ ## 概述
13
+
14
+ 详细描述这个技能的功能和用途。
15
+
16
+ ## 适用场景
17
+
18
+ - 场景 1
19
+ - 场景 2
20
+ - 场景 3
21
+
22
+ ## 触发关键词
23
+
24
+ ```
25
+ keyword1, keyword2, "exact phrase"
26
+ ```
27
+
28
+ ## 使用方法
29
+
30
+ ### 基础用法
31
+
32
+ ```bash
33
+ # 示例命令
34
+ your-command-here
35
+ ```
36
+
37
+ ### 高级用法
38
+
39
+ ```yaml
40
+ # 配置示例
41
+ key: value
42
+ ```
43
+
44
+ ## 输出格式
45
+
46
+ 描述这个技能的输出结果格式。
47
+
48
+ ## 注意事项
49
+
50
+ - 注意事项 1
51
+ - 注意事项 2
52
+
53
+ ## 相关技能
54
+
55
+ - [related-skill](../related-skill/)
56
+ - [another-skill](../another-skill/)
57
+
58
+ ## 更新日志
59
+
60
+ ### 1.0.0 (YYYY-MM-DD)
61
+ - 初始版本
@@ -0,0 +1,3 @@
1
+ # Basic Example for api-tester
2
+
3
+ Replace this with your actual example.
@@ -0,0 +1,30 @@
1
+ # Skill Metadata
2
+ # 这个文件定义技能的基本信息,用于自动发现和索引
3
+
4
+ name: api-tester
5
+ version: 1.0.0
6
+ author: @username
7
+ description: 简短描述技能功能
8
+
9
+ tags:
10
+ - category1
11
+ - category2
12
+
13
+ triggers:
14
+ - keyword1
15
+ - keyword2
16
+ - "exact phrase"
17
+
18
+ dependencies: [] # 依赖的其他技能
19
+
20
+ difficulty: beginner # beginner | intermediate | advanced
21
+
22
+ # 模板文件
23
+ templates:
24
+ - name: default
25
+ file: templates/default.md
26
+
27
+ # 示例文件
28
+ examples:
29
+ - name: basic
30
+ file: examples/basic.md
@@ -0,0 +1,3 @@
1
+ # Default Template for api-tester
2
+
3
+ Replace this with your actual template.
@@ -0,0 +1,61 @@
1
+ # Code Reviewer 123
2
+
3
+ > 简短描述这个技能的作用(一句话)
4
+
5
+ **版本**: 1.0.0
6
+ **作者**: @username
7
+ **标签**: [category1, category2]
8
+ **难度**: 初级/中级/高级
9
+
10
+ ---
11
+
12
+ ## 概述
13
+
14
+ 详细描述这个技能的功能和用途。
15
+
16
+ ## 适用场景
17
+
18
+ - 场景 1
19
+ - 场景 2
20
+ - 场景 3
21
+
22
+ ## 触发关键词
23
+
24
+ ```
25
+ keyword1, keyword2, "exact phrase"
26
+ ```
27
+
28
+ ## 使用方法
29
+
30
+ ### 基础用法
31
+
32
+ ```bash
33
+ # 示例命令
34
+ your-command-here
35
+ ```
36
+
37
+ ### 高级用法
38
+
39
+ ```yaml
40
+ # 配置示例
41
+ key: value
42
+ ```
43
+
44
+ ## 输出格式
45
+
46
+ 描述这个技能的输出结果格式。
47
+
48
+ ## 注意事项
49
+
50
+ - 注意事项 1
51
+ - 注意事项 2
52
+
53
+ ## 相关技能
54
+
55
+ - [related-skill](../related-skill/)
56
+ - [another-skill](../another-skill/)
57
+
58
+ ## 更新日志
59
+
60
+ ### 1.0.0 (YYYY-MM-DD)
61
+ - 初始版本
@@ -0,0 +1,3 @@
1
+ # Basic Example for code-reviewer-123
2
+
3
+ Replace this with your actual example.
@@ -0,0 +1,30 @@
1
+ # Skill Metadata
2
+ # 这个文件定义技能的基本信息,用于自动发现和索引
3
+
4
+ name: code-reviewer-123
5
+ version: 1.0.0
6
+ author: @username
7
+ description: 简短描述技能功能
8
+
9
+ tags:
10
+ - category1
11
+ - category2
12
+
13
+ triggers:
14
+ - keyword1
15
+ - keyword2
16
+ - "exact phrase"
17
+
18
+ dependencies: [] # 依赖的其他技能
19
+
20
+ difficulty: beginner # beginner | intermediate | advanced
21
+
22
+ # 模板文件
23
+ templates:
24
+ - name: default
25
+ file: templates/default.md
26
+
27
+ # 示例文件
28
+ examples:
29
+ - name: basic
30
+ file: examples/basic.md
@@ -0,0 +1,3 @@
1
+ # Default Template for code-reviewer-123
2
+
3
+ Replace this with your actual template.