feat(aircoding): AirCoding V2 baseline — deterministic multi-agent architecture
Forked from OpenCode v1.17.4 with multi-agent system: - 5 agents: aircoding, scheduler, worker, architect, reviewer - Deterministic DAG scheduling engine (coordinator_tick) - Tool whitelists as hard enforcement - AirCoding validation plugin - V1 requirements: C4 docs, ADR, AGENTS.md, debug-log.md - Design documents in docs/
This commit is contained in:
53
packages/tui/src/audio.ts
Normal file
53
packages/tui/src/audio.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { Audio, type AudioErrorContext, type AudioPlayOptions, type AudioSound, type AudioVoice } from "@opentui/core"
|
||||
import { readFile } from "node:fs/promises"
|
||||
|
||||
let audio: Audio | null | undefined
|
||||
const sounds = new Map<string, Promise<AudioSound | null>>()
|
||||
|
||||
function getAudio() {
|
||||
if (audio !== undefined) return audio
|
||||
try {
|
||||
const next = Audio.create({ autoStart: false })
|
||||
next.on("error", (error: Error, context: AudioErrorContext) => {
|
||||
console.debug("tui audio error", { error, context })
|
||||
})
|
||||
audio = next
|
||||
return next
|
||||
} catch (error) {
|
||||
console.debug("failed to create tui audio", { error })
|
||||
audio = null
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export function loadSoundFile(file: string) {
|
||||
const current = getAudio()
|
||||
if (!current) return Promise.resolve(null)
|
||||
const cached = sounds.get(file)
|
||||
if (cached) return cached
|
||||
const task = readFile(file)
|
||||
.then((bytes) => current.loadSound(bytes))
|
||||
.catch((error) => {
|
||||
console.debug("failed to load tui sound", { file, error })
|
||||
return null
|
||||
})
|
||||
sounds.set(file, task)
|
||||
return task
|
||||
}
|
||||
|
||||
export function play(sound: AudioSound, options?: AudioPlayOptions) {
|
||||
const current = getAudio()
|
||||
if (!current) return null
|
||||
if (!current.isStarted() && !current.start()) return null
|
||||
return current.play(sound, options)
|
||||
}
|
||||
|
||||
export function stopVoice(voice: AudioVoice) {
|
||||
return audio?.stopVoice(voice) ?? false
|
||||
}
|
||||
|
||||
export function dispose() {
|
||||
audio?.dispose()
|
||||
audio = undefined
|
||||
sounds.clear()
|
||||
}
|
||||
Reference in New Issue
Block a user