@adonis0123/react-best-practices 1.0.2 → 1.0.3

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.
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "react-best-practices",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "package": "@adonis0123/react-best-practices",
5
+ "remoteSource": "vercel-labs/agent-skills/skills/react-best-practices",
5
6
  "files": {
6
7
  "AGENTS.md": "AGENTS.md",
7
8
  "README.md": "README.md",
@@ -14,6 +15,34 @@
14
15
  "global": ".claude/skills",
15
16
  "project": ".claude/skills"
16
17
  }
18
+ },
19
+ "cursor": {
20
+ "enabled": true,
21
+ "paths": {
22
+ "global": ".cursor/skills",
23
+ "project": ".cursor/skills"
24
+ }
25
+ },
26
+ "windsurf": {
27
+ "enabled": false,
28
+ "paths": {
29
+ "global": ".windsurf/skills",
30
+ "project": ".windsurf/skills"
31
+ }
32
+ },
33
+ "aider": {
34
+ "enabled": false,
35
+ "paths": {
36
+ "global": ".aider/skills",
37
+ "project": ".aider/skills"
38
+ }
39
+ },
40
+ "custom": {
41
+ "enabled": false,
42
+ "paths": {
43
+ "global": ".ai-skills",
44
+ "project": ".ai-skills"
45
+ }
17
46
  }
18
47
  }
19
48
  }
package/install-skill.js CHANGED
@@ -1,207 +1,315 @@
1
1
  #!/usr/bin/env node
