PHP Classes

How to Use a PHP Artificial Intelligence Prompt Manager with the Package Prompt Deck: Organize versioned artificial intelligence promts

Recommend this page to a friend!
     
  Info   Example   View files Files   Install with Composer Install with Composer   Download Download   Reputation   Support forum   Blog    
Last Updated Ratings Unique User Downloads Download Rankings
2026-03-07 (25 days ago) RSS 2.0 feedNot yet rated by the usersTotal: Not yet counted Not yet ranked
Version License PHP version Categories
prompt-deck 0.1MIT/X Consortium ...8Libraries, Artificial intelligence, P...
Description 

Author

This package can organize versioned artificial intelligence prompts.

It provides model classes that can store information on artificial intelligence prompts and multiple versions of each prompt.

The package also provides a middleware class that can track the handling and execution of a prompt.

Innovation Award
PHP Programming Innovation award nominee
March 2026
Nominee
Vote
The increasing popularity of artificial intelligence usage in applications brought new challenges.

Many developers are using multiple prompts in their applications.

This package provides a way to organize prompts that can be stored in a database using versioning to specify different versions of the same prompt.

Manuel Lemos
Picture of Victor John Ukam
  Performance   Level  
Name: Victor John Ukam is available for providing paid consulting. Contact Victor John Ukam .
Classes: 2 packages by
Country: United Kingdom
Age: 32
All time rank: Not yet ranked
Week rank: Not yet ranked
Innovation award
Innovation award
Nominee: 2x

Winner: 1x

Instructions

Example

<?php

declare(strict_types=1);

// =====================================================================
// prompt:list ? directory / prompt discovery
// =====================================================================

test('prompt:list warns when prompts directory does not exist', function () {
   
// Point config at a non-existent path.
   
$this->app['config']->set('prompt-deck.path', $this->tempDir.'/nonexistent');

   
$this->artisan('prompt:list')
        ->
expectsOutput('Prompts directory not found.')
        ->
assertSuccessful();
});

test('prompt:list shows info when directory exists but has no prompts', function () {
   
// tempDir exists but is empty ? no prompt subdirectories.
   
$this->artisan('prompt:list')
        ->
expectsOutput('No prompts found.')
        ->
assertSuccessful();
});

// =====================================================================
// prompt:list ? table output (default: active version only)
// =====================================================================

test('prompt:list displays prompts in a table', function () {
   
$this->createPromptFixture('greeting', 1, 'sys', 'usr', ['description' => 'A greeting prompt'], ['active_version' => 1]);

   
$this->artisan('prompt:list')
        ->
expectsTable(
            [
'Prompt', 'Active Version', 'Active', 'Description'],
            [[
'greeting', 'v1', '?', 'A greeting prompt']]
        )
        ->
assertSuccessful();
});

test('prompt:list shows multiple prompts sorted by directory order', function () {
   
$this->createPromptFixture('alpha', 1, 'sys', 'usr', null, ['active_version' => 1]);
   
$this->createPromptFixture('beta', 1, 'sys', 'usr', null, ['active_version' => 1]);

   
$this->artisan('prompt:list')
        ->
assertSuccessful();
});

test('prompt:list shows active version from metadata.json', function () {
   
$this->createPromptFixture('multi-ver', 1, 'sys v1', 'usr v1');
   
$this->createPromptFixture('multi-ver', 2, 'sys v2', 'usr v2');
   
$this->createPromptFixture('multi-ver', 3, 'sys v3', 'usr v3', null, ['active_version' => 2]);

   
$this->artisan('prompt:list')
        ->
expectsTable(
            [
'Prompt', 'Active Version', 'Active', 'Description'],
            [[
'multi-ver', 'v2', '?', '']]
        )
        ->
assertSuccessful();
});

