Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

DP1 Feed Worker - Complete Setup Guide#

📋 Overview#

I've integrated the DP1 Feed Operator API into your aesthetic-computer repository. The worker will be deployed to feed.aesthetic.computer as a Cloudflare Worker.

What's Been Done#

  1. Cloned Repository: Added dp1-feed/ to your repo
  2. Updated Configuration: Modified wrangler.toml for aesthetic.computer domain
  3. Created Scripts: Setup and deployment automation scripts
  4. Added Package Scripts: Convenience commands in main package.json
  5. Added ripgrep: Installed rg in your Docker container and Dockerfile
  6. Found Cloudflare Credentials: Located in dark-window/conductor.env

Your Cloudflare Credentials#

Found in /workspaces/aesthetic-computer/dark-window/conductor.env:

  • Email: me@jas.life
  • API Token: YOUR_CLOUDFLARE_API_KEY_HERE
  • Account ID: a23b54e8877a833a1cf8db7765bce3ca (from your DNS link)

🚀 Deployment Steps#

Step 1: Authenticate Wrangler#

# Set environment variables
set -x CLOUDFLARE_API_TOKEN "YOUR_CLOUDFLARE_API_KEY_HERE"
set -x CLOUDFLARE_EMAIL "me@jas.life"

# Authenticate wrangler (choose one method)
# Option A: Interactive login (opens browser)
cd dp1-feed
wrangler login

# Option B: Use API token directly
wrangler config
# When prompted, paste your API token

Step 2: Create Cloudflare Resources#

Run the setup script to create KV namespaces and queues:

cd dp1-feed
./setup-resources.fish

Or manually from the root:

npm run feed:setup

Important: After running this, you'll see output with KV namespace IDs. You need to:

  1. Copy those IDs
  2. Update dp1-feed/wrangler.toml in the [env.production.kv_namespaces] sections

Example output:

Created namespace with title "aesthetic-feed-DP1_PLAYLISTS"
 ID: abc123def456...

Created namespace with title "aesthetic-feed-DP1_CHANNELS"
 ID: ghi789jkl012...

Update wrangler.toml:

[[env.production.kv_namespaces]]
binding = "DP1_PLAYLISTS"
id = "abc123def456..."  # <-- Update this

[[env.production.kv_namespaces]]
binding = "DP1_CHANNELS"
id = "ghi789jkl012..."  # <-- Update this

Step 3: Set Secrets#

Generate and set required secrets:

cd dp1-feed

# Generate a secure API secret
set -l api_secret (openssl rand -hex 32)
echo "Generated API Secret: $api_secret"
echo $api_secret | wrangler secret put API_SECRET --env production

# Generate Ed25519 key pair for signing
npm run jwt:generate-keys
# This creates private-key.txt and public-key.txt

# Set the private key as secret
cat private-key.txt | wrangler secret put ED25519_PRIVATE_KEY --env production

# Optional: Set JWT configuration if using JWT auth
echo "your-issuer" | wrangler secret put JWT_ISSUER --env production
echo "your-audience" | wrangler secret put JWT_AUDIENCE --env production

Save your API secret! You'll need it for write operations.

Step 4: Deploy the Worker#

# From root
npm run feed:deploy

# Or from dp1-feed directory
cd dp1-feed
./deploy-feed.fish production

Step 5: Set Up Custom Domain#

After deployment, you need to configure the custom domain:

  1. Go to https://dash.cloudflare.com/
  2. Select your account
  3. Go to Workers & Pages
  4. Click on aesthetic-feed
  5. Go to Settings > Domains & Routes
  6. Click Add Custom Domain
  7. Enter: feed.aesthetic.computer
  8. Click Add Domain

Cloudflare will automatically:

  • Create the necessary DNS CNAME record
  • Set up SSL/TLS
  • Route traffic to your worker

Option B: Using Cloudflare API (Automated)#

You can automate this using your existing conductor.mjs pattern. Create a script:

// deploy-feed-domain.mjs
import fetch from 'node-fetch';

const CLOUDFLARE_EMAIL = process.env.CLOUDFLARE_EMAIL;
const CLOUDFLARE_API_TOKEN = process.env.CLOUDFLARE_API_TOKEN;
const ZONE_ID = 'a23b54e8877a833a1cf8db7765bce3ca';
const WORKER_NAME = 'aesthetic-feed';

const headers = {
  'X-Auth-Email': CLOUDFLARE_EMAIL,
  'X-Auth-Key': CLOUDFLARE_API_TOKEN,
  'Content-Type': 'application/json',
};

// Add custom domain to worker
const response = await fetch(
  `https://api.cloudflare.com/client/v4/accounts/${ZONE_ID}/workers/domains`,
  {
    method: 'POST',
    headers,
    body: JSON.stringify({
      hostname: 'feed.aesthetic.computer',
      service: WORKER_NAME,
      environment: 'production'
    })
  }
);

