

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
1<!-- Generated by Ruler -->234<!-- Source: .ruler/openskills.md -->56<skills_system priority="1">78## Available Skills910<!-- PRPM_MANIFEST_START -->1112<skills_system priority="1">13<usage>14When users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities and domain knowledge.1516How to use skills (loaded into main context):17- Use the <path> from the skill entry below18- Invoke: Bash("cat <path>")19- The skill content will load into your current context20- Example: Bash("cat .openskills/backend-architect/SKILL.md")2122Usage notes:23- Skills share your context window24- Do not invoke a skill that is already loaded in your context25</usage>2627<available_skills>2829<skill>30<name>prpm-development</name>31<description>Use when developing PRPM (Prompt Package Manager) - comprehensive knowledge base covering architecture, format conversion, package types, collections, quality standards, testing, and deployment</description>32<path>.openskills/prpm-development/SKILL.md</path>33</skill>3435<skill>36<name>osgrep-skill</name>37<description>Skill for using osgrep semantic code search - teaches how to effectively search codebases using natural language queries instead of exact string matching</description>38<path>.openskills/osgrep-skill/SKILL.md</path>39</skill>4041</available_skills>42</skills_system>4344<!-- PRPM_MANIFEST_END -->4546</skills_system>47484950<!-- Source: .ruler/prpm-development.md -->5152<!-- Package: prpm-development -->53<!-- Author: user -->54<!-- Description: Use when developing PRPM (Prompt Package Manager) - comprehensive knowledge base covering architecture, format conversion, package types, collections, quality standards, testing, and deployment -->5556# Individual package5758Use when developing PRPM (Prompt Package Manager) - comprehensive knowledge base covering architecture, format conversion, package types, collections, quality standards, testing, and deployment5960## Mission6162Build 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.6364## Core Architecture6566### Git Workflow - CRITICAL RULES6768```bash69git checkout -b feature/your-feature-name70 # or71 git checkout -b fix/bug-description72```7374## Package Types7576- Knowledge and guidelines for AI assistants7778- `.claude/skills/`, `.cursor/rules/`7980- `@prpm/pulumi-troubleshooting`, `@typescript/best-practices`8182- Autonomous AI agents for multi-step tasks8384- `.claude/agents/`, `.cursor/agents/`8586- `@prpm/code-reviewer`, `@cursor/debugging-agent`8788- Specific instructions or constraints for AI behavior8990- `.cursor/rules/`, `.cursorrules`9192- `@cursor/react-conventions`, `@cursor/test-first`9394- Extensions that add functionality9596- `.cursor/plugins/`, `.claude/plugins/`9798- Reusable prompt templates99100- `.prompts/`, project-specific directories101102- Multi-step automation workflows103104- `.workflows/`, `.github/workflows/`105106- Executable utilities and scripts107108- `scripts/`, `tools/`, `.bin/`109110- Reusable file and project templates111112- `templates/`, project-specific directories113114- Model Context Protocol servers115116- `.mcp/servers/`117118## Format Conversion System119120- Cursor (.mdc)121122- MDC frontmatter with `ruleType`, `alwaysApply`, `description`123124- Markdown body125126- Simple, focused on coding rules127128- No structured tools/persona definitions129130- Claude (agent format)131132- YAML frontmatter: `name`, `description`133134- Optional: `tools` (comma-separated), `model` (sonnet/opus/haiku/inherit)135136- Markdown body137138- Supports persona, examples, instructions139140- Continue (JSON)141142- JSON configuration143144- Simple prompts, context rules145146- Limited metadata support147148- Windsurf149150- Similar to Cursor151152- Markdown-based153154- Basic structure155156- Missing tools: -10 points157158- Missing persona: -5 points159160- Missing examples: -5 points161162- Unsupported sections: -10 points each163164- Format-specific features lost: -5 points165166- **Canonical ↔ Claude**: Nearly lossless (95-100%)167168- **Canonical ↔ Cursor**: Lossy on tools/persona (70-85%)169170- **Canonical ↔ Continue**: Most lossy (60-75%)171172## Collections System173174### Collection Structure175176```json177{178 "id": "@collection/nextjs-pro",179 "name": "Next.js Professional Setup",180 "description": "Complete Next.js development setup",181 "category": "frontend",182 "packages": [183 {184 "packageId": "react-best-practices",185 "required": true,186 "reason": "Core React patterns"187 },188 {189 "packageId": "typescript-strict",190 "required": true,191 "reason": "Type safety"192 },193 {194 "packageId": "tailwind-helper",195 "required": false,196 "reason": "Styling utilities"197 }198 ]199}200```201202### Installation Formats (Priority Order)203204```bash205prpm install collections/nextjs-pro206prpm install collections/nextjs-pro@2.0.0207```208209### Registry Resolution Logic210211```typescript212// When scope is 'collection' (default from CLI for collections/* prefix):213if (scope === 'collection') {214 // Search across ALL scopes, prioritize by:215 // 1. Official collections (official = true)216 // 2. Verified authors (verified = true)217 // 3. Most downloads218 // 4. Most recent219 SELECT * FROM collections220 WHERE name_slug = $1221 ORDER BY official DESC, verified DESC, downloads DESC, created_at DESC222 LIMIT 1223} else {224 // Explicit scope: exact match only225 SELECT * FROM collections226 WHERE scope = $1 AND name_slug = $2227 ORDER BY created_at DESC228 LIMIT 1229}230```231232### CLI Resolution Logic233234```typescript235// Parse collection spec:236// - collections/nextjs-pro → scope='collection', name_slug='nextjs-pro'237// - khaliqgant/nextjs-pro → scope='khaliqgant', name_slug='nextjs-pro'238// - @khaliqgant/nextjs-pro → scope='khaliqgant', name_slug='nextjs-pro'239// - nextjs-pro → scope='collection', name_slug='nextjs-pro'240241const matchWithScope = collectionSpec.match(/^@?([^/]+)\/([^/@]+)(?:@(.+))?$/);242if (matchWithScope) {243 [, scope, name_slug, version] = matchWithScope;244} else {245 // No scope: default to 'collection'246 [, name_slug, version] = collectionSpec.match(/^([^/@]+)(?:@(.+))?$/);247 scope = 'collection';248}249```250251### Version Resolution252253```bash254prpm install collections/nextjs-pro255256prpm install collections/nextjs-pro@2.0.4257258prpm install khaliqgant/nextjs-pro@2.0.4259```260261### Error Handling262263```bash264prpm install collections/nonexistent265```266267## Quality & Ranking System268269- (0-30 points):270271- Total downloads (weighted by recency)272273- Stars/favorites274275- Trending velocity276277- (0-30 points):278279- User ratings (1-5 stars)280281- Review sentiment282283- Documentation completeness284285- (0-20 points):286287- Verified author badge288289- Original creator vs fork290291- Publisher reputation292293- Security scan results294295- (0-10 points):296297- Last updated date (<30 days = 10 points)298299- Release frequency300301- Active maintenance302303- (0-10 points):304305- Has README306307- Has examples308309- Has tags310311- Complete metadata312313## Technical Stack314315- **Commander.js**: CLI framework316317- **Fastify Client**: HTTP client for registry318319- **Tar**: Package tarball creation/extraction320321- **Chalk**: Terminal colors322323- **Ora**: Spinners for async operations324325- **Fastify**: High-performance web framework326327- **PostgreSQL**: Primary database with GIN indexes328329- **Redis**: Caching layer for converted packages330331- **GitHub OAuth**: Authentication provider332333- **Docker**: Containerized deployment334335- **Vitest**: Unit and integration tests336337- **100% Coverage Goal**: Especially for format converters338339- **Round-Trip Tests**: Ensure conversion quality340341- **Fixtures**: Real-world package examples342343## Testing Standards344345### Key Testing Patterns346347```typescript348// Format converter test349describe('toCursor', () => {350 it('preserves data in roundtrip', () => {351 const result = toCursor(canonical);352 const back = fromCursor(result.content);353 expect(back).toEqual(canonical);354 });355});356357// CLI command test358describe('install', () => {359 it('downloads and installs package', async () => {360 await handleInstall('test-pkg', { as: 'cursor' });361 expect(fs.existsSync('.cursor/rules/test-pkg.md')).toBe(true);362 });363});364```365366## Development Workflow367368### Package Manager: npm (NOT pnpm)369370```bash371npm install372373npm install --workspace=@pr-pm/cli374375npm test376377npm run build378379npm run dev --workspace=prpm380```381382### Dependency Management Best Practices383384```typescript385// BAD - tar-stream is imported dynamically at runtime386const tarStream = await import('tar-stream');387```388389### Environment Variable Management390391```bash392NEW_FEATURE_API_KEY=your-key-here393```394395## Security Standards396397- **No Secrets in DB**: Never store GitHub tokens, use session IDs398399- **SQL Injection**: Parameterized queries only400401- **Rate Limiting**: Prevent abuse of registry API402403- **Content Security**: Validate package contents before publishing404405## Performance Considerations406407- **Batch Operations**: Use Promise.all for independent operations408409- **Database Indexes**: GIN for full-text, B-tree for lookups410411- **Caching Strategy**: Cache converted packages, not raw data412413- **Lazy Loading**: Don't load full package data until needed414415- **Connection Pooling**: Reuse PostgreSQL connections416417## Deployment418419### Webapp (S3 Static Export) ⚠️ CRITICAL420421```typescript422// ❌ Dynamic route (doesn't work with 'use client')423 // /app/shared/[token]/page.tsx424 const params = useParams();425 const token = params.token;426427 // ✅ Query string with Suspense (works with 'use client')428 // /app/shared/page.tsx429 import { Suspense } from 'react';430431 function Content() {432 const searchParams = useSearchParams();433 const token = searchParams.get('token');434 // ... component logic435 }436437 export default function Page() {438 return (439 <Suspense fallback={<div>Loading...</div>}>440 <Content />441 </Suspense>442 );443 }444```445446### Publishing PRPM to NPM447448```bash449npm version patch --workspace=prpm --workspace=@prpm/registry-client450451npm version minor --workspace=prpm452```453454## Common Patterns455456### CLI Command Structure457458```typescript459export async function handleCommand(args: Args, options: Options) {460 const startTime = Date.now();461 try {462 const config = await loadUserConfig();463 const client = getRegistryClient(config);464 const result = await client.fetchData();465 console.log('✅ Success');466 await telemetry.track({ command: 'name', success: true });467 } catch (error) {468 console.error('❌ Failed:', error.message);469 await telemetry.track({ command: 'name', success: false });470 process.exit(1);471 }472}473```474475### Registry Route Structure476477```typescript478server.get('/:id', {479 schema: { /* OpenAPI schema */ },480}, async (request, reply) => {481 const { id } = request.params;482 if (!id) return reply.code(400).send({ error: 'Missing ID' });483 const result = await server.pg.query('SELECT...');484 return result.rows[0];485});486```487488### Format Converter Structure489490```typescript491export function toFormat(pkg: CanonicalPackage): ConversionResult {492 const warnings: string[] = [];493 let qualityScore = 100;494 const content = convertSections(pkg.content.sections, warnings);495 const lossyConversion = warnings.some(w => w.includes('not supported'));496 if (lossyConversion) qualityScore -= 10;497 return { content, format: 'target', warnings, qualityScore, lossyConversion };498}499```500501## Naming Conventions502503- **Files**: kebab-case (`registry-client.ts`, `to-cursor.ts`)504505- **Types**: PascalCase (`CanonicalPackage`, `ConversionResult`)506507- **Functions**: camelCase (`getPackage`, `convertToFormat`)508509- **Constants**: UPPER_SNAKE_CASE (`DEFAULT_REGISTRY_URL`)510511- **Database**: snake_case (`package_id`, `created_at`)512513- **API Requests/Responses**: snake_case (`package_id`, `session_id`, `created_at`)514515- **Important**: All API request and response fields use snake_case to match PostgreSQL database conventions516517- Internal service methods may use camelCase, but must convert to snake_case at API boundaries518519- TypeScript interfaces for API types should use snake_case fields520521- Examples: `PlaygroundRunRequest.package_id`, `CreditBalance.reset_at`522523## Documentation Standards524525- **Inline Comments**: Explain WHY, not WHAT526527- **JSDoc**: Required for public APIs528529- **README**: Keep examples up-to-date530531- **Markdown Docs**: Use code blocks with language tags532533- **Changelog**: Follow Keep a Changelog format534535- **Continuous Accuracy**: Documentation must be continuously updated and tended to for accuracy536537- When adding features, update relevant docs immediately538539- When fixing bugs, check if docs need corrections540541- When refactoring, verify examples still work542543- Review docs quarterly for outdated information544545- Keep CLI docs, README, and Mintlify docs in sync546547## Overview548549Complete knowledge base for developing PRPM - the universal package manager for AI prompts, agents, and rules.550551## Reference Documentation552553- `format-conversion.md` - Complete format conversion specs554555- `package-types.md` - All package types with examples556557- `collections.md` - Collections system and examples558559- `quality-ranking.md` - Quality and ranking algorithms560561- `testing-guide.md` - Testing patterns and standards562563- `deployment.md` - Deployment procedures564565566567<!-- Source: .ruler/thoroughness.md -->568569<!-- Package: thoroughness -->570<!-- Author: user -->571<!-- Description: Use when implementing complex multi-step tasks, fixing critical bugs, or when quality and completeness matter more than speed - ensures comprehensive implementation without shortcuts through systematic analysis, implementation, and verification phases -->572573# Thoroughness574575Use when implementing complex multi-step tasks, fixing critical bugs, or when quality and completeness matter more than speed - ensures comprehensive implementation without shortcuts through systematic analysis, implementation, and verification phases576577## Purpose578579This skill ensures comprehensive, complete implementation of complex tasks without shortcuts. Use this when quality and completeness matter more than speed.580581## When to Use582583- Fixing critical bugs or compilation errors584585- Implementing complex multi-step features586587- Debugging test failures588589- Refactoring large codebases590591- Production deployments592593- Any task where shortcuts could cause future problems594595## Methodology596597- **Identify All Issues**598599- List every error, warning, and failing test600601- Group related issues together602603- Prioritize by dependency order604605- Create issue hierarchy (what blocks what)606607- **Root Cause Analysis**608609- Don't fix symptoms, find root causes610611- Trace errors to their source612613- Identify patterns in failures614615- Document assumptions that were wrong616617- **Create Detailed Plan**618619- Break down into atomic steps620621- Estimate time for each step622623- Identify dependencies between steps624625- Plan verification for each step626627- Schedule breaks/checkpoints628629- **Fix Issues in Dependency Order**630631- Start with foundational issues632633- Fix one thing completely before moving on634635- Test after each fix636637- Document what was changed and why638639- **Verify Each Fix**640641- Write/run tests for the specific fix642643- Check for side effects644645- Verify related functionality still works646647- Document test results648649- **Track Progress**650651- Mark issues as completed652653- Update plan with new discoveries654655- Adjust time estimates656657- Note any blockers immediately658659- **Run All Tests**660661- Unit tests662663- Integration tests664665- E2E tests666667- Manual verification668669- **Cross-Check Everything**670671- Review all changed files672673- Verify compilation succeeds674675- Check for console errors/warnings676677- Test edge cases678679- **Documentation**680681- Update relevant docs682683- Add inline comments for complex fixes684685- Document known limitations686687- Create issues for future work688689## Anti-Patterns to Avoid690691- ❌ Fixing multiple unrelated issues at once692693- ❌ Moving on before verifying a fix works694695- ❌ Assuming similar errors have the same cause696697- ❌ Skipping test writing "to save time"698699- ❌ Copy-pasting solutions without understanding700701- ❌ Ignoring warnings "because it compiles"702703- ❌ Making changes without reading existing code first704705## Quality Checkpoints706707- [ ] Can I explain why this fix works?708709- [ ] Have I tested this specific change?710711- [ ] Are there any side effects?712713- [ ] Is this the root cause or a symptom?714715- [ ] Will this prevent similar issues in the future?716717- [ ] Is the code readable and maintainable?718719- [ ] Have I documented non-obvious decisions?720721## Example Workflow722723### Bad Approach (Shortcut-Driven)724725*Bad example*726727```7281. See 24 TypeScript errors7292. Add @ts-ignore to all of them7303. Hope tests pass7314. Move on732```733734### Good Approach (Thoroughness-Driven)735736*Good example*737738```7391. List all 24 errors systematically7402. Group by error type (7 missing types, 10 unknown casts, 7 property access)7413. Find root causes:742 - Missing @types/tar package743 - No type assertions on fetch responses744 - Implicit any types in callbacks7454. Fix by category:746 - Install @types/tar (fixes 7 errors)747 - Add proper type assertions to registry-client.ts (fixes 10 errors)748 - Add explicit parameter types (fixes 7 errors)7495. Test after each category7506. Run full test suite7517. Document what was learned752```753754## Time Investment755756- Initial: 2-3x slower than shortcuts757758- Long-term: 10x faster (no debugging later, no rework)759760- Quality: Near-perfect first time761762- Maintenance: Minimal763764## Success Metrics765766- ✅ 100% of tests passing767768- ✅ Zero warnings in production build769770- ✅ All code has test coverage771772- ✅ Documentation is complete and accurate773774- ✅ No known issues or TODOs left behind775776- ✅ Future developers can understand the code777778## Mantras779780- "Slow is smooth, smooth is fast"781782- "Do it right the first time"783784- "Test everything, assume nothing"785786- "Document for your future self"787788- "Root causes, not symptoms"789790791792<!-- Source: .ruler/typescript-type-safety.md -->793794<!-- Package: typescript-type-safety -->795<!-- Author: user -->796<!-- Description: Use when encountering TypeScript any types, type errors, or lax type checking - eliminates type holes and enforces strict type safety through proper interfaces, type guards, and module augmentation -->797798# TypeScript Type Safety799800Use when encountering TypeScript any types, type errors, or lax type checking - eliminates type holes and enforces strict type safety through proper interfaces, type guards, and module augmentation801802## Overview803804**Zero tolerance for `any` types.** Every `any` is a runtime bug waiting to happen.805806Replace `any` with proper types using interfaces, `unknown` with type guards, or generic constraints. Use `@ts-expect-error` with explanation only when absolutely necessary.807808## When to Use809810- Use when you see:811812- `: any` in function parameters or return types813814- `as any` type assertions815816- TypeScript errors you're tempted to ignore817818- External libraries without proper types819820- Catch blocks with implicit `any`821822- Don't use for:823824- Already properly typed code825826- Third-party `.d.ts` files (contribute upstream instead)827828## Type Safety Hierarchy829830**Prefer in this order:**8311. Explicit interface/type definition8322. Generic type parameters with constraints8333. Union types8344. `unknown` (with type guards)8355. `never` (for impossible states)836837**Never use:** `any`838839## Quick Reference840841| Pattern | Bad | Good |842|---------|-----|------|843| **Error handling** | `catch (error: any)` | `catch (error) { if (error instanceof Error) ... }` |844| **Unknown data** | `JSON.parse(str) as any` | `const data = JSON.parse(str); if (isValid(data)) ...` |845| **Type assertions** | `(request as any).user` | `(request as AuthRequest).user` |846| **Double casting** | `return data as unknown as Type` | Align interfaces instead: make types compatible |847| **External libs** | `const server = fastify() as any` | `declare module 'fastify' { ... }` |848| **Generics** | `function process(data: any)` | `function process<T extends Record<string, unknown>>(data: T)` |849850## Implementation851852### Error Handling853854```typescript855// ❌ BAD856try {857 await operation();858} catch (error: any) {859 console.error(error.message);860}861862// ✅ GOOD - Use unknown and type guard863try {864 await operation();865} catch (error) {866 if (error instanceof Error) {867 console.error(error.message);868 } else {869 console.error('Unknown error:', String(error));870 }871}872873// ✅ BETTER - Helper function874function toError(error: unknown): Error {875 if (error instanceof Error) return error;876 return new Error(String(error));877}878879try {880 await operation();881} catch (error) {882 const err = toError(error);883 console.error(err.message);884}885```886887### Unknown Data Validation888889```typescript890// ❌ BAD891const data = await response.json() as any;892console.log(data.user.name);893894// ✅ GOOD - Type guard895interface UserResponse {896 user: {897 name: string;898 email: string;899 };900}901902function isUserResponse(data: unknown): data is UserResponse {903 return (904 typeof data === 'object' &&905 data !== null &&906 'user' in data &&907 typeof data.user === 'object' &&908 data.user !== null &&909 'name' in data.user &&910 typeof data.user.name === 'string'911 );912}913914const data = await response.json();915if (isUserResponse(data)) {916 console.log(data.user.name); // Type-safe917}918```919920### Module Augmentation921922```typescript923// ❌ BAD924const user = (request as any).user;925const db = (server as any).pg;926927// ✅ GOOD - Augment third-party types928import { FastifyRequest, FastifyInstance } from 'fastify';929930interface AuthUser {931 user_id: string;932 username: string;933 email: string;934}935936declare module 'fastify' {937 interface FastifyRequest {938 user?: AuthUser;939 }940941 interface FastifyInstance {942 pg: PostgresPlugin;943 }944}945946// Now type-safe everywhere947const user = request.user; // AuthUser | undefined948const db = server.pg; // PostgresPlugin949```950951### Generic Constraints952953```typescript954// ❌ BAD955function merge(a: any, b: any): any {956 return { ...a, ...b };957}958959// ✅ GOOD - Constrained generic960function merge<961 T extends Record<string, unknown>,962 U extends Record<string, unknown>963>(a: T, b: U): T & U {964 return { ...a, ...b };965}966```967968### Type Alignment (Avoid Double Casts)969970```typescript971// ❌ BAD - Double cast indicates misaligned types972interface SearchPackage {973 id: string;974 type: string; // Too loose975}976977interface RegistryPackage {978 id: string;979 type: PackageType; // Specific enum980}981982return data.packages as unknown as RegistryPackage[]; // Hiding incompatibility983984// ✅ GOOD - Align types from the source985interface SearchPackage {986 id: string;987 type: PackageType; // Use same specific type988}989990interface RegistryPackage {991 id: string;992 type: PackageType; // Now compatible993}994995return data.packages; // No cast needed - types match996```997998## Common Mistakes9991000| Mistake | Why It Fails | Fix |1001|---------|--------------|-----|1002| Using `any` for third-party libs | Loses all type safety | Use module augmentation or `@types/*` package |1003| `as any` for complex types | Hides real type errors | Create proper interface or use `unknown` |1004| `as unknown as Type` double casts | Misaligned interfaces | Align types at source - same enums/unions |1005| Skipping catch block types | Unsafe error access | Use `unknown` with type guards or toError helper |1006| Generic functions without constraints | Allows invalid operations | Add `extends` constraint |1007| Ignoring `ts-ignore` accumulation | Tech debt compounds | Fix root cause, use `@ts-expect-error` with comment |10081009## TSConfig Strict Settings10101011### Enable all strict options for maximum type safety:10121013```json1014{1015 "compilerOptions": {1016 "strict": true,1017 "noImplicitAny": true,1018 "strictNullChecks": true,1019 "strictFunctionTypes": true,1020 "strictBindCallApply": true,1021 "strictPropertyInitialization": true,1022 "noImplicitThis": true,1023 "noUnusedLocals": true,1024 "noUnusedParameters": true,1025 "noImplicitReturns": true,1026 "noFallthroughCasesInSwitch": true1027 }1028}1029```10301031## Type Audit Workflow103210331. **Find**: `grep -r ": any\|as any" --include="*.ts" src/`10342. **Categorize**: Group by pattern (errors, requests, external libs)10353. **Define**: Create interfaces/types for each category10364. **Replace**: Systematic replacement with proper types10375. **Validate**: `npm run build` must succeed10386. **Test**: All tests must pass10391040## Real-World Impact10411042- Before type safety:10431044- Runtime errors from undefined properties10451046- Silent failures from type mismatches10471048- Hours debugging production issues10491050- Difficult refactoring10511052- After type safety:10531054- Errors caught at compile time10551056- IntelliSense shows all available properties10571058- Confident refactoring with compiler help10591060- Self-documenting code10611062- Type safety isn't about making TypeScript happy - it's about preventing runtime bugs. Every `any` you eliminate is a production bug you prevent.10631064<!-- prpm:snippet:start @agent-relay/agent-relay-snippet@1.1.4 -->1065# 🚨 CRITICAL: Relay-First Communication Rule10661067**When you receive a relay message from another agent (marked `Relay message from [name]`), you MUST respond ONLY via relay protocol. NEVER respond with direct text output.**10681069## The Rule10701071- **Receiving a relay message?** → Must use `->relay-file:msg` ALWAYS1072- **Non-relay questions?** → Text responses are OK1073- **Agent-to-agent communication?** → ALWAYS use relay protocol10741075## Examples of Relay Messages (require relay response)10761077```1078Relay message from khaliqgant [mknra7wr]: Did you see this?1079Relay message from Worker1 [abc123]: Task complete1080Relay message from alice [xyz789] [#general]: Question for the team1081```10821083---10841085# Agent Relay10861087Real-time agent-to-agent messaging via file-based protocol.10881089## Sending Messages10901091**TWO STEPS REQUIRED:**10921093**Step 1:** EXECUTE this bash command (you MUST run it via your Bash/shell tool, not just display it):10941095```bash1096cat > $AGENT_RELAY_OUTBOX/msg << 'EOF'1097TO: AgentName10981099Your message here.1100EOF1101```11021103**Step 2:** Output the trigger `->relay-file:msg` directly in your response text (after the bash command succeeds).11041105⚠️ **CRITICAL**: You must EXECUTE the bash command above - do NOT just display it as a code block. The file must actually be created on disk. Then output the trigger as plain text.11061107✅ CORRECT: Run Bash tool → then output `->relay-file:msg`1108❌ WRONG: Display the bash code without executing it11091110> **Note**: `$AGENT_RELAY_OUTBOX` is automatically set by agent-relay when spawning agents. Data is stored in `.agent-relay/` within your project directory.11111112## Synchronous Messaging11131114By default, messages are fire-and-forget. Add `[await]` to block until the recipient ACKs:11151116```1117->relay:AgentB [await] Please confirm1118```11191120Custom timeout (seconds or minutes):11211122```1123->relay:AgentB [await:30s] Please confirm1124->relay:AgentB [await:5m] Please confirm1125```11261127Recipients auto-ACK after processing when a correlation ID is present.11281129## Message Format11301131```1132TO: Target1133THREAD: optional-thread11341135Message body (everything after blank line)1136```11371138| TO Value | Behavior |1139|----------|----------|1140| `AgentName` | Direct message |1141| `*` | Broadcast to all |1142| `#channel` | Channel message |11431144## Agent Naming (Local vs Bridge)11451146**Local communication** uses plain agent names. The `project:` prefix is **ONLY** for cross-project bridge mode.11471148| Context | Correct | Incorrect |1149|---------|---------|-----------|1150| Local (same project) | `TO: Lead` | `TO: project:lead` |1151| Local (same project) | `TO: Worker1` | `TO: myproject:Worker1` |1152| Bridge (cross-project) | `TO: frontend:Designer` | N/A |1153| Bridge (to another lead) | `TO: otherproject:lead` | N/A |11541155**Common mistake**: Using `project:lead` when communicating locally. This will fail because the relay looks for an agent literally named "project:lead".11561157```bash1158# CORRECT - local communication to Lead agent1159cat > $AGENT_RELAY_OUTBOX/msg << 'EOF'1160TO: Lead11611162Status update here.1163EOF1164```11651166```bash1167# WRONG - project: prefix is only for bridge mode1168cat > $AGENT_RELAY_OUTBOX/msg << 'EOF'1169TO: project:lead11701171This will fail locally!1172EOF1173```11741175## Spawning & Releasing11761177**IMPORTANT**: The filename is always `spawn` (not `spawn-agentname`) and the trigger is always `->relay-file:spawn`. Spawn agents one at a time sequentially.11781179### CLI Options11801181The `CLI` header specifies which AI CLI to use. Valid values:11821183| CLI Value | Description |1184|-----------|-------------|1185| `claude` | Claude Code (Anthropic) |1186| `codex` | Codex CLI (OpenAI) |1187| `gemini` | Gemini CLI (Google) |1188| `aider` | Aider coding assistant |1189| `goose` | Goose AI assistant |11901191**Step 1:** EXECUTE this bash command (run it, don't just display it):1192```bash1193# Spawn a Claude agent1194cat > $AGENT_RELAY_OUTBOX/spawn << 'EOF'1195KIND: spawn1196NAME: WorkerName1197CLI: claude11981199Task description here.1200EOF1201```1202**Step 2:** Output: `->relay-file:spawn`12031204```bash1205# Spawn a Codex agent1206cat > $AGENT_RELAY_OUTBOX/spawn << 'EOF'1207KIND: spawn1208NAME: CodexWorker1209CLI: codex12101211Task description here.1212EOF1213```12141215**Step 1:** EXECUTE this bash command (run it, don't just display it):1216```bash1217# Release1218cat > $AGENT_RELAY_OUTBOX/release << 'EOF'1219KIND: release1220NAME: WorkerName1221EOF1222```1223**Step 2:** Output: `->relay-file:release`12241225## When You Are Spawned12261227If you were spawned by another agent:122812291. **Check who spawned you**: `echo $AGENT_RELAY_SPAWNER`12302. **Your first message** is your task from your spawner - reply to THEM, not "spawner"12313. **Report status** to your spawner (your lead), not broadcast12321233```bash1234# Check your spawner1235echo "I was spawned by: $AGENT_RELAY_SPAWNER"1236```12371238**Step 1:** EXECUTE this bash command:1239```bash1240# Reply to your spawner1241cat > $AGENT_RELAY_OUTBOX/msg << 'EOF'1242TO: $AGENT_RELAY_SPAWNER12431244ACK: Starting on the task.1245EOF1246```1247**Step 2:** Output: `->relay-file:msg`12481249## Receiving Messages12501251Messages appear as:1252```1253Relay message from Alice [abc123]: Content here1254```12551256Channel messages include `[#channel]`:1257```1258Relay message from Alice [abc123] [#general]: Hello!1259```1260Reply to the channel shown, not the sender.12611262## Protocol12631264- **ACK** when you receive a task: `ACK: Brief description`1265- **DONE** when complete: `DONE: What was accomplished`1266- Send status to your **lead** (the agent in `$AGENT_RELAY_SPAWNER`), not broadcast12671268## Headers Reference12691270| Header | Required | Description |1271|--------|----------|-------------|1272| TO | Yes (messages) | Target agent/channel |1273| KIND | No | `message` (default), `spawn`, `release` |1274| NAME | Yes (spawn/release) | Agent name |1275| CLI | Yes (spawn) | CLI to use: `claude`, `codex`, `gemini`, `aider`, `goose` |1276| THREAD | No | Thread identifier |1277<!-- prpm:snippet:end @agent-relay/agent-relay-snippet@1.1.4 -->1278
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| pr-pm/prpm.cursor/rules/testing-patterns.mdc · 121 | Cursor rules | testlint-formatstyletesting-strategy | 77/100 | 14 days ago | |
| pr-pm/prpm.cursor/rules/beanstalk-deploy.mdc · 121 | Cursor rules | teststyletypes | 62/100 | 14 days ago | |
| pr-pm/prpm.cursor/rules/core-principles.mdc · 121 | Cursor rules | testlint-formatstylearch+6 | 69/100 | 14 days ago | |
| pr-pm/prpm.cursor/rules/creating-agents-md.mdc · 121 | Cursor rules | testlint-formatstylearch+7 | 92/100 | 14 days ago | |
| pr-pm/prpm.cursor/rules/creating-cursor-rules.mdc · 121 | Cursor rules | testlint-formatstylearch+5 | 76/100 | 14 days ago | |
| pr-pm/prpm.cursor/rules/creating-skills.mdc · 121 | Cursor rules | stylearchtesting-strategydo-not+1 | 61/100 | 14 days ago | |
| pr-pm/prpm.cursor/rules/github-actions-testing.mdc · 121 | Cursor rules | setupbuildstylearch+4 | 93/100 | 14 days ago | |
| pr-pm/prpm.cursor/rules/karen-repo-reviewer.mdc · 121 | Cursor rules | archgit | 58/100 | 14 days ago | |
| pr-pm/prpm.cursor/rules/prpm-json-best-practices.mdc · 121 | Cursor rules | setuplint-formatstylearch+5 | 73/100 | 14 days ago | |
| pr-pm/prpm.cursor/rules/self-improve-cursor.mdc · 121 | Cursor rules | setuptestarchdependencies+3 | 69/100 | 14 days ago | |
| pr-pm/prpm.cursor/rules/typescript-type-safety.mdc · 121 | Cursor rules | buildstylearchtypes+2 | 89/100 | 14 days ago | |
| pr-pm/prpm.cursor/rules/typescript-type-specialist.mdc · 121 | Cursor rules | styletypesdo-notagent-behaviour | 65/100 | 14 days ago | |
| pr-pm/prpmCLAUDE.md · 121 | CLAUDE.md | teststylegitapi+2 | 69/100 | 14 days ago | |
| pr-pm/prpm.cursor/rules/creating-kiro-agents.mdc · 121 | Cursor rules | setupbuildteststyle+5 | 76/100 | 14 days ago | |
| pr-pm/prpm.cursor/rules/format-conversion.mdc · 121 | Cursor rules | testlint-formatstyledo-not+1 | 63/100 | 14 days ago |
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| code-yeongyu/oh-my-openagentpackages/web/AGENTS.md · 68k | AGENTS.md | setupbuildtestlint-format+6 | 100/100 | 13 days ago | |
| mui/material-uiAGENTS.md · 99k | AGENTS.md | setupbuildtestlint-format+9 | 100/100 | 14 days ago | |
| aaif-goose/gooseAGENTS.md · 53k | AGENTS.md | setupbuildtestlint-format+7 | 100/100 | 8 days ago | |
| duckduckgo/content-scope-scriptsspecial-pages/AGENTS.md · 70 | AGENTS.md | buildteststylearch+3 | 100/100 | 14 days ago | |
| deepseek-ai/deepseek-harnessnative/landlock-run/AGENTS.md · 104k | AGENTS.md | setupteststylearch+3 | 100/100 | today | |
| TryGhost/Ghoste2e/AGENTS.md · 55k | AGENTS.md | setupteststylearch+2 | 100/100 | today | |
| n8n-io/n8npackages/@n8n/agents/AGENTS.md · 201k | AGENTS.md | buildteststylearch+3 | 100/100 | 14 days ago | |
| elastic/elasticsearchx-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/AGENTS.md · 78k | AGENTS.md | buildtestlint-formatstyle+2 | 100/100 | 14 days ago |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/pr-pm-prpm-agents)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.