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.
- package/README.md +928 -0
- package/dist/commands/add.js +107 -0
- package/dist/commands/collections.js +409 -0
- package/dist/commands/deps.js +92 -0
- package/dist/commands/index.js +124 -0
- package/dist/commands/info.js +81 -0
- package/dist/commands/install.js +252 -0
- package/dist/commands/list.js +89 -0
- package/dist/commands/login.js +219 -0
- package/dist/commands/outdated.js +127 -0
- package/dist/commands/popular.js +27 -0
- package/dist/commands/publish.js +217 -0
- package/dist/commands/remove.js +43 -0
- package/dist/commands/search.js +179 -0
- package/dist/commands/telemetry.js +103 -0
- package/dist/commands/trending.js +75 -0
- package/dist/commands/update.js +120 -0
- package/dist/commands/upgrade.js +120 -0
- package/dist/commands/whoami.js +51 -0
- package/dist/core/config.js +91 -0
- package/dist/core/downloader.js +64 -0
- package/dist/core/filesystem.js +94 -0
- package/dist/core/lockfile.js +182 -0
- package/dist/core/registry-client.js +265 -0
- package/dist/core/telemetry.js +170 -0
- package/dist/core/user-config.js +79 -0
- package/dist/index.js +69 -0
- package/dist/types.js +5 -0
- package/package.json +67 -0
|
@@ -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
|
+
}
|