# Prpm Development

> Individual package

- Skill: `pr-pm/prpm-development` (Agent Skill)
- Install (CLI): `npx skillmds@latest add pr-pm/prpm-development`
- Raw SKILL.md: https://api.skillmd.com/api/skills/pr-pm/prpm-development/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: pr-pm (https://skillmd.com/u/pr-pm)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/pr-pm/prpm-development

---

# Individual package

Use when developing PRPM (Prompt Package Manager) - comprehensive knowledge base covering architecture, format conversion, package types, collections, quality standards, testing, and deployment

## 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

- **Canonical Format**: All packages stored in normalized JSON structure
- **Smart Conversion**: Server-side format conversion with quality scoring
- **Zero Lock-In**: Users convert between any format without data loss
- **Format-Specific Optimization**: IDE-specific variants (e.g., Claude with MCP)
- **Semantic Versioning**: Strict semver for all packages
- **Dependency Resolution**: Smart conflict resolution like npm/cargo
- **Lock Files**: Reproducible installs (prpm-lock.json)
- **Registry-First**: All operations through central registry API
- **Caching**: Redis caching for converted packages (1-hour TTL)
- **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

## Package Types

- Knowledge and guidelines for AI assistants
- `.claude/skills/`, `.cursor/rules/`
- `@prpm/pulumi-troubleshooting`, `@typescript/best-practices`
- Autonomous AI agents for multi-step tasks
- `.claude/agents/`, `.cursor/agents/`
- `@prpm/code-reviewer`, `@cursor/debugging-agent`
- Specific instructions or constraints for AI behavior
- `.cursor/rules/`, `.cursorrules`
- `@cursor/react-conventions`, `@cursor/test-first`
- Extensions that add functionality
- `.cursor/plugins/`, `.claude/plugins/`
- Reusable prompt templates
- `.prompts/`, project-specific directories
- Multi-step automation workflows
- `.workflows/`, `.github/workflows/`
- Executable utilities and scripts
- `scripts/`, `tools/`, `.bin/`
- Reusable file and project templates
- `templates/`, project-specific directories
- Model Context Protocol servers
- `.mcp/servers/`

## Format Conversion System

- Cursor (.mdc)
- MDC frontmatter with `ruleType`, `alwaysApply`, `description`
- Markdown body
- Simple, focused on coding rules
- No structured tools/persona definitions
- Claude (agent format)
- YAML frontmatter: `name`, `description`
- Optional: `tools` (comma-separated), `model` (sonnet/opus/haiku/inherit)
- Markdown body
- Supports persona, examples, instructions
- Continue (JSON)
- JSON configuration
- Simple prompts, context rules
- Limited metadata support
- Windsurf
- Similar to Cursor
- Markdown-based
- Basic structure
- Missing tools: -10 points
- Missing persona: -5 points
- Missing examples: -5 points
- Unsupported sections: -10 points each
- Format-specific features lost: -5 points
- **Canonical ↔ Claude**: Nearly lossless (95-100%)
- **Canonical ↔ Cursor**: Lossy on tools/persona (70-85%)
- **Canonical ↔ Continue**: Most lossy (60-75%)

## Collections System

### Collection Structure

```json
{
  "id": "@collection/nextjs-pro",
  "name": "Next.js Professional Setup",
  "description": "Complete Next.js development setup",
  "category": "frontend",
  "packages": [
    {
      "packageId": "react-best-practices",
      "required": true,
      "reason": "Core React patterns"
    },
    {
      "packageId": "typescript-strict",
      "required": true,
      "reason": "Type safety"
    },
    {
      "packageId": "tailwind-helper",
      "required": false,
      "reason": "Styling utilities"
    }
  ]
}
```


## Quality & Ranking System

- (0-30 points):
- Total downloads (weighted by recency)
- Stars/favorites
- Trending velocity
- (0-30 points):
- User ratings (1-5 stars)
- Review sentiment
- Documentation completeness
- (0-20 points):
- Verified author badge
- Original creator vs fork
- Publisher reputation
- Security scan results
- (0-10 points):
- Last updated date (<30 days = 10 points)
- Release frequency
- Active maintenance
- (0-10 points):
- Has README
- Has examples
- Has tags
- Complete metadata

## Technical Stack

- **Commander.js**: CLI framework
- **Fastify Client**: HTTP client for registry
- **Tar**: Package tarball creation/extraction
- **Chalk**: Terminal colors
- **Ora**: Spinners for async operations
- **Fastify**: High-performance web framework
- **PostgreSQL**: Primary database with GIN indexes
- **Redis**: Caching layer for converted packages
- **GitHub OAuth**: Authentication provider
- **Docker**: Containerized deployment
- **Vitest**: Unit and integration tests
- **100% Coverage Goal**: Especially for format converters
- **Round-Trip Tests**: Ensure conversion quality
- **Fixtures**: Real-world package examples

## Testing Standards

### Key Testing Patterns

```typescript
// Format converter test
describe('toCursor', () => {
  it('preserves data in roundtrip', () => {
    const result = toCursor(canonical);
    const back = fromCursor(result.content);
    expect(back).toEqual(canonical);
  });
});

// CLI command test
describe('install', () => {
  it('downloads and installs package', async () => {
    await handleInstall('test-pkg', { as: 'cursor' });
    expect(fs.existsSync('.cursor/rules/test-pkg.md')).toBe(true);
  });
});
```


## Development Workflow

- **Check Existing Patterns**: Look at similar commands/routes
- **Update Types First**: TypeScript interfaces drive implementation
- **Write Tests**: Create test fixtures and cases
- **Document**: Update README and relevant docs
- **Telemetry**: Add tracking for new commands (with privacy)
- **Write Failing Test**: Reproduce the bug in a test
- **Fix Minimally**: Smallest change that fixes the issue
- **Check Round-Trip**: Ensure conversions still work
- **Update Fixtures**: Add bug case to test fixtures
- **REST Best Practices**: 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

## Security Standards

- **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

## 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

## Deployment

### Publishing PRPM to NPM

```bash
npm version patch --workspace=prpm --workspace=@prpm/registry-client

npm version minor --workspace=prpm
```


## Common Patterns

### CLI Command Structure

```typescript
export async function handleCommand(args: Args, options: Options) {
  const startTime = Date.now();
  try {
    const config = await loadUserConfig();
    const client = getRegistryClient(config);
    const result = await client.fetchData();
    console.log('✅ Success');
    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
server.get('/:id', {
  schema: { /* OpenAPI schema */ },
}, async (request, reply) => {
  const { id } = request.params;
  if (!id) return reply.code(400).send({ error: 'Missing ID' });
  const result = await server.pg.query('SELECT...');
  return result.rows[0];
});
```

### Format Converter Structure

```typescript
export function toFormat(pkg: CanonicalPackage): ConversionResult {
  const warnings: string[] = [];
  let qualityScore = 100;
  const content = convertSections(pkg.content.sections, warnings);
  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

## Overview

Complete knowledge base for developing PRPM - the universal package manager for AI prompts, agents, and rules.

## Reference Documentation

- `format-conversion.md` - Complete format conversion specs
- `package-types.md` - All package types with examples
- `collections.md` - Collections system and examples
- `quality-ranking.md` - Quality and ranking algorithms
- `testing-guide.md` - Testing patterns and standards
- `deployment.md` - Deployment procedures
