sumulige-claude 1.0.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.
Files changed (72) hide show
  1. package/.claude/AGENTS.md +42 -0
  2. package/.claude/README.md +142 -0
  3. package/.claude/rag/skill-index.json +15 -0
  4. package/.claude/settings.local.json +36 -0
  5. package/.claude/skills/api-tester/SKILL.md +61 -0
  6. package/.claude/skills/api-tester/examples/basic.md +3 -0
  7. package/.claude/skills/api-tester/metadata.yaml +30 -0
  8. package/.claude/skills/api-tester/templates/default.md +3 -0
  9. package/AGENTS.md +33 -0
  10. package/README.md +857 -0
  11. package/cli.js +814 -0
  12. package/development/todos/INDEX.md +114 -0
  13. package/development/todos/active/_README.md +49 -0
  14. package/development/todos/active/todo-system.md +37 -0
  15. package/development/todos/archived/_README.md +11 -0
  16. package/development/todos/backlog/_README.md +11 -0
  17. package/development/todos/backlog/mcp-integration.md +35 -0
  18. package/development/todos/completed/_README.md +11 -0
  19. package/development/todos/completed/boris-optimizations.md +39 -0
  20. package/package.json +35 -0
  21. package/template/.claude/CLAUDE-template.md +138 -0
  22. package/template/.claude/README.md +142 -0
  23. package/template/.claude/boris-optimizations.md +167 -0
  24. package/template/.claude/commands/commit-push-pr.md +59 -0
  25. package/template/.claude/commands/commit.md +53 -0
  26. package/template/.claude/commands/pr.md +76 -0
  27. package/template/.claude/commands/review.md +61 -0
  28. package/template/.claude/commands/sessions.md +62 -0
  29. package/template/.claude/commands/skill-create.md +131 -0
  30. package/template/.claude/commands/test.md +56 -0
  31. package/template/.claude/commands/todos.md +99 -0
  32. package/template/.claude/commands/verify-work.md +63 -0
  33. package/template/.claude/hooks/code-formatter.cjs +187 -0
  34. package/template/.claude/hooks/multi-session.cjs +181 -0
  35. package/template/.claude/hooks/project-kickoff.cjs +114 -0
  36. package/template/.claude/hooks/rag-skill-loader.cjs +159 -0
  37. package/template/.claude/hooks/session-end.sh +61 -0
  38. package/template/.claude/hooks/sync-to-log.sh +83 -0
  39. package/template/.claude/hooks/thinking-silent.cjs +145 -0
  40. package/template/.claude/hooks/tl-summary.sh +54 -0
  41. package/template/.claude/hooks/todo-manager.cjs +248 -0
  42. package/template/.claude/hooks/verify-work.cjs +134 -0
  43. package/template/.claude/rag/skill-index.json +135 -0
  44. package/template/.claude/settings.json +33 -0
  45. package/template/.claude/skills/SKILLS.md +145 -0
  46. package/template/.claude/skills/examples/README.md +47 -0
  47. package/template/.claude/skills/examples/basic-task.md +67 -0
  48. package/template/.claude/skills/examples/bug-fix-workflow.md +92 -0
  49. package/template/.claude/skills/examples/feature-development.md +81 -0
  50. package/template/.claude/skills/manus-kickoff/SKILL.md +128 -0
  51. package/template/.claude/skills/manus-kickoff/examples/basic.md +84 -0
  52. package/template/.claude/skills/manus-kickoff/metadata.yaml +33 -0
  53. package/template/.claude/skills/manus-kickoff/templates/PROJECT_KICKOFF.md +89 -0
  54. package/template/.claude/skills/manus-kickoff/templates/PROJECT_PROPOSAL.md +227 -0
  55. package/template/.claude/skills/manus-kickoff/templates/TASK_PLAN.md +121 -0
  56. package/template/.claude/skills/template/SKILL.md +61 -0
  57. package/template/.claude/skills/template/metadata.yaml +30 -0
  58. package/template/.claude/templates/PROJECT_KICKOFF.md +89 -0
  59. package/template/.claude/templates/PROJECT_PROPOSAL.md +227 -0
  60. package/template/.claude/templates/TASK_PLAN.md +121 -0
  61. package/template/.claude/thinking-routes/QUICKREF.md +98 -0
  62. package/template/CLAUDE-template.md +114 -0
  63. package/template/README.md +148 -0
  64. package/template/development/todos/INDEX.md +63 -0
  65. package/template/development/todos/active/_README.md +49 -0
  66. package/template/development/todos/archived/_README.md +11 -0
  67. package/template/development/todos/backlog/_README.md +11 -0
  68. package/template/development/todos/completed/_README.md +11 -0
  69. package/template/init.sh +150 -0
  70. package/template/project-paradigm.md +313 -0
  71. package/template/prompts/how-to-find.md +163 -0
  72. package/template/thinkinglens-silent.md +138 -0
