# 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). ```bash # Install PHP + JS dependencies, create .env, generate key, migrate, build composer setup ``` …or manually: ```bash composer install npm install cp .env.example .env php artisan key:generate php artisan migrate --force ``` Then run the app (two terminals): ```bash 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/`): ```bash 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): ```bash 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 ``` ## License [MIT](https://opensource.org/licenses/MIT)