Skip to content

Migration Guide

This guide helps you migrate existing AI instructions to PromptScript.

Upgrading an existing PromptScript project?

This guide converts third-party instruction files into PromptScript. Existing PromptScript 1.15 projects should use Upgrade 1.15 to 1.16.

Choose a Migration Command

Need Command
Convert all detected project instructions prs migrate --static --dry-run
Generate an AI-assisted migration prompt prs migrate --llm
Convert one known file prs import <file> --dry-run
Upgrade existing .prs syntax prs upgrade --dry-run

Prefer prs migrate for project adoption. Use prs import as a lower-level single-file tool.

Overview

PromptScript can consolidate instructions from multiple sources:

flowchart LR
    subgraph Sources["Existing Files"]
        A[".github/copilot-instructions.md"]
        B["CLAUDE.md"]
        C[".cursorrules"]
        D["Custom docs"]
    end

    subgraph PS["PromptScript"]
        E["project.prs"]
    end

    subgraph Output["Generated"]
        F[".github/copilot-instructions.md"]
        G["CLAUDE.md"]
        H[".cursorrules"]
    end

    A --> E
    B --> E
    C --> E
    D --> E
    E --> F
    E --> G
    E --> H

Step 1: Analyze Existing Instructions

Gather Current Files

Collect all existing AI instruction files:

# Common locations
cat .github/copilot-instructions.md
cat CLAUDE.md
cat .cursorrules
cat AGENTS.md
cat AI_INSTRUCTIONS.md

Identify Content Categories

Map your content to PromptScript blocks:

Content Type PromptScript Block
Identity/persona @identity
Project context @context
Coding standards @standards
Don'ts/restrictions @restrictions
Custom commands @shortcuts
Reference docs @knowledge
Configuration @params

Example Analysis

Existing CLAUDE.md:

# Project Instructions

You are a senior developer working on the checkout service.

## Tech Stack

- Node.js 20
- TypeScript
- PostgreSQL

## Standards

- Use functional programming
- Write tests for all code
- Document public APIs

## Don'ts

- Never commit secrets
- Don't use var

## Commands

/test - Run tests
/lint - Run linter

Mapped to:

  • Identity: "You are a senior developer..."
  • Context: Tech stack section
  • Standards: Standards section
  • Restrictions: Don'ts section
  • Shortcuts: Commands section

Step 2: Create PromptScript Structure

Initialize Project

prs init

Create Base Structure

# .promptscript/project.prs
@meta {
  id: "checkout-service"
  syntax: "1.0.0"
}

# Content will be added in next steps

Try in Playground

Step 3: Migrate Content

Identity Block

You are a senior developer working on the checkout service.
Focus on clean, maintainable code.
@identity {
  """
  You are a senior developer working on the checkout service.
  Focus on clean, maintainable code.
  """
}

Try in Playground

Context Block

## Tech Stack

- Node.js 20
- TypeScript
- PostgreSQL
- Redis for caching
@context {
  stack: {
    runtime: "Node.js 20"
    language: "TypeScript"
    database: "PostgreSQL"
    cache: "Redis"
  }

  """
  The checkout service handles payment processing
  and order management for the e-commerce platform.
  """
}

Try in Playground

Standards Block

## Coding Standards

- Use functional programming patterns
- Write tests for all code (80% coverage)
- Document public APIs with JSDoc
- Use ESLint and Prettier
@standards {
  code: [
    "Use functional programming style",
    "Write tests for all code (80% coverage)",
    "Document public APIs with JSDoc",
    "Use ESLint and Prettier"
  ]
}

Try in Playground

Restrictions Block

## Don'ts

- Never commit secrets or credentials
- Don't use `var`, use `const` or `let`
- Never bypass code review
@restrictions {
  - "Never commit secrets or credentials"
  - "Don't use var, use const or let"
  - "Never bypass code review"
}

Try in Playground

Shortcuts Block

## Commands

- /test - Run the test suite
- /lint - Run ESLint
- /build - Build for production
@shortcuts {
  "/test": "Run the test suite with coverage"
  "/lint": "Run ESLint and fix issues"
  "/build": "Build for production deployment"
}

Try in Playground

Knowledge Block

## API Reference

### Authentication

- POST /auth/login
- POST /auth/logout

### Orders

- GET /orders
- POST /orders
@knowledge {
  """
  ## API Reference

  ### Authentication
  - POST /auth/login
  - POST /auth/logout

  ### Orders
  - GET /orders - List orders
  - POST /orders - Create order
  """
}

Try in Playground

Step 4: Complete Migration

Full Example

# Checkout Service

You are a senior developer working on the checkout service.

## Tech Stack

- Node.js 20
- TypeScript
- PostgreSQL

## Standards

- Use functional programming
- Write tests (80% coverage)
- Document public APIs

## Don'ts

- Never commit secrets
- Don't use var

## Commands

/test - Run tests
/lint - Run linter

## API Reference

### Orders

