@catcuts-skills/hello-world 1.0.4 → 1.0.6
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/package.json +3 -1
- package/scripts/uninstall-skill.js +100 -36
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@catcuts-skills/hello-world",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "简单的 Hello World 示例技能,用于验证技能安装是否成功。显示欢迎信息、环境信息和使用示例。",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
"test": "node scripts/install-skill.js --dry-run",
|
|
10
10
|
"install:global": "node scripts/install-skill.js --global",
|
|
11
11
|
"install:local": "node scripts/install-skill.js --local",
|
|
12
|
+
"uninstall:global": "node scripts/uninstall-skill.js --global",
|
|
13
|
+
"uninstall:local": "node scripts/uninstall-skill.js --local",
|
|
12
14
|
"lint": "echo 'Add your linting commands here'"
|
|
13
15
|
},
|
|
14
16
|
"files": [
|
|
@@ -16,6 +16,9 @@ const path = require('path');
|
|
|
16
16
|
const fs = require('fs');
|
|
17
17
|
const os = require('os');
|
|
18
18
|
|
|
19
|
+
// 技能名称
|
|
20
|
+
const skillName = 'hello-world';
|
|
21
|
+
|
|
19
22
|
// 解析命令行参数
|
|
20
23
|
const args = process.argv.slice(2);
|
|
21
24
|
const forceGlobal = args.includes('--global');
|
|
@@ -46,18 +49,49 @@ function log(message, type = 'info') {
|
|
|
46
49
|
console.log(`${prefix} ${message}`);
|
|
47
50
|
}
|
|
48
51
|
|
|
49
|
-
//
|
|
50
|
-
function
|
|
51
|
-
if (!fs.existsSync(dirPath)) {
|
|
52
|
-
return false;
|
|
53
|
-
}
|
|
54
|
-
|
|
52
|
+
// 安全删除路径(支持符号链接、文件、目录)
|
|
53
|
+
function safeRemovePath(filePath, description) {
|
|
55
54
|
try {
|
|
56
|
-
fs.
|
|
57
|
-
|
|
55
|
+
if (!fs.existsSync(filePath)) {
|
|
56
|
+
return { success: true, removed: false, message: `已不存在:${description}(${filePath})` };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const stats = fs.lstatSync(filePath);
|
|
60
|
+
const isLink = stats.isSymbolicLink();
|
|
61
|
+
const isDir = stats.isDirectory();
|
|
62
|
+
|
|
63
|
+
if (isLink) {
|
|
64
|
+
fs.unlinkSync(filePath);
|
|
65
|
+
return {
|
|
66
|
+
success: true,
|
|
67
|
+
removed: true,
|
|
68
|
+
message: `已删除符号链接: ${description}(${filePath})`
|
|
69
|
+
};
|
|
70
|
+
} else if (isDir) {
|
|
71
|
+
fs.rmSync(filePath, { recursive: true, force: true });
|
|
72
|
+
return {
|
|
73
|
+
success: true,
|
|
74
|
+
removed: true,
|
|
75
|
+
message: `已删除目录: ${description}(${filePath})`
|
|
76
|
+
};
|
|
77
|
+
} else {
|
|
78
|
+
fs.unlinkSync(filePath);
|
|
79
|
+
return {
|
|
80
|
+
success: true,
|
|
81
|
+
removed: true,
|
|
82
|
+
message: `已删除文件: ${description}(${filePath})`
|
|
83
|
+
};
|
|
84
|
+
}
|
|
58
85
|
} catch (error) {
|
|
59
|
-
|
|
60
|
-
|
|
86
|
+
// 忽略"文件不存在"错误,可能已被并发删除
|
|
87
|
+
if (error.code === 'ENOENT') {
|
|
88
|
+
return { success: true, removed: false, message: `已不存在:${description}(${filePath})` };
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
success: false,
|
|
92
|
+
removed: false,
|
|
93
|
+
message: `删除失败: ${description}(${filePath}) - ${error.message}`
|
|
94
|
+
};
|
|
61
95
|
}
|
|
62
96
|
}
|
|
63
97
|
|
|
@@ -65,42 +99,72 @@ try {
|
|
|
65
99
|
log(`开始卸载 Hello World Skill...`, 'info');
|
|
66
100
|
log(`卸载范围: ${isGlobal ? '全局(GLOBAL)' : '项目级(LOCAL)'}`, 'info');
|
|
67
101
|
|
|
68
|
-
|
|
102
|
+
log('\n正在清理技能文件...', 'info');
|
|
103
|
+
|
|
104
|
+
const results = [];
|
|
69
105
|
|
|
70
106
|
if (isGlobal) {
|
|
71
107
|
// 全局卸载
|
|
72
108
|
const homeDir = os.homedir();
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
109
|
+
|
|
110
|
+
// 1. 清理规范副本目录(.agents/skills/hello-world)
|
|
111
|
+
const canonicalResult = safeRemovePath(
|
|
112
|
+
path.join(homeDir, '.agents', 'skills', skillName),
|
|
113
|
+
'规范副本'
|
|
114
|
+
);
|
|
115
|
+
results.push(canonicalResult);
|
|
116
|
+
|
|
117
|
+
// 2. 清理 Claude Code 全局符号链接
|
|
118
|
+
const globalResult = safeRemovePath(
|
|
119
|
+
path.join(homeDir, '.claude', 'skills', skillName),
|
|
120
|
+
'全局技能链接'
|
|
121
|
+
);
|
|
122
|
+
results.push(globalResult);
|
|
84
123
|
} else {
|
|
85
124
|
// 项目级卸载
|
|
86
125
|
const cwd = process.cwd();
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
126
|
+
|
|
127
|
+
// 1. 清理项目级规范副本(如果存在)
|
|
128
|
+
const canonicalResult = safeRemovePath(
|
|
129
|
+
path.join(cwd, '.agents', 'skills', skillName),
|
|
130
|
+
'项目级规范副本'
|
|
131
|
+
);
|
|
132
|
+
results.push(canonicalResult);
|
|
133
|
+
|
|
134
|
+
// 2. 清理 Claude Code 项目级技能
|
|
135
|
+
const localResult = safeRemovePath(
|
|
136
|
+
path.join(cwd, '.claude', 'skills', skillName),
|
|
137
|
+
'项目级技能'
|
|
138
|
+
);
|
|
139
|
+
results.push(localResult);
|
|
98
140
|
}
|
|
99
141
|
|
|
142
|
+
// 输出清理结果
|
|
143
|
+
let removedCount = 0;
|
|
144
|
+
let errorCount = 0;
|
|
145
|
+
|
|
146
|
+
results.forEach((result) => {
|
|
147
|
+
if (result.removed) {
|
|
148
|
+
log(` ✓ ${result.message}`, 'success');
|
|
149
|
+
removedCount++;
|
|
150
|
+
} else if (result.success) {
|
|
151
|
+
log(` ⊗ ${result.message} (跳过)`, 'info');
|
|
152
|
+
} else {
|
|
153
|
+
log(` ✗ ${result.message}`, 'error');
|
|
154
|
+
errorCount++;
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// 总结
|
|
100
159
|
if (removedCount > 0) {
|
|
101
|
-
log(`\n卸载成功! 已删除 ${removedCount}
|
|
102
|
-
} else {
|
|
103
|
-
log('\n
|
|
160
|
+
log(`\n✓ 卸载成功! 已删除 ${removedCount} 个文件/目录`, 'success');
|
|
161
|
+
} else if (errorCount === 0) {
|
|
162
|
+
log('\n⊗ 未找到需要卸载的文件', 'warning');
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (errorCount > 0) {
|
|
166
|
+
log(`\n⚠ 有 ${errorCount} 个项目删除失败,请手动清理`, 'warning');
|
|
167
|
+
process.exit(1);
|
|
104
168
|
}
|
|
105
169
|
} catch (error) {
|
|
106
170
|
log(`卸载失败: ${error.message}`, 'error');
|