Managing Collections
Relevant source files
The following files were used as context for generating this wiki page:Collections in PRPM are bundles of related packages designed to establish complete workflow setups with a single command. Instead of installing individual packages for tasks like linting, testing, and framework conventions, a user can install a curated collection to get a productive development environment instantly. This system simplifies project scaffolding and ensures teams use a consistent set of AI-powered tools.
The Collections system involves the CLI for installation, a registry for discovery and resolution, and a database for storing collection metadata and their associated packages. This allows for features like versioning, scoped collections, and a default public collection namespace.
Sources: CONTRIBUTING.md:41-43, packages/webapp/src/app/blog/prpm-complete-feature-guide/page.tsx:111-117, DOCUMENTATION_MAP.md:8
Collection Structure
A collection is defined by a collection.prpm.json file. This manifest specifies the collection's metadata and lists the packages it includes.
Sources: CONTRIBUTING.md:45-47
collection.prpm.json Manifest
The following table details the fields within the collection.prpm.json file.
| Field | Type | Required | Description |
|---|---|---|---|
scope | string | No | The scope or namespace of the collection (e.g., @collection). |
id | string | Yes | A unique identifier for the collection, often prefixed with the scope. |
name | string | Yes | A human-readable name for the collection. |
version | string | Yes | The semantic version of the collection. |
description | string | Yes | A brief description of the collection's purpose. |
category | string | Yes | A category to help with discovery (e.g., frontend). |
packages | object[] | Yes | An array of packages included in the collection. |
Sources: CONTRIBUTING.md:49-69
packages Array Structure
Each object in the packages array has the following structure:
| Field | Type | Required | Description |
|---|---|---|---|
id / packageId | string | Yes | The ID of the package to include. |
version | string | Yes | The required semantic version range for the package. |
required | boolean | Yes | Whether the package is mandatory for the collection. |
reason | string | No | An explanation for why the package is included. |
Sources: CONTRIBUTING.md:59-68, AGENTS.md:124-135
Example Manifest
{
"scope": "@collection",
"id": "nextjs-pro",
"name": "Next.js Professional Setup",
"version": "1.0.0",
"description": "Complete Next.js development environment",
"category": "frontend",
"packages": [
{
"id": "react-best-practices",
"version": "^1.0.0",
"required": true
},
{
"id": "typescript-strict",
"version": "^1.0.0",
"required": true
},
{
"id": "tailwind-helper",
"version": "^1.0.0",
"required": false
}
]
}
Sources: CONTRIBUTING.md:49-69
Database Schema
The registry uses a PostgreSQL database to store information about collections and their constituent packages. The schema is defined using Drizzle ORM.
Sources: packages/registry/src/db/schema/collections.ts
Entity Relationship Diagram
This diagram shows the relationship between the collections and collection_packages tables.
collections Table
This table stores the metadata for each collection.
| Column | Type | Constraints | Description |
|---|---|---|---|
id | text | Primary Key | Unique identifier for the collection. |
name | text | Not Null | Human-readable name. |
name_slug | text | Not Null | URL-friendly slug of the name. |
scope | text | Not Null | The scope/namespace of the collection. |
description | text | A brief description. | |
category | text | The collection's category. | |
user_id | text | Not Null, Foreign Key | The ID of the user who created the collection. |
official | boolean | Default false | Flag for official PRPM collections. |
verified_author | boolean | Default false | Flag if the author is verified. |
version_major | integer | Not Null | Major version number. |
version_minor | integer | Not Null | Minor version number. |
version_patch | integer | Not Null | Patch version number. |
created_at | timestamp | Not Null, Default now() | Timestamp of creation. |
updated_at | timestamp | Timestamp of the last update. |
Sources: packages/registry/src/db/schema/collections.ts:5-30
collection_packages Table
This table links packages to collections, forming the content of a collection.
| Column | Type | Constraints | Description |
|---|---|---|---|
id | text | Primary Key | Unique identifier for the relationship. |
collection_id | text | Not Null, Foreign Key | The ID of the collection. |
package_id | text | Not Null, Foreign Key | The ID of the package. |
required | boolean | Default true | Whether the package is required. |
version_range | text | The required semver range for the package. | |
reason | text | An explanation for including the package. |
Sources: packages/registry/src/db/schema/collections.ts:32-48
CLI Interaction
The primary user interaction with collections is through the prpm install command. The CLI is responsible for parsing the collection identifier and orchestrating the installation of all packages within it.
Sources: packages/cli/src/commands/collections.ts, packages/webapp/src/app/blog/prpm-complete-feature-guide/page.tsx:115-117
Installation Command
Users install a collection using a special collections/ prefix or a scoped name.
# Install from the default 'collection' scope
prpm install collections/nextjs-pro
prpm install collections/nextjs-pro@2.0.0
# Install from a user-specific scope
prpm install khaliqgant/nextjs-pro@2.0.4
Sources: AGENTS.md:138-142
CLI Resolution and Installation Flow
The CLI parses the user's input to determine the scope, name, and version, then fetches the collection from the registry and installs its packages.
This diagram illustrates the process the CLI follows to install a collection.
Sources: packages/cli/src/commands/collections.ts:25-58, AGENTS.md:154-162
Parsing the Collection Specifier
The CLI uses a regular expression to parse the collection string provided by the user. It can handle scoped and unscoped collection names. If no scope is provided, it defaults to 'collection'.
// packages/cli/src/commands/collections.ts:28-40
const matchWithScope = collectionSpec.match(/^@?([^/]+)\/([^/@]+)(?:@(.+))?$/);
if (matchWithScope) {
[, scope, name_slug, version] = matchWithScope;
} else {
// No scope: default to 'collection'
const matchWithoutScope = collectionSpec.match(/^([^/@]+)(?:@(.+))?$/);
if (matchWithoutScope) {
[, name_slug, version] = matchWithoutScope;
} else {
// ... error handling
}
scope = 'collection';
}
Sources: packages/cli/src/commands/collections.ts:28-40, AGENTS.md:154-166
Registry API and Resolution
The registry exposes endpoints for fetching collection data. It contains logic to resolve collection names based on scope and other quality metrics.
Sources: packages/registry/src/routes/collections.ts, AGENTS.md:145-152
API Endpoints
The primary endpoint for retrieving a collection is:
GET /collections/:scope/:name_slug
This endpoint fetches a specific collection version or the latest version if none is specified.
Sources: packages/registry/src/routes/collections.ts:16-18
CLI and Registry Sequence Diagram
This diagram shows the interaction between the CLI and the Registry when a user installs a collection.
Registry Resolution Logic
The registry's logic for finding a collection depends on whether the scope is the default 'collection' or a specific user/organization scope.
This logic ensures that unscoped searches find the most popular or official collections, while scoped searches are precise.
Sources: AGENTS.md:145-152
The corresponding SQL query for an unscoped search is designed to rank results based on these quality metrics:
-- AGENTS.md:145-152
SELECT * FROM collections
WHERE name_slug = $1
ORDER BY official DESC, verified DESC, downloads DESC, created_at DESC
LIMIT 1
Sources: AGENTS.md:145-152
Conclusion
The Collections feature is a cornerstone of PRPM, designed to enhance developer productivity by bundling related AI tools. It provides a streamlined experience for setting up complex development environments through a simple prpm install command. The system is supported by a robust backend that includes a versioned database schema, a smart resolution API, and a flexible CLI parser, making it easy for users to find and install high-quality, curated sets of packages.