Skip to content

Build Your Registry

PromptScript supports registries - collections of reusable configurations that can be inherited across projects. Each organization creates and manages their own registry, giving full control over AI instruction standards.

Quick Start

1. Create a Registry

prs registry init my-company-registry

This scaffolds a complete registry with starter configurations. See Creating a Registry for details.

2. Configure Your Project

Add to your promptscript.yaml:

registry:
  git:
    url: https://github.com/your-org/your-registry.git
    ref: main # Or pin to version: v1.0.0

2. Inherit Configurations

@meta {
  id: "my-project"
  syntax: "1.0.0"
}

@inherit @stacks/react
@use @fragments/testing

Try in Playground

3. Compile

prs compile  # Automatically fetches registry and generates output

Note: When using a Git registry, the CLI automatically clones and caches the repository. You don't need to run prs pull separately - the compile and validate commands handle this automatically.

The registry is cached at ~/.promptscript/.cache/git/ with a default TTL of 1 hour. Use prs pull --refresh to force an update.

Using prs init

The prs init command can connect to your registry and suggest configurations:

prs init

It will:

  1. Detect your tech stack (React, Node, Python, etc.)
  2. Offer to connect to a Git or local registry
  3. Suggest relevant configurations from your registry's catalog
  4. Generate your promptscript.yaml and .promptscript/project.prs

You can also set a default registry via user-level config so prs init --yes automatically uses it.

How Overlay-Aware Suggestions Work

When your registry catalogs Layer 2 / Layer 3 skill overlays, prs init collapses overlay relationships before showing the picker so you don't see both the base skill and its overlay as separate choices.

Detection works two ways:

  1. Manifest extends field — when a skill entry in registry-manifest.yaml declares extends: <base-skill-id>, the suggestion engine treats it as an overlay of that base.
  2. Inline @extend scan — when no manifest hint exists, the engine scans the suggested skill's .prs source for @use … as <alias> plus @extend <alias>.skills.<name> and resolves the base skill via the alias map.

When an overlay is detected and both the overlay and its base were suggested, the base is removed from the choices. The overlay choice is annotated inline:

? Select skills to add: (Use space to select, enter to confirm)
  ◉ @stacks/react (use)
  ◉ @skills/code-review (extends @skills/code-review-base) (skill)
  ◉ @skills/security-review (skill)

The (extends …) annotation makes it explicit which base the overlay is layering on top of, so reviewers can audit the chain at a glance. If your registry doesn't yet declare extends, populate the field in registry-manifest.yaml to get the cleanest experience:

catalog:
  - id: '@skills/code-review-base'
    description: 'Generic code-review base skill'
  - id: '@skills/code-review'
    description: 'Org-specific code-review overlay (banking compliance)'
    extends: '@skills/code-review-base'

See Skill Overlays for the overlay model itself, and the Registry Manifest section below for the full schema.

Usage Patterns

Pattern 1: Inherit a Tech Stack

@meta { id: "react-app" syntax: "1.0.0" }

@inherit @stacks/react

Try in Playground

Pattern 2: Mix in Fragments

@meta { id: "secure-app" syntax: "1.0.0" }

@inherit @stacks/node
@use @fragments/testing
@use @fragments/security/owasp-security-review

Try in Playground

Pattern 3: Use Prompts Directly

@meta { id: "terminal" syntax: "1.0.0" }

@inherit @prompts/coding/linux-terminal

Try in Playground

How Git Registry Resolution Works

When you configure a Git registry, the CLI handles everything automatically:

  1. On first use: The registry is cloned to ~/.promptscript/.cache/git/<hash>/
  2. On subsequent uses: The cached version is used if not stale (default: 1 hour TTL)
  3. On cache expiry: The registry is updated with git fetch
prs init --yes
Creates config with registry.git.url

prs compile
resolveRegistryPath() → checks cache validity
If stale/missing: GitRegistry.fetch() → clone/update
Compiler uses cached registry path

Cache Configuration

Control caching behavior in promptscript.yaml:

registry:
  git:
    url: https://github.com/your-org/your-registry.git
    ref: main
  cache:
    enabled: true # Set to false to always fetch
    ttl: 3600000 # Cache TTL in ms (default: 1 hour)

Force Refresh

