prpm 0.0.20 → 0.1.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/commands/install.js +5 -3
- package/dist/commands/list.js +2 -0
- package/dist/commands/popular.js +1 -1
- package/dist/commands/publish.js +118 -12
- package/dist/commands/search.js +2 -2
- package/dist/commands/trending.js +2 -2
- package/dist/core/filesystem.js +2 -0
- package/package.json +3 -3
- package/schemas/prpm-manifest.schema.json +146 -0
package/dist/commands/install.js
CHANGED
|
@@ -502,18 +502,20 @@ function createInstallCommand() {
|
|
|
502
502
|
.description('Install a package from the registry')
|
|
503
503
|
.argument('<package>', 'Package to install (e.g., react-rules or react-rules@1.2.0)')
|
|
504
504
|
.option('--version <version>', 'Specific version to install')
|
|
505
|
-
.option('--as <format>', 'Convert and install in specific format (cursor, claude, continue, windsurf, canonical)')
|
|
505
|
+
.option('--as <format>', 'Convert and install in specific format (cursor, claude, continue, windsurf, copilot, kiro, agents.md, canonical)')
|
|
506
506
|
.option('--format <format>', 'Alias for --as')
|
|
507
507
|
.option('--subtype <subtype>', 'Specify subtype when converting (skill, agent, rule, etc.)')
|
|
508
508
|
.option('--frozen-lockfile', 'Fail if lock file needs to be updated (for CI)')
|
|
509
509
|
.action(async (packageSpec, options) => {
|
|
510
510
|
// Support both --as and --format (format is alias for as)
|
|
511
511
|
const convertTo = options.format || options.as;
|
|
512
|
-
if (convertTo && !['cursor', 'claude', 'continue', 'windsurf', 'canonical'].includes(convertTo)) {
|
|
513
|
-
console.error('❌ Format must be one of: cursor, claude, continue, windsurf, canonical');
|
|
512
|
+
if (convertTo && !['cursor', 'claude', 'continue', 'windsurf', 'copilot', 'kiro', 'agents.md', 'canonical'].includes(convertTo)) {
|
|
513
|
+
console.error('❌ Format must be one of: cursor, claude, continue, windsurf, copilot, kiro, agents.md, canonical');
|
|
514
514
|
console.log('\n💡 Examples:');
|
|
515
515
|
console.log(' prpm install my-package --as cursor # Convert to Cursor format');
|
|
516
516
|
console.log(' prpm install my-package --format claude # Convert to Claude format');
|
|
517
|
+
console.log(' prpm install my-package --format kiro # Convert to Kiro format');
|
|
518
|
+
console.log(' prpm install my-package --format agents.md # Convert to Agents.md format');
|
|
517
519
|
console.log(' prpm install my-package # Install in native format');
|
|
518
520
|
process.exit(1);
|
|
519
521
|
}
|
package/dist/commands/list.js
CHANGED
package/dist/commands/popular.js
CHANGED
|
@@ -25,7 +25,7 @@ async function handlePopular(options) {
|
|
|
25
25
|
function createPopularCommand() {
|
|
26
26
|
return new commander_1.Command('popular')
|
|
27
27
|
.description('Show popular packages (all time)')
|
|
28
|
-
.option('--format <format>', 'Filter by format (cursor, claude, continue, windsurf, copilot, kiro, generic)')
|
|
28
|
+
.option('--format <format>', 'Filter by format (cursor, claude, continue, windsurf, copilot, kiro, agents.md, generic)')
|
|
29
29
|
.option('--subtype <subtype>', 'Filter by subtype (rule, agent, skill, slash-command, prompt, workflow, tool, template, collection)')
|
|
30
30
|
.action(async (options) => {
|
|
31
31
|
await handlePopular(options);
|
package/dist/commands/publish.js
CHANGED
|
@@ -54,7 +54,7 @@ const snippet_extractor_1 = require("../utils/snippet-extractor");
|
|
|
54
54
|
/**
|
|
55
55
|
* Try to find and load manifest files
|
|
56
56
|
* Checks for:
|
|
57
|
-
* 1. prpm.json (native format) - returns single manifest or array of packages
|
|
57
|
+
* 1. prpm.json (native format) - returns single manifest or array of packages and collections
|
|
58
58
|
* 2. .claude/marketplace.json (Claude format) - returns all plugins as separate manifests
|
|
59
59
|
* 3. .claude-plugin/marketplace.json (Claude format - alternative location) - returns all plugins
|
|
60
60
|
*/
|
|
@@ -66,6 +66,12 @@ async function findAndLoadManifests() {
|
|
|
66
66
|
try {
|
|
67
67
|
const content = await (0, promises_1.readFile)(prpmJsonPath, 'utf-8');
|
|
68
68
|
const manifest = JSON.parse(content);
|
|
69
|
+
// Extract collections if present
|
|
70
|
+
const collections = [];
|
|
71
|
+
if ('collections' in manifest && Array.isArray(manifest.collections)) {
|
|
72
|
+
const rawCollections = manifest.collections;
|
|
73
|
+
collections.push(...rawCollections);
|
|
74
|
+
}
|
|
69
75
|
// Check if this is a multi-package manifest
|
|
70
76
|
if ('packages' in manifest && Array.isArray(manifest.packages)) {
|
|
71
77
|
const multiManifest = manifest;
|
|
@@ -94,11 +100,11 @@ async function findAndLoadManifests() {
|
|
|
94
100
|
};
|
|
95
101
|
return validateManifest(packageWithDefaults);
|
|
96
102
|
});
|
|
97
|
-
return { manifests: validatedManifests, source: 'prpm.json (multi-package)' };
|
|
103
|
+
return { manifests: validatedManifests, collections, source: 'prpm.json (multi-package)' };
|
|
98
104
|
}
|
|
99
105
|
// Single package manifest
|
|
100
106
|
const validated = validateManifest(manifest);
|
|
101
|
-
return { manifests: [validated], source: 'prpm.json' };
|
|
107
|
+
return { manifests: [validated], collections, source: 'prpm.json' };
|
|
102
108
|
}
|
|
103
109
|
catch (error) {
|
|
104
110
|
// Store error for later
|
|
@@ -127,7 +133,7 @@ async function findAndLoadManifests() {
|
|
|
127
133
|
const validated = validateManifest(manifest);
|
|
128
134
|
manifests.push(validated);
|
|
129
135
|
}
|
|
130
|
-
return { manifests, source: '.claude/marketplace.json' };
|
|
136
|
+
return { manifests, collections: [], source: '.claude/marketplace.json' };
|
|
131
137
|
}
|
|
132
138
|
catch (error) {
|
|
133
139
|
// marketplace.json not found or invalid at .claude path, try .claude-plugin
|
|
@@ -147,7 +153,7 @@ async function findAndLoadManifests() {
|
|
|
147
153
|
const validated = validateManifest(manifest);
|
|
148
154
|
manifests.push(validated);
|
|
149
155
|
}
|
|
150
|
-
return { manifests, source: '.claude-plugin/marketplace.json' };
|
|
156
|
+
return { manifests, collections: [], source: '.claude-plugin/marketplace.json' };
|
|
151
157
|
}
|
|
152
158
|
catch (error) {
|
|
153
159
|
// marketplace.json not found or invalid
|
|
@@ -322,13 +328,21 @@ async function handlePublish(options) {
|
|
|
322
328
|
console.log('📦 Publishing package...\n');
|
|
323
329
|
// Read and validate manifests
|
|
324
330
|
console.log('🔍 Validating package manifest(s)...');
|
|
325
|
-
const { manifests, source } = await findAndLoadManifests();
|
|
326
|
-
if (manifests.length > 1) {
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
331
|
+
const { manifests, collections, source } = await findAndLoadManifests();
|
|
332
|
+
if (manifests.length > 1 || collections.length > 0) {
|
|
333
|
+
if (manifests.length > 0) {
|
|
334
|
+
console.log(` Found ${manifests.length} package(s) in ${source}`);
|
|
335
|
+
if (options.package) {
|
|
336
|
+
console.log(` Filtering to package: ${options.package}`);
|
|
337
|
+
}
|
|
330
338
|
}
|
|
331
|
-
|
|
339
|
+
if (collections.length > 0) {
|
|
340
|
+
console.log(` Found ${collections.length} collection(s) in ${source}`);
|
|
341
|
+
if (options.collection) {
|
|
342
|
+
console.log(` Filtering to collection: ${options.collection}`);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
console.log(' Will publish each separately\n');
|
|
332
346
|
}
|
|
333
347
|
// Filter to specific package if requested
|
|
334
348
|
let filteredManifests = manifests;
|
|
@@ -538,6 +552,97 @@ async function handlePublish(options) {
|
|
|
538
552
|
});
|
|
539
553
|
}
|
|
540
554
|
}
|
|
555
|
+
// Publish collections if present
|
|
556
|
+
if (collections.length > 0) {
|
|
557
|
+
// Filter to specific collection if requested
|
|
558
|
+
let filteredCollections = collections;
|
|
559
|
+
if (options.collection) {
|
|
560
|
+
filteredCollections = collections.filter(c => c.id === options.collection);
|
|
561
|
+
if (filteredCollections.length === 0) {
|
|
562
|
+
throw new Error(`Collection "${options.collection}" not found in manifest. Available collections: ${collections.map(c => c.id).join(', ')}`);
|
|
563
|
+
}
|
|
564
|
+
console.log(` ✓ Found collection "${options.collection}"\n`);
|
|
565
|
+
}
|
|
566
|
+
// Track published collections
|
|
567
|
+
const publishedCollections = [];
|
|
568
|
+
const failedCollections = [];
|
|
569
|
+
for (const collection of filteredCollections) {
|
|
570
|
+
if (filteredCollections.length > 1) {
|
|
571
|
+
console.log(`\n${'='.repeat(60)}`);
|
|
572
|
+
console.log(`📚 Publishing collection`);
|
|
573
|
+
console.log(`${'='.repeat(60)}\n`);
|
|
574
|
+
}
|
|
575
|
+
try {
|
|
576
|
+
console.log(`📚 Publishing collection "${collection.name}"...`);
|
|
577
|
+
console.log(` ID: ${collection.id}`);
|
|
578
|
+
console.log(` Packages: ${collection.packages.length}`);
|
|
579
|
+
console.log('');
|
|
580
|
+
if (options.dryRun) {
|
|
581
|
+
console.log('✅ Dry run successful! Collection is ready to publish.');
|
|
582
|
+
publishedCollections.push({
|
|
583
|
+
id: collection.id,
|
|
584
|
+
name: collection.name,
|
|
585
|
+
version: collection.version || '1.0.0'
|
|
586
|
+
});
|
|
587
|
+
continue;
|
|
588
|
+
}
|
|
589
|
+
// Import and call the collection publish logic
|
|
590
|
+
const { handleCollectionPublish } = await Promise.resolve().then(() => __importStar(require('./collections.js')));
|
|
591
|
+
// Create a temporary manifest object for the collection
|
|
592
|
+
const collectionData = {
|
|
593
|
+
id: collection.id,
|
|
594
|
+
name: collection.name,
|
|
595
|
+
description: collection.description,
|
|
596
|
+
version: collection.version,
|
|
597
|
+
category: collection.category,
|
|
598
|
+
tags: collection.tags,
|
|
599
|
+
icon: collection.icon,
|
|
600
|
+
packages: collection.packages.map(pkg => ({
|
|
601
|
+
packageId: pkg.packageId,
|
|
602
|
+
version: pkg.version,
|
|
603
|
+
required: pkg.required !== false,
|
|
604
|
+
reason: pkg.reason,
|
|
605
|
+
})),
|
|
606
|
+
};
|
|
607
|
+
const result = await client.createCollection(collectionData);
|
|
608
|
+
console.log(`✅ Collection published successfully!`);
|
|
609
|
+
console.log(` Scope: ${result.scope}`);
|
|
610
|
+
console.log(` Name: ${result.name_slug}`);
|
|
611
|
+
console.log(` Version: ${result.version || '1.0.0'}`);
|
|
612
|
+
console.log('');
|
|
613
|
+
console.log(`💡 Install: prpm install collections/${result.name_slug}`);
|
|
614
|
+
console.log('');
|
|
615
|
+
publishedCollections.push({
|
|
616
|
+
id: collection.id,
|
|
617
|
+
name: collection.name,
|
|
618
|
+
version: result.version || '1.0.0'
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
catch (err) {
|
|
622
|
+
const collError = err instanceof Error ? err.message : String(err);
|
|
623
|
+
console.error(`\n❌ Failed to publish collection ${collection.id}: ${collError}\n`);
|
|
624
|
+
failedCollections.push({
|
|
625
|
+
id: collection.id,
|
|
626
|
+
error: collError
|
|
627
|
+
});
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
// Add collection results to summary
|
|
631
|
+
if (publishedCollections.length > 0) {
|
|
632
|
+
console.log(`✅ Successfully published ${publishedCollections.length} collection(s):`);
|
|
633
|
+
publishedCollections.forEach(coll => {
|
|
634
|
+
console.log(` - ${coll.name} (${coll.id}) v${coll.version}`);
|
|
635
|
+
});
|
|
636
|
+
console.log('');
|
|
637
|
+
}
|
|
638
|
+
if (failedCollections.length > 0) {
|
|
639
|
+
console.log(`❌ Failed to publish ${failedCollections.length} collection(s):`);
|
|
640
|
+
failedCollections.forEach(coll => {
|
|
641
|
+
console.log(` - ${coll.id}: ${coll.error}`);
|
|
642
|
+
});
|
|
643
|
+
console.log('');
|
|
644
|
+
}
|
|
645
|
+
}
|
|
541
646
|
// Print summary if multiple packages
|
|
542
647
|
if (manifests.length > 1) {
|
|
543
648
|
console.log(`\n${'='.repeat(60)}`);
|
|
@@ -628,11 +733,12 @@ async function handlePublish(options) {
|
|
|
628
733
|
*/
|
|
629
734
|
function createPublishCommand() {
|
|
630
735
|
return new commander_1.Command('publish')
|
|
631
|
-
.description('Publish
|
|
736
|
+
.description('Publish packages and collections to the registry')
|
|
632
737
|
.option('--access <type>', 'Package access (public or private) - overrides manifest setting')
|
|
633
738
|
.option('--tag <tag>', 'NPM-style tag (e.g., latest, beta)', 'latest')
|
|
634
739
|
.option('--dry-run', 'Validate package without publishing')
|
|
635
740
|
.option('--package <name>', 'Publish only a specific package from multi-package manifest')
|
|
741
|
+
.option('--collection <id>', 'Publish only a specific collection from manifest')
|
|
636
742
|
.action(async (options) => {
|
|
637
743
|
await handlePublish(options);
|
|
638
744
|
process.exit(0);
|
package/dist/commands/search.js
CHANGED
|
@@ -391,7 +391,7 @@ function createSearchCommand() {
|
|
|
391
391
|
command
|
|
392
392
|
.description('Search for packages in the registry')
|
|
393
393
|
.argument('[query]', 'Search query (optional when using --format/--subtype or --author)')
|
|
394
|
-
.option('--format <format>', 'Filter by package format (cursor, claude, continue, windsurf, copilot, kiro, generic, mcp)')
|
|
394
|
+
.option('--format <format>', 'Filter by package format (cursor, claude, continue, windsurf, copilot, kiro, agents.md, generic, mcp)')
|
|
395
395
|
.option('--subtype <subtype>', 'Filter by package subtype (rule, agent, skill, slash-command, prompt, workflow, tool, template, collection)')
|
|
396
396
|
.option('--author <username>', 'Filter by author username')
|
|
397
397
|
.option('--limit <number>', 'Number of results per page', '20')
|
|
@@ -404,7 +404,7 @@ function createSearchCommand() {
|
|
|
404
404
|
const author = options.author;
|
|
405
405
|
const limit = options.limit ? parseInt(options.limit, 10) : 20;
|
|
406
406
|
const page = options.page ? parseInt(options.page, 10) : 1;
|
|
407
|
-
const validFormats = ['cursor', 'claude', 'continue', 'windsurf', 'copilot', 'kiro', 'generic', 'mcp'];
|
|
407
|
+
const validFormats = ['cursor', 'claude', 'continue', 'windsurf', 'copilot', 'kiro', 'agents.md', 'generic', 'mcp'];
|
|
408
408
|
const validSubtypes = ['rule', 'agent', 'skill', 'slash-command', 'prompt', 'collection', 'chatmode'];
|
|
409
409
|
if (options.format && !validFormats.includes(format)) {
|
|
410
410
|
console.error(`❌ Format must be one of: ${validFormats.join(', ')}`);
|
|
@@ -62,14 +62,14 @@ function createTrendingCommand() {
|
|
|
62
62
|
const command = new commander_1.Command('trending');
|
|
63
63
|
command
|
|
64
64
|
.description('Show trending packages')
|
|
65
|
-
.option('--format <format>', 'Filter by format (cursor, claude, continue, windsurf, copilot, kiro, generic)')
|
|
65
|
+
.option('--format <format>', 'Filter by format (cursor, claude, continue, windsurf, copilot, kiro, agents.md, generic)')
|
|
66
66
|
.option('--subtype <subtype>', 'Filter by subtype (rule, agent, skill, slash-command, prompt, workflow, tool, template, collection)')
|
|
67
67
|
.option('--limit <number>', 'Number of packages to show', '10')
|
|
68
68
|
.action(async (options) => {
|
|
69
69
|
const format = options.format;
|
|
70
70
|
const subtype = options.subtype;
|
|
71
71
|
const limit = options.limit ? parseInt(options.limit, 10) : 10;
|
|
72
|
-
const validFormats = ['cursor', 'claude', 'continue', 'windsurf', 'copilot', 'kiro', 'generic', 'mcp'];
|
|
72
|
+
const validFormats = ['cursor', 'claude', 'continue', 'windsurf', 'copilot', 'kiro', 'agents.md', 'generic', 'mcp'];
|
|
73
73
|
const validSubtypes = ['rule', 'agent', 'skill', 'slash-command', 'prompt', 'workflow', 'tool', 'template', 'collection'];
|
|
74
74
|
if (options.format && !validFormats.includes(format)) {
|
|
75
75
|
console.error(`❌ Format must be one of: ${validFormats.join(', ')}`);
|
package/dist/core/filesystem.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prpm",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
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.2.
|
|
49
|
-
"@pr-pm/types": "^0.1.
|
|
48
|
+
"@pr-pm/registry-client": "^1.2.16",
|
|
49
|
+
"@pr-pm/types": "^0.1.16",
|
|
50
50
|
"ajv": "^8.17.1",
|
|
51
51
|
"ajv-formats": "^3.0.1",
|
|
52
52
|
"commander": "^11.1.0",
|
|
@@ -367,6 +367,100 @@
|
|
|
367
367
|
"$ref": "#"
|
|
368
368
|
},
|
|
369
369
|
"minItems": 1
|
|
370
|
+
},
|
|
371
|
+
"collections": {
|
|
372
|
+
"type": "array",
|
|
373
|
+
"description": "Array of collections to publish. Collections bundle multiple packages together for easier installation.",
|
|
374
|
+
"items": {
|
|
375
|
+
"type": "object",
|
|
376
|
+
"required": ["id", "name", "description", "packages"],
|
|
377
|
+
"properties": {
|
|
378
|
+
"id": {
|
|
379
|
+
"type": "string",
|
|
380
|
+
"description": "Unique collection identifier (kebab-case)",
|
|
381
|
+
"pattern": "^[a-z0-9-]+$",
|
|
382
|
+
"minLength": 3,
|
|
383
|
+
"maxLength": 100,
|
|
384
|
+
"examples": ["nextjs-complete", "fullstack-setup", "react-essentials"]
|
|
385
|
+
},
|
|
386
|
+
"name": {
|
|
387
|
+
"type": "string",
|
|
388
|
+
"description": "Display name of the collection",
|
|
389
|
+
"minLength": 3,
|
|
390
|
+
"maxLength": 100,
|
|
391
|
+
"examples": ["Next.js Complete", "Full Stack Setup"]
|
|
392
|
+
},
|
|
393
|
+
"description": {
|
|
394
|
+
"type": "string",
|
|
395
|
+
"description": "What this collection provides",
|
|
396
|
+
"minLength": 10,
|
|
397
|
+
"maxLength": 500
|
|
398
|
+
},
|
|
399
|
+
"version": {
|
|
400
|
+
"type": "string",
|
|
401
|
+
"description": "Semantic version of the collection",
|
|
402
|
+
"pattern": "^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?(\\+[a-zA-Z0-9.-]+)?$",
|
|
403
|
+
"examples": ["1.0.0", "2.1.0"]
|
|
404
|
+
},
|
|
405
|
+
"category": {
|
|
406
|
+
"type": "string",
|
|
407
|
+
"description": "Collection category",
|
|
408
|
+
"enum": ["development", "testing", "deployment", "data-science", "devops", "design", "documentation", "security", "performance", "general"],
|
|
409
|
+
"examples": ["development", "testing"]
|
|
410
|
+
},
|
|
411
|
+
"tags": {
|
|
412
|
+
"type": "array",
|
|
413
|
+
"description": "Tags for discoverability (kebab-case)",
|
|
414
|
+
"items": {
|
|
415
|
+
"type": "string",
|
|
416
|
+
"pattern": "^[a-z0-9-]+$"
|
|
417
|
+
},
|
|
418
|
+
"minItems": 1,
|
|
419
|
+
"maxItems": 10,
|
|
420
|
+
"examples": [["react", "typescript", "nextjs"], ["python", "data-science", "ml"]]
|
|
421
|
+
},
|
|
422
|
+
"icon": {
|
|
423
|
+
"type": "string",
|
|
424
|
+
"description": "Emoji or icon for the collection",
|
|
425
|
+
"maxLength": 10,
|
|
426
|
+
"examples": ["⚛️", "🚀", "📦"]
|
|
427
|
+
},
|
|
428
|
+
"packages": {
|
|
429
|
+
"type": "array",
|
|
430
|
+
"description": "Array of packages included in this collection",
|
|
431
|
+
"items": {
|
|
432
|
+
"type": "object",
|
|
433
|
+
"required": ["packageId"],
|
|
434
|
+
"properties": {
|
|
435
|
+
"packageId": {
|
|
436
|
+
"type": "string",
|
|
437
|
+
"description": "Package identifier to include",
|
|
438
|
+
"minLength": 1,
|
|
439
|
+
"examples": ["typescript-strict", "react-best-practices"]
|
|
440
|
+
},
|
|
441
|
+
"version": {
|
|
442
|
+
"type": "string",
|
|
443
|
+
"description": "Version range (semver) or 'latest'",
|
|
444
|
+
"examples": ["^1.0.0", "~2.1.0", "1.0.0", "latest"]
|
|
445
|
+
},
|
|
446
|
+
"required": {
|
|
447
|
+
"type": "boolean",
|
|
448
|
+
"description": "Whether this package is required (true) or optional (false)",
|
|
449
|
+
"default": true
|
|
450
|
+
},
|
|
451
|
+
"reason": {
|
|
452
|
+
"type": "string",
|
|
453
|
+
"description": "Explanation of why this package is included",
|
|
454
|
+
"maxLength": 200,
|
|
455
|
+
"examples": ["Enforces strict TypeScript type safety", "React component best practices"]
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
},
|
|
459
|
+
"minItems": 1
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
},
|
|
463
|
+
"minItems": 1
|
|
370
464
|
}
|
|
371
465
|
},
|
|
372
466
|
"additionalProperties": false,
|
|
@@ -549,6 +643,58 @@
|
|
|
549
643
|
]
|
|
550
644
|
}
|
|
551
645
|
]
|
|
646
|
+
},
|
|
647
|
+
{
|
|
648
|
+
"name": "@username/multi-package-with-collection",
|
|
649
|
+
"version": "1.0.0",
|
|
650
|
+
"description": "Repository with both packages and a collection",
|
|
651
|
+
"author": "Your Name",
|
|
652
|
+
"license": "MIT",
|
|
653
|
+
"packages": [
|
|
654
|
+
{
|
|
655
|
+
"name": "typescript-rules",
|
|
656
|
+
"version": "1.0.0",
|
|
657
|
+
"description": "TypeScript coding standards",
|
|
658
|
+
"format": "cursor",
|
|
659
|
+
"subtype": "rule",
|
|
660
|
+
"tags": ["typescript", "cursor"],
|
|
661
|
+
"files": [".cursor/rules/typescript.mdc"]
|
|
662
|
+
},
|
|
663
|
+
{
|
|
664
|
+
"name": "react-patterns",
|
|
665
|
+
"version": "1.0.0",
|
|
666
|
+
"description": "React best practices",
|
|
667
|
+
"format": "claude",
|
|
668
|
+
"subtype": "skill",
|
|
669
|
+
"tags": ["react", "best-practices"],
|
|
670
|
+
"files": [".claude/skills/react-patterns/SKILL.md"]
|
|
671
|
+
}
|
|
672
|
+
],
|
|
673
|
+
"collections": [
|
|
674
|
+
{
|
|
675
|
+
"id": "fullstack-setup",
|
|
676
|
+
"name": "Full Stack Setup",
|
|
677
|
+
"description": "Complete full-stack development setup with TypeScript and React",
|
|
678
|
+
"version": "1.0.0",
|
|
679
|
+
"category": "development",
|
|
680
|
+
"tags": ["typescript", "react", "fullstack"],
|
|
681
|
+
"icon": "🚀",
|
|
682
|
+
"packages": [
|
|
683
|
+
{
|
|
684
|
+
"packageId": "typescript-rules",
|
|
685
|
+
"version": "^1.0.0",
|
|
686
|
+
"required": true,
|
|
687
|
+
"reason": "TypeScript coding standards for the project"
|
|
688
|
+
},
|
|
689
|
+
{
|
|
690
|
+
"packageId": "react-patterns",
|
|
691
|
+
"version": "^1.0.0",
|
|
692
|
+
"required": true,
|
|
693
|
+
"reason": "React component best practices"
|
|
694
|
+
}
|
|
695
|
+
]
|
|
696
|
+
}
|
|
697
|
+
]
|
|
552
698
|
}
|
|
553
699
|
]
|
|
554
700
|
}
|