prpm 0.1.6 → 0.1.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.
@@ -10,6 +10,7 @@ const user_config_1 = require("../core/user-config");
10
10
  const telemetry_1 = require("../core/telemetry");
11
11
  const child_process_1 = require("child_process");
12
12
  const util_1 = require("util");
13
+ const webapp_url_1 = require("../utils/webapp-url");
13
14
  const execAsync = (0, util_1.promisify)(child_process_1.exec);
14
15
  /**
15
16
  * Make authenticated API call
@@ -114,8 +115,8 @@ async function handleBuyCredits(options) {
114
115
  console.log('\n✨ These credits never expire!');
115
116
  console.log('šŸ’” Tip: Subscribe to PRPM+ for 100 monthly credits at just $6/month');
116
117
  // Build URL with package parameter if specified
117
- const baseUrl = (config.registryUrl || 'https://registry.prpm.dev').replace(/api\/?$/, '');
118
- let purchaseUrl = `${baseUrl}/playground/credits/buy`;
118
+ const webappUrl = (0, webapp_url_1.getWebappUrl)(config.registryUrl || 'https://registry.prpm.dev');
119
+ let purchaseUrl = `${webappUrl}/playground/credits/buy`;
119
120
  if (options.package) {
120
121
  const validPackages = ['small', 'medium', 'large'];
121
122
  if (!validPackages.includes(options.package)) {
@@ -220,8 +220,20 @@ async function handleInstall(packageSpec, options) {
220
220
  console.log(` ${pkg.name} ${pkg.official ? 'šŸ…' : ''}`);
221
221
  console.log(` ${pkg.description || 'No description'}`);
222
222
  console.log(` ${typeIcon} Type: ${typeLabel}`);
223
- // Determine format preference
224
- let format = options.as || pkg.format;
223
+ // Determine format preference with auto-detection
224
+ let format = options.as;
225
+ // Auto-detect format if not explicitly specified
226
+ if (!format) {
227
+ const detectedFormat = await (0, filesystem_1.autoDetectFormat)();
228
+ if (detectedFormat) {
229
+ format = detectedFormat;
230
+ console.log(` šŸ” Auto-detected ${format} format (found .${format}/ directory)`);
231
+ }
232
+ else {
233
+ // No existing directories found, use package's native format
234
+ format = pkg.format;
235
+ }
236
+ }
225
237
  // Special handling for Claude packages: default to CLAUDE.md if it doesn't exist
226
238
  // BUT only for packages that are generic rules (not skills, agents, or commands)
227
239
  if (!options.as && pkg.format === 'claude' && pkg.subtype === 'rule') {
@@ -355,7 +367,25 @@ async function handleInstall(packageSpec, options) {
355
367
  }
356
368
  }
357
369
  for (const file of extractedFiles) {
358
- const filePath = `${packageDir}/${file.name}`;
370
+ // Strip the tarball's root directory prefix to preserve subdirectories
371
+ // Example: ".claude/skills/agent-builder/docs/examples.md" → "docs/examples.md"
372
+ // ".claude/skills/agent-builder/SKILL.md" → "SKILL.md"
373
+ // Find the common prefix (the package's root directory in the tarball)
374
+ const pathParts = file.name.split('/');
375
+ // For Claude skills, the tarball structure is typically: .claude/skills/package-name/...
376
+ // We want to strip everything up to and including the package-name directory
377
+ let relativeFileName = file.name;
378
+ // Find the skills directory index
379
+ const skillsDirIndex = pathParts.indexOf('skills');
380
+ if (skillsDirIndex !== -1 && pathParts.length > skillsDirIndex + 2) {
381
+ // Skip: .claude/skills/package-name/ and keep the rest
382
+ relativeFileName = pathParts.slice(skillsDirIndex + 2).join('/');
383
+ }
384
+ else if (pathParts.length > 1) {
385
+ // Fallback: just take the filename (last part)
386
+ relativeFileName = pathParts[pathParts.length - 1];
387
+ }
388
+ const filePath = `${packageDir}/${relativeFileName}`;
359
389
  await (0, filesystem_1.saveFile)(filePath, file.content);
360
390
  fileCount++;
361
391
  }
@@ -10,6 +10,7 @@ const user_config_1 = require("../core/user-config");
10
10
  const telemetry_1 = require("../core/telemetry");
11
11
  const child_process_1 = require("child_process");
12
12
  const util_1 = require("util");
13
+ const webapp_url_1 = require("../utils/webapp-url");
13
14
  const execAsync = (0, util_1.promisify)(child_process_1.exec);
14
15
  /**
15
16
  * Make authenticated API call
@@ -125,7 +126,8 @@ async function handleSubscribe() {
125
126
  console.log(' $6/month for individuals');
126
127
  console.log(' $3/month for verified organization members (50% off)');
127
128
  // Open subscription page
128
- const subscribeUrl = `${(config.registryUrl || "https://registry.prpm.dev").replace(/api\/?$/, '')}/playground/credits/subscribe`;
129
+ const webappUrl = (0, webapp_url_1.getWebappUrl)(config.registryUrl || 'https://registry.prpm.dev');
130
+ const subscribeUrl = `${webappUrl}/playground/credits/subscribe`;
129
131
  console.log(`\n🌐 Opening subscription page in your browser...`);
130
132
  await openBrowser(subscribeUrl);
131
133
  // Poll for subscription confirmation
@@ -27,40 +27,24 @@ async function handleUninstall(name) {
27
27
  const packageName = (0, filesystem_1.stripAuthorNamespace)(name);
28
28
  const destDir = (0, filesystem_1.getDestinationDir)(format, subtype, packageName);
29
29
  const fileExtension = pkg.format === 'cursor' ? 'mdc' : 'md';
30
- // For Claude skills, check the directory structure first (since they use SKILL.md)
30
+ // For Claude skills, delete the entire directory (may contain multiple files)
31
31
  if (format === 'claude' && subtype === 'skill') {
32
- // Claude skills are in .claude/skills/${packageName}/ with SKILL.md file
33
- const skillPath = `${destDir}/SKILL.md`;
34
- if (await (0, filesystem_1.fileExists)(skillPath)) {
35
- // Delete the SKILL.md file
36
- await (0, filesystem_1.deleteFile)(skillPath);
37
- console.log(` šŸ—‘ļø Deleted file: ${skillPath}`);
38
- // If the directory is empty or only contains SKILL.md, delete the directory too
39
- try {
40
- const dirContents = await fs_1.promises.readdir(destDir);
41
- if (dirContents.length === 0) {
42
- await fs_1.promises.rmdir(destDir);
43
- console.log(` šŸ—‘ļø Deleted empty directory: ${destDir}`);
44
- }
45
- }
46
- catch (error) {
47
- // Directory doesn't exist or can't be deleted, that's okay
32
+ // Claude skills are in .claude/skills/${packageName}/ directory
33
+ // Delete the entire directory (includes SKILL.md, EXAMPLES.md, docs/, etc.)
34
+ try {
35
+ const stats = await fs_1.promises.stat(destDir);
36
+ if (stats.isDirectory()) {
37
+ await fs_1.promises.rm(destDir, { recursive: true, force: true });
38
+ console.log(` šŸ—‘ļø Deleted directory: ${destDir}`);
48
39
  }
49
40
  }
50
- else {
51
- // Try the whole directory
52
- try {
53
- const stats = await fs_1.promises.stat(destDir);
54
- if (stats.isDirectory()) {
55
- await fs_1.promises.rm(destDir, { recursive: true, force: true });
56
- console.log(` šŸ—‘ļø Deleted directory: ${destDir}`);
57
- }
41
+ catch (error) {
42
+ const err = error;
43
+ if (err.code === 'ENOENT') {
44
+ console.warn(` āš ļø Skill directory not found: ${destDir}`);
58
45
  }
59
- catch (error) {
60
- const err = error;
61
- if (err.code !== 'ENOENT') {
62
- console.warn(` āš ļø Could not delete package files: ${err.message}`);
63
- }
46
+ else {
47
+ console.warn(` āš ļø Could not delete skill directory: ${err.message}`);
64
48
  }
65
49
  }
66
50
  }
@@ -11,6 +11,8 @@ exports.ensureDirectoryExists = ensureDirectoryExists;
11
11
  exports.saveFile = saveFile;
12
12
  exports.deleteFile = deleteFile;
13
13
  exports.fileExists = fileExists;
14
+ exports.directoryExists = directoryExists;
15
+ exports.autoDetectFormat = autoDetectFormat;
14
16
  exports.generateId = generateId;
15
17
  exports.stripAuthorNamespace = stripAuthorNamespace;
16
18
  exports.getInstalledFilePath = getInstalledFilePath;
@@ -119,6 +121,39 @@ async function fileExists(filePath) {
119
121
  return false;
120
122
  }
121
123
  }
124
+ /**
125
+ * Check if a directory exists
126
+ */
127
+ async function directoryExists(dirPath) {
128
+ try {
129
+ const stats = await fs_1.promises.stat(dirPath);
130
+ return stats.isDirectory();
131
+ }
132
+ catch {
133
+ return false;
134
+ }
135
+ }
136
+ /**
137
+ * Auto-detect the format based on existing directories in the current project
138
+ * Returns the format if a matching directory is found, or null if none found
139
+ */
140
+ async function autoDetectFormat() {
141
+ const formatDirs = [
142
+ { format: 'cursor', dir: '.cursor' },
143
+ { format: 'claude', dir: '.claude' },
144
+ { format: 'continue', dir: '.continue' },
145
+ { format: 'windsurf', dir: '.windsurf' },
146
+ { format: 'copilot', dir: '.github/instructions' },
147
+ { format: 'kiro', dir: '.kiro' },
148
+ { format: 'agents.md', dir: '.agents' },
149
+ ];
150
+ for (const { format, dir } of formatDirs) {
151
+ if (await directoryExists(dir)) {
152
+ return format;
153
+ }
154
+ }
155
+ return null;
156
+ }
122
157
  /**
123
158
  * Generate a unique ID from filename
124
159
  */