package/cli.js ADDED
@@ -0,0 +1,814 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Sumulige Claude - CLI Entry Point
4
+ * Agent harness for Claude Code
5
+ *
6
+ * Features:
7
+ * - Multi-agent orchestration
8
+ * - Skills management via OpenSkills
9
+ * - Built-in Claude Code project template
10
+ * - ThinkingLens conversation tracking
11
+ */
12
+
13
+ const fs = require('fs');
14
+ const path = require('path');
15
+ const { execSync } = require('child_process');
16
+
17
+ const CONFIG_DIR = path.join(process.env.HOME, '.claude');
18
+ const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
19
+ const SKILLS_DIR = path.join(CONFIG_DIR, 'skills');
20
+ const TEMPLATE_DIR = path.join(__dirname, 'template');
21
+
22
+ // 默认配置 - 所有 Agent 使用 Opus 4.5
23
+ const DEFAULT_CONFIG = {
24
+ version: '1.0.0',
25
+ agents: {
26
+ conductor: { model: 'claude-opus-4.5', role: 'Task coordination and decomposition' },
27
+ architect: { model: 'claude-opus-4.5', role: 'Architecture design and decisions' },
28
+ builder: { model: 'claude-opus-4.5', role: 'Code implementation and testing' },
29
+ reviewer: { model: 'claude-opus-4.5', role: 'Code review and quality check' },
30
+ librarian: { model: 'claude-opus-4.5', role: 'Documentation and knowledge' }
31
+ },
32
+ skills: [
33
+ 'anthropics/skills',
34
+ 'numman-ali/n-skills'
35
+ ],
36
+ hooks: {
37
+ preTask: [],
38
+ postTask: []
39
+ },
40
+ thinkingLens: {
41
+ enabled: true,
42
+ autoSync: true,
43
+ syncInterval: 20
44
+ }
45
+ };
46
+
47
+ // 命令处理
48
+ const commands = {
49
+ init: () => {
50
+ console.log('🚀 Initializing Sumulige Claude...');
51
+
52
+ // 创建配置目录
53
+ if (!fs.existsSync(CONFIG_DIR)) {
54
+ fs.mkdirSync(CONFIG_DIR, { recursive: true });
55
+ }
56
+
57
+ // 创建配置文件
58
+ if (!fs.existsSync(CONFIG_FILE)) {
59
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(DEFAULT_CONFIG, null, 2));
60
+ console.log('✅ Created config:', CONFIG_FILE);
61
+ } else {
62
+ console.log('ℹ️ Config already exists:', CONFIG_FILE);
63
+ }
64
+
65
+ // 创建技能目录
66
+ if (!fs.existsSync(SKILLS_DIR)) {
67
+ fs.mkdirSync(SKILLS_DIR, { recursive: true });
68
+ console.log('✅ Created skills directory:', SKILLS_DIR);
69
+ }
70
+
71
+ // 安装 openskills(如果未安装)
72
+ try {
73
+ execSync('openskills --version', { stdio: 'ignore' });
74
+ console.log('✅ OpenSkills already installed');
75
+ } catch {
76
+ console.log('📦 Installing OpenSkills...');
77
+ try {
78
+ execSync('npm i -g openskills', { stdio: 'inherit' });
79
+ console.log('✅ OpenSkills installed');
80
+ } catch (e) {
81
+ console.log('⚠️ Failed to install OpenSkills. Run: npm i -g openskills');
82
+ }
83
+ }
84
+
85
+ console.log('');
86
+ console.log('🎉 Sumulige Claude initialized!');
87
+ console.log('');
88
+ console.log('Next steps:');
89
+ console.log(' sumulige-claude sync # Sync to current project');
90
+ console.log(' sumulige-claude agent # Run agent orchestration');
91
+ console.log(' sumulige-claude status # Show configuration');
92
+ },
93
+
94
+ sync: () => {
95
+ console.log('🔄 Syncing Sumulige Claude to current project...');
96
+
97
+ const projectDir = process.cwd();
98
+ const projectConfigDir = path.join(projectDir, '.claude');
99
+ const agentsFile = path.join(projectConfigDir, 'AGENTS.md');
100
+ const readmeFile = path.join(projectConfigDir, 'README.md');
101
+ const templateReadme = path.join(TEMPLATE_DIR, '.claude', 'README.md');
102
+
103
+ // 创建 .claude 目录
104
+ if (!fs.existsSync(projectConfigDir)) {
105
+ fs.mkdirSync(projectConfigDir, { recursive: true });
106
+ console.log('✅ Created .claude directory');
107
+ }
108
+
109
+ // 同步配置
110
+ const config = loadConfig();
111
+
112
+ // 生成 AGENTS.md
113
+ const agentsMd = generateAgentsMd(config);
114
+ fs.writeFileSync(agentsFile, agentsMd);
115
+ console.log('✅ Created AGENTS.md');
116
+
117
+ // 静默同步 README.md(如果 template 更新了)
118
+ if (fs.existsSync(templateReadme)) {
119
+ const templateContent = fs.readFileSync(templateReadme, 'utf-8');
120
+ let needsUpdate = true;
121
+
122
+ // 检查是否需要更新(比较文件内容)
123
+ if (fs.existsSync(readmeFile)) {
124
+ const existingContent = fs.readFileSync(readmeFile, 'utf-8');
125
+ // 提取版本标记(如果有)
126
+ const templateVersion = templateContent.match(/@version:\s*(\d+\.\d+\.\d+)/)?.[1] || '0.0.0';
127
+ const existingVersion = existingContent.match(/@version:\s*(\d+\.\d+\.\d+)/)?.[1] || '0.0.0';
128
+ needsUpdate = templateVersion !== existingVersion;
129
+ }
130
+
131
+ if (needsUpdate) {
132
+ fs.writeFileSync(readmeFile, templateContent);
133
+ // 静默更新,不输出
134
+ }
135
+ }
136
+
137
+ // 同步 todos 目录结构
138
+ const todosTemplateDir = path.join(TEMPLATE_DIR, 'development', 'todos');
139
+ const todosProjectDir = path.join(projectDir, 'development', 'todos');
140
+
141
+ if (fs.existsSync(todosTemplateDir)) {
142
+ // 复制 todos 模板文件(如果不存在)
143
+ const copyRecursive = (src, dest) => {
144
+ if (!fs.existsSync(dest)) {
145
+ fs.mkdirSync(dest, { recursive: true });
146
+ }
147
+ const entries = fs.readdirSync(src, { withFileTypes: true });
148
+ for (const entry of entries) {
149
+ const srcPath = path.join(src, entry.name);
150
+ const destPath = path.join(dest, entry.name);
151
+ if (entry.isDirectory()) {
152
+ copyRecursive(srcPath, destPath);
153
+ } else if (!fs.existsSync(destPath)) {
154
+ fs.copyFileSync(srcPath, destPath);
155
+ }
156
+ }
157
+ };
158
+ copyRecursive(todosTemplateDir, todosProjectDir);
159
+ // 静默同步,不输出
160
+ }
161
+
162
+ // 同步技能
163
+ try {
164
+ execSync('openskills sync -y', { stdio: 'pipe' });
165
+ console.log('✅ Synced skills');
166
+ } catch (e) {
167
+ console.log('⚠️ Failed to sync skills');
168
+ }
169
+
170
+ console.log('');
171
+ console.log('✅ Sync complete!');
172
+ },
173
+
174
+ agent: (task) => {
175
+ if (!task) {
176
+ console.log('Usage: sumulige-claude agent <task>');
177
+ console.log('');
178
+ console.log('Example: sumulige-claude agent "Build a React dashboard"');
179
+ return;
180
+ }
181
+
182
+ const config = loadConfig();
183
+ console.log('🤖 Starting Agent Orchestration...');
184
+ console.log('');
185
+ console.log('Task:', task);
186
+ console.log('');
187
+ console.log('Available Agents:');
188
+ Object.entries(config.agents).forEach(([name, agent]) => {
189
+ console.log(` - ${name}: ${agent.model} (${agent.role})`);
190
+ });
191
+ console.log('');
192
+ console.log('💡 In Claude Code, use /skill <name> to invoke specific agent capabilities');
193
+ },
194
+
195
+ status: () => {
196
+ const config = loadConfig();
197
+ console.log('📊 Sumulige Claude Status');
198
+ console.log('');
199
+ console.log('Config:', CONFIG_FILE);
200
+ console.log('');
201
+ console.log('Agents:');
202
+ Object.entries(config.agents).forEach(([name, agent]) => {
203
+ console.log(` ${name.padEnd(12)} ${agent.model.padEnd(20)} (${agent.role})`);
204
+ });
205
+ console.log('');
206
+ console.log('Skills:', config.skills.join(', '));
207
+ console.log('');
208
+ console.log('ThinkingLens:', config.thinkingLens.enabled ? '✅ Enabled' : '❌ Disabled');
209
+ console.log('');
210
+
211
+ // 显示项目 todos 状态
212
+ const projectDir = process.cwd();
213
+ const todosIndex = path.join(projectDir, 'development', 'todos', 'INDEX.md');
214
+
215
+ if (fs.existsSync(todosIndex)) {
216
+ const content = fs.readFileSync(todosIndex, 'utf-8');
217
+
218
+ // 提取进度信息
219
+ const totalMatch = content.match(/Total:\s+`([^`]+)`\s+(\d+)%/);
220
+ const p0Match = content.match(/P0[^`]*`([^`]+)`\s+(\d+)%\s+\((\d+)\/(\d+)\)/);
221
+ const p1Match = content.match(/P1[^`]*`([^`]+)`\s+(\d+)%\s+\((\d+)\/(\d+)\)/);
222
+ const p2Match = content.match(/P2[^`]*`([^`]+)`\s+(\d+)%\s+\((\d+)\/(\d+)\)/);
223
+
224
+ const activeMatch = content.match(/\|\s+🚧 进行中[^|]*\|\s+`active\/`\s+\|\s+(\d+)/);
225
+ const completedMatch = content.match(/\|\s+✅ 已完成[^|]*\|\s+`completed\/`\s+\|\s+(\d+)/);
226
+ const backlogMatch = content.match(/\|\s+📋 待办[^|]*\|\s+`backlog\/`\s+\|\s+(\d+)/);
227
+
228
+ console.log('📋 Project Tasks:');
229
+ console.log('');
230
+ if (totalMatch) {
231
+ console.log(` Total: ${totalMatch[1]} ${totalMatch[2]}%`);
232
+ }
233
+ if (p0Match) {
234
+ console.log(` P0: ${p0Match[1]} ${p0Match[2]}% (${p0Match[3]}/${p0Match[4]})`);
235
+ }
236
+ if (p1Match) {
237
+ console.log(` P1: ${p1Match[1]} ${p1Match[2]}% (${p1Match[3]}/${p1Match[4]})`);
238
+ }
239
+ if (p2Match) {
240
+ console.log(` P2: ${p2Match[1]} ${p2Match[2]}% (${p2Match[3]}/${p2Match[4]})`);
241
+ }
242
+ console.log('');
243
+ console.log(` 🚧 Active: ${activeMatch ? activeMatch[1] : 0}`);
244
+ console.log(` ✅ Completed: ${completedMatch ? completedMatch[1] : 0}`);
245
+ console.log(` 📋 Backlog: ${backlogMatch ? backlogMatch[1] : 0}`);
246
+ console.log('');
247
+ console.log(` View: cat development/todos/INDEX.md`);
248
+ } else {
249
+ console.log('📋 Project Tasks: (not initialized)');
250
+ console.log(' Run: node .claude/hooks/todo-manager.cjs --force');
251
+ }
252
+ },
253
+
254
+ 'skill:list': () => {
255
+ try {
256
+ const result = execSync('openskills list', { encoding: 'utf-8' });
257
+ console.log(result);
258
+ } catch (e) {
259
+ console.log('⚠️ OpenSkills not installed. Run: npm i -g openskills');
260
+ }
261
+ },
262
+
263
+ 'skill:create': (skillName) => {
264
+ if (!skillName) {
265
+ console.log('Usage: sumulige-claude skill:create <skill-name>');
266
+ console.log('');
267
+ console.log('Example: sumulige-claude skill:create api-tester');
268
+ console.log('');
269
+ console.log('The skill will be created at:');
270
+ console.log(' .claude/skills/<skill-name>/');
271
+ return;
272
+ }
273
+
274
+ // 验证 skill 名称 (kebab-case)
275
+ if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(skillName)) {
276
+ console.log('❌ Invalid skill name. Use kebab-case (e.g., api-tester, code-reviewer)');
277
+ return;
278
+ }
279
+
280
+ const projectDir = process.cwd();
281
+ const skillsDir = path.join(projectDir, '.claude', 'skills');
282
+ const skillDir = path.join(skillsDir, skillName);
283
+ const templateDir = path.join(TEMPLATE_DIR, '.claude', 'skills', 'template');
284
+
285
+ // 检查技能是否已存在
286
+ if (fs.existsSync(skillDir)) {
287
+ console.log(`⚠️ Skill "${skillName}" already exists at ${skillDir}`);
288
+ return;
289
+ }
290
+
291
+ console.log(`📝 Creating skill: ${skillName}`);
292
+ console.log('');
293
+
294
+ // 创建技能目录结构
295
+ fs.mkdirSync(path.join(skillDir, 'templates'), { recursive: true });
296
+ fs.mkdirSync(path.join(skillDir, 'examples'), { recursive: true });
297
+ console.log('✅ Created directory structure');
298
+
299
+ // 复制模板文件
300
+ if (fs.existsSync(templateDir)) {
301
+ const skillTemplate = fs.readFileSync(path.join(templateDir, 'SKILL.md'), 'utf-8');
302
+ const metadataTemplate = fs.readFileSync(path.join(templateDir, 'metadata.yaml'), 'utf-8');
303
+
304
+ // 替换占位符
305
+ const date = new Date().toISOString().split('T')[0];
306
+ let skillContent = skillTemplate
307
+ .replace(/Skill Name/g, toTitleCase(skillName.replace(/-/g, ' ')))
308
+ .replace(/{current-date}/g, date)
309
+ .replace(/skill-name/g, skillName);
310
+
311
+ let metadataContent = metadataTemplate
312
+ .replace(/skill-name/g, skillName)
313
+ .replace(/dependencies: \[\]/g, 'dependencies: []') // 保持依赖为空,用户手动添加
314
+ .replace(/difficulty: beginner/g, 'difficulty: beginner'); // 默认难度
315
+
316
+ fs.writeFileSync(path.join(skillDir, 'SKILL.md'), skillContent);
317
+ fs.writeFileSync(path.join(skillDir, 'metadata.yaml'), metadataContent);
318
+ console.log('✅ Created SKILL.md and metadata.yaml');
319
+ }
320
+
321
+ // 创建示例模板
322
+ fs.writeFileSync(
323
+ path.join(skillDir, 'templates', 'default.md'),
324
+ `# Default Template for ${skillName}\n\nReplace this with your actual template.\n`
325
+ );
326
+ fs.writeFileSync(
327
+ path.join(skillDir, 'examples', 'basic.md'),
328
+ `# Basic Example for ${skillName}\n\nReplace this with your actual example.\n`
329
+ );
330
+ console.log('✅ Created templates and examples');
331
+
332
+ // 更新 RAG 索引
333
+ const ragDir = path.join(projectDir, '.claude', 'rag');
334
+ const ragIndexFile = path.join(ragDir, 'skill-index.json');
335
+ let ragIndex = { skills: [], auto_load: { enabled: true } };
336
+
337
+ // 确保 rag 目录存在
338
+ if (!fs.existsSync(ragDir)) {
339
+ fs.mkdirSync(ragDir, { recursive: true });
340
+ }
341
+
342
+ if (fs.existsSync(ragIndexFile)) {
343
+ try {
344
+ ragIndex = JSON.parse(fs.readFileSync(ragIndexFile, 'utf-8'));
345
+ } catch (e) {}
346
+ }
347
+
348
+ // 添加新技能到索引
349
+ const newSkill = {
350
+ name: skillName,
351
+ description: `TODO: Add description for ${skillName}`,
352
+ keywords: [skillName.replace(/-/g, ' ')],
353
+ path: `.claude/skills/${skillName}/SKILL.md`
354
+ };
355
+
356
+ // 避免重复
357
+ if (!ragIndex.skills.some(s => s.name === skillName)) {
358
+ ragIndex.skills.push(newSkill);
359
+ fs.writeFileSync(ragIndexFile, JSON.stringify(ragIndex, null, 2));
360
+ console.log('✅ Updated RAG skill index');
361
+ }
362
+
363
+ console.log('');
364
+ console.log('✅ Skill created successfully!');
365
+ console.log('');
366
+ console.log(`Next steps:`);
367
+ console.log(` 1. Edit .claude/skills/${skillName}/SKILL.md`);
368
+ console.log(` 2. Add your templates and examples`);
369
+ console.log(` 3. Use in Claude Code: /skill ${skillName}`);
370
+ },
371
+
372
+ 'skill:check': (skillName) => {
373
+ const projectDir = process.cwd();
374
+ const skillsDir = path.join(projectDir, '.claude', 'skills');
375
+
376
+ console.log('🔍 Checking skill dependencies...');
377
+ console.log('');
378
+
379
+ const checkSkill = (name, visited = new Set()) => {
380
+ if (visited.has(name)) {
381
+ console.log(`⚠️ Circular dependency detected: ${name}`);
382
+ return;
383
+ }
384
+ visited.add(name);
385
+
386
+ const skillDir = path.join(skillsDir, name);
387
+ const metadataFile = path.join(skillDir, 'metadata.yaml');
388
+
389
+ if (!fs.existsSync(skillDir)) {
390
+ console.log(`❌ Skill "${name}" not found`);
391
+ return;
392
+ }
393
+
394
+ if (!fs.existsSync(metadataFile)) {
395
+ console.log(`ℹ️ ${name}: No metadata.yaml`);
396
+ return;
397
+ }
398
+
399
+ // 简单解析 YAML(只支持基本的 key: value 格式)
400
+ const parseSimpleYaml = (content) => {
401
+ const result = {};
402
+ content.split('\n').forEach(line => {
403
+ const match = line.match(/^(\w+):\s*(.*)$/);
404
+ if (match) {
405
+ const value = match[2].trim();
406
+ if (value === '[]') {
407
+ result[match[1]] = [];
408
+ } else if (value.startsWith('[')) {
409
+ try {
410
+ result[match[1]] = JSON.parse(value.replace(/'/g, '"'));
411
+ } catch (e) {
412
+ result[match[1]] = [];
413
+ }
414
+ } else {
415
+ result[match[1]] = value;
416
+ }
417
+ }
418
+ });
419
+ return result;
420
+ };
421
+
422
+ const metadata = parseSimpleYaml(fs.readFileSync(metadataFile, 'utf-8'));
423
+ const deps = metadata.dependencies || [];
424
+
425
+ if (deps.length === 0) {
426
+ console.log(`✅ ${name}: No dependencies`);
427
+ return;
428
+ }
429
+
430
+ console.log(`📦 ${name} depends on:`);
431
+ deps.forEach(dep => {
432
+ const depDir = path.join(skillsDir, dep);
433
+ if (fs.existsSync(depDir)) {
434
+ console.log(` ✅ ${dep}`);
435
+ checkSkill(dep, new Set(visited));
436
+ } else {
437
+ console.log(` ❌ ${dep} (missing)`);
438
+ }
439
+ });
440
+ };
441
+
442
+ if (skillName) {
443
+ checkSkill(skillName);
444
+ } else {
445
+ // 检查所有技能
446
+ const allSkills = fs.existsSync(skillsDir)
447
+ ? fs.readdirSync(skillsDir).filter(f => {
448
+ const dir = path.join(skillsDir, f);
449
+ return fs.statSync(dir).isDirectory() && f !== 'template' && f !== 'examples';
450
+ })
451
+ : [];
452
+
453
+ console.log(`Found ${allSkills.length} skills\n`);
454
+ allSkills.forEach(skill => checkSkill(skill));
455
+ }
456
+ },
457
+
458
+ 'skill:install': (source) => {
459
+ if (!source) {
460
+ console.log('Usage: sumulige-claude skill:install <source>');
461
+ console.log('Example: sumulige-claude skill:install anthropics/skills');
462
+ return;
463
+ }
464
+ try {
465
+ execSync(`openskills install ${source} -y`, { stdio: 'inherit' });
466
+ execSync('openskills sync -y', { stdio: 'pipe' });
467
+ console.log('✅ Skill installed and synced');
468
+ } catch (e) {
469
+ console.log('❌ Failed to install skill');
470
+ }
471
+ },
472
+
473
+ template: (targetPath) => {
474
+ const targetDir = targetPath ? path.resolve(targetPath) : process.cwd();
475
+
476
+ console.log('🚀 Initializing Claude Code project template...');
477
+ console.log(' Target:', targetDir);
478
+ console.log('');
479
+
480
+ // 检查模板目录是否存在
481
+ if (!fs.existsSync(TEMPLATE_DIR)) {
482
+ console.log('❌ Template not found at:', TEMPLATE_DIR);
483
+ console.log(' Please reinstall sumulige-claude');
484
+ process.exit(1);
485
+ }
486
+
487
+ // 创建目录结构
488
+ console.log('📁 Creating directory structure...');
489
+ const dirs = [
490
+ path.join(targetDir, '.claude/hooks'),
491
+ path.join(targetDir, '.claude/thinking-routes'),
492
+ path.join(targetDir, '.claude/skills'),
493
+ path.join(targetDir, '.claude/rag'),
494
+ path.join(targetDir, 'prompts')
495
+ ];
496
+
497
+ dirs.forEach(dir => {
498
+ if (!fs.existsSync(dir)) {
499
+ fs.mkdirSync(dir, { recursive: true });
500
+ }
501
+ });
502
+ console.log(' ✅ Directories created');
503
+
504
+ // 复制文件
505
+ console.log('📋 Copying template files...');
506
+
507
+ // 复制 .claude 文件
508
+ const claudeTemplateDir = path.join(TEMPLATE_DIR, '.claude');
509
+ if (fs.existsSync(claudeTemplateDir)) {
510
+ // CLAUDE-template.md
511
+ const claudeTemplate = path.join(claudeTemplateDir, 'CLAUDE-template.md');
512
+ if (fs.existsSync(claudeTemplate)) {
513
+ fs.copyFileSync(claudeTemplate, path.join(targetDir, '.claude/CLAUDE.md'));
514
+ console.log(' ✅ .claude/CLAUDE.md');
515
+ }
516
+
517
+ // settings.json
518
+ const settingsFile = path.join(claudeTemplateDir, 'settings.json');
519
+ if (fs.existsSync(settingsFile)) {
520
+ fs.copyFileSync(settingsFile, path.join(targetDir, '.claude/settings.json'));
521
+ console.log(' ✅ .claude/settings.json');
522
+ }
523
+
524
+ // hooks/
525
+ const hooksDir = path.join(claudeTemplateDir, 'hooks');
526
+ if (fs.existsSync(hooksDir)) {
527
+ const hooks = fs.readdirSync(hooksDir);
528
+ hooks.forEach(hook => {
529
+ const src = path.join(hooksDir, hook);
530
+ const dest = path.join(targetDir, '.claude/hooks', hook);
531
+ fs.copyFileSync(src, dest);
532
+ // 添加执行权限
533
+ if (hook.endsWith('.js') || hook.endsWith('.sh')) {
534
+ fs.chmodSync(dest, 0o755);
535
+ }
536
+ });
537
+ console.log(' ✅ .claude/hooks/ (' + hooks.length + ' files)');
538
+ }
539
+
540
+ // thinking-routes/
541
+ const routesDir = path.join(claudeTemplateDir, 'thinking-routes');
542
+ if (fs.existsSync(routesDir)) {
543
+ const files = fs.readdirSync(routesDir);
544
+ files.forEach(file => {
545
+ fs.copyFileSync(
546
+ path.join(routesDir, file),
547
+ path.join(targetDir, '.claude/thinking-routes', file)
548
+ );
549
+ });
550
+ console.log(' ✅ .claude/thinking-routes/');
551
+ }
552
+
553
+ // rag/
554
+ const ragDir = path.join(claudeTemplateDir, 'rag');
555
+ if (fs.existsSync(ragDir)) {
556
+ const files = fs.readdirSync(ragDir);
557
+ files.forEach(file => {
558
+ fs.copyFileSync(
559
+ path.join(ragDir, file),
560
+ path.join(targetDir, '.claude/rag', file)
561
+ );
562
+ });
563
+ console.log(' ✅ .claude/rag/');
564
+ }
565
+ }
566
+
567
+ // 复制 prompts/
568
+ const promptsDir = path.join(TEMPLATE_DIR, 'prompts');
569
+ if (fs.existsSync(promptsDir)) {
570
+ const files = fs.readdirSync(promptsDir);
571
+ files.forEach(file => {
572
+ fs.copyFileSync(
573
+ path.join(promptsDir, file),
574
+ path.join(targetDir, 'prompts', file)
575
+ );
576
+ });
577
+ console.log(' ✅ prompts/');
578
+ }
579
+
580
+ // 复制根目录文件
581
+ const files = ['project-paradigm.md', 'thinkinglens-silent.md'];
582
+ files.forEach(file => {
583
+ const src = path.join(TEMPLATE_DIR, file);
584
+ if (fs.existsSync(src)) {
585
+ fs.copyFileSync(src, path.join(targetDir, file));
586
+ console.log(' ✅ ' + file);
587
+ }
588
+ });
589
+
590
+ // 创建记忆文件
591
+ console.log('📝 Creating memory files...');
592
+ if (!fs.existsSync(path.join(targetDir, '.claude/MEMORY.md'))) {
593
+ fs.writeFileSync(path.join(targetDir, '.claude/MEMORY.md'), '# Memory\n\n<!-- Project memory updated by AI -->\n');
594
+ }
595
+ if (!fs.existsSync(path.join(targetDir, '.claude/PROJECT_LOG.md'))) {
596
+ fs.writeFileSync(path.join(targetDir, '.claude/PROJECT_LOG.md'), '# Project Log\n\n<!-- Build history and decisions -->\n');
597
+ }
598
+ console.log(' ✅ Memory files created');
599
+
600
+ // 创建 ANCHORS.md
601
+ const anchorsContent = `# [Project Name] - Skill Anchors Index
602
+
603
+ > This file is auto-maintained by AI as a quick index for the skill system
604
+ > Last updated: ${new Date().toISOString().split('T')[0]}
605
+
606
+ ---
607
+
608
+ ## 🚀 AI Startup: Memory Loading Order
609
+
610
+ \`\`\`
611
+ 1. ANCHORS.md (this file) → Quick locate modules
612
+ 2. PROJECT_LOG.md → Understand build history
613
+ 3. MEMORY.md → View latest changes
614
+ 4. CLAUDE.md → Load core knowledge
615
+ 5. prompts/ → View tutorials
616
+ 6. .claude/rag/skills.md → RAG skill index ⭐
617
+ 7. Specific files → Deep dive into implementation
618
+ \`\`\`
619
+
620
+ ---
621
+
622
+ ## Current Anchor Mapping
623
+
624
+ ### Teaching Resources
625
+ | Anchor | File Path | Purpose |
626
+ |--------|-----------|---------|
627
+ | \`[doc:paradigm]\` | \`prompts/project-paradigm.md\` | General development paradigm ⭐ |
628
+ | \`[doc:claude-template]\` | \`.claude/CLAUDE.md\` | CLAUDE.md template for new projects |
629
+
630
+ ### RAG System
631
+ | Anchor | File Path | Purpose |
632
+ |--------|-----------|---------|
633
+ | \`[system:rag-index]\` | \`.claude/rag/skill-index.json\` | Dynamic skill index ⭐ |
634
+
635
+ ---
636
+
637
+ ## Add Your Anchors Here...
638
+
639
+ `;
640
+ fs.writeFileSync(path.join(targetDir, '.claude/ANCHORS.md'), anchorsContent);
641
+ console.log(' ✅ .claude/ANCHORS.md');
642
+
643
+ // 初始化 Sumulige Claude(如果已安装)
644
+ console.log('');
645
+ console.log('🤖 Initializing Sumulige Claude...');
646
+ try {
647
+ execSync('sumulige-claude sync', { cwd: targetDir, stdio: 'pipe' });
648
+ console.log(' ✅ Sumulige Claude synced');
649
+ } catch (e) {
650
+ console.log(' ⚠️ Sumulige Claude not available (run: npm i -g sumulige-claude)');
651
+ }
652
+
653
+ console.log('');
654
+ console.log('✅ Template initialization complete!');
655
+ console.log('');
656
+ console.log('📦 What was included:');
657
+ console.log(' • AI autonomous memory system (ThinkingLens)');
658
+ console.log(' • Sumulige Claude integration');
659
+ console.log(' • RAG dynamic skill index');
660
+ console.log(' • 20+ pre-configured skills');
661
+ console.log('');
662
+ console.log('Next steps:');
663
+ console.log(' 1. Run: sumulige-claude kickoff # 开始项目规划');
664
+ console.log(' 2. Edit .claude/CLAUDE.md with your project info');
665
+ console.log(' 3. Run: sumulige-claude status');
666
+ console.log('');
667
+ },
668
+
669
+ kickoff: () => {
670
+ const projectDir = process.cwd();
671
+ const kickoffFile = path.join(projectDir, 'PROJECT_KICKOFF.md');
672
+ const hintFile = path.join(projectDir, '.claude/.kickoff-hint.txt');
673
+
674
+ console.log('🚀 Project Kickoff - Manus 风格项目启动');
675
+ console.log('');
676
+
677
+ if (fs.existsSync(kickoffFile)) {
678
+ console.log('ℹ️ 项目已经完成启动流程');
679
+ console.log(' 文件:', kickoffFile);
680
+ console.log('');
681
+ console.log('如需重新规划,请先删除以下文件:');
682
+ console.log(' - PROJECT_KICKOFF.md');
683
+ console.log(' - TASK_PLAN.md');
684
+ console.log(' - PROJECT_PROPOSAL.md');
685
+ return;
686
+ }
687
+
688
+ // 运行启动 Hook
689
+ const kickoffHook = path.join(projectDir, '.claude/hooks/project-kickoff.cjs');
690
+ if (fs.existsSync(kickoffHook)) {
691
+ try {
692
+ execSync(`node "${kickoffHook}"`, {
693
+ cwd: projectDir,
694
+ env: { ...process.env, CLAUDE_PROJECT_DIR: projectDir },
695
+ stdio: 'inherit'
696
+ });
697
+ } catch (e) {
698
+ // Hook 可能会输出内容然后退出,这是正常的
699
+ }
700
+
701
+ // 显示提示文件内容(如果存在)
702
+ if (fs.existsSync(hintFile)) {
703
+ const hint = fs.readFileSync(hintFile, 'utf-8');
704
+ console.log(hint);
705
+ }
706
+ } else {
707
+ console.log('⚠️ 启动 Hook 不存在');
708
+ console.log(' 请先运行: sumulige-claude template');
709
+ console.log(' 或: sumulige-claude sync');
710
+ }
711
+ }
712
+ };
713
+
714
+ function loadConfig() {
715
+ if (fs.existsSync(CONFIG_FILE)) {
716
+ return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf-8'));
717
+ }
718
+ return DEFAULT_CONFIG;
719
+ }
720
+
721
+ function toTitleCase(str) {
722
+ return str.replace(/\b\w/g, char => char.toUpperCase());
723
+ }
724
+
725
+ function generateAgentsMd(config) {
726
+ const agentsList = Object.entries(config.agents)
727
+ .map(([name, agent]) => `### ${name}\n- **Model**: ${agent.model}\n- **Role**: ${agent.role}`)
728
+ .join('\n\n');
729
+
730
+ return `# AGENTS
731
+
732
+ <skills_system priority="1">
733
+
734
+ ## Agent Orchestration
735
+
736
+ This project uses **Sumulige Claude** for multi-agent collaboration.
737
+
738
+ ${agentsList}
739
+
740
+ ## Usage
741
+
742
+ \`\`\`bash
743
+ # View agent status
744
+ sumulige-claude status
745
+
746
+ # Run agent task
747
+ sumulige-claude agent <task>
748
+
749
+ # List skills
750
+ sumulige-claude skill:list
751
+ \`\`\`
752
+
753
+ </skills_system>
754
+ `;
755
+ }
756
+
757
+ // CLI 入口
758
+ function main() {
759
+ const args = process.argv.slice(2);
760
+ const cmd = args[0];
761
+ const arg = args[1];
762
+
763
+ if (cmd === 'init') {
764
+ commands.init();
765
+ } else if (cmd === 'sync') {
766
+ commands.sync();
767
+ } else if (cmd === 'agent') {
768
+ commands.agent(arg);
769
+ } else if (cmd === 'status') {
770
+ commands.status();
771
+ } else if (cmd === 'skill:list') {
772
+ commands['skill:list']();
773
+ } else if (cmd === 'skill:create') {
774
+ commands['skill:create'](arg);
775
+ } else if (cmd === 'skill:check') {
776
+ commands['skill:check'](arg);
777
+ } else if (cmd === 'skill:install') {
778
+ commands['skill:install'](arg);
779
+ } else if (cmd === 'template') {
780
+ commands.template(arg);
781
+ } else if (cmd === 'kickoff') {
782
+ commands.kickoff();
783
+ } else {
784
+ console.log('Sumulige Claude (smc) - Agent Harness for Claude Code');
785
+ console.log('');
786
+ console.log('Usage: smc <command> [args]');
787
+ console.log(' (or: sumulige-claude <command> [args])');
788
+ console.log('');
789
+ console.log('Commands:');
790
+ console.log(' init Initialize configuration');
791
+ console.log(' sync Sync to current project');
792
+ console.log(' template [path] Deploy Claude Code project template');
793
+ console.log(' kickoff Start project planning workflow (Manus-style)');
794
+ console.log(' agent <task> Run agent orchestration');
795
+ console.log(' status Show configuration status');
796
+ console.log(' skill:list List installed skills');
797
+ console.log(' skill:create <n> Create a new skill');
798
+ console.log(' skill:check [n] Check skill dependencies');
799
+ console.log(' skill:install <s> Install a skill');
800
+ console.log('');
801
+ console.log('Examples:');
802
+ console.log(' smc init');
803
+ console.log(' smc sync');
804
+ console.log(' smc template');
805
+ console.log(' smc template /path/to/project');
806
+ console.log(' smc kickoff # Start project planning');
807
+ console.log(' smc agent "Build a REST API"');
808
+ console.log(' smc skill:create api-tester');
809
+ console.log(' smc skill:check manus-kickoff');
810
+ console.log(' smc skill:install anthropics/skills');
811
+ }
812
+ }
813
+
814
+ main();