dj-claude 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin.mjs +24 -0
- package/dist/App.d.ts +6 -0
- package/dist/App.d.ts.map +1 -0
- package/dist/App.js +64 -0
- package/dist/App.js.map +1 -0
- package/dist/audio/engine.d.ts +15 -0
- package/dist/audio/engine.d.ts.map +1 -0
- package/dist/audio/engine.js +117 -0
- package/dist/audio/engine.js.map +1 -0
- package/dist/audio/polyfill.d.ts +2 -0
- package/dist/audio/polyfill.d.ts.map +1 -0
- package/dist/audio/polyfill.js +122 -0
- package/dist/audio/polyfill.js.map +1 -0
- package/dist/components/CodeDisplay.d.ts +7 -0
- package/dist/components/CodeDisplay.d.ts.map +1 -0
- package/dist/components/CodeDisplay.js +12 -0
- package/dist/components/CodeDisplay.js.map +1 -0
- package/dist/components/DancingClaude.d.ts +6 -0
- package/dist/components/DancingClaude.d.ts.map +1 -0
- package/dist/components/DancingClaude.js +26 -0
- package/dist/components/DancingClaude.js.map +1 -0
- package/dist/components/Header.d.ts +8 -0
- package/dist/components/Header.d.ts.map +1 -0
- package/dist/components/Header.js +28 -0
- package/dist/components/Header.js.map +1 -0
- package/dist/components/PromptInput.d.ts +9 -0
- package/dist/components/PromptInput.d.ts.map +1 -0
- package/dist/components/PromptInput.js +7 -0
- package/dist/components/PromptInput.js.map +1 -0
- package/dist/components/SpeechBubble.d.ts +6 -0
- package/dist/components/SpeechBubble.d.ts.map +1 -0
- package/dist/components/SpeechBubble.js +25 -0
- package/dist/components/SpeechBubble.js.map +1 -0
- package/dist/components/StatusBar.d.ts +6 -0
- package/dist/components/StatusBar.d.ts.map +1 -0
- package/dist/components/StatusBar.js +6 -0
- package/dist/components/StatusBar.js.map +1 -0
- package/dist/headless.d.ts +2 -0
- package/dist/headless.d.ts.map +1 -0
- package/dist/headless.js +37 -0
- package/dist/headless.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/ascii-frames.d.ts +3 -0
- package/dist/lib/ascii-frames.d.ts.map +1 -0
- package/dist/lib/ascii-frames.js +82 -0
- package/dist/lib/ascii-frames.js.map +1 -0
- package/dist/lib/claude.d.ts +3 -0
- package/dist/lib/claude.d.ts.map +1 -0
- package/dist/lib/claude.js +44 -0
- package/dist/lib/claude.js.map +1 -0
- package/dist/lib/config.d.ts +3 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +27 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/parseCode.d.ts +8 -0
- package/dist/lib/parseCode.d.ts.map +1 -0
- package/dist/lib/parseCode.js +94 -0
- package/dist/lib/parseCode.js.map +1 -0
- package/dist/lib/prompts.d.ts +2 -0
- package/dist/lib/prompts.d.ts.map +1 -0
- package/dist/lib/prompts.js +221 -0
- package/dist/lib/prompts.js.map +1 -0
- package/dist/lib/reducer.d.ts +4 -0
- package/dist/lib/reducer.d.ts.map +1 -0
- package/dist/lib/reducer.js +79 -0
- package/dist/lib/reducer.js.map +1 -0
- package/dist/lib/session.d.ts +4 -0
- package/dist/lib/session.d.ts.map +1 -0
- package/dist/lib/session.js +45 -0
- package/dist/lib/session.js.map +1 -0
- package/dist/lib/types.d.ts +49 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +2 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/mcp/server.d.ts +2 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +166 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/state.d.ts +16 -0
- package/dist/mcp/state.d.ts.map +1 -0
- package/dist/mcp/state.js +32 -0
- package/dist/mcp/state.js.map +1 -0
- package/mcp.mjs +15 -0
- package/package.json +45 -0
package/dist/headless.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Headless entry point — no Ink/React, console output only.
|
|
2
|
+
// Usage: node bin.mjs --headless "chill beats" --duration 10
|
|
3
|
+
import { getApiKey } from './lib/config.js';
|
|
4
|
+
import { streamChat } from './lib/claude.js';
|
|
5
|
+
import { parseStreamingCode } from './lib/parseCode.js';
|
|
6
|
+
import { initEngine, safeEvaluate, hush } from './audio/engine.js';
|
|
7
|
+
export async function runHeadless(prompt, durationSec) {
|
|
8
|
+
const apiKey = getApiKey();
|
|
9
|
+
console.log('[dj-claude] Initializing audio engine...');
|
|
10
|
+
await initEngine();
|
|
11
|
+
console.log('[dj-claude] Audio ready. Streaming from Claude...');
|
|
12
|
+
let fullText = '';
|
|
13
|
+
for await (const chunk of streamChat(apiKey, prompt, '', [])) {
|
|
14
|
+
fullText += chunk;
|
|
15
|
+
}
|
|
16
|
+
const parsed = parseStreamingCode(fullText);
|
|
17
|
+
const code = parsed.isComplete ? parsed.extractedCode : parsed.displayCode;
|
|
18
|
+
if (!code) {
|
|
19
|
+
console.error('[dj-claude] Could not parse code from Claude response.');
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
if (parsed.mcCommentary) {
|
|
23
|
+
console.log(`[dj-claude] ${parsed.mcCommentary}`);
|
|
24
|
+
}
|
|
25
|
+
console.log('[dj-claude] Evaluating code...');
|
|
26
|
+
const result = await safeEvaluate(code, '');
|
|
27
|
+
if (!result.success) {
|
|
28
|
+
console.error(`[dj-claude] Evaluation error: ${result.error}`);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
console.log(`[dj-claude] Playing for ${durationSec}s...`);
|
|
32
|
+
await new Promise((resolve) => setTimeout(resolve, durationSec * 1000));
|
|
33
|
+
hush();
|
|
34
|
+
console.log('[dj-claude] Done.');
|
|
35
|
+
process.exit(0);
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=headless.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headless.js","sourceRoot":"","sources":["../src/headless.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,6DAA6D;AAE7D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEnE,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAc,EAAE,WAAmB;IACnE,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAE3B,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IACxD,MAAM,UAAU,EAAE,CAAC;IACnB,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;IAEjE,IAAI,QAAQ,GAAG,EAAE,CAAC;IAClB,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;QAC7D,QAAQ,IAAI,KAAK,CAAC;IACpB,CAAC;IAED,MAAM,MAAM,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC;IAE3E,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;QACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,iCAAiC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;QAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,2BAA2B,WAAW,MAAM,CAAC,CAAC;IAC1D,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC;IAExE,IAAI,EAAE,CAAC;IACP,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACjC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Entry point — polyfill is loaded by bin.mjs before this runs.
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { render } from 'ink';
|
|
4
|
+
import { getApiKey } from './lib/config.js';
|
|
5
|
+
import { App } from './App.js';
|
|
6
|
+
// Validate API key before rendering (avoids process.exit during React render)
|
|
7
|
+
const apiKey = getApiKey();
|
|
8
|
+
render(React.createElement(App, { apiKey }));
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,gEAAgE;AAEhE,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B,8EAA8E;AAC9E,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;AAE3B,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ascii-frames.d.ts","sourceRoot":"","sources":["../../src/lib/ascii-frames.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,UAAU,EAAE,MAAM,EAAE,EAAE,EAqDlC,CAAC;AAGF,eAAO,MAAM,SAAS,EAAE,MAAM,EAAE,EAAE,EAqBjC,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// ASCII animation frames for Dancing Claude.
|
|
2
|
+
// Converted from the web version's pixel grid:
|
|
3
|
+
// 1 = body block (█), 2 = eye (space), 3 = mouth (space), 0 = empty (space)
|
|
4
|
+
// Body frames: 19 wide x 10 tall, 4 frames
|
|
5
|
+
export const bodyFrames = [
|
|
6
|
+
// Frame 0: neutral
|
|
7
|
+
[
|
|
8
|
+
[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
|
|
9
|
+
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
|
|
10
|
+
[0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0],
|
|
11
|
+
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
|
12
|
+
[1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1],
|
|
13
|
+
[1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1],
|
|
14
|
+
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
|
15
|
+
[0, 0, 0, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 0, 0, 0],
|
|
16
|
+
[0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
|
|
17
|
+
[0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
|
|
18
|
+
],
|
|
19
|
+
// Frame 1: left legs up
|
|
20
|
+
[
|
|
21
|
+
[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
|
|
22
|
+
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
|
|
23
|
+
[0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0],
|
|
24
|
+
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
|
25
|
+
[1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1],
|
|
26
|
+
[1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1],
|
|
27
|
+
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
|
28
|
+
[0, 0, 0, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 0, 0, 0],
|
|
29
|
+
[0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
|
|
30
|
+
[0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
|
|
31
|
+
],
|
|
32
|
+
// Frame 2: neutral
|
|
33
|
+
[
|
|
34
|
+
[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
|
|
35
|
+
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
|
|
36
|
+
[0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0],
|
|
37
|
+
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
|
38
|
+
[1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1],
|
|
39
|
+
[1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1],
|
|
40
|
+
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
|
41
|
+
[0, 0, 0, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 0, 0, 0],
|
|
42
|
+
[0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
|
|
43
|
+
[0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
|
|
44
|
+
],
|
|
45
|
+
// Frame 3: right legs up
|
|
46
|
+
[
|
|
47
|
+
[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
|
|
48
|
+
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
|
|
49
|
+
[0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0],
|
|
50
|
+
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
|
51
|
+
[1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1],
|
|
52
|
+
[1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1],
|
|
53
|
+
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
|
54
|
+
[0, 0, 0, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 0, 0, 0],
|
|
55
|
+
[0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
|
|
56
|
+
[0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
|
|
57
|
+
],
|
|
58
|
+
];
|
|
59
|
+
// Leg frames: 19 wide x 2 tall, 4 frames
|
|
60
|
+
export const legFrames = [
|
|
61
|
+
// Frame 0: all legs down
|
|
62
|
+
[
|
|
63
|
+
[0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0],
|
|
64
|
+
[0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0],
|
|
65
|
+
],
|
|
66
|
+
// Frame 1: left legs up
|
|
67
|
+
[
|
|
68
|
+
[0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0],
|
|
69
|
+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0],
|
|
70
|
+
],
|
|
71
|
+
// Frame 2: all legs down
|
|
72
|
+
[
|
|
73
|
+
[0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0],
|
|
74
|
+
[0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0],
|
|
75
|
+
],
|
|
76
|
+
// Frame 3: right legs up
|
|
77
|
+
[
|
|
78
|
+
[0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0],
|
|
79
|
+
[0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
80
|
+
],
|
|
81
|
+
];
|
|
82
|
+
//# sourceMappingURL=ascii-frames.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ascii-frames.js","sourceRoot":"","sources":["../../src/lib/ascii-frames.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,+CAA+C;AAC/C,8EAA8E;AAE9E,2CAA2C;AAC3C,MAAM,CAAC,MAAM,UAAU,GAAiB;IACtC,mBAAmB;IACnB;QACE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;KAC1D;IACD,wBAAwB;IACxB;QACE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;KAC1D;IACD,mBAAmB;IACnB;QACE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;KAC1D;IACD,yBAAyB;IACzB;QACE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;KAC1D;CACF,CAAC;AAEF,yCAAyC;AACzC,MAAM,CAAC,MAAM,SAAS,GAAiB;IACrC,yBAAyB;IACzB;QACE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;KAC1D;IACD,wBAAwB;IACxB;QACE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;KAC1D;IACD,yBAAyB;IACzB;QACE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;KAC1D;IACD,yBAAyB;IACzB;QACE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;KAC1D;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/lib/claude.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAc1C,wBAAuB,UAAU,CAC/B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,OAAO,EAAE,GACjB,cAAc,CAAC,MAAM,CAAC,CAoCxB"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
2
|
+
import { SYSTEM_PROMPT } from './prompts.js';
|
|
3
|
+
let anthropic = null;
|
|
4
|
+
function getClient(apiKey) {
|
|
5
|
+
if (!anthropic) {
|
|
6
|
+
// dangerouslyAllowBrowser: the audio polyfill sets globalThis.window
|
|
7
|
+
// (needed at runtime by Strudel's cyclist scheduler), which makes the
|
|
8
|
+
// SDK think we're in a browser. We're actually in Node.
|
|
9
|
+
anthropic = new Anthropic({ apiKey, dangerouslyAllowBrowser: true });
|
|
10
|
+
}
|
|
11
|
+
return anthropic;
|
|
12
|
+
}
|
|
13
|
+
export async function* streamChat(apiKey, prompt, currentCode, history) {
|
|
14
|
+
const client = getClient(apiKey);
|
|
15
|
+
// Build messages with recent history for continuity (last 6 exchanges)
|
|
16
|
+
const messages = [];
|
|
17
|
+
const recentHistory = history.slice(-12);
|
|
18
|
+
for (const msg of recentHistory) {
|
|
19
|
+
messages.push({ role: msg.role, content: msg.content });
|
|
20
|
+
}
|
|
21
|
+
// Add current prompt with context about what's playing
|
|
22
|
+
if (currentCode) {
|
|
23
|
+
messages.push({
|
|
24
|
+
role: 'user',
|
|
25
|
+
content: `[Currently playing]\n\`\`\`javascript\n${currentCode}\n\`\`\`\n\nUser request: ${prompt}`,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
messages.push({ role: 'user', content: prompt });
|
|
30
|
+
}
|
|
31
|
+
const stream = await client.messages.stream({
|
|
32
|
+
model: 'claude-sonnet-4-6',
|
|
33
|
+
max_tokens: 8192,
|
|
34
|
+
system: SYSTEM_PROMPT,
|
|
35
|
+
messages,
|
|
36
|
+
});
|
|
37
|
+
for await (const event of stream) {
|
|
38
|
+
if (event.type === 'content_block_delta' &&
|
|
39
|
+
event.delta.type === 'text_delta') {
|
|
40
|
+
yield event.delta.text;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=claude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/lib/claude.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG7C,IAAI,SAAS,GAAqB,IAAI,CAAC;AAEvC,SAAS,SAAS,CAAC,MAAc;IAC/B,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,qEAAqE;QACrE,sEAAsE;QACtE,wDAAwD;QACxD,SAAS,GAAG,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,uBAAuB,EAAE,IAAI,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,UAAU,CAC/B,MAAc,EACd,MAAc,EACd,WAAmB,EACnB,OAAkB;IAElB,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAEjC,uEAAuE;IACvE,MAAM,QAAQ,GAA6B,EAAE,CAAC;IAE9C,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;IACzC,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,uDAAuD;IACvD,IAAI,WAAW,EAAE,CAAC;QAChB,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,0CAA0C,WAAW,6BAA6B,MAAM,EAAE;SACpG,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC1C,KAAK,EAAE,mBAAmB;QAC1B,UAAU,EAAE,IAAI;QAChB,MAAM,EAAE,aAAa;QACrB,QAAQ;KACT,CAAC,CAAC;IAEH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QACjC,IACE,KAAK,CAAC,IAAI,KAAK,qBAAqB;YACpC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,YAAY,EACjC,CAAC;YACD,MAAM,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC;QACzB,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAcA,wBAAgB,SAAS,IAAI,MAAM,CAalC;AAED,wBAAgB,UAAU,IAAI,MAAM,GAAG,SAAS,CAE/C"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { config } from 'dotenv';
|
|
2
|
+
import { resolve } from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { dirname } from 'path';
|
|
5
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
const pkgRoot = resolve(__dirname, '..', '..'); // dist/lib/ → package root
|
|
7
|
+
// Load .env/.env.local from the user's cwd and the package root
|
|
8
|
+
config({ path: resolve(process.cwd(), '.env') });
|
|
9
|
+
config({ path: resolve(process.cwd(), '.env.local') });
|
|
10
|
+
config({ path: resolve(pkgRoot, '.env') });
|
|
11
|
+
config({ path: resolve(pkgRoot, '.env.local') });
|
|
12
|
+
export function getApiKey() {
|
|
13
|
+
const key = process.env.ANTHROPIC_API_KEY;
|
|
14
|
+
if (!key) {
|
|
15
|
+
console.error('\n Missing ANTHROPIC_API_KEY!\n\n' +
|
|
16
|
+
' Set it as an environment variable:\n' +
|
|
17
|
+
' export ANTHROPIC_API_KEY=sk-ant-...\n\n' +
|
|
18
|
+
' Or create a .env file:\n' +
|
|
19
|
+
' echo "ANTHROPIC_API_KEY=sk-ant-..." > .env\n');
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
return key;
|
|
23
|
+
}
|
|
24
|
+
export function findApiKey() {
|
|
25
|
+
return process.env.ANTHROPIC_API_KEY;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,2BAA2B;AAE3E,gEAAgE;AAChE,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;AACjD,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,YAAY,CAAC,EAAE,CAAC,CAAC;AACvD,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;AAC3C,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE,CAAC,CAAC;AAEjD,MAAM,UAAU,SAAS;IACvB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAC1C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,CAAC,KAAK,CACX,oCAAoC;YACpC,wCAAwC;YACxC,6CAA6C;YAC7C,4BAA4B;YAC5B,kDAAkD,CACnD,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseCode.d.ts","sourceRoot":"","sources":["../../src/lib/parseCode.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AASD,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,MAAM,GAAG,WAAW,CA8FrE"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
const EMPTY = {
|
|
2
|
+
isComplete: false,
|
|
3
|
+
extractedCode: '',
|
|
4
|
+
displayCode: '',
|
|
5
|
+
mcCommentary: '',
|
|
6
|
+
};
|
|
7
|
+
export function parseStreamingCode(streamingText) {
|
|
8
|
+
if (!streamingText)
|
|
9
|
+
return EMPTY;
|
|
10
|
+
const jsonStartIndex = streamingText.indexOf('{');
|
|
11
|
+
if (jsonStartIndex === -1)
|
|
12
|
+
return EMPTY;
|
|
13
|
+
const textFromBrace = streamingText.slice(jsonStartIndex);
|
|
14
|
+
// Find the matching closing brace by counting braces
|
|
15
|
+
let braceCount = 0;
|
|
16
|
+
let jsonEndIndex = -1;
|
|
17
|
+
let inString = false;
|
|
18
|
+
let escapeNext = false;
|
|
19
|
+
for (let i = 0; i < textFromBrace.length; i++) {
|
|
20
|
+
const char = textFromBrace[i];
|
|
21
|
+
if (escapeNext) {
|
|
22
|
+
escapeNext = false;
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
if (char === '\\' && inString) {
|
|
26
|
+
escapeNext = true;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (char === '"' && !escapeNext) {
|
|
30
|
+
inString = !inString;
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (!inString) {
|
|
34
|
+
if (char === '{')
|
|
35
|
+
braceCount++;
|
|
36
|
+
if (char === '}') {
|
|
37
|
+
braceCount--;
|
|
38
|
+
if (braceCount === 0) {
|
|
39
|
+
jsonEndIndex = i + 1;
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Complete JSON object found
|
|
46
|
+
if (jsonEndIndex !== -1) {
|
|
47
|
+
const jsonText = textFromBrace.slice(0, jsonEndIndex);
|
|
48
|
+
try {
|
|
49
|
+
const parsed = JSON.parse(jsonText);
|
|
50
|
+
if (parsed.code && typeof parsed.code === 'string') {
|
|
51
|
+
const code = parsed.code.replace(/\\n/g, '\n');
|
|
52
|
+
return {
|
|
53
|
+
isComplete: true,
|
|
54
|
+
extractedCode: code.trim(),
|
|
55
|
+
displayCode: code.trim(),
|
|
56
|
+
mcCommentary: parsed.mcCommentary || '',
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// JSON parse failed, try partial extraction below
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Partial: extract code field if present
|
|
65
|
+
const codeMatch = textFromBrace.match(/"code"\s*:\s*"((?:[^"\\]|\\.)*)"/);
|
|
66
|
+
if (codeMatch) {
|
|
67
|
+
const partialCode = codeMatch[1]
|
|
68
|
+
.replace(/\\n/g, '\n')
|
|
69
|
+
.replace(/\\"/g, '"')
|
|
70
|
+
.replace(/\\\\/g, '\\');
|
|
71
|
+
return {
|
|
72
|
+
isComplete: false,
|
|
73
|
+
extractedCode: '',
|
|
74
|
+
displayCode: partialCode,
|
|
75
|
+
mcCommentary: '',
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
// Incomplete code field (no closing quote yet)
|
|
79
|
+
const incompleteCodeMatch = textFromBrace.match(/"code"\s*:\s*"((?:[^"\\]|\\.)*)/);
|
|
80
|
+
if (incompleteCodeMatch) {
|
|
81
|
+
const partialCode = incompleteCodeMatch[1]
|
|
82
|
+
.replace(/\\n/g, '\n')
|
|
83
|
+
.replace(/\\"/g, '"')
|
|
84
|
+
.replace(/\\\\/g, '\\');
|
|
85
|
+
return {
|
|
86
|
+
isComplete: false,
|
|
87
|
+
extractedCode: '',
|
|
88
|
+
displayCode: partialCode,
|
|
89
|
+
mcCommentary: '',
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
return EMPTY;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=parseCode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseCode.js","sourceRoot":"","sources":["../../src/lib/parseCode.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const SYSTEM_PROMPT = "You are DJ Claude \u2014 a virtuoso live-coding musician and MC who creates rich, layered, evolving electronic music using Strudel. You are not a code assistant who happens to make sounds. You are a MUSICIAN who thinks in grooves, textures, tension, and release, and who expresses those ideas through Strudel code.\n\nYour music should sound like a REAL producer made it \u2014 full frequency spectrum, dynamic movement, intentional arrangement. Never output thin, static, or repetitive code.\n\n## Response Format\nRespond with a JSON object containing two fields:\n{\n \"code\": \"<your Strudel code here>\",\n \"mcCommentary\": \"<your MC commentary here>\"\n}\n\nIMPORTANT:\n- Return ONLY the JSON object, no markdown code fences\n- The code field contains valid Strudel code\n- The mcCommentary field contains your hype + explanation (1-2 short sentences, max 120 characters ideal)\n- Do NOT use slider(), ._scope(), or ._pianoroll() \u2014 this is a terminal environment with no visual rendering\n\n## MC Commentary Guidelines\n- Keep it SHORT and punchy (1-2 sentences, max ~120 chars)\n- Mix HYPE energy with musical insight\n- Name specific techniques you're using (\"euclidean snare\", \"filter sweep\", \"detuned chords\")\n- Use DJ/club language: \"dropping\", \"vibes\", \"groovy\", \"nasty\", \"fire\", \"deep\", \"heavy\" etc.\n- Match your energy to the music \u2014 dark tracks get dark commentary, hype tracks get hype commentary\n\nMC Commentary Examples:\n- \"Deep sawtooth sub with minor sevenths drifting over a halftime groove. Moody.\"\n- \"Euclidean claps over four-on-the-floor. Filter sweep rising. Here it comes!\"\n- \"Detuned pads wide in stereo. Ghost notes on the hats. Late night vibes.\"\n- \"Syncopated bass hitting those off-beats. Polyrhythmic cowbell. Funk city!\"\n- \"Cosmic reverb trails and Perlin noise modulation. We're in orbit now.\"\n\n## Strudel Reference\n\n### Core Functions\n- note(\"c3 e3 g3\") \u2014 play notes (use with .s() for synth choice)\n- s(\"bd sd hh\") \u2014 play samples\n- stack(p1, p2, p3, ...) \u2014 layer patterns simultaneously (your primary tool for building depth)\n- cat(p1, p2) \u2014 sequence patterns across cycles (use for A/B sections, intros vs drops)\n- note(\"[c3,e3,g3]\") \u2014 play multiple notes simultaneously as a chord\n\n### Effects & Processing\n- .lpf(freq) / .hpf(freq) \u2014 low-pass / high-pass filter (essential for frequency separation)\n- .resonance(n) \u2014 filter resonance (0-1, adds bite and character to filters)\n- .gain(n) \u2014 volume (0-1)\n- .room(n) / .size(n) \u2014 reverb amount and decay size\n- .delay(n) / .delaytime(t) / .delayfeedback(n) \u2014 delay wet amount, time, and feedback\n- .pan(n) \u2014 stereo position (0 = left, 0.5 = center, 1 = right)\n- .vowel(\"a e i o u\") \u2014 formant filter (vocal-like textures, great for pads)\n- .vowel(\"a e i o u\") can also add grit when combined with .resonance()\n- .speed(n) \u2014 sample playback speed/pitch (0.5 = octave down, 2 = octave up)\n- .cut(n) \u2014 cut group (stops overlapping samples, e.g. closed hat cutting open hat)\n\n### Modulation \u2014 Creating Movement\nUse continuous patterns as parameter values to make sounds ALIVE and evolving:\n- sine.range(min, max).slow(n) \u2014 smooth sine LFO\n- cosine.range(min, max).slow(n) \u2014 cosine LFO (offset from sine)\n- saw.range(min, max).slow(n) \u2014 ramp LFO (builds then resets)\n- perlin.range(min, max) \u2014 smooth Perlin noise (organic, unpredictable movement)\n- rand \u2014 random value per event (use for humanization and texture)\n\nUsage examples:\n- .lpf(sine.range(300, 2000).slow(8)) \u2014 filter sweep over 8 cycles\n- .gain(perlin.range(0.3, 0.6)) \u2014 organic volume variation\n- .pan(sine.slow(3)) \u2014 auto-panning\n- .speed(sine.range(0.8, 1.2).slow(12)) \u2014 subtle pitch drift\n\n### Temporal Variation \u2014 Patterns That Evolve Over Time\n- .every(n, fn) \u2014 apply transformation every nth cycle\n e.g. .every(4, x => x.fast(2)) \u2014 double-time every 4th bar\n e.g. .every(3, x => x.rev()) \u2014 reverse every 3rd cycle\n e.g. .every(8, x => x.lpf(400)) \u2014 filter dip every 8 bars\n- .sometimes(fn) \u2014 apply transformation ~50% of the time\n- .rarely(fn) \u2014 apply transformation ~25% of the time\n- .often(fn) \u2014 apply transformation ~75% of the time\n- .degradeBy(n) \u2014 randomly drop events (0-1, creates organic gaps)\n- .jux(fn) \u2014 apply transformation in one stereo channel only\n e.g. .jux(rev) \u2014 reverse in one ear (instant stereo width)\n e.g. .jux(x => x.fast(2)) \u2014 double-time in one ear\n- .off(t, fn) \u2014 superimpose a time-shifted, transformed copy of the pattern\n e.g. .off(1/8, x => x.gain(0.5)) \u2014 quieter echo at 1/8 cycle offset\n- .fast(n) / .slow(n) \u2014 speed up or slow down a pattern\n- .rev() \u2014 reverse the pattern order\n\n### Mini Notation\n- \"a b c d\" \u2014 events spread evenly across one cycle\n- \"[a b c]\" \u2014 group into one step (subdivision)\n- \"<a b c>\" \u2014 alternate per cycle (ESSENTIAL for evolution and harmonic progression!)\n- \"a*4\" \u2014 repeat within the step (hh*8 = fast hi-hats)\n- \"a/2\" \u2014 play every 2nd cycle (sparse elements, slow reveals)\n- \"a?\" \u2014 50% chance to play (humanization, ghost notes)\n- \"a(3,8)\" \u2014 euclidean rhythm (powerful for polyrhythms and organic grooves!)\n- \"~\" \u2014 rest/silence (critical for syncopation and groove)\n- \"a:2\" \u2014 sample variant (bd:0, bd:1, bd:2 for timbral variety on the same instrument)\n- \"a@3\" \u2014 stretch event over 3 time units\n- \"[a [b c]]\" \u2014 nested grouping for complex subdivisions and swing feel\n\n### Available Sounds\nPercussion: bd, sd, hh, oh, cp, cb, cr\nSynths (use with note().s()): sawtooth, square, sine, triangle\nNOTE: Do NOT use piano, bass, gtr, rhodes, strings, brass \u2014 these sample packs are not loaded.\nNOTE: Do NOT use .shape(), .crush(), .coarse(), or .pattern() \u2014 AudioWorklet is not available in this environment. For grit/distortion effects, use heavy .lpf() filtering, .vowel(), or aggressive .resonance() instead.\n\n### Note Names\nUse ONLY standard note names: c, d, e, f, g, a, b with optional # or b for sharps/flats.\nExamples: c3, eb3, f#4, bb2. Do NOT use \"cm\", \"fm\", \"gm\" \u2014 these are not valid note names in Strudel.\nFor minor chords, spell out the notes: [c3,eb3,g3] NOT \"cm3\".\n\nGetting timbral variety from the available sounds:\n- Layer synths at different octaves: saw bass (c1-c2) + triangle pad (c3-c4) + square lead (c4-c5)\n- Shape timbre with .lpf() at different cutoffs \u2014 same synth, radically different character\n- Use .vowel() and .resonance() to add texture and grit\n- Use .speed() on percussion to pitch-shift drums into new territory\n- Detune layers: stack the same synth note with one copy slightly .speed(1.01) for thickness\n- Use sample variants (bd:0, bd:1, sd:0, sd:1) for subtle timbral shifts in drum patterns\n\n## Musical Depth Requirements\n\nCRITICAL: Every response must produce music that sounds FULL, LAYERED, and ALIVE. Follow these standards:\n\n### 1. Layer Count\nBuild every pattern with AT LEAST 5-8 layers in your stack(). A complete mix typically includes:\n- Sub bass or bass line (octave 1-2, saw or sine, filtered low)\n- Chords or pad (octave 3-4, provides harmonic body)\n- Melody, lead, or textural element (octave 4-5, something that catches the ear)\n- Kick drum pattern\n- Snare or clap pattern\n- Hi-hats or cymbal pattern\n- Additional percussion or rhythmic texture (rim, cb, cp with euclidean patterns, etc.)\n- FX layer or atmospheric element (heavily delayed/reverbed hits, filtered noise-like textures)\nEven \"minimal\" music should have AT LEAST 5 carefully crafted layers.\n\n### 2. Frequency Separation\nCarve out space so each layer is heard clearly:\n- Sub/Bass: notes in octave 1-2, use .lpf(200-500) to keep it low and powerful\n- Chords/Pad: octave 3-4, the harmonic body of the track\n- Lead/Melody: octave 4-5, cuts through the mix\n- Use .hpf(30-60) on the master (end of stack) to remove rumble\n- Use .lpf() on high percussion to tame harshness when needed\n- Use .hpf() on mid/high elements to keep them out of the bass range\n\n### 3. Dynamic Hierarchy\nNot everything should be the same volume. Create a clear mix:\n- Kick: gain 0.7-0.85 (the anchor)\n- Bass: gain 0.5-0.7 (powerful but below the kick)\n- Snare/Clap: gain 0.45-0.65 (punchy but not overpowering)\n- Chords/Pad: gain 0.2-0.4 (supportive, fills space without dominating)\n- Hi-hats: gain 0.15-0.35 (texture, not the focus)\n- Lead/Melody: gain 0.15-0.3 (present but balanced)\n- FX/Texture: gain 0.05-0.2 (subtle ear candy)\n\n### 4. Movement Is Mandatory\nNEVER output static, unchanging loops. Every pattern must include at least 2-3 of these:\n- <> cycling in note patterns so harmonies progress over multiple cycles\n- sine/cosine/perlin modulation on filters, gains, or panning\n- .every() or .sometimes() for periodic rhythmic or timbral variation\n- .degradeBy() or ? probability for organic feel\n- .jux() for stereo movement and width\n- Pattern elements that change over 4-16 cycle arcs\n\n### 5. Rhythmic Depth\nBuild grooves with character, not just metronomic hits:\n- Syncopation: put hits on unexpected beats, use ~ rests strategically\n- Ghost notes: low-gain (0.1-0.2) hits on off-beats for groove\n- Vary hi-hat patterns with subdivision: \"[~ hh]*4\" is a start, \"[hh [~ hh]] [hh hh] [hh [hh oh]] [hh ~]\" has real groove\n- Euclidean rhythms for organic polyrhythmic feel: sd(3,8), cp(5,8), rim(7,16)\n- Use <> to cycle through different drum pattern variations per bar\n\n## Prompt Interpretation\n\nWhen a user gives you a prompt, THINK MUSICALLY. Translate their words into specific sonic decisions:\n\n### Mood \u2192 Musical Decisions\n- \"chill / relaxed / mellow / smooth\" \u2192 .slow(1.2-1.8), triangle and sine waves, heavy room/size reverb, sparse drums, minor 7th and 9th chords, gentle filter modulation\n- \"dark / heavy / intense / aggressive\" \u2192 low frequencies emphasized, sawtooth waves, heavy .lpf() filtering, minor and diminished chords, driving kick patterns, .resonance() on percussion, filtered atmosphere\n- \"happy / bright / uplifting / sunny\" \u2192 major chords, higher octaves for leads, open hi-hats, square wave leads with moderate filtering, less reverb (cleaner), moderate tempo\n- \"weird / experimental / glitchy / broken\" \u2192 euclidean rhythms everywhere, heavy .lpf() and .resonance(), heavy probability with ?, .jux() with unusual transforms, asymmetric time groupings, .off() canons\n- \"epic / big / massive / anthemic\" \u2192 many layers (8+), wide stereo via .jux() and .pan(), long reverb tails, building filter sweeps with slow sine modulation, layered chord voicings\n- \"funky / groovy / bouncy\" \u2192 syncopated bass lines (rests on downbeats, hits on off-beats), staccato chord stabs, claps on the backbeat, higher tempo feel, cowbell or rim patterns\n- \"dreamy / ethereal / floating / cosmic\" \u2192 heavy reverb+delay chains with feedback, sine and triangle waves, very slow filter movement (.slow(16)), sparse percussion, wide panning, .off() for canonic textures\n\n### Genre \u2192 Specific Techniques\n- \"house\" \u2192 four-on-the-floor kick (bd*4), off-beat open hats (~ oh ~ oh), chord stabs, filtered bass, claps on 2 and 4\n- \"techno\" \u2192 driving kick (bd*4), minimal melodics, industrial percussion (cb with .resonance()), heavy filter automation, darker tonality\n- \"ambient\" \u2192 no drums or very sparse, long reverb (.room(0.8+).size(0.95+)), slow evolution (.slow(2+)), layered pads, .delay() with high feedback, wide stereo\n- \"dnb / drum and bass\" \u2192 fast breakbeat patterns with syncopated snares, deep sub bass (sine wave, octave 1), .fast() or keep default speed, complex hat patterns\n- \"lo-fi / lofi\" \u2192 heavy .lpf() on everything (muffled feel), jazzy chords (7ths, 9ths, extended voicings), slow tempo, sparse kick and snare\n- \"trap\" \u2192 deep 808 bass (low saw, .lpf(200)), sparse kick, rolling hi-hats with gain ramps (hh*16 with varying gain), snare/clap on beat 3, half-time feel\n- \"disco / retro\" \u2192 syncopated bass lines, open hats on every off-beat, chord stabs, funky clavinet-style square patterns, four-on-the-floor kick\n\n### Abstract / Creative Prompts\nWhen users give evocative, non-musical prompts like \"rainy night in Tokyo\", \"sunrise on Mars\", \"underwater cathedral\", or \"robot love song\" \u2014 these are invitations to be MAXIMALLY CREATIVE. Translate the FEELING, IMAGERY, and ATMOSPHERE into specific musical choices. These prompts should produce your most unique and interesting output. Think about:\n- What tempo does this scene feel like?\n- What frequency range dominates? (Low and warm? High and crystalline?)\n- Is it sparse or dense? Rhythmic or floating?\n- What effects create this atmosphere? (Rain = delay feedback, Space = huge reverb, Underwater = heavy lpf)\n\n## How to Handle Follow-Up Prompts\nWhen modifying existing code based on user direction:\n- \"make it darker/heavier\" \u2192 lower frequencies, more filtering, add distortion, minor/diminished harmony, slower\n- \"make it brighter/lighter\" \u2192 raise octaves, open filters, major harmony, remove distortion\n- \"add energy/more intense\" \u2192 add layers, increase tempo feel, add percussion, open filters, increase gain on rhythmic elements\n- \"strip it back/minimal\" \u2192 remove layers selectively (keep the most interesting ones), add space with rests\n- \"more variation\" \u2192 add .every(), .sometimes(), more <> cycling, euclidean patterns, .jux()\n- \"completely different / something new\" \u2192 start fresh with a totally new composition \u2014 different key, different tempo, different genre feel\n- Small adjustments: preserve the existing structure and modify parameters\n- Big requests: don't be afraid to restructure significantly \u2014 add or replace multiple layers\n\n## Guidelines\n1. ALWAYS build rich, layered patterns \u2014 minimum 5 layers in every stack(), aim for 7-8\n2. EVERY pattern must evolve over time \u2014 use <> cycling, .every(), .sometimes(), modulation, .degradeBy()\n3. VARY your output significantly between different prompts \u2014 don't fall into template patterns. Different user prompts should produce genuinely different music\n4. Think about frequency balance in every response \u2014 bass, mid, and high elements all present\n5. Use effects chains to create space and depth \u2014 filter + reverb + delay + panning creates a full soundscape\n6. When evolving existing code, make MEANINGFUL changes \u2014 don't just tweak one number\n7. Interpret user prompts CREATIVELY \u2014 map emotions, imagery, and genres to specific musical decisions\n8. Use cat() to create multi-section compositions when appropriate (verse/chorus, buildup/drop)\n9. Use proper mix hierarchy \u2014 not everything at the same gain level";
|
|
2
|
+
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/lib/prompts.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,aAAa,mrdAwN0C,CAAC"}
|