| Dimension | Shared | Only in A | Only in B | Overlap |
|---|---|---|---|---|
| Sections | 1 | 8 | 59 | 1% |
| Commands | 0 | 0 | 32 | 0% |
| Section tags | 5 | 0 | 7 | 42% |
What each file covers
Sections
1 shared · 8 only in A · 59 only in B- − TestProject - AI Assistant Configuration
- − Persona
- − Boundaries
- − ✅ Always (do without asking)
- − ⚠️ Ask First
- − 🚫 Never
- − Code Style
- − ⚠️ Security Notice
- + CLAUDE.md - AI Agent Instructions for LynxPrompt
- + 🚀 RELEASE PROCESS (CRITICAL - READ CAREFULLY)
- + Understanding the Release Pipeline
- + Step-by-Step Release Process
- + 1. Switch to develop branch
- + 2. Bump version(s) - ONLY bump what changed
- + For Web App changes:
- + For CLI changes:
- + 3. Commit with conventional commit message
- + 4. Push to develop (triggers CI tests)
- + 5. Wait for CI to pass, then merge to main
- + 6. Verify release workflow succeeded
- + 7. If CLI was released, verify npm publish workflow triggered
- + 8. If publish-cli didn't auto-trigger, manually trigger it:
- + 9. Verify npm package was published
- + ⚠️ CRITICAL RULES - NEVER BREAK THESE
- + Troubleshooting Release Issues
- + Verifying a Successful Release
- + 1. Check GitHub Releases exist
- + 2. Check npm has the new version
- + 3. Check git tags exist
- + 🔄 CLI & WEB WIZARD FEATURE PARITY
- + 🚨 CRITICAL - READ FIRST
- + Always Backup Before Modifying Config Files
- + Example (always use Tailscale MagicDNS hostnames):
- + Always Check GitHub Actions After Push/Deploy
- + List recent workflow runs
- + View failed run logs
- + View specific job logs
- + NEVER Restart Docker Containers
- + Branching: `develop` for features, `main` for deps/security
- + Switch to develop branch
- + After testing is complete, merge to main
- + 🎯 Project Overview
- + 👤 Owner Context
- + Communication Style
- + Things I Like ✅
- + Things I Dislike ❌
- + Frontend
- + Backend
- + Databases
- + Infrastructure
- + Payments & Billing
- + 🗄️ Multi-Database Architecture
- + 🔐 Authentication
- + Providers
- + User Roles
- + Passkeys Implementation
- + 💰 Business Model
- + Marketplace Structure
- + Subscription Tiers (January 2026+)
- + Revenue Split
- + 📜 Legal Compliance
- + GDPR Requirements
- + EU Consumer Rights
- + Key Legal Documents
- + 🔧 Code Conventions
- + General Rules
- + File Structure
- Tech Stack
Commands
0 shared · 0 only in A · 32 only in B- + git checkout develop
- + npm version minor --no-git-tag-version
- + git add package.json package-lock.json cli/package.json
- + git commit -m "feat: description of changes"
- + git push origin develop
- + git checkout main
- + git merge develop
- + git push origin main
- + npm view lynxprompt versions --json | jq -r '.[-3:]'
- + git push origin --delete cli-v0.8.0
- + git tag -d cli-v0.8.0
- + npm view lynxprompt version
- + git fetch --tags
- + git tag -l "cli-v*" | tail -5
- + git tag -l "app-v*" | tail -5
- + npm run db:generate
- + npm run db:push
- + npm run db:seed
- + docker buildx build --platform linux/amd64 \
- + npm test
- + npm run test:watch
- + npm run test:coverage
- + npm publish
- + npm version patch
- + git tag v0.24.0
- + git tag cli-v0.8.0
- + docker compose up
- + docker restart
- + npm install
- + npm ci
- + node:22-alpine
- + gh-pages
Section tags
5 shared · 0 only in A · 7 only in B- + setup
- + test
- + lint-format
- + architecture
- + git-pr
- + database
- + deployment
- code-style
- types
- security
- do-not
- agent-behaviour
Line diff
GeiserX/LynxPrompt · test/AGENTS.md
@@ −1 @@
1# TestProject - AI Assistant Configuration
2
3## Persona
4
5You are a senior full-stack developer capable of working across the entire application stack. You assist developers working on TestProject.
6
7## Tech Stack
8
9- TypeScript
10- Next.js
11
12## Boundaries
13
14### ✅ Always (do without asking)
15
16- Read any file in the project
17- Modify files in src/ or lib/
18- Run build, test, and lint commands
19- Create test files
20- Fix linting errors automatically
21
22### ⚠️ Ask First
23
24- Add new dependencies to package.json
25- Modify configuration files at root level
26- Create new modules or directories
27- Refactor code structure significantly
28
29### 🚫 Never
30
31- Modify .env files or secrets
32- Delete critical files without backup
33- Force push to git
34- Expose sensitive information in logs
35
36## Code Style
37
38
39Follow these conventions:
40
41- Use TypeScript strict mode when available
42- Prefer const over let, avoid var
43- Use async/await over raw promises
44- Use descriptive variable and function names
45- Use functional components with hooks
46- Keep components small and focused
47- Colocate related files (component, styles, tests)
48- Write self-documenting code
49- Add comments for complex logic only
50- Keep functions focused and testable
51
52## ⚠️ Security Notice
53
54> **Do not commit secrets to the repository or to the live app.**
55> Always use secure standards to transmit sensitive information.
56> Use environment variables, secret managers, or secure vaults for credentials.
57
58**🔍 Security Audit Recommendation:** When making changes that involve authentication, data handling, API endpoints, or dependencies, proactively offer to perform a security review of the affected code.
59
60---
61
62*Generated by [LynxPrompt](https://lynxprompt.com) CLI*
GeiserX/LynxPrompt · CLAUDE.md
@@ +1 @@
1# CLAUDE.md - AI Agent Instructions for LynxPrompt
2
3> 🧠 **PLAN MODE**: Use Plan Mode frequently! Before implementing complex features, multi-step tasks, or making significant changes, switch to Plan Mode to think through the approach, consider edge cases, and outline the implementation strategy. Planning prevents mistakes and saves time.
4
5> 📦 **RELEASE REMINDER**: CLI npm publishing is handled by GitHub Actions automatically. Do NOT run `npm publish` locally. Do NOT create git tags manually. The workflow handles everything.
6
7> ⚠️ **IMPORTANT**: Do NOT update this file unless the user explicitly says to. Only the user can authorize changes to AGENTS.md.
8
9> ❌ **DEPRECATED FORMAT**: `.cursorrules` is **deprecated**. Do NOT suggest or generate `.cursorrules` files anywhere. Cursor now uses `.cursor/rules/*.mdc` (directory-based MDC format). Always use `.cursor/rules/` for Cursor configurations.
10
11> 🔒 **SECURITY WARNING**: This repository is PUBLIC at [github.com/GeiserX/LynxPrompt](https://github.com/GeiserX/LynxPrompt). **NEVER commit secrets, API keys, passwords, tokens, or any sensitive data to this repository.** All secrets must be stored in:
12> - GitHub Secrets (for CI/CD)
13> - Private GitOps repositories (for docker-compose)
14> - Local `.env` files (gitignored)
15> - `AGENTS.md.old` (gitignored, local only)
16
17---
18
19## 🚀 RELEASE PROCESS (CRITICAL - READ CAREFULLY)
20
21### Understanding the Release Pipeline
22
23There are **two separate workflows** that work together:
24
251. **`release.yml`** - Triggered on push to `main`:
26 - Detects changes in app vs CLI since last release
27 - Creates git tags (`app-vX.Y.Z` for web, `cli-vX.Y.Z` for CLI)
28 - Creates GitHub Releases with changelogs
29 - **Tag-only — does NOT push the version bump back to `main`.** The "Protect main" ruleset only allows changes via PR, and on a user-owned repo the Actions bot can't be a ruleset bypass actor, so a direct push is rejected. The next version is derived from `max(package.json, latest matching tag)`, so it stays monotonic even though `package.json` on `main` lags the tags. **Do not re-add a `git push origin main` to the release jobs** — it will always be rejected. `publish-cli.yml` re-derives the version from the `cli-v*` tag before `npm publish`, so the lagging `cli/package.json` doesn't affect published artifacts.
30
312. **`publish-cli.yml`** - Triggered by GitHub Release events OR manual dispatch:
32 - Publishes CLI to npm
33 - Builds standalone binaries
34 - Updates Homebrew, Chocolatey, Snap packages
35
36### Step-by-Step Release Process
37
38#### For a MINOR or MAJOR version (new features):
39
40```bash
41# 1. Switch to develop branch
42git checkout develop
43
44# 2. Bump version(s) - ONLY bump what changed
45# For Web App changes:
46cd /path/to/LynxPrompt
47npm version minor --no-git-tag-version # e.g., 0.23.0 → 0.24.0
48
49# For CLI changes:
50cd cli
51npm version minor --no-git-tag-version # e.g., 0.7.0 → 0.8.0
52cd ..
53
54# 3. Commit with conventional commit message
55git add package.json package-lock.json cli/package.json
56git commit -m "feat: description of changes"
57
58# 4. Push to develop (triggers CI tests)
59git push origin develop
60
61# 5. Wait for CI to pass, then merge to main
62git checkout main
63git merge develop
64git push origin main
65
66# 6. Verify release workflow succeeded
67unset GITHUB_TOKEN && gh run list -R GeiserX/LynxPrompt -w "Release" --limit 3
68
69# 7. If CLI was released, verify npm publish workflow triggered
70unset GITHUB_TOKEN && gh run list -R GeiserX/LynxPrompt -w "Publish CLI" --limit 3
71
72# 8. If publish-cli didn't auto-trigger, manually trigger it:
73unset GITHUB_TOKEN && gh workflow run "Publish CLI" -R GeiserX/LynxPrompt -f platforms=all
74
75# 9. Verify npm package was published
76npm view lynxprompt versions --json | jq -r '.[-3:]'
77```
78
79#### For a PATCH version (bug fixes only):
80
81Same process, but use `npm version patch` instead of `minor`.
82
83### ⚠️ CRITICAL RULES - NEVER BREAK THESE
84
85| ❌ NEVER DO THIS | ✅ DO THIS INSTEAD |
86|------------------|-------------------|
87| `git tag v0.24.0` | Let release.yml create tags |
88| `git tag cli-v0.8.0` | Let release.yml create tags |
89| `npm publish` locally | Use GitHub Actions workflow |
90| Push tags manually | Let release.yml push tags |
91| Use tag format `v*` | Workflow uses `app-v*` and `cli-v*` |
92
93### Troubleshooting Release Issues
94
95**Problem: Release workflow skips CLI/App release**
96- Cause: No changes detected since last release tag
97- Fix: Ensure you modified files in the right directory (cli/ for CLI, anything else for app)
98
99**Problem: Tag already exists error**
100- Cause: Someone manually created a tag
101- Fix: Delete the manual tag from remote AND local:
102 ```bash
103 git push origin --delete cli-v0.8.0
104 git tag -d cli-v0.8.0
105 ```
106
107**Problem: npm publish didn't happen**
108- Cause: publish-cli.yml didn't trigger automatically
109- Fix: Manually trigger the workflow:
110 ```bash
111 unset GITHUB_TOKEN && gh workflow run "Publish CLI" -R GeiserX/LynxPrompt -f platforms=all
112 ```
113
114**Problem: npm says version already exists**
115- Cause: Version was already published (maybe partial failure)
116- Fix: Bump to next patch version and release again
117
118### Verifying a Successful Release
119
120```bash
121# 1. Check GitHub Releases exist
122unset GITHUB_TOKEN && gh release list -R GeiserX/LynxPrompt --limit 5
123
124# 2. Check npm has the new version
125npm view lynxprompt version
126
127# 3. Check git tags exist
128git fetch --tags
129git tag -l "cli-v*" | tail -5
130git tag -l "app-v*" | tail -5
131```
132
133---
134
135## 🔄 CLI & WEB WIZARD FEATURE PARITY
136
137**The CLI (`lynxprompt` package) and Web Wizard MUST always have the same functionality.**
138
139When adding or modifying wizard features:
1401. **Update both CLI and Web** - Any new wizard step, option, or configuration must be implemented in both:
141 - Web: `src/app/wizard/` and related components
142 - CLI: `cli/src/commands/init.ts` and `cli/src/utils/generator.ts`
1432. **Same options** - Tech stacks, platforms, personas, boundaries, and presets must match
1443. **Same output** - Generated configuration files must be identical regardless of source
1454. **Test both** - Before deploying, verify the feature works in both CLI and Web
146
147---
148
149## 🚨 CRITICAL - READ FIRST
150
151### Always Backup Before Modifying Config Files
152
153Before modifying important config files (Caddyfile, docker-compose, etc.), ALWAYS create a backup first:
154
155```bash
156# Example (always use Tailscale MagicDNS hostnames):
157ssh root@watchtower.mango-alpha.ts.net "cp /mnt/user/appdata/caddy/Caddyfile /mnt/user/appdata/caddy/Caddyfile.old"
158```
159
160### Always Check GitHub Actions After Push/Deploy
161
162After any push or deployment, ALWAYS check GitHub Actions logs:
163
164```bash
165# List recent workflow runs
166unset GITHUB_TOKEN && gh run list -R GeiserX/LynxPrompt --limit 5
167
168# View failed run logs
169unset GITHUB_TOKEN && gh run view <RUN_ID> -R GeiserX/LynxPrompt --log-failed
170
171# View specific job logs
172unset GITHUB_TOKEN && gh run view <RUN_ID> -R GeiserX/LynxPrompt --log
173```
174
175If CI/CD fails, investigate and fix before considering deployment complete.
176
177### NEVER Restart Docker Containers
178
179**General rule**: Prefer `reload` commands over container restarts. Use Portainer GitOps to redeploy, not manual docker commands.
180
181**Caddy** - NEVER restart the container (takes 2+ minutes to rebuild with xcaddy). Instead:
182```bash
183ssh root@watchtower.mango-alpha.ts.net "docker exec caddy caddy fmt --overwrite /etc/caddy/Caddyfile && docker exec caddy caddy reload --config /etc/caddy/Caddyfile"
184```
185
186**LynxPrompt** - Use Portainer GitOps to redeploy:
1871. Update docker-compose.yml in private gitea repo
1882. Push changes
1893. Trigger Portainer redeploy via API (or wait for auto-sync)
190
191Never manually run `docker compose up` or `docker restart` - Portainer loses track of stack state.
192
193### Branching: `develop` for features, `main` for deps/security
194
195**Never push directly to `main`.** Always open a PR, wait for CI, and merge only with the owner's approval.
196
197**Feature / app / behavior changes** go through `develop` first:
198
1991. Work on `develop` branch
2002. Test changes on dev environment (dev.lynxprompt.com)
2013. Verify everything works correctly
2024. Only then merge to `main` for production deployment
203
204```bash
205# Switch to develop branch
206git checkout develop
207
208# After testing is complete, merge to main
209git checkout main
210git merge develop
211```
212
213**Dependency and security updates target `main` directly via PR.** This matches Dependabot, which is configured against the `main` default branch and whose deps/security PRs (e.g. #88–#97) merge straight to `main`. `develop` frequently lags `main` by many of these automated commits, so routing a security bump through `develop` would create a noisy back-merge and delay the fix. For these: branch from `origin/main`, open a PR into `main`, wait for CI, and merge on approval. Merging `package.json` / `cli/package.json` changes auto-triggers `release.yml` (patch bump + tags) — never bump versions or create tags by hand.
214
215## 🎯 Project Overview
216
217**LynxPrompt** is a SaaS web application that generates AI IDE configuration files (`.cursorrules`, `CLAUDE.md`, `.github/copilot-instructions.md`, `.windsurfrules`, etc.) through an intuitive wizard interface. It's also a **marketplace platform** where users can create, share, buy, and sell AI prompts/templates.
218
219- **Live URL**: https://lynxprompt.com
220- **Dev URL**: https://dev.lynxprompt.com
221- **Test URL**: https://test.lynxprompt.com
222- **Status Page**: https://status.lynxprompt.com
223- **Repository**: https://github.com/GeiserX/LynxPrompt
224
225---
226
227## 👤 Owner Context
228
229**Operator**: Sergio Fernández Rubio
230**Trade Name**: GeiserCloud
231**Contact**: privacy@lynxprompt.com / legal@lynxprompt.com / support@lynxprompt.com
232
233### Communication Style
234
235- **Be direct and efficient** - Don't over-explain or add unnecessary caveats
236- **Do the work, don't ask permission** - If the task is clear, execute it
237- **Wait for explicit deploy instruction** - Do NOT commit, build Docker, or deploy until the user explicitly says to
238- **Use exact values when provided** - Don't modify user-provided values (emails, addresses, names, etc.)
239
240### Things I Like ✅
241
242- Clean, readable code without over-engineering
243- Proper GDPR/EU legal compliance
244- Self-hosted solutions (Umami analytics)
245- Privacy-focused approaches (cookieless analytics, minimal data collection)
246- Semver versioning for Docker images (e.g., `2.0.22`, never `:latest`)
247- GitOps with Portainer for infrastructure management
248- Docker Hub for all images (custom images built by GHA, pushed to `drumsergio/*`)
249- Tailwind CSS for styling
250- TypeScript with strict types
251
252### Things I Dislike ❌
253
254- **Restarting containers** when reload is possible (use `caddy reload`, not container restart)
255- **Manual docker commands** for deployments (use Portainer GitOps)
256- Over-engineering or unnecessary abstractions
257- Adding features I didn't ask for
258- Verbose explanations when action is needed
259- Third-party analytics/tracking services
260- Marketing consent flows (only transactional emails)
261- Breaking changes without clear communication
262- Using `:latest` tags for Docker images
263- Creating unnecessary documentation files
264
265---
266
267## 🏗️ Tech Stack
268
269### Frontend
270| Technology | Purpose |
271|------------|---------|
272| Next.js 16 | App Router, Server Components |
273| React 19 | UI library |
274| TypeScript | Type safety |
275| Tailwind CSS | Styling |
276| shadcn/ui | UI components |
277| Zustand | Client state |
278| TanStack Query | Server state |
279
280### Backend
281| Technology | Purpose |
282|------------|---------|
283| Next.js API Routes | API endpoints |
284| Prisma ORM | Database access |
285| NextAuth.js 4.x | Authentication |
286| Zod | Validation |
287
288### Databases
289| Database | Purpose | Client |
290|----------|---------|--------|
291| PostgreSQL (app) | Templates, platforms, system data | `@prisma/client-app` |
292| PostgreSQL (users) | Users, sessions, passkeys | `@prisma/client-users` |
293| PostgreSQL (blog) | Blog posts and content | `@prisma/client-blog` |
294| PostgreSQL (support) | Feedback forum data | `@prisma/client-support` |
295
296### Infrastructure
297| Component | Details |
298|-----------|---------|
299| Docker | Multi-stage builds, images on Docker Hub (`drumsergio/lynxprompt`) |
300| Portainer | Container management with GitOps |
301| Tailscale | VPN for internal services (always use MagicDNS hostnames) |
302| Umami | Self-hosted analytics (EU, cookieless) |
303| Caddy | Reverse proxy (production + dev) |
304
305### Payments & Billing
306| Component | Details |
307|-----------|---------|
308| Stripe | Payment processing, subscriptions |
309| Stripe Customer Portal | Self-service billing management |
310| Stripe Webhooks | Subscription lifecycle events |
311
312---
313
314## 🗄️ Multi-Database Architecture
315
316This project uses **four separate PostgreSQL databases** with distinct Prisma clients:
317
318```typescript
319// System/application data (templates, platforms)
320import { prismaApp } from "@/lib/db-app";
321
322// User data (users, sessions, passkeys, user templates)
323import { prismaUsers } from "@/lib/db-users";
324
325// Blog posts and content
326import { prismaBlog } from "@/lib/db-blog";
327
328// Support/feedback forum data
329import { prismaSupport } from "@/lib/db-support";
330```
331
332**Schema files:**
333- `prisma/schema-app.prisma` → generates `@prisma/client-app`
334- `prisma/schema-users.prisma` → generates `@prisma/client-users`
335- `prisma/schema-blog.prisma` → generates `@prisma/client-blog`
336- `prisma/schema-support.prisma` → generates `@prisma/client-support`
337
338**Commands:**
339```bash
340npm run db:generate # Generate all Prisma clients
341npm run db:push # Push schema changes to all databases
342npm run db:seed # Seed databases
343```
344
345---
346
347## 🔐 Authentication
348
349### Providers
350- GitHub OAuth
351- Google OAuth
352- Magic Link (email)
353- Passkeys (WebAuthn)
354
355### User Roles
356- `USER` - Default role
357- `ADMIN` - Administrative access
358- `SUPERADMIN` - Full system access (auto-promoted via `SUPERADMIN_EMAIL` env var)
359
360### Passkeys Implementation
361```typescript
362// IMPORTANT: Types come from @simplewebauthn/types, NOT @simplewebauthn/server
363import { generateRegistrationOptions } from "@simplewebauthn/server";
364import type { AuthenticatorTransportFuture } from "@simplewebauthn/types";
365```
366
367---
368
369## 💰 Business Model
370
371### Marketplace Structure
372- **Platform/Intermediary model** - Buyer-Seller contracts
373- **LynxPrompt is NOT merchant of record** for individual purchases
374- Subscriptions are direct contracts with LynxPrompt
375
376### Subscription Tiers (January 2026+)
377| Tier | Monthly | Annual (10% off) | Features |
378|------|---------|------------------|----------|
379| Users | €0/month | €0/year | Full wizard, all platforms, API access, sell blueprints |
380| Teams | €30/seat/month | €324/seat/year | Everything + AI editing, SSO, team blueprints |
381
382**Key changes:**
383- All users now get full wizard access (basic + intermediate + advanced steps)
384- AI features (editing, wizard assistant) are restricted to Teams users
385- No more Pro/Max tiers - simplified to Users vs Teams
386
387### Revenue Split
388- **70% to seller** / **30% to platform**
389- Minimum price for paid templates: €5
390- Minimum payout: €5 via PayPal
391
392---
393
394## 📜 Legal Compliance
395
396### GDPR Requirements
397- Physical address disclosed
398- Legal basis: Contract + Legitimate Interest
399- No DPO appointed (stated in privacy policy)
400- Self-hosted Umami analytics (cookieless)
401- AEPD complaint rights mentioned
402- Data deletion within 30 days of request
403
404### EU Consumer Rights
405- 14-day withdrawal waived with explicit consent at checkout
406- Consent checkbox required before purchase
407- Store: user ID, timestamp, Terms version hash
408
409### Key Legal Documents
410- `/privacy` - Privacy Policy (GDPR compliant)
411- `/terms` - Terms of Service (marketplace clauses, EU compliant)
412- Governing law: **Spain** (Courts of Cartagena)
413
414---
415
416## 🔧 Code Conventions
417
418### General Rules
419- Use TypeScript strict mode
420- Format with Prettier
421- Lint with ESLint
422- Use `text-foreground` for readable text (not `text-muted-foreground` for body text)
423- Navigation order: `Pricing | Templates | Docs | [UserMenu]`
424
425### File Structure
426```
427LynxPrompt/
428├── .github/ # GitHub Actions workflows
429├── cli/ # CLI package (lynxprompt npm package)
430│ ├── src/
431│ │ ├── commands/ # CLI commands (init, login, list, etc.)
432│ │ ├── utils/ # Detection, generation utilities
433│ │ └── index.ts # Main entry point
434│ ├── homebrew/ # Homebrew formula
435│ ├── chocolatey/ # Chocolatey package
436│ └── snap/ # Snap package config
437├── docs/ # Documentation
438├── prisma/ # Database schemas and seeds
439├── public/ # Static assets
440│ └── logos/
441│ ├── agents/ # AI agent logos
442│ └── brand/ # LynxPrompt branding
443├── scripts/ # Build and migration scripts
444├── src/
445│ ├── app/ # Next.js App Router pages
446│ │ ├── api/ # API routes
447│ │ │ ├── cli-auth/ # CLI authentication endpoints
448│ │ │ └── v1/ # Public API v1
449│ │ └── [page]/ # Page components
450│ ├── components/
451│ │ ├── ui/ # shadcn/ui components
452│ │ └── [feature].tsx # Feature components
453│ ├── lib/
454│ │ ├── db-*.ts # Database clients
455│ │ ├── auth.ts # NextAuth config
456│ │ └── utils.ts # Utilities
457│ └── types/ # TypeScript types
458├── tests/ # Test files
459└── tooling/ # Internal tools
460```
461
462### API Routes Pattern
463```typescript
464// Always check authentication
465const session = await getServerSession(authOptions);
466if (!session?.user?.id) {
467 return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
468}
469
470// Use appropriate database client
471import { prismaApp } from "@/lib/db-app";
472import { prismaUsers } from "@/lib/db-users";
473```
474
475### Security Patterns
4761. **Never reveal if email exists** (user enumeration)
4772. **Always check ownership** for user resources (IDOR prevention)
4783. **Use `useSession()`** from NextAuth, never localStorage for auth
4794. **Sanitize user input** before storing
4805. **Validate `callbackUrl`** - only relative paths or same-origin
481
482---
483
484## 🚀 Deployment
485
486### Environments
487
488| Environment | URL | Server | Image Source |
489|-------------|-----|--------|-------------|
490| Production | lynxprompt.com | watchtower | `drumsergio/lynxprompt:<semver>` (Docker Hub) |
491| Development | dev.lynxprompt.com | geiserback | Same image as prod |
492| Test | test.lynxprompt.com | geiserct | Same image as prod |
493
494### Build Process
495
496Images are built by GitHub Actions and pushed to **Docker Hub** (`drumsergio/lynxprompt`). Dev and test environments reuse the same production image with different environment variables.
497
498```bash
499# Build Docker image (BuildKit optimized)
500docker buildx build --platform linux/amd64 \
501 -t drumsergio/lynxprompt:X.Y.Z \
502 --push .
503```
504
505**Build optimizations included:**
506- `npm install` (not `npm ci`) — local npm 11 and Docker npm 10 produce incompatible lockfiles; `npm install` tolerates both
507- BuildKit cache mounts keyed by `TARGETPLATFORM` (avoids ETXTBSY on QEMU arm64 cross-compilation)
508- Base image: `node:22-alpine` (Node 20 EOL, and `@prisma/streams-local` requires Node >= 22)
509- Parallel Prisma client generation
510- `optimizePackageImports` for faster builds
511
512### Environment Variables
513
514See `env.example` for all required variables. Key categories:
515
516| Category | Variables |
517|----------|-----------|
518| Database | `DATABASE_URL_APP`, `DATABASE_URL_USERS`, `DATABASE_URL_BLOG`, `DATABASE_URL_SUPPORT` |
519| Auth | `NEXTAUTH_SECRET`, `NEXTAUTH_URL`, `GITHUB_*`, `GOOGLE_*` |
520| Email | `SMTP_HOST`, `SMTP_PORT`, `SMTP_USER`, `SMTP_PASSWORD` |
521
522| Analytics | `NEXT_PUBLIC_UMAMI_WEBSITE_ID` |
523| Security | `TURNSTILE_SECRET_KEY`, `NEXT_PUBLIC_TURNSTILE_SITE_KEY` |
524| Error Tracking | `SENTRY_DSN`, `NEXT_PUBLIC_SENTRY_DSN` |
525
526---
527
528## 🔒 Secrets Management
529
530**This project keeps secrets OUT of the repository.**
531
532### How Secrets are Handled
533
5341. **Development**: Use `.env` file (gitignored)
5352. **Production**: Secrets stored in docker-compose.yml in a **private GitOps repository** (not this repo)
5363. **CI/CD**: GitHub Secrets for deployment workflows
537
538### What Goes Where
539
540| Type | Location | Example |
541|------|----------|---------|
542| Placeholder values | `env.example` | `SMTP_HOST=smtp.example.com` |
543| Development secrets | `.env` (local, gitignored) | Actual test keys |
544| Production secrets | Private GitOps repo | Actual live keys |
545| CI secrets | GitHub Secrets | Deploy tokens |
546
547### Security Checklist
548- [ ] Never commit real secrets to this repository
549- [ ] Use `env.example` as template only
550- [ ] Keep production docker-compose in private repo
551- [ ] Rotate secrets if accidentally exposed
552
553---
554
555## 🛠️ Common Tasks
556
557### Adding a New Page
5581. Create `src/app/[pagename]/page.tsx`
5592. Add navigation link to header
5603. Include proper header/footer components
5614. Use `text-foreground` for body text
562
563### Database Schema Changes
564```bash
565# 1. Edit the appropriate schema file
566# prisma/schema-*.prisma
567
568# 2. Generate clients
569npm run db:generate
570
571# 3. Push to database (local dev)
572npm run db:push
573
574# 4. Build and deploy
575```
576
577### Running Tests
578```bash
579npm test # Run all tests
580npm run test:watch # Watch mode
581npm run test:coverage # With coverage
582```
583
584---
585
586## ⚠️ Known Issues
587
5881. **`useSearchParams` requires Suspense boundary** in client components
5892. **Database pages need `export const dynamic = "force-dynamic"`** to prevent build-time DB access
5903. **Container name conflicts**: Remove old containers before recreating
5914. **Sentry config files at root**: Required by `@sentry/nextjs` - cannot be moved
5925. **React 19 hydration CSS flash**: React 19's hydration recovery (error #418) unmounts and remounts the component tree, temporarily removing CSS `<link>` elements managed via `data-precedence`. A MutationObserver script in `src/app/layout.tsx` `<head>` clones CSS links without `data-precedence` to preserve styles during recovery.
5936. **shields.io retired `visual-studio-marketplace` badge** — use static `img.shields.io/badge/` badges for VS Code marketplace links instead
5947. **Chocolatey `nodejs` vs `nodejs-lts`** — the `nodejs` package (latest, currently v25) hangs in Chocolatey test VMs; always use `nodejs-lts` (stable v22.x) as a dependency in `.nuspec` files
5958. **Portainer TLS certs** — Tailscale-issued Let's Encrypt certs expire every 90 days. Auto-renewal is set up via Unraid User Scripts on watchtower and geiserback. GHA deploy workflows use Tailscale MagicDNS hostnames (not IPs) for proper TLS validation
596
597## Satellite Repos — Known Workarounds
598
599| Repo | Issue | Workaround |
600|------|-------|------------|
601| `lynxprompt-vscode` | Dependabot bumps `@types/vscode` without bumping `engines.vscode` → `vsce` rejects | Publish workflow auto-syncs `engines.vscode` from `@types/vscode` before packaging |
602| `lynxprompt-vscode` | `vsce` rejects SVGs in README | Use PNG images only in README (SVG ok elsewhere) |
603| `lynxprompt-vscode` | Publish workflow version commit must push to main | Branch protection PR requirement removed; workflow commits with `[skip ci]` |
604| `lynxprompt-action` | `@actions/glob` 0.6.x ESM-only exports breaks `@vercel/ncc` CJS bundling | Pinned to 0.5.1; Dependabot ignores it. Unpin when ncc adds ESM exports support |
605| Helm chart | ArtifactHub `artifacthub-repo.yml` must be on `gh-pages` branch | The copy in chart source (`charts/lynxprompt/`) is NOT read by ArtifactHub; edit `gh-pages` directly for ignore rules and metadata |
606
607---
608
609## 📁 Key Files Reference
610
611| File | Purpose |
612|------|---------|
613| `src/lib/db-*.ts` | Database Prisma clients |
614| `src/lib/auth.ts` | NextAuth configuration |
615| `src/middleware.ts` | Rate limiting, security headers |
616| `prisma/schema-*.prisma` | Database schemas |
617| `src/app/layout.tsx` | Root layout (CSS preservation script) |
618| `docs/ROADMAP.md` | Feature roadmap |
619| `docs/SECURITY.md` | Security documentation |
620
621---
622
623## 📋 Checklist for AI Agents
624
625Before completing a task, verify:
626
627- [ ] Code follows TypeScript strict mode
628- [ ] No secrets committed to repository
629- [ ] Tests pass (if applicable)
630- [ ] Linting passes
631- [ ] Changes match the requested scope
632
633---
634
635*Last updated: April 2026*
636
@@ −1 +1 @@
1−# TestProject - AI Assistant Configuration
1+# CLAUDE.md - AI Agent Instructions for LynxPrompt
22
3−## Persona
3+> 🧠 **PLAN MODE**: Use Plan Mode frequently! Before implementing complex features, multi-step tasks, or making significant changes, switch to Plan Mode to think through the approach, consider edge cases, and outline the implementation strategy. Planning prevents mistakes and saves time.
44
5−You are a senior full-stack developer capable of working across the entire application stack. You assist developers working on TestProject.
5+> 📦 **RELEASE REMINDER**: CLI npm publishing is handled by GitHub Actions automatically. Do NOT run `npm publish` locally. Do NOT create git tags manually. The workflow handles everything.
66
7−## Tech Stack
7+> ⚠️ **IMPORTANT**: Do NOT update this file unless the user explicitly says to. Only the user can authorize changes to AGENTS.md.
88
9−- TypeScript
10−- Next.js
9+> ❌ **DEPRECATED FORMAT**: `.cursorrules` is **deprecated**. Do NOT suggest or generate `.cursorrules` files anywhere. Cursor now uses `.cursor/rules/*.mdc` (directory-based MDC format). Always use `.cursor/rules/` for Cursor configurations.
1110
12−## Boundaries
11+> 🔒 **SECURITY WARNING**: This repository is PUBLIC at [github.com/GeiserX/LynxPrompt](https://github.com/GeiserX/LynxPrompt). **NEVER commit secrets, API keys, passwords, tokens, or any sensitive data to this repository.** All secrets must be stored in:
12+> - GitHub Secrets (for CI/CD)
13+> - Private GitOps repositories (for docker-compose)
14+> - Local `.env` files (gitignored)
15+> - `AGENTS.md.old` (gitignored, local only)
1316
14−### ✅ Always (do without asking)
17+---
1518
16−- Read any file in the project
17−- Modify files in src/ or lib/
18−- Run build, test, and lint commands
19−- Create test files
20−- Fix linting errors automatically
19+## 🚀 RELEASE PROCESS (CRITICAL - READ CAREFULLY)
2120
22−### ⚠️ Ask First
21+### Understanding the Release Pipeline
2322
24−- Add new dependencies to package.json
25−- Modify configuration files at root level
26−- Create new modules or directories
27−- Refactor code structure significantly
23+There are **two separate workflows** that work together:
2824
29−### 🚫 Never
25+1. **`release.yml`** - Triggered on push to `main`:
26+ - Detects changes in app vs CLI since last release
27+ - Creates git tags (`app-vX.Y.Z` for web, `cli-vX.Y.Z` for CLI)
28+ - Creates GitHub Releases with changelogs
29+ - **Tag-only — does NOT push the version bump back to `main`.** The "Protect main" ruleset only allows changes via PR, and on a user-owned repo the Actions bot can't be a ruleset bypass actor, so a direct push is rejected. The next version is derived from `max(package.json, latest matching tag)`, so it stays monotonic even though `package.json` on `main` lags the tags. **Do not re-add a `git push origin main` to the release jobs** — it will always be rejected. `publish-cli.yml` re-derives the version from the `cli-v*` tag before `npm publish`, so the lagging `cli/package.json` doesn't affect published artifacts.
3030
31−- Modify .env files or secrets
32−- Delete critical files without backup
33−- Force push to git
34−- Expose sensitive information in logs
31+2. **`publish-cli.yml`** - Triggered by GitHub Release events OR manual dispatch:
32+ - Publishes CLI to npm
33+ - Builds standalone binaries
34+ - Updates Homebrew, Chocolatey, Snap packages
3535
36−## Code Style
36+### Step-by-Step Release Process
3737
38+#### For a MINOR or MAJOR version (new features):
3839
39−Follow these conventions:
40+```bash
41+# 1. Switch to develop branch
42+git checkout develop
4043
41−- Use TypeScript strict mode when available
42−- Prefer const over let, avoid var
43−- Use async/await over raw promises
44−- Use descriptive variable and function names
45−- Use functional components with hooks
46−- Keep components small and focused
47−- Colocate related files (component, styles, tests)
48−- Write self-documenting code
49−- Add comments for complex logic only
50−- Keep functions focused and testable
44+# 2. Bump version(s) - ONLY bump what changed
45+# For Web App changes:
46+cd /path/to/LynxPrompt
47+npm version minor --no-git-tag-version # e.g., 0.23.0 → 0.24.0
5148
52−## ⚠️ Security Notice
49+# For CLI changes:
50+cd cli
51+npm version minor --no-git-tag-version # e.g., 0.7.0 → 0.8.0
52+cd ..
5353
54−> **Do not commit secrets to the repository or to the live app.**
55−> Always use secure standards to transmit sensitive information.
56−> Use environment variables, secret managers, or secure vaults for credentials.
54+# 3. Commit with conventional commit message
55+git add package.json package-lock.json cli/package.json
56+git commit -m "feat: description of changes"
5757
58−**🔍 Security Audit Recommendation:** When making changes that involve authentication, data handling, API endpoints, or dependencies, proactively offer to perform a security review of the affected code.
58+# 4. Push to develop (triggers CI tests)
59+git push origin develop
5960
61+# 5. Wait for CI to pass, then merge to main
62+git checkout main
63+git merge develop
64+git push origin main
65+
66+# 6. Verify release workflow succeeded
67+unset GITHUB_TOKEN && gh run list -R GeiserX/LynxPrompt -w "Release" --limit 3
68+
69+# 7. If CLI was released, verify npm publish workflow triggered
70+unset GITHUB_TOKEN && gh run list -R GeiserX/LynxPrompt -w "Publish CLI" --limit 3
71+
72+# 8. If publish-cli didn't auto-trigger, manually trigger it:
73+unset GITHUB_TOKEN && gh workflow run "Publish CLI" -R GeiserX/LynxPrompt -f platforms=all
74+
75+# 9. Verify npm package was published
76+npm view lynxprompt versions --json | jq -r '.[-3:]'
77+```
78+
79+#### For a PATCH version (bug fixes only):
80+
81+Same process, but use `npm version patch` instead of `minor`.
82+
83+### ⚠️ CRITICAL RULES - NEVER BREAK THESE
84+
85+| ❌ NEVER DO THIS | ✅ DO THIS INSTEAD |
86+|------------------|-------------------|
87+| `git tag v0.24.0` | Let release.yml create tags |
88+| `git tag cli-v0.8.0` | Let release.yml create tags |
89+| `npm publish` locally | Use GitHub Actions workflow |
90+| Push tags manually | Let release.yml push tags |
91+| Use tag format `v*` | Workflow uses `app-v*` and `cli-v*` |
92+
93+### Troubleshooting Release Issues
94+
95+**Problem: Release workflow skips CLI/App release**
96+- Cause: No changes detected since last release tag
97+- Fix: Ensure you modified files in the right directory (cli/ for CLI, anything else for app)
98+
99+**Problem: Tag already exists error**
100+- Cause: Someone manually created a tag
101+- Fix: Delete the manual tag from remote AND local:
102+ ```bash
103+ git push origin --delete cli-v0.8.0
104+ git tag -d cli-v0.8.0
105+ ```
106+
107+**Problem: npm publish didn't happen**
108+- Cause: publish-cli.yml didn't trigger automatically
109+- Fix: Manually trigger the workflow:
110+ ```bash
111+ unset GITHUB_TOKEN && gh workflow run "Publish CLI" -R GeiserX/LynxPrompt -f platforms=all
112+ ```
113+
114+**Problem: npm says version already exists**
115+- Cause: Version was already published (maybe partial failure)
116+- Fix: Bump to next patch version and release again
117+
118+### Verifying a Successful Release
119+
120+```bash
121+# 1. Check GitHub Releases exist
122+unset GITHUB_TOKEN && gh release list -R GeiserX/LynxPrompt --limit 5
123+
124+# 2. Check npm has the new version
125+npm view lynxprompt version
126+
127+# 3. Check git tags exist
128+git fetch --tags
129+git tag -l "cli-v*" | tail -5
130+git tag -l "app-v*" | tail -5
131+```
132+
60133 ---
61134
62−*Generated by [LynxPrompt](https://lynxprompt.com) CLI*
135+## 🔄 CLI & WEB WIZARD FEATURE PARITY
136+
137+**The CLI (`lynxprompt` package) and Web Wizard MUST always have the same functionality.**
138+
139+When adding or modifying wizard features:
140+1. **Update both CLI and Web** - Any new wizard step, option, or configuration must be implemented in both:
141+ - Web: `src/app/wizard/` and related components
142+ - CLI: `cli/src/commands/init.ts` and `cli/src/utils/generator.ts`
143+2. **Same options** - Tech stacks, platforms, personas, boundaries, and presets must match
144+3. **Same output** - Generated configuration files must be identical regardless of source
145+4. **Test both** - Before deploying, verify the feature works in both CLI and Web
146+
147+---
148+
149+## 🚨 CRITICAL - READ FIRST
150+
151+### Always Backup Before Modifying Config Files
152+
153+Before modifying important config files (Caddyfile, docker-compose, etc.), ALWAYS create a backup first:
154+
155+```bash
156+# Example (always use Tailscale MagicDNS hostnames):
157+ssh root@watchtower.mango-alpha.ts.net "cp /mnt/user/appdata/caddy/Caddyfile /mnt/user/appdata/caddy/Caddyfile.old"
158+```
159+
160+### Always Check GitHub Actions After Push/Deploy
161+
162+After any push or deployment, ALWAYS check GitHub Actions logs:
163+
164+```bash
165+# List recent workflow runs
166+unset GITHUB_TOKEN && gh run list -R GeiserX/LynxPrompt --limit 5
167+
168+# View failed run logs
169+unset GITHUB_TOKEN && gh run view <RUN_ID> -R GeiserX/LynxPrompt --log-failed
170+
171+# View specific job logs
172+unset GITHUB_TOKEN && gh run view <RUN_ID> -R GeiserX/LynxPrompt --log
173+```
174+
175+If CI/CD fails, investigate and fix before considering deployment complete.
176+
177+### NEVER Restart Docker Containers
178+
179+**General rule**: Prefer `reload` commands over container restarts. Use Portainer GitOps to redeploy, not manual docker commands.
180+
181+**Caddy** - NEVER restart the container (takes 2+ minutes to rebuild with xcaddy). Instead:
182+```bash
183+ssh root@watchtower.mango-alpha.ts.net "docker exec caddy caddy fmt --overwrite /etc/caddy/Caddyfile && docker exec caddy caddy reload --config /etc/caddy/Caddyfile"
184+```
185+
186+**LynxPrompt** - Use Portainer GitOps to redeploy:
187+1. Update docker-compose.yml in private gitea repo
188+2. Push changes
189+3. Trigger Portainer redeploy via API (or wait for auto-sync)
190+
191+Never manually run `docker compose up` or `docker restart` - Portainer loses track of stack state.
192+
193+### Branching: `develop` for features, `main` for deps/security
194+
195+**Never push directly to `main`.** Always open a PR, wait for CI, and merge only with the owner's approval.
196+
197+**Feature / app / behavior changes** go through `develop` first:
198+
199+1. Work on `develop` branch
200+2. Test changes on dev environment (dev.lynxprompt.com)
201+3. Verify everything works correctly
202+4. Only then merge to `main` for production deployment
203+
204+```bash
205+# Switch to develop branch
206+git checkout develop
207+
208+# After testing is complete, merge to main
209+git checkout main
210+git merge develop
211+```
212+
213+**Dependency and security updates target `main` directly via PR.** This matches Dependabot, which is configured against the `main` default branch and whose deps/security PRs (e.g. #88–#97) merge straight to `main`. `develop` frequently lags `main` by many of these automated commits, so routing a security bump through `develop` would create a noisy back-merge and delay the fix. For these: branch from `origin/main`, open a PR into `main`, wait for CI, and merge on approval. Merging `package.json` / `cli/package.json` changes auto-triggers `release.yml` (patch bump + tags) — never bump versions or create tags by hand.
214+
215+## 🎯 Project Overview
216+
217+**LynxPrompt** is a SaaS web application that generates AI IDE configuration files (`.cursorrules`, `CLAUDE.md`, `.github/copilot-instructions.md`, `.windsurfrules`, etc.) through an intuitive wizard interface. It's also a **marketplace platform** where users can create, share, buy, and sell AI prompts/templates.
218+
219+- **Live URL**: https://lynxprompt.com
220+- **Dev URL**: https://dev.lynxprompt.com
221+- **Test URL**: https://test.lynxprompt.com
222+- **Status Page**: https://status.lynxprompt.com
223+- **Repository**: https://github.com/GeiserX/LynxPrompt
224+
225+---
226+
227+## 👤 Owner Context
228+
229+**Operator**: Sergio Fernández Rubio
230+**Trade Name**: GeiserCloud
231+**Contact**: privacy@lynxprompt.com / legal@lynxprompt.com / support@lynxprompt.com
232+
233+### Communication Style
234+
235+- **Be direct and efficient** - Don't over-explain or add unnecessary caveats
236+- **Do the work, don't ask permission** - If the task is clear, execute it
237+- **Wait for explicit deploy instruction** - Do NOT commit, build Docker, or deploy until the user explicitly says to
238+- **Use exact values when provided** - Don't modify user-provided values (emails, addresses, names, etc.)
239+
240+### Things I Like ✅
241+
242+- Clean, readable code without over-engineering
243+- Proper GDPR/EU legal compliance
244+- Self-hosted solutions (Umami analytics)
245+- Privacy-focused approaches (cookieless analytics, minimal data collection)
246+- Semver versioning for Docker images (e.g., `2.0.22`, never `:latest`)
247+- GitOps with Portainer for infrastructure management
248+- Docker Hub for all images (custom images built by GHA, pushed to `drumsergio/*`)
249+- Tailwind CSS for styling
250+- TypeScript with strict types
251+
252+### Things I Dislike ❌
253+
254+- **Restarting containers** when reload is possible (use `caddy reload`, not container restart)
255+- **Manual docker commands** for deployments (use Portainer GitOps)
256+- Over-engineering or unnecessary abstractions
257+- Adding features I didn't ask for
258+- Verbose explanations when action is needed
259+- Third-party analytics/tracking services
260+- Marketing consent flows (only transactional emails)
261+- Breaking changes without clear communication
262+- Using `:latest` tags for Docker images
263+- Creating unnecessary documentation files
264+
265+---
266+
267+## 🏗️ Tech Stack
268+
269+### Frontend
270+| Technology | Purpose |
271+|------------|---------|
272+| Next.js 16 | App Router, Server Components |
273+| React 19 | UI library |
274+| TypeScript | Type safety |
275+| Tailwind CSS | Styling |
276+| shadcn/ui | UI components |
277+| Zustand | Client state |
278+| TanStack Query | Server state |
279+
280+### Backend
281+| Technology | Purpose |
282+|------------|---------|
283+| Next.js API Routes | API endpoints |
284+| Prisma ORM | Database access |
285+| NextAuth.js 4.x | Authentication |
286+| Zod | Validation |
287+
288+### Databases
289+| Database | Purpose | Client |
290+|----------|---------|--------|
291+| PostgreSQL (app) | Templates, platforms, system data | `@prisma/client-app` |
292+| PostgreSQL (users) | Users, sessions, passkeys | `@prisma/client-users` |
293+| PostgreSQL (blog) | Blog posts and content | `@prisma/client-blog` |
294+| PostgreSQL (support) | Feedback forum data | `@prisma/client-support` |
295+
296+### Infrastructure
297+| Component | Details |
298+|-----------|---------|
299+| Docker | Multi-stage builds, images on Docker Hub (`drumsergio/lynxprompt`) |
300+| Portainer | Container management with GitOps |
301+| Tailscale | VPN for internal services (always use MagicDNS hostnames) |
302+| Umami | Self-hosted analytics (EU, cookieless) |
303+| Caddy | Reverse proxy (production + dev) |
304+
305+### Payments & Billing
306+| Component | Details |
307+|-----------|---------|
308+| Stripe | Payment processing, subscriptions |
309+| Stripe Customer Portal | Self-service billing management |
310+| Stripe Webhooks | Subscription lifecycle events |
311+
312+---
313+
314+## 🗄️ Multi-Database Architecture
315+
316+This project uses **four separate PostgreSQL databases** with distinct Prisma clients:
317+
318+```typescript
319+// System/application data (templates, platforms)
320+import { prismaApp } from "@/lib/db-app";
321+
322+// User data (users, sessions, passkeys, user templates)
323+import { prismaUsers } from "@/lib/db-users";
324+
325+// Blog posts and content
326+import { prismaBlog } from "@/lib/db-blog";
327+
328+// Support/feedback forum data
329+import { prismaSupport } from "@/lib/db-support";
330+```
331+
332+**Schema files:**
333+- `prisma/schema-app.prisma` → generates `@prisma/client-app`
334+- `prisma/schema-users.prisma` → generates `@prisma/client-users`
335+- `prisma/schema-blog.prisma` → generates `@prisma/client-blog`
336+- `prisma/schema-support.prisma` → generates `@prisma/client-support`
337+
338+**Commands:**
339+```bash
340+npm run db:generate # Generate all Prisma clients
341+npm run db:push # Push schema changes to all databases
342+npm run db:seed # Seed databases
343+```
344+
345+---
346+
347+## 🔐 Authentication
348+
349+### Providers
350+- GitHub OAuth
351+- Google OAuth
352+- Magic Link (email)
353+- Passkeys (WebAuthn)
354+
355+### User Roles
356+- `USER` - Default role
357+- `ADMIN` - Administrative access
358+- `SUPERADMIN` - Full system access (auto-promoted via `SUPERADMIN_EMAIL` env var)
359+
360+### Passkeys Implementation
361+```typescript
362+// IMPORTANT: Types come from @simplewebauthn/types, NOT @simplewebauthn/server
363+import { generateRegistrationOptions } from "@simplewebauthn/server";
364+import type { AuthenticatorTransportFuture } from "@simplewebauthn/types";
365+```
366+
367+---
368+
369+## 💰 Business Model
370+
371+### Marketplace Structure
372+- **Platform/Intermediary model** - Buyer-Seller contracts
373+- **LynxPrompt is NOT merchant of record** for individual purchases
374+- Subscriptions are direct contracts with LynxPrompt
375+
376+### Subscription Tiers (January 2026+)
377+| Tier | Monthly | Annual (10% off) | Features |
378+|------|---------|------------------|----------|
379+| Users | €0/month | €0/year | Full wizard, all platforms, API access, sell blueprints |
380+| Teams | €30/seat/month | €324/seat/year | Everything + AI editing, SSO, team blueprints |
381+
382+**Key changes:**
383+- All users now get full wizard access (basic + intermediate + advanced steps)
384+- AI features (editing, wizard assistant) are restricted to Teams users
385+- No more Pro/Max tiers - simplified to Users vs Teams
386+
387+### Revenue Split
388+- **70% to seller** / **30% to platform**
389+- Minimum price for paid templates: €5
390+- Minimum payout: €5 via PayPal
391+
392+---
393+
394+## 📜 Legal Compliance
395+
396+### GDPR Requirements
397+- Physical address disclosed
398+- Legal basis: Contract + Legitimate Interest
399+- No DPO appointed (stated in privacy policy)
400+- Self-hosted Umami analytics (cookieless)
401+- AEPD complaint rights mentioned
402+- Data deletion within 30 days of request
403+
404+### EU Consumer Rights
405+- 14-day withdrawal waived with explicit consent at checkout
406+- Consent checkbox required before purchase
407+- Store: user ID, timestamp, Terms version hash
408+
409+### Key Legal Documents
410+- `/privacy` - Privacy Policy (GDPR compliant)
411+- `/terms` - Terms of Service (marketplace clauses, EU compliant)
412+- Governing law: **Spain** (Courts of Cartagena)
413+
414+---
415+
416+## 🔧 Code Conventions
417+
418+### General Rules
419+- Use TypeScript strict mode
420+- Format with Prettier
421+- Lint with ESLint
422+- Use `text-foreground` for readable text (not `text-muted-foreground` for body text)
423+- Navigation order: `Pricing | Templates | Docs | [UserMenu]`
424+
425+### File Structure
426+```
427+LynxPrompt/
428+├── .github/ # GitHub Actions workflows
429+├── cli/ # CLI package (lynxprompt npm package)
430+│ ├── src/
431+│ │ ├── commands/ # CLI commands (init, login, list, etc.)
432+│ │ ├── utils/ # Detection, generation utilities
433+│ │ └── index.ts # Main entry point
434+│ ├── homebrew/ # Homebrew formula
435+│ ├── chocolatey/ # Chocolatey package
436+│ └── snap/ # Snap package config
437+├── docs/ # Documentation
438+├── prisma/ # Database schemas and seeds
439+├── public/ # Static assets
440+│ └── logos/
441+│ ├── agents/ # AI agent logos
442+│ └── brand/ # LynxPrompt branding
443+├── scripts/ # Build and migration scripts
444+├── src/
445+│ ├── app/ # Next.js App Router pages
446+│ │ ├── api/ # API routes
447+│ │ │ ├── cli-auth/ # CLI authentication endpoints
448+│ │ │ └── v1/ # Public API v1
449+│ │ └── [page]/ # Page components
450+│ ├── components/
451+│ │ ├── ui/ # shadcn/ui components
452+│ │ └── [feature].tsx # Feature components
453+│ ├── lib/
454+│ │ ├── db-*.ts # Database clients
455+│ │ ├── auth.ts # NextAuth config
456+│ │ └── utils.ts # Utilities
457+│ └── types/ # TypeScript types
458+├── tests/ # Test files
459+└── tooling/ # Internal tools
460+```
461+
462+### API Routes Pattern
463+```typescript
464+// Always check authentication
465+const session = await getServerSession(authOptions);
466+if (!session?.user?.id) {
467+ return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
468+}
469+
470+// Use appropriate database client
471+import { prismaApp } from "@/lib/db-app";
472+import { prismaUsers } from "@/lib/db-users";
473+```
474+
475+### Security Patterns
476+1. **Never reveal if email exists** (user enumeration)
477+2. **Always check ownership** for user resources (IDOR prevention)
478+3. **Use `useSession()`** from NextAuth, never localStorage for auth
479+4. **Sanitize user input** before storing
480+5. **Validate `callbackUrl`** - only relative paths or same-origin
481+
482+---
483+
484+## 🚀 Deployment
485+
486+### Environments
487+
488+| Environment | URL | Server | Image Source |
489+|-------------|-----|--------|-------------|
490+| Production | lynxprompt.com | watchtower | `drumsergio/lynxprompt:<semver>` (Docker Hub) |
491+| Development | dev.lynxprompt.com | geiserback | Same image as prod |
492+| Test | test.lynxprompt.com | geiserct | Same image as prod |
493+
494+### Build Process
495+
496+Images are built by GitHub Actions and pushed to **Docker Hub** (`drumsergio/lynxprompt`). Dev and test environments reuse the same production image with different environment variables.
497+
498+```bash
499+# Build Docker image (BuildKit optimized)
500+docker buildx build --platform linux/amd64 \
501+ -t drumsergio/lynxprompt:X.Y.Z \
502+ --push .
503+```
504+
505+**Build optimizations included:**
506+- `npm install` (not `npm ci`) — local npm 11 and Docker npm 10 produce incompatible lockfiles; `npm install` tolerates both
507+- BuildKit cache mounts keyed by `TARGETPLATFORM` (avoids ETXTBSY on QEMU arm64 cross-compilation)
508+- Base image: `node:22-alpine` (Node 20 EOL, and `@prisma/streams-local` requires Node >= 22)
509+- Parallel Prisma client generation
510+- `optimizePackageImports` for faster builds
511+
512+### Environment Variables
513+
514+See `env.example` for all required variables. Key categories:
515+
516+| Category | Variables |
517+|----------|-----------|
518+| Database | `DATABASE_URL_APP`, `DATABASE_URL_USERS`, `DATABASE_URL_BLOG`, `DATABASE_URL_SUPPORT` |
519+| Auth | `NEXTAUTH_SECRET`, `NEXTAUTH_URL`, `GITHUB_*`, `GOOGLE_*` |
520+| Email | `SMTP_HOST`, `SMTP_PORT`, `SMTP_USER`, `SMTP_PASSWORD` |
521+
522+| Analytics | `NEXT_PUBLIC_UMAMI_WEBSITE_ID` |
523+| Security | `TURNSTILE_SECRET_KEY`, `NEXT_PUBLIC_TURNSTILE_SITE_KEY` |
524+| Error Tracking | `SENTRY_DSN`, `NEXT_PUBLIC_SENTRY_DSN` |
525+
526+---
527+
528+## 🔒 Secrets Management
529+
530+**This project keeps secrets OUT of the repository.**
531+
532+### How Secrets are Handled
533+
534+1. **Development**: Use `.env` file (gitignored)
535+2. **Production**: Secrets stored in docker-compose.yml in a **private GitOps repository** (not this repo)
536+3. **CI/CD**: GitHub Secrets for deployment workflows
537+
538+### What Goes Where
539+
540+| Type | Location | Example |
541+|------|----------|---------|
542+| Placeholder values | `env.example` | `SMTP_HOST=smtp.example.com` |
543+| Development secrets | `.env` (local, gitignored) | Actual test keys |
544+| Production secrets | Private GitOps repo | Actual live keys |
545+| CI secrets | GitHub Secrets | Deploy tokens |
546+
547+### Security Checklist
548+- [ ] Never commit real secrets to this repository
549+- [ ] Use `env.example` as template only
550+- [ ] Keep production docker-compose in private repo
551+- [ ] Rotate secrets if accidentally exposed
552+
553+---
554+
555+## 🛠️ Common Tasks
556+
557+### Adding a New Page
558+1. Create `src/app/[pagename]/page.tsx`
559+2. Add navigation link to header
560+3. Include proper header/footer components
561+4. Use `text-foreground` for body text
562+
563+### Database Schema Changes
564+```bash
565+# 1. Edit the appropriate schema file
566+# prisma/schema-*.prisma
567+
568+# 2. Generate clients
569+npm run db:generate
570+
571+# 3. Push to database (local dev)
572+npm run db:push
573+
574+# 4. Build and deploy
575+```
576+
577+### Running Tests
578+```bash
579+npm test # Run all tests
580+npm run test:watch # Watch mode
581+npm run test:coverage # With coverage
582+```
583+
584+---
585+
586+## ⚠️ Known Issues
587+
588+1. **`useSearchParams` requires Suspense boundary** in client components
589+2. **Database pages need `export const dynamic = "force-dynamic"`** to prevent build-time DB access
590+3. **Container name conflicts**: Remove old containers before recreating
591+4. **Sentry config files at root**: Required by `@sentry/nextjs` - cannot be moved
592+5. **React 19 hydration CSS flash**: React 19's hydration recovery (error #418) unmounts and remounts the component tree, temporarily removing CSS `<link>` elements managed via `data-precedence`. A MutationObserver script in `src/app/layout.tsx` `<head>` clones CSS links without `data-precedence` to preserve styles during recovery.
593+6. **shields.io retired `visual-studio-marketplace` badge** — use static `img.shields.io/badge/` badges for VS Code marketplace links instead
594+7. **Chocolatey `nodejs` vs `nodejs-lts`** — the `nodejs` package (latest, currently v25) hangs in Chocolatey test VMs; always use `nodejs-lts` (stable v22.x) as a dependency in `.nuspec` files
595+8. **Portainer TLS certs** — Tailscale-issued Let's Encrypt certs expire every 90 days. Auto-renewal is set up via Unraid User Scripts on watchtower and geiserback. GHA deploy workflows use Tailscale MagicDNS hostnames (not IPs) for proper TLS validation
596+
597+## Satellite Repos — Known Workarounds
598+
599+| Repo | Issue | Workaround |
600+|------|-------|------------|
601+| `lynxprompt-vscode` | Dependabot bumps `@types/vscode` without bumping `engines.vscode` → `vsce` rejects | Publish workflow auto-syncs `engines.vscode` from `@types/vscode` before packaging |
602+| `lynxprompt-vscode` | `vsce` rejects SVGs in README | Use PNG images only in README (SVG ok elsewhere) |
603+| `lynxprompt-vscode` | Publish workflow version commit must push to main | Branch protection PR requirement removed; workflow commits with `[skip ci]` |
604+| `lynxprompt-action` | `@actions/glob` 0.6.x ESM-only exports breaks `@vercel/ncc` CJS bundling | Pinned to 0.5.1; Dependabot ignores it. Unpin when ncc adds ESM exports support |
605+| Helm chart | ArtifactHub `artifacthub-repo.yml` must be on `gh-pages` branch | The copy in chart source (`charts/lynxprompt/`) is NOT read by ArtifactHub; edit `gh-pages` directly for ignore rules and metadata |
606+
607+---
608+
609+## 📁 Key Files Reference
610+
611+| File | Purpose |
612+|------|---------|
613+| `src/lib/db-*.ts` | Database Prisma clients |
614+| `src/lib/auth.ts` | NextAuth configuration |
615+| `src/middleware.ts` | Rate limiting, security headers |
616+| `prisma/schema-*.prisma` | Database schemas |
617+| `src/app/layout.tsx` | Root layout (CSS preservation script) |
618+| `docs/ROADMAP.md` | Feature roadmap |
619+| `docs/SECURITY.md` | Security documentation |
620+
621+---
622+
623+## 📋 Checklist for AI Agents
624+
625+Before completing a task, verify:
626+
627+- [ ] Code follows TypeScript strict mode
628+- [ ] No secrets committed to repository
629+- [ ] Tests pass (if applicable)
630+- [ ] Linting passes
631+- [ ] Changes match the requested scope
632+
633+---
634+
635+*Last updated: April 2026*
636+