prs pull --refresh  # Force re-clone the registry

Version Pinning

Pin to a specific version for stability:

registry:
  git:
    ref: v1.0.0

Or in .prs files:

@inherit @stacks/react@1.0.0

Try in Playground


Creating a Registry

Use the prs registry init command to scaffold a new registry:

prs registry init my-registry

This creates the full directory structure, manifest, and optional seed configurations.

Interactive Mode

prs registry init my-registry
# Prompts for: name, description, namespaces, seed configs

Non-Interactive Mode

prs registry init my-registry --yes --name "My Company Registry" --namespaces @core @stacks @fragments

Skip Seed Configs

prs registry init my-registry --no-seed

Registry Structure

my-registry/
├── registry-manifest.yaml    # Catalog of all configurations
├── @core/
│   └── base.prs
├── @roles/
│   └── developer/
│       └── fullstack.prs
├── @stacks/
│   └── react.prs
└── @fragments/
    └── testing.prs

Registry Manifest

The registry-manifest.yaml file catalogs all configurations and enables prs init suggestions:

version: '1'

meta:
  name: 'My Company Registry'
  description: 'Internal AI instruction configurations'
  lastUpdated: '2025-01-28'

namespaces:
  '@core':
    description: 'Universal foundations'
    priority: 100
  '@roles':
    description: 'AI personas'
    priority: 90
  '@stacks':
    description: 'Tech stack configurations'
    priority: 80
  '@fragments':
    description: 'Reusable mixins'
    priority: 70

catalog:
  - id: '@core/base'
    path: '@core/base.prs'
    name: 'Base Foundation'
    description: 'Universal AI assistant foundation'
    tags: [core, foundation]
    targets: [github, claude, cursor]
    dependencies: []
    detectionHints:
      always: true

  - id: '@stacks/react'
    path: '@stacks/react.prs'
    name: 'React Stack'
    description: 'React + TypeScript configuration'
    tags: [react, typescript, frontend]
    targets: [github, claude, cursor]
    dependencies: ['@core/base']
    detectionHints:
      dependencies: ['react', 'react-dom']
      frameworks: ['react', 'nextjs']

suggestionRules:
  - condition: { always: true }
    suggest: { inherit: '@core/base' }
  - condition: { frameworks: ['react'] }
    suggest: { inherit: '@stacks/react', use: ['@fragments/testing'] }

Manifest Fields

catalog Entry Fields

Field Required Description
id Yes Unique ID matching file path
path Yes Path to the .prs file
name Yes Human-readable name
description Yes Brief description
tags Yes Searchable tags
targets No Supported targets (github, claude, etc.)
dependencies No Required configurations
detectionHints No Auto-suggestion hints (see below)

detectionHints Fields

Field Description
always Always suggest this configuration
files Suggest if these files exist
dependencies Suggest if package.json has these dependencies
languages Suggest for these languages
frameworks Suggest for these frameworks

Using Your Registry

Git Registry

Host on GitHub, GitLab, or any Git provider:

registry:
  git:
    url: https://github.com/your-org/your-registry.git
    ref: main

Local Registry

For development or air-gapped environments:

registry:
  path: ./path/to/registry

Validating a Registry

Use prs registry validate to check your registry structure:

prs registry validate ./my-registry

Validation checks:

  • registry-manifest.yaml exists and parses correctly
  • Manifest schema is valid (version, meta, namespaces, catalog)
  • All catalog entry .prs files exist
  • Catalog IDs match declared namespaces
  • No circular dependencies
  • Warns about orphaned .prs files not in catalog

Use --strict to treat warnings as errors:

prs registry validate ./my-registry --strict

Use --format json for machine-readable output:

prs registry validate ./my-registry --format json

Publishing a Registry

Use prs registry publish to commit and push registry updates:

prs registry publish ./my-registry

This will:

  1. Validate the registry (use --force to skip)
  2. Update meta.lastUpdated in the manifest
  3. Stage, commit, and push changes

Options:

prs registry publish ./my-registry --dry-run              # Preview without publishing
prs registry publish ./my-registry -m "Add React stack"    # Custom commit message
prs registry publish ./my-registry --tag v1.0.0            # Tag the release
prs registry publish ./my-registry --force                 # Skip validation

CI/CD Integration

