prpm 0.0.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.
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ /**
3
+ * Index command implementation
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.handleIndex = handleIndex;
10
+ exports.createIndexCommand = createIndexCommand;
11
+ const commander_1 = require("commander");
12
+ const fs_1 = require("fs");
13
+ const path_1 = __importDefault(require("path"));
14
+ const config_1 = require("../core/config");
15
+ const filesystem_1 = require("../core/filesystem");
16
+ /**
17
+ * Scan directory for files and return file information
18
+ */
19
+ async function scanDirectory(dirPath, type) {
20
+ try {
21
+ const files = await fs_1.promises.readdir(dirPath, { withFileTypes: true });
22
+ const results = [];
23
+ for (const file of files) {
24
+ if (file.isFile()) {
25
+ const filePath = path_1.default.join(dirPath, file.name);
26
+ const id = (0, filesystem_1.generateId)(file.name);
27
+ results.push({
28
+ filePath,
29
+ filename: file.name,
30
+ id
31
+ });
32
+ }
33
+ }
34
+ return results;
35
+ }
36
+ catch (error) {
37
+ // Directory doesn't exist or can't be read
38
+ return [];
39
+ }
40
+ }
41
+ /**
42
+ * Check if a package is already registered
43
+ */
44
+ function isPackageRegistered(packages, id, filePath) {
45
+ return packages.some(pkg => pkg.id === id || pkg.dest === filePath);
46
+ }
47
+ /**
48
+ * Handle the index command
49
+ */
50
+ async function handleIndex() {
51
+ try {
52
+ console.log('šŸ” Scanning for existing prompt files...');
53
+ // Get currently registered packages
54
+ const existingPackages = await (0, config_1.listPackages)();
55
+ console.log(`šŸ“‹ Found ${existingPackages.length} already registered packages`);
56
+ let totalFound = 0;
57
+ let totalAdded = 0;
58
+ // Scan .cursor/rules directory
59
+ console.log('\nšŸ“ Scanning .cursor/rules/...');
60
+ const cursorFiles = await scanDirectory('.cursor/rules', 'cursor');
61
+ totalFound += cursorFiles.length;
62
+ for (const file of cursorFiles) {
63
+ if (!isPackageRegistered(existingPackages, file.id, file.filePath)) {
64
+ const pkg = {
65
+ id: file.id,
66
+ type: 'cursor',
67
+ url: `file://${path_1.default.resolve(file.filePath)}`, // Use file:// URL for local files
68
+ dest: file.filePath
69
+ };
70
+ await (0, config_1.addPackage)(pkg);
71
+ console.log(` āœ… Added: ${file.filename} (${file.id})`);
72
+ totalAdded++;
73
+ }
74
+ else {
75
+ console.log(` ā­ļø Skipped: ${file.filename} (already registered)`);
76
+ }
77
+ }
78
+ // Scan .claude/agents directory
79
+ console.log('\nšŸ“ Scanning .claude/agents/...');
80
+ const claudeFiles = await scanDirectory('.claude/agents', 'claude');
81
+ totalFound += claudeFiles.length;
82
+ for (const file of claudeFiles) {
83
+ if (!isPackageRegistered(existingPackages, file.id, file.filePath)) {
84
+ const pkg = {
85
+ id: file.id,
86
+ type: 'claude',
87
+ url: `file://${path_1.default.resolve(file.filePath)}`, // Use file:// URL for local files
88
+ dest: file.filePath
89
+ };
90
+ await (0, config_1.addPackage)(pkg);
91
+ console.log(` āœ… Added: ${file.filename} (${file.id})`);
92
+ totalAdded++;
93
+ }
94
+ else {
95
+ console.log(` ā­ļø Skipped: ${file.filename} (already registered)`);
96
+ }
97
+ }
98
+ // Summary
99
+ console.log('\nšŸ“Š Index Summary:');
100
+ console.log(` šŸ“ Total files found: ${totalFound}`);
101
+ console.log(` āž• New packages added: ${totalAdded}`);
102
+ console.log(` ā­ļø Already registered: ${totalFound - totalAdded}`);
103
+ if (totalAdded > 0) {
104
+ console.log(`\nāœ… Successfully indexed ${totalAdded} new packages!`);
105
+ }
106
+ else {
107
+ console.log('\n✨ All existing files are already registered.');
108
+ }
109
+ }
110
+ catch (error) {
111
+ console.error(`āŒ Failed to index packages: ${error}`);
112
+ process.exit(1);
113
+ }
114
+ }
115
+ /**
116
+ * Create the index command
117
+ */
118
+ function createIndexCommand() {
119
+ const command = new commander_1.Command('index');
120
+ command
121
+ .description('Scan existing .cursor/rules/ and .claude/agents/ directories and register unregistered files')
122
+ .action(handleIndex);
123
+ return command;
124
+ }
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ /**
3
+ * Info command - Display detailed package information
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.handleInfo = handleInfo;
7
+ exports.createInfoCommand = createInfoCommand;
8
+ const commander_1 = require("commander");
9
+ const registry_client_1 = require("@prpm/registry-client");
10
+ const user_config_1 = require("../core/user-config");
11
+ const telemetry_1 = require("../core/telemetry");
12
+ async function handleInfo(packageId) {
13
+ const startTime = Date.now();
14
+ let success = false;
15
+ let error;
16
+ try {
17
+ console.log(`šŸ“¦ Fetching package info for "${packageId}"...`);
18
+ const config = await (0, user_config_1.getConfig)();
19
+ const client = (0, registry_client_1.getRegistryClient)(config);
20
+ const pkg = await client.getPackage(packageId);
21
+ console.log('\n' + '='.repeat(60));
22
+ console.log(` ${pkg.display_name} ${pkg.verified ? 'āœ“ Verified' : ''}`);
23
+ console.log('='.repeat(60));
24
+ // Description
25
+ if (pkg.description) {
26
+ console.log(`\nšŸ“ ${pkg.description}`);
27
+ }
28
+ // Stats
29
+ console.log('\nšŸ“Š Stats:');
30
+ console.log(` Downloads: ${pkg.total_downloads.toLocaleString()}`);
31
+ if (pkg.rating_average) {
32
+ console.log(` Rating: ${'⭐'.repeat(Math.round(pkg.rating_average))} (${pkg.rating_average.toFixed(1)}/5)`);
33
+ }
34
+ // Latest version
35
+ if (pkg.latest_version) {
36
+ console.log(`\nšŸ·ļø Latest Version: ${pkg.latest_version.version}`);
37
+ }
38
+ // Tags
39
+ if (pkg.tags && pkg.tags.length > 0) {
40
+ console.log(`\nšŸ·ļø Tags: ${pkg.tags.join(', ')}`);
41
+ }
42
+ // Type
43
+ console.log(`\nšŸ“‚ Type: ${pkg.type}`);
44
+ // Installation
45
+ console.log('\nšŸ’» Installation:');
46
+ console.log(` prpm install ${pkg.id}`);
47
+ console.log(` prpm install ${pkg.id}@${pkg.latest_version?.version || 'latest'}`);
48
+ console.log('\n' + '='.repeat(60));
49
+ success = true;
50
+ }
51
+ catch (err) {
52
+ error = err instanceof Error ? err.message : String(err);
53
+ console.error(`\nāŒ Failed to fetch package info: ${error}`);
54
+ console.log(`\nšŸ’” Tips:`);
55
+ console.log(` - Check the package ID spelling`);
56
+ console.log(` - Search for packages: prpm search <query>`);
57
+ console.log(` - View trending: prpm trending`);
58
+ process.exit(1);
59
+ }
60
+ finally {
61
+ await telemetry_1.telemetry.track({
62
+ command: 'info',
63
+ success,
64
+ error,
65
+ duration: Date.now() - startTime,
66
+ data: {
67
+ packageId,
68
+ },
69
+ });
70
+ }
71
+ }
72
+ function createInfoCommand() {
73
+ const command = new commander_1.Command('info');
74
+ command
75
+ .description('Display detailed package information')
76
+ .argument('<package>', 'Package ID to get information about')
77
+ .action(async (packageId) => {
78
+ await handleInfo(packageId);
79
+ });
80
+ return command;
81
+ }
@@ -0,0 +1,252 @@
1
+ "use strict";
2
+ /**
3
+ * Install command - Install packages from registry
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.handleInstall = handleInstall;
40
+ exports.createInstallCommand = createInstallCommand;
41
+ const commander_1 = require("commander");
42
+ const registry_client_1 = require("@prpm/registry-client");
43
+ const user_config_1 = require("../core/user-config");
44
+ const filesystem_1 = require("../core/filesystem");
45
+ const config_1 = require("../core/config");
46
+ const telemetry_1 = require("../core/telemetry");
47
+ const lockfile_1 = require("../core/lockfile");
48
+ /**
49
+ * Get icon for package type
50
+ */
51
+ function getTypeIcon(type) {
52
+ const icons = {
53
+ skill: 'šŸŽ“',
54
+ agent: 'šŸ¤–',
55
+ rule: 'šŸ“‹',
56
+ plugin: 'šŸ”Œ',
57
+ prompt: 'šŸ’¬',
58
+ workflow: '⚔',
59
+ tool: 'šŸ”§',
60
+ template: 'šŸ“„',
61
+ mcp: 'šŸ”—',
62
+ };
63
+ return icons[type] || 'šŸ“¦';
64
+ }
65
+ /**
66
+ * Get human-readable label for package type
67
+ */
68
+ function getTypeLabel(type) {
69
+ const labels = {
70
+ skill: 'Skill',
71
+ agent: 'Agent',
72
+ rule: 'Rule',
73
+ plugin: 'Plugin',
74
+ prompt: 'Prompt',
75
+ workflow: 'Workflow',
76
+ tool: 'Tool',
77
+ template: 'Template',
78
+ mcp: 'MCP Server',
79
+ };
80
+ return labels[type] || type;
81
+ }
82
+ async function handleInstall(packageSpec, options) {
83
+ const startTime = Date.now();
84
+ let success = false;
85
+ let error;
86
+ try {
87
+ // Parse package spec (e.g., "react-rules" or "react-rules@1.2.0")
88
+ const [packageId, specVersion] = packageSpec.split('@');
89
+ // Read existing lock file
90
+ const lockfile = await (0, lockfile_1.readLockfile)();
91
+ const lockedVersion = (0, lockfile_1.getLockedVersion)(lockfile, packageId);
92
+ // Determine version to install
93
+ let version;
94
+ if (options.frozenLockfile) {
95
+ // Frozen lockfile mode - must use exact locked version
96
+ if (!lockedVersion) {
97
+ throw new Error(`Package ${packageId} not found in lock file. Run without --frozen-lockfile to update.`);
98
+ }
99
+ version = lockedVersion;
100
+ }
101
+ else {
102
+ // Normal mode - use specified version or locked version or latest
103
+ version = options.version || specVersion || lockedVersion || 'latest';
104
+ }
105
+ console.log(`šŸ“„ Installing ${packageId}@${version}...`);
106
+ const config = await (0, user_config_1.getConfig)();
107
+ const client = (0, registry_client_1.getRegistryClient)(config);
108
+ // Determine format preference
109
+ const format = options.as || config.defaultFormat || detectProjectFormat() || 'cursor';
110
+ if (format !== 'canonical') {
111
+ console.log(` šŸ”„ Converting to ${format} format...`);
112
+ }
113
+ // Get package info
114
+ const pkg = await client.getPackage(packageId);
115
+ const typeIcon = getTypeIcon(pkg.type);
116
+ const typeLabel = getTypeLabel(pkg.type);
117
+ console.log(` ${pkg.display_name} ${pkg.official ? 'šŸ…' : ''}`);
118
+ console.log(` ${pkg.description || 'No description'}`);
119
+ console.log(` ${typeIcon} Type: ${typeLabel}`);
120
+ // Determine version to install
121
+ let tarballUrl;
122
+ if (version === 'latest') {
123
+ if (!pkg.latest_version) {
124
+ throw new Error('No versions available for this package');
125
+ }
126
+ tarballUrl = pkg.latest_version.tarball_url;
127
+ console.log(` šŸ“¦ Installing version ${pkg.latest_version.version}`);
128
+ }
129
+ else {
130
+ const versionInfo = await client.getPackageVersion(packageId, version);
131
+ tarballUrl = versionInfo.tarball_url;
132
+ console.log(` šŸ“¦ Installing version ${version}`);
133
+ }
134
+ // Download package in requested format
135
+ console.log(` ā¬‡ļø Downloading...`);
136
+ const tarball = await client.downloadPackage(tarballUrl, { format });
137
+ // Extract tarball and save files
138
+ console.log(` šŸ“‚ Extracting...`);
139
+ const type = options.type || pkg.type;
140
+ const destDir = (0, filesystem_1.getDestinationDir)(type);
141
+ // For MVP, assume single file in tarball
142
+ // TODO: Implement proper tar extraction
143
+ const mainFile = await extractMainFile(tarball, packageId);
144
+ const destPath = `${destDir}/${packageId}.md`;
145
+ await (0, filesystem_1.saveFile)(destPath, mainFile);
146
+ // Update or create lock file
147
+ const updatedLockfile = lockfile || (0, lockfile_1.createLockfile)();
148
+ const actualVersion = version === 'latest' ? pkg.latest_version?.version : version;
149
+ (0, lockfile_1.addToLockfile)(updatedLockfile, packageId, {
150
+ version: actualVersion || version,
151
+ tarballUrl,
152
+ type,
153
+ format,
154
+ });
155
+ (0, lockfile_1.setPackageIntegrity)(updatedLockfile, packageId, tarball);
156
+ await (0, lockfile_1.writeLockfile)(updatedLockfile);
157
+ // Update configuration
158
+ const packageRecord = {
159
+ id: packageId,
160
+ type,
161
+ url: tarballUrl,
162
+ dest: destPath,
163
+ version: actualVersion,
164
+ };
165
+ await (0, config_1.addPackage)(packageRecord);
166
+ console.log(`\nāœ… Successfully installed ${packageId}`);
167
+ console.log(` šŸ“ Saved to: ${destPath}`);
168
+ console.log(` šŸ”’ Lock file updated`);
169
+ console.log(`\nšŸ’” This package has been downloaded ${pkg.total_downloads.toLocaleString()} times`);
170
+ success = true;
171
+ }
172
+ catch (err) {
173
+ error = err instanceof Error ? err.message : String(err);
174
+ console.error(`\nāŒ Installation failed: ${error}`);
175
+ console.log(`\nšŸ’” Tips:`);
176
+ console.log(` - Check package name: prpm search <query>`);
177
+ console.log(` - Get package info: prpm info <package>`);
178
+ console.log(` - Install from URL: prpm add <url> --as <type>`);
179
+ process.exit(1);
180
+ }
181
+ finally {
182
+ await telemetry_1.telemetry.track({
183
+ command: 'install',
184
+ success,
185
+ error,
186
+ duration: Date.now() - startTime,
187
+ data: {
188
+ packageId: packageSpec.split('@')[0],
189
+ version: options.version || 'latest',
190
+ type: options.type,
191
+ },
192
+ });
193
+ }
194
+ }
195
+ /**
196
+ * Extract main file from tarball
197
+ * TODO: Implement proper tar extraction with tar library
198
+ */
199
+ async function extractMainFile(tarball, packageId) {
200
+ // Placeholder implementation
201
+ // In reality, we need to:
202
+ // 1. Extract tar.gz
203
+ // 2. Find main file (from manifest or naming convention)
204
+ // 3. Return file contents
205
+ // For now, assume tarball is just gzipped content
206
+ const zlib = await Promise.resolve().then(() => __importStar(require('zlib')));
207
+ return new Promise((resolve, reject) => {
208
+ zlib.gunzip(tarball, (err, result) => {
209
+ if (err)
210
+ reject(err);
211
+ else
212
+ resolve(result.toString('utf-8'));
213
+ });
214
+ });
215
+ }
216
+ /**
217
+ * Detect project format from existing directories
218
+ */
219
+ function detectProjectFormat() {
220
+ const fs = require('fs');
221
+ if (fs.existsSync('.cursor/rules') || fs.existsSync('.cursor'))
222
+ return 'cursor';
223
+ if (fs.existsSync('.claude/agents') || fs.existsSync('.claude'))
224
+ return 'claude';
225
+ if (fs.existsSync('.continue'))
226
+ return 'continue';
227
+ if (fs.existsSync('.windsurf'))
228
+ return 'windsurf';
229
+ return null;
230
+ }
231
+ function createInstallCommand() {
232
+ const command = new commander_1.Command('install');
233
+ command
234
+ .description('Install a package from the registry')
235
+ .argument('<package>', 'Package to install (e.g., react-rules or react-rules@1.2.0)')
236
+ .option('--version <version>', 'Specific version to install')
237
+ .option('--type <type>', 'Override package type (cursor, claude, continue)')
238
+ .option('--as <format>', 'Download in specific format (cursor, claude, continue, windsurf)')
239
+ .option('--frozen-lockfile', 'Fail if lock file needs to be updated (for CI)')
240
+ .action(async (packageSpec, options) => {
241
+ if (options.type && !['cursor', 'claude', 'continue', 'windsurf', 'generic'].includes(options.type)) {
242
+ console.error('āŒ Type must be one of: cursor, claude, continue, windsurf, generic');
243
+ process.exit(1);
244
+ }
245
+ if (options.as && !['cursor', 'claude', 'continue', 'windsurf', 'canonical'].includes(options.as)) {
246
+ console.error('āŒ Format must be one of: cursor, claude, continue, windsurf, canonical');
247
+ process.exit(1);
248
+ }
249
+ await handleInstall(packageSpec, options);
250
+ });
251
+ return command;
252
+ }
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ /**
3
+ * List command implementation
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.handleList = handleList;
7
+ exports.createListCommand = createListCommand;
8
+ const commander_1 = require("commander");
9
+ const config_1 = require("../core/config");
10
+ const telemetry_1 = require("../core/telemetry");
11
+ /**
12
+ * Display packages in a formatted table
13
+ */
14
+ function displayPackages(packages) {
15
+ if (packages.length === 0) {
16
+ console.log('šŸ“¦ No packages installed');
17
+ return;
18
+ }
19
+ console.log('šŸ“¦ Installed packages:');
20
+ console.log('');
21
+ // Calculate column widths
22
+ const idWidth = Math.max(8, ...packages.map(p => p.id.length));
23
+ const typeWidth = Math.max(6, ...packages.map(p => p.type.length));
24
+ const urlWidth = Math.max(20, ...packages.map(p => p.url.length));
25
+ const destWidth = Math.max(15, ...packages.map(p => p.dest.length));
26
+ // Header
27
+ const header = [
28
+ 'ID'.padEnd(idWidth),
29
+ 'TYPE'.padEnd(typeWidth),
30
+ 'URL'.padEnd(urlWidth),
31
+ 'DESTINATION'.padEnd(destWidth)
32
+ ].join(' | ');
33
+ console.log(header);
34
+ console.log('-'.repeat(header.length));
35
+ // Rows
36
+ packages.forEach(pkg => {
37
+ const row = [
38
+ pkg.id.padEnd(idWidth),
39
+ pkg.type.padEnd(typeWidth),
40
+ pkg.url.padEnd(urlWidth),
41
+ pkg.dest.padEnd(destWidth)
42
+ ].join(' | ');
43
+ console.log(row);
44
+ });
45
+ console.log('');
46
+ console.log(`Total: ${packages.length} package${packages.length === 1 ? '' : 's'}`);
47
+ }
48
+ /**
49
+ * Handle the list command
50
+ */
51
+ async function handleList() {
52
+ const startTime = Date.now();
53
+ let success = false;
54
+ let error;
55
+ let packageCount = 0;
56
+ try {
57
+ const packages = await (0, config_1.listPackages)();
58
+ packageCount = packages.length;
59
+ displayPackages(packages);
60
+ success = true;
61
+ }
62
+ catch (err) {
63
+ error = err instanceof Error ? err.message : String(err);
64
+ console.error(`āŒ Failed to list packages: ${error}`);
65
+ process.exit(1);
66
+ }
67
+ finally {
68
+ // Track telemetry
69
+ await telemetry_1.telemetry.track({
70
+ command: 'list',
71
+ success,
72
+ error,
73
+ duration: Date.now() - startTime,
74
+ data: {
75
+ packageCount,
76
+ },
77
+ });
78
+ }
79
+ }
80
+ /**
81
+ * Create the list command
82
+ */
83
+ function createListCommand() {
84
+ const command = new commander_1.Command('list');
85
+ command
86
+ .description('List all installed prompt packages')
87
+ .action(handleList);
88
+ return command;
89
+ }