@causyne/agent 0.0.0-stage → 1.10.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/LICENSE +102 -0
- package/README.md +31 -2
- package/SECURITY.md +24 -0
- package/bin/causyne.js +13 -0
- package/docs/ARCHITECTURE.md +63 -0
- package/docs/PROVENANCE.md +29 -0
- package/docs/SECURITY_REVIEW.md +89 -0
- package/docs/THIRD_PARTY_NOTICES.md +49 -0
- package/native-skills/ai-engineering/context-window-management/SKILL.md +43 -0
- package/native-skills/ai-engineering/llm-evaluation/SKILL.md +46 -0
- package/native-skills/ai-engineering/model-cost-and-latency/SKILL.md +46 -0
- package/native-skills/ai-engineering/prompt-construction/SKILL.md +42 -0
- package/native-skills/ai-engineering/retrieval-augmented-generation/SKILL.md +42 -0
- package/native-skills/ai-engineering/structured-output-and-schemas/SKILL.md +45 -0
- package/native-skills/ai-engineering/tool-calling-agents/SKILL.md +43 -0
- package/native-skills/android/app-performance-profiling/SKILL.md +42 -0
- package/native-skills/android/background-work-scheduling/SKILL.md +47 -0
- package/native-skills/android/compose-state-and-recomposition/SKILL.md +43 -0
- package/native-skills/android/gradle-build-configuration/SKILL.md +41 -0
- package/native-skills/android/lifecycle-and-leaks/SKILL.md +46 -0
- package/native-skills/android/play-store-release/SKILL.md +43 -0
- package/native-skills/android/room-and-persistence/SKILL.md +40 -0
- package/native-skills/backend/authentication-and-sessions/SKILL.md +45 -0
- package/native-skills/backend/background-jobs-and-queues/SKILL.md +42 -0
- package/native-skills/backend/caching-strategy/SKILL.md +44 -0
- package/native-skills/backend/graceful-shutdown/SKILL.md +42 -0
- package/native-skills/backend/rate-limiting-and-quotas/SKILL.md +40 -0
- package/native-skills/backend/rest-api-design/SKILL.md +40 -0
- package/native-skills/backend/webhook-delivery-and-receipt/SKILL.md +43 -0
- package/native-skills/cloud/cost-optimisation/SKILL.md +46 -0
- package/native-skills/cloud/iam-least-privilege/SKILL.md +43 -0
- package/native-skills/cloud/infrastructure-as-code/SKILL.md +43 -0
- package/native-skills/cloud/multi-region-and-failover/SKILL.md +43 -0
- package/native-skills/cloud/serverless-patterns/SKILL.md +47 -0
- package/native-skills/data/data-quality-monitoring/SKILL.md +51 -0
- package/native-skills/data/etl-pipeline-reliability/SKILL.md +43 -0
- package/native-skills/data/exploratory-analysis/SKILL.md +43 -0
- package/native-skills/data/metric-definition/SKILL.md +42 -0
- package/native-skills/data/notebook-to-production/SKILL.md +43 -0
- package/native-skills/database/backup-and-recovery/SKILL.md +43 -0
- package/native-skills/database/connection-pooling/SKILL.md +42 -0
- package/native-skills/database/data-integrity-and-constraints/SKILL.md +42 -0
- package/native-skills/database/query-optimisation/SKILL.md +38 -0
- package/native-skills/database/safe-migrations/SKILL.md +47 -0
- package/native-skills/database/schema-design/SKILL.md +38 -0
- package/native-skills/database/transactions-and-isolation/SKILL.md +41 -0
- package/native-skills/design/colour-system-construction/SKILL.md +38 -0
- package/native-skills/design/design-direction-brief/SKILL.md +41 -0
- package/native-skills/design/motion-and-transitions/SKILL.md +38 -0
- package/native-skills/design/responsive-strategy/SKILL.md +39 -0
- package/native-skills/design/spacing-and-rhythm/SKILL.md +38 -0
- package/native-skills/design/type-scale-and-hierarchy/SKILL.md +39 -0
- package/native-skills/design/visual-qa-loop/SKILL.md +42 -0
- package/native-skills/devops/docker-multi-stage-builds/SKILL.md +60 -0
- package/native-skills/devops/github-actions-ci/SKILL.md +60 -0
- package/native-skills/devops/incident-triage/SKILL.md +38 -0
- package/native-skills/devops/kubernetes-deployment-hardening/SKILL.md +64 -0
- package/native-skills/devops/observability-baseline/SKILL.md +38 -0
- package/native-skills/devops/secret-management/SKILL.md +40 -0
- package/native-skills/devops/terraform-state-and-modules/SKILL.md +36 -0
- package/native-skills/devops/zero-downtime-deploys/SKILL.md +40 -0
- package/native-skills/git/bisect-regression-hunt/SKILL.md +43 -0
- package/native-skills/git/branch-strategy/SKILL.md +39 -0
- package/native-skills/git/commit-hygiene/SKILL.md +41 -0
- package/native-skills/git/history-recovery/SKILL.md +44 -0
- package/native-skills/git/large-repository-surgery/SKILL.md +46 -0
- package/native-skills/git/merge-conflict-resolution/SKILL.md +42 -0
- package/native-skills/media/cinematic-3d-shot/SKILL.md +104 -0
- package/native-skills/mobile/app-startup-optimisation/SKILL.md +41 -0
- package/native-skills/mobile/cross-platform-tradeoffs/SKILL.md +42 -0
- package/native-skills/mobile/deep-linking/SKILL.md +39 -0
- package/native-skills/mobile/mobile-storage-security/SKILL.md +45 -0
- package/native-skills/mobile/offline-first-sync/SKILL.md +42 -0
- package/native-skills/mobile/push-notifications/SKILL.md +38 -0
- package/native-skills/performance/algorithmic-complexity/SKILL.md +43 -0
- package/native-skills/performance/concurrency-and-parallelism/SKILL.md +42 -0
- package/native-skills/performance/load-testing/SKILL.md +42 -0
- package/native-skills/performance/memory-and-leak-hunting/SKILL.md +41 -0
- package/native-skills/performance/network-and-payload-efficiency/SKILL.md +42 -0
- package/native-skills/performance/profiling-methodology/SKILL.md +46 -0
- package/native-skills/python/async-correctness/SKILL.md +40 -0
- package/native-skills/python/cli-tool-construction/SKILL.md +44 -0
- package/native-skills/python/data-processing-pipelines/SKILL.md +38 -0
- package/native-skills/python/environment-isolation/SKILL.md +41 -0
- package/native-skills/python/packaging-and-distribution/SKILL.md +56 -0
- package/native-skills/python/pytest-suite-design/SKILL.md +39 -0
- package/native-skills/python/type-hints-and-static-checking/SKILL.md +42 -0
- package/native-skills/security/authorization-model/SKILL.md +42 -0
- package/native-skills/security/crypto-usage/SKILL.md +48 -0
- package/native-skills/security/dependency-supply-chain/SKILL.md +42 -0
- package/native-skills/security/input-validation-and-injection/SKILL.md +44 -0
- package/native-skills/security/secure-file-uploads/SKILL.md +46 -0
- package/native-skills/security/security-headers-and-csp/SKILL.md +44 -0
- package/native-skills/security/threat-modelling/SKILL.md +46 -0
- package/native-skills/testing/end-to-end-test-stability/SKILL.md +42 -0
- package/native-skills/testing/property-based-testing/SKILL.md +46 -0
- package/native-skills/testing/regression-test-from-a-bug/SKILL.md +41 -0
- package/native-skills/testing/snapshot-and-visual-regression/SKILL.md +42 -0
- package/native-skills/testing/test-doubles-and-mocking/SKILL.md +43 -0
- package/native-skills/testing/test-strategy-and-pyramid/SKILL.md +39 -0
- package/native-skills/testing/writing-good-assertions/SKILL.md +42 -0
- package/native-skills/web/accessible-components/SKILL.md +45 -0
- package/native-skills/web/api-client-resilience/SKILL.md +39 -0
- package/native-skills/web/bundle-size-reduction/SKILL.md +38 -0
- package/native-skills/web/core-web-vitals/SKILL.md +40 -0
- package/native-skills/web/css-layout-systems/SKILL.md +41 -0
- package/native-skills/web/form-validation-ux/SKILL.md +39 -0
- package/native-skills/web/react-state-architecture/SKILL.md +41 -0
- package/native-skills/web/ssr-hydration-correctness/SKILL.md +45 -0
- package/package.json +68 -4
- package/src/agentLoop.js +2458 -0
- package/src/appChannel.js +109 -0
- package/src/approvalGrants.js +66 -0
- package/src/auditLog.js +52 -0
- package/src/autoUpdate.js +12 -0
- package/src/capabilities.js +36 -0
- package/src/checkpoints.js +1199 -0
- package/src/cliMode.js +638 -0
- package/src/commands.js +805 -0
- package/src/compiledSkills.js +540 -0
- package/src/config.js +130 -0
- package/src/contextManager.js +498 -0
- package/src/cortex/autoCondenser.js +192 -0
- package/src/cortex/provisioner.js +27 -0
- package/src/cortex/vectorDb.js +447 -0
- package/src/designPalettes.js +99 -0
- package/src/devMode.js +6 -0
- package/src/embodimentSession.js +180 -0
- package/src/entrypoint.js +194 -0
- package/src/execSafe.js +21 -0
- package/src/gitSnapshot.js +378 -0
- package/src/mcp/jsonRpc.js +165 -0
- package/src/mcp/mcpClient.js +136 -0
- package/src/mcp/mcpRegistry.js +207 -0
- package/src/memory.js +62 -0
- package/src/memoryManager.js +124 -0
- package/src/modelCatalogue.js +132 -0
- package/src/modelIds.js +42 -0
- package/src/modelRouter.js +145 -0
- package/src/outputStore.js +246 -0
- package/src/perception.js +124 -0
- package/src/planCache.js +437 -0
- package/src/procSignal.js +32 -0
- package/src/providers/anthropic.js +408 -0
- package/src/providers/base.js +328 -0
- package/src/providers/dashscope-byok.js +86 -0
- package/src/providers/deepseek.js +80 -0
- package/src/providers/factory.js +37 -0
- package/src/providers/gemini.js +346 -0
- package/src/providers/moonshot.js +73 -0
- package/src/providers/muse.js +169 -0
- package/src/providers/ollama.js +104 -0
- package/src/providers/openai-compatible.js +84 -0
- package/src/providers/openai.js +20 -0
- package/src/providers/qwen-byok.js +76 -0
- package/src/providers/xai.js +73 -0
- package/src/provisioning/capabilityConsent.js +24 -0
- package/src/provisioning/capabilityProvisioner.js +271 -0
- package/src/provisioning/capabilityTools.js +29 -0
- package/src/reporting.js +373 -0
- package/src/sandbox.js +529 -0
- package/src/sessionStore.js +279 -0
- package/src/skillsManager.js +288 -0
- package/src/slopDetector.js +307 -0
- package/src/taskBuffer.js +45 -0
- package/src/taskShape.js +241 -0
- package/src/textDiff.js +150 -0
- package/src/tokenTracker.js +560 -0
- package/src/tool-scripts/ax_snapshot.applescript +39 -0
- package/src/tool-scripts/ax_snapshot.ps1 +10 -0
- package/src/tool-scripts/desktop_act.applescript +58 -0
- package/src/tool-scripts/resolve_automator.py +119 -0
- package/src/toolPacks.js +524 -0
- package/src/tools/archive.js +63 -0
- package/src/tools/astryxOracle.js +78 -0
- package/src/tools/axSnapshot.js +165 -0
- package/src/tools/blenderAutomator.js +349 -0
- package/src/tools/browserAutomator.js +252 -0
- package/src/tools/checkSystemSpecs.js +64 -0
- package/src/tools/clipboard.js +36 -0
- package/src/tools/codeSearchAst.js +101 -0
- package/src/tools/codeSearcher.js +230 -0
- package/src/tools/codeTools.js +262 -0
- package/src/tools/codebaseSearch.js +75 -0
- package/src/tools/createSkill.js +129 -0
- package/src/tools/deferredMcpSearch.js +246 -0
- package/src/tools/desktopAct.js +208 -0
- package/src/tools/desktopOpen.js +34 -0
- package/src/tools/dynamicLoader.js +44 -0
- package/src/tools/executeProceduralMedia.js +93 -0
- package/src/tools/fsDelete.js +51 -0
- package/src/tools/fsEdit.js +105 -0
- package/src/tools/fsFind.js +128 -0
- package/src/tools/fsList.js +77 -0
- package/src/tools/fsMove.js +57 -0
- package/src/tools/fsRead.js +87 -0
- package/src/tools/fsSearch.js +198 -0
- package/src/tools/fsWrite.js +41 -0
- package/src/tools/gameAiBehaviorTree.js +208 -0
- package/src/tools/gameAnimationRig.js +194 -0
- package/src/tools/gameAssetFetcher.js +372 -0
- package/src/tools/gameAssetHarvester.js +210 -0
- package/src/tools/gameAudioSynth.js +267 -0
- package/src/tools/gameBuilder.js +886 -0
- package/src/tools/gameCanvasAudit.js +101 -0
- package/src/tools/gameCinematicSequencer.js +151 -0
- package/src/tools/gameDataForge.js +124 -0
- package/src/tools/gameDialogueTreeGen.js +166 -0
- package/src/tools/gameEconomyBalancer.js +161 -0
- package/src/tools/gameEntitySpawner.js +207 -0
- package/src/tools/gameLoreForge.js +153 -0
- package/src/tools/gameQuestArcBuilder.js +152 -0
- package/src/tools/gameSceneBuilder.js +158 -0
- package/src/tools/gameShaderForge.js +181 -0
- package/src/tools/gameTilemapGenerator.js +164 -0
- package/src/tools/gameUiHudBuilder.js +292 -0
- package/src/tools/gameVfxEmitterGen.js +108 -0
- package/src/tools/gameWebRuntimeInspector.js +91 -0
- package/src/tools/generateMediaViaApi.js +358 -0
- package/src/tools/gitExec.js +54 -0
- package/src/tools/godotAutomator.js +437 -0
- package/src/tools/manageLocalAiDependencies.js +220 -0
- package/src/tools/memoryWrite.js +99 -0
- package/src/tools/multiEdit.js +107 -0
- package/src/tools/palmierAutomator.js +104 -0
- package/src/tools/pdfReader.js +112 -0
- package/src/tools/persistentShell.js +148 -0
- package/src/tools/printer.js +316 -0
- package/src/tools/procTerm.js +91 -0
- package/src/tools/processList.js +52 -0
- package/src/tools/readNativeSkill.js +39 -0
- package/src/tools/registry.js +277 -0
- package/src/tools/resolveAutomator.js +102 -0
- package/src/tools/screenshot.js +75 -0
- package/src/tools/subagentOrchestrator.js +305 -0
- package/src/tools/sysRun.js +125 -0
- package/src/tools/todoWrite.js +75 -0
- package/src/tools/toolDispatch.js +127 -0
- package/src/tools/toolForge.js +124 -0
- package/src/tools/updatePlan.js +88 -0
- package/src/tools/viewImage.js +82 -0
- package/src/tools/visionInspector.js +154 -0
- package/src/tools/webFetch.js +74 -0
- package/src/tools/webSearch.js +82 -0
- package/src/tui/ask.js +164 -0
- package/src/tui/banner.js +158 -0
- package/src/tui/block.js +152 -0
- package/src/tui/chatRenderer.js +953 -0
- package/src/tui/completion.js +424 -0
- package/src/tui/dialogs.js +606 -0
- package/src/tui/diff.js +296 -0
- package/src/tui/history.js +135 -0
- package/src/tui/home.js +217 -0
- package/src/tui/invocation.js +105 -0
- package/src/tui/keys.js +443 -0
- package/src/tui/lineEditor.js +256 -0
- package/src/tui/overlay.js +256 -0
- package/src/tui/prompt.js +1258 -0
- package/src/tui/selectList.js +335 -0
- package/src/tui/stage.js +330 -0
- package/src/tui/stageSurface.js +609 -0
- package/src/tui/statusLine.js +254 -0
- package/src/tui/text.js +345 -0
- package/src/tui/theme.js +393 -0
- package/src/tui/toolDisplay.js +176 -0
- package/src/tui/transcript.js +235 -0
- package/src/tui/viewport.js +337 -0
- package/src/uncertainty.js +271 -0
- package/src/userSkills.js +265 -0
- package/src/utils/cli_ui.js +0 -0
- package/src/utils/inquirer.js +12 -0
- package/src/utils/paths.js +37 -0
- package/src/version.js +38 -0
- package/src/vfeTracker.js +220 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import fsSync from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
|
|
5
|
+
// Helper: Encode raw 16-bit PCM samples array (-1.0 to 1.0) into valid WAV binary Buffer
|
|
6
|
+
function encodeWav(samples, sampleRate = 44100) {
|
|
7
|
+
const numSamples = samples.length;
|
|
8
|
+
const buffer = Buffer.alloc(44 + numSamples * 2);
|
|
9
|
+
|
|
10
|
+
// RIFF Chunk
|
|
11
|
+
buffer.write('RIFF', 0);
|
|
12
|
+
buffer.writeUInt32LE(36 + numSamples * 2, 4);
|
|
13
|
+
buffer.write('WAVE', 8);
|
|
14
|
+
|
|
15
|
+
// fmt Sub-chunk
|
|
16
|
+
buffer.write('fmt ', 12);
|
|
17
|
+
buffer.writeUInt32LE(16, 16); // Sub-chunk size
|
|
18
|
+
buffer.writeUInt16LE(1, 20); // Audio format 1 = PCM
|
|
19
|
+
buffer.writeUInt16LE(1, 22); // Channels = 1 (Mono)
|
|
20
|
+
buffer.writeUInt32LE(sampleRate, 24); // Sample rate
|
|
21
|
+
buffer.writeUInt32LE(sampleRate * 2, 28); // Byte rate
|
|
22
|
+
buffer.writeUInt16LE(2, 32); // Block align
|
|
23
|
+
buffer.writeUInt16LE(16, 34); // Bits per sample
|
|
24
|
+
|
|
25
|
+
// data Sub-chunk
|
|
26
|
+
buffer.write('data', 36);
|
|
27
|
+
buffer.writeUInt32LE(numSamples * 2, 40);
|
|
28
|
+
|
|
29
|
+
// Write PCM 16-bit samples
|
|
30
|
+
let offset = 44;
|
|
31
|
+
for (let i = 0; i < numSamples; i++) {
|
|
32
|
+
const clamped = Math.max(-1.0, Math.min(1.0, samples[i]));
|
|
33
|
+
const intVal = clamped < 0 ? clamped * 32768 : clamped * 32767;
|
|
34
|
+
buffer.writeInt16LE(Math.floor(intVal), offset);
|
|
35
|
+
offset += 2;
|
|
36
|
+
}
|
|
37
|
+
return buffer;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const gameAudioSynth = {
|
|
41
|
+
schema: {
|
|
42
|
+
name: 'game.audio_synth',
|
|
43
|
+
description: 'Offline mathematical 16-bit PCM WAV audio synthesizer for Godot (`AudioStreamPlayer`) and Web games. Generates 15+ specialized game SFX (`sword_slash`, `spell_cast`, `hit_damage`, `potion_drink`, `car_drift`, `engine_rev`, `coin_pickup`, `jump`, `laser`, `explosion`, `footstep`, `boss_roar`) and looping Synthwave / Medieval BGM without external dependencies.',
|
|
44
|
+
parameters: {
|
|
45
|
+
type: 'object',
|
|
46
|
+
properties: {
|
|
47
|
+
action: {
|
|
48
|
+
type: 'string',
|
|
49
|
+
enum: ['synthesize_sfx', 'synthesize_bgm', 'generate_sound_pack'],
|
|
50
|
+
description: 'Action: synthesize_sfx (generate individual WAV sound effect), synthesize_bgm (generate looping background track), or generate_sound_pack (batch generate 10+ essential SFX into project audio/sfx folder).'
|
|
51
|
+
},
|
|
52
|
+
sfxType: {
|
|
53
|
+
type: 'string',
|
|
54
|
+
enum: [
|
|
55
|
+
'sword_slash', 'spell_cast', 'hit_damage', 'potion_drink',
|
|
56
|
+
'car_drift', 'engine_rev', 'coin_pickup', 'jump',
|
|
57
|
+
'laser', 'explosion', 'footstep', 'boss_roar',
|
|
58
|
+
'door_open', 'chest_unlock', 'level_up'
|
|
59
|
+
],
|
|
60
|
+
description: 'Type of sound effect to synthesize.'
|
|
61
|
+
},
|
|
62
|
+
bgmGenre: {
|
|
63
|
+
type: 'string',
|
|
64
|
+
enum: ['synthwave_racer', 'medieval_battle', 'mystic_dungeon'],
|
|
65
|
+
description: 'Genre for background music synthesis.'
|
|
66
|
+
},
|
|
67
|
+
durationSeconds: {
|
|
68
|
+
type: 'number',
|
|
69
|
+
description: 'Duration in seconds (default 0.4s for SFX, 4.0s loop for BGM).'
|
|
70
|
+
},
|
|
71
|
+
outputPath: {
|
|
72
|
+
type: 'string',
|
|
73
|
+
description: 'Absolute path to write the generated `.wav` file (`res://audio/sfx/sword.wav`).'
|
|
74
|
+
},
|
|
75
|
+
projectDir: {
|
|
76
|
+
type: 'string',
|
|
77
|
+
description: 'Absolute path to Godot project directory for generate_sound_pack.'
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
required: ['action']
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
async execute(args) {
|
|
85
|
+
try {
|
|
86
|
+
const { action, sfxType = 'sword_slash', bgmGenre = 'synthwave_racer', durationSeconds, outputPath, projectDir } = args;
|
|
87
|
+
const sampleRate = 44100;
|
|
88
|
+
|
|
89
|
+
if (action === 'synthesize_sfx') {
|
|
90
|
+
const duration = durationSeconds || (sfxType === 'boss_roar' || sfxType === 'explosion' ? 1.2 : 0.4);
|
|
91
|
+
const numSamples = Math.floor(sampleRate * duration);
|
|
92
|
+
const samples = new Float32Array(numSamples);
|
|
93
|
+
|
|
94
|
+
for (let i = 0; i < numSamples; i++) {
|
|
95
|
+
const t = i / sampleRate;
|
|
96
|
+
const progress = i / numSamples;
|
|
97
|
+
const envelope = Math.exp(-progress * 4.0); // Exponential decay
|
|
98
|
+
|
|
99
|
+
if (sfxType === 'sword_slash') {
|
|
100
|
+
// White noise filtered with high pitch sweep down
|
|
101
|
+
const freq = 1200 - progress * 900;
|
|
102
|
+
const noise = (Math.random() * 2 - 1) * 0.7;
|
|
103
|
+
const tone = Math.sin(2 * Math.PI * freq * t) * 0.3;
|
|
104
|
+
samples[i] = (noise + tone) * envelope * (progress < 0.1 ? progress * 10 : 1.0);
|
|
105
|
+
} else if (sfxType === 'spell_cast') {
|
|
106
|
+
// Frequency modulation chime sweep upwards
|
|
107
|
+
const freq = 400 + progress * 800 + Math.sin(2 * Math.PI * 30 * t) * 100;
|
|
108
|
+
samples[i] = Math.sin(2 * Math.PI * freq * t) * envelope;
|
|
109
|
+
} else if (sfxType === 'hit_damage') {
|
|
110
|
+
// Heavy low frequency impact + crunch noise
|
|
111
|
+
const freq = 120 - progress * 80;
|
|
112
|
+
const noise = (Math.random() * 2 - 1) * 0.5;
|
|
113
|
+
samples[i] = (Math.sin(2 * Math.PI * freq * t) + noise) * Math.exp(-progress * 8.0);
|
|
114
|
+
} else if (sfxType === 'potion_drink') {
|
|
115
|
+
// Liquid gulp pitch step up
|
|
116
|
+
const step = Math.floor(progress * 4);
|
|
117
|
+
const freq = 300 + step * 80;
|
|
118
|
+
samples[i] = Math.sin(2 * Math.PI * freq * t) * Math.exp(-(progress % 0.25) * 15.0);
|
|
119
|
+
} else if (sfxType === 'car_drift') {
|
|
120
|
+
// Tire screech high frequency noise modulation
|
|
121
|
+
const screech = Math.sin(2 * Math.PI * (1800 + Math.sin(2 * Math.PI * 40 * t) * 300) * t);
|
|
122
|
+
const noise = (Math.random() * 2 - 1) * 0.6;
|
|
123
|
+
samples[i] = (screech * 0.4 + noise * 0.6) * (1.0 - progress * 0.5);
|
|
124
|
+
} else if (sfxType === 'engine_rev') {
|
|
125
|
+
// Low sawtooth pulse growing in frequency
|
|
126
|
+
const freq = 60 + progress * 140;
|
|
127
|
+
const saw = 2 * (t * freq - Math.floor(0.5 + t * freq));
|
|
128
|
+
samples[i] = saw * 0.8 * Math.min(1.0, progress * 3.0);
|
|
129
|
+
} else if (sfxType === 'coin_pickup') {
|
|
130
|
+
// Classic two-tone high pitch chime
|
|
131
|
+
const freq = progress < 0.4 ? 987.77 : 1318.51; // B5 -> E6
|
|
132
|
+
samples[i] = Math.sin(2 * Math.PI * freq * t) * envelope * 0.7;
|
|
133
|
+
} else if (sfxType === 'jump') {
|
|
134
|
+
// Rapid pitch slide upwards
|
|
135
|
+
const freq = 180 + progress * 400;
|
|
136
|
+
samples[i] = Math.sin(2 * Math.PI * freq * t) * envelope;
|
|
137
|
+
} else if (sfxType === 'laser') {
|
|
138
|
+
// Fast downward sweep
|
|
139
|
+
const freq = 1500 * Math.pow(0.1, progress);
|
|
140
|
+
samples[i] = Math.sin(2 * Math.PI * freq * t) * envelope;
|
|
141
|
+
} else if (sfxType === 'explosion') {
|
|
142
|
+
// Deep bass rumble + heavy noise
|
|
143
|
+
const bass = Math.sin(2 * Math.PI * (50 - progress * 30) * t);
|
|
144
|
+
const noise = (Math.random() * 2 - 1);
|
|
145
|
+
samples[i] = (bass * 0.6 + noise * 0.6) * Math.exp(-progress * 2.5);
|
|
146
|
+
} else if (sfxType === 'boss_roar') {
|
|
147
|
+
// Aggressive guttural distortion & growl
|
|
148
|
+
const growl = Math.sin(2 * Math.PI * 45 * t + Math.sin(2 * Math.PI * 15 * t) * 5);
|
|
149
|
+
const noise = (Math.random() * 2 - 1) * 0.4;
|
|
150
|
+
samples[i] = Math.max(-0.8, Math.min(0.8, (growl + noise) * 1.5)) * Math.exp(-progress * 2.0);
|
|
151
|
+
} else if (sfxType === 'level_up') {
|
|
152
|
+
// Fanfare arpeggio C major (C5, E5, G5, C6)
|
|
153
|
+
const step = Math.floor(progress * 4);
|
|
154
|
+
const freqs = [523.25, 659.25, 783.99, 1046.50];
|
|
155
|
+
const freq = freqs[Math.min(3, step)];
|
|
156
|
+
samples[i] = Math.sin(2 * Math.PI * freq * t) * 0.7;
|
|
157
|
+
} else {
|
|
158
|
+
// Default crisp pop/click
|
|
159
|
+
samples[i] = Math.sin(2 * Math.PI * 440 * t) * envelope;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const wavBuffer = encodeWav(samples, sampleRate);
|
|
164
|
+
const finalPath = outputPath || path.join(process.cwd(), '.tmp_causyne_3d', `${sfxType}_${Date.now()}.wav`);
|
|
165
|
+
await fs.mkdir(path.dirname(finalPath), { recursive: true });
|
|
166
|
+
await fs.writeFile(finalPath, wavBuffer);
|
|
167
|
+
|
|
168
|
+
return {
|
|
169
|
+
success: true,
|
|
170
|
+
output: JSON.stringify({
|
|
171
|
+
status: 'SYNTHESIZED_SFX',
|
|
172
|
+
sfx_type: sfxType,
|
|
173
|
+
duration_seconds: duration,
|
|
174
|
+
sample_rate: sampleRate,
|
|
175
|
+
file_path: finalPath,
|
|
176
|
+
size_bytes: wavBuffer.length
|
|
177
|
+
}, null, 2)
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (action === 'synthesize_bgm') {
|
|
182
|
+
const duration = durationSeconds || 4.0;
|
|
183
|
+
const numSamples = Math.floor(sampleRate * duration);
|
|
184
|
+
const samples = new Float32Array(numSamples);
|
|
185
|
+
|
|
186
|
+
for (let i = 0; i < numSamples; i++) {
|
|
187
|
+
const t = i / sampleRate;
|
|
188
|
+
if (bgmGenre === 'synthwave_racer') {
|
|
189
|
+
// Driving bass pulse at 120 BPM (2 Hz pulse) + arpeggiator
|
|
190
|
+
const beat = (t * 4) % 1.0;
|
|
191
|
+
const bassFreq = 55.0; // A1
|
|
192
|
+
const bass = Math.sin(2 * Math.PI * bassFreq * t) * Math.exp(-beat * 4.0) * 0.6;
|
|
193
|
+
const arpStep = Math.floor((t * 8) % 4);
|
|
194
|
+
const arpFreqs = [220.0, 261.63, 329.63, 392.00];
|
|
195
|
+
const arp = Math.sin(2 * Math.PI * arpFreqs[arpStep] * t) * 0.2;
|
|
196
|
+
samples[i] = bass + arp;
|
|
197
|
+
} else if (bgmGenre === 'medieval_battle') {
|
|
198
|
+
// Marching drums + horns
|
|
199
|
+
const drumBeat = (t * 2) % 1.0;
|
|
200
|
+
const drum = (Math.random() * 2 - 1) * Math.exp(-drumBeat * 12.0) * 0.5;
|
|
201
|
+
const horn = Math.sin(2 * Math.PI * 146.83 * t) * 0.3; // D3
|
|
202
|
+
samples[i] = drum + horn;
|
|
203
|
+
} else {
|
|
204
|
+
// Mystic dungeon atmospheric drone
|
|
205
|
+
const drone = Math.sin(2 * Math.PI * 82.41 * t) * 0.4 + Math.sin(2 * Math.PI * 123.47 * t + Math.sin(t) * 2) * 0.2;
|
|
206
|
+
samples[i] = drone;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const wavBuffer = encodeWav(samples, sampleRate);
|
|
211
|
+
const finalPath = outputPath || path.join(process.cwd(), '.tmp_causyne_3d', `bgm_${bgmGenre}_${Date.now()}.wav`);
|
|
212
|
+
await fs.mkdir(path.dirname(finalPath), { recursive: true });
|
|
213
|
+
await fs.writeFile(finalPath, wavBuffer);
|
|
214
|
+
|
|
215
|
+
return {
|
|
216
|
+
success: true,
|
|
217
|
+
output: JSON.stringify({
|
|
218
|
+
status: 'SYNTHESIZED_BGM_LOOP',
|
|
219
|
+
bgm_genre: bgmGenre,
|
|
220
|
+
duration_seconds: duration,
|
|
221
|
+
file_path: finalPath,
|
|
222
|
+
size_bytes: wavBuffer.length
|
|
223
|
+
}, null, 2)
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (action === 'generate_sound_pack') {
|
|
228
|
+
if (!projectDir || !fsSync.existsSync(projectDir)) {
|
|
229
|
+
return { success: false, error: `Valid projectDir is required for generate_sound_pack. Found: ${projectDir}` };
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const sfxDir = path.join(projectDir, 'audio', 'sfx');
|
|
233
|
+
await fs.mkdir(sfxDir, { recursive: true });
|
|
234
|
+
|
|
235
|
+
const essentials = [
|
|
236
|
+
'sword_slash', 'spell_cast', 'hit_damage', 'potion_drink',
|
|
237
|
+
'coin_pickup', 'jump', 'level_up', 'explosion', 'boss_roar', 'car_drift'
|
|
238
|
+
];
|
|
239
|
+
|
|
240
|
+
const generatedFiles = [];
|
|
241
|
+
for (const sfx of essentials) {
|
|
242
|
+
const res = await gameAudioSynth.execute({
|
|
243
|
+
action: 'synthesize_sfx',
|
|
244
|
+
sfxType: sfx,
|
|
245
|
+
outputPath: path.join(sfxDir, `${sfx}.wav`)
|
|
246
|
+
});
|
|
247
|
+
const parsed = JSON.parse(res.output);
|
|
248
|
+
generatedFiles.push(parsed.file_path);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return {
|
|
252
|
+
success: true,
|
|
253
|
+
output: JSON.stringify({
|
|
254
|
+
status: 'GENERATED_SOUND_PACK',
|
|
255
|
+
project_dir: projectDir,
|
|
256
|
+
total_sounds_created: generatedFiles.length,
|
|
257
|
+
files: generatedFiles
|
|
258
|
+
}, null, 2)
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return { success: false, error: `Unknown action: ${action}` };
|
|
263
|
+
} catch (e) {
|
|
264
|
+
return { success: false, error: e.message };
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
};
|