test('prompt:list falls back to highest version when no active_version is set', function () {
   
$this->createPromptFixture('fallback', 1, 'sys', 'usr');
   
$this->createPromptFixture('fallback', 3, 'sys', 'usr');

   
$this->artisan('prompt:list')
        ->
expectsTable(
            [
'Prompt', 'Active Version', 'Active', 'Description'],
            [[
'fallback', 'v3', '?', '']]
        )
        ->
assertSuccessful();
});

test('prompt:list shows description from per-version metadata', function () {
   
$this->createPromptFixture('described', 1, 'sys', 'usr', ['description' => 'Version one desc'], ['active_version' => 1]);

   
$this->artisan('prompt:list')
        ->
expectsTable(
            [
'Prompt', 'Active Version', 'Active', 'Description'],
            [[
'described', 'v1', '?', 'Version one desc']]
        )
        ->
assertSuccessful();
});

test('prompt:list shows empty description when metadata has no description key', function () {
   
$this->createPromptFixture('no-desc', 1, 'sys', 'usr', ['author' => 'tester'], ['active_version' => 1]);

   
$this->artisan('prompt:list')
        ->
expectsTable(
            [
'Prompt', 'Active Version', 'Active', 'Description'],
            [[
'no-desc', 'v1', '?', '']]
        )
        ->
assertSuccessful();
});

// =====================================================================
// prompt:list --all ? shows every version per prompt
// =====================================================================

test('prompt:list --all shows all versions for each prompt', function () {
   
$this->createPromptFixture('chat', 1, 'sys v1', 'usr v1', ['description' => 'Initial']);
   
$this->createPromptFixture('chat', 2, 'sys v2', 'usr v2', ['description' => 'Improved']);
   
$this->createPromptFixture('chat', 3, 'sys v3', 'usr v3', ['description' => 'Latest'], ['active_version' => 2]);

   
$this->artisan('prompt:list', ['--all' => true])
        ->
expectsTable(
            [
'Prompt', 'Active Version', 'Active', 'Description'],
            [
                [
'chat', 'v1', '', 'Initial'],
                [
'chat', 'v2', '?', 'Improved'],
                [
'chat', 'v3', '', 'Latest'],
            ]
        )
        ->
assertSuccessful();
});

test('prompt:list --all marks only the active version with checkmark', function () {
   
$this->createPromptFixture('marker', 1, 'sys', 'usr', null, ['active_version' => 1]);
   
$this->createPromptFixture('marker', 2, 'sys', 'usr');

   
$this->artisan('prompt:list', ['--all' => true])
        ->
expectsTable(
            [
'Prompt', 'Active Version', 'Active', 'Description'],
            [
                [
'marker', 'v1', '?', ''],
                [
'marker', 'v2', '', ''],
            ]
        )
        ->
assertSuccessful();
});

test('prompt:list --all with multiple prompts lists all versions for each', function () {
   
$this->createPromptFixture('alpha', 1, 'sys', 'usr', null, ['active_version' => 1]);
   
$this->createPromptFixture('alpha', 2, 'sys', 'usr');
   
$this->createPromptFixture('beta', 1, 'sys', 'usr', null, ['active_version' => 1]);

   
$this->artisan('prompt:list', ['--all' => true])
        ->
assertSuccessful();
});

// =====================================================================
// Edge cases
// =====================================================================

test('prompt:list handles prompt with no version directories gracefully', function () {
   
// Create a prompt directory with no v* subdirectories.
   
mkdir("{$this->tempDir}/empty-prompt", 0755, true);

   
// getActiveVersion catches the exception and returns 0.
   
$this->artisan('prompt:list')
        ->
expectsTable(
            [
'Prompt', 'Active Version', 'Active', 'Description'],
            [[
'empty-prompt', 'v0', '?', '']]
        )
        ->
assertSuccessful();
});

