@adonis0123/skill-development 1.0.6 → 1.0.8
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/README.md +1 -0
- package/install-skill.js +149 -26
- package/package.json +1 -1
- package/uninstall-skill.js +83 -10
package/README.md
CHANGED
|
@@ -77,6 +77,7 @@ skill-name/
|
|
|
77
77
|
- [@adonis0123/staged-changes-review](https://www.npmjs.com/package/@adonis0123/staged-changes-review) - 代码审查
|
|
78
78
|
- [@adonis0123/create-skill](https://www.npmjs.com/package/@adonis0123/create-skill) - 创建新技能包
|
|
79
79
|
- [@adonis0123/code-doc-generator](https://www.npmjs.com/package/@adonis0123/code-doc-generator) - 代码文档生成
|
|
80
|
+
- [@adonis0123/css-tailwind-styling](https://www.npmjs.com/package/@adonis0123/css-tailwind-styling) - CSS 和 Tailwind 样式规范
|
|
80
81
|
## License
|
|
81
82
|
|
|
82
83
|
MIT
|
package/install-skill.js
CHANGED
|
@@ -23,9 +23,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
23
23
|
));
|
|
24
24
|
|
|
25
25
|
// shared/src/install-skill.ts
|
|
26
|
-
var
|
|
27
|
-
var
|
|
28
|
-
var
|
|
26
|
+
var import_fs3 = __toESM(require("fs"));
|
|
27
|
+
var import_path3 = __toESM(require("path"));
|
|
28
|
+
var import_os3 = __toESM(require("os"));
|
|
29
29
|
var import_child_process = require("child_process");
|
|
30
30
|
|
|
31
31
|
// shared/src/utils.ts
|
|
@@ -115,6 +115,110 @@ function readSkillConfig(dir) {
|
|
|
115
115
|
}
|
|
116
116
|
return JSON.parse(import_fs.default.readFileSync(configPath, "utf-8"));
|
|
117
117
|
}
|
|
118
|
+
function parseYamlFrontmatter(content) {
|
|
119
|
+
const match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
120
|
+
if (!match) {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
const [, frontmatterStr, body] = match;
|
|
124
|
+
const frontmatter = {};
|
|
125
|
+
const lines = frontmatterStr.split("\n");
|
|
126
|
+
for (const line of lines) {
|
|
127
|
+
const match2 = line.match(/^(\w+):\s*(.*)$/);
|
|
128
|
+
if (match2) {
|
|
129
|
+
const [, key, value] = match2;
|
|
130
|
+
frontmatter[key] = value.replace(/^["']|["']$/g, "").trim();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return { frontmatter, body };
|
|
134
|
+
}
|
|
135
|
+
function patchSkillMdName(skillMdPath, name) {
|
|
136
|
+
try {
|
|
137
|
+
const content = import_fs.default.readFileSync(skillMdPath, "utf-8");
|
|
138
|
+
const parsed = parseYamlFrontmatter(content);
|
|
139
|
+
if (!parsed) {
|
|
140
|
+
console.warn(" \u26A0 Warning: SKILL.md has no frontmatter, skipping name patch");
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const { frontmatter, body } = parsed;
|
|
144
|
+
frontmatter.name = name;
|
|
145
|
+
const frontmatterLines = Object.entries(frontmatter).map(
|
|
146
|
+
([key, value]) => `${key}: ${value}`
|
|
147
|
+
);
|
|
148
|
+
const newContent = `---
|
|
149
|
+
${frontmatterLines.join("\n")}
|
|
150
|
+
---
|
|
151
|
+
${body}`;
|
|
152
|
+
import_fs.default.writeFileSync(skillMdPath, newContent, "utf-8");
|
|
153
|
+
console.log(` \u2713 Patched SKILL.md name: ${name}`);
|
|
154
|
+
} catch (error) {
|
|
155
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
156
|
+
console.warn(` \u26A0 Warning: Failed to patch SKILL.md name: ${message}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// shared/src/claude-settings.ts
|
|
161
|
+
var import_fs2 = __toESM(require("fs"));
|
|
162
|
+
var import_path2 = __toESM(require("path"));
|
|
163
|
+
var import_os2 = __toESM(require("os"));
|
|
164
|
+
function getClaudeSettingsPath() {
|
|
165
|
+
return import_path2.default.join(import_os2.default.homedir(), ".claude", "settings.json");
|
|
166
|
+
}
|
|
167
|
+
function readClaudeSettings() {
|
|
168
|
+
const settingsPath = getClaudeSettingsPath();
|
|
169
|
+
if (!import_fs2.default.existsSync(settingsPath)) {
|
|
170
|
+
return {};
|
|
171
|
+
}
|
|
172
|
+
try {
|
|
173
|
+
const content = import_fs2.default.readFileSync(settingsPath, "utf-8");
|
|
174
|
+
return JSON.parse(content);
|
|
175
|
+
} catch (error) {
|
|
176
|
+
console.warn(" \u26A0 Warning: Could not parse settings.json, treating as empty");
|
|
177
|
+
return {};
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
function writeClaudeSettings(settings) {
|
|
181
|
+
const settingsPath = getClaudeSettingsPath();
|
|
182
|
+
const settingsDir = import_path2.default.dirname(settingsPath);
|
|
183
|
+
if (!import_fs2.default.existsSync(settingsDir)) {
|
|
184
|
+
import_fs2.default.mkdirSync(settingsDir, { recursive: true });
|
|
185
|
+
}
|
|
186
|
+
import_fs2.default.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), "utf-8");
|
|
187
|
+
}
|
|
188
|
+
function hookMatcherExists(existingHooks, newMatcher) {
|
|
189
|
+
return existingHooks.some((hook) => hook.matcher === newMatcher.matcher);
|
|
190
|
+
}
|
|
191
|
+
function addClaudeHooks(hooksConfig, skillName) {
|
|
192
|
+
const settings = readClaudeSettings();
|
|
193
|
+
let modified = false;
|
|
194
|
+
if (!settings.hooks || typeof settings.hooks !== "object") {
|
|
195
|
+
settings.hooks = {};
|
|
196
|
+
}
|
|
197
|
+
const hooks = settings.hooks;
|
|
198
|
+
for (const [hookType, hookMatchers] of Object.entries(hooksConfig)) {
|
|
199
|
+
if (!hookMatchers || !Array.isArray(hookMatchers)) {
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
if (!hooks[hookType] || !Array.isArray(hooks[hookType])) {
|
|
203
|
+
hooks[hookType] = [];
|
|
204
|
+
}
|
|
205
|
+
const existingHooks = hooks[hookType];
|
|
206
|
+
for (const matcher of hookMatchers) {
|
|
207
|
+
if (!hookMatcherExists(existingHooks, matcher)) {
|
|
208
|
+
existingHooks.push(matcher);
|
|
209
|
+
modified = true;
|
|
210
|
+
console.log(` \u2713 Added ${hookType} hook for ${skillName}`);
|
|
211
|
+
} else {
|
|
212
|
+
console.log(` \u2139 ${hookType} hook already exists, skipping`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
hooks[hookType] = existingHooks;
|
|
216
|
+
}
|
|
217
|
+
if (modified) {
|
|
218
|
+
writeClaudeSettings(settings);
|
|
219
|
+
}
|
|
220
|
+
return modified;
|
|
221
|
+
}
|
|
118
222
|
|
|
119
223
|
// shared/src/install-skill.ts
|
|
120
224
|
function fetchFromRemote(tempDir, remoteSource) {
|
|
@@ -124,7 +228,7 @@ function fetchFromRemote(tempDir, remoteSource) {
|
|
|
124
228
|
stdio: "pipe",
|
|
125
229
|
timeout: 6e4
|
|
126
230
|
});
|
|
127
|
-
if (
|
|
231
|
+
if (import_fs3.default.existsSync(import_path3.default.join(tempDir, "SKILL.md"))) {
|
|
128
232
|
console.log(" \u2713 Fetched latest version from remote");
|
|
129
233
|
return true;
|
|
130
234
|
}
|
|
@@ -146,14 +250,14 @@ function getSourceDir(config, packageDir) {
|
|
|
146
250
|
isRemote: false
|
|
147
251
|
};
|
|
148
252
|
}
|
|
149
|
-
const tempDir =
|
|
253
|
+
const tempDir = import_path3.default.join(import_os3.default.tmpdir(), `skill-fetch-${Date.now()}`);
|
|
150
254
|
const remoteSuccess = fetchFromRemote(tempDir, config.remoteSource);
|
|
151
255
|
if (remoteSuccess) {
|
|
152
256
|
return {
|
|
153
257
|
sourceDir: tempDir,
|
|
154
258
|
cleanup: () => {
|
|
155
259
|
try {
|
|
156
|
-
|
|
260
|
+
import_fs3.default.rmSync(tempDir, { recursive: true, force: true });
|
|
157
261
|
} catch {
|
|
158
262
|
}
|
|
159
263
|
},
|
|
@@ -161,7 +265,7 @@ function getSourceDir(config, packageDir) {
|
|
|
161
265
|
};
|
|
162
266
|
}
|
|
163
267
|
try {
|
|
164
|
-
|
|
268
|
+
import_fs3.default.rmSync(tempDir, { recursive: true, force: true });
|
|
165
269
|
} catch {
|
|
166
270
|
}
|
|
167
271
|
return {
|
|
@@ -172,11 +276,11 @@ function getSourceDir(config, packageDir) {
|
|
|
172
276
|
};
|
|
173
277
|
}
|
|
174
278
|
function updateManifest(skillsDir, config, targetName, isRemote) {
|
|
175
|
-
const manifestPath =
|
|
279
|
+
const manifestPath = import_path3.default.join(skillsDir, ".skills-manifest.json");
|
|
176
280
|
let manifest = { skills: {} };
|
|
177
|
-
if (
|
|
281
|
+
if (import_fs3.default.existsSync(manifestPath)) {
|
|
178
282
|
try {
|
|
179
|
-
manifest = JSON.parse(
|
|
283
|
+
manifest = JSON.parse(import_fs3.default.readFileSync(manifestPath, "utf-8"));
|
|
180
284
|
} catch {
|
|
181
285
|
console.warn(" Warning: Could not parse existing manifest, creating new one");
|
|
182
286
|
manifest = { skills: {} };
|
|
@@ -187,55 +291,74 @@ function updateManifest(skillsDir, config, targetName, isRemote) {
|
|
|
187
291
|
version: config.version,
|
|
188
292
|
installedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
189
293
|
package: config.package || config.name,
|
|
190
|
-
path:
|
|
294
|
+
path: import_path3.default.join(skillsDir, skillName),
|
|
191
295
|
target: targetName,
|
|
192
296
|
...config.remoteSource && { source: config.remoteSource }
|
|
193
297
|
};
|
|
194
|
-
|
|
298
|
+
import_fs3.default.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
|
|
195
299
|
}
|
|
196
300
|
function installToTarget(target, config, sourceDir, isRemote) {
|
|
197
|
-
var _a;
|
|
301
|
+
var _a, _b;
|
|
198
302
|
console.log(`
|
|
199
303
|
\u{1F4E6} Installing to ${target.name}...`);
|
|
200
304
|
const isGlobal = isGlobalInstall();
|
|
201
305
|
const location = detectInstallLocation(target.paths, isGlobal);
|
|
202
306
|
const skillName = extractSkillName(config.name);
|
|
203
|
-
const targetDir =
|
|
204
|
-
const altTargetDir =
|
|
307
|
+
const targetDir = import_path3.default.join(location.base, skillName);
|
|
308
|
+
const altTargetDir = import_path3.default.join(location.base, config.name);
|
|
205
309
|
console.log(` Type: ${location.type}${isGlobal ? " (global)" : " (project)"}`);
|
|
206
310
|
console.log(` Directory: ${targetDir}`);
|
|
207
|
-
if (
|
|
311
|
+
if (import_fs3.default.existsSync(altTargetDir) && altTargetDir !== targetDir) {
|
|
208
312
|
console.log(" \u{1F9F9} Cleaning up alternative path format...");
|
|
209
313
|
removeDir(altTargetDir);
|
|
210
314
|
console.log(` \u2713 Removed directory: ${config.name}`);
|
|
211
315
|
}
|
|
212
316
|
ensureDir(targetDir);
|
|
213
|
-
const skillMdSource =
|
|
214
|
-
if (!
|
|
317
|
+
const skillMdSource = import_path3.default.join(sourceDir, "SKILL.md");
|
|
318
|
+
if (!import_fs3.default.existsSync(skillMdSource)) {
|
|
215
319
|
throw new Error("SKILL.md is required but not found");
|
|
216
320
|
}
|
|
217
|
-
|
|
321
|
+
import_fs3.default.copyFileSync(skillMdSource, import_path3.default.join(targetDir, "SKILL.md"));
|
|
218
322
|
console.log(" \u2713 Copied SKILL.md");
|
|
323
|
+
if (isRemote && config.remoteSource) {
|
|
324
|
+
patchSkillMdName(import_path3.default.join(targetDir, "SKILL.md"), config.name);
|
|
325
|
+
}
|
|
219
326
|
const filesToCopy = config.files || {};
|
|
220
327
|
for (const [source, dest] of Object.entries(filesToCopy)) {
|
|
221
|
-
|
|
222
|
-
|
|
328
|
+
if (source === "SKILL.md") {
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
const sourcePath = import_path3.default.join(sourceDir, source);
|
|
332
|
+
if (!import_fs3.default.existsSync(sourcePath)) {
|
|
223
333
|
console.warn(` \u26A0 Warning: ${source} not found, skipping`);
|
|
224
334
|
continue;
|
|
225
335
|
}
|
|
226
|
-
const destPath =
|
|
227
|
-
if (
|
|
336
|
+
const destPath = import_path3.default.join(targetDir, dest);
|
|
337
|
+
if (import_fs3.default.statSync(sourcePath).isDirectory()) {
|
|
228
338
|
copyDir(sourcePath, destPath);
|
|
229
339
|
console.log(` \u2713 Copied directory: ${source}`);
|
|
230
340
|
} else {
|
|
231
|
-
const destDir =
|
|
341
|
+
const destDir = import_path3.default.dirname(destPath);
|
|
232
342
|
ensureDir(destDir);
|
|
233
|
-
|
|
343
|
+
import_fs3.default.copyFileSync(sourcePath, destPath);
|
|
234
344
|
console.log(` \u2713 Copied file: ${source}`);
|
|
235
345
|
}
|
|
236
346
|
}
|
|
237
347
|
updateManifest(location.base, config, target.name, isRemote);
|
|
238
|
-
if ((_a = config.
|
|
348
|
+
if (target.name === "claude-code" && ((_a = config.claudeSettings) == null ? void 0 : _a.hooks)) {
|
|
349
|
+
console.log(" \u{1F527} \u914D\u7F6E Claude Code \u94A9\u5B50...");
|
|
350
|
+
try {
|
|
351
|
+
const skillName2 = extractSkillName(config.name);
|
|
352
|
+
const modified = addClaudeHooks(config.claudeSettings.hooks, skillName2);
|
|
353
|
+
if (modified) {
|
|
354
|
+
console.log(" \u2705 \u94A9\u5B50\u5DF2\u914D\u7F6E\u5230 ~/.claude/settings.json");
|
|
355
|
+
}
|
|
356
|
+
} catch (error) {
|
|
357
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
358
|
+
console.warn(` \u26A0 \u8B66\u544A: \u65E0\u6CD5\u914D\u7F6E\u94A9\u5B50: ${message}`);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
if ((_b = config.hooks) == null ? void 0 : _b.postinstall) {
|
|
239
362
|
console.log(" \u{1F527} Running postinstall hook...");
|
|
240
363
|
try {
|
|
241
364
|
(0, import_child_process.execSync)(config.hooks.postinstall, {
|
package/package.json
CHANGED
package/uninstall-skill.js
CHANGED
|
@@ -23,8 +23,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
23
23
|
));
|
|
24
24
|
|
|
25
25
|
// shared/src/uninstall-skill.ts
|
|
26
|
-
var
|
|
27
|
-
var
|
|
26
|
+
var import_fs3 = __toESM(require("fs"));
|
|
27
|
+
var import_path3 = __toESM(require("path"));
|
|
28
28
|
|
|
29
29
|
// shared/src/utils.ts
|
|
30
30
|
var import_fs = __toESM(require("fs"));
|
|
@@ -96,17 +96,77 @@ function readSkillConfig(dir) {
|
|
|
96
96
|
return JSON.parse(import_fs.default.readFileSync(configPath, "utf-8"));
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
// shared/src/claude-settings.ts
|
|
100
|
+
var import_fs2 = __toESM(require("fs"));
|
|
101
|
+
var import_path2 = __toESM(require("path"));
|
|
102
|
+
var import_os2 = __toESM(require("os"));
|
|
103
|
+
function getClaudeSettingsPath() {
|
|
104
|
+
return import_path2.default.join(import_os2.default.homedir(), ".claude", "settings.json");
|
|
105
|
+
}
|
|
106
|
+
function readClaudeSettings() {
|
|
107
|
+
const settingsPath = getClaudeSettingsPath();
|
|
108
|
+
if (!import_fs2.default.existsSync(settingsPath)) {
|
|
109
|
+
return {};
|
|
110
|
+
}
|
|
111
|
+
try {
|
|
112
|
+
const content = import_fs2.default.readFileSync(settingsPath, "utf-8");
|
|
113
|
+
return JSON.parse(content);
|
|
114
|
+
} catch (error) {
|
|
115
|
+
console.warn(" \u26A0 Warning: Could not parse settings.json, treating as empty");
|
|
116
|
+
return {};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function writeClaudeSettings(settings) {
|
|
120
|
+
const settingsPath = getClaudeSettingsPath();
|
|
121
|
+
const settingsDir = import_path2.default.dirname(settingsPath);
|
|
122
|
+
if (!import_fs2.default.existsSync(settingsDir)) {
|
|
123
|
+
import_fs2.default.mkdirSync(settingsDir, { recursive: true });
|
|
124
|
+
}
|
|
125
|
+
import_fs2.default.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), "utf-8");
|
|
126
|
+
}
|
|
127
|
+
function removeClaudeHooks(hooksConfig, skillName) {
|
|
128
|
+
const settings = readClaudeSettings();
|
|
129
|
+
let modified = false;
|
|
130
|
+
if (!settings.hooks || typeof settings.hooks !== "object") {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
const hooks = settings.hooks;
|
|
134
|
+
for (const [hookType, hookMatchers] of Object.entries(hooksConfig)) {
|
|
135
|
+
if (!hookMatchers || !Array.isArray(hookMatchers)) {
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
if (!hooks[hookType] || !Array.isArray(hooks[hookType])) {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
const existingHooks = hooks[hookType];
|
|
142
|
+
const initialLength = existingHooks.length;
|
|
143
|
+
const matchersToRemove = hookMatchers.map((m) => m.matcher);
|
|
144
|
+
const filteredHooks = existingHooks.filter(
|
|
145
|
+
(hook) => !matchersToRemove.includes(hook.matcher)
|
|
146
|
+
);
|
|
147
|
+
if (filteredHooks.length < initialLength) {
|
|
148
|
+
hooks[hookType] = filteredHooks;
|
|
149
|
+
modified = true;
|
|
150
|
+
console.log(` \u2713 Removed ${hookType} hook for ${skillName}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (modified) {
|
|
154
|
+
writeClaudeSettings(settings);
|
|
155
|
+
}
|
|
156
|
+
return modified;
|
|
157
|
+
}
|
|
158
|
+
|
|
99
159
|
// shared/src/uninstall-skill.ts
|
|
100
160
|
function updateManifest(skillsDir, config) {
|
|
101
|
-
const manifestPath =
|
|
102
|
-
if (!
|
|
161
|
+
const manifestPath = import_path3.default.join(skillsDir, ".skills-manifest.json");
|
|
162
|
+
if (!import_fs3.default.existsSync(manifestPath)) {
|
|
103
163
|
return;
|
|
104
164
|
}
|
|
105
165
|
try {
|
|
106
|
-
const manifest = JSON.parse(
|
|
166
|
+
const manifest = JSON.parse(import_fs3.default.readFileSync(manifestPath, "utf-8"));
|
|
107
167
|
if (manifest.skills && manifest.skills[config.name]) {
|
|
108
168
|
delete manifest.skills[config.name];
|
|
109
|
-
|
|
169
|
+
import_fs3.default.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
|
|
110
170
|
console.log(" \u2713 Updated manifest");
|
|
111
171
|
}
|
|
112
172
|
} catch (error) {
|
|
@@ -115,25 +175,38 @@ function updateManifest(skillsDir, config) {
|
|
|
115
175
|
}
|
|
116
176
|
}
|
|
117
177
|
function uninstallFromTarget(target, config) {
|
|
178
|
+
var _a;
|
|
118
179
|
console.log(`
|
|
119
180
|
\u{1F5D1}\uFE0F Uninstalling from ${target.name}...`);
|
|
120
181
|
const isGlobal = isGlobalInstall();
|
|
121
182
|
const location = detectInstallLocation(target.paths, isGlobal);
|
|
122
183
|
const skillName = extractSkillName(config.name);
|
|
123
|
-
const skillNameTargetDir =
|
|
124
|
-
const fullPackageNameTargetDir =
|
|
184
|
+
const skillNameTargetDir = import_path3.default.join(location.base, skillName);
|
|
185
|
+
const fullPackageNameTargetDir = import_path3.default.join(location.base, config.name);
|
|
125
186
|
let removed = false;
|
|
126
|
-
if (
|
|
187
|
+
if (import_fs3.default.existsSync(skillNameTargetDir)) {
|
|
127
188
|
removeDir(skillNameTargetDir);
|
|
128
189
|
console.log(` \u2713 Removed skill directory: ${skillName}`);
|
|
129
190
|
removed = true;
|
|
130
191
|
}
|
|
131
|
-
if (
|
|
192
|
+
if (import_fs3.default.existsSync(fullPackageNameTargetDir) && fullPackageNameTargetDir !== skillNameTargetDir) {
|
|
132
193
|
removeDir(fullPackageNameTargetDir);
|
|
133
194
|
console.log(` \u2713 Removed skill directory: ${config.name}`);
|
|
134
195
|
removed = true;
|
|
135
196
|
}
|
|
136
197
|
updateManifest(location.base, config);
|
|
198
|
+
if (target.name === "claude-code" && removed && ((_a = config.claudeSettings) == null ? void 0 : _a.hooks)) {
|
|
199
|
+
try {
|
|
200
|
+
console.log(" \u{1F527} \u79FB\u9664 Claude Code \u94A9\u5B50...");
|
|
201
|
+
const skillName2 = extractSkillName(config.name);
|
|
202
|
+
const modified = removeClaudeHooks(config.claudeSettings.hooks, skillName2);
|
|
203
|
+
if (modified) {
|
|
204
|
+
console.log(" \u2705 \u94A9\u5B50\u5DF2\u4ECE ~/.claude/settings.json \u79FB\u9664");
|
|
205
|
+
}
|
|
206
|
+
} catch (error) {
|
|
207
|
+
console.warn(" \u26A0 \u8B66\u544A: \u65E0\u6CD5\u79FB\u9664\u94A9\u5B50\uFF08\u53EF\u5B89\u5168\u5FFD\u7565\uFF09");
|
|
208
|
+
}
|
|
209
|
+
}
|
|
137
210
|
if (removed) {
|
|
138
211
|
console.log(` \u2705 Uninstalled from ${target.name}`);
|
|
139
212
|
return true;
|