Tech notes regarding AI

ChordPro Editor — Build & Deploy Documentation

A Ghost theme integrated ChordPro editor with an AI cleaning service backed by the Anthropic API.
Built for mcox.ca. Documents everything needed to rebuild from scratch.


What This Is

A custom Ghost page that lets you:

  1. Paste messy scraped chord/lyric text from any source
  2. Have Claude (via Anthropic API) clean it into valid ChordPro format
  3. Edit chord placement visually — chords above lyrics, draggable to correct syllables
  4. Copy the finished ChordPro and paste it into a Ghost song post

File Overview

Ghost Theme Files (in your theme repo)

music-edition/
  assets/
    js/
      chopro-editor.js      ← Editor logic, AI fetch call
    css/
      chopro-editor.css     ← Editor styles, namespaced cpe-
  page-chopro-editor.hbs    ← Ghost custom page template

Node Proxy (on the server)

/var/www/chopro-proxy/
  server.js                 ← Express proxy app
  package.json              ← Dependencies
  .env                      ← API key (never in git)
  .env.example              ← Template (safe to commit)
  chopro-proxy.service      ← systemd service file

Ghost Theme Setup

1. Page Template

Create page-chopro-editor.hbs in your theme root.
The template uses {{#contentFor "scripts"}} to load the editor JS only on this page.

2. Ghost Page

  • Create a new page in Ghost admin
  • Title: ChordPro Editor (or whatever you like)
  • Under Page settings → Template → select chopro-editor
  • Set visibility to Staff only or leave public — your call
  • Publish

3. CSS Build Pipeline

chopro-editor.css goes through your existing Gulp build pipeline.
It hooks into your existing --music-* CSS variables and body[data-theme="dark"]
so dark mode works automatically.


Node Proxy Setup (Droplet)

1. Create the directory and copy files

sudo mkdir -p /var/www/chopro-proxy
sudo cp server.js package.json .env.example /var/www/chopro-proxy/
sudo chown -R www-data:www-data /var/www/chopro-proxy

2. Install dependencies

cd /var/www/chopro-proxy
sudo -u www-data npm install

3. Create the .env file

sudo cp .env.example .env
sudo nano .env

Add your Anthropic API key:

ANTHROPIC_API_KEY=sk-ant-your-key-here
PORT=3000

Lock down permissions:

sudo chmod 600 /var/www/chopro-proxy/.env
sudo chown www-data:www-data /var/www/chopro-proxy/.env

4. Install the systemd service

sudo cp chopro-proxy.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable chopro-proxy
sudo systemctl start chopro-proxy

Verify it's running:

sudo systemctl status chopro-proxy
curl http://localhost:3000/api/health

Should return: {"status":"ok","service":"chopro-proxy"}

5. NGINX config

Add the location blocks from chopro-api.nginx.conf inside your existing
server {} block for mcox.ca. Usually in:

/etc/nginx/sites-available/mcox.ca

Then test and reload:

sudo nginx -t
sudo systemctl reload nginx

Local Dev Setup (Mint machine)

1. Run the proxy locally

cd /path/to/chopro-proxy
cp .env.example .env
# Add your API key to .env
npm install
npm run dev

2. NGINX local config

Add the same location blocks from chopro-api.nginx.conf to your
dev.notes NGINX config (or whichever local site hosts the editor).

sudo nginx -t
sudo systemctl reload nginx

The editor fetch call hits /api/clean as a relative URL, so it works
on any domain — local or live — as long as NGINX is proxying to Node.


How the AI Clean Works

  1. User pastes messy text into the paste panel
  2. Browser POSTs { text: "..." } to /api/clean on the same domain
  3. NGINX proxies to localhost:3000/api/clean
  4. Node proxy calls Anthropic API with the ChordPro system prompt
  5. Claude returns clean ChordPro — no explanation, just the file
  6. Proxy returns { chopro: "..." } to the browser
  7. Editor loads the ChordPro and renders it for editing

The Anthropic API key never touches the browser.


Useful Commands

# Proxy service management
sudo systemctl status chopro-proxy
sudo systemctl restart chopro-proxy
sudo systemctl stop chopro-proxy

# View proxy logs
sudo journalctl -u chopro-proxy -f

# Health check
curl https://mcox.ca/api/health

# Test the clean endpoint
curl -X POST https://mcox.ca/api/clean \
  -H "Content-Type: application/json" \
  -d '{"text": "[C]Test [G]song"}'

Rebuild Checklist (if starting fresh)

  • [ ] Node 18+ installed (Ghost requires it, so it will be there)
  • [ ] Copy proxy files to /var/www/chopro-proxy/
  • [ ] npm install in proxy directory
  • [ ] Create .env with ANTHROPIC_API_KEY
  • [ ] Install and start chopro-proxy.service via systemd
  • [ ] Add NGINX location blocks for /api/clean and /api/health
  • [ ] Reload NGINX
  • [ ] Deploy Ghost theme with chopro-editor.js, chopro-editor.css, page-chopro-editor.hbs
  • [ ] Create Ghost page using chopro-editor template
  • [ ] Test health endpoint
  • [ ] Test clean endpoint with a real paste

Notes

  • The editor is namespaced cpe- in CSS and cpeEditor in JS to avoid
    conflicts with the existing chordpro.js (namespaced cp-) which handles
    song page rendering, transposition, autoscroll, setlist, etc.
  • The proxy system prompt lives in server.js — edit it there if you want
    to tune the AI output behaviour.
  • Anthropic API billing is pay-as-you-go. Each clean call is a short
    completion — fractions of a cent per song.