Skip to content

Repository files navigation

Jade Three

Music website for Jade Three — a chronological showcase of releases with Spotify embeds, platform links, and song notes.

Built with Astro and Tailwind CSS. Deployed on Netlify at jadethreemusic.com.

Development

npm install
npm run dev # dev server at localhost:4321
npm run build # production build
npm run preview # preview production build

Key files

PathPurpose
src/data/releases.jsonAll release data — platform links, track data
src/content/songs/*.mdPer-song notes and metadata
src/content/artist/profile.mdArtist bio/profile
src/components/Astro UI components
clips.yamlApproved/sent Bluesky clips
scripts/Data-fetching and posting scripts

Adding a new release

Run the /new-release skill in Claude Code. It walks through the full workflow:

  1. Syncs release data from iTunes (npm run fetch-releases)
  2. Identifies which releases don't have a song page yet
  3. Asks for any missing platform URLs (Spotify, YouTube)
  4. Creates src/content/songs/<slug>.md with frontmatter
  5. Conducts a short interview and writes the answers into the file
  6. Generates Bluesky clips for the new song

To start: open Claude Code in this directory and type /new-release.

Updating release data only

To pull the latest iTunes data without going through the full workflow:

npm run fetch-releases # syncs from iTunes (no credentials required)

This preserves any existing Spotify/YouTube/Amazon links in releases.json.

Tests

npm test# Playwright end-to-end tests
npm run test:scripts # unit tests for post-clip.mjs

Posting clips to Bluesky

scripts/post-clip.mjs picks a random approved, unsent clip from clips.yaml and posts it to Bluesky with a link card. A launchd job (scripts/com.jade.jade3-to-bluesky.plist) runs this automatically on Tue/Thu/Sat at 1:14 PM.

Generating clips

scripts/generate-clips.mjs uses Claude to generate social media clips for each song from its markdown notes in src/content/songs/. Output is written to clips.yaml.

node scripts/generate-clips.mjs # all songs
node scripts/generate-clips.mjs stinger # one song by slug

Re-running skips songs that already have entries in clips.yaml. To regenerate a song, delete its entry first.

1. Get a Bluesky app password

  1. Log into Bluesky
  2. Go to Settings → Privacy and Security → App Passwords
  3. Create a new app password and copy it

2. Set environment variables

export BLUESKY_HANDLE=yourhandle.bsky.social
export BLUESKY_APP_PASSWORD=xxxx-xxxx-xxxx-xxxx

3. Mark clips for posting in clips.yaml

Each clip has two flags:

- approved: false # set to true to make eligible for postingsent: false # updated automatically after posting — don't change by handtext: | Your post text here. https://jadethreemusic.com/releases/your-song

Set approved: true on any clips you want to post. Leave sent alone — the script flips it to true automatically after a successful post.

4. Preview before posting (dry run)

node scripts/post-clip.mjs --dry-run

Prints the clip that would be posted without sending anything.

5. Post for real

node scripts/post-clip.mjs

Picks one eligible clip at random, posts it to Bluesky with a link card, then marks it sent: true in clips.yaml. Commit the updated clips.yaml afterward to keep the record in sync.

About

Website for my musical projects

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages