sumulige-claude 1.3.1 → 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 (31) hide show
  1. package/.claude/MEMORY.md +9 -0
  2. package/.claude/handoffs/INDEX.md +21 -0
  3. package/.claude/handoffs/LATEST.md +76 -0
  4. package/.claude/handoffs/handoff_2026-01-22T13-07-04-757Z.md +76 -0
  5. package/.claude/hooks/auto-handoff.cjs +353 -0
  6. package/.claude/hooks/memory-loader.cjs +208 -0
  7. package/.claude/hooks/memory-saver.cjs +268 -0
  8. package/.claude/sessions/session_2026-01-22T13-07-26-625Z.json +23 -0
  9. package/.claude/settings.json +40 -0
  10. package/.claude/settings.local.json +5 -1
  11. package/.claude/skills/api-tester/SKILL.md +61 -0
  12. package/.claude/skills/api-tester/examples/basic.md +3 -0
  13. package/.claude/skills/api-tester/metadata.yaml +30 -0
  14. package/.claude/skills/api-tester/templates/default.md +3 -0
  15. package/.claude/skills/code-reviewer-123/SKILL.md +61 -0
  16. package/.claude/skills/code-reviewer-123/examples/basic.md +3 -0
  17. package/.claude/skills/code-reviewer-123/metadata.yaml +30 -0
  18. package/.claude/skills/code-reviewer-123/templates/default.md +3 -0
  19. package/.claude/skills/my-skill/SKILL.md +61 -0
  20. package/.claude/skills/my-skill/examples/basic.md +3 -0
  21. package/.claude/skills/my-skill/metadata.yaml +30 -0
  22. package/.claude/skills/my-skill/templates/default.md +3 -0
  23. package/.claude/skills/template/SKILL.md +6 -0
  24. package/.claude/skills/template/metadata.yaml +30 -0
  25. package/.claude/skills/test-skill-name/SKILL.md +61 -0
  26. package/.claude/skills/test-skill-name/examples/basic.md +3 -0
  27. package/.claude/skills/test-skill-name/metadata.yaml +30 -0
  28. package/.claude/skills/test-skill-name/templates/default.md +3 -0
  29. package/CHANGELOG.md +20 -0
  30. package/development/todos/.state.json +3 -1
  31. package/package.json +1 -1
package/.claude/MEMORY.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## 2026-01-22
2
+
3
+ ### Session 2026-01-22T13:07:26.622Z
4
+
5
+ - **Duration**: 1 minutes
6
+ - **Project**: sumulige-claude
7
+ - **Memory entries**: 4
8
+ - **TODOs**: 0 active, 0 completed
9
+
1
10
  # 项目增量记忆
2
11
 
3
12
  > 记录最近变更和重要决策