test('prompt:list ignores non-directory items in the prompts path', function () {
   
// Create a file (not a directory) in the prompts path.
   
file_put_contents("{$this->tempDir}/readme.txt", 'Not a prompt');
   
$this->createPromptFixture('valid', 1, 'sys', 'usr', null, ['active_version' => 1]);

   
// glob with GLOB_ONLYDIR should skip the file.
   
$this->artisan('prompt:list')
        ->
expectsTable(
            [
'Prompt', 'Active Version', 'Active', 'Description'],
            [[
'valid', 'v1', '?', '']]
        )
        ->
assertSuccessful();
});

test('prompt:list returns success exit code', function () {
   
$this->createPromptFixture('exit-test', 1, 'sys', 'usr', null, ['active_version' => 1]);

   
$this->artisan('prompt:list')
        ->
assertExitCode(0);
});


Details

<p align="center"><img src="/docs/public/logo.svg" alt="Prompt Deck Logo"></p>

<p align="center"> <a href="https://packagist.org/packages/veeqtoh/prompt-deck"><img src="https://img.shields.io/packagist/v/veeqtoh/prompt-deck?style=flat-square" alt="Latest Version on Packagist"></a> <a href="https://packagist.org/packages/veeqtoh/prompt-deck"><img src="https://img.shields.io/packagist/dt/veeqtoh/prompt-deck?style=flat-square" alt="Total Downloads"></a> <a href="https://packagist.org/packages/veeqtoh/prompt-deck"><img src="https://img.shields.io/packagist/php-v/veeqtoh/prompt-deck?style=flat-square" alt="PHP from Packagist"></a> <a href="https://github.com/veeqtoh/prompt-deck/blob/master/LICENSE"><img src="https://img.shields.io/github/license/veeqtoh/prompt-deck?style=flat-square" alt="GitHub license"></a> </p>

Introduction

Prompt Deck helps you organise your AI Agents instructions as structured, version-controlled files, making it easy to iterate, compare, and activate prompt versions across your Laravel / PHP application. It provides variable interpolation, performance tracking, A/B testing, and optional seamless integration with the Laravel AI SDK.

Quick Start

Installation

composer require veeqtoh/prompt-deck

Publish the config and migrations

php artisan vendor:publish --provider="Veeqtoh\PromptDeck\Providers\PromptDeckServiceProvider"

# Run migrations.
php artisan migrate

Creating a Prompt

Use the Artisan command to create a versioned prompt

php artisan make:prompt order-summary

This creates the following structure

resources/prompts/
??? order-summary/
    ??? v1/
    ?   ??? system.md
    ??? metadata.json

Edit resources/prompts/order-summary/v1/system.md with your prompt content. Use {{ $variable }} syntax for dynamic values:

You are a {{ $tone }} customer service agent.
Summarise the following order for the customer: {{ $order }}.

Using a Prompt

Load and render prompts with the PromptDeck facade

use Veeqtoh\PromptDeck\Facades\PromptDeck;

// Load the active version of a prompt
$prompt = PromptDeck::get('order-summary');

// Render a role with variables
$prompt->system(['tone' => 'friendly', 'order' => $orderDetails]);
// "You are a friendly customer service agent. Summarise the following order..."

// Build a messages array ready for any chat-completion API
$messages = $prompt->toMessages(['tone' => 'friendly', 'order' => $orderDetails]);
// [['role' => 'system', 'content' => '...']]

Versioning

Create a new version of an existing prompt

php artisan make:prompt order-summary
# Automatically creates v2, v3, etc.

Activate a specific version

php artisan prompt:activate order-summary v2

Or load a specific version programmatically

$prompt = PromptDeck::get('order-summary', 'v2');

Laravel AI SDK Integration

If you use the Laravel AI SDK, add the HasPromptTemplate trait to your agents. This way, you do not need to define the instructions() method as it is provided automatically.

use Veeqtoh\PromptDeck\Concerns\HasPromptTemplate;

class OrderAgent extends Agent
{
    use HasPromptTemplate;

