4.1 KiB
PromptVault
A local-first prompt library for LLM workflows. Store, organize, search,
and reuse prompt templates with {{variable}} placeholders — fill in the
variables, see the rendered result live, and copy the final text when you're
done. No accounts, no cloud, no external LLM calls: everything runs locally.
Features
- Prompt templates — create, edit, and delete prompts with
{{variable}}placeholders (strict rendering: only declared variables are accepted, unknown ones are left untouched). - Live preview — type into the generated variable inputs and watch the rendered output update as you type.
- Use a prompt — server-side render with validation; if a variable is missing you get a 422 plus the exact list of missing variables.
- Tags — free-form, normalized (lowercased) tags with suggestions and tag-based filtering.
- Favorites, duplicates, clipboard — star prompts, clone one (stats reset), copy the template text.
- Catalog controls — full-text search, tag/favorites filters, sorting (name, created, last used), 10-per-page pagination.
Tech stack
| Layer | Technology |
|---|---|
| Backend | Laravel 13 (PHP 8.3+) |
| Database | SQLite (zero-config, local file) |
| Frontend | Vue 3 + Inertia 3 (@inertiajs/vue3) |
| Styling | Tailwind CSS 4 |
| Build | Vite 8 |
| Tests | PHPUnit 12 (PHP, Xdebug coverage) · Vitest 5 (JS, v8 coverage) |
Getting started
Requirements: PHP 8.3+, Composer, Node 20+ (any recent LTS).
# Install PHP + JS dependencies, create .env, generate key, migrate, build
composer setup
…or manually:
composer install
npm install
cp .env.example .env
php artisan key:generate
php artisan migrate --force
Then run the app (two terminals):
php artisan serve # → http://localhost:8000 (redirects to /prompts)
npm run dev # Vite dev server with HMR
Testing
The application code (app/ + resources/js/) is tested to ≥ 95% code
coverage (vendor excluded).
PHP (unit + feature tests of app/):
vendor/bin/phpunit # run the suite
XDEBUG_MODE=coverage ./vendor/bin/phpunit --coverage-text # with coverage
Current state: 60 tests, 522 assertions, all green — 99.05% line coverage.
JavaScript (Vitest + Vue Test Utils under tests/js/, Inertia mocked via
a shared stub):
npm run test:js # run the suite
npm run test:js:coverage # with coverage (v8 provider)
Current state: 64 tests across 10 files, all green — 100% line coverage (99.57% statements, 96.31% branches, 98.82% functions).
Disclosed exclusions (see SPECS.md): resources/js/app.js is Vite/Inertia
entry wiring; two defensive preg_*-failure guards in PromptRenderer are
unreachable with the app's static pattern and deliberately uncovered.
Project layout
app/
Actions/Prompts/ # CQRS-lite actions: ListPrompts, StorePrompt, UpdatePrompt
Exceptions/ # PromptRenderException
Http/Controllers/ # PromptController (thin — delegates to services)
Http/Requests/ # StorePromptRequest, UpdatePromptRequest, PromptFormRequest
Models/ # Prompt, Tag
Services/ # PromptService (writes), PromptCatalog (reads), PromptRenderer (pure)
resources/js/
Components/ # PromptForm, RenderPreview, ConfirmDialog, TagPill
Layouts/AppLayout.vue
Pages/Prompts/ # Index, Show, Create, Edit
lib/format.js
routes/web.php # /prompts resource + duplicate, toggle-favorite, use
tests/
Feature/, Unit/ # PHPUnit (app/)
js/ # Vitest (resources/js/) + shared Inertia stub (stubs/inertia.js)
SPECS.md # application specification — source of truth