sumulige-claude 1.0.5 → 1.0.7
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/.kickoff-hint.txt +51 -0
- package/.claude/ANCHORS.md +40 -0
- package/.claude/MEMORY.md +34 -0
- package/.claude/PROJECT_LOG.md +101 -0
- package/.claude/THINKING_CHAIN_GUIDE.md +287 -0
- package/.claude/commands/commit-push-pr.md +59 -0
- package/.claude/commands/commit.md +53 -0
- package/.claude/commands/pr.md +76 -0
- package/.claude/commands/review.md +61 -0
- package/.claude/commands/sessions.md +62 -0
- package/.claude/commands/skill-create.md +131 -0
- package/.claude/commands/test.md +56 -0
- package/.claude/commands/todos.md +99 -0
- package/.claude/commands/verify-work.md +63 -0
- package/.claude/hooks/code-formatter.cjs +187 -0
- package/.claude/hooks/code-tracer.cjs +331 -0
- package/.claude/hooks/conversation-recorder.cjs +340 -0
- package/.claude/hooks/decision-tracker.cjs +398 -0
- package/.claude/hooks/export.cjs +329 -0
- package/.claude/hooks/multi-session.cjs +181 -0
- package/.claude/hooks/privacy-filter.js +224 -0
- package/.claude/hooks/project-kickoff.cjs +114 -0
- package/.claude/hooks/rag-skill-loader.cjs +159 -0
- package/.claude/hooks/session-end.sh +61 -0
- package/.claude/hooks/sync-to-log.sh +83 -0
- package/.claude/hooks/thinking-silent.cjs +145 -0
- package/.claude/hooks/tl-summary.sh +54 -0
- package/.claude/hooks/todo-manager.cjs +248 -0
- package/.claude/hooks/verify-work.cjs +134 -0
- package/.claude/sessions/active-sessions.json +444 -0
- package/.claude/settings.local.json +36 -2
- package/.claude/thinking-routes/.last-sync +1 -0
- package/.claude/thinking-routes/QUICKREF.md +98 -0
- package/CHANGELOG.md +56 -0
- package/DEV_TOOLS_GUIDE.md +190 -0
- package/PROJECT_STRUCTURE.md +10 -1
- package/README.md +20 -6
- package/cli.js +85 -824
- package/config/defaults.json +34 -0
- package/development/todos/INDEX.md +14 -58
- package/lib/commands.js +698 -0
- package/lib/config.js +71 -0
- package/lib/utils.js +62 -0
- package/package.json +2 -2
package/cli.js
CHANGED
|
@@ -8,855 +8,116 @@
|
|
|
8
8
|
* - Skills management via OpenSkills
|
|
9
9
|
* - Built-in Claude Code project template
|
|
10
10
|
* - ThinkingLens conversation tracking
|
|
11
|
+
*
|
|
12
|
+
* @version 1.0.7
|
|
11
13
|
*/
|
|
12
14
|
|
|
13
|
-
const
|
|
14
|
-
const path = require('path');
|
|
15
|
-
const { execSync } = require('child_process');
|
|
15
|
+
const { runCommand } = require('./lib/commands');
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const TEMPLATE_DIR = path.join(__dirname, 'template');
|
|
17
|
+
// ============================================================================
|
|
18
|
+
// Command Registry (data-driven, no if-else chains)
|
|
19
|
+
// ============================================================================
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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' }
|
|
21
|
+
const COMMANDS = {
|
|
22
|
+
init: {
|
|
23
|
+
help: 'Initialize configuration',
|
|
24
|
+
args: ''
|
|
31
25
|
},
|
|
32
|
-
|
|
33
|
-
'
|
|
34
|
-
'
|
|
35
|
-
],
|
|
36
|
-
hooks: {
|
|
37
|
-
preTask: [],
|
|
38
|
-
postTask: []
|
|
26
|
+
sync: {
|
|
27
|
+
help: 'Sync to current project',
|
|
28
|
+
args: ''
|
|
39
29
|
},
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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');
|
|
30
|
+
template: {
|
|
31
|
+
help: 'Deploy Claude Code project template',
|
|
32
|
+
args: '[path]'
|
|
92
33
|
},
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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!');
|
|
34
|
+
kickoff: {
|
|
35
|
+
help: 'Start project planning workflow (Manus-style)',
|
|
36
|
+
args: ''
|
|
172
37
|
},
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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');
|
|
38
|
+
agent: {
|
|
39
|
+
help: 'Run agent orchestration',
|
|
40
|
+
args: '<task>'
|
|
193
41
|
},
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
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}`);
|
|
42
|
+
status: {
|
|
43
|
+
help: 'Show configuration status',
|
|
44
|
+
args: ''
|
|
370
45
|
},
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
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
|
-
}
|
|
46
|
+
'skill:list': {
|
|
47
|
+
help: 'List installed skills',
|
|
48
|
+
args: ''
|
|
456
49
|
},
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
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
|
-
}
|
|
50
|
+
'skill:create': {
|
|
51
|
+
help: 'Create a new skill',
|
|
52
|
+
args: '<name>'
|
|
471
53
|
},
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
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
|
-
const copyRecursive = (src, dest, overwrite = false) => {
|
|
489
|
-
if (!fs.existsSync(src)) return 0;
|
|
490
|
-
|
|
491
|
-
if (!fs.existsSync(dest)) {
|
|
492
|
-
fs.mkdirSync(dest, { recursive: true });
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
let count = 0;
|
|
496
|
-
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
497
|
-
|
|
498
|
-
for (const entry of entries) {
|
|
499
|
-
const srcPath = path.join(src, entry.name);
|
|
500
|
-
const destPath = path.join(dest, entry.name);
|
|
501
|
-
|
|
502
|
-
if (entry.isDirectory()) {
|
|
503
|
-
count += copyRecursive(srcPath, destPath, overwrite);
|
|
504
|
-
} else {
|
|
505
|
-
if (overwrite || !fs.existsSync(destPath)) {
|
|
506
|
-
fs.copyFileSync(srcPath, destPath);
|
|
507
|
-
// 添加执行权限
|
|
508
|
-
if (entry.name.endsWith('.sh') || entry.name.endsWith('.cjs')) {
|
|
509
|
-
fs.chmodSync(destPath, 0o755);
|
|
510
|
-
}
|
|
511
|
-
count++;
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
return count;
|
|
516
|
-
};
|
|
517
|
-
|
|
518
|
-
// 创建目录结构
|
|
519
|
-
console.log('📁 Creating directory structure...');
|
|
520
|
-
const dirs = [
|
|
521
|
-
path.join(targetDir, '.claude'),
|
|
522
|
-
path.join(targetDir, 'prompts'),
|
|
523
|
-
path.join(targetDir, 'development/todos/active'),
|
|
524
|
-
path.join(targetDir, 'development/todos/completed'),
|
|
525
|
-
path.join(targetDir, 'development/todos/backlog'),
|
|
526
|
-
path.join(targetDir, 'development/todos/archived')
|
|
527
|
-
];
|
|
528
|
-
|
|
529
|
-
dirs.forEach(dir => {
|
|
530
|
-
if (!fs.existsSync(dir)) {
|
|
531
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
532
|
-
}
|
|
533
|
-
});
|
|
534
|
-
console.log(' ✅ Directories created');
|
|
535
|
-
|
|
536
|
-
// 复制文件
|
|
537
|
-
console.log('📋 Copying template files...');
|
|
538
|
-
|
|
539
|
-
const claudeTemplateDir = path.join(TEMPLATE_DIR, '.claude');
|
|
540
|
-
const targetClaudeDir = path.join(targetDir, '.claude');
|
|
541
|
-
|
|
542
|
-
// 1. CLAUDE.md (从 CLAUDE-template.md)
|
|
543
|
-
const claudeTemplate = path.join(claudeTemplateDir, 'CLAUDE-template.md');
|
|
544
|
-
if (fs.existsSync(claudeTemplate)) {
|
|
545
|
-
fs.copyFileSync(claudeTemplate, path.join(targetClaudeDir, 'CLAUDE.md'));
|
|
546
|
-
console.log(' ✅ .claude/CLAUDE.md');
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
// 2. README.md
|
|
550
|
-
const readmeFile = path.join(claudeTemplateDir, 'README.md');
|
|
551
|
-
if (fs.existsSync(readmeFile)) {
|
|
552
|
-
fs.copyFileSync(readmeFile, path.join(targetClaudeDir, 'README.md'));
|
|
553
|
-
console.log(' ✅ .claude/README.md');
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
// 3. settings.json
|
|
557
|
-
const settingsFile = path.join(claudeTemplateDir, 'settings.json');
|
|
558
|
-
if (fs.existsSync(settingsFile)) {
|
|
559
|
-
fs.copyFileSync(settingsFile, path.join(targetClaudeDir, 'settings.json'));
|
|
560
|
-
console.log(' ✅ .claude/settings.json');
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
// 4. boris-optimizations.md
|
|
564
|
-
const borisFile = path.join(claudeTemplateDir, 'boris-optimizations.md');
|
|
565
|
-
if (fs.existsSync(borisFile)) {
|
|
566
|
-
fs.copyFileSync(borisFile, path.join(targetClaudeDir, 'boris-optimizations.md'));
|
|
567
|
-
console.log(' ✅ .claude/boris-optimizations.md');
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
// 5. hooks/ (递归复制)
|
|
571
|
-
const hooksDir = path.join(claudeTemplateDir, 'hooks');
|
|
572
|
-
if (fs.existsSync(hooksDir)) {
|
|
573
|
-
const count = copyRecursive(hooksDir, path.join(targetClaudeDir, 'hooks'), true);
|
|
574
|
-
console.log(` ✅ .claude/hooks/ (${count} files)`);
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
// 6. commands/ (递归复制) ⭐ 新增
|
|
578
|
-
const commandsDir = path.join(claudeTemplateDir, 'commands');
|
|
579
|
-
if (fs.existsSync(commandsDir)) {
|
|
580
|
-
const count = copyRecursive(commandsDir, path.join(targetClaudeDir, 'commands'), true);
|
|
581
|
-
console.log(` ✅ .claude/commands/ (${count} files)`);
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
// 7. skills/ (递归复制) ⭐ 新增
|
|
585
|
-
const skillsDir = path.join(claudeTemplateDir, 'skills');
|
|
586
|
-
if (fs.existsSync(skillsDir)) {
|
|
587
|
-
const count = copyRecursive(skillsDir, path.join(targetClaudeDir, 'skills'), false);
|
|
588
|
-
console.log(` ✅ .claude/skills/ (${count} files)`);
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
// 8. templates/ (递归复制) ⭐ 新增
|
|
592
|
-
const templatesDir = path.join(claudeTemplateDir, 'templates');
|
|
593
|
-
if (fs.existsSync(templatesDir)) {
|
|
594
|
-
const count = copyRecursive(templatesDir, path.join(targetClaudeDir, 'templates'), false);
|
|
595
|
-
console.log(` ✅ .claude/templates/ (${count} files)`);
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
// 9. thinking-routes/
|
|
599
|
-
const routesDir = path.join(claudeTemplateDir, 'thinking-routes');
|
|
600
|
-
if (fs.existsSync(routesDir)) {
|
|
601
|
-
const count = copyRecursive(routesDir, path.join(targetClaudeDir, 'thinking-routes'), false);
|
|
602
|
-
console.log(` ✅ .claude/thinking-routes/ (${count} files)`);
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
// 10. rag/
|
|
606
|
-
const ragDir = path.join(claudeTemplateDir, 'rag');
|
|
607
|
-
if (fs.existsSync(ragDir)) {
|
|
608
|
-
const count = copyRecursive(ragDir, path.join(targetClaudeDir, 'rag'), true);
|
|
609
|
-
console.log(` ✅ .claude/rag/ (${count} files)`);
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
// 11. prompts/
|
|
613
|
-
const promptsDir = path.join(TEMPLATE_DIR, 'prompts');
|
|
614
|
-
if (fs.existsSync(promptsDir)) {
|
|
615
|
-
const count = copyRecursive(promptsDir, path.join(targetDir, 'prompts'), false);
|
|
616
|
-
console.log(` ✅ prompts/ (${count} files)`);
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
// 12. development/todos/
|
|
620
|
-
const todosDir = path.join(TEMPLATE_DIR, 'development', 'todos');
|
|
621
|
-
if (fs.existsSync(todosDir)) {
|
|
622
|
-
const count = copyRecursive(todosDir, path.join(targetDir, 'development', 'todos'), false);
|
|
623
|
-
console.log(` ✅ development/todos/ (${count} files)`);
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
// 13. 根目录文件
|
|
627
|
-
const rootFiles = ['project-paradigm.md', 'thinkinglens-silent.md', 'CLAUDE-template.md'];
|
|
628
|
-
rootFiles.forEach(file => {
|
|
629
|
-
const src = path.join(TEMPLATE_DIR, file);
|
|
630
|
-
if (fs.existsSync(src)) {
|
|
631
|
-
fs.copyFileSync(src, path.join(targetDir, file));
|
|
632
|
-
console.log(' ✅ ' + file);
|
|
633
|
-
}
|
|
634
|
-
});
|
|
635
|
-
|
|
636
|
-
// 创建记忆文件
|
|
637
|
-
console.log('📝 Creating memory files...');
|
|
638
|
-
if (!fs.existsSync(path.join(targetClaudeDir, 'MEMORY.md'))) {
|
|
639
|
-
fs.writeFileSync(path.join(targetClaudeDir, 'MEMORY.md'), '# Memory\n\n<!-- Project memory updated by AI -->\n');
|
|
640
|
-
}
|
|
641
|
-
if (!fs.existsSync(path.join(targetClaudeDir, 'PROJECT_LOG.md'))) {
|
|
642
|
-
fs.writeFileSync(path.join(targetClaudeDir, 'PROJECT_LOG.md'), '# Project Log\n\n<!-- Build history and decisions -->\n');
|
|
643
|
-
}
|
|
644
|
-
console.log(' ✅ Memory files created');
|
|
645
|
-
|
|
646
|
-
// 创建 ANCHORS.md
|
|
647
|
-
const anchorsContent = `# [Project Name] - Skill Anchors Index
|
|
648
|
-
|
|
649
|
-
> This file is auto-maintained by AI as a quick index for the skill system
|
|
650
|
-
> Last updated: ${new Date().toISOString().split('T')[0]}
|
|
651
|
-
|
|
652
|
-
---
|
|
653
|
-
|
|
654
|
-
## 🚀 AI Startup: Memory Loading Order
|
|
655
|
-
|
|
656
|
-
\`\`\`
|
|
657
|
-
1. ANCHORS.md (this file) → Quick locate modules
|
|
658
|
-
2. PROJECT_LOG.md → Understand build history
|
|
659
|
-
3. MEMORY.md → View latest changes
|
|
660
|
-
4. CLAUDE.md → Load core knowledge
|
|
661
|
-
5. prompts/ → View tutorials
|
|
662
|
-
6. .claude/rag/skills.md → RAG skill index ⭐
|
|
663
|
-
7. Specific files → Deep dive into implementation
|
|
664
|
-
\`\`\`
|
|
665
|
-
|
|
666
|
-
---
|
|
667
|
-
|
|
668
|
-
## Current Anchor Mapping
|
|
669
|
-
|
|
670
|
-
### Teaching Resources
|
|
671
|
-
| Anchor | File Path | Purpose |
|
|
672
|
-
|--------|-----------|---------|
|
|
673
|
-
| \`[doc:paradigm]\` | \`prompts/project-paradigm.md\` | General development paradigm ⭐ |
|
|
674
|
-
| \`[doc:claude-template]\` | \`.claude/CLAUDE.md\` | CLAUDE.md template for new projects |
|
|
675
|
-
|
|
676
|
-
### RAG System
|
|
677
|
-
| Anchor | File Path | Purpose |
|
|
678
|
-
|--------|-----------|---------|
|
|
679
|
-
| \`[system:rag-index]\` | \`.claude/rag/skill-index.json\` | Dynamic skill index ⭐ |
|
|
680
|
-
|
|
681
|
-
---
|
|
682
|
-
|
|
683
|
-
## Add Your Anchors Here...
|
|
684
|
-
|
|
685
|
-
`;
|
|
686
|
-
fs.writeFileSync(path.join(targetClaudeDir, 'ANCHORS.md'), anchorsContent);
|
|
687
|
-
console.log(' ✅ .claude/ANCHORS.md');
|
|
688
|
-
|
|
689
|
-
// 初始化 Sumulige Claude(如果已安装)
|
|
690
|
-
console.log('');
|
|
691
|
-
console.log('🤖 Initializing Sumulige Claude...');
|
|
692
|
-
try {
|
|
693
|
-
execSync('sumulige-claude sync', { cwd: targetDir, stdio: 'pipe' });
|
|
694
|
-
console.log(' ✅ Sumulige Claude synced');
|
|
695
|
-
} catch (e) {
|
|
696
|
-
console.log(' ⚠️ Sumulige Claude not available (run: npm i -g sumulige-claude)');
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
console.log('');
|
|
700
|
-
console.log('✅ Template initialization complete!');
|
|
701
|
-
console.log('');
|
|
702
|
-
console.log('📦 What was included:');
|
|
703
|
-
console.log(' • AI autonomous memory system (ThinkingLens)');
|
|
704
|
-
console.log(' • Slash commands (/commit, /test, /review, etc.)');
|
|
705
|
-
console.log(' • Skills system with templates');
|
|
706
|
-
console.log(' • RAG dynamic skill index');
|
|
707
|
-
console.log(' • Hooks for automation');
|
|
708
|
-
console.log(' • TODO management system');
|
|
709
|
-
console.log('');
|
|
710
|
-
console.log('Next steps:');
|
|
711
|
-
console.log(' 1. Edit .claude/CLAUDE.md with your project info');
|
|
712
|
-
console.log(' 2. Run: claude # Start Claude Code');
|
|
713
|
-
console.log(' 3. Try: /commit, /test, /review');
|
|
714
|
-
console.log('');
|
|
54
|
+
'skill:check': {
|
|
55
|
+
help: 'Check skill dependencies',
|
|
56
|
+
args: '[name]'
|
|
715
57
|
},
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
const kickoffFile = path.join(projectDir, 'PROJECT_KICKOFF.md');
|
|
720
|
-
const hintFile = path.join(projectDir, '.claude/.kickoff-hint.txt');
|
|
721
|
-
|
|
722
|
-
console.log('🚀 Project Kickoff - Manus 风格项目启动');
|
|
723
|
-
console.log('');
|
|
724
|
-
|
|
725
|
-
if (fs.existsSync(kickoffFile)) {
|
|
726
|
-
console.log('ℹ️ 项目已经完成启动流程');
|
|
727
|
-
console.log(' 文件:', kickoffFile);
|
|
728
|
-
console.log('');
|
|
729
|
-
console.log('如需重新规划,请先删除以下文件:');
|
|
730
|
-
console.log(' - PROJECT_KICKOFF.md');
|
|
731
|
-
console.log(' - TASK_PLAN.md');
|
|
732
|
-
console.log(' - PROJECT_PROPOSAL.md');
|
|
733
|
-
return;
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
// 运行启动 Hook
|
|
737
|
-
const kickoffHook = path.join(projectDir, '.claude/hooks/project-kickoff.cjs');
|
|
738
|
-
if (fs.existsSync(kickoffHook)) {
|
|
739
|
-
try {
|
|
740
|
-
execSync(`node "${kickoffHook}"`, {
|
|
741
|
-
cwd: projectDir,
|
|
742
|
-
env: { ...process.env, CLAUDE_PROJECT_DIR: projectDir },
|
|
743
|
-
stdio: 'inherit'
|
|
744
|
-
});
|
|
745
|
-
} catch (e) {
|
|
746
|
-
// Hook 可能会输出内容然后退出,这是正常的
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
// 显示提示文件内容(如果存在)
|
|
750
|
-
if (fs.existsSync(hintFile)) {
|
|
751
|
-
const hint = fs.readFileSync(hintFile, 'utf-8');
|
|
752
|
-
console.log(hint);
|
|
753
|
-
}
|
|
754
|
-
} else {
|
|
755
|
-
console.log('⚠️ 启动 Hook 不存在');
|
|
756
|
-
console.log(' 请先运行: sumulige-claude template');
|
|
757
|
-
console.log(' 或: sumulige-claude sync');
|
|
758
|
-
}
|
|
58
|
+
'skill:install': {
|
|
59
|
+
help: 'Install a skill',
|
|
60
|
+
args: '<source>'
|
|
759
61
|
}
|
|
760
62
|
};
|
|
761
63
|
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
64
|
+
// ============================================================================
|
|
65
|
+
// Help Display
|
|
66
|
+
// ============================================================================
|
|
67
|
+
|
|
68
|
+
function showHelp() {
|
|
69
|
+
console.log('Sumulige Claude (smc) - Agent Harness for Claude Code');
|
|
70
|
+
console.log('');
|
|
71
|
+
console.log('Usage: smc <command> [args]');
|
|
72
|
+
console.log(' (or: sumulige-claude <command> [args])');
|
|
73
|
+
console.log('');
|
|
74
|
+
console.log('Commands:');
|
|
75
|
+
|
|
76
|
+
const maxCmdLen = Math.max(...Object.keys(COMMANDS).map(k => k.length));
|
|
77
|
+
|
|
78
|
+
Object.entries(COMMANDS).forEach(([cmd, info]) => {
|
|
79
|
+
const cmdPad = cmd.padEnd(maxCmdLen);
|
|
80
|
+
const args = info.args ? ' ' + info.args : '';
|
|
81
|
+
const argsPad = args.padEnd(10);
|
|
82
|
+
console.log(` ${cmdPad}${argsPad} ${info.help}`);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
console.log('');
|
|
86
|
+
console.log('Examples:');
|
|
87
|
+
console.log(' smc init');
|
|
88
|
+
console.log(' smc sync');
|
|
89
|
+
console.log(' smc template');
|
|
90
|
+
console.log(' smc template /path/to/project');
|
|
91
|
+
console.log(' smc kickoff # Start project planning');
|
|
92
|
+
console.log(' smc agent "Build a REST API"');
|
|
93
|
+
console.log(' smc skill:create api-tester');
|
|
94
|
+
console.log(' smc skill:check manus-kickoff');
|
|
95
|
+
console.log(' smc skill:install anthropics/skills');
|
|
767
96
|
}
|
|
768
97
|
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
function generateAgentsMd(config) {
|
|
774
|
-
const agentsList = Object.entries(config.agents)
|
|
775
|
-
.map(([name, agent]) => `### ${name}\n- **Model**: ${agent.model}\n- **Role**: ${agent.role}`)
|
|
776
|
-
.join('\n\n');
|
|
777
|
-
|
|
778
|
-
return `# AGENTS
|
|
779
|
-
|
|
780
|
-
<skills_system priority="1">
|
|
781
|
-
|
|
782
|
-
## Agent Orchestration
|
|
783
|
-
|
|
784
|
-
This project uses **Sumulige Claude** for multi-agent collaboration.
|
|
785
|
-
|
|
786
|
-
${agentsList}
|
|
98
|
+
// ============================================================================
|
|
99
|
+
// Main Entry
|
|
100
|
+
// ============================================================================
|
|
787
101
|
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
\`\`\`bash
|
|
791
|
-
# View agent status
|
|
792
|
-
sumulige-claude status
|
|
793
|
-
|
|
794
|
-
# Run agent task
|
|
795
|
-
sumulige-claude agent <task>
|
|
796
|
-
|
|
797
|
-
# List skills
|
|
798
|
-
sumulige-claude skill:list
|
|
799
|
-
\`\`\`
|
|
102
|
+
function main() {
|
|
103
|
+
const [cmd, ...args] = process.argv.slice(2);
|
|
800
104
|
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
105
|
+
if (!cmd) {
|
|
106
|
+
showHelp();
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
804
109
|
|
|
805
|
-
|
|
806
|
-
function main() {
|
|
807
|
-
const args = process.argv.slice(2);
|
|
808
|
-
const cmd = args[0];
|
|
809
|
-
const arg = args[1];
|
|
110
|
+
const handler = COMMANDS[cmd];
|
|
810
111
|
|
|
811
|
-
if (
|
|
812
|
-
|
|
813
|
-
} else if (cmd === 'sync') {
|
|
814
|
-
commands.sync();
|
|
815
|
-
} else if (cmd === 'agent') {
|
|
816
|
-
commands.agent(arg);
|
|
817
|
-
} else if (cmd === 'status') {
|
|
818
|
-
commands.status();
|
|
819
|
-
} else if (cmd === 'skill:list') {
|
|
820
|
-
commands['skill:list']();
|
|
821
|
-
} else if (cmd === 'skill:create') {
|
|
822
|
-
commands['skill:create'](arg);
|
|
823
|
-
} else if (cmd === 'skill:check') {
|
|
824
|
-
commands['skill:check'](arg);
|
|
825
|
-
} else if (cmd === 'skill:install') {
|
|
826
|
-
commands['skill:install'](arg);
|
|
827
|
-
} else if (cmd === 'template') {
|
|
828
|
-
commands.template(arg);
|
|
829
|
-
} else if (cmd === 'kickoff') {
|
|
830
|
-
commands.kickoff();
|
|
112
|
+
if (handler) {
|
|
113
|
+
runCommand(cmd, args);
|
|
831
114
|
} else {
|
|
832
|
-
console.log(
|
|
833
|
-
console.log('');
|
|
834
|
-
console.log('Usage: smc <command> [args]');
|
|
835
|
-
console.log(' (or: sumulige-claude <command> [args])');
|
|
836
|
-
console.log('');
|
|
837
|
-
console.log('Commands:');
|
|
838
|
-
console.log(' init Initialize configuration');
|
|
839
|
-
console.log(' sync Sync to current project');
|
|
840
|
-
console.log(' template [path] Deploy Claude Code project template');
|
|
841
|
-
console.log(' kickoff Start project planning workflow (Manus-style)');
|
|
842
|
-
console.log(' agent <task> Run agent orchestration');
|
|
843
|
-
console.log(' status Show configuration status');
|
|
844
|
-
console.log(' skill:list List installed skills');
|
|
845
|
-
console.log(' skill:create <n> Create a new skill');
|
|
846
|
-
console.log(' skill:check [n] Check skill dependencies');
|
|
847
|
-
console.log(' skill:install <s> Install a skill');
|
|
115
|
+
console.log(`Unknown command: ${cmd}`);
|
|
848
116
|
console.log('');
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
console.log(' smc sync');
|
|
852
|
-
console.log(' smc template');
|
|
853
|
-
console.log(' smc template /path/to/project');
|
|
854
|
-
console.log(' smc kickoff # Start project planning');
|
|
855
|
-
console.log(' smc agent "Build a REST API"');
|
|
856
|
-
console.log(' smc skill:create api-tester');
|
|
857
|
-
console.log(' smc skill:check manus-kickoff');
|
|
858
|
-
console.log(' smc skill:install anthropics/skills');
|
|
117
|
+
showHelp();
|
|
118
|
+
process.exit(1);
|
|
859
119
|
}
|
|
860
120
|
}
|
|
861
121
|
|
|
122
|
+
// Run
|
|
862
123
|
main();
|