- GET /orders
- POST /orders
@meta {
  id: "checkout-service"
  syntax: "1.0.0"
}

@identity {
  """
  You are a senior developer working on the checkout service.
  """
}

@context {
  stack: {
    runtime: "Node.js 20"
    language: "TypeScript"
    database: "PostgreSQL"
  }
}

@standards {
  code: [
    "Use functional programming style",
    "Write tests for all code (80% coverage)",
    "Document public APIs with JSDoc"
  ]
}

@restrictions {
  - "Never commit secrets"
  - "Don't use var"
}

@shortcuts {
  "/test": "Run the test suite"
  "/lint": "Run ESLint"
}

@knowledge {
  """
  ## API Reference

  ### Orders
  - GET /orders - List orders
  - POST /orders - Create order
  """
}

Try in Playground

Step 5: Configure and Compile

Update Configuration

# promptscript.yaml
id: my-project
syntax: '1.4.0'

input:
  entry: .promptscript/project.prs

targets:
  - github:
      output: .github/copilot-instructions.md
  - claude:
      output: CLAUDE.md
  - cursor:
      output: .cursor/rules/project.mdc

Compile and Compare

Before PromptScript takes ownership of existing instruction files, create a recoverable baseline. Tracked files are recoverable from the migration branch. Back up any untracked or ignored instruction files outside configured output paths, or copy them into a local migration-backup directory that will not be committed.

# Confirm every planned output and ownership conflict.
prs compile --dry-run

# Compare complete planned output with existing files.
prs diff --all --full

Review source parity, target-specific omissions, file modes, and every conflict path. Do not delete an existing configured target merely to bypass ownership protection. When all planned outputs and backups are approved, perform one controlled takeover:

prs validate --strict
prs compile --force
git diff -- .
prs diff --all --full

The final PromptScript diff must be empty. The Git diff must contain only approved generated replacements and migration source or configuration. Restore from version control or backup if the result loses user-owned content.

Step 6: Update Git

Keep Generated Files Tracked

git add .promptscript/ promptscript.yaml
git add .github/copilot-instructions.md CLAUDE.md .cursor/rules/project.mdc
git commit -m "chore: migrate AI instructions to PromptScript"

This lets CI detect drift between PromptScript sources and generated outputs. If your team prefers to generate outputs locally, adopt one consistent ignored-output workflow only after the controlled compile above has created and verified every configured target:

printf '%s\n' \
  '.github/copilot-instructions.md' \
  'CLAUDE.md' \
  '.cursor/rules/project.mdc' >> .gitignore
git rm --cached .github/copilot-instructions.md CLAUDE.md .cursor/rules/project.mdc
git add .gitignore .promptscript/ promptscript.yaml
git commit -m "chore: migrate AI instructions to PromptScript"

git rm --cached stops tracking these files but keeps the verified working-tree copies. It is not a workaround for overwrite conflicts and must not run before the takeover review.

Migration Patterns

Merging Multiple Sources

If you have different instructions in different files:

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

# From copilot-instructions.md
@identity {
  """
  Content from GitHub Copilot instructions...
  """
}

# From CLAUDE.md
@context {
  """
  Content from Claude instructions...
  """
}

# From .cursorrules
@standards {
  # Rules from Cursor...
}

Try in Playground

Extracting Common Patterns

If you have similar instructions across projects, extract to registry:

# registry/@company/base.prs
@meta {
  id: "@company/base"
  syntax: "1.0.0"
}

@standards {
  # Common standards...
}

@restrictions {
  # Common restrictions...
}

Try in Playground

Then inherit:

# Project file
@inherit @company/base

@context {
  # Project-specific context
}

Try in Playground

Handling Tool-Specific Content

Some content may be specific to certain tools:

# Most content is shared
@identity {
  """
  Shared identity...
  """
}

# Tool-specific might need adjustment
# Consider using params for variations
@params {
  tool?: enum("copilot", "claude", "cursor")
}

Try in Playground

Advanced Block Migration

@skills Block

Skills define reusable capabilities for AI agents:

## Skills

### Code Review

When reviewing code:

1. Check for type safety
2. Verify error handling
3. Ensure tests exist

### Deployment

Steps to deploy:

1. Build the project
2. Run tests
3. Deploy to staging
@skills {
  code-review: {
    description: "Review code for quality and best practices"
    content: """
      When reviewing code:
      1. Check for type safety
      2. Verify error handling
      3. Ensure tests exist
    """
  }

  deployment: {
    description: "Deploy the application"
    content: """
      Deployment process:
      1. Build the project
      2. Run tests
      3. Deploy to staging
    """
  }
}

Try in Playground

@agents Block

Define specialized AI subagents:

# Code Reviewer

Reviews code for quality.

Tools: Read, Grep, Bash
Model: claude-sonnet

Instructions:
Review code checking for type safety and error handling.
@agents {
  code-reviewer: {
    description: "Reviews code for quality and best practices"
    tools: ["Read", "Grep", "Bash"]
    model: "sonnet"
    content: """
      Review code checking for:
      - Type safety
      - Error handling
      - Test coverage
    """
  }
}

