Multi-File Organization¶
Learn how to split PromptScript files across multiple files for better organization and maintainability.
Overview¶
As projects grow, a single .prs file can become unwieldy. PromptScript supports splitting your configuration across multiple files using @use imports and a registry structure.
flowchart TB
subgraph Project["Project Files"]
main["project.prs<br/>Main entry point"]
end
subgraph Fragments["Fragments"]
security["security.prs<br/>Security rules"]
testing["testing.prs<br/>Testing standards"]
docs["documentation.prs<br/>Doc guidelines"]
end
subgraph Registry["Registry"]
base["@company/base<br/>Organization defaults"]
end
main --> security
main --> testing
main --> docs
main --> base File Organization Patterns¶
Pattern 1: Responsibility-Based Split¶
Split by type of concern:
.promptscript/
├── project.prs # Main entry, imports fragments
├── fragments/
│ ├── security.prs # Security restrictions
│ ├── testing.prs # Testing standards
│ ├── documentation.prs # Doc guidelines
│ └── code-style.prs # Coding conventions
└── skills/
├── review.prs # Code review skill
└── deploy.prs # Deployment skill
Main entry file:
# .promptscript/project.prs
@meta {
id: "my-project"
syntax: "1.0.0"
}
@inherit @company/frontend
# Import responsibility fragments
@use ./fragments/security
@use ./fragments/testing
@use ./fragments/documentation
@use ./fragments/code-style
@identity {
"""
You are a senior developer on the Customer Portal team.
"""
}
@context {
project: "Customer Portal"
repository: "github.com/company/customer-portal"
}
Security fragment:
# .promptscript/fragments/security.prs
@meta {
id: "security-fragment"
syntax: "1.0.0"
}
@restrictions {
- "Never expose API keys or secrets in code"
- "Never commit credentials to version control"
- "Always validate and sanitize user input"
- "Never disable security features"
- "Use parameterized queries for database access"
}
@standards {
security: {
authentication: required
authorization: "RBAC"
inputValidation: required
outputEncoding: required
}
}
Testing fragment:
# .promptscript/fragments/testing.prs
@meta {
id: "testing-fragment"
syntax: "1.0.0"
}
@standards {
testing: {
framework: "vitest"
coverage: 80
patterns: ["unit", "integration", "e2e"]
mocking: "MSW for API mocking"
}
}
@shortcuts {
"/test": """
Write tests using:
- Vitest as the test runner
- Testing Library for DOM testing
- MSW for API mocking
"""
"/coverage": "Check test coverage and identify gaps"
}
Pattern 2: Feature-Based Split¶
For large projects, split by feature area:
.promptscript/
├── project.prs # Main entry
├── features/
│ ├── auth.prs # Authentication module
│ ├── payments.prs # Payment processing
│ ├── notifications.prs # Notification system
│ └── analytics.prs # Analytics features
└── shared/
├── api.prs # API conventions
└── database.prs # Database patterns
Auth feature:
# .promptscript/features/auth.prs
@meta {
id: "auth-feature"
syntax: "1.0.0"
}
@context {
"""
## Authentication Module
- OAuth 2.0 with PKCE
- JWT tokens with refresh rotation
- SSO via SAML 2.0
"""
}
@standards {
auth: {
tokenStorage: "httpOnly cookies"
sessionTimeout: 3600
refreshTokenRotation: true
}
}
@knowledge {
"""
## Auth API Endpoints
- POST /auth/login - User login
- POST /auth/logout - User logout
- POST /auth/refresh - Refresh token
- GET /auth/me - Current user info
"""
}
Pattern 3: Environment-Based Split¶
Different configurations for different environments:
.promptscript/
├── project.prs # Main entry
├── environments/
│ ├── development.prs # Dev-specific settings
│ ├── staging.prs # Staging settings
│ └── production.prs # Production settings
└── fragments/
└── ... # Shared fragments
Development environment:
# .promptscript/environments/development.prs
@meta {
id: "dev-environment"
syntax: "1.0.0"
}
@context {
environment: development
"""
## Development Environment
- Hot reloading enabled
- Debug logging on
- Mock services available
"""
}
@local {
"""
Local development setup:
- API: http://localhost:8080
- Database: local PostgreSQL
- Redis: local instance
"""
}
Using @use for Composition¶
Basic Import¶
# Import fragment from same directory
@use ./fragments/security
# Import from registry
@use @company/standards/testing
# Import with alias (for namespacing)
@use @core/guards/security as sec
How @use Merges Content¶
When you @use a file, its blocks are merged into the current file:
| Block Type | Merge Behavior |
|---|---|
@identity | Content concatenated |
@context | Objects deep merged, text concatenated |
@standards | Deep merge of objects |
@restrictions | Array concatenated |
@shortcuts | Merged by key (later overrides) |
@knowledge | Content concatenated |
@skills | Merged by skill name |
Import Order Matters¶
Later imports override earlier ones for same-key content:
@use ./fragments/base-shortcuts # /test -> "Run unit tests"
@use ./fragments/advanced-shortcuts # /test -> "Run full test suite"
# Result: /test -> "Run full test suite"
Registry vs Local Fragments¶
When to Use Registry¶
- Shared across projects: Company-wide standards
- Versioned: Need version pinning
- Team-wide: Team conventions
- Reusable: Generic patterns
When to Use Local Fragments¶
- Project-specific: Only relevant to this project
- Frequently changing: Rapid iteration needed
- Experimental: Testing new patterns
Best Practices¶
1. Keep Fragments Focused¶
Each fragment should have a single responsibility:
# ✅ Good: Single responsibility
# security.prs - Only security rules
# testing.prs - Only testing standards
# ❌ Bad: Mixed concerns
# everything.prs - Security, testing, docs, etc.
2. Use Meaningful Names¶
# ✅ Good
@use ./fragments/api-conventions
@use ./fragments/error-handling
# ❌ Bad
@use ./fragments/stuff
@use ./fragments/misc
3. Document Dependencies¶
Add comments explaining why fragments are needed:
# Security compliance required for all ACME projects
@use @core/security
# Frontend testing patterns from design system
@use @acme-ui/testing
# Project-specific payment integrations
@use ./features/stripe-integration
4. Keep Import Lists Organized¶
# Organization/team base
@inherit @company/frontend
# Core standards (alphabetical)
@use @core/compliance
@use @core/security
# Team fragments
@use @frontend/accessibility
@use @frontend/performance
# Project fragments
@use ./fragments/api
@use ./fragments/testing
5. Avoid Deep Nesting¶
# ✅ Good: Flat structure
@use ./fragments/security
@use ./fragments/testing
# ❌ Bad: Deep nesting
@use ./fragments/standards/code/security/v2/latest
Example: Complete Multi-File Setup¶
Directory Structure¶
my-project/
├── .promptscript/
│ ├── project.prs
│ └── fragments/
│ ├── security.prs
│ ├── testing.prs
│ ├── api-standards.prs
│ └── documentation.prs
├── registry/ # Local registry (optional)
│ └── @team/
│ └── base.prs
└── promptscript.yaml
Main Entry (project.prs)¶
@meta {
id: "my-project"
syntax: "1.0.0"
}
# Inherit team base configuration
@inherit @team/base
# Import project fragments
@use ./fragments/security
@use ./fragments/testing
@use ./fragments/api-standards
@use ./fragments/documentation
@identity {
"""
You are a senior full-stack developer working on My Project.
You follow team conventions and project-specific patterns.
"""
}
@context {
project: "My Project"
team: "Platform"
"""
A microservices-based platform for data processing.
Tech Stack:
- Backend: Node.js, TypeScript, NestJS
- Frontend: React, TypeScript, Vite
- Database: PostgreSQL, Redis
- Infrastructure: Kubernetes, AWS
"""
}
@shortcuts {
"/start": "Initialize development environment"
"/deploy": "Deploy to staging environment"
}
Configuration (promptscript.yaml)¶
version: '1'
project:
id: my-project
team: platform
input:
entry: .promptscript/project.prs
include:
- '.promptscript/**/*.prs'
registry:
path: ./registry
targets:
- github
- claude
- cursor
Compiled Output¶
When you run prs compile, all fragments are merged into a single output per target. The multi-file organization is a source-level concern only.
prs compile
# Output:
# ✓ .github/copilot-instructions.md
# ✓ CLAUDE.md
# ✓ .cursor/rules/project.mdc
Debugging Multi-File Setup¶
View Resolved Configuration¶
This shows how all fragments merge together.
Validate All Files¶
Validates main file and all imported fragments.
Check Import Resolution¶
If imports fail:
- Check file paths are correct
- Verify registry path in
promptscript.yaml - Ensure
@meta.idmatches expected paths
Next Steps¶
- Inheritance Guide - Deep dive into inheritance patterns
- Enterprise Setup - Organization-wide registries
- Configuration Reference - Full config options