package/dist/index.js CHANGED
File without changes
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ /**
3
+ * Utility to convert registry URL to webapp URL
4
+ * Handles localhost, production, and custom registry URLs
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.getWebappUrl = getWebappUrl;
8
+ /**
9
+ * Convert a registry URL to its corresponding webapp URL
10
+ *
11
+ * @param registryUrl - The registry URL (e.g., https://registry.prpm.dev)
12
+ * @returns The webapp URL (e.g., https://prpm.dev)
13
+ *
14
+ * @example
15
+ * // Production
16
+ * getWebappUrl('https://registry.prpm.dev') // => 'https://prpm.dev'
17
+ *
18
+ * // Local development
19
+ * getWebappUrl('http://localhost:3111') // => 'http://localhost:5173'
20
+ *
21
+ * // Custom registry
22
+ * getWebappUrl('https://registry.custom.com') // => 'https://custom.com'
23
+ */
24
+ function getWebappUrl(registryUrl) {
25
+ const cleanUrl = registryUrl.replace(/\/$/, '').replace(/\/api\/?$/, '');
26
+ if (cleanUrl.includes('localhost') || cleanUrl.includes('127.0.0.1')) {
27
+ // Local development: registry on port 3111, webapp on port 5173
28
+ return cleanUrl.replace(':3111', ':5173');
29
+ }
30
+ if (cleanUrl.includes('registry.prpm.dev')) {
31
+ // Production: always use prpm.dev webapp
32
+ return 'https://prpm.dev';
33
+ }
34
+ // Custom registry: assume webapp is on same host without 'registry.' subdomain
35
+ try {
36
+ const url = new URL(cleanUrl);
37
+ const hostname = url.hostname.replace(/^registry\./, '');
38
+ return `${url.protocol}//${hostname}`;
39
+ }
40
+ catch {
41
+ // If URL parsing fails, return as-is
42
+ return cleanUrl;
43
+ }
44
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prpm",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "Prompt Package Manager CLI - Install and manage prompt-based files",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -45,8 +45,8 @@
45
45
  "license": "MIT",
46
46
  "dependencies": {
47
47
  "@octokit/rest": "^22.0.0",
48
- "@pr-pm/registry-client": "^1.3.4",
49
- "@pr-pm/types": "^0.2.6",
48
+ "@pr-pm/registry-client": "^1.3.6",
49
+ "@pr-pm/types": "^0.2.7",
50
50
  "ajv": "^8.17.1",
51
51
  "ajv-formats": "^3.0.1",
52
52
  "commander": "^11.1.0",
@@ -1,280 +0,0 @@
1
- "use strict";
2
- /**
3
- * Hooks command - Manage git hooks for running agents
4
- */
5
- var __importDefault = (this && this.__importDefault) || function (mod) {
6
- return (mod && mod.__esModule) ? mod : { "default": mod };
7
- };
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.createHooksCommand = createHooksCommand;
10
- const commander_1 = require("commander");
11
- const fs_1 = require("fs");
12
- const path_1 = require("path");
13
- const child_process_1 = require("child_process");
14
- const chalk_1 = __importDefault(require("chalk"));
15
- /**
16
- * Check if we're in a git repository
17
- */
18
- function isGitRepo() {
19
- try {
20
- (0, child_process_1.execSync)('git rev-parse --git-dir', { stdio: 'ignore' });
21
- return true;
22
- }
23
- catch {
24
- return false;
25
- }
26
- }
27
- /**
28
- * Get the git hooks directory
29
- */
30
- function getGitHooksDir() {
31
- try {
32
- const gitDir = (0, child_process_1.execSync)('git rev-parse --git-dir', { encoding: 'utf-8' }).trim();
33
- return (0, path_1.join)(gitDir, 'hooks');
34
- }
35
- catch (error) {
36
- throw new Error('Not in a git repository');
37
- }
38
- }
39
- /**
40
- * Create hooks configuration file template
41
- */
42
- function createHooksConfig() {
43
- const configDir = '.prpm';
44
- const configPath = (0, path_1.join)(configDir, 'hooks.json');
45
- if ((0, fs_1.existsSync)(configPath)) {
46
- console.log(chalk_1.default.yellow(`āš ļø Hooks configuration already exists at ${configPath}`));
47
- return;
48
- }
49
- // Create .prpm directory if it doesn't exist
50
- if (!(0, fs_1.existsSync)(configDir)) {
51
- (0, fs_1.mkdirSync)(configDir, { recursive: true });
52
- }
53
- const template = {
54
- hooks: {
55
- 'pre-commit': {
56
- enabled: true,
57
- agents: [
58
- {
59
- name: '@pre-commit/security-scanner',
60
- files: '**/*.{js,ts,py}',
61
- severity: 'error',
62
- autoFix: false,
63
- },
64
- ],
65
- },
66
- },
67
- settings: {
68
- enabled: true,
69
- timeout: 30000,
70
- cache: {
71
- enabled: true,
72
- ttl: 3600,
73
- },
74
- },
75
- };
76
- (0, fs_1.writeFileSync)(configPath, JSON.stringify(template, null, 2));
77
- console.log(chalk_1.default.green(`āœ“ Created hooks configuration at ${configPath}`));
78
- console.log(chalk_1.default.dim('\nEdit this file to configure which agents run on git hooks.'));
79
- console.log(chalk_1.default.dim('Install agents with: prpm install @pre-commit/security-scanner\n'));
80
- }
81
- /**
82
- * Install git hooks
83
- */
84
- async function handleInstall() {
85
- if (!isGitRepo()) {
86
- console.error(chalk_1.default.red('āœ— Not in a git repository'));
87
- console.log(chalk_1.default.dim('Run this command from the root of your git repository.\n'));
88
- process.exit(1);
89
- }
90
- const hooksDir = getGitHooksDir();
91
- const configPath = (0, path_1.join)('.prpm', 'hooks.json');
92
- // Create hooks config if it doesn't exist
93
- if (!(0, fs_1.existsSync)(configPath)) {
94
- createHooksConfig();
95
- }
96
- // Create hooks directory if it doesn't exist
97
- if (!(0, fs_1.existsSync)(hooksDir)) {
98
- (0, fs_1.mkdirSync)(hooksDir, { recursive: true });
99
- }
100
- // Create pre-commit hook
101
- const preCommitHook = (0, path_1.join)(hooksDir, 'pre-commit');
102
- const hookScript = `#!/bin/sh
103
- # PRPM pre-commit hook
104
- # Generated by prpm hooks install
105
-
106
- # Run PRPM hooks command
107
- prpm hooks run pre-commit
108
-
109
- # Exit with the same code as the hooks command
110
- exit $?
111
- `;
112
- (0, fs_1.writeFileSync)(preCommitHook, hookScript);
113
- (0, fs_1.chmodSync)(preCommitHook, 0o755);
114
- console.log(chalk_1.default.green('āœ“ Git hooks installed successfully'));
115
- console.log(chalk_1.default.dim(`\nInstalled hooks:`));
116
- console.log(chalk_1.default.dim(` - pre-commit → ${preCommitHook}`));
117
- console.log(chalk_1.default.dim(`\nConfiguration: ${configPath}`));
118
- console.log(chalk_1.default.dim('\nRun ') + chalk_1.default.cyan('prpm hooks uninstall') + chalk_1.default.dim(' to remove hooks.\n'));
119
- }
120
- /**
121
- * Uninstall git hooks
122
- */
123
- async function handleUninstall() {
124
- if (!isGitRepo()) {
125
- console.error(chalk_1.default.red('āœ— Not in a git repository'));
126
- process.exit(1);
127
- }
128
- const hooksDir = getGitHooksDir();
129
- const preCommitHook = (0, path_1.join)(hooksDir, 'pre-commit');
130
- if ((0, fs_1.existsSync)(preCommitHook)) {
131
- // Check if it's a PRPM hook
132
- const content = (0, fs_1.readFileSync)(preCommitHook, 'utf-8');
133
- if (content.includes('PRPM pre-commit hook')) {
134
- (0, fs_1.unlinkSync)(preCommitHook);
135
- console.log(chalk_1.default.green('āœ“ PRPM git hooks uninstalled successfully'));
136
- console.log(chalk_1.default.dim(`\nRemoved: ${preCommitHook}\n`));
137
- }
138
- else {
139
- console.log(chalk_1.default.yellow('āš ļø Pre-commit hook exists but was not installed by PRPM'));
140
- console.log(chalk_1.default.dim('Will not remove it. Please remove manually if needed.\n'));
141
- }
142
- }
143
- else {
144
- console.log(chalk_1.default.yellow('āš ļø No PRPM hooks found'));
145
- console.log(chalk_1.default.dim('Hooks may have already been removed.\n'));
146
- }
147
- }
148
- /**
149
- * Run hooks for a specific event (pre-commit, pre-push, etc.)
150
- */
151
- async function handleRun(hookType) {
152
- const configPath = (0, path_1.join)('.prpm', 'hooks.json');
153
- if (!(0, fs_1.existsSync)(configPath)) {
154
- console.error(chalk_1.default.red('āœ— Hooks configuration not found'));
155
- console.log(chalk_1.default.dim(`Run ${chalk_1.default.cyan('prpm hooks install')} to set up hooks.\n`));
156
- process.exit(1);
157
- }
158
- // Read configuration
159
- const config = JSON.parse((0, fs_1.readFileSync)(configPath, 'utf-8'));
160
- // Check if hooks are globally enabled
161
- if (config.settings?.enabled === false) {
162
- console.log(chalk_1.default.dim('ā„¹ļø Hooks are disabled in configuration'));
163
- process.exit(0);
164
- }
165
- // Get hook configuration
166
- const hookConfig = config.hooks?.[hookType];
167
- if (!hookConfig || !hookConfig.enabled) {
168
- console.log(chalk_1.default.dim(`ā„¹ļø ${hookType} hook is not enabled`));
169
- process.exit(0);
170
- }
171
- // Check if any agents are configured
172
- if (!hookConfig.agents || hookConfig.agents.length === 0) {
173
- console.log(chalk_1.default.dim(`ā„¹ļø No agents configured for ${hookType}`));
174
- process.exit(0);
175
- }
176
- console.log(chalk_1.default.blue(`\nšŸ” Running ${hookType} checks...\n`));
177
- // TODO: Implement agent execution
178
- // For now, just show what would be executed
179
- let hasErrors = false;
180
- for (const agent of hookConfig.agents) {
181
- if (!agent.enabled) {
182
- continue;
183
- }
184
- console.log(chalk_1.default.dim(` Checking with ${agent.name}...`));
185
- // TODO: Execute agent here
186
- // This is a placeholder - actual implementation will:
187
- // 1. Get staged files (for pre-commit) using git diff --cached --name-only
188
- // 2. Filter files by glob pattern (agent.files)
189
- // 3. Load agent package
190
- // 4. Execute agent via Anthropic SDK
191
- // 5. Process results and show output
192
- console.log(chalk_1.default.yellow(` āš ļø Not implemented yet - would check files matching: ${agent.files}`));
193
- if (agent.severity === 'error') {
194
- // hasErrors = true; // Uncomment when implemented
195
- }
196
- }
197
- if (hasErrors) {
198
- console.log(chalk_1.default.red('\nāœ— Checks failed. Please fix the issues above.\n'));
199
- process.exit(1);
200
- }
201
- console.log(chalk_1.default.green('\nāœ“ All checks passed\n'));
202
- process.exit(0);
203
- }
204
- /**
205
- * Show status of installed hooks
206
- */
207
- async function handleStatus() {
208
- if (!isGitRepo()) {
209
- console.error(chalk_1.default.red('āœ— Not in a git repository'));
210
- process.exit(1);
211
- }
212
- const hooksDir = getGitHooksDir();
213
- const configPath = (0, path_1.join)('.prpm', 'hooks.json');
214
- const preCommitHook = (0, path_1.join)(hooksDir, 'pre-commit');
215
- console.log(chalk_1.default.blue('\nšŸ“‹ PRPM Hooks Status\n'));
216
- // Check if hooks are installed
217
- let hooksInstalled = false;
218
- if ((0, fs_1.existsSync)(preCommitHook)) {
219
- const content = (0, fs_1.readFileSync)(preCommitHook, 'utf-8');
220
- if (content.includes('PRPM pre-commit hook')) {
221
- hooksInstalled = true;
222
- console.log(chalk_1.default.green('āœ“ Git hooks: Installed'));
223
- }
224
- else {
225
- console.log(chalk_1.default.yellow('āš ļø Git hooks: Other hook exists'));
226
- }
227
- }
228
- else {
229
- console.log(chalk_1.default.red('āœ— Git hooks: Not installed'));
230
- }
231
- // Check if config exists
232
- if ((0, fs_1.existsSync)(configPath)) {
233
- console.log(chalk_1.default.green(`āœ“ Configuration: ${configPath}`));
234
- const config = JSON.parse((0, fs_1.readFileSync)(configPath, 'utf-8'));
235
- const enabled = config.settings?.enabled !== false;
236
- console.log(chalk_1.default.dim(` Enabled: ${enabled ? 'yes' : 'no'}`));
237
- // Show configured hooks
238
- if (config.hooks) {
239
- const hookTypes = Object.keys(config.hooks);
240
- if (hookTypes.length > 0) {
241
- console.log(chalk_1.default.dim(`\n Configured hooks:`));
242
- for (const hookType of hookTypes) {
243
- const hookConfig = config.hooks[hookType];
244
- const agentCount = hookConfig.agents?.length || 0;
245
- const hookEnabled = hookConfig.enabled !== false;
246
- const status = hookEnabled ? chalk_1.default.green('enabled') : chalk_1.default.dim('disabled');
247
- console.log(chalk_1.default.dim(` - ${hookType}: ${status}, ${agentCount} agent(s)`));
248
- }
249
- }
250
- }
251
- }
252
- else {
253
- console.log(chalk_1.default.yellow('āš ļø Configuration: Not found'));
254
- }
255
- console.log();
256
- }
257
- /**
258
- * Create the hooks command
259
- */
260
- function createHooksCommand() {
261
- const hooksCommand = new commander_1.Command('hooks')
262
- .description('Manage git hooks for running agents on code changes');
263
- hooksCommand
264
- .command('install')
265
- .description('Install PRPM git hooks')
266
- .action(handleInstall);
267
- hooksCommand
268
- .command('uninstall')
269
- .description('Uninstall PRPM git hooks')
270
- .action(handleUninstall);
271
- hooksCommand
272
- .command('run <hook-type>')
273
- .description('Run agents for a specific hook (used internally by git)')
274
- .action(handleRun);
275
- hooksCommand
276
- .command('status')
277
- .description('Show status of installed hooks and configuration')
278
- .action(handleStatus);
279
- return hooksCommand;
280
- }
@@ -1,76 +0,0 @@
1
- "use strict";
2
- /**
3
- * Remove command implementation
4
- */
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.handleRemove = handleRemove;
7
- exports.createRemoveCommand = createRemoveCommand;
8
- const commander_1 = require("commander");
9
- const lockfile_1 = require("../core/lockfile");
10
- const filesystem_1 = require("../core/filesystem");
11
- const fs_1 = require("fs");
12
- /**
13
- * Handle the remove command
14
- */
15
- async function handleRemove(name) {
16
- try {
17
- console.log(`šŸ—‘ļø Removing package: ${name}`);
18
- // Remove from lockfile and get package info
19
- const pkg = await (0, lockfile_1.removePackage)(name);
20
- if (!pkg) {
21
- console.error(`āŒ Package "${name}" not found`);
22
- process.exit(1);
23
- }
24
- // Determine file path based on package type and format
25
- const effectiveType = (pkg.format === 'claude' ? 'claude-skill' :
26
- pkg.format === 'cursor' ? 'cursor' :
27
- pkg.format === 'continue' ? 'continue' :
28
- pkg.format === 'windsurf' ? 'windsurf' :
29
- pkg.type);
30
- const destDir = (0, filesystem_1.getDestinationDir)(effectiveType);
31
- const fileExtension = pkg.format === 'cursor' ? 'mdc' : 'md';
32
- // Strip author namespace to get just the package name
33
- const packageName = (0, filesystem_1.stripAuthorNamespace)(name);
34
- // Try single file first
35
- const singleFilePath = `${destDir}/${packageName}.${fileExtension}`;
36
- if (await (0, filesystem_1.fileExists)(singleFilePath)) {
37
- // Single file package
38
- await (0, filesystem_1.deleteFile)(singleFilePath);
39
- console.log(` šŸ—‘ļø Deleted file: ${singleFilePath}`);
40
- }
41
- else {
42
- // Try multi-file package directory
43
- const packageDir = `${destDir}/${packageName}`;
44
- try {
45
- const stats = await fs_1.promises.stat(packageDir);
46
- if (stats.isDirectory()) {
47
- await fs_1.promises.rm(packageDir, { recursive: true, force: true });
48
- console.log(` šŸ—‘ļø Deleted directory: ${packageDir}`);
49
- }
50
- }
51
- catch (error) {
52
- const err = error;
53
- if (err.code !== 'ENOENT') {
54
- console.warn(` āš ļø Could not delete package files: ${err.message}`);
55
- }
56
- }
57
- }
58
- console.log(`āœ… Successfully removed ${name}`);
59
- process.exit(0);
60
- }
61
- catch (error) {
62
- console.error(`āŒ Failed to remove package: ${error}`);
63
- process.exit(1);
64
- }
65
- }
66
- /**
67
- * Create the remove command
68
- */
69
- function createRemoveCommand() {
70
- const command = new commander_1.Command('remove');
71
- command
72
- .description('Remove a prompt package')
73
- .argument('<id>', 'Package ID to remove')
74
- .action(handleRemove);
75
- return command;
76
- }