2
-
3
- const fs = require('fs');
4
- const path = require('path');
5
- const os = require('os');
6
-
7
- const { getEnabledTargets,extractSkillName, detectInstallLocation } = require('./utils');
8
-
9
- function installToTarget(target, config) {
10
- console.log(`\nšŸ“¦ Installing to ${target.name}...`);
11
-
12
- // Check if this is a global installation
13
- const isGlobal = process.env.npm_config_global === 'true';
14
-
15
- // Determine installation location
16
- const location = detectInstallLocation(target.paths, isGlobal);
17
-
18
- // Extract skill name from package name (remove scope prefix)
19
- const skillName = extractSkillName(config.name);
20
-
21
- const targetDir = path.join(location.base, skillName);
22
-
23
- // Alternative path format with full package name (including scope)
24
- const altTargetDir = path.join(location.base, config.name);
25
-
26
- console.log(` Type: ${location.type}${isGlobal ? ' (global)' : ' (project)'}`);
27
- console.log(` Directory: ${targetDir}`);
28
-
29
- // Clean up alternative path format
30
- if (fs.existsSync(altTargetDir) && altTargetDir !== targetDir) {
31
- console.log(` 🧹 Cleaning up alternative path format...`);
32
- fs.rmSync(altTargetDir, { recursive: true, force: true });
33
- console.log(` āœ“ Removed directory: ${config.name}`);
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (let key of __getOwnPropNames(from))
11
+ if (!__hasOwnProp.call(to, key) && key !== except)
12
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
34
13
  }
35
-
36
- // Create target directory
37
- if (!fs.existsSync(targetDir)) {
38
- fs.mkdirSync(targetDir, { recursive: true });
14
+ return to;
15
+ };
16
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
17
+ // If the importer is in node compatibility mode or this is not an ESM
18
+ // file that has been converted to a CommonJS file using a Babel-
19
+ // compatible transform (i.e. "__esModule" has not been set), then set
20
+ // "default" to the CommonJS "module.exports" for node compatibility.
21
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
+ mod
23
+ ));
24
+
25
+ // shared/src/install-skill.ts
26
+ var import_fs2 = __toESM(require("fs"));
27
+ var import_path2 = __toESM(require("path"));
28
+ var import_os2 = __toESM(require("os"));
29
+ var import_child_process = require("child_process");
30
+
31
+ // shared/src/utils.ts
32
+ var import_fs = __toESM(require("fs"));
33
+ var import_path = __toESM(require("path"));
34
+ var import_os = __toESM(require("os"));
35
+ var CWD = process.env.INIT_CWD || process.cwd();
36
+ var DEFAULT_TARGET = {
37
+ name: "claude-code",
38
+ paths: {
39
+ global: ".claude/skills",
40
+ project: ".claude/skills"
39
41
  }
40
-
41
- // Copy SKILL.md (required)
42
- const skillMdSource = path.join(__dirname, 'SKILL.md');
43
- if (!fs.existsSync(skillMdSource)) {
44
- throw new Error('SKILL.md is required but not found');
45
- }
46
- fs.copyFileSync(skillMdSource, path.join(targetDir, 'SKILL.md'));
47
- console.log(' āœ“ Copied SKILL.md');
48
-
49
- // Copy other files
50
- if (config.files) {
51
- Object.entries(config.files).forEach(([source, dest]) => {
52
- const sourcePath = path.join(__dirname, source);
53
- if (!fs.existsSync(sourcePath)) {
54
- console.warn(` ⚠ Warning: ${source} not found, skipping`);
55
- return;
56
- }
57
-
58
- const destPath = path.join(targetDir, dest);
59
-
60
- if (fs.statSync(sourcePath).isDirectory()) {
61
- copyDir(sourcePath, destPath);
62
- console.log(` āœ“ Copied directory: ${source}`);
63
- } else {
64
- // Ensure target directory exists
65
- const destDir = path.dirname(destPath);
66
- if (!fs.existsSync(destDir)) {
67
- fs.mkdirSync(destDir, { recursive: true });
68
- }
69
- fs.copyFileSync(sourcePath, destPath);
70
- console.log(` āœ“ Copied file: ${source}`);
71
- }
72
- });
73
- }
74
-
75
- // Update manifest
76
- updateManifest(location.base, config, target.name);
77
-
78
- // Run postinstall hooks
79
- if (config.hooks && config.hooks.postinstall) {
80
- console.log(' šŸ”§ Running postinstall hook...');
81
- const { execSync } = require('child_process');
82
- try {
83
- execSync(config.hooks.postinstall, {
84
- cwd: targetDir,
85
- stdio: 'pipe'
86
- });
87
- console.log(' āœ“ Postinstall hook completed');
88
- } catch (error) {
89
- console.warn(` ⚠ Warning: postinstall hook failed`);
90
- }
42
+ };
43
+ function getEnabledTargets(config) {
44
+ if (!config.targets) {
45
+ return [DEFAULT_TARGET];
91
46
  }
92
-
93
- console.log(` āœ… Installed to ${target.name}`);
94
- return targetDir;
47
+ return Object.entries(config.targets).filter(([_, target]) => target.enabled).map(([name, target]) => ({
48
+ name,
49
+ paths: target.paths
50
+ }));
95
51
  }
96
-
97
- function installSkill() {
98
- console.log('šŸš€ Installing AI Coding Skill...\n');
99
-
100
- // Read configuration
101
- const configPath = path.join(__dirname, '.claude-skill.json');
102
- if (!fs.existsSync(configPath)) {
103
- throw new Error('.claude-skill.json not found');
52
+ function extractSkillName(packageName) {
53
+ if (packageName.startsWith("@")) {
54
+ return packageName.split("/")[1] || packageName;
104
55
  }
105
- const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
106
-
107
- // Get enabled targets
108
- const enabledTargets = getEnabledTargets(config);
109
-
110
- if (enabledTargets.length === 0) {
111
- console.warn('⚠ No targets enabled in configuration');
112
- console.warn('Please enable at least one target in .claude-skill.json');
113
- return;
56
+ return packageName;
57
+ }
58
+ function detectInstallLocation(targetPaths, isGlobal) {
59
+ if (isGlobal) {
60
+ return {
61
+ type: "personal",
62
+ base: import_path.default.join(import_os.default.homedir(), targetPaths.global)
63
+ };
114
64
  }
115
-
116
- console.log(`Installing skill "${config.name}" to ${enabledTargets.length} target(s):`);
117
- enabledTargets.forEach(target => {
118
- console.log(` • ${target.name}`);
119
- });
120
-
121
- // Install to all enabled targets
122
- const installedPaths = [];
123
- for (const target of enabledTargets) {
124
- try {
125
- const installPath = installToTarget(target, config);
126
- installedPaths.push({ target: target.name, path: installPath });
127
- } catch (error) {
128
- console.error(`\nāŒ Failed to install to ${target.name}:`, error.message);
65
+ let projectRoot = CWD;
66
+ while (projectRoot !== import_path.default.dirname(projectRoot)) {
67
+ const hasPackageJson = import_fs.default.existsSync(import_path.default.join(projectRoot, "package.json"));
68
+ const hasGit = import_fs.default.existsSync(import_path.default.join(projectRoot, ".git"));
69
+ const isInNodeModules = projectRoot.includes("/node_modules/") || import_path.default.basename(projectRoot) === "node_modules";
70
+ if ((hasPackageJson || hasGit) && !isInNodeModules) {
71
+ break;
129
72
  }
73
+ projectRoot = import_path.default.dirname(projectRoot);
130
74
  }
131
-
132
- // Summary
133
- console.log('\n' + '='.repeat(60));
134
- console.log('āœ… Installation Complete!');
135
- console.log('='.repeat(60));
136
-
137
- if (installedPaths.length > 0) {
138
- console.log('\nInstalled to:');
139
- installedPaths.forEach(({ target, path: installPath }) => {
140
- console.log(` • ${target}: ${installPath}`);
141
- });
142
-
143
- console.log('\nšŸ“– Next Steps:');
144
- console.log(' 1. Restart your AI coding tool(s)');
145
- console.log(' 2. Ask: "What skills are available?"');
146
- console.log(' 3. Start using your skill!');
75
+ const finalIsInNodeModules = projectRoot.includes("/node_modules/") || import_path.default.basename(projectRoot) === "node_modules";
76
+ if (finalIsInNodeModules) {
77
+ console.warn("\u26A0 Warning: Could not find project root directory, using current directory");
78
+ projectRoot = CWD;
147
79
  }
80
+ return {
81
+ type: "project",
82
+ base: import_path.default.join(projectRoot, targetPaths.project)
83
+ };
84
+ }
85
+ function isGlobalInstall() {
86
+ return process.env.npm_config_global === "true";
148
87
  }
149
-
150
88
  function copyDir(src, dest) {
151
- fs.mkdirSync(dest, { recursive: true });
152
- const entries = fs.readdirSync(src, { withFileTypes: true });
153
-
154
- for (let entry of entries) {
155
- const srcPath = path.join(src, entry.name);
156
- const destPath = path.join(dest, entry.name);
157
-
89
+ import_fs.default.mkdirSync(dest, { recursive: true });
90
+ const entries = import_fs.default.readdirSync(src, { withFileTypes: true });
91
+ for (const entry of entries) {
92
+ const srcPath = import_path.default.join(src, entry.name);
93
+ const destPath = import_path.default.join(dest, entry.name);
158
94
  if (entry.isDirectory()) {
159
95
  copyDir(srcPath, destPath);
160
96
  } else {
161
- fs.copyFileSync(srcPath, destPath);
97
+ import_fs.default.copyFileSync(srcPath, destPath);
162
98
  }
163
99
  }
164
100
  }
101
+ function ensureDir(dir) {
102
+ if (!import_fs.default.existsSync(dir)) {
103
+ import_fs.default.mkdirSync(dir, { recursive: true });
104
+ }
105
+ }
106
+ function removeDir(dir) {
107
+ if (import_fs.default.existsSync(dir)) {
108
+ import_fs.default.rmSync(dir, { recursive: true, force: true });
109
+ }
110
+ }
111
+ function readSkillConfig(dir) {
112
+ const configPath = import_path.default.join(dir, ".claude-skill.json");
113
+ if (!import_fs.default.existsSync(configPath)) {
114
+ throw new Error(".claude-skill.json not found");
115
+ }
116
+ return JSON.parse(import_fs.default.readFileSync(configPath, "utf-8"));
117
+ }
165
118
 
166
- function updateManifest(skillsDir, config, targetName) {
167
- const manifestPath = path.join(skillsDir, '.skills-manifest.json');
119
+ // shared/src/install-skill.ts
120
+ function fetchFromRemote(tempDir, remoteSource) {
121
+ try {
122
+ console.log(` \u{1F310} Fetching latest from ${remoteSource}...`);
123
+ (0, import_child_process.execSync)(`npx degit ${remoteSource} "${tempDir}" --force`, {
124
+ stdio: "pipe",
125
+ timeout: 6e4
126
+ });
127
+ if (import_fs2.default.existsSync(import_path2.default.join(tempDir, "SKILL.md"))) {
128
+ console.log(" \u2713 Fetched latest version from remote");
129
+ return true;
130
+ }
131
+ console.warn(" \u26A0 Remote fetch succeeded but SKILL.md not found");
132
+ return false;
133
+ } catch (error) {
134
+ const message = error instanceof Error ? error.message : String(error);
135
+ console.warn(` \u26A0 Could not fetch from remote: ${message}`);
136
+ console.log(" \u2139 Using bundled version as fallback");
137
+ return false;
138
+ }
139
+ }
140
+ function getSourceDir(config, packageDir) {
141
+ if (!config.remoteSource) {
142
+ return {
143
+ sourceDir: packageDir,
144
+ cleanup: () => {
145
+ },
146
+ isRemote: false
147
+ };
148
+ }
149
+ const tempDir = import_path2.default.join(import_os2.default.tmpdir(), `skill-fetch-${Date.now()}`);
150
+ const remoteSuccess = fetchFromRemote(tempDir, config.remoteSource);
151
+ if (remoteSuccess) {
152
+ return {
153
+ sourceDir: tempDir,
154
+ cleanup: () => {
155
+ try {
156
+ import_fs2.default.rmSync(tempDir, { recursive: true, force: true });
157
+ } catch {
158
+ }
159
+ },
160
+ isRemote: true
161
+ };
162
+ }
163
+ try {
164
+ import_fs2.default.rmSync(tempDir, { recursive: true, force: true });
165
+ } catch {
166
+ }
167
+ return {
168
+ sourceDir: packageDir,
169
+ cleanup: () => {
170
+ },
171
+ isRemote: false
172
+ };
173
+ }
174
+ function updateManifest(skillsDir, config, targetName, isRemote) {
175
+ const manifestPath = import_path2.default.join(skillsDir, ".skills-manifest.json");
168
176
  let manifest = { skills: {} };
169
-
170
- if (fs.existsSync(manifestPath)) {
177
+ if (import_fs2.default.existsSync(manifestPath)) {
171
178
  try {
172
- manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
173
- } catch (error) {
174
- console.warn(' Warning: Could not parse existing manifest, creating new one');
179
+ manifest = JSON.parse(import_fs2.default.readFileSync(manifestPath, "utf-8"));
180
+ } catch {
181
+ console.warn(" Warning: Could not parse existing manifest, creating new one");
175
182
  manifest = { skills: {} };
176
183
  }
177
184
  }
178
-
179
- // Extract skill name from package name (remove scope prefix)
180
- const skillName = config.name.startsWith('@') ?
181
- config.name.split('/')[1] || config.name :
182
- config.name;
183
-
185
+ const skillName = extractSkillName(config.name);
184
186
  manifest.skills[config.name] = {
185
187
  version: config.version,
186
- installedAt: new Date().toISOString(),
188
+ installedAt: (/* @__PURE__ */ new Date()).toISOString(),
187
189
  package: config.package || config.name,
188
- path: path.join(skillsDir, skillName),
189
- target: targetName
190
+ path: import_path2.default.join(skillsDir, skillName),
191
+ target: targetName,
192
+ ...config.remoteSource && { source: config.remoteSource }
190
193
  };
191
-
192
- fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
194
+ import_fs2.default.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
195
+ }
196
+ function installToTarget(target, config, sourceDir, isRemote) {
197
+ var _a;
198
+ console.log(`
199
+ \u{1F4E6} Installing to ${target.name}...`);
200
+ const isGlobal = isGlobalInstall();
201
+ const location = detectInstallLocation(target.paths, isGlobal);
202
+ const skillName = extractSkillName(config.name);
203
+ const targetDir = import_path2.default.join(location.base, skillName);
204
+ const altTargetDir = import_path2.default.join(location.base, config.name);
205
+ console.log(` Type: ${location.type}${isGlobal ? " (global)" : " (project)"}`);
206
+ console.log(` Directory: ${targetDir}`);
207
+ if (import_fs2.default.existsSync(altTargetDir) && altTargetDir !== targetDir) {
208
+ console.log(" \u{1F9F9} Cleaning up alternative path format...");
209
+ removeDir(altTargetDir);
210
+ console.log(` \u2713 Removed directory: ${config.name}`);
211
+ }
212
+ ensureDir(targetDir);
213
+ const skillMdSource = import_path2.default.join(sourceDir, "SKILL.md");
214
+ if (!import_fs2.default.existsSync(skillMdSource)) {
215
+ throw new Error("SKILL.md is required but not found");
216
+ }
217
+ import_fs2.default.copyFileSync(skillMdSource, import_path2.default.join(targetDir, "SKILL.md"));
218
+ console.log(" \u2713 Copied SKILL.md");
219
+ const filesToCopy = config.files || {};
220
+ for (const [source, dest] of Object.entries(filesToCopy)) {
221
+ const sourcePath = import_path2.default.join(sourceDir, source);
222
+ if (!import_fs2.default.existsSync(sourcePath)) {
223
+ console.warn(` \u26A0 Warning: ${source} not found, skipping`);
224
+ continue;
225
+ }
226
+ const destPath = import_path2.default.join(targetDir, dest);
227
+ if (import_fs2.default.statSync(sourcePath).isDirectory()) {
228
+ copyDir(sourcePath, destPath);
229
+ console.log(` \u2713 Copied directory: ${source}`);
230
+ } else {
231
+ const destDir = import_path2.default.dirname(destPath);
232
+ ensureDir(destDir);
233
+ import_fs2.default.copyFileSync(sourcePath, destPath);
234
+ console.log(` \u2713 Copied file: ${source}`);
235
+ }
236
+ }
237
+ updateManifest(location.base, config, target.name, isRemote);
238
+ if ((_a = config.hooks) == null ? void 0 : _a.postinstall) {
239
+ console.log(" \u{1F527} Running postinstall hook...");
240
+ try {
241
+ (0, import_child_process.execSync)(config.hooks.postinstall, {
242
+ cwd: targetDir,
243
+ stdio: "pipe"
244
+ });
245
+ console.log(" \u2713 Postinstall hook completed");
246
+ } catch {
247
+ console.warn(" \u26A0 Warning: postinstall hook failed");
248
+ }
249
+ }
250
+ console.log(` \u2705 Installed to ${target.name}`);
251
+ return targetDir;
252
+ }
253
+ function installSkill() {
254
+ console.log("\u{1F680} Installing AI Coding Skill...\n");
255
+ const packageDir = __dirname;
256
+ const config = readSkillConfig(packageDir);
257
+ const enabledTargets = getEnabledTargets(config);
258
+ if (enabledTargets.length === 0) {
259
+ console.warn("\u26A0 No targets enabled in configuration");
260
+ console.warn("Please enable at least one target in .claude-skill.json");
261
+ return;
262
+ }
263
+ console.log(`Installing skill "${config.name}" to ${enabledTargets.length} target(s):`);
264
+ enabledTargets.forEach((target) => {
265
+ console.log(` \u2022 ${target.name}`);
266
+ });
267
+ const { sourceDir, cleanup, isRemote } = getSourceDir(config, packageDir);
268
+ if (isRemote) {
269
+ console.log(`
270
+ \u{1F4E1} Source: Remote (${config.remoteSource})`);
271
+ } else {
272
+ console.log("\n\u{1F4E6} Source: Bundled (local)");
273
+ }
274
+ try {
275
+ const installedPaths = [];
276
+ for (const target of enabledTargets) {
277
+ try {
278
+ const installPath = installToTarget(target, config, sourceDir, isRemote);
279
+ installedPaths.push({ target: target.name, path: installPath });
280
+ } catch (error) {
281
+ const message = error instanceof Error ? error.message : String(error);
282
+ console.error(`
283
+ \u274C Failed to install to ${target.name}:`, message);
284
+ }
285
+ }
286
+ console.log("\n" + "=".repeat(60));
287
+ console.log("\u2705 Installation Complete!");
288
+ console.log("=".repeat(60));
289
+ if (installedPaths.length > 0) {
290
+ console.log("\nInstalled to:");
291
+ installedPaths.forEach(({ target, path: installPath }) => {
292
+ console.log(` \u2022 ${target}: ${installPath}`);
293
+ });
294
+ console.log("\n\u{1F4D6} Next Steps:");
295
+ console.log(" 1. Restart your AI coding tool(s)");
296
+ console.log(' 2. Ask: "What skills are available?"');
297
+ console.log(" 3. Start using your skill!");
298
+ }
299
+ } finally {
300
+ cleanup();
301
+ }
193
302
  }
194
-
195
- // Execute installation
196
303
  try {
197
304
  installSkill();
198
305
  } catch (error) {
199
- console.error('\nāŒ Failed to install skill:', error.message);
200
- console.error('\nTroubleshooting:');
201
- console.error('- Ensure .claude-skill.json exists and is valid JSON');
202
- console.error('- Ensure SKILL.md exists');
203
- console.error('- Check file permissions for target directories');
204
- console.error('- Verify at least one target is enabled in .claude-skill.json');
205
- console.error('- Try running with sudo for global installation (if needed)');
306
+ const message = error instanceof Error ? error.message : String(error);
307
+ console.error("\n\u274C Failed to install skill:", message);
308
+ console.error("\nTroubleshooting:");
309
+ console.error("- Ensure .claude-skill.json exists and is valid JSON");
310
+ console.error("- Ensure SKILL.md exists");
311
+ console.error("- Check file permissions for target directories");
312
+ console.error("- Verify at least one target is enabled in .claude-skill.json");
313
+ console.error("- Try running with sudo for global installation (if needed)");
206
314
  process.exit(1);
207
315
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@adonis0123/react-best-practices",
3
- "version": "1.0.2",
4
- "description": "Claude Code Skill - React 和 Next.js ę€§čƒ½ä¼˜åŒ–ęœ€ä½³å®žč·µęŒ‡å—ļ¼Œę„č‡Ŗ Vercel Engineering",
3
+ "version": "1.0.3",
4
+ "description": "Claude Code Skill - React 和 Next.js ę€§čƒ½ä¼˜åŒ–ęœ€ä½³å®žč·µęŒ‡å—ļ¼Œę„č‡Ŗ Vercel Engineeringć€‚å®‰č£…ę—¶č‡ŖåŠØä»ŽäøŠęøøä»“åŗ“ę‹‰å–ęœ€ę–°ē‰ˆęœ¬ć€‚",
5
5
  "files": [
6
6
  "SKILL.md",
7
7
  "AGENTS.md",
@@ -1,87 +1,162 @@
1
1
  #!/usr/bin/env node
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (let key of __getOwnPropNames(from))
11
+ if (!__hasOwnProp.call(to, key) && key !== except)
12
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
13
+ }
14
+ return to;
15
+ };
16
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
17
+ // If the importer is in node compatibility mode or this is not an ESM
18
+ // file that has been converted to a CommonJS file using a Babel-
19
+ // compatible transform (i.e. "__esModule" has not been set), then set
20
+ // "default" to the CommonJS "module.exports" for node compatibility.
21
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
+ mod
23
+ ));
24
+
25
+ // shared/src/uninstall-skill.ts
26
+ var import_fs2 = __toESM(require("fs"));
27
+ var import_path2 = __toESM(require("path"));
28
+
29
+ // shared/src/utils.ts
30
+ var import_fs = __toESM(require("fs"));
31
+ var import_path = __toESM(require("path"));
32
+ var import_os = __toESM(require("os"));
33
+ var CWD = process.env.INIT_CWD || process.cwd();
34
+ var DEFAULT_TARGET = {
35
+ name: "claude-code",
36
+ paths: {
37
+ global: ".claude/skills",
38
+ project: ".claude/skills"
39
+ }
40
+ };
41
+ function getEnabledTargets(config) {
42
+ if (!config.targets) {
43
+ return [DEFAULT_TARGET];
44
+ }
45
+ return Object.entries(config.targets).filter(([_, target]) => target.enabled).map(([name, target]) => ({
46
+ name,
47
+ paths: target.paths
48
+ }));
49
+ }
50
+ function extractSkillName(packageName) {
51
+ if (packageName.startsWith("@")) {
52
+ return packageName.split("/")[1] || packageName;
53
+ }
54
+ return packageName;
55
+ }
56
+ function detectInstallLocation(targetPaths, isGlobal) {
57
+ if (isGlobal) {
58
+ return {
59
+ type: "personal",
60
+ base: import_path.default.join(import_os.default.homedir(), targetPaths.global)
61
+ };
62
+ }
63
+ let projectRoot = CWD;
64
+ while (projectRoot !== import_path.default.dirname(projectRoot)) {
65
+ const hasPackageJson = import_fs.default.existsSync(import_path.default.join(projectRoot, "package.json"));
66
+ const hasGit = import_fs.default.existsSync(import_path.default.join(projectRoot, ".git"));
67
+ const isInNodeModules = projectRoot.includes("/node_modules/") || import_path.default.basename(projectRoot) === "node_modules";
68
+ if ((hasPackageJson || hasGit) && !isInNodeModules) {
69
+ break;
70
+ }
71
+ projectRoot = import_path.default.dirname(projectRoot);
72
+ }
73
+ const finalIsInNodeModules = projectRoot.includes("/node_modules/") || import_path.default.basename(projectRoot) === "node_modules";
74
+ if (finalIsInNodeModules) {
75
+ console.warn("\u26A0 Warning: Could not find project root directory, using current directory");
76
+ projectRoot = CWD;
77
+ }
78
+ return {
79
+ type: "project",
80
+ base: import_path.default.join(projectRoot, targetPaths.project)
81
+ };
82
+ }
83
+ function isGlobalInstall() {
84
+ return process.env.npm_config_global === "true";
85
+ }
86
+ function removeDir(dir) {
87
+ if (import_fs.default.existsSync(dir)) {
88
+ import_fs.default.rmSync(dir, { recursive: true, force: true });
89
+ }
90
+ }
91
+ function readSkillConfig(dir) {
92
+ const configPath = import_path.default.join(dir, ".claude-skill.json");
93
+ if (!import_fs.default.existsSync(configPath)) {
94
+ throw new Error(".claude-skill.json not found");
95
+ }
96
+ return JSON.parse(import_fs.default.readFileSync(configPath, "utf-8"));
97
+ }
2
98
 
3
- const fs = require('fs');
4
- const path = require('path');
5
- const os = require('os');
6
-
7
- const { getEnabledTargets, extractSkillName, detectInstallLocation } = require('./utils');
8
-
99
+ // shared/src/uninstall-skill.ts
100
+ function updateManifest(skillsDir, config) {
101
+ const manifestPath = import_path2.default.join(skillsDir, ".skills-manifest.json");
102
+ if (!import_fs2.default.existsSync(manifestPath)) {
103
+ return;
104
+ }
105
+ try {
106
+ const manifest = JSON.parse(import_fs2.default.readFileSync(manifestPath, "utf-8"));
107
+ if (manifest.skills && manifest.skills[config.name]) {
108
+ delete manifest.skills[config.name];
109
+ import_fs2.default.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
110
+ console.log(" \u2713 Updated manifest");
111
+ }
112
+ } catch (error) {
113
+ const message = error instanceof Error ? error.message : String(error);
114
+ console.warn(" Warning: Could not update manifest:", message);
115
+ }
116
+ }
9
117
  function uninstallFromTarget(target, config) {
10
- console.log(`\nšŸ—‘ļø Uninstalling from ${target.name}...`);
11
-
12
- const isGlobal = process.env.npm_config_global === 'true';
118
+ console.log(`
119
+ \u{1F5D1}\uFE0F Uninstalling from ${target.name}...`);
120
+ const isGlobal = isGlobalInstall();
13
121
  const location = detectInstallLocation(target.paths, isGlobal);
14
-
15
- // Extract skill name from package name (remove scope prefix)
16
122
  const skillName = extractSkillName(config.name);
17
-
18
- // Path format using skill name
19
- const skillNameTargetDir = path.join(location.base, skillName);
20
-
21
- // Path format with full package name (including scope)
22
- const fullPackageNameTargetDir = path.join(location.base, config.name);
23
-
123
+ const skillNameTargetDir = import_path2.default.join(location.base, skillName);
124
+ const fullPackageNameTargetDir = import_path2.default.join(location.base, config.name);
24
125
  let removed = false;
25
-
26
- // Check and remove path using skill name
27
- if (fs.existsSync(skillNameTargetDir)) {
28
- fs.rmSync(skillNameTargetDir, { recursive: true, force: true });
29
- console.log(` āœ“ Removed skill directory: ${skillName}`);
126
+ if (import_fs2.default.existsSync(skillNameTargetDir)) {
127
+ removeDir(skillNameTargetDir);
128
+ console.log(` \u2713 Removed skill directory: ${skillName}`);
30
129
  removed = true;
31
130
  }
32
-
33
- // Check and remove path with full package name (for compatibility)
34
- if (fs.existsSync(fullPackageNameTargetDir) && fullPackageNameTargetDir !== skillNameTargetDir) {
35
- fs.rmSync(fullPackageNameTargetDir, { recursive: true, force: true });
36
- console.log(` āœ“ Removed skill directory: ${config.name}`);
131
+ if (import_fs2.default.existsSync(fullPackageNameTargetDir) && fullPackageNameTargetDir !== skillNameTargetDir) {
132
+ removeDir(fullPackageNameTargetDir);
133
+ console.log(` \u2713 Removed skill directory: ${config.name}`);
37
134
  removed = true;
38
135
  }
39
-
40
- // Update manifest
41
- const manifestPath = path.join(location.base, '.skills-manifest.json');
42
- if (fs.existsSync(manifestPath)) {
43
- try {
44
- const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
45
- if (manifest.skills && manifest.skills[config.name]) {
46
- delete manifest.skills[config.name];
47
- fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
48
- console.log(` āœ“ Updated manifest`);
49
- }
50
- } catch (error) {
51
- console.warn(' Warning: Could not update manifest:', error.message);
52
- }
53
- }
54
-
136
+ updateManifest(location.base, config);
55
137
  if (removed) {
56
- console.log(` āœ… Uninstalled from ${target.name}`);
138
+ console.log(` \u2705 Uninstalled from ${target.name}`);
57
139
  return true;
58
140
  } else {
59
- console.log(` ā„¹ļø Skill was not installed in ${target.name}`);
141
+ console.log(` \u2139\uFE0F Skill was not installed in ${target.name}`);
60
142
  return false;
61
143
  }
62
144
  }
63
-
64
145
  function uninstallSkill() {
65
- console.log('šŸ—‘ļø Uninstalling AI Coding Skill...\n');
66
-
67
- // Read configuration
68
- const configPath = path.join(__dirname, '.claude-skill.json');
69
- if (!fs.existsSync(configPath)) {
70
- console.warn('Warning: .claude-skill.json not found, skipping cleanup');
146
+ console.log("\u{1F5D1}\uFE0F Uninstalling AI Coding Skill...\n");
147
+ const packageDir = __dirname;
148
+ let config;
149
+ try {
150
+ config = readSkillConfig(packageDir);
151
+ } catch {
152
+ console.warn("Warning: .claude-skill.json not found, skipping cleanup");
71
153
  return;
72
154
  }
73
-
74
- const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
75
-
76
- // Get enabled targets
77
155
  const enabledTargets = getEnabledTargets(config);
78
-
79
156
  console.log(`Uninstalling skill "${config.name}" from ${enabledTargets.length} target(s):`);
80
- enabledTargets.forEach(target => {
81
- console.log(` • ${target.name}`);
157
+ enabledTargets.forEach((target) => {
158
+ console.log(` \u2022 ${target.name}`);
82
159
  });
83
-
84
- // Uninstall from all enabled targets
85
160
  const uninstalledFrom = [];
86
161
  for (const target of enabledTargets) {
87
162
  try {
@@ -90,29 +165,27 @@ function uninstallSkill() {
90
165
  uninstalledFrom.push(target.name);
91
166
  }
92
167
  } catch (error) {
93
- console.error(`\nāŒ Failed to uninstall from ${target.name}:`, error.message);
168
+ const message = error instanceof Error ? error.message : String(error);
169
+ console.error(`
170
+ \u274C Failed to uninstall from ${target.name}:`, message);
94
171
  }
95
172
  }
96
-
97
- // Summary
98
- console.log('\n' + '='.repeat(60));
173
+ console.log("\n" + "=".repeat(60));
99
174
  if (uninstalledFrom.length > 0) {
100
- console.log('āœ… Uninstallation Complete!');
101
- console.log('='.repeat(60));
102
- console.log('\nUninstalled from:');
103
- uninstalledFrom.forEach(target => {
104
- console.log(` • ${target}`);
175
+ console.log("\u2705 Uninstallation Complete!");
176
+ console.log("=".repeat(60));
177
+ console.log("\nUninstalled from:");
178
+ uninstalledFrom.forEach((target) => {
179
+ console.log(` \u2022 ${target}`);
105
180
  });
106
181
  } else {
107
- console.log('ā„¹ļø Skill was not installed');
108
- console.log('='.repeat(60));
182
+ console.log("\u2139\uFE0F Skill was not installed");
183
+ console.log("=".repeat(60));
109
184
  }
110
185
  }
111
-
112
- // Execute uninstall
113
186
  try {
114
187
  uninstallSkill();
115
188
  } catch (error) {
116
- console.error('\nāš ļø Warning during uninstall:', error.message);
117
- // Don't exit with error code as uninstall should be best-effort
189
+ const message = error instanceof Error ? error.message : String(error);
190
+ console.error("\n\u26A0\uFE0F Warning during uninstall:", message);
118
191
  }
package/utils.js DELETED
@@ -1,94 +0,0 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
- const os = require('os');
4
-
5
- const CWD = process.env.INIT_CWD || process.cwd();
6
-
7
- /**
8
- * Get enabled target configurations
9
- */
10
- function getEnabledTargets(config) {
11
- // If no targets configuration, use default Claude Code configuration
12
- if (!config.targets) {
13
- return [{
14
- name: 'claude-code',
15
- paths: {
16
- global: '.claude/skills',
17
- project: '.claude/skills'
18
- }
19
- }];
20
- }
21
-
22
- // Return all enabled targets
23
- return Object.entries(config.targets)
24
- .filter(([_, target]) => target.enabled)
25
- .map(([name, target]) => ({
26
- name,
27
- paths: target.paths
28
- }));
29
- }
30
-
31
- /**
32
- * Extract skill name from package name (remove scope prefix)
33
- */
34
- function extractSkillName(packageName) {
35
- return packageName.startsWith('@') ?
36
- packageName.split('/')[1] || packageName :
37
- packageName;
38
- }
39
-
40
- /**
41
- * Detect installation location
42
- */
43
- function detectInstallLocation(targetPaths, isGlobal) {
44
- if (isGlobal) {
45
- // Global installation: install to user home directory
46
- return {
47
- type: 'personal',
48
- base: path.join(os.homedir(), targetPaths.global)
49
- };
50
- } else {
51
- // Project-level installation: find the actual project root directory
52
- let projectRoot = CWD;
53
-
54
- // Search upward, skip node_modules directories, find the actual project root
55
- while (projectRoot !== path.dirname(projectRoot)) {
56
- // Check if this is a project root directory (contains package.json or .git)
57
- const hasPackageJson = fs.existsSync(path.join(projectRoot, 'package.json'));
58
- const hasGit = fs.existsSync(path.join(projectRoot, '.git'));
59
-
60
- // Check if current directory is in node_modules
61
- const isInNodeModules = projectRoot.includes('/node_modules/') ||
62
- path.basename(projectRoot) === 'node_modules';
63
-
64
- if ((hasPackageJson || hasGit) && !isInNodeModules) {
65
- // Found the actual project root directory
66
- break;
67
- }
68
-
69
- // Continue searching upward
70
- projectRoot = path.dirname(projectRoot);
71
- }
72
-
73
- // Verify the final path is reasonable
74
- const finalIsInNodeModules = projectRoot.includes('/node_modules/') ||
75
- path.basename(projectRoot) === 'node_modules';
76
-
77
- if (finalIsInNodeModules) {
78
- // If suitable project root not found, use current working directory (with warning)
79
- console.warn('⚠ Warning: Could not find project root directory, using current directory');
80
- projectRoot = CWD;
81
- }
82
-
83
- return {
84
- type: 'project',
85
- base: path.join(projectRoot, targetPaths.project)
86
- };
87
- }
88
- }
89
-
90
- module.exports = {
91
- getEnabledTargets,
92
- extractSkillName,
93
- detectInstallLocation
94
- };