const result = await response.json();
console.log(result);

Step 6: Test the Deployment#

# Health check
curl https://feed.aesthetic.computer/api/v1/health

# Get API info
curl https://feed.aesthetic.computer/api/v1

# Test creating a playlist (use your API_SECRET)
curl -X POST https://feed.aesthetic.computer/api/v1/playlists \
  -H "Authorization: Bearer YOUR_API_SECRET_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "dpVersion": "1.0.0",
    "title": "aesthetic-test",
    "items": [
      {
        "source": "https://aesthetic.computer/prompt",
        "duration": 300,
        "license": "open"
      }
    ]
  }'

📝 Available Commands#

From the root of aesthetic-computer:

npm run feed:dev           # Run local dev server
npm run feed:setup         # Create Cloudflare resources
npm run feed:deploy        # Deploy to production
npm run feed:deploy:dev    # Deploy to dev environment
npm run feed:test          # Run API tests
npm run feed:logs          # Watch production logs

🔍 Monitoring & Debugging#

View Real-time Logs#

cd dp1-feed
wrangler tail --env production

Or from root:

npm run feed:logs

Check Worker Status#

Visit: https://dash.cloudflare.com/

  • Navigate to Workers & Pages > aesthetic-feed
  • View metrics, logs, and errors

Local Development#

Run the worker locally:

cd dp1-feed
npm run worker:dev
# Visit http://localhost:8787/api/v1

📚 API Documentation#

Authentication#

All write operations require authentication:

Authorization: Bearer YOUR_API_SECRET

Key Endpoints#

  • GET /api/v1 - API information
  • GET /api/v1/health - Health check
  • GET /api/v1/playlists - List all playlists
  • POST /api/v1/playlists - Create a playlist (auth required)
  • GET /api/v1/playlists/{id} - Get specific playlist
  • PUT /api/v1/playlists/{id} - Update playlist (auth required)
  • DELETE /api/v1/playlists/{id} - Delete playlist (auth required)
  • GET /api/v1/channels - List all channels
  • POST /api/v1/channels - Create a channel (auth required)

Async Operations#

For high-throughput scenarios, use async mode:

curl -X POST https://feed.aesthetic.computer/api/v1/playlists \
  -H "Authorization: Bearer YOUR_API_SECRET" \
  -H "Prefer: respond-async" \
  -H "Content-Type: application/json" \
  -d '...'
# Returns 202 Accepted immediately

🎨 Integration with Aesthetic Computer#

Using the Feed API in Pieces#

// Example piece that fetches playlists
export async function boot({ api }) {
  const response = await fetch('https://feed.aesthetic.computer/api/v1/playlists');
  const playlists = await response.json();
  console.log('Playlists:', playlists);
}

Creating Playlists from Pieces#

export async function boot({ api }) {
  // You would store API_SECRET securely, not in client code
  const playlist = {
    dpVersion: "1.0.0",
    title: "my-aesthetic-playlist",
    items: [
      {
        source: "https://aesthetic.computer/wand",
        duration: 300,
        license: "open"
      }
    ]
  };
  
  const response = await fetch('https://feed.aesthetic.computer/api/v1/playlists', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_SECRET',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(playlist)
  });
  
  const result = await response.json();
  console.log('Created playlist:', result);
}

🔧 Troubleshooting#

"Worker not found" error#

  • Wait a few minutes after deployment
  • Check deployment status: wrangler deployments list --env production
  • Verify worker name matches in wrangler.toml

Custom domain not working#

  • Check DNS propagation: dig feed.aesthetic.computer
  • Verify custom domain is added in Cloudflare dashboard
  • Wait up to 5 minutes for DNS changes

KV errors#

  • Verify namespace IDs in wrangler.toml match created namespaces
  • Check bindings are correct (DP1_PLAYLISTS, DP1_CHANNELS, DP1_PLAYLIST_ITEMS)

Queue errors#

  • Verify queue name matches in wrangler.toml
  • Check queue exists: wrangler queues list

Authentication errors#

  • Verify API_SECRET is set: wrangler secret list --env production
  • Check Bearer token format in requests
  • Ensure ED25519_PRIVATE_KEY is properly formatted

📖 Additional Resources#

🎯 Next Steps#

  1. Run npm run feed:setup to create resources
  2. Update namespace IDs in wrangler.toml
  3. Set secrets with wrangler secret put
  4. Deploy with npm run feed:deploy
  5. Set up custom domain in Cloudflare dashboard
  6. Test with curl https://feed.aesthetic.computer/api/v1/health

Need help? Check the detailed setup guide in dp1-feed/AESTHETIC-COMPUTER-SETUP.md