First off, thank you for considering contributing to PromptScript! 🎉
- Code of Conduct
- Getting Started
- Development Workflow
- Pull Request Process
- Coding Standards
- Testing
- Documentation
This project adheres to the Contributor Covenant Code of Conduct. By participating, you are expected to uphold this code.
- Node.js 20+
- pnpm 8+
- Git
# Fork and clone the repository
git clone https://github.com/mrwogu/promptscript.git
cd promptscript
# Install dependencies
pnpm install
# Verify setup
nx run-many -t testpromptscript/
├── packages/
│ ├── core/ # Types, errors, utilities
│ ├── parser/ # PromptScript parser
│ ├── resolver/ # Inheritance resolution
│ ├── validator/ # Validation rules
│ ├── compiler/ # Compilation pipeline
│ ├── formatters/ # Output formatters (GitHub, Claude, Cursor, etc.)
│ ├── importer/ # Reverse-parser for importing AI instruction files
│ ├── browser-compiler/ # Browser-compatible compiler bundle
│ ├── playground/ # Web-based playground UI (private)
│ ├── server/ # Local dev server for playground (private)
│ └── cli/ # CLI application
├── docs/ # Documentation
└── examples/ # Example projects
During development, you can run the CLI without building:
# Using pnpm script (recommended)
pnpm prs --help
pnpm prs init
pnpm prs compile
# Or directly with node
node -r @swc-node/register packages/cli/src/cli.ts --helpThis uses @swc-node/register to transpile TypeScript on-the-fly, so changes are reflected immediately without rebuilding.
To use PromptScript in this repository itself:
pnpm prs initThis creates:
promptscript.config.yaml- project configuration.promptscript/project.prs- AI instructions file
-
Create a branch from
main:git checkout -b feat/your-feature-name
-
Make your changes following our coding standards
-
Write/update tests
-
Run checks:
nx affected -t test nx affected -t lint nx affected -t build -
Commit using conventional commits:
git commit -m "feat(parser): add support for multiline strings"
We use Conventional Commits:
feat:- New featurefix:- Bug fixdocs:- Documentation onlyrefactor:- Code change that neither fixes nor addstest:- Adding or updating testschore:- Maintenance tasks
Scope should be the package name: feat(parser):, fix(cli):, etc.
- Update documentation if needed
- Add tests for new functionality
- Ensure all checks pass
- Fill out the PR template completely
- Request review from maintainers
<type>(<scope>): <description>
Examples:
feat(parser): add support for @extend syntax
fix(cli): handle missing config file gracefully
docs(readme): update installation instructions
- Strict mode enabled
- No
anytypes (useunknownwith type guards) - Named exports only
- Explicit return types on public functions
// ✅ Good
export function parseVersion(input: string): SemVer {
// ...
}
// ❌ Bad
export default function (input) {
// ...
}- Files:
kebab-case.ts - Test files:
kebab-case.spec.ts - Interfaces:
PascalCase
- TSDoc on all public exports
- Examples in documentation
/**
* Parses a PromptScript path reference.
*
* @param path - The path string (e.g., "@core/guards/compliance@1.0.0")
* @returns Parsed path object
* @throws {ParseError} If path format is invalid
*
* @example
* ```typescript
* const parsed = parsePath('@core/org');
* // { namespace: 'core', segments: ['org'], version: undefined }
* ```
*/
export function parsePath(path: string): ParsedPath {
// ...
}# All tests
nx run-many -t test
# Specific package
nx test parser
# With coverage
nx test parser --coverage
# Watch mode
nx test parser --watch# Run CLI in development mode
pnpm prs init
pnpm prs validate
pnpm prs compile --dry-run- Use Vitest
- Follow AAA pattern (Arrange, Act, Assert)
-
90% coverage for library packages
describe('parseVersion', () => {
it('should parse valid version', () => {
// Arrange
const input = '1.2.3';
// Act
const result = parseVersion(input);
// Assert
expect(result).toEqual({ major: 1, minor: 2, patch: 3 });
});
it('should throw on invalid version', () => {
expect(() => parseVersion('invalid')).toThrow(ParseError);
});
});- Update README.md when adding features
- Add JSDoc comments to public APIs
- Include examples for complex functionality
- Update CHANGELOG.md following Keep a Changelog format
Releases are managed via release-please.
- Run the workflow: Go to Actions → "Release Please" → Run workflow
- Review the PR: release-please creates/updates a PR with changelog and version bump
- Merge the PR: This triggers the publish to npm
By default, release-please creates stable versions based on conventional commits:
feat:→ minor bump (0.1.0 → 0.2.0)fix:→ patch bump (0.1.0 → 0.1.1)feat!:orBREAKING CHANGE:→ major bump (0.1.0 → 1.0.0)
To create a prerelease version, add a commit with Release-As footer:
git commit --allow-empty -m "chore: prepare alpha release
Release-As: 1.1.0-alpha.0"
git pushThen run the workflow - the PR will have the specified prerelease version.
Before publishing, you can test the build output:
# Build all packages
pnpm nx run-many -t build
# Check what would be published
cd dist/packages/cli
pnpm pack --dry-run- Stable releases (1.0.0) → published as
latest - Prereleases (1.0.0-alpha.0) → published as
next
Install prerelease: npm install @promptscript/cli@next
Feel free to open an issue with the question label.
Thank you for contributing! 🙏