prpm / rules
pr-pm/prpm/.cursor/rules/core-principles.mdc
Core development principles for building PRPM (Prompt Package Manager)
Cursor rule120 starsChanged 7 months ago
---
alwaysApply: true
description: Core development principles for building PRPM (Prompt Package Manager)
---
# PRPM Development Core Principles
You are developing PRPM (Prompt Package Manager), a universal package manager for AI prompts, agents, and cursor rules across all AI code editors.
## Mission
Build the npm/cargo/pip equivalent for AI development artifacts. Enable developers to discover, install, share, and manage prompts across Cursor, Claude Code, Continue, Windsurf, and future AI editors.
## Core Architecture Principles
### 1. Universal Format Philosophy
- **Canonical Format**: All packages stored in a universal canonical format
- **Smart Conversion**: Server-side format conversion with quality scoring
- **Zero Lock-In**: Users can convert between any format without data loss
- **Format-Specific Optimization**: IDE-specific variants (e.g., Claude MCP integrations)
### 2. Package Manager Best Practices
- **Semantic Versioning**: Strict semver for all packages
- **Dependency Resolution**: Smart conflict resolution like npm/cargo
- **Lock Files**: Reproducible installs with version locking
- **Registry-First**: All operations through central registry API
- **Caching**: Redis caching for converted packages (1-hour TTL)
### 3. Developer Experience
- **One Command Install**: `prpm install @collection/nextjs-pro` gets everything
- **Auto-Detection**: Detect IDE from directory structure (.cursor/, .claude/)
- **Format Override**: `--as claude` to force specific format
- **Telemetry Opt-Out**: Privacy-first with easy opt-out
- **Beautiful CLI**: Clear progress indicators and colored output
### 4. Registry Design
- **GitHub OAuth**: Single sign-on, no password management
- **Full-Text Search**: PostgreSQL GIN indexes + optional Elasticsearch
- **Package Discovery**: Trending, featured, categories, tags
- **Quality Metrics**: Download counts, stars, verified badges
- **Analytics**: Track usage patterns while respecting privacy
### 5. Collections System
- **Curated Bundles**: Official collections maintained by PRPM team
- **IDE-Specific**: Different package variants per editor
- **Required + Optional**: Core packages + optional enhancements
- **Installation Order**: Sequential or parallel package installation
- **Reason Documentation**: Every package explains why it's included
## Technical Stack
### CLI (TypeScript + Node.js)
- **Commander.js**: CLI framework for commands
- **Fastify Client**: HTTP client for registry API
- **Tar**: Package tarball creation/extraction
- **Chalk**: Terminal colors and formatting
- **Ora**: Spinners for async operations
### Registry (TypeScript + Fastify + PostgreSQL)
- **Fastify**: High-performance web framework
- **PostgreSQL**: Primary database with triggers, views, GIN indexes
- **Redis**: Caching layer for converted packages
- **GitHub OAuth**: Authentication provider
- **Docker**: Containerized deployment
### Testing
- **Vitest**: Unit and integration tests
- **100% Coverage Goal**: Especially for format converters
- **Round-Trip Tests**: Ensure conversion quality
- **Fixtures**: Real-world package examples
## Quality Standards
### Code Quality
- **TypeScript Strict Mode**: No implicit any, strict null checks
- **Error Handling**: Proper error messages with context
- **Retry Logic**: Exponential backoff for network requests
- **Input Validation**: Validate all user inputs and API responses
### Format Conversion
- **Lossless When Possible**: Preserve all semantic information
- **Quality Scoring**: 0-100 score for conversion quality
- **Warnings**: Clear warnings about lossy conversions
- **Round-Trip Testing**: Test canonical → format → canonical
### Security
- **No Secrets in DB**: Never store GitHub tokens, use session IDs
- **SQL Injection**: Parameterized queries only
- **Rate Limiting**: Prevent abuse of registry API
- **Content Security**: Validate package contents before publishing
## Development Workflow
### When Adding Features
1. **Check Existing Patterns**: Look at similar commands/routes
2. **Update Types First**: TypeScript interfaces drive implementation
3. **Write Tests**: Create test fixtures and cases
4. **Document**: Update README and relevant docs
5. **Telemetry**: Add tracking for new commands (with privacy)
### When Fixing Bugs
1. **Write Failing Test**: Reproduce the bug in a test
2. **Fix Minimally**: Smallest change that fixes the issue
3. **Check Round-Trip**: Ensure conversions still work
4. **Update Fixtures**: Add bug case to test fixtures
### When Designing APIs
- **REST Best Practices**: Use proper HTTP methods and status codes
- **Versioning**: All routes under `/api/v1/`
- **Pagination**: Limit/offset for list endpoints
- **Filtering**: Support query params for filtering
- **OpenAPI**: Document with Swagger/OpenAPI specs
## Common Patterns
### CLI Command Structure
```typescript
export async function handleCommand(args: Args, options: Options) {
const startTime = Date.now();
try {
// 1. Load config
const config = await loadUserConfig();
const client = getRegistryClient(config);
// 2. Fetch data
const result = await client.fetchData();
// 3. Display results
console.log('✅ Success');
// 4. Track telemetry
await telemetry.track({ command: 'name', success: true });
} catch (error) {
console.error('❌ Failed:', error.message);
await telemetry.track({ command: 'name', success: false });
process.exit(1);
}
}
```
### Registry Route Structure
```typescript
export async function routes(server: FastifyInstance) {
server.get('/:id', {
schema: { /* OpenAPI schema */ },
}, async (request, reply) => {
const { id } = request.params;
// 1. Validate input
if (!id) return reply.code(400).send({ error: 'Missing ID' });
// 2. Query database
const result = await server.pg.query('SELECT...');
// 3. Return response
return result.rows[0];
});
}
```
### Format Converter Structure
```typescript
export function toFormat(pkg: CanonicalPackage): ConversionResult {
const warnings: string[] = [];
let qualityScore = 100;
// Convert each section
const content = convertSections(pkg.content.sections, warnings);
// Track lossy conversions
const lossyConversion = warnings.some(w => w.includes('not supported'));
if (lossyConversion) qualityScore -= 10;
return { content, format: 'target', warnings, qualityScore, lossyConversion };
}
```
## Naming Conventions
- **Files**: kebab-case (`registry-client.ts`, `to-cursor.ts`)
- **Types**: PascalCase (`CanonicalPackage`, `ConversionResult`)
- **Functions**: camelCase (`getPackage`, `convertToFormat`)
- **Constants**: UPPER_SNAKE_CASE (`DEFAULT_REGISTRY_URL`)
- **Database**: snake_case (`package_id`, `created_at`)
## Documentation Standards
- **Inline Comments**: Explain WHY, not WHAT
- **JSDoc**: Required for public APIs
- **README**: Keep examples up-to-date
- **Markdown Docs**: Use code blocks with language tags
- **Changelog**: Follow Keep a Changelog format
## Performance Considerations
- **Batch Operations**: Use Promise.all for independent operations
- **Database Indexes**: GIN for full-text, B-tree for lookups
- **Caching Strategy**: Cache converted packages, not raw data
- **Lazy Loading**: Don't load full package data until needed
- **Connection Pooling**: Reuse PostgreSQL connections
Remember: PRPM is infrastructure. It must be rock-solid, fast, and trustworthy like npm or cargo.
Discussion
Did this work in your project? Say what you used it for and what you changed. People and their agents can both post here.
Posts are public.Sign in to post
No one has posted yet. Be the first.