Add registry validation to your CI pipeline:

# .github/workflows/registry.yml
name: Registry CI
on: [push, pull_request]
jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm install -g @promptscript/cli
      - run: prs registry validate --strict

Next Steps


Registry Aliases

Registry aliases let you define short names for Git repository URLs so that imports stay readable and organization-wide base URLs are configured in one place.

Configuring Aliases

Aliases are defined in the registries field of promptscript.yaml (project scope) or ~/.promptscript/config.yaml (user scope):

# promptscript.yaml
registries:
  '@company': github.com/acme/promptscript-base
  '@team': github.com/acme/team-frontend

Use any scoped name as the key. The value is a bare Git host path - no https:// prefix required.

Three-Level Merge

Aliases are merged from three sources in priority order (highest first):

  1. Project - promptscript.yaml in the repo (team-specific overrides)
  2. User - ~/.promptscript/config.yaml (developer preferences)
  3. System - /etc/promptscript/config.yaml (IT-provisioned defaults)

Project aliases win over user aliases, which win over system aliases. This lets IT provision company-wide aliases while still allowing projects to override specific ones.

Using Aliases in .prs Files

Once configured, use the alias as the scope prefix in any import:

@meta { id: "my-project" syntax: "1.0.0" }

# Resolves to github.com/acme/promptscript-base/@org/base.prs
@inherit @company/@org/base

# Resolves to github.com/acme/team-frontend/@stacks/react.prs
@use @team/@stacks/react

Try in Playground


Go-Style URL Imports

Beyond registry aliases, PromptScript supports Go-module-style bare URL imports. You can reference any Git repository directly by its host path - no alias required.

Basic URL Import

@meta { id: "my-project" syntax: "1.0.0" }

# Import directly from a public GitHub repo
@use github.com/acme/shared-standards/@fragments/security

# Import from any Git host
@use gitlab.com/myorg/prompts/@stacks/python

Try in Playground

Version Pinning in URL Imports

Append a version specifier with @:

# Pin to an exact tag
@use github.com/acme/shared-standards/@org/base@1.2.0

# Pin to a semver range (latest patch in 1.x)
@use github.com/acme/shared-standards/@org/base@^1.0.0

# Pin to a branch
@use github.com/acme/shared-standards/@org/base@main

Try in Playground

Specifier Meaning
@1.2.0 Exact tag v1.2.0 or 1.2.0
@^1.0.0 Latest tag matching ^1.0.0 (semver)
@main Tip of branch main
(none) Default branch as configured

Alias vs URL Import

Style Example When to Use
Alias @use @company/security Frequently-used internal packages
Full URL @use github.com/acme/security One-off external imports
Versioned URL @use github.com/acme/security@^1.0.0 Reproducible external dependencies

Auto-Discovery

When you import a repository that does not contain .prs files, PromptScript looks for native AI plugin files and converts them automatically. This means you can @use any GitHub repository that contains SKILL.md, agent definitions, or command files - even if it was not authored with PromptScript.

What Gets Auto-Discovered

Source File Pattern Imported As
SKILL.md in root or skills/ directory @skills block
.claude/agents/*.md @agents block
.claude/commands/*.md @shortcuts block
.github/skills/*/SKILL.md @skills block

Example: Importing an Open-Source Skill Library

@meta { id: "my-project" syntax: "1.0.0" }

# This repo has a SKILL.md but no .prs files - auto-discovered
@use github.com/some-org/claude-skills/skills/tdd-workflow

Try in Playground

PromptScript fetches the repository, detects the SKILL.md, and synthesizes a virtual .prs fragment that you can merge into your project just like any other import.

Zero Config Required

Auto-discovery works without any setup in the remote repo. The remote maintainer does not need to know about PromptScript.


Lockfile

PromptScript generates a promptscript.lock file to record the exact resolved commit for every remote import. This gives you reproducible builds - the same source always produces the same output, regardless of when you compile.

Generating the Lockfile

prs lock            # Create or update promptscript.lock
prs lock --dry-run  # Show what would change without writing

The lockfile is also written automatically during prs compile when remote imports are present.

Lockfile Format