    // instructions() and promptMessages() are provided automatically
}

Running make:agent will also auto-scaffold a matching prompt directory.

For the complete guide, see the full documentation below.

Documentation

Full documentation can be found on the Prompt Deck website or the docs directory on GitHub.

Contributing

Thank you for considering contributing to Prompt Deck! Please open an issue or submit a pull request on GitHub.

Code of Conduct

While we aren't affiliated with Laravel, we follow the Laravel Code of Conduct. We expect you to abide by these guidelines as well.

Security Vulnerabilities

If you discover a security vulnerability within Prompt Deck, please email Victor Ukam at victorjohnukam@gmail.com. All security vulnerabilities will be addressed promptly.

License

Prompt Deck is open-sourced software licensed under the MIT license.

Support

This library is created by Victor Ukam with contributions from the Open Source Community. If you've found this package useful, please consider sponsoring this project. It will go along way to help with maintenance.


  Files folder image Files (65)  
File Role Description
Files folder image.github (3 files)
Files folder imageconfig (1 file)
Files folder imagedocs (9 files, 1 directory)
Files folder imagesrc (2 files, 9 directories)
Files folder imagestubs (3 files)
Files folder imagetests (2 files, 3 directories)
Accessible without login Plain text file composer.json Data Auxiliary data
Accessible without login Plain text file LICENSE Lic. License text
Accessible without login Plain text file phpunit.xml Data Auxiliary data
Accessible without login Plain text file pint.json Data Auxiliary data
Accessible without login Plain text file README.md Doc. Documentation

  Files folder image Files (65)  /  .github  
File Role Description
  Accessible without login Plain text file CODEOWNERS Data Auxiliary data
  Accessible without login Plain text file FUNDING.yml Data Auxiliary data
  Accessible without login Plain text file pull_request_template.md Data Auxiliary data

  Files folder image Files (65)  /  config  
File Role Description
  Accessible without login Plain text file prompt-deck.php Aux. Configuration script

  Files folder image Files (65)  /  docs  
File Role Description
Files folder imagepublic (1 file)
  Plain text file ai-sdk.md Class Class source
  Accessible without login Plain text file api-reference.md Data Auxiliary data
  Accessible without login Plain text file commands.md Data Auxiliary data
  Accessible without login Plain text file configuration.md Data Auxiliary data
  Accessible without login Plain text file installation.md Data Auxiliary data
  Accessible without login Plain text file make-prompt.md Data Auxiliary data
  Accessible without login Plain text file prompts.md Data Auxiliary data
  Plain text file testing.md Class Class source
  Accessible without login Plain text file tracking.md Data Auxiliary data

  Files folder image Files (65)  /  docs  /  public  
File Role Description
  Accessible without login Plain text file logo.svg Data Auxiliary data

  Files folder image Files (65)  /  src  
File Role Description
Files folder imageAi (1 file)
Files folder imageConcerns (1 file)
Files folder imageConsole (1 directory)
Files folder imagedatabase (2 directories)
Files folder imageExceptions (5 files)
Files folder imageFacades (1 file)
Files folder imageListeners (1 file)
Files folder imageModels (2 files)
Files folder imageProviders (1 file)
  Plain text file PromptManager.php Class Class source
  Plain text file PromptTemplate.php Class Class source

  Files folder image Files (65)  /  src  /  Ai  
File Role Description
  Plain text file TrackPromptMiddleware.php Class Class source

  Files folder image Files (65)  /  src  /  Concerns  
File Role Description
  Plain text file HasPromptTemplate.php Class Class source

  Files folder image Files (65)  /  src  /  Console  
File Role Description
Files folder imageCommands (5 files)

  Files folder image Files (65)  /  src  /  Console  /  Commands  
File Role Description
  Plain text file ActivatePromptCommand.php Class Class source
  Plain text file ListPromptsCommand.php Class Class source
  Plain text file MakePromptCommand.php Class Class source
  Plain text file PromptDiffCommand.php Class Class source
  Plain text file TestPromptCommand.php Class Class source

  Files folder image Files (65)  /  src  /  database  