@@ -0,0 +1,21 @@
1
+ # Handoffs Index
2
+
3
+ > Auto-generated context preservation documents
4
+ > Updated: 2026-01-22T13:07:04.758Z
5
+
6
+ ---
7
+
8
+ ## Recent Handoffs (1)
9
+
10
+ - [handoff_2026-01-22T13-07-04-757Z.md](./handoff_2026-01-22T13-07-04-757Z.md) - 2026-01-22T13:07:04.758Z
11
+
12
+
13
+ ---
14
+
15
+ ## Latest Handoff
16
+
17
+ See [LATEST.md](./LATEST.md) for the most recent context snapshot.
18
+
19
+ ---
20
+
21
+ *Index maintained by auto-handoff.cjs*
@@ -0,0 +1,76 @@
1
+ # Handoff: Pre-Compact Context Preservation
2
+
3
+ > Auto-generated before context compression
4
+ > Date: 2026-01-22T13:07:04.742Z
5
+ > Session: unknown
6
+ > Conversation: unknown
7
+
8
+ ---
9
+
10
+ ## Session Info
11
+
12
+ - **Project**: sumulige-claude
13
+ - **Version**: 1.3.1
14
+ - **Start Time**: 2026-01-22T13:06:23.872Z
15
+
16
+ ---
17
+
18
+ ## Memory State
19
+
20
+ - **Entries Loaded**: 4
21
+ - **Anchors Modules**: 0
22
+
23
+ ---
24
+
25
+ ## Active TODOs (0)
26
+
27
+ *No active TODOs*
28
+
29
+
30
+ ---
31
+
32
+ ## Recently Modified Files (Last 24h)
33
+
34
+ - `.claude/.session-state.json` (2026-01-22)
35
+ - `.claude/settings.local.json` (2026-01-22)
36
+ - `.claude/settings.json` (2026-01-22)
37
+ - `.claude/hooks/auto-handoff.cjs` (2026-01-22)
38
+ - `.claude/hooks/memory-saver.cjs` (2026-01-22)
39
+ - `.claude/hooks/memory-loader.cjs` (2026-01-22)
40
+ - `.claude/.kickoff-hint.txt` (2026-01-22)
41
+ - `.claude/skills/xlsx/LICENSE.txt` (2026-01-22)
42
+ - `.claude/skills/web-artifacts-builder/LICENSE.txt` (2026-01-22)
43
+ - `.claude/skills/webapp-testing/LICENSE.txt` (2026-01-22)
44
+ - *...and 10 more files*
45
+
46
+
47
+ ---
48
+
49
+ ## Context Preservation Notes
50
+
51
+ **Important**: This handoff was auto-generated before context compaction.
52
+ The following information should be re-loaded after compaction:
53
+
54
+ 1. Read `.claude/MEMORY.md` for recent session context
55
+ 2. Check `development/todos/INDEX.md` for task status
56
+ 3. Review recent git commits for code changes
57
+
58
+ ---
59
+
60
+ ## Recovery Commands
61
+
62
+ ```bash
63
+ # View recent memory
64
+ cat .claude/MEMORY.md | head -100
65
+
66
+ # Check active TODOs
67
+ ls development/todos/active/
68
+
69
+ # View recent changes
70
+ git log --oneline -10
71
+ git status
72
+ ```
73
+
74
+ ---
75
+
76
+ *Auto-generated by auto-handoff.cjs at 2026-01-22T13:07:04.742Z*
@@ -0,0 +1,76 @@
1
+ # Handoff: Pre-Compact Context Preservation
2
+
3
+ > Auto-generated before context compression
4
+ > Date: 2026-01-22T13:07:04.742Z
5
+ > Session: unknown
6
+ > Conversation: unknown
7
+
8
+ ---
9
+
10
+ ## Session Info
11
+
12
+ - **Project**: sumulige-claude
13
+ - **Version**: 1.3.1
14
+ - **Start Time**: 2026-01-22T13:06:23.872Z
15
+
16
+ ---
17
+
18
+ ## Memory State
19
+
20
+ - **Entries Loaded**: 4
21
+ - **Anchors Modules**: 0
22
+
23
+ ---
24
+
25
+ ## Active TODOs (0)
26
+
27
+ *No active TODOs*
28
+
29
+
30
+ ---
31
+
32
+ ## Recently Modified Files (Last 24h)
33
+
34
+ - `.claude/.session-state.json` (2026-01-22)
35
+ - `.claude/settings.local.json` (2026-01-22)
36
+ - `.claude/settings.json` (2026-01-22)
37
+ - `.claude/hooks/auto-handoff.cjs` (2026-01-22)
38
+ - `.claude/hooks/memory-saver.cjs` (2026-01-22)
39
+ - `.claude/hooks/memory-loader.cjs` (2026-01-22)
40
+ - `.claude/.kickoff-hint.txt` (2026-01-22)
41
+ - `.claude/skills/xlsx/LICENSE.txt` (2026-01-22)
42
+ - `.claude/skills/web-artifacts-builder/LICENSE.txt` (2026-01-22)
43
+ - `.claude/skills/webapp-testing/LICENSE.txt` (2026-01-22)
44
+ - *...and 10 more files*
45
+
46
+
47
+ ---
48
+
49
+ ## Context Preservation Notes
50
+
51
+ **Important**: This handoff was auto-generated before context compaction.
52
+ The following information should be re-loaded after compaction:
53
+
54
+ 1. Read `.claude/MEMORY.md` for recent session context
55
+ 2. Check `development/todos/INDEX.md` for task status
56
+ 3. Review recent git commits for code changes
57
+
58
+ ---
59
+
60
+ ## Recovery Commands
61
+
62
+ ```bash
63
+ # View recent memory
64
+ cat .claude/MEMORY.md | head -100
65
+
66
+ # Check active TODOs
67
+ ls development/todos/active/
68
+
69
+ # View recent changes
70
+ git log --oneline -10
71
+ git status
72
+ ```
73
+
74
+ ---
75
+
76
+ *Auto-generated by auto-handoff.cjs at 2026-01-22T13:07:04.742Z*
@@ -0,0 +1,353 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Auto Handoff Hook - PreCompact Context Preservation
4
+ *
5
+ * Claude Official Hook: PreCompact
6
+ * Triggered: Before conversation context is compressed
7
+ *
8
+ * Features:
9
+ * - Auto-generate handoff document before context compression
10
+ * - Preserve critical context that might be lost during compaction
11
+ * - Save current state including progress, blockers, and next steps
12
+ *
13
+ * Environment Variables:
14
+ * - CLAUDE_PROJECT_DIR: Project directory path
15
+ * - CLAUDE_SESSION_ID: Unique session identifier
16
+ * - CLAUDE_CONVERSATION_ID: Conversation 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 HANDOFFS_DIR = path.join(CLAUDE_DIR, 'handoffs');
25
+ const SESSION_STATE_FILE = path.join(CLAUDE_DIR, '.session-state.json');
26
+ const STATE_FILE = path.join(PROJECT_DIR, 'development', 'todos', '.state.json');
27
+ const SESSION_ID = process.env.CLAUDE_SESSION_ID || 'unknown';
28
+ const CONVERSATION_ID = process.env.CLAUDE_CONVERSATION_ID || 'unknown';
29
+
30
+ /**
31
+ * Ensure handoffs directory exists
32
+ */
33
+ function ensureHandoffsDir() {
34
+ if (!fs.existsSync(HANDOFFS_DIR)) {
35
+ fs.mkdirSync(HANDOFFS_DIR, { recursive: true });
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Load current session state
41
+ */
42
+ function loadSessionState() {
43
+ if (!fs.existsSync(SESSION_STATE_FILE)) {
44
+ return {
45
+ session: { project: path.basename(PROJECT_DIR) },
46
+ memory: { entries: 0 },
47
+ todos: { active: 0, completed: 0 }
48
+ };
49
+ }
50
+
51
+ try {
52
+ return JSON.parse(fs.readFileSync(SESSION_STATE_FILE, 'utf-8'));
53
+ } catch (e) {
54
+ return {
55
+ session: { project: path.basename(PROJECT_DIR) },
56
+ memory: { entries: 0 },
57
+ todos: { active: 0, completed: 0 }
58
+ };
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Load active TODOs
64
+ */
65
+ function loadActiveTodos() {
66
+ const todosDir = path.join(PROJECT_DIR, 'development', 'todos', 'active');
67
+ if (!fs.existsSync(todosDir)) {
68
+ return [];
69
+ }
70
+
71
+ try {
72
+ const files = fs.readdirSync(todosDir)
73
+ .filter(f => f.endsWith('.md') && f !== '_README.md');
74
+
75
+ return files.map(f => {
76
+ const content = fs.readFileSync(path.join(todosDir, f), 'utf-8');
77
+ const titleMatch = content.match(/^#\s+(.+)$/m);
78
+ return {
79
+ file: f,
80
+ title: titleMatch ? titleMatch[1] : path.basename(f, '.md')
81
+ };
82
+ });
83
+ } catch (e) {
84
+ return [];
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Get recently modified files
90
+ */
91
+ function getRecentlyModifiedFiles(hours = 24) {
92
+ const recentFiles = [];
93
+ const cutoff = Date.now() - (hours * 60 * 60 * 1000);
94
+
95
+ // Check common source directories
96
+ const sourceDirs = ['src', 'lib', '.claude', 'development'];
97
+
98
+ for (const dir of sourceDirs) {
99
+ const fullPath = path.join(PROJECT_DIR, dir);
100
+ if (!fs.existsSync(fullPath)) continue;
101
+
102
+ try {
103
+ const walkDir = (dirPath, depth = 0) => {
104
+ if (depth > 3) return; // Limit depth
105
+
106
+ const items = fs.readdirSync(dirPath, { withFileTypes: true });
107
+ for (const item of items) {
108
+ const itemPath = path.join(dirPath, item.name);
109
+
110
+ if (item.isDirectory() && !item.name.startsWith('.') && item.name !== 'node_modules') {
111
+ walkDir(itemPath, depth + 1);
112
+ } else if (item.isFile()) {
113
+ try {
114
+ const stat = fs.statSync(itemPath);
115
+ if (stat.mtimeMs > cutoff) {
116
+ const relativePath = path.relative(PROJECT_DIR, itemPath);
117
+ recentFiles.push({
118
+ path: relativePath,
119
+ modified: stat.mtime.toISOString()
120
+ });
121
+ }
122
+ } catch (e) {
123
+ // Ignore stat errors
124
+ }
125
+ }
126
+ }
127
+ };
128
+
129
+ walkDir(fullPath);
130
+ } catch (e) {
131
+ // Ignore directory errors
132
+ }
133
+ }
134
+
135
+ // Sort by modification time (most recent first)
136
+ recentFiles.sort((a, b) => b.modified.localeCompare(a.modified));
137
+
138
+ return recentFiles.slice(0, 20); // Return top 20
139
+ }
140
+
141
+ /**
142
+ * Generate handoff document
143
+ */
144
+ function generateHandoff(sessionState) {
145
+ const now = new Date();
146
+ const todos = loadActiveTodos();
147
+ const recentFiles = getRecentlyModifiedFiles();
148
+
149
+ let content = `# Handoff: Pre-Compact Context Preservation
150
+
151
+ > Auto-generated before context compression
152
+ > Date: ${now.toISOString()}
153
+ > Session: ${SESSION_ID}
154
+ > Conversation: ${CONVERSATION_ID}
155
+
156
+ ---
157
+
158
+ ## Session Info
159
+
160
+ - **Project**: ${sessionState.session?.project || 'unknown'}
161
+ - **Version**: ${sessionState.session?.version || 'unknown'}
162
+ - **Start Time**: ${sessionState.session?.startTime || 'unknown'}
163
+
164
+ ---
165
+
166
+ ## Memory State
167
+
168
+ - **Entries Loaded**: ${sessionState.memory?.entries || 0}
169
+ - **Anchors Modules**: ${sessionState.anchors?.modules || 0}
170
+
171
+ ---
172
+
173
+ ## Active TODOs (${todos.length})
174
+
175
+ `;
176
+
177
+ if (todos.length > 0) {
178
+ todos.forEach(todo => {
179
+ content += `- [ ] ${todo.title} (\`${todo.file}\`)\n`;
180
+ });
181
+ } else {
182
+ content += `*No active TODOs*\n`;
183
+ }
184
+
185
+ content += `
186
+
187
+ ---
188
+
189
+ ## Recently Modified Files (Last 24h)
190
+
191
+ `;
192
+
193
+ if (recentFiles.length > 0) {
194
+ recentFiles.slice(0, 10).forEach(f => {
195
+ content += `- \`${f.path}\` (${f.modified.split('T')[0]})\n`;
196
+ });
197
+ if (recentFiles.length > 10) {
198
+ content += `- *...and ${recentFiles.length - 10} more files*\n`;
199
+ }
200
+ } else {
201
+ content += `*No recently modified files*\n`;
202
+ }
203
+
204
+ content += `
205
+
206
+ ---
207
+
208
+ ## Context Preservation Notes
209
+
210
+ **Important**: This handoff was auto-generated before context compaction.
211
+ The following information should be re-loaded after compaction:
212
+
213
+ 1. Read \`.claude/MEMORY.md\` for recent session context
214
+ 2. Check \`development/todos/INDEX.md\` for task status
215
+ 3. Review recent git commits for code changes
216
+
217
+ ---
218
+
219
+ ## Recovery Commands
220
+
221
+ \`\`\`bash
222
+ # View recent memory
223
+ cat .claude/MEMORY.md | head -100
224
+
225
+ # Check active TODOs
226
+ ls development/todos/active/
227
+
228
+ # View recent changes
229
+ git log --oneline -10
230
+ git status
231
+ \`\`\`
232
+
233
+ ---
234
+
235
+ *Auto-generated by auto-handoff.cjs at ${now.toISOString()}*
236
+ `;
237
+
238
+ return content;
239
+ }
240
+
241
+ /**
242
+ * Save handoff document
243
+ */
244
+ function saveHandoff(content) {
245
+ ensureHandoffsDir();
246
+
247
+ const now = new Date();
248
+ const filename = `handoff_${now.toISOString().replace(/[:.]/g, '-')}.md`;
249
+ const filepath = path.join(HANDOFFS_DIR, filename);
250
+
251
+ fs.writeFileSync(filepath, content);
252
+
253
+ // Also save as latest handoff for easy access
254
+ const latestPath = path.join(HANDOFFS_DIR, 'LATEST.md');
255
+ fs.writeFileSync(latestPath, content);
256
+
257
+ // Clean up old handoffs (keep last 10)
258
+ const files = fs.readdirSync(HANDOFFS_DIR)
259
+ .filter(f => f.startsWith('handoff_') && f.endsWith('.md'))
260
+ .sort()
261
+ .reverse();
262
+
263
+ if (files.length > 10) {
264
+ files.slice(10).forEach(f => {
265
+ try {
266
+ fs.unlinkSync(path.join(HANDOFFS_DIR, f));
267
+ } catch (e) {
268
+ // Ignore deletion errors
269
+ }
270
+ });
271
+ }
272
+
273
+ return filename;
274
+ }
275
+
276
+ /**
277
+ * Update handoffs index
278
+ */
279
+ function updateHandoffsIndex() {
280
+ const indexPath = path.join(HANDOFFS_DIR, 'INDEX.md');
281
+
282
+ const files = fs.readdirSync(HANDOFFS_DIR)
283
+ .filter(f => f.startsWith('handoff_') && f.endsWith('.md'))
284
+ .sort()
285
+ .reverse();
286
+
287
+ let content = `# Handoffs Index
288
+
289
+ > Auto-generated context preservation documents
290
+ > Updated: ${new Date().toISOString()}
291
+
292
+ ---
293
+
294
+ ## Recent Handoffs (${files.length})
295
+
296
+ `;
297
+
298
+ files.slice(0, 20).forEach(f => {
299
+ const filepath = path.join(HANDOFFS_DIR, f);
300
+ const stat = fs.statSync(filepath);
301
+ content += `- [${f}](./${f}) - ${stat.mtime.toISOString()}\n`;
302
+ });
303
+
304
+ content += `
305
+
306
+ ---
307
+
308
+ ## Latest Handoff
309
+
310
+ See [LATEST.md](./LATEST.md) for the most recent context snapshot.
311
+
312
+ ---
313
+
314
+ *Index maintained by auto-handoff.cjs*
315
+ `;
316
+
317
+ fs.writeFileSync(indexPath, content);
318
+ }
319
+
320
+ /**
321
+ * Main execution
322
+ */
323
+ function main() {
324
+ try {
325
+ const sessionState = loadSessionState();
326
+ const content = generateHandoff(sessionState);
327
+ const filename = saveHandoff(content);
328
+ updateHandoffsIndex();
329
+
330
+ console.log(`\n⚡ PreCompact: Context preserved → ${filename}`);
331
+ console.log(` Recovery: .claude/handoffs/LATEST.md\n`);
332
+
333
+ process.exit(0);
334
+ } catch (e) {
335
+ // Silent failure - don't interrupt compaction
336
+ console.error(`PreCompact handoff error: ${e.message}`);
337
+ process.exit(0);
338
+ }
339
+ }
340
+
341
+ // Run
342
+ if (require.main === module) {
343
+ main();
344
+ }
345
+
346
+ module.exports = {
347
+ loadSessionState,
348
+ loadActiveTodos,
349
+ getRecentlyModifiedFiles,
350
+ generateHandoff,
351
+ saveHandoff,
352
+ updateHandoffsIndex
353
+ };