sumulige-claude 1.3.3 → 1.4.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.
- package/.claude/.sumulige-claude-version +1 -0
- package/.claude/AGENTS.md +6 -6
- package/.claude/commands/workflow.md +81 -0
- package/.claude/hooks/auto-handoff.cjs +0 -0
- package/.claude/hooks/hook-dispatcher.cjs +304 -0
- package/.claude/hooks/hook-registry.json +73 -0
- package/.claude/hooks/lib/cache.cjs +161 -0
- package/.claude/hooks/lib/fs-utils.cjs +133 -0
- package/.claude/hooks/memory-loader.cjs +0 -0
- package/.claude/hooks/memory-saver.cjs +0 -0
- package/.claude/hooks/rag-skill-loader.cjs +84 -4
- package/.claude/settings.json +8 -82
- package/.claude/settings.local.json +4 -1
- package/CHANGELOG.md +132 -0
- package/README.md +160 -1
- package/config/version-manifest.json +85 -0
- package/lib/commands.js +56 -0
- package/lib/incremental-sync.js +274 -0
- package/lib/version-manifest.js +171 -0
- package/package.json +1 -1
- package/scripts/sync-to-home.sh +108 -0
- package/template/.claude/commands/workflow.md +81 -0
- package/template/.claude/hooks/hook-dispatcher.cjs +304 -0
- package/template/.claude/hooks/hook-registry.json +73 -0
- package/template/.claude/hooks/lib/cache.cjs +161 -0
- package/template/.claude/hooks/lib/fs-utils.cjs +133 -0
- package/template/.claude/hooks/rag-skill-loader.cjs +84 -4
- package/template/.claude/settings.json +8 -82
- package/template/CHANGELOG.md +297 -0
- package/template/README.md +558 -88
- package/.claude/sessions/active-sessions.json +0 -1
- package/.claude/sessions/session_2026-01-22T13-07-26-625Z.json +0 -23
- package/.claude/skills/api-tester/SKILL.md +0 -61
- package/.claude/skills/api-tester/examples/basic.md +0 -3
- package/.claude/skills/api-tester/metadata.yaml +0 -30
- package/.claude/skills/api-tester/templates/default.md +0 -3
- package/.claude/skills/code-reviewer-123/SKILL.md +0 -61
- package/.claude/skills/code-reviewer-123/examples/basic.md +0 -3
- package/.claude/skills/code-reviewer-123/metadata.yaml +0 -30
- package/.claude/skills/code-reviewer-123/templates/default.md +0 -3
- package/.claude/skills/my-skill/SKILL.md +0 -61
- package/.claude/skills/my-skill/examples/basic.md +0 -3
- package/.claude/skills/my-skill/metadata.yaml +0 -30
- package/.claude/skills/my-skill/templates/default.md +0 -3
- package/.claude/skills/test-skill-name/SKILL.md +0 -61
- package/.claude/skills/test-skill-name/examples/basic.md +0 -3
- package/.claude/skills/test-skill-name/metadata.yaml +0 -30
- package/.claude/skills/test-skill-name/templates/default.md +0 -3
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hooks Shared Library - File System Utilities
|
|
3
|
+
*
|
|
4
|
+
* 带缓存的文件操作,减少重复读写
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
// 内存缓存
|
|
11
|
+
const fileCache = new Map();
|
|
12
|
+
const DEFAULT_TTL = 60000; // 1分钟
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* 带缓存的 JSON 文件读取
|
|
16
|
+
*/
|
|
17
|
+
function readJsonCached(filePath, ttl = DEFAULT_TTL) {
|
|
18
|
+
const cached = fileCache.get(filePath);
|
|
19
|
+
const now = Date.now();
|
|
20
|
+
|
|
21
|
+
if (cached && now - cached.time < ttl) {
|
|
22
|
+
return cached.data;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (!fs.existsSync(filePath)) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
const data = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
31
|
+
fileCache.set(filePath, { data, time: now });
|
|
32
|
+
return data;
|
|
33
|
+
} catch (e) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* 写入 JSON 文件并更新缓存
|
|
40
|
+
*/
|
|
41
|
+
function writeJsonCached(filePath, data) {
|
|
42
|
+
try {
|
|
43
|
+
const dir = path.dirname(filePath);
|
|
44
|
+
if (!fs.existsSync(dir)) {
|
|
45
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
46
|
+
}
|
|
47
|
+
fs.writeFileSync(filePath, JSON.stringify(data, null, 2));
|
|
48
|
+
fileCache.set(filePath, { data, time: Date.now() });
|
|
49
|
+
return true;
|
|
50
|
+
} catch (e) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* 带缓存的文本文件读取
|
|
57
|
+
*/
|
|
58
|
+
function readTextCached(filePath, ttl = DEFAULT_TTL) {
|
|
59
|
+
const cached = fileCache.get(filePath);
|
|
60
|
+
const now = Date.now();
|
|
61
|
+
|
|
62
|
+
if (cached && now - cached.time < ttl) {
|
|
63
|
+
return cached.data;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (!fs.existsSync(filePath)) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
const data = fs.readFileSync(filePath, 'utf-8');
|
|
72
|
+
fileCache.set(filePath, { data, time: now });
|
|
73
|
+
return data;
|
|
74
|
+
} catch (e) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* 清除缓存
|
|
81
|
+
*/
|
|
82
|
+
function clearCache(filePath = null) {
|
|
83
|
+
if (filePath) {
|
|
84
|
+
fileCache.delete(filePath);
|
|
85
|
+
} else {
|
|
86
|
+
fileCache.clear();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* 确保目录存在
|
|
92
|
+
*/
|
|
93
|
+
function ensureDir(dirPath) {
|
|
94
|
+
if (!fs.existsSync(dirPath)) {
|
|
95
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* 安全文件操作 - 写入
|
|
101
|
+
*/
|
|
102
|
+
function safeWriteFile(filePath, content) {
|
|
103
|
+
try {
|
|
104
|
+
ensureDir(path.dirname(filePath));
|
|
105
|
+
fs.writeFileSync(filePath, content);
|
|
106
|
+
return true;
|
|
107
|
+
} catch (e) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* 安全文件操作 - 追加
|
|
114
|
+
*/
|
|
115
|
+
function safeAppendFile(filePath, content) {
|
|
116
|
+
try {
|
|
117
|
+
ensureDir(path.dirname(filePath));
|
|
118
|
+
fs.appendFileSync(filePath, content);
|
|
119
|
+
return true;
|
|
120
|
+
} catch (e) {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
module.exports = {
|
|
126
|
+
readJsonCached,
|
|
127
|
+
writeJsonCached,
|
|
128
|
+
readTextCached,
|
|
129
|
+
clearCache,
|
|
130
|
+
ensureDir,
|
|
131
|
+
safeWriteFile,
|
|
132
|
+
safeAppendFile
|
|
133
|
+
};
|
|
File without changes
|
|
File without changes
|
|
@@ -13,6 +13,10 @@ const PROJECT_DIR = process.env.CLAUDE_PROJECT_DIR || process.cwd();
|
|
|
13
13
|
const RAG_DIR = path.join(PROJECT_DIR, '.claude/rag');
|
|
14
14
|
const SKILL_INDEX_FILE = path.join(RAG_DIR, 'skill-index.json');
|
|
15
15
|
const SKILLS_DIR = path.join(PROJECT_DIR, '.claude/skills');
|
|
16
|
+
const CACHE_FILE = path.join(RAG_DIR, '.match-cache.json');
|
|
17
|
+
|
|
18
|
+
// 缓存配置
|
|
19
|
+
const CACHE_TTL = 300000; // 5分钟缓存有效期
|
|
16
20
|
|
|
17
21
|
// 技能关键词匹配权重
|
|
18
22
|
const KEYWORD_WEIGHTS = {
|
|
@@ -21,6 +25,67 @@ const KEYWORD_WEIGHTS = {
|
|
|
21
25
|
related: 0.5 // 相关匹配
|
|
22
26
|
};
|
|
23
27
|
|
|
28
|
+
// 简单哈希函数
|
|
29
|
+
function hashInput(input) {
|
|
30
|
+
let hash = 0;
|
|
31
|
+
for (let i = 0; i < input.length; i++) {
|
|
32
|
+
const char = input.charCodeAt(i);
|
|
33
|
+
hash = ((hash << 5) - hash) + char;
|
|
34
|
+
hash = hash & hash;
|
|
35
|
+
}
|
|
36
|
+
return hash.toString(16);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// 加载缓存
|
|
40
|
+
function loadCache() {
|
|
41
|
+
if (!fs.existsSync(CACHE_FILE)) {
|
|
42
|
+
return {};
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
return JSON.parse(fs.readFileSync(CACHE_FILE, 'utf-8'));
|
|
46
|
+
} catch (e) {
|
|
47
|
+
return {};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// 保存缓存
|
|
52
|
+
function saveCache(cache) {
|
|
53
|
+
try {
|
|
54
|
+
// 清理过期条目
|
|
55
|
+
const now = Date.now();
|
|
56
|
+
const cleaned = {};
|
|
57
|
+
for (const [key, value] of Object.entries(cache)) {
|
|
58
|
+
if (now - value.timestamp < (value.ttl || CACHE_TTL)) {
|
|
59
|
+
cleaned[key] = value;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
fs.writeFileSync(CACHE_FILE, JSON.stringify(cleaned, null, 2));
|
|
63
|
+
} catch (e) {
|
|
64
|
+
// 忽略保存错误
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// 从缓存获取结果
|
|
69
|
+
function getCachedResult(inputHash) {
|
|
70
|
+
const cache = loadCache();
|
|
71
|
+
const cached = cache[inputHash];
|
|
72
|
+
if (cached && Date.now() - cached.timestamp < (cached.ttl || CACHE_TTL)) {
|
|
73
|
+
return cached.result;
|
|
74
|
+
}
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// 保存结果到缓存
|
|
79
|
+
function setCachedResult(inputHash, result) {
|
|
80
|
+
const cache = loadCache();
|
|
81
|
+
cache[inputHash] = {
|
|
82
|
+
result,
|
|
83
|
+
timestamp: Date.now(),
|
|
84
|
+
ttl: CACHE_TTL
|
|
85
|
+
};
|
|
86
|
+
saveCache(cache);
|
|
87
|
+
}
|
|
88
|
+
|
|
24
89
|
// 加载技能索引
|
|
25
90
|
function loadSkillIndex() {
|
|
26
91
|
if (!fs.existsSync(SKILL_INDEX_FILE)) {
|
|
@@ -134,12 +199,27 @@ function main() {
|
|
|
134
199
|
process.exit(0);
|
|
135
200
|
}
|
|
136
201
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
202
|
+
// 检查缓存
|
|
203
|
+
const inputHash = hashInput(toolInput);
|
|
204
|
+
const cachedResult = getCachedResult(inputHash);
|
|
205
|
+
|
|
206
|
+
let matches;
|
|
207
|
+
if (cachedResult) {
|
|
208
|
+
// 使用缓存结果
|
|
209
|
+
matches = cachedResult;
|
|
210
|
+
} else {
|
|
211
|
+
// 分析并匹配
|
|
212
|
+
const analysis = analyzeInput(toolInput);
|
|
213
|
+
if (analysis.keywords.length === 0) {
|
|
214
|
+
process.exit(0);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
matches = matchSkills(analysis, skillIndex);
|
|
218
|
+
|
|
219
|
+
// 缓存结果
|
|
220
|
+
setCachedResult(inputHash, matches);
|
|
140
221
|
}
|
|
141
222
|
|
|
142
|
-
const matches = matchSkills(analysis, skillIndex);
|
|
143
223
|
if (matches.length === 0) {
|
|
144
224
|
process.exit(0);
|
|
145
225
|
}
|
package/.claude/settings.json
CHANGED
|
@@ -45,82 +45,23 @@
|
|
|
45
45
|
"hooks": [
|
|
46
46
|
{
|
|
47
47
|
"type": "command",
|
|
48
|
-
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/
|
|
49
|
-
"timeout":
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
"type": "command",
|
|
53
|
-
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/rag-skill-loader.cjs",
|
|
54
|
-
"timeout": 1000
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
"type": "command",
|
|
58
|
-
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/thinking-silent.cjs",
|
|
59
|
-
"timeout": 1000
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
"type": "command",
|
|
63
|
-
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/multi-session.cjs",
|
|
64
|
-
"timeout": 1000
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
"type": "command",
|
|
68
|
-
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/todo-manager.cjs",
|
|
69
|
-
"timeout": 1000
|
|
70
|
-
}
|
|
71
|
-
]
|
|
72
|
-
}
|
|
73
|
-
],
|
|
74
|
-
"PreToolUse": [
|
|
75
|
-
{
|
|
76
|
-
"matcher": {},
|
|
77
|
-
"hooks": [
|
|
78
|
-
{
|
|
79
|
-
"type": "command",
|
|
80
|
-
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/thinking-silent.cjs",
|
|
81
|
-
"timeout": 1000
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
"type": "command",
|
|
85
|
-
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/multi-session.cjs",
|
|
86
|
-
"timeout": 1000
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
"type": "command",
|
|
90
|
-
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/todo-manager.cjs",
|
|
91
|
-
"timeout": 1000
|
|
48
|
+
"command": "CLAUDE_EVENT_TYPE=UserPromptSubmit node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/hook-dispatcher.cjs",
|
|
49
|
+
"timeout": 3000
|
|
92
50
|
}
|
|
93
51
|
]
|
|
94
52
|
}
|
|
95
53
|
],
|
|
54
|
+
"PreToolUse": [],
|
|
96
55
|
"PostToolUse": [
|
|
97
56
|
{
|
|
98
|
-
"matcher": {
|
|
57
|
+
"matcher": {
|
|
58
|
+
"tool_name": "^(Write|Edit)$"
|
|
59
|
+
},
|
|
99
60
|
"hooks": [
|
|
100
61
|
{
|
|
101
62
|
"type": "command",
|
|
102
63
|
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/code-formatter.cjs",
|
|
103
64
|
"timeout": 5000
|
|
104
|
-
},
|
|
105
|
-
{
|
|
106
|
-
"type": "command",
|
|
107
|
-
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/verify-work.cjs",
|
|
108
|
-
"timeout": 1000
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
"type": "command",
|
|
112
|
-
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/thinking-silent.cjs",
|
|
113
|
-
"timeout": 1000
|
|
114
|
-
},
|
|
115
|
-
{
|
|
116
|
-
"type": "command",
|
|
117
|
-
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/multi-session.cjs",
|
|
118
|
-
"timeout": 1000
|
|
119
|
-
},
|
|
120
|
-
{
|
|
121
|
-
"type": "command",
|
|
122
|
-
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/todo-manager.cjs",
|
|
123
|
-
"timeout": 1000
|
|
124
65
|
}
|
|
125
66
|
]
|
|
126
67
|
}
|
|
@@ -131,23 +72,8 @@
|
|
|
131
72
|
"hooks": [
|
|
132
73
|
{
|
|
133
74
|
"type": "command",
|
|
134
|
-
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/
|
|
135
|
-
"timeout":
|
|
136
|
-
},
|
|
137
|
-
{
|
|
138
|
-
"type": "command",
|
|
139
|
-
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/thinking-silent.cjs",
|
|
140
|
-
"timeout": 1000
|
|
141
|
-
},
|
|
142
|
-
{
|
|
143
|
-
"type": "command",
|
|
144
|
-
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/multi-session.cjs",
|
|
145
|
-
"timeout": 1000
|
|
146
|
-
},
|
|
147
|
-
{
|
|
148
|
-
"type": "command",
|
|
149
|
-
"command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/todo-manager.cjs",
|
|
150
|
-
"timeout": 1000
|
|
75
|
+
"command": "CLAUDE_EVENT_TYPE=AgentStop node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/hook-dispatcher.cjs",
|
|
76
|
+
"timeout": 3000
|
|
151
77
|
}
|
|
152
78
|
]
|
|
153
79
|
}
|
|
@@ -132,7 +132,10 @@
|
|
|
132
132
|
"Bash(/opt/homebrew/Cellar/node/25.3.0/bin/node:*)",
|
|
133
133
|
"WebFetch(domain:docs.anthropic.com)",
|
|
134
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)"
|
|
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)",
|
|
136
|
+
"Bash(du:*)",
|
|
137
|
+
"Bash(wc:*)",
|
|
138
|
+
"Bash(/Users/sumulige/.local/share/fnm/node-versions/v24.3.0/installation/bin/node /Users/sumulige/.local/share/fnm/node-versions/v24.3.0/installation/lib/node_modules/npm/bin/npm-cli.js test)"
|
|
136
139
|
]
|
|
137
140
|
},
|
|
138
141
|
"hooks": {
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,135 @@
|
|
|
1
|
+
## [1.4.1](https://github.com/sumulige/sumulige-claude/compare/v1.4.0...v1.4.1) (2026-01-23)
|
|
2
|
+
|
|
3
|
+
### 💡 契机
|
|
4
|
+
|
|
5
|
+
在将 sumulige-claude 配置同步到多个项目时,发现每次更新后需要手动复制 hooks/skills/templates/commands 到各项目的 `.claude/` 目录,维护成本高且容易出现配置漂移。
|
|
6
|
+
|
|
7
|
+
**问题**:
|
|
8
|
+
- 14 个项目各自维护 `.claude/` 副本
|
|
9
|
+
- 更新 sumulige-claude 后需要逐个同步
|
|
10
|
+
- 项目间配置不一致
|
|
11
|
+
|
|
12
|
+
**解决方案**:利用 Claude Code 的全局配置继承机制,实现单一真相源。
|
|
13
|
+
|
|
14
|
+
### 🏗️ 架构优化:配置分层继承
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
18
|
+
│ sumulige-claude/.claude/ (Git 仓库 - 版本控制) │
|
|
19
|
+
│ hooks/ ─────────────────────────────────────────────────────── │
|
|
20
|
+
│ skills/ ────────────────────────────────────────────────────── │ 符号链接
|
|
21
|
+
│ templates/ ─────────────────────────────────────────────────── │ ↓
|
|
22
|
+
│ commands/ ──────────────────────────────────────────────────── │
|
|
23
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
24
|
+
↓
|
|
25
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
26
|
+
│ ~/.claude/ (运行时) │
|
|
27
|
+
│ hooks/ → symlink to sumulige-claude │
|
|
28
|
+
│ skills/ → symlink to sumulige-claude │
|
|
29
|
+
│ templates/ → symlink to sumulige-claude │
|
|
30
|
+
│ commands/ → symlink to sumulige-claude │
|
|
31
|
+
│ + 运行时数据 (cache, debug, history.jsonl...) │
|
|
32
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
33
|
+
↓ 自动继承
|
|
34
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
35
|
+
│ 项目/.claude/ (仅项目特定内容) │
|
|
36
|
+
│ MEMORY.md, PROJECT_LOG.md, ANCHORS.md, CLAUDE.md │
|
|
37
|
+
│ thinking-routes/, rag/ │
|
|
38
|
+
│ ❌ 不再需要: hooks/, skills/, templates/, commands/ │
|
|
39
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### ✨ 新增
|
|
43
|
+
|
|
44
|
+
- **`scripts/sync-to-home.sh`**: 符号链接同步脚本
|
|
45
|
+
```bash
|
|
46
|
+
./scripts/sync-to-home.sh # 完整同步(链接 + 复制模板)
|
|
47
|
+
./scripts/sync-to-home.sh --link # 仅建立符号链接
|
|
48
|
+
./scripts/sync-to-home.sh --copy # 仅复制模板文件
|
|
49
|
+
./scripts/sync-to-home.sh --status # 查看当前状态
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
- **`.claude/skills/template/`**: Skill 创建模板目录
|
|
53
|
+
|
|
54
|
+
### 🧹 清理
|
|
55
|
+
|
|
56
|
+
| 删除 | 原因 |
|
|
57
|
+
|------|------|
|
|
58
|
+
| `.claude/backup/` | 空目录 |
|
|
59
|
+
| `.claude/verify/` | 空目录 |
|
|
60
|
+
| `.claude/sessions/*.json` | 运行时数据 |
|
|
61
|
+
| 测试 skills (api-tester, my-skill...) | 测试数据 |
|
|
62
|
+
|
|
63
|
+
### 📚 文档更新
|
|
64
|
+
|
|
65
|
+
- **CLAUDE.md**: 更新受保护目录说明,添加全局继承注意事项
|
|
66
|
+
- **MEMORY.md**: 重置为空模板
|
|
67
|
+
|
|
68
|
+
### 🎯 收益
|
|
69
|
+
|
|
70
|
+
| 指标 | 之前 | 之后 |
|
|
71
|
+
|------|------|------|
|
|
72
|
+
| 项目 `.claude/` 文件数 | ~300 个 | ~10 个 |
|
|
73
|
+
| 更新配置需同步项目数 | 14 个 | 0 个 (自动) |
|
|
74
|
+
| 配置漂移风险 | 高 | 零 |
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## [1.4.0](https://github.com/sumulige/sumulige-claude/compare/v1.3.3...v1.4.0) (2026-01-23)
|
|
79
|
+
|
|
80
|
+
### 🚀 架构优化 (Token 成本降低 62%)
|
|
81
|
+
|
|
82
|
+
#### 新增文件 (10 个)
|
|
83
|
+
|
|
84
|
+
| 文件 | 用途 |
|
|
85
|
+
|------|------|
|
|
86
|
+
| `hook-dispatcher.cjs` | 统一 Hook 调度器,支持 debounce 和条件执行 |
|
|
87
|
+
| `hook-registry.json` | Hook 配置注册表 |
|
|
88
|
+
| `hooks/lib/fs-utils.cjs` | 共享文件操作库 |
|
|
89
|
+
| `hooks/lib/cache.cjs` | 缓存工具类 |
|
|
90
|
+
| `version-manifest.json` | 版本兼容性矩阵 |
|
|
91
|
+
| `lib/version-manifest.js` | 版本管理库 |
|
|
92
|
+
| `lib/incremental-sync.js` | 增量同步实现 |
|
|
93
|
+
| `commands/workflow.md` | /workflow 统一命令 |
|
|
94
|
+
|
|
95
|
+
#### 精简内容
|
|
96
|
+
|
|
97
|
+
| 项目 | 之前 | 之后 | 变化 |
|
|
98
|
+
|------|------|------|------|
|
|
99
|
+
| `PreToolUse` hooks | 3 个 | 0 个 | **清空** |
|
|
100
|
+
| `PostToolUse` hooks | 5 个 | 1 个 | **-80%** |
|
|
101
|
+
| `UserPromptSubmit` hooks | 5 个 | 1 个 | **-80%** |
|
|
102
|
+
| `AgentStop` hooks | 4 个 | 1 个 | **-75%** |
|
|
103
|
+
| `settings.json` 行数 | 155 行 | 81 行 | **-48%** |
|
|
104
|
+
|
|
105
|
+
#### 性能提升
|
|
106
|
+
|
|
107
|
+
| 指标 | 优化前 | 优化后 | 提升 |
|
|
108
|
+
|------|--------|--------|------|
|
|
109
|
+
| Hook 调用次数/tool call | 12+ 次 | 2-3 次 | **-75%** |
|
|
110
|
+
| RAG 匹配 | O(n×m) | O(1) 缓存 | **显著** |
|
|
111
|
+
| PostToolUse 开销 | 每次 5 hooks | 仅 Write/Edit | **-90%+** |
|
|
112
|
+
|
|
113
|
+
### ✨ New Features
|
|
114
|
+
|
|
115
|
+
- **`smc sync --incremental`**: 增量同步,只更新变更文件
|
|
116
|
+
- **`/workflow` 命令**: 统一工作流
|
|
117
|
+
- `/workflow check` - 检查更新状态
|
|
118
|
+
- `/workflow pull` - 增量同步
|
|
119
|
+
- `/workflow full` - 一键完整流程
|
|
120
|
+
- **Hook 智能调度**: debounce、runOnce、条件执行
|
|
121
|
+
- **RAG 缓存**: 5 分钟 TTL,避免重复匹配
|
|
122
|
+
- **版本追踪**: 自动检测 breaking changes
|
|
123
|
+
|
|
124
|
+
### 🧪 Tests
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
Test Suites: 15 passed, 15 total
|
|
128
|
+
Tests: 575 passed, 575 total
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
1
133
|
## [1.3.3](https://github.com/sumulige/sumulige-claude/compare/v1.3.2...v1.3.3) (2026-01-22)
|
|
2
134
|
|
|
3
135
|
### ✨ New Features
|
package/README.md
CHANGED
|
@@ -16,7 +16,10 @@
|
|
|
16
16
|
4. [Layer 4: Quick Start / 第四层:快速开始](#layer-4-quick-start--第四层快速开始)
|
|
17
17
|
5. [Layer 5: Commands / 第五层:命令参考](#layer-5-commands--第五层命令参考)
|
|
18
18
|
6. [Layer 6: Advanced / 第六层:高级配置](#layer-6-advanced--第六层高级配置)
|
|
19
|
-
7. [
|
|
19
|
+
7. [Layer 7: Lifecycle Hooks / 第七层:生命周期钩子](#layer-7-lifecycle-hooks--第七层生命周期钩子)
|
|
20
|
+
8. [Layer 8: Data Flow Architecture / 第八层:数据流转架构](#layer-8-data-flow-architecture--第八层数据流转架构)
|
|
21
|
+
9. [Layer 9: Config Inheritance / 第九层:配置分层继承](#layer-9-config-inheritance--第九层配置分层继承)
|
|
22
|
+
10. [Documentation / 文档](#documentation--文档)
|
|
20
23
|
|
|
21
24
|
---
|
|
22
25
|
|
|
@@ -462,6 +465,162 @@ smc template
|
|
|
462
465
|
|
|
463
466
|
---
|
|
464
467
|
|
|
468
|
+
## Layer 8: Data Flow Architecture / 第八层:数据流转架构
|
|
469
|
+
|
|
470
|
+
> v1.4.0: Hook 统一调度 + 智能过滤,Token 成本降低 62%
|
|
471
|
+
|
|
472
|
+
### Hook 调度流程
|
|
473
|
+
|
|
474
|
+
```
|
|
475
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
476
|
+
│ Claude Code 事件触发 │
|
|
477
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
478
|
+
│
|
|
479
|
+
▼
|
|
480
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
481
|
+
│ settings.json 路由 │
|
|
482
|
+
├─────────────────────────────────────────────────────────────────────────┤
|
|
483
|
+
│ SessionStart ──────→ memory-loader.cjs (直接执行) │
|
|
484
|
+
│ SessionEnd ──────→ memory-saver.cjs (直接执行) │
|
|
485
|
+
│ PreCompact ──────→ auto-handoff.cjs (直接执行) │
|
|
486
|
+
│ UserPromptSubmit ───→ hook-dispatcher.cjs │
|
|
487
|
+
│ PreToolUse ──────→ (空,不执行任何 hook) │
|
|
488
|
+
│ PostToolUse ──────→ code-formatter.cjs (仅 Write/Edit 时) │
|
|
489
|
+
│ AgentStop ──────→ hook-dispatcher.cjs │
|
|
490
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
### Hook Dispatcher 内部流程
|
|
494
|
+
|
|
495
|
+
```
|
|
496
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
497
|
+
│ hook-dispatcher.cjs │
|
|
498
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
499
|
+
│
|
|
500
|
+
┌───────────────┼───────────────┐
|
|
501
|
+
▼ ▼ ▼
|
|
502
|
+
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
|
503
|
+
│ 加载 Registry│ │ 加载 State │ │ 获取事件类型 │
|
|
504
|
+
│ hook-registry│ │ .dispatcher │ │CLAUDE_EVENT │
|
|
505
|
+
│ .json │ │ -state.json │ │ _TYPE │
|
|
506
|
+
└─────────────┘ └─────────────┘ └─────────────┘
|
|
507
|
+
│ │ │
|
|
508
|
+
└───────────────┼───────────────┘
|
|
509
|
+
▼
|
|
510
|
+
┌───────────────────────────────┐
|
|
511
|
+
│ 筛选当前事件的 Hooks │
|
|
512
|
+
└───────────────────────────────┘
|
|
513
|
+
│
|
|
514
|
+
▼
|
|
515
|
+
┌───────────────────────────────────────────────┐
|
|
516
|
+
│ 对每个 Hook 检查 │
|
|
517
|
+
├───────────────────────────────────────────────┤
|
|
518
|
+
│ 1. shouldRunDebounce() - 5秒内执行过? → 跳过 │
|
|
519
|
+
│ 2. shouldRunOnce() - 已执行过? → 跳过 │
|
|
520
|
+
│ 3. shouldRunCondition() - 条件不满足? → 跳过 │
|
|
521
|
+
└───────────────────────────────────────────────┘
|
|
522
|
+
│
|
|
523
|
+
▼
|
|
524
|
+
┌───────────────────────────────┐
|
|
525
|
+
│ 执行通过检查的 Hook + 更新状态 │
|
|
526
|
+
└───────────────────────────────┘
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
### 增量同步流程
|
|
530
|
+
|
|
531
|
+
```
|
|
532
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
533
|
+
│ smc sync --incremental │
|
|
534
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
535
|
+
│
|
|
536
|
+
┌───────────────────────────┼───────────────────────────┐
|
|
537
|
+
▼ ▼ ▼
|
|
538
|
+
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
|
|
539
|
+
│ 读取项目版本 │ │ 读取版本清单 │ │ 计算差异变更 │
|
|
540
|
+
│ .sumulige- │ │ version- │ │ getChangesSince│
|
|
541
|
+
│ claude-version│ │ manifest.json │ │ (1.3.3) │
|
|
542
|
+
└───────────────┘ └───────────────┘ └───────────────┘
|
|
543
|
+
│
|
|
544
|
+
▼
|
|
545
|
+
┌───────────────────────────────────────────────┐
|
|
546
|
+
│ 应用变更: hook/config/lib/command │
|
|
547
|
+
│ 更新项目版本标记 │
|
|
548
|
+
└───────────────────────────────────────────────┘
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
### 状态文件汇总
|
|
552
|
+
|
|
553
|
+
| 文件 | 用途 | 生命周期 |
|
|
554
|
+
|------|------|----------|
|
|
555
|
+
| `.dispatcher-state.json` | Hook 执行状态 | 会话级 |
|
|
556
|
+
| `.match-cache.json` | RAG 匹配缓存 | 5 分钟 TTL |
|
|
557
|
+
| `.sumulige-claude-version` | 项目版本标记 | 永久 |
|
|
558
|
+
|
|
559
|
+
---
|
|
560
|
+
|
|
561
|
+
## Layer 9: Config Inheritance / 第九层:配置分层继承
|
|
562
|
+
|
|
563
|
+
> v1.4.1: 单一真相源架构,零维护成本的多项目配置管理
|
|
564
|
+
|
|
565
|
+
### 架构图
|
|
566
|
+
|
|
567
|
+
```
|
|
568
|
+
sumulige-claude/.claude/ ~/.claude/ 项目/.claude/
|
|
569
|
+
(Git 仓库 - 版本控制) (运行时 - 符号链接) (项目特定)
|
|
570
|
+
│ │ │
|
|
571
|
+
├── hooks/ ─────→ symlink ────→│ │
|
|
572
|
+
├── skills/ ────→ symlink ────→│ 自动继承 │
|
|
573
|
+
├── templates/ ─→ symlink ────→│ ─────────────────────→│
|
|
574
|
+
├── commands/ ──→ symlink ────→│ │
|
|
575
|
+
│ │ │
|
|
576
|
+
└── *.md ────────→ 复制 ──────→│ │
|
|
577
|
+
│ │
|
|
578
|
+
├── cache/ ├── MEMORY.md
|
|
579
|
+
├── debug/ ├── PROJECT_LOG.md
|
|
580
|
+
└── history.jsonl └── thinking-routes/
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
### 使用方式
|
|
584
|
+
|
|
585
|
+
```bash
|
|
586
|
+
# 首次设置:建立符号链接
|
|
587
|
+
cd ~/Documents/Antigravity/sumulige-claude
|
|
588
|
+
./scripts/sync-to-home.sh
|
|
589
|
+
|
|
590
|
+
# 日常更新:修改 sumulige-claude 后自动生效
|
|
591
|
+
git pull # 所有项目自动获得最新配置!
|
|
592
|
+
|
|
593
|
+
# 更新模板文件(CLAUDE.md, MEMORY.md 等)
|
|
594
|
+
./scripts/sync-to-home.sh --copy
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
### 项目配置精简
|
|
598
|
+
|
|
599
|
+
**之前**:每个项目复制完整 `.claude/` (~300 个文件)
|
|
600
|
+
|
|
601
|
+
**之后**:项目只保留特定内容 (~10 个文件)
|
|
602
|
+
|
|
603
|
+
```
|
|
604
|
+
项目/.claude/
|
|
605
|
+
├── MEMORY.md # 项目记忆
|
|
606
|
+
├── PROJECT_LOG.md # 项目日志
|
|
607
|
+
├── ANCHORS.md # 项目锚点
|
|
608
|
+
├── CLAUDE.md # 项目配置 (继承+覆盖)
|
|
609
|
+
├── thinking-routes/ # 思维轨迹
|
|
610
|
+
└── rag/ # 项目 RAG 索引
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
### 收益
|
|
614
|
+
|
|
615
|
+
| 指标 | 传统方式 | 分层继承 |
|
|
616
|
+
|------|---------|---------|
|
|
617
|
+
| 配置同步 | 手动复制到每个项目 | 自动(符号链接) |
|
|
618
|
+
| 更新成本 | O(n) 项目数 | O(1) |
|
|
619
|
+
| 配置漂移 | 容易发生 | 不可能 |
|
|
620
|
+
| 存储空间 | 每项目 ~5MB | 每项目 ~50KB |
|
|
621
|
+
|
|
622
|
+
---
|
|
623
|
+
|
|
465
624
|
## Documentation / 文档
|
|
466
625
|
|
|
467
626
|
- **[Development Guide / 开发指南](docs/DEVELOPMENT.md)** - Architecture, adding skills / 架构、添加技能
|