# promptscript.lock
version: 1
packages:
  github.com/acme/promptscript-base:
    url: https://github.com/acme/promptscript-base.git
    ref: main
    commit: a3f8c2d91b4e6f7890123456789abcdef0123456
    resolved: '2026-03-23T10:00:00Z'
    references:
      '@stacks/react.prs':
        hash: sha256:a1b2c3d4e5f6...
      '@fragments/testing.prs':
        hash: sha256:f6e5d4c3b2a1...
  github.com/some-org/claude-skills:
    url: https://github.com/some-org/claude-skills.git
    ref: v1.2.0
    commit: deadbeef12345678901234567890abcdef012345
    resolved: '2026-03-22T08:30:00Z'
    references:
      'skills/tdd-workflow/SKILL.md':
        hash: sha256:1234abcd5678...

Integrity Hashes

Each lockfile entry includes SHA-256 hashes for the individual files resolved from that package. During compilation and validation, these hashes are verified against the actual file contents. If a file has been modified since it was locked, a reference integrity error is raised.

This protects against:

  • Tampered dependencies - changes to registry files after locking
  • Cache corruption - stale or corrupted cached copies
  • Supply chain attacks - unauthorized modifications to shared skills

To skip hash verification (e.g., during local development), use:

prs compile --ignore-hashes
prs validate --ignore-hashes

Warning

Never use --ignore-hashes in CI pipelines. Hash verification is a critical security check for production builds.

Committing the Lockfile

Commit promptscript.lock to version control. This ensures:

  • Reproducible builds - CI always compiles against the same commits
  • Auditable deps - diffs show exactly when a dependency was updated
  • Offline support - works with prs vendor sync (see below)

Updating Dependencies

# Update a specific package to its latest allowed version
prs update github.com/acme/promptscript-base

# Update all packages
prs update

# Preview updates without writing
prs update --dry-run

Vendor Mode

Vendor mode copies all remote dependencies into a local .promptscript/vendor/ directory. This enables fully offline builds - useful in air-gapped CI environments or when you want to audit third-party content before it runs.

Syncing the Vendor Directory

# Download all lockfile-resolved packages to vendor/
prs vendor sync

# Check that vendor/ is in sync with the lockfile
prs vendor check

After running prs vendor sync, compilation never performs network requests. The vendor directory is used as-is.

Vendor Directory Structure

.promptscript/
└── vendor/
    ├── github.com/
    │   ├── acme/
    │   │   └── promptscript-base/
    │   │       ├── @org/base.prs
    │   │       └── @org/security.prs
    │   └── some-org/
    │       └── claude-skills/
    │           └── skills/
    │               └── tdd-workflow/
    │                   └── SKILL.md
    └── .vendor-manifest.yaml

CI Pipeline with Vendor

# .github/workflows/promptscript.yml
- name: Sync vendor
  run: prs vendor sync

- name: Validate
  run: prs vendor check && prs validate --strict

- name: Compile
  run: prs compile

Commit the vendor directory to your repository if you want fully self-contained, network-free builds. Otherwise, regenerate it in CI from the lockfile.


Private Repositories

SSH Authentication

PromptScript uses your existing SSH keys automatically for git@ URLs:

registries:
  '@company': git@github.com:acme/promptscript-base

Or in URL imports:

@use git@github.com:acme/private-skills/@fragments/security

Try in Playground

Ensure your SSH key is added to ssh-agent or configured in ~/.ssh/config.

Token Authentication (GITHUB_TOKEN)

For HTTPS URLs, configure a token in your registry entry:

# promptscript.yaml
registry:
  git:
    url: https://github.com/acme/promptscript-base.git
    ref: main
    auth:
      type: token
      tokenEnvVar: GITHUB_TOKEN

The tokenEnvVar field names the environment variable that holds the token - it is never stored in plain text.

User-Level Token Configuration

Set up credentials once in ~/.promptscript/config.yaml and they apply to all projects:

# ~/.promptscript/config.yaml
registries:
  '@company': github.com/acme/promptscript-base

auth:
  github.com:
    type: token
    tokenEnvVar: GITHUB_TOKEN
  gitlab.com:
    type: token
    tokenEnvVar: GITLAB_TOKEN

CI Configuration

# .github/workflows/promptscript.yml
- name: Compile
  run: prs compile
  env:
    GITHUB_TOKEN: ${{ secrets.REGISTRY_TOKEN }}