Monorepo for Aesthetic.Computer
aesthetic.computer
1#!/usr/bin/env node
2
3/**
4 * Create KidLisp Chords Playlist
5 *
6 * Generates a DP-1 playlist featuring common Western musical chords
7 * using the clock piece with notepat notation.
8 *
9 * Usage: node create-kidlisp-chords-playlist.mjs
10 */
11
12// Common Western chords using notepat notation
13// Format: name, notes (as they appear in clock)
14const chords = [
15 // Major Chords
16 { name: 'C Major', notes: 'ceg' },
17 { name: 'D Major', notes: 'dwv' }, // d f# a
18 { name: 'E Major', notes: 'ewh' }, // e g# b
19 { name: 'F Major', notes: 'fac' },
20 { name: 'G Major', notes: 'gbd' },
21 { name: 'A Major', notes: 'avh' }, // a c# e
22 { name: 'B Major', notes: 'bsi' }, // b d# f#
23
24 // Minor Chords
25 { name: 'C Minor', notes: 'crg' }, // c eb g
26 { name: 'D Minor', notes: 'dfa' },
27 { name: 'E Minor', notes: 'egb' },
28 { name: 'F Minor', notes: 'fry' }, // f ab c
29 { name: 'G Minor', notes: 'gqd' }, // g bb d
30 { name: 'A Minor', notes: 'ace' },
31 { name: 'B Minor', notes: 'bdi' }, // b d f#
32
33 // Seventh Chords
34 { name: 'C Major 7', notes: 'cegb' },
35 { name: 'D Major 7', notes: 'dwvv' }, // d f# a c#
36 { name: 'G Major 7', notes: 'gbdw' }, // g b d f#
37 { name: 'A Minor 7', notes: 'aceg' },
38 { name: 'E Minor 7', notes: 'egbd' },
39
40 // Diminished Chords
41 { name: 'C Diminished', notes: 'crq' }, // c eb gb
42 { name: 'D Diminished', notes: 'dfy' }, // d f ab
43 { name: 'B Diminished', notes: 'bdf' },
44
45 // Augmented Chords
46 { name: 'C Augmented', notes: 'cew' }, // c e g#
47 { name: 'F Augmented', notes: 'fav' }, // f a c#
48
49 // Suspended Chords
50 { name: 'C Sus4', notes: 'cfg' },
51 { name: 'D Sus4', notes: 'dga' },
52 { name: 'G Sus4', notes: 'gcd' },
53 { name: 'A Sus4', notes: 'ade' },
54
55 // Extended Chords
56 { name: 'C Major 9', notes: 'cegbd' },
57 { name: 'D Minor 9', notes: 'dfae' },
58 { name: 'G Dominant 7', notes: 'gbdf' },
59];
60
61const FEED_API_URL = 'https://feed.aesthetic.computer/api/v1';
62const API_SECRET = process.env.FEED_API_SECRET || 'YOUR_FEED_API_SECRET_HERE';
63
64/**
65 * Generate DP-1 compliant playlist from chord definitions
66 */
67function generateChordsPlaylist() {
68 const duration = 16; // seconds per chord
69
70 // Create the DP-1 playlist
71 const playlist = {
72 dpVersion: '1.1.0',
73 title: 'Chords for `clock`',
74 summary: 'Western musical chords using the clock piece with notepat notation',
75 items: chords.map((chord, index) => ({
76 title: chord.name,
77 // Include playlist params so device.kidlisp.com shows progress bar
78 source: `https://device.kidlisp.com/clock~^${chord.notes}?playlist=true&duration=${duration}&index=${index}&total=${chords.length}`,
79 duration: duration,
80 license: 'open',
81 provenance: {
82 type: 'offChainURI',
83 uri: `https://kidlisp.com/clock~^${chord.notes}`,
84 },
85 })),
86 defaults: {
87 display: {
88 scaling: 'fit',
89 background: '#000000',
90 margin: '0%'
91 },
92 license: 'open',
93 duration: 24
94 }
95 };
96
97 return playlist;
98}
99
100/**
101 * Upload playlist to feed API
102 */
103async function uploadPlaylist(playlist) {
104 const response = await fetch(`${FEED_API_URL}/playlists`, {
105 method: 'POST',
106 headers: {
107 'Content-Type': 'application/json',
108 'Authorization': `Bearer ${API_SECRET}`,
109 },
110 body: JSON.stringify(playlist),
111 });
112
113 if (!response.ok) {
114 const error = await response.text();
115 throw new Error(`Failed to upload playlist: ${response.status} ${error}`);
116 }
117
118 return await response.json();
119}
120
121/**
122 * Main execution
123 */
124async function main() {
125 try {
126 console.log('🎵 Creating KidLisp Chords playlist...\n');
127
128 // Generate playlist
129 const playlist = generateChordsPlaylist();
130 console.log(`📝 Generated playlist with ${playlist.items.length} chords`);
131 console.log(`🎵 Sample chords: ${chords.slice(0, 5).map(c => c.name).join(', ')}...\n`);
132
133 // Upload playlist
134 console.log('📤 Uploading playlist to feed.aesthetic.computer...');
135 const playlistResult = await uploadPlaylist(playlist);
136 console.log(`✅ Playlist uploaded successfully! ID: ${playlistResult.id}`);
137 console.log(`🔗 ${FEED_API_URL}/playlists/${playlistResult.id}\n`);
138
139 console.log('🎉 Done!');
140 process.exit(0);
141 } catch (error) {
142 console.error('❌ Error:', error.message);
143 process.exit(1);
144 }
145}
146
147main();