AI Prompt Engineering Operating System — A comprehensive 6-zone workspace for building, validating, and monetizing AI prompts. 47+ modifiers, 21 workflows, 66 skills, Zod-validated state, debounced persistence, and WCAG AA accessibility.
| Links | |
|---|---|
| 🌐 | Live App (GitHub Pages): marktantongco.github.io/promptc-os |
| 🚀 | Vercel: promptc-os.vercel.app |
| 📦 | Repository: github.com/marktantongco/promptc-os |
| 📋 | npm Package: use-validated-reducer |
| 📊 | Skills Manifest: skills-manifest.json |
promptc OS is a production-grade prompt engineering environment that treats prompt creation as a systematic engineering discipline — not ad-hoc copy-pasting. It provides structured tools across 6 interconnected zones — from initial activation through building, validation, playbook orchestration, monetization, and system management. Every prompt, modifier, template, and workflow in the system is copy-ready — paste directly into ChatGPT, Claude, Gemini, or any AI chat.
The universal Collection Basket (⌘B) lets you gather your favorite prompts from any zone into a persistent, searchable collection. The Clipboard History tracks every copy action with timestamp and zone context. The Command Palette (⌘K) provides instant fuzzy search across the entire library. Designed mobile-first at 375px with PWA install support, WCAG AA accessibility, and zero external AI dependencies for core features — everything works offline.
v4.0 introduces a Data Integrity Layer — every piece of state that enters the system (from localStorage, from user actions, from corrupt data) is validated at the boundary with Zod schemas. The app no longer just handles errors; it prevents them. A null/undefined text field will never crash search again. A corrupt basket item will never enter the collection. And 25 property-based tests with 1,000+ random inputs prove it. This is the foundation for the next phase: making promptc OS a discoverable platform that AI agents can programmatically query via MCP.
v4.0 was delivered in three promoted phases, each building on the last — from immediate crash fix to architectural integrity layer to platform discoverability. Each phase was promoted only after the previous one was validated in production.
The problem: Calling .toLowerCase().includes() on null or undefined text fields crashed the search filter chain across the entire app. Users with corrupt localStorage data (missing text fields on basket items) would hit an unhandled TypeError on every keystroke in the Command Palette or basket search.
The fix — defense in depth at every filter boundary:
| Layer | Fix | Impact |
|---|---|---|
safeIncludes() |
Null-safe case-insensitive string search in src/lib/utils.ts — returns false for null/undefined text instead of crashing |
Prevents TypeError on every search filter |
| BasketItem validation gate | Never adds empty/corrupt items to the collection basket — validateBasketItem() rejects items missing id or text |
Stops corrupt data from ever entering the basket |
| localStorage load filter | loadPersistedState() validates each key on load, skips corrupt entries with console.warn |
Graceful degradation on corrupt persisted state |
| 7 filter chains hardened | All .toLowerCase().includes() calls replaced with safeIncludes() |
Every search path is null-safe |
// Before (crashes on null):
item.text.toLowerCase().includes(query)
// After (null-safe):
safeIncludes(item.text, query)The problem: 35+ individual useEffect writers each saving one piece of state to localStorage. No validation on load. No validation on save. If localStorage had corrupt data from a previous version, the app would load it silently and crash downstream. The state was a house of cards — every write independent, every load unverified, every boundary unguarded.
The fix — Zod-validated state architecture:
| Component | File | Purpose |
|---|---|---|
stateSchema.ts |
src/lib/stateSchema.ts |
Zod validators for all state shapes (basketItemSchema, persistedStateSchema). Single source of truth for state validation |
useAppReducer.ts |
src/hooks/useAppReducer.ts |
usePersistedReducer hook combining useReducer + Zod validation + debounced batch localStorage save. Replaces 35+ individual useEffect writers |
stateSchema.test.ts |
src/lib/stateSchema.test.ts |
25 property-based tests with 1,000+ random inputs proving validators never throw on corrupt data |
appReducer |
src/hooks/useAppReducer.ts |
Pure reducer with 20 typed actions + BATCH_UPDATE for atomic multi-field updates |
loadPersistedState() |
src/lib/stateSchema.ts |
Loads + validates each key from localStorage, skips corrupt entries with warning log |
How it works — the data flow:
User Action
↓
dispatch(SET_SEARCH, "hello")
↓
appReducer → new state object
↓
Zod validation (boundary check)
↓
Component re-renders
↓
Debounced 500ms batch save
↓
Only changed keys written to localStorage
Key design decisions:
- Validate on load, not on save — corrupt localStorage data is gracefully skipped, never crashing the app
- Debounced batch save — a single
setTimeout(500ms)replaces 35+ individualuseEffectwriters, reducing localStorage writes by ~95% - Only write changed keys —
prevStateRefcomparison ensures no redundant writes BATCH_UPDATEaction —dispatch({ type: "BATCH_UPDATE", payload: { zone: "build", search: "" } })for atomic multi-field updates- Never throws — all validators use
safeParse(), returningnullfor invalid data instead of throwing
Test coverage — 25 property-based tests:
| Test Category | Count | What it proves |
|---|---|---|
validateBasketItem — valid/invalid inputs |
6 | Accepts valid items, rejects null/undefined/empty/missing fields |
| Fuzz inputs (never throws) | 1 | Symbol, BigInt, Date, RegExp, Error, deeply nested objects — never throws |
| 1000 random inputs (always null or valid) | 1 | Statistical proof that validators always return `null |
loadPersistedState — robustness |
4 | Returns empty object, never throws, skips corrupt entries, handles all-null localStorage |
| Schema robustness — edge types | 13 | Symbol, BigInt, Date, Function, RegExp, Error, deep nesting, sparse arrays, prototype objects, NaN, Infinity, optional fields, defaults |
The vision: promptc OS becomes a discoverable platform — not just a web app, but an ecosystem of skills, tools, and integrations that AI agents and developers can programmatically access.
| Component | Status | Purpose |
|---|---|---|
skills-manifest.json |
✅ Done | 66 skills registered for skills.sh discovery — 13 categories, trigger keywords, file counts |
| MCP server | 📐 Design documented | Exposing search/basket/compose as tools for AI agents via Model Context Protocol |
use-validated-reducer |
✅ Built & tested | npm package extraction of usePersistedReducer hook — generic React hook for Zod-validated persisted state (8/8 tests passing, dual CJS/ESM) |
| Platform API | 🔜 Planned | REST/MCP endpoints for programmatic access to the prompt library |
promptc OS organizes the entire prompt engineering lifecycle into 6 color-coded zones, each with sub-tabs that focus on a specific aspect of the craft.
The starting zone. Browse, search, and collect the building blocks of great prompts.
| Sub-tab | Contents | Count |
|---|---|---|
| Tasks | Ready-to-use task prompts (YouTube, Coding, Business, Research, UI/UX, Image AI, Copy, Email) | 8 |
| Modifiers | Prompt modifiers across 9 categories (Role, Output, Reasoning, Speed, Strategy, Hack, Data, Agent, Productivity) | 47 |
| Templates | Pre-built prompt templates (Web App, Mobile, Brand, Landing Page, Dashboard, API Design, AI Agent, MCP Server, and more) | 20 |
| Brands | Complete brand design systems (powerUP, SaaS/B2B, E-commerce, Fintech, Insurance, Creative Agency) | 6 |
| Animals | 7 animal thinking modes with multi-select and combined generation | 7 |
| Composer | 8-layer prompt builder (Role → Context → Objective → Constraints → Aesthetic → Planning → Output → Refinement) | 1 |
| Sub-tab | Contents |
|---|---|
| Master Prompt | Foundational system prompt (10 core rules + advocacy mode + writing rules) |
| Enhancements | 8 advanced techniques with user input for combined enhancement |
| Meta Builder | 3 instant prompt transformers: Quick Critique, Structured Analysis, Expert Engineering (no AI required — fully offline) |
| Sub-tab | Contents |
|---|---|
| Lint Rules | 28 automated lint checks across 5 segments |
| Word Swaps | 40+ weak → strong word replacements across 4 levels |
| Vocabulary | 60+ design terms with CSS implementations |
| Quality Score | AI-powered 4-dimension analysis |
| Sub-tab | Contents |
|---|---|
| Workflows | 21 production workflows across Design, Dev, Business, AI/ML, and more |
| Animal Chains | 6 multi-animal thinking sequences |
| Design Combos | 12 design element combinations with psychological rationale |
| Typography | 4 display + mono font pairings with use-case recommendations |
| Sub-tab | Contents |
|---|---|
| Top Prompts | 6 highest-value prompt products with revenue potential |
| SaaS Templates | 6 automation blueprints with tech stacks and time estimates |
| Stacks | 4 income strategies (Quick Win → Active → Passive → Hybrid) |
| AI Tools | 5 agent frameworks with starter prompts |
| Compounding | The compounding system philosophy |
| Pricing Guide | Revenue tier strategy |
| Sub-tab | Contents |
|---|---|
| Skills Library | 66 skills across 13 categories |
| Compounding | System health dashboard |
| Principles | 6 core operating principles |
| Skill Builder | 6-step wizard |
| Workflow Patterns | Visual step-flow patterns |
| Self-Evolve | Growth tracking dashboard |
| Infographics | Zone overview + modifier coverage |
| Package Docs | Markdown reference generator |
Collect prompts from any zone into a persistent, searchable collection. Pin, favorite, multi-select, sort, search, filter by zone, export to .md/.JSON, pipeline progress visualization, smart recommendations, stats & insights, and cross-zone forwarding.
v4.0: Every basket item is validated through basketItemSchema — corrupt items with missing id or empty text are rejected at the boundary. The basket is bulletproof.
User input field + +Add buttons on each modifier. Numbered assembly list with sequential connector format (→ [anticipates next modifier]). Copy Assembly exports the complete chain as a single ready-to-paste prompt.
Paste a prompt, select enhancement techniques from the palette, and generate a combined enhanced output with all selected techniques applied in a single pass.
Every copy action tracked with timestamp and zone. Slide-in panel, Copy All, Clear, individual re-copy. Persists up to 50 items across sessions.
v4.0: Clipboard history entries are Zod-validated on load — corrupt entries are silently skipped.
Fuzzy search across all modifiers, templates, tasks, workflows, brands, animals, enhancements, lint rules, word swaps, and chains. Zone quick-switch, keyboard navigation.
v4.0: All 7 filter chains use safeIncludes() — null text fields never crash search.
| Shortcut | Action |
|---|---|
⌘K / Ctrl+K |
Open Command Palette |
⌘B / Ctrl+B |
Toggle Basket panel |
⌘⇧C / Ctrl+Shift+C |
Toggle Clipboard History |
⌘P / Ctrl+P |
Quick Compose |
⌘1 through ⌘6 |
Switch to Zone 1–6 |
? |
Keyboard shortcuts overlay |
Escape |
Close panels |
- PWA: Install to home screen, standalone display, service worker caching with stale-while-revalidate strategy
- iOS bottom tab bar: 5 primary zones + "More" vertical menu
- Safe area padding: Notch and home indicator support via
env(safe-area-inset-*) - 375px design minimum: All layouts tested at iPhone SE width
Zod-validated state at every boundary — load, update, persist. basketItemSchema and persistedStateSchema provide single-source-of-truth validation. Debounced batch save replaces 35+ individual useEffect writers. 25 property-based tests with 1,000+ random inputs prove the validators are bulletproof.
v4.0 introduces a three-layer validation architecture that prevents corrupt data from ever reaching the UI. Every boundary — load, update, persist — is validated with Zod schemas. This is the single most important architectural change in v4.0.
┌─────────────────────────────────────────────────────────────┐
│ LAYER 3: UI Render │
│ Components receive only validated, typed state objects │
│ safeIncludes() prevents null crashes in filter chains │
├─────────────────────────────────────────────────────────────┤
│ LAYER 2: State Manager │
│ appReducer — 20 typed actions + BATCH_UPDATE │
│ usePersistedReducer — Zod validation on every dispatch │
│ Debounced 500ms batch save (replaces 35+ useEffects) │
├─────────────────────────────────────────────────────────────┤
│ LAYER 1: Storage Boundary │
│ loadPersistedState() — validates each key, skips corrupt │
│ validateBasketItem() — rejects null/empty/invalid items │
│ safeIncludes() — null-safe string search │
└─────────────────────────────────────────────────────────────┘
localStorage
↓ loadPersistedState()
↓ Zod field-by-field validation
↓ skip corrupt keys → console.warn
↓
Initial State (validated)
↓
dispatch(ACTION)
↓ appReducer (pure function)
↓
New State
↓ component re-renders
↓
Debounced 500ms save
↓ diff against prevStateRef
↓ only changed keys written
↓
localStorage
| Schema | File | Validates |
|---|---|---|
basketItemSchema |
stateSchema.ts |
id (min 1), text (min 1), label, zone, time, chars (int ≥ 0), pinned (default false), favorited (default false), pipelineStage (optional), copyCount (optional) |
persistedStateSchema |
stateSchema.ts |
19 persisted keys: zone, subtab, search, skills-search, quickstart-dismissed, basket-search, basket-zone-filter, basket-sort (enum: newest/oldest/longest/shortest/az), animal-input, chain-input, meta-prompt, qa-input, composer-fields, compose-text, mod-assembly, mod-user-input, selected-animals, enhance-input, clipboard-history |
// Usage:
const [state, dispatch] = usePersistedReducer(
appReducer, // pure reducer with 20 actions
initialState, // default state shape
persistedStateSchema, // Zod schema for validation
{ storageKey: "promptc-state", debounceMs: 500 }
);
// Individual action:
dispatch({ type: "SET_SEARCH", payload: "role prompt" });
// Batch update (atomic multi-field):
dispatch({
type: "BATCH_UPDATE",
payload: { zone: "build", search: "", subtab: { build: "master" } }
});User Action
↓
try { operation() }
↓ (fails)
classifyError(err)
↓
├─ retryable? ──→ Retry up to 2x (300ms backoff)
│ ↓ (still fails)
│ console.error("[promptc]", code, message)
│ toast.error("Action: Human message")
│ throw err
│
└─ not retryable ──→ console.error("[promptc]", code, message)
toast.error("Action: Human message")
throw err
Error codes: LS_QUOTA (storage full), LS_BLOCKED (security), CLIP_FAIL (clipboard denied), UNKNOWN
v4.0 addition: Before errors even reach this handler, the Data Integrity Layer prevents many of them. safeIncludes() prevents TypeError on null text. validateBasketItem() prevents corrupt items from entering state. loadPersistedState() skips corrupt localStorage entries instead of crashing. The error handler is the last line of defense — the validation layer is the first.
promptc OS meets WCAG AA standards across all zones and components. Accessibility is a first-class requirement, not an afterthought.
| Requirement | Implementation |
|---|---|
| Text contrast | All text meets 4.5:1 minimum on dark background (#9CA3AF = 7.5:1 contrast ratio) |
| UI contrast | Interactive elements meet 3:1 minimum against adjacent colors |
| aria-labels | All icon-only buttons have descriptive aria-label attributes |
| Keyboard nav | Tab-navigable, focus-visible ring on all interactive elements |
| Touch targets | Minimum 40×40px on nav buttons, 44×44px on primary actions |
| Focus management | Backdrop overlays use tabIndex={-1} to prevent trapping |
| Screen reader | Semantic HTML, proper <button> elements, descriptive labels |
| Data integrity | v4.0: Corrupt state never reaches UI — no broken states to navigate |
| Technology | Version | Purpose |
|---|---|---|
| Next.js | 16 | React framework (App Router, Turbopack) |
| React | 19 | UI library |
| TypeScript | 5 | Type safety |
| Zod | 4 | Runtime state validation — single source of truth for all state shapes |
| Tailwind CSS | 4 | Utility-first styling |
| Framer Motion | 12 | Animations and transitions |
| Lucide React | — | Icon library |
| Sonner | — | Toast notifications |
| React Markdown | — | Markdown rendering (lazy-loaded) |
| Radix UI | — | 50+ accessible primitives (Dialog, Tabs, Tooltip, Accordion, etc.) |
| cmdk | — | Command palette engine |
| Recharts | — | Data visualization |
| Bun | — | JavaScript runtime and package manager |
- Node.js 18+ or Bun (recommended)
# Clone the repository
git clone https://github.com/marktantongco/promptc-os.git
cd promptc-os
# Install dependencies
bun install
# Start development server
bun run devOpen http://localhost:3000 in your browser.
# Property-based tests for state validation (25 tests, 1000+ random inputs)
bun test src/lib/stateSchema.test.ts- Push your repo to GitHub
- Connect at vercel.com/new
- Vercel auto-detects Next.js — deploy with zero config
Or use the Vercel CLI:
npm i -g vercel
vercel --prodThe app is configured for static export and deployed at marktantongco.github.io/promptc-os.
bun run build
# Static files are generated in the `out/` directorypromptc-os/
├── src/
│ ├── app/
│ │ ├── page.tsx # Server component with loading skeleton
│ │ ├── layout.tsx # Root layout (PWA meta, fonts, SW registration)
│ │ ├── globals.css # Theme, micro-interactions, animations, accessibility
│ │ ├── PageClient.tsx # Core client component (~1,950 lines)
│ │ ├── api/
│ │ │ ├── route.ts # Health check endpoint
│ │ │ ├── generate/route.ts # Prompt generation API
│ │ │ └── analyze/route.ts # Prompt analysis API
│ │ └── data/
│ │ ├── promptc-data.ts # Core data layer (1,337 lines) — 22 exports
│ │ └── skills-catalog.ts # Skills registry (162 lines) — 66 skills, 13 categories
│ ├── components/
│ │ ├── CommandPalette.tsx # ⌘K search (safeIncludes filter chain)
│ │ ├── OnboardingTour.tsx # First-visit tutorial
│ │ └── ui/ # 50+ Radix UI primitives (Dialog, Tabs, Tooltip, etc.)
│ ├── hooks/
│ │ ├── useAppReducer.ts # v4.0: usePersistedReducer + appReducer (20 actions + BATCH_UPDATE)
│ │ ├── use-toast.ts # Toast notification hook
│ │ └── use-mobile.ts # Mobile detection hook
│ └── lib/
│ ├── db.ts # Database config (Prisma)
│ ├── utils.ts # Utilities + safeIncludes() (v4.0 null-safe search)
│ ├── stateSchema.ts # v4.0: Zod validators (basketItemSchema, persistedStateSchema, loadPersistedState)
│ └── stateSchema.test.ts # v4.0: 25 property-based tests (1,000+ random inputs)
├── public/
│ ├── manifest.json # PWA manifest
│ ├── sw.js # Service worker (stale-while-revalidate caching)
│ ├── icons/ # PWA icons (192px, 512px)
│ ├── logo.svg # App logo
│ └── robots.txt # Search engine directives
├── skills-manifest.json # v4.0: 66 skills registered for skills.sh discovery
└── package.json # v4.0.0
| Decision | Rationale |
|---|---|
Single PageClient.tsx |
All 6 zones rendered client-side for instant tab switching; server component provides loading skeleton |
usePersistedReducer over 35+ useEffects |
Single debounced save replaces dozens of independent writers; Zod validation at every boundary |
safeIncludes() utility |
Null-safe search prevents TypeError crashes across all 7 filter chains |
| Zod as single source of truth | Runtime validation matches TypeScript types; schema is the contract |
| Radix UI primitives | Accessible by default; eliminates custom ARIA implementation for 50+ components |
| PWA with stale-while-revalidate | Instant load from cache, background update; works fully offline for core features |
| Version | Changes |
|---|---|
| v4.0 | The Three Promotions — C-1 Triage: safeIncludes() null-safe search, BasketItem validation gate, localStorage load filter, 7 hardened filter chains. Beaver: stateSchema.ts Zod validators, usePersistedReducer hook (replaces 35+ useEffect writers), appReducer with 20 typed actions + BATCH_UPDATE, loadPersistedState() with boundary validation, 25 property-based tests (1,000+ random inputs). Eagle: skills-manifest.json (66 skills), MCP server design, use-validated-reducer npm extraction documented |
| v3.9 | WCAG AA accessibility overhaul (contrast, aria-labels, focus-visible, touch targets), mobile-first 375px design, interaction state spec (80ms press, 150ms hover), error handling system (retry → notify → log → halt), Meta Builder fully local, PWA support, Wordswap redesign |
| v3.8 | PWA manifest + service worker + icons, mobile right space fix, bottom buttons always visible, Meta Builder local restructuring |
| v3.7 | Modifier +Add to Basket, Prompt Chaining Format, Meta Builder API fix, Clipboard History shortcut |
| v3.6 | Modifier Assembly, Animal Multi-Select, Prompt Enhancer, Clipboard History, Universal +Add to Basket, Micro-Interactions |
| v3.5 | Micro-interactions, visual cues, tooltips, speed optimization |
| v3.2 | Favorites, iOS mobile nav, Quick Compose, cross-zone forwarding |
| v3.0 | CommandPalette, OnboardingTour, Skills Library |
| v2.0 | Collection Basket, Skills Library, Compounding Dashboard |
These principles guide every decision in the promptc OS codebase. They are non-negotiable.
- NO ONE-OFF WORK — Every task produces a reusable asset. If you build it once, it compounds forever.
- THE RULE — Plan → Validate → Execute. Never skip validation. Every boundary is a checkpoint.
- COMPOUNDING SYSTEM — Build once → runs forever → every skill makes the system smarter. The system gets better with every use.
- ACCESSIBILITY FIRST — WCAG AA minimum, keyboard navigable, contrast compliant. No exceptions.
- MOBILE FIRST — Design at 375px, scale up. The smallest screen is the most important.
- NO SILENT FAILURES — Retry → notify → log → halt. If something fails, the user knows.
- VALIDATE AT EVERY BOUNDARY — v4.0: Zod schemas validate state on load, update, and persist. Corrupt data is rejected, never propagated. The schema is the contract.
The Eagle phase includes exposing promptc OS as a Model Context Protocol (MCP) server, making the prompt library, basket, and composer available as tools for AI agents like Claude, GPT, and others.
| Tool | Description | Status |
|---|---|---|
search_prompts |
Search across all zones — modifiers, templates, tasks, workflows, brands, animals | 📐 Design documented |
basket_add |
Add a prompt to the collection basket | 📐 Design documented |
basket_list |
List all items in the collection basket | 📐 Design documented |
basket_remove |
Remove an item from the collection basket | 📐 Design documented |
compose_prompt |
Run the 8-layer Composer to build a structured prompt | 📐 Design documented |
validate_prompt |
Run lint rules and quality scoring on a prompt | 🔜 Planned |
get_workflow |
Retrieve a complete workflow with all steps | 🔜 Planned |
AI Agent (Claude, GPT, etc.)
↓ MCP Protocol (JSON-RPC over stdio/SSE)
promptc OS MCP Server
↓
├── Search Engine → safeIncludes() filter chain
├── Basket Manager → basketItemSchema validation
├── Composer → 8-layer prompt builder
└── Validator → Lint rules + Quality Score
The usePersistedReducer hook has been extracted into a standalone npm package at packages/use-validated-reducer/. It is built, tested (8/8 tests passing), and ready for publishing:
# Build and test locally
cd packages/use-validated-reducer
npm install
npm run build # → dist/index.js (CJS) + dist/index.mjs (ESM) + types
npm test # → 8 tests passing
# Publish to npm (requires npm login)
npm publish// Installation (after publish):
// npm install use-validated-reducer
import { usePersistedReducer } from "use-validated-reducer";
import { z } from "zod";
const schema = z.object({
count: z.number().default(0),
name: z.string().default(""),
});
const [state, dispatch] = usePersistedReducer(reducer, initialState, schema, {
storageKey: "my-app",
debounceMs: 300,
validateOnLoad: true,
});Features of the extracted package:
- Generic over any state shape and Zod schema
- Debounced batch persistence to localStorage
prevStateRefdiffing — only writes changed keysvalidateOnLoad— Zod validation on hydrationpersistKeys— opt-in to persist only specific keys- Zero dependencies beyond React + Zod
Extraction documented in: src/hooks/useAppReducer.ts header comments
Built with ⚡ by promptc OS — AI Prompt Engineering Operating System