prpm 0.2.0 → 1.0.0
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/dist/index.js +14257 -109
- package/package.json +11 -9
- package/dist/__tests__/e2e/test-helpers.js +0 -153
- package/dist/commands/buy-credits.js +0 -224
- package/dist/commands/catalog.js +0 -365
- package/dist/commands/collections.js +0 -655
- package/dist/commands/config.js +0 -161
- package/dist/commands/credits.js +0 -186
- package/dist/commands/index.js +0 -184
- package/dist/commands/info.js +0 -78
- package/dist/commands/init.js +0 -684
- package/dist/commands/install.js +0 -829
- package/dist/commands/list.js +0 -198
- package/dist/commands/login.js +0 -316
- package/dist/commands/outdated.js +0 -130
- package/dist/commands/playground.js +0 -637
- package/dist/commands/popular.js +0 -33
- package/dist/commands/publish.js +0 -803
- package/dist/commands/schema.js +0 -41
- package/dist/commands/search.js +0 -446
- package/dist/commands/starred.js +0 -147
- package/dist/commands/subscribe.js +0 -211
- package/dist/commands/telemetry.js +0 -104
- package/dist/commands/trending.js +0 -86
- package/dist/commands/uninstall.js +0 -120
- package/dist/commands/update.js +0 -121
- package/dist/commands/upgrade.js +0 -121
- package/dist/commands/whoami.js +0 -83
- package/dist/core/claude-config.js +0 -91
- package/dist/core/cursor-config.js +0 -130
- package/dist/core/downloader.js +0 -64
- package/dist/core/errors.js +0 -29
- package/dist/core/filesystem.js +0 -246
- package/dist/core/lockfile.js +0 -292
- package/dist/core/marketplace-converter.js +0 -224
- package/dist/core/prompts.js +0 -62
- package/dist/core/registry-client.js +0 -305
- package/dist/core/schema-validator.js +0 -74
- package/dist/core/telemetry.js +0 -253
- package/dist/core/user-config.js +0 -147
- package/dist/types/registry.js +0 -12
- package/dist/types.js +0 -9
- package/dist/utils/license-extractor.js +0 -122
- package/dist/utils/multi-package.js +0 -117
- package/dist/utils/parallel-publisher.js +0 -144
- package/dist/utils/script-executor.js +0 -72
- package/dist/utils/snippet-extractor.js +0 -77
- package/dist/utils/webapp-url.js +0 -44
package/dist/commands/config.js
DELETED
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Config command implementation
|
|
4
|
-
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.createConfigCommand = createConfigCommand;
|
|
7
|
-
const commander_1 = require("commander");
|
|
8
|
-
const user_config_1 = require("../core/user-config");
|
|
9
|
-
const errors_1 = require("../core/errors");
|
|
10
|
-
/**
|
|
11
|
-
* Get a config value
|
|
12
|
-
*/
|
|
13
|
-
async function handleConfigGet(key) {
|
|
14
|
-
try {
|
|
15
|
-
const config = await (0, user_config_1.getConfig)();
|
|
16
|
-
const value = config[key];
|
|
17
|
-
if (value === undefined) {
|
|
18
|
-
throw new errors_1.CLIError(`❌ Config key "${key}" not found\n\nAvailable keys: registryUrl, telemetryEnabled, token, username`, 1);
|
|
19
|
-
}
|
|
20
|
-
console.log(value);
|
|
21
|
-
}
|
|
22
|
-
catch (error) {
|
|
23
|
-
if (error instanceof errors_1.CLIError) {
|
|
24
|
-
throw error;
|
|
25
|
-
}
|
|
26
|
-
throw new errors_1.CLIError(`❌ Failed to get config: ${error instanceof Error ? error.message : String(error)}`, 1);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Set a config value
|
|
31
|
-
*/
|
|
32
|
-
async function handleConfigSet(key, value) {
|
|
33
|
-
try {
|
|
34
|
-
const config = await (0, user_config_1.getConfig)();
|
|
35
|
-
// Validate key
|
|
36
|
-
const validKeys = ['registryUrl', 'telemetryEnabled'];
|
|
37
|
-
if (!validKeys.includes(key)) {
|
|
38
|
-
throw new errors_1.CLIError(`❌ Cannot set config key "${key}"\n\nSettable keys: registryUrl, telemetryEnabled\nNote: token and username are set via "prpm login"`, 1);
|
|
39
|
-
}
|
|
40
|
-
// Parse boolean values
|
|
41
|
-
let parsedValue = value;
|
|
42
|
-
if (key === 'telemetryEnabled') {
|
|
43
|
-
if (value === 'true' || value === '1' || value === 'yes') {
|
|
44
|
-
parsedValue = true;
|
|
45
|
-
}
|
|
46
|
-
else if (value === 'false' || value === '0' || value === 'no') {
|
|
47
|
-
parsedValue = false;
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
throw new errors_1.CLIError(`❌ Invalid boolean value "${value}". Use: true, false, yes, no, 1, or 0`, 1);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
// Update config
|
|
54
|
-
config[key] = parsedValue;
|
|
55
|
-
await (0, user_config_1.saveConfig)(config);
|
|
56
|
-
console.log(`✅ Set ${key} = ${parsedValue}`);
|
|
57
|
-
}
|
|
58
|
-
catch (error) {
|
|
59
|
-
if (error instanceof errors_1.CLIError) {
|
|
60
|
-
throw error;
|
|
61
|
-
}
|
|
62
|
-
throw new errors_1.CLIError(`❌ Failed to set config: ${error instanceof Error ? error.message : String(error)}`, 1);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* List all config values
|
|
67
|
-
*/
|
|
68
|
-
async function handleConfigList() {
|
|
69
|
-
try {
|
|
70
|
-
const config = await (0, user_config_1.getConfig)();
|
|
71
|
-
console.log('📋 Current configuration:\n');
|
|
72
|
-
console.log(` Registry URL: ${config.registryUrl}`);
|
|
73
|
-
console.log(` Telemetry: ${config.telemetryEnabled ? 'enabled' : 'disabled'}`);
|
|
74
|
-
console.log(` Username: ${config.username || '(not logged in)'}`);
|
|
75
|
-
console.log(` Token: ${config.token ? '(set)' : '(not set)'}`);
|
|
76
|
-
console.log('');
|
|
77
|
-
const configPath = process.platform === 'win32'
|
|
78
|
-
? `${process.env.USERPROFILE}\\.prpmrc`
|
|
79
|
-
: `${process.env.HOME}/.prpmrc`;
|
|
80
|
-
console.log(`Config file: ${configPath}`);
|
|
81
|
-
}
|
|
82
|
-
catch (error) {
|
|
83
|
-
throw new errors_1.CLIError(`❌ Failed to list config: ${error instanceof Error ? error.message : String(error)}`, 1);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Delete a config value (reset to default)
|
|
88
|
-
*/
|
|
89
|
-
async function handleConfigDelete(key) {
|
|
90
|
-
try {
|
|
91
|
-
const config = await (0, user_config_1.getConfig)();
|
|
92
|
-
// Validate key
|
|
93
|
-
const deletableKeys = ['registryUrl', 'telemetryEnabled', 'token', 'username'];
|
|
94
|
-
if (!deletableKeys.includes(key)) {
|
|
95
|
-
throw new errors_1.CLIError(`❌ Cannot delete config key "${key}"`, 1);
|
|
96
|
-
}
|
|
97
|
-
// Reset to defaults
|
|
98
|
-
if (key === 'registryUrl') {
|
|
99
|
-
config.registryUrl = 'https://registry.prpm.dev';
|
|
100
|
-
}
|
|
101
|
-
else if (key === 'telemetryEnabled') {
|
|
102
|
-
config.telemetryEnabled = true;
|
|
103
|
-
}
|
|
104
|
-
else if (key === 'token') {
|
|
105
|
-
config.token = undefined;
|
|
106
|
-
}
|
|
107
|
-
else if (key === 'username') {
|
|
108
|
-
config.username = undefined;
|
|
109
|
-
}
|
|
110
|
-
await (0, user_config_1.saveConfig)(config);
|
|
111
|
-
console.log(`✅ Reset ${key} to default value`);
|
|
112
|
-
}
|
|
113
|
-
catch (error) {
|
|
114
|
-
if (error instanceof errors_1.CLIError) {
|
|
115
|
-
throw error;
|
|
116
|
-
}
|
|
117
|
-
throw new errors_1.CLIError(`❌ Failed to delete config: ${error instanceof Error ? error.message : String(error)}`, 1);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Create the config command
|
|
122
|
-
*/
|
|
123
|
-
function createConfigCommand() {
|
|
124
|
-
const command = new commander_1.Command('config')
|
|
125
|
-
.description('Manage CLI configuration');
|
|
126
|
-
// config list
|
|
127
|
-
command
|
|
128
|
-
.command('list')
|
|
129
|
-
.alias('ls')
|
|
130
|
-
.description('List all configuration values')
|
|
131
|
-
.action(async () => {
|
|
132
|
-
await handleConfigList();
|
|
133
|
-
});
|
|
134
|
-
// config get <key>
|
|
135
|
-
command
|
|
136
|
-
.command('get <key>')
|
|
137
|
-
.description('Get a configuration value')
|
|
138
|
-
.action(async (key) => {
|
|
139
|
-
await handleConfigGet(key);
|
|
140
|
-
});
|
|
141
|
-
// config set <key> <value>
|
|
142
|
-
command
|
|
143
|
-
.command('set <key> <value>')
|
|
144
|
-
.description('Set a configuration value')
|
|
145
|
-
.action(async (key, value) => {
|
|
146
|
-
await handleConfigSet(key, value);
|
|
147
|
-
});
|
|
148
|
-
// config delete <key>
|
|
149
|
-
command
|
|
150
|
-
.command('delete <key>')
|
|
151
|
-
.alias('rm')
|
|
152
|
-
.description('Reset a configuration value to default')
|
|
153
|
-
.action(async (key) => {
|
|
154
|
-
await handleConfigDelete(key);
|
|
155
|
-
});
|
|
156
|
-
// Default action (show list if no subcommand)
|
|
157
|
-
command.action(async () => {
|
|
158
|
-
await handleConfigList();
|
|
159
|
-
});
|
|
160
|
-
return command;
|
|
161
|
-
}
|
package/dist/commands/credits.js
DELETED
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Credits command - Check and manage playground credits
|
|
4
|
-
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.handleCredits = handleCredits;
|
|
7
|
-
exports.createCreditsCommand = createCreditsCommand;
|
|
8
|
-
const commander_1 = require("commander");
|
|
9
|
-
const user_config_1 = require("../core/user-config");
|
|
10
|
-
const telemetry_1 = require("../core/telemetry");
|
|
11
|
-
const errors_1 = require("../core/errors");
|
|
12
|
-
/**
|
|
13
|
-
* Make authenticated API call
|
|
14
|
-
*/
|
|
15
|
-
async function apiCall(endpoint) {
|
|
16
|
-
const config = await (0, user_config_1.getConfig)();
|
|
17
|
-
const baseUrl = (config.registryUrl || "https://registry.prpm.dev").replace(/\/$/, '');
|
|
18
|
-
if (!config.token) {
|
|
19
|
-
throw new Error('Authentication required. Please run `prpm login` first.');
|
|
20
|
-
}
|
|
21
|
-
const response = await fetch(`${baseUrl}${endpoint}`, {
|
|
22
|
-
headers: {
|
|
23
|
-
Authorization: `Bearer ${config.token}`,
|
|
24
|
-
},
|
|
25
|
-
});
|
|
26
|
-
if (!response.ok) {
|
|
27
|
-
const errorData = await response.json().catch(() => ({}));
|
|
28
|
-
throw new Error(errorData.message || `API request failed: ${response.statusText}`);
|
|
29
|
-
}
|
|
30
|
-
return response;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Display credits balance
|
|
34
|
-
*/
|
|
35
|
-
async function showBalance() {
|
|
36
|
-
console.log('💳 Fetching playground credits balance...\n');
|
|
37
|
-
const response = await apiCall('/api/v1/playground/credits');
|
|
38
|
-
const balance = await response.json();
|
|
39
|
-
console.log('═'.repeat(5));
|
|
40
|
-
console.log(' PLAYGROUND CREDITS BALANCE');
|
|
41
|
-
console.log('═'.repeat(5));
|
|
42
|
-
// Total balance
|
|
43
|
-
console.log(`\n💰 Total Balance: ${balance.balance} credits`);
|
|
44
|
-
// Breakdown
|
|
45
|
-
console.log('\n📊 Breakdown:');
|
|
46
|
-
if (balance.monthly_credits > 0) {
|
|
47
|
-
const monthlyRemaining = balance.monthly_credits - balance.monthly_credits_used;
|
|
48
|
-
console.log(` Monthly (PRPM+): ${monthlyRemaining}/${balance.monthly_credits} credits`);
|
|
49
|
-
if (balance.monthly_reset_at) {
|
|
50
|
-
const resetDate = new Date(balance.monthly_reset_at).toLocaleDateString();
|
|
51
|
-
console.log(` (Resets: ${resetDate})`);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
if (balance.rollover_credits > 0) {
|
|
55
|
-
console.log(` Rollover: ${balance.rollover_credits} credits`);
|
|
56
|
-
if (balance.rollover_expires_at) {
|
|
57
|
-
const expiresDate = new Date(balance.rollover_expires_at).toLocaleDateString();
|
|
58
|
-
console.log(` (Expires: ${expiresDate})`);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
if (balance.purchased_credits > 0) {
|
|
62
|
-
console.log(` Purchased: ${balance.purchased_credits} credits`);
|
|
63
|
-
console.log(` (Never expire)`);
|
|
64
|
-
}
|
|
65
|
-
// PRPM+ Status
|
|
66
|
-
if (balance.prpm_plus_status === 'active') {
|
|
67
|
-
console.log('\n✨ PRPM+ Active - You get 100 monthly credits!');
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
console.log('\n💡 Upgrade to PRPM+ for 100 monthly credits');
|
|
71
|
-
console.log(' Visit: https://prpm.dev/pricing');
|
|
72
|
-
}
|
|
73
|
-
console.log('\n═'.repeat(5));
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Display recent credit transactions
|
|
77
|
-
*/
|
|
78
|
-
async function showHistory(limit = 10) {
|
|
79
|
-
console.log(`💳 Fetching recent credit transactions...\n`);
|
|
80
|
-
const response = await apiCall(`/api/v1/playground/credits/history?limit=${limit}`);
|
|
81
|
-
const data = await response.json();
|
|
82
|
-
if (data.transactions.length === 0) {
|
|
83
|
-
console.log('No transaction history yet.');
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
console.log('═'.repeat(5));
|
|
87
|
-
console.log(' CREDIT TRANSACTION HISTORY');
|
|
88
|
-
console.log('═'.repeat(5));
|
|
89
|
-
console.log();
|
|
90
|
-
for (const tx of data.transactions) {
|
|
91
|
-
const date = new Date(tx.created_at).toLocaleString();
|
|
92
|
-
const amount = tx.amount >= 0 ? `+${tx.amount}` : `${tx.amount}`;
|
|
93
|
-
const emoji = tx.amount >= 0 ? '💰' : '💸';
|
|
94
|
-
console.log(`${emoji} ${date}`);
|
|
95
|
-
console.log(` Type: ${tx.transaction_type}`);
|
|
96
|
-
console.log(` Amount: ${amount} credits`);
|
|
97
|
-
console.log(` Balance: ${tx.balance_after} credits`);
|
|
98
|
-
console.log(` Details: ${tx.description}`);
|
|
99
|
-
console.log();
|
|
100
|
-
}
|
|
101
|
-
console.log('═'.repeat(5));
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Handle the credits command
|
|
105
|
-
*/
|
|
106
|
-
async function handleCredits(options) {
|
|
107
|
-
const startTime = Date.now();
|
|
108
|
-
let success = false;
|
|
109
|
-
let error;
|
|
110
|
-
try {
|
|
111
|
-
const config = await (0, user_config_1.getConfig)();
|
|
112
|
-
if (!config.token) {
|
|
113
|
-
console.error('❌ Authentication required');
|
|
114
|
-
console.log('\n💡 Please login first:');
|
|
115
|
-
console.log(' prpm login');
|
|
116
|
-
throw new errors_1.CLIError('❌ Authentication required', 1);
|
|
117
|
-
}
|
|
118
|
-
if (options.history) {
|
|
119
|
-
await showHistory(options.limit || 10);
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
await showBalance();
|
|
123
|
-
}
|
|
124
|
-
console.log('\n💡 Tips:');
|
|
125
|
-
console.log(' - Test packages: prpm playground <package> "<input>"');
|
|
126
|
-
console.log(' - View history: prpm credits --history');
|
|
127
|
-
console.log(' - Purchase credits: prpm buy-credits');
|
|
128
|
-
console.log(' - Subscribe to PRPM+: prpm subscribe');
|
|
129
|
-
success = true;
|
|
130
|
-
}
|
|
131
|
-
catch (err) {
|
|
132
|
-
error = err instanceof Error ? err.message : String(err);
|
|
133
|
-
console.error(`\n❌ Failed to fetch credits: ${error}`);
|
|
134
|
-
throw new errors_1.CLIError(`\n❌ Failed to fetch credits: ${error}`, 1);
|
|
135
|
-
}
|
|
136
|
-
finally {
|
|
137
|
-
await telemetry_1.telemetry.track({
|
|
138
|
-
command: 'credits',
|
|
139
|
-
success,
|
|
140
|
-
error,
|
|
141
|
-
duration: Date.now() - startTime,
|
|
142
|
-
data: {
|
|
143
|
-
showHistory: options.history || false,
|
|
144
|
-
},
|
|
145
|
-
});
|
|
146
|
-
await telemetry_1.telemetry.shutdown();
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Create the credits command
|
|
151
|
-
*/
|
|
152
|
-
function createCreditsCommand() {
|
|
153
|
-
const command = new commander_1.Command('credits');
|
|
154
|
-
command
|
|
155
|
-
.description('Check playground credits balance and transaction history')
|
|
156
|
-
.option('-h, --history', 'Show transaction history instead of balance', false)
|
|
157
|
-
.option('-l, --limit <number>', 'Number of transactions to show in history', '10')
|
|
158
|
-
.addHelpText('after', `
|
|
159
|
-
Examples:
|
|
160
|
-
# Check current balance
|
|
161
|
-
$ prpm credits
|
|
162
|
-
|
|
163
|
-
# View transaction history
|
|
164
|
-
$ prpm credits --history
|
|
165
|
-
|
|
166
|
-
# View last 20 transactions
|
|
167
|
-
$ prpm credits --history --limit 20
|
|
168
|
-
|
|
169
|
-
Credits are used for:
|
|
170
|
-
- Testing packages in the playground
|
|
171
|
-
- Running prompts with AI models
|
|
172
|
-
- Comparing packages against baselines
|
|
173
|
-
|
|
174
|
-
Get more credits:
|
|
175
|
-
- PRPM+ subscribers get 100 monthly credits
|
|
176
|
-
- Purchase additional credits at https://prpm.dev/playground/credits/buy
|
|
177
|
-
- Free tier gets 5 trial credits
|
|
178
|
-
`)
|
|
179
|
-
.action(async (options) => {
|
|
180
|
-
await handleCredits({
|
|
181
|
-
history: options.history,
|
|
182
|
-
limit: options.limit ? parseInt(options.limit, 10) : undefined,
|
|
183
|
-
});
|
|
184
|
-
});
|
|
185
|
-
return command;
|
|
186
|
-
}
|
package/dist/commands/index.js
DELETED
|
@@ -1,184 +0,0 @@
|
|
|
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 lockfile_1 = require("../core/lockfile");
|
|
15
|
-
const filesystem_1 = require("../core/filesystem");
|
|
16
|
-
const errors_1 = require("../core/errors");
|
|
17
|
-
/**
|
|
18
|
-
* Scan directory for files and return file information
|
|
19
|
-
* Recursively scans subdirectories for Claude skills/agents
|
|
20
|
-
*/
|
|
21
|
-
async function scanDirectory(dirPath, format, subtype) {
|
|
22
|
-
try {
|
|
23
|
-
const files = await fs_1.promises.readdir(dirPath, { withFileTypes: true });
|
|
24
|
-
const results = [];
|
|
25
|
-
for (const file of files) {
|
|
26
|
-
const fullPath = path_1.default.join(dirPath, file.name);
|
|
27
|
-
if (file.isFile()) {
|
|
28
|
-
// Direct file in the directory
|
|
29
|
-
const id = (0, filesystem_1.generateId)(file.name);
|
|
30
|
-
results.push({
|
|
31
|
-
filePath: fullPath,
|
|
32
|
-
filename: file.name,
|
|
33
|
-
id
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
else if (file.isDirectory()) {
|
|
37
|
-
// For Claude/Cursor skills/agents, scan subdirectories for structured packages
|
|
38
|
-
const isClaudeType = format === 'claude';
|
|
39
|
-
const isCursorAgent = format === 'cursor' && subtype === 'agent';
|
|
40
|
-
if (isClaudeType || isCursorAgent) {
|
|
41
|
-
try {
|
|
42
|
-
const subFiles = await fs_1.promises.readdir(fullPath, { withFileTypes: true });
|
|
43
|
-
for (const subFile of subFiles) {
|
|
44
|
-
const isValidFile = subFile.isFile() && (subFile.name === 'SKILL.md' ||
|
|
45
|
-
subFile.name === 'AGENT.md' ||
|
|
46
|
-
subFile.name === 'skill.md' ||
|
|
47
|
-
subFile.name === 'agent.md');
|
|
48
|
-
if (isValidFile) {
|
|
49
|
-
const subFilePath = path_1.default.join(fullPath, subFile.name);
|
|
50
|
-
const id = file.name; // Use directory name as package ID
|
|
51
|
-
results.push({
|
|
52
|
-
filePath: subFilePath,
|
|
53
|
-
filename: `${file.name}/${subFile.name}`,
|
|
54
|
-
id
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
catch {
|
|
60
|
-
// Subdirectory can't be read, skip it
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return results;
|
|
66
|
-
}
|
|
67
|
-
catch (error) {
|
|
68
|
-
// Directory doesn't exist or can't be read
|
|
69
|
-
return [];
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Check if a package is already registered
|
|
74
|
-
*/
|
|
75
|
-
function isPackageRegistered(packages, id) {
|
|
76
|
-
return packages.some(pkg => pkg.id === id);
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Handle the index command
|
|
80
|
-
*/
|
|
81
|
-
async function handleIndex(options = {}) {
|
|
82
|
-
try {
|
|
83
|
-
console.log('🔍 Scanning AI editor directories for prompt files...\n');
|
|
84
|
-
// Get currently registered packages
|
|
85
|
-
const existingPackages = await (0, lockfile_1.listPackages)();
|
|
86
|
-
if (options.verbose) {
|
|
87
|
-
console.log(`📋 Currently registered: ${existingPackages.length} packages\n`);
|
|
88
|
-
}
|
|
89
|
-
let totalFound = 0;
|
|
90
|
-
let totalAdded = 0;
|
|
91
|
-
const summary = [];
|
|
92
|
-
// Define directories to scan with their format and subtype
|
|
93
|
-
const dirsToScan = [
|
|
94
|
-
{ path: '.cursor/rules', format: 'cursor', subtype: 'rule', label: 'Cursor Rules' },
|
|
95
|
-
{ path: '.cursor/agents', format: 'cursor', subtype: 'agent', label: 'Cursor Agents' },
|
|
96
|
-
{ path: '.cursor/commands', format: 'cursor', subtype: 'slash-command', label: 'Cursor Slash Commands' },
|
|
97
|
-
{ path: '.claude/agents', format: 'claude', subtype: 'agent', label: 'Claude Agents' },
|
|
98
|
-
{ path: '.claude/skills', format: 'claude', subtype: 'skill', label: 'Claude Skills' },
|
|
99
|
-
{ path: '.claude/commands', format: 'claude', subtype: 'slash-command', label: 'Claude Slash Commands' },
|
|
100
|
-
{ path: '.continue/rules', format: 'continue', subtype: 'rule', label: 'Continue Rules' },
|
|
101
|
-
{ path: '.windsurf/rules', format: 'windsurf', subtype: 'rule', label: 'Windsurf Rules' },
|
|
102
|
-
{ path: '.prompts', format: 'generic', subtype: 'prompt', label: 'Generic Prompts' },
|
|
103
|
-
{ path: '.mcp', format: 'mcp', subtype: 'tool', label: 'MCP Servers' },
|
|
104
|
-
];
|
|
105
|
-
// Scan each directory
|
|
106
|
-
for (const dir of dirsToScan) {
|
|
107
|
-
const files = await scanDirectory(dir.path, dir.format, dir.subtype);
|
|
108
|
-
if (files.length === 0) {
|
|
109
|
-
if (options.verbose) {
|
|
110
|
-
console.log(`📁 ${dir.path}/ - No files found`);
|
|
111
|
-
}
|
|
112
|
-
continue;
|
|
113
|
-
}
|
|
114
|
-
console.log(`📁 ${dir.path}/ (${dir.label}) - Found ${files.length} file(s)`);
|
|
115
|
-
let dirAdded = 0;
|
|
116
|
-
totalFound += files.length;
|
|
117
|
-
for (const file of files) {
|
|
118
|
-
if (!isPackageRegistered(existingPackages, file.id)) {
|
|
119
|
-
await (0, lockfile_1.addPackage)({
|
|
120
|
-
id: file.id,
|
|
121
|
-
version: '0.0.0', // Local files don't have versions
|
|
122
|
-
tarballUrl: `file://${path_1.default.resolve(file.filePath)}`,
|
|
123
|
-
format: dir.format,
|
|
124
|
-
subtype: dir.subtype,
|
|
125
|
-
});
|
|
126
|
-
if (options.verbose) {
|
|
127
|
-
console.log(` ✅ Added: ${file.filename} (${file.id})`);
|
|
128
|
-
}
|
|
129
|
-
totalAdded++;
|
|
130
|
-
dirAdded++;
|
|
131
|
-
}
|
|
132
|
-
else if (options.verbose) {
|
|
133
|
-
console.log(` ⏭️ Skipped: ${file.filename} (already registered)`);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
if (dirAdded > 0) {
|
|
137
|
-
console.log(` ➕ Added ${dirAdded} new package(s)\n`);
|
|
138
|
-
}
|
|
139
|
-
else if (!options.verbose) {
|
|
140
|
-
console.log(` ✓ All files already registered\n`);
|
|
141
|
-
}
|
|
142
|
-
summary.push({ dir: dir.path, found: files.length, added: dirAdded });
|
|
143
|
-
}
|
|
144
|
-
// Summary
|
|
145
|
-
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
146
|
-
console.log('📊 Index Summary\n');
|
|
147
|
-
console.log(` 📁 Total files found: ${totalFound}`);
|
|
148
|
-
console.log(` ➕ New packages added: ${totalAdded}`);
|
|
149
|
-
console.log(` ⏭️ Already registered: ${totalFound - totalAdded}`);
|
|
150
|
-
if (options.verbose && summary.length > 0) {
|
|
151
|
-
console.log('\n Breakdown by directory:');
|
|
152
|
-
summary.filter(s => s.found > 0).forEach(s => {
|
|
153
|
-
console.log(` ${s.dir}: ${s.found} found, ${s.added} added`);
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
157
|
-
if (totalAdded > 0) {
|
|
158
|
-
console.log(`\n✅ Successfully indexed ${totalAdded} new package(s)`);
|
|
159
|
-
console.log(' Run `prpm list` to see all registered packages');
|
|
160
|
-
}
|
|
161
|
-
else if (totalFound > 0) {
|
|
162
|
-
console.log('\n✨ All existing files are already registered');
|
|
163
|
-
}
|
|
164
|
-
else {
|
|
165
|
-
console.log('\n💡 No prompt files found in standard directories');
|
|
166
|
-
console.log(' Install packages with: prpm install <package-name>');
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
catch (error) {
|
|
170
|
-
console.error(`❌ Failed to index packages: ${error}`);
|
|
171
|
-
throw new errors_1.CLIError(`❌ Failed to index packages: ${error}`, 1);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Create the index command
|
|
176
|
-
*/
|
|
177
|
-
function createIndexCommand() {
|
|
178
|
-
const command = new commander_1.Command('index');
|
|
179
|
-
command
|
|
180
|
-
.description('Scan AI editor directories and register untracked prompt files in prpm-lock.json')
|
|
181
|
-
.option('-v, --verbose', 'Show detailed output for each file scanned')
|
|
182
|
-
.action(handleIndex);
|
|
183
|
-
return command;
|
|
184
|
-
}
|
package/dist/commands/info.js
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
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("@pr-pm/registry-client");
|
|
10
|
-
const user_config_1 = require("../core/user-config");
|
|
11
|
-
const telemetry_1 = require("../core/telemetry");
|
|
12
|
-
const errors_1 = require("../core/errors");
|
|
13
|
-
async function handleInfo(packageName) {
|
|
14
|
-
const startTime = Date.now();
|
|
15
|
-
let success = false;
|
|
16
|
-
let error;
|
|
17
|
-
try {
|
|
18
|
-
console.log(`📦 Fetching package info for "${packageName}"...`);
|
|
19
|
-
const config = await (0, user_config_1.getConfig)();
|
|
20
|
-
const client = (0, registry_client_1.getRegistryClient)(config);
|
|
21
|
-
const pkg = await client.getPackage(packageName);
|
|
22
|
-
console.log('\n' + '='.repeat(60));
|
|
23
|
-
console.log(` ${pkg.name} ${pkg.verified ? '✓ Verified' : ''}`);
|
|
24
|
-
console.log('='.repeat(60));
|
|
25
|
-
// Description
|
|
26
|
-
if (pkg.description) {
|
|
27
|
-
console.log(`\n📝 ${pkg.description}`);
|
|
28
|
-
}
|
|
29
|
-
// Stats
|
|
30
|
-
console.log('\n📊 Stats:');
|
|
31
|
-
console.log(` Downloads: ${pkg.total_downloads.toLocaleString()}`);
|
|
32
|
-
if (pkg.rating_average) {
|
|
33
|
-
console.log(` Rating: ${'⭐'.repeat(Math.round(pkg.rating_average))} (${pkg.rating_average.toFixed(1)}/5)`);
|
|
34
|
-
}
|
|
35
|
-
// Latest version
|
|
36
|
-
if (pkg.latest_version) {
|
|
37
|
-
console.log(`\n🏷️ Latest Version: ${pkg.latest_version.version}`);
|
|
38
|
-
}
|
|
39
|
-
// Tags
|
|
40
|
-
if (pkg.tags && pkg.tags.length > 0) {
|
|
41
|
-
console.log(`\n🏷️ Tags: ${pkg.tags.join(', ')}`);
|
|
42
|
-
}
|
|
43
|
-
// Type
|
|
44
|
-
console.log(`\n📂 Type: ${`${pkg.format || 'unknown'} ${pkg.subtype || 'unknown'}`}`);
|
|
45
|
-
// Installation
|
|
46
|
-
console.log('\n💻 Installation:');
|
|
47
|
-
console.log(` prpm install ${pkg.name}`);
|
|
48
|
-
console.log(` prpm install ${pkg.name}@${pkg.latest_version?.version || 'latest'}`);
|
|
49
|
-
console.log('\n' + '='.repeat(60));
|
|
50
|
-
success = true;
|
|
51
|
-
}
|
|
52
|
-
catch (err) {
|
|
53
|
-
error = err instanceof Error ? err.message : String(err);
|
|
54
|
-
throw new errors_1.CLIError(`\n❌ Failed to fetch package info: ${error}\n\n💡 Tips:\n - Check the package ID spelling\n - Search for packages: prpm search <query>\n - View trending: prpm trending`, 1);
|
|
55
|
-
}
|
|
56
|
-
finally {
|
|
57
|
-
await telemetry_1.telemetry.track({
|
|
58
|
-
command: 'info',
|
|
59
|
-
success,
|
|
60
|
-
error,
|
|
61
|
-
duration: Date.now() - startTime,
|
|
62
|
-
data: {
|
|
63
|
-
packageName,
|
|
64
|
-
},
|
|
65
|
-
});
|
|
66
|
-
await telemetry_1.telemetry.shutdown();
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
function createInfoCommand() {
|
|
70
|
-
const command = new commander_1.Command('info');
|
|
71
|
-
command
|
|
72
|
-
.description('Display detailed package information')
|
|
73
|
-
.argument('<package>', 'Package ID to get information about')
|
|
74
|
-
.action(async (packageId) => {
|
|
75
|
-
await handleInfo(packageId);
|
|
76
|
-
});
|
|
77
|
-
return command;
|
|
78
|
-
}
|