Try in Playground

@local Block

Private instructions not committed to version control:

# Local Development

- API endpoint: http://localhost:8080
- Debug mode enabled
- Use staging database
@local {
  apiEndpoint: "http://localhost:8080"
  debugMode: true

  """
  Local development notes:
  - Use staging database for testing
  - Mock external services
  """
}

Try in Playground

@guards Block with Globs

File-specific rules using glob patterns:

---
applyTo: src/components/**/*.tsx
---

# Component Guidelines

Use functional components with TypeScript.
@guards {
  globs: ["src/components/**/*.tsx"]

  """
  Component Guidelines:
  - Use functional components
  - Include TypeScript types
  - Add unit tests
  """
}

Try in Playground

@guards Named Entries

For projects with multiple .github/instructions/*.instructions.md files — each with different applyTo patterns — use named entries in @guards to preserve the one-file-per-rule-set structure:

---
applyTo: apps/admin/**/*.ts
---

# Angular Component Standards

Use OnPush change detection for all components.
Always implement OnDestroy for cleanup.
@meta { id: "named-guards-migration" syntax: "1.0.0" }

@guards {
  angular-components: {
    applyTo: ["apps/admin/**/*.ts"]
    description: "Angular component coding standards"
    content: """
    Use OnPush change detection for all components.
    Always implement OnDestroy for cleanup.
    """
  }
}

Try in Playground

Each named entry generates a separate .github/instructions/<name>.instructions.md file with the corresponding applyTo frontmatter. This is the recommended approach when migrating multiple instruction files — prs import can detect and convert these files automatically.

@params Block

Configurable parameters with types:

## Configuration

- Verbosity: 1-5 (default: 3)
- Output format: json | text | markdown
- Strict mode: on/off
@params {
  verbosity: range(1..5) = 3
  format?: enum("json", "text", "markdown") = "text"
  strict: boolean = false
}

Try in Playground

@extend Block

Modify inherited blocks at specific paths:

@inherit @company/base

# Add to existing identity
@extend identity {
  """
  Additional expertise in React development.
  """
}

# Modify nested standards
@extend standards.code.testing {
  framework: "vitest"
  coverage: 90
}

# Add to restrictions array
@extend restrictions {
  - "Use functional components only"
  - "No class-based components"
}

Try in Playground

Choose modification syntax by migration intent:

  • Keep @extend when old and new values should merge or append.
  • Keep field! as a compatibility form for replacing one direct regular field inside @extend.
  • Use @override with syntax 1.5.0 when one complete existing block or nested value must replace the previous value.
@meta { id: "migrated-project" syntax: "1.5.0" }

@standards {
  testing: ["Use Jest", "Use Mocha"]
}

@override standards.testing {
  ["Use Vitest"]
}

Try in Playground

Unlike field!, @override requires the complete target path to exist. It cannot bypass sealed skill properties.

Validation Checklist

After migration, verify:

  • prs validate passes without errors
  • prs compile generates all targets
  • Generated files match expected content
  • No duplicate or conflicting instructions
  • All custom commands work in each tool
  • Team members can compile locally

Common Issues

Missing Metadata

Error: @meta block is required

Add required @meta block with id and syntax.

Invalid Syntax

Error: Unexpected token at line 15

Check PromptScript syntax, especially:

  • Colons after property names
  • Proper string quoting
  • Array/object brackets

Multiline Strings in Objects

Multiline strings cannot be loose inside objects:

# ❌ Invalid
@standards {
  code: {
    style: "clean"
    """
    Additional notes...
    """
  }
}

# ✅ Valid - assign to a key
@standards {
  code: {
    style: "clean"
    notes: """
      Additional notes...
    """
  }
}

Try in Playground

Content Loss

If compiled output is missing content:

  1. Check block names are correct
  2. Verify no syntax errors in blocks
  3. Use --verbose flag for debugging

AI-Assisted Migration

For automated migration using AI assistants, PromptScript installs its bundled promptscript skill, which includes migration guidance.

Using the PromptScript Skill

Claude Code:

# Use the PromptScript skill
/promptscript

# Or ask directly
"migrate my existing instructions to PromptScript"

GitHub Copilot:

Ask Chat to use the promptscript skill and migrate the existing instruction files.

Cursor:

Use Composer with migration context or reference the PromptScript migration documentation.

What the AI Will Do

  1. Discover existing instruction files (CLAUDE.md, .cursorrules, copilot-instructions.md)
  2. Analyze content and classify into PromptScript blocks
  3. Generate properly structured PromptScript files
  4. Validate the output with prs validate

Best Practices for AI Migration

For detailed guidelines on AI-assisted migration, including content mapping patterns and common pitfalls, see AI Migration Best Practices.

Next Steps

After migration:

  1. Set up inheritance if you have multiple projects
  2. Organize multi-file setup for complex projects
  3. Configure CI/CD for validation
  4. Train team on PromptScript workflow