115 lines
4.1 KiB
Markdown
115 lines
4.1 KiB
Markdown
|
|
# 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)
|