@alextechhq/promptetheus
v0.1.0
Published
CLI for fetching, filling and copying AI prompt templates from Promptetheus
Maintainers
Readme
Promptetheus
A Next.js + Supabase SaaS for creating, sharing, and discovering AI prompt templates.
Tech Stack
- Next.js 15 (App Router) + TypeScript
- Supabase (Postgres, Auth, RLS)
- Tailwind CSS + shadcn/ui
- Recharts for analytics
- Vercel for hosting
Local Development
# 1. Install deps
pnpm install
# 2. Start local Supabase (Docker required)
pnpm dev:supabase # or: supabase start
# 3. Start Next.js dev server (uses .env.local)
pnpm dev:next
# Or start both together:
pnpm dev:local # runs scripts/dev-local.sh.env.local — copy the values from supabase status after supabase start:
NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54321
NEXT_PUBLIC_SUPABASE_ANON_KEY=sb_publishable_...
SUPABASE_SERVICE_ROLE_KEY=sb_secret_...Vercel Development (vercel dev)
⚠️ Important:
vercel devdownloads your Vercel project's environment variables from the Vercel dashboard and injects them before Next.js boots. This means.env.localis completely ignored — the app will always hit the remote Supabase.
Use pnpm dev:next when you want to work against the local Supabase instance.
E2E Tests (Playwright)
Tests live in tests/e2e/ and run against the local dev server and local Supabase.
Prerequisites: Dev server must be running (pnpm dev:local) and local Supabase must be up.
# Run all tests headlessly (CI-friendly)
pnpm test # or: pnpm exec playwright test
# Run with the Playwright interactive UI (step-through, trace viewer)
pnpm test:ui
# Run in headed browser (watch the browser open)
pnpm test:headed
# Run a specific test file
pnpm exec playwright test tests/e2e/01-library-upvote.spec.ts --project=chromium
# Show the last HTML report
pnpm exec playwright show-reportTest files:
| File | What it tests |
|---|---|
| 01-library-upvote.spec.ts | Upvote a community prompt → appears in Starred |
| 02-create-prompt.spec.ts | Create a prompt → appears in My Prompts |
| 03-delete-prompt.spec.ts | Delete a prompt → removed from My Prompts |
| 04-saves-reflect-in-stats.spec.ts | Another user saves a prompt → stat_saves increments |
| 05-authorization.spec.ts | Auth guards redirect to /login; Supabase RLS enforced |
| 06-prompt-detail.spec.ts | /prompt/[id] renders without React hooks errors |
Each test uses createTestUser / deleteTestUser helpers that create and clean up isolated Supabase auth users. If a test fails mid-run and leaves stale users, subsequent runs auto-detect and delete them before re-creating.
pt CLI
pt is a zero-dependency Node.js CLI (requires Node ≥ 18) for fetching, filling, and copying AI prompt templates from the command line.
Installation
npm install -g @alextechhq/promptetheusFirst-time setup
Run once after installing to save the product's Supabase URL and anon key to ~/.config/pt/config.json:
pt init
# pt init — Set up the Promptetheus CLI
#
# The following fixed product credentials will be saved:
# PT_SUPABASE_URL https://jxistuzrdnamzhekafdx.supabase.co
# PT_ANON_KEY sb_publishable_...
#
# Save to ~/.config/pt/config.json? [Y/n]
# ✓ Config saved (mode 0600)
#
# Next: pt login — sign in with your Promptetheus accountLogin
Authenticate with your Promptetheus account (same credentials as the website):
pt login
# Email: [email protected]
# Password: ········
# ✓ Logged in as [email protected]
# Session stored at ~/.config/pt/session.jsonThe session token is stored locally (mode 0600) and refreshed automatically 60 s before expiry.
Auth commands
pt login # sign in with your Promptetheus account
pt logout # remove the local session
pt whoami # show current user and token expiryPrompt commands
# List all your prompts — shows stable #ID and required variables
pt list
pt list --cat=debugging
# Get a prompt by stable numeric ID (always the same, stored in DB)
pt get 3
# Get by text — shows ALL matching prompts if ambiguous
pt get youtube
# → shows disambiguation list:
# # 5 YouTube Script Generator {{title}}
# # 6 YouTube Description Generator {{title, transcript}}
# # 8 YouTube Intro Generator {{topic}}
# Use pt get <#N> to select one.
# Fill variables and print
pt fill 8 topic="How to become an AI engineer"
# Fill and copy to clipboard
pt copy 8 topic="How to become an AI engineer"
# Search by title or description
pt search "debugging"
# Pipe to another tool
pt fill 8 topic="AI tools" | llm
pt get 3 > prompt.txtWhen you run pt get <#N>, the CLI shows:
- The template with a variable table (name + label + example)
- An ⚠ unfilled warning with the exact
pt fillcommand to run next
Security model
| Credential | What it is | Where it lives |
|---|---|---|
| PT_SUPABASE_URL | Fixed product URL (same for all users) | ~/.config/pt/config.json (written by pt init) |
| PT_ANON_KEY | Shared, public project anon key — safe to store unencrypted | ~/.config/pt/config.json (written by pt init) |
| Access token | User-specific JWT issued by Supabase Auth after pt login | ~/.config/pt/session.json (mode 0600) |
| Refresh token | Used to silently refresh the access token | ~/.config/pt/session.json (mode 0600) |
pt init only saves the anon key — it is not a secret. It is the same key the website sends in every browser request, and it cannot access data beyond what Row-Level Security policies allow. User-specific privileges come exclusively from the JWT stored after pt login.
Config resolution order (highest → lowest priority):
process.env— CI / shell overrides~/.config/pt/config.json— set bypt init.env.local/.env.remote/.env— repo-level dev fallbacks
MCP Endpoint (Model Context Protocol)
The app exposes a read-only MCP endpoint for IDE integrations (e.g. VS Code Copilot, Cursor):
GET /api/mcp/promptsReturns all static prompts as JSON:
[
{
"name": "YouTube Script Generator",
"description": "...",
"variables": ["topic", "length"],
"template": "Act as a YouTube scriptwriter..."
}
]VS Code Copilot integration
Add to your VS Code settings (settings.json) or .vscode/settings.json:
{
"github.copilot.chat.codeGeneration.instructions": [
{
"url": "http://localhost:3000/api/mcp/prompts"
}
]
}Or configure as an MCP server if your tool supports the protocol directly (e.g. Cursor, Continue.dev).
Migrations live in supabase/migrations/. They run in filename-timestamp order.
# Apply pending migrations to remote (linked project)
supabase db push
# Check migration status (local vs remote)
supabase migration list
# Apply SQL to local DB only (no migration file created)
supabase db query "ALTER TABLE ..."
# Reset local DB and replay all migrations
supabase db resetSchema cache: After schema changes, Supabase PostgREST needs to reload its schema cache. If you get PGRST205 – table not found, the migration hasn't run on the target environment yet (local vs. remote mismatch). Run supabase db push to push to remote.
Key Lessons Learned
| Problem | Cause | Fix |
|---|---|---|
| user_prompts table not found | Table existed locally only; app was hitting remote via vercel dev | supabase db push to sync migration to remote |
| vercel dev ignores .env.local | Vercel CLI injects remote env vars first | Use pnpm dev:next for local Supabase dev |
| PGRST205 after migration | Schema cache not refreshed | Supabase auto-refreshes; or restart with supabase stop && supabase start |
| RLS blocking inserts | Missing WITH CHECK clause on INSERT policy | Always pair USING (SELECT/DELETE) with WITH CHECK (INSERT/UPDATE) |
| Old catch-all ALL policy conflicts | Existing Users manage own prompts policy overlapped new scoped policies | Drop old policies before creating per-operation ones |
Project Structure
app/
api/ # Route handlers (auth, saved-prompts, etc.)
dashboard/
create/ # Create prompt form
my-prompts/
[id]/ # Edit prompt + analytics
saved/ # Saved prompts
settings/
components/
dashboard-create-page-client.tsx # Create form
dashboard-edit-prompt-client.tsx # Edit form + delete + analytics tabs
prompt-card.tsx # Reusable prompt card (hideActions prop)
prompt-stats-panel.tsx # Analytics chart panel
lib/
prompts.ts # Types, model definitions, category labels
supabase.ts # Supabase client (anon key, session-managed auth)
auth-context.tsx # Auth React context
supabase/
migrations/ # SQL migration files (applied in order)