File Role Description
Files folder imagefactories (2 files)
Files folder imagemigrations (2 files)

  Files folder image Files (65)  /  src  /  database  /  factories  
File Role Description
  Plain text file PromptExecutionFactory.php Class Class source
  Plain text file PromptVersionFactory.php Class Class source

  Files folder image Files (65)  /  src  /  database  /  migrations  
File Role Description
  Plain text file 2025_02_28_0000001...ompt_executions.php Class Class source
  Plain text file 2025_02_28_0000001...prompt_versions.php Class Class source

  Files folder image Files (65)  /  src  /  Exceptions  
File Role Description
  Plain text file ConfigurationException.php Class Class source
  Plain text file InvalidVersionException.php Class Class source
  Plain text file PromptDeckException.php Class Class source
  Plain text file PromptNotFoundException.php Class Class source
  Plain text file PromptRenderingException.php Class Class source

  Files folder image Files (65)  /  src  /  Facades  
File Role Description
  Plain text file PromptDeck.php Class Class source

  Files folder image Files (65)  /  src  /  Listeners  
File Role Description
  Plain text file AfterMakeAgent.php Class Class source

  Files folder image Files (65)  /  src  /  Models  
File Role Description
  Plain text file PromptExecution.php Class Class source
  Plain text file PromptVersion.php Class Class source

  Files folder image Files (65)  /  src  /  Providers  
File Role Description
  Plain text file PromptDeckServiceProvider.php Class Class source

  Files folder image Files (65)  /  stubs  
File Role Description
  Accessible without login Plain text file role-prompt.stub Data Auxiliary data
  Accessible without login Plain text file system-prompt.stub Data Auxiliary data
  Accessible without login Plain text file user-prompt.stub Data Auxiliary data

  Files folder image Files (65)  /  tests  
File Role Description
Files folder imageArchitecture (4 files)
Files folder imageFeature (4 files, 1 directory)
Files folder imageUnit (5 files)
  Plain text file Pest.php Class Class source
  Plain text file TestCase.php Class Class source

  Files folder image Files (65)  /  tests  /  Architecture  
File Role Description
  Plain text file ClassesTest.php Class Class source
  Accessible without login Plain text file GlobalsTest.php Example Example script
  Plain text file ModelsTest.php Class Class source
  Plain text file ProvidersTest.php Class Class source

  Files folder image Files (65)  /  tests  /  Feature  
File Role Description
Files folder imageCommands (5 files)
  Plain text file AfterMakeAgentTest.php Class Class source
  Plain text file MigrationTest.php Class Class source
  Plain text file PromptDeckFacadeTest.php Class Class source
  Plain text file PromptDeckServiceProviderTest.php Class Class source

  Files folder image Files (65)  /  tests  /  Feature  /  Commands  
File Role Description
  Plain text file ActivatePromptCommandTest.php Class Class source
  Accessible without login Plain text file ListPromptsCommandTest.php Example Example script
  Plain text file MakePromptCommandTest.php Class Class source
  Plain text file PromptDiffCommandTest.php Class Class source
  Accessible without login Plain text file TestPromptCommandTest.php Example Example script

  Files folder image Files (65)  /  tests  /  Unit  
File Role Description
  Plain text file ExceptionsTest.php Class Class source
  Plain text file HasPromptTemplateTest.php Class Class source
  Plain text file PromptManagerTest.php Class Class source
  Plain text file PromptTest.php Class Class source
  Plain text file TrackPromptMiddlewareTest.php Class Class source

The PHP Classes site has supported package installation using the Composer tool since 2013, as you may verify by reading this instructions page.
Install with Composer Install with Composer
 Version Control Unique User Downloads  
 100%
Total:0
This week:0