sdd-full 1.4.3 → 1.5.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/bin.js +225 -0
- package/package.json +4 -3
package/bin.js
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// sdd-full npm 包 CLI 入口
|
|
4
|
+
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
|
|
8
|
+
const SDD = {
|
|
9
|
+
version: '1.5.1',
|
|
10
|
+
name: 'sdd-full',
|
|
11
|
+
description: '完整的软件设计开发技能包'
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
let VERBOSE = false;
|
|
15
|
+
|
|
16
|
+
function debug(msg) {
|
|
17
|
+
if (VERBOSE) {
|
|
18
|
+
console.log(`[DEBUG] ${msg}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function copyDirectory(src, dest) {
|
|
23
|
+
debug(`copyDirectory: ${src} -> ${dest}`);
|
|
24
|
+
|
|
25
|
+
if (!fs.existsSync(dest)) {
|
|
26
|
+
debug(`创建目录: ${dest}`);
|
|
27
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const items = fs.readdirSync(src);
|
|
31
|
+
debug(`源目录内容: ${items.length} 项`);
|
|
32
|
+
|
|
33
|
+
items.forEach(item => {
|
|
34
|
+
const srcPath = path.join(src, item);
|
|
35
|
+
const destPath = path.join(dest, item);
|
|
36
|
+
const stat = fs.statSync(srcPath);
|
|
37
|
+
|
|
38
|
+
if (stat.isDirectory()) {
|
|
39
|
+
copyDirectory(srcPath, destPath);
|
|
40
|
+
} else {
|
|
41
|
+
debug(`复制文件: ${item}`);
|
|
42
|
+
fs.copyFileSync(srcPath, destPath);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function getSkills() {
|
|
48
|
+
const skillsDir = path.join(__dirname, 'skills');
|
|
49
|
+
debug(`技能目录: ${skillsDir}`);
|
|
50
|
+
debug(`技能目录存在: ${fs.existsSync(skillsDir)}`);
|
|
51
|
+
|
|
52
|
+
const skills = [];
|
|
53
|
+
|
|
54
|
+
if (fs.existsSync(skillsDir)) {
|
|
55
|
+
const items = fs.readdirSync(skillsDir);
|
|
56
|
+
|
|
57
|
+
items.forEach(item => {
|
|
58
|
+
const itemPath = path.join(skillsDir, item);
|
|
59
|
+
const stat = fs.statSync(itemPath);
|
|
60
|
+
|
|
61
|
+
if (stat.isDirectory() && !item.endsWith('.md')) {
|
|
62
|
+
const skillPath = path.join(itemPath, 'SKILL.md');
|
|
63
|
+
if (fs.existsSync(skillPath)) {
|
|
64
|
+
skills.push(item);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
debug(`找到技能: ${skills.length} 个`);
|
|
71
|
+
return skills;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function install(targetDir, environment) {
|
|
75
|
+
const baseDir = targetDir || process.cwd();
|
|
76
|
+
debug(`安装基准目录: ${baseDir}`);
|
|
77
|
+
debug(`环境: ${environment}`);
|
|
78
|
+
|
|
79
|
+
console.log('========================================');
|
|
80
|
+
console.log(` ${SDD.name} - ${SDD.description}`);
|
|
81
|
+
console.log(` 版本: ${SDD.version}`);
|
|
82
|
+
console.log('========================================');
|
|
83
|
+
|
|
84
|
+
const sourceDir = path.join(__dirname, 'skills');
|
|
85
|
+
debug(`技能源目录: ${sourceDir}`);
|
|
86
|
+
debug(`技能源目录存在: ${fs.existsSync(sourceDir)}`);
|
|
87
|
+
|
|
88
|
+
// 根据环境选择安装目录
|
|
89
|
+
let dirsToInstall;
|
|
90
|
+
|
|
91
|
+
if (environment === 'cc') {
|
|
92
|
+
dirsToInstall = [
|
|
93
|
+
{ name: 'Claude Code', path: path.join(baseDir, '.claude', 'skills') }
|
|
94
|
+
];
|
|
95
|
+
} else if (environment === 'all') {
|
|
96
|
+
dirsToInstall = [
|
|
97
|
+
{ name: 'Trae / Solo', path: path.join(baseDir, '.trae', 'skills') },
|
|
98
|
+
{ name: 'Claude Code', path: path.join(baseDir, '.claude', 'skills') },
|
|
99
|
+
{ name: '通用 sdd-full', path: path.join(baseDir, '.sdd-full', 'skills') }
|
|
100
|
+
];
|
|
101
|
+
} else {
|
|
102
|
+
// 默认:Trae / Solo
|
|
103
|
+
dirsToInstall = [
|
|
104
|
+
{ name: 'Trae / Solo', path: path.join(baseDir, '.trae', 'skills') }
|
|
105
|
+
];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
let totalCount = 0;
|
|
109
|
+
|
|
110
|
+
dirsToInstall.forEach(dirInfo => {
|
|
111
|
+
const destDir = dirInfo.path;
|
|
112
|
+
debug(`安装目标: ${dirInfo.name} -> ${destDir}`);
|
|
113
|
+
|
|
114
|
+
console.log(`\n正在安装到: ${dirInfo.name} (${destDir})`);
|
|
115
|
+
|
|
116
|
+
if (!fs.existsSync(destDir)) {
|
|
117
|
+
debug(`创建目标目录: ${destDir}`);
|
|
118
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
let count = 0;
|
|
122
|
+
if (fs.existsSync(sourceDir)) {
|
|
123
|
+
const items = fs.readdirSync(sourceDir);
|
|
124
|
+
debug(`源目录内容: ${items.join(', ')}`);
|
|
125
|
+
|
|
126
|
+
items.forEach(item => {
|
|
127
|
+
const srcItem = path.join(sourceDir, item);
|
|
128
|
+
const destItem = path.join(destDir, item);
|
|
129
|
+
const stat = fs.statSync(srcItem);
|
|
130
|
+
|
|
131
|
+
if (stat.isDirectory()) {
|
|
132
|
+
debug(`复制目录: ${item}`);
|
|
133
|
+
copyDirectory(srcItem, destItem);
|
|
134
|
+
count++;
|
|
135
|
+
} else if (stat.isFile() && item.endsWith('.md')) {
|
|
136
|
+
debug(`复制文件: ${item}`);
|
|
137
|
+
fs.copyFileSync(srcItem, destItem);
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
totalCount += count;
|
|
143
|
+
console.log(` ✅ ${count} 个技能`);
|
|
144
|
+
|
|
145
|
+
// 验证安装结果
|
|
146
|
+
if (fs.existsSync(destDir)) {
|
|
147
|
+
const installedItems = fs.readdirSync(destDir);
|
|
148
|
+
debug(`目标目录内容: ${installedItems.join(', ')}`);
|
|
149
|
+
console.log(` 📁 已安装内容: ${installedItems.length} 项`);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
console.log('\n========================================');
|
|
154
|
+
console.log(`✅ 安装完成!共安装 ${totalCount} 个技能!`);
|
|
155
|
+
console.log('========================================');
|
|
156
|
+
console.log('\n现在您可以在以下环境中使用这些技能:');
|
|
157
|
+
dirsToInstall.forEach(dirInfo => {
|
|
158
|
+
console.log(` - ${dirInfo.name}`);
|
|
159
|
+
console.log(` 位置: ${dirInfo.path}`);
|
|
160
|
+
});
|
|
161
|
+
console.log('\n🎉 开始使用吧!\n');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// 主入口
|
|
165
|
+
function main() {
|
|
166
|
+
const args = process.argv.slice(2);
|
|
167
|
+
|
|
168
|
+
// 检查是否启用 verbose
|
|
169
|
+
VERBOSE = args.some(arg => arg === '--verbose' || arg === '-v');
|
|
170
|
+
if (VERBOSE) {
|
|
171
|
+
debug(`Verbose 模式已启用`);
|
|
172
|
+
debug(`工作目录: ${process.cwd()}`);
|
|
173
|
+
debug(`__dirname: ${__dirname}`);
|
|
174
|
+
debug(`命令行参数: ${args.join(', ')}`);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// 检查是否需要显示帮助
|
|
178
|
+
const showHelp = args.some(arg => arg === '--help' || arg === '-h');
|
|
179
|
+
|
|
180
|
+
if (showHelp) {
|
|
181
|
+
console.log('========================================');
|
|
182
|
+
console.log(` ${SDD.name} - ${SDD.description}`);
|
|
183
|
+
console.log(` 版本: ${SDD.version}`);
|
|
184
|
+
console.log('========================================');
|
|
185
|
+
console.log('\n用法:');
|
|
186
|
+
console.log(' npx sdd-full - 安装到 Trae / Solo(默认)');
|
|
187
|
+
console.log(' npx sdd-full cc - 安装到 Claude Code');
|
|
188
|
+
console.log(' npx sdd-full all - 安装到所有环境');
|
|
189
|
+
console.log(' npx sdd-full --help - 显示帮助');
|
|
190
|
+
console.log(' npx sdd-full --dir ./myproj - 安装到指定目录');
|
|
191
|
+
console.log(' npx sdd-full --verbose - 显示详细调试信息');
|
|
192
|
+
|
|
193
|
+
const skills = getSkills();
|
|
194
|
+
console.log('\n可用技能:');
|
|
195
|
+
skills.forEach(skill => {
|
|
196
|
+
console.log(` - ${skill}`);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
console.log(`\n总计 ${skills.length} 个技能\n`);
|
|
200
|
+
} else {
|
|
201
|
+
// 否则,直接安装
|
|
202
|
+
let targetDir;
|
|
203
|
+
const targetIndex = args.indexOf('--dir');
|
|
204
|
+
const targetIndexShort = args.indexOf('-d');
|
|
205
|
+
if (targetIndex !== -1 && args[targetIndex + 1]) {
|
|
206
|
+
targetDir = args[targetIndex + 1];
|
|
207
|
+
} else if (targetIndexShort !== -1 && args[targetIndexShort + 1]) {
|
|
208
|
+
targetDir = args[targetIndexShort + 1];
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
let environment;
|
|
212
|
+
if (args.indexOf('cc') !== -1) {
|
|
213
|
+
environment = 'cc';
|
|
214
|
+
} else if (args.indexOf('all') !== -1) {
|
|
215
|
+
environment = 'all';
|
|
216
|
+
} else {
|
|
217
|
+
environment = 'trae'; // 默认
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
install(targetDir, environment);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// 运行主函数
|
|
225
|
+
main();
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sdd-full",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"description": "SDD Full - 完整的软件设计开发技能包",
|
|
5
5
|
"main": "index.js",
|
|
6
|
-
"bin": "./
|
|
6
|
+
"bin": "./bin.js",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"sdd",
|
|
9
9
|
"software design",
|
|
@@ -15,9 +15,10 @@
|
|
|
15
15
|
"license": "MIT",
|
|
16
16
|
"scripts": {
|
|
17
17
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
18
|
-
"start": "node
|
|
18
|
+
"start": "node bin.js"
|
|
19
19
|
},
|
|
20
20
|
"files": [
|
|
21
|
+
"bin.js",
|
|
21
22
|
"index.js",
|
|
22
23
|
"package.json",
|
|
23
24
|
"README.md",
|