Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions .claude/commands/debug-prod.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Debug Production

Investigate production issues on the live server.

## Access

- **SSH**: `ssh root@167.235.133.87`
- **App directory**: `/opt/pseuno`

## Common commands

All commands below assume you are in `/opt/pseuno` on the server.

### View logs
```bash
docker compose -f docker-compose.prod.yml logs --tail=200 backend
```

### View all service logs
```bash
docker compose -f docker-compose.prod.yml logs --tail=100
```

### Filter errors
```bash
docker compose -f docker-compose.prod.yml logs backend 2>&1 | grep -i error | tail -30
```

### Check health
```bash
curl -s localhost:8000/health
```

### Check running containers
```bash
docker compose -f docker-compose.prod.yml ps
```

### Database access
```bash
docker compose -f docker-compose.prod.yml exec postgres psql -U pseuno -d pseuno
```

### Redis
```bash
docker compose -f docker-compose.prod.yml exec redis redis-cli
```

### Restart backend
```bash
docker compose -f docker-compose.prod.yml restart backend
```

### Deploy latest
```bash
cd /opt/pseuno && git pull && docker compose -f docker-compose.prod.yml up -d --build backend
```

## Investigation workflow

1. SSH in and check health first
2. View recent logs, filter for errors
3. Check if containers are running
4. If needed, check DB/Redis state
5. Restart backend if it's stuck
6. If a code fix is needed, deploy from main after merging the fix
36 changes: 36 additions & 0 deletions .claude/commands/test-frontend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Test Frontend

Validate frontend changes compile, lint, and build correctly.

## Steps

### 1. Type check

```bash
cd frontend && npx tsc --noEmit
```
Must have zero errors.

### 2. Lint

```bash
cd frontend && npm run lint
```
Must have zero warnings (strict policy).

### 3. Build

```bash
cd frontend && npm run build
```
Must succeed.

### 4. E2E tests (if dev stack is running)

```bash
cd frontend && npx playwright test
```

### 5. Visual verification (if making UI changes)

Open `localhost:5173` in a browser (via Playwright MCP) and visually verify the change looks correct.
70 changes: 70 additions & 0 deletions .claude/commands/test-perf.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Test Performance

Benchmark endpoint latency. Run this when making changes that could affect generation speed.

## Prerequisites

1. Verify dev stack is up: `curl -s localhost:8000/health`
2. If not running, run `make dev-up` and wait for health check to pass.

## Steps

### 1. Benchmark `/generate/input-concept`

Call 5 times and report min/max/avg latency. Target: <2s each.

```bash
for i in 1 2 3 4 5; do
time curl -s -X POST localhost:8000/generate/input-concept \
-H "Content-Type: application/json" \
-d '{"raw_input": "upbeat pop song about summer"}' > /dev/null
done
```

### 2. Benchmark `/generate/advanced`

Call 3 times with different inputs. Target: <15s each.

```bash
curl -s -w "\n%{time_total}s\n" -X POST localhost:8000/generate/advanced \
-H "Content-Type: application/json" \
-d '{"user_prompt": "indie rock with jangly guitars", "lyrics_about": "leaving home for the first time"}'

curl -s -w "\n%{time_total}s\n" -X POST localhost:8000/generate/advanced \
-H "Content-Type: application/json" \
-d '{"user_prompt": "lo-fi hip hop beats", "lyrics_about": "late night studying"}'

curl -s -w "\n%{time_total}s\n" -X POST localhost:8000/generate/advanced \
-H "Content-Type: application/json" \
-d '{"user_prompt": "orchestral film score", "lyrics_about": ""}'
```

### 3. Benchmark `/generate/refine`

Call 3 times with `refine_target=lyrics`. Target: <15s each.

Use the full response from step 2 to build the refine request (the endpoint requires the current snapshot, not just a generation_id):
```bash
curl -s -w "\n%{time_total}s\n" -X POST localhost:8000/generate/refine \
-H "Content-Type: application/json" \
-d '{
"suno_prompt": "<suno_prompt from step 2>",
"lyrics": "<lyrics from step 2>",
"exclude": "<exclude from step 2>",
"title": "<concept_title from step 2>",
"weirdness": <weirdness from step 2>,
"change_request": "make it more emotional",
"refine_target": "lyrics"
}'
```

### 4. Compare (if testing a change)

If benchmarking before/after a code change:
1. Run steps 1-3 on the base branch, save results
2. Switch to feature branch, run again
3. Report the delta for each endpoint

### 5. Save results

Save the report to `benchmarks/perf-YYYY-MM-DD.md` (use today's date). Include the git branch/commit, per-call latencies, and min/max/avg for each endpoint. See `benchmarks/README.md` for the format.
97 changes: 97 additions & 0 deletions .claude/commands/test-quality.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Test Quality

Assess generation quality by hitting real endpoints. Run this after prompt or generation changes.

## Prerequisites

1. Verify dev stack is up: `curl -s localhost:8000/health`
2. If not running, run `make dev-up` and wait for health check to pass.

## Steps

### 1. Generate 5 songs across varied genres

Call `POST localhost:8000/generate/advanced` with these inputs:

```bash
# Country
curl -s -X POST localhost:8000/generate/advanced \
-H "Content-Type: application/json" \
-d '{"user_prompt": "classic country with steel guitar and fiddle", "lyrics_about": "driving down a dirt road at sunset"}'

# Punk
curl -s -X POST localhost:8000/generate/advanced \
-H "Content-Type: application/json" \
-d '{"user_prompt": "fast aggressive punk rock", "lyrics_about": "being fed up with corporate greed"}'

# Hip-hop
curl -s -X POST localhost:8000/generate/advanced \
-H "Content-Type: application/json" \
-d '{"user_prompt": "boom bap hip hop with jazz samples", "lyrics_about": "growing up in the city"}'

# Folk
curl -s -X POST localhost:8000/generate/advanced \
-H "Content-Type: application/json" \
-d '{"user_prompt": "acoustic folk with fingerpicking", "lyrics_about": "a small town slowly disappearing"}'

# Electronic
curl -s -X POST localhost:8000/generate/advanced \
-H "Content-Type: application/json" \
-d '{"user_prompt": "dark synthwave with arpeggiated bass", "lyrics_about": "neon lights in an empty city"}'
```

Capture full JSON responses from each.

### 2. Assess vocabulary

Read the lyrics from each response. Check:
- **Banned/overused words**: silver, velvet, neon, shattered, whisper, shadows, echoes, crimson, golden, embers
- Flag if any of these appear in 3+ of the 5 songs
- Check that vocabulary feels genre-appropriate (country should sound different from punk)

### 3. Assess chorus quality

Parse `[Chorus]` sections from each song. Flag if any chorus has the same line repeated 3+ times consecutively.

### 4. Assess style names

Check that each response's `concept_title` / style name is:
- Short (under 30 characters)
- Descriptive, not a full style prompt sentence

### 5. Assess structure

For each song, verify:
- Section tags are present (`[Verse]`, `[Chorus]`, etc.)
- No stage directions in lyrics (e.g., "(softly)", "(guitar solo)")
- No periods at end of lines

### 6. Test refine

Take one generated song's full response and call refine. The refine endpoint requires the full current snapshot:
```bash
curl -s -X POST localhost:8000/generate/refine \
-H "Content-Type: application/json" \
-d '{
"suno_prompt": "<suno_prompt from step 1>",
"lyrics": "<lyrics from step 1>",
"exclude": "<exclude from step 1>",
"title": "<concept_title from step 1>",
"weirdness": <weirdness from step 1>,
"change_request": "make the chorus more upbeat and energetic",
"refine_target": "lyrics"
}'
```

Verify:
- `changed_fields` includes "lyrics"
- `changed_fields` does NOT include "suno_prompt"
- Completed in <30s

### 7. Report

Summarize findings: what passed, what failed, with specific examples of issues found.

### 8. Save results

Save the report to `benchmarks/quality-YYYY-MM-DD.md` (use today's date). Include the git branch/commit, per-song results for each check (vocabulary, chorus, style names, structure), and a summary. See `benchmarks/README.md` for the format.
17 changes: 17 additions & 0 deletions .claude/commands/update-rules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Update Rules

Add new conventions or pitfalls to CLAUDE.md when you discover them during a task.

## Steps

1. Read current `CLAUDE.md` at the project root.
2. Identify the new convention, pattern, or pitfall discovered during the current task.
3. Add it to the appropriate section (keep entries concise, 1-2 lines).
4. Don't remove existing rules unless they're demonstrably wrong.

## Examples of things to add

- A new testing pattern you had to figure out
- A file that's easy to break and how to avoid it
- A config value that doesn't do what its name suggests
- An API behavior that's surprising or undocumented
54 changes: 54 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
backend-lint:
runs-on: ubuntu-latest
defaults:
run:
working-directory: backend
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
- run: pip install -r requirements.txt ruff
- run: python -m ruff check app/ tests/

backend-test:
runs-on: ubuntu-latest
defaults:
run:
working-directory: backend
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
- run: pip install -r requirements.txt
- run: >-
python -m pytest -v
--ignore=tests/test_artist_bank_routing.py
--ignore=tests/test_v8_channel_split.py

frontend-build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontend
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: npm
cache-dependency-path: frontend/package-lock.json
- run: npm ci
- run: npm run build
Loading