feat: add git branch/worktree setup, message queueing, file explorer improvements, and server restart

This commit is contained in:
Mohamed Boudra
2025-11-22 23:20:42 +01:00
parent 9feec81047
commit 95bacf8fc7
40 changed files with 3759 additions and 644 deletions
+1
View File
@@ -0,0 +1 @@
export * from "./use-audio-player.native";
@@ -0,0 +1,27 @@
import { useMemo } from "react";
export interface AudioPlayerOptions {
isDetecting?: () => boolean;
isSpeaking?: () => boolean;
}
/**
* Web shim for the native two-way audio player.
* We currently don't support realtime voice playback on web.
*/
export function useAudioPlayer(_options?: AudioPlayerOptions) {
return useMemo(
() => ({
play: async () => {
console.warn("[AudioPlayer] Web playback is disabled");
return 0;
},
stop: () => {
console.warn("[AudioPlayer] Web playback stop noop");
},
isPlaying: () => false,
clearQueue: () => {},
}),
[]
);
}
+1
View File
@@ -0,0 +1 @@
export * from "./use-speechmatics-audio.native";
@@ -0,0 +1,63 @@
import { useCallback, useMemo, useState } from "react";
export interface SpeechmaticsAudioConfig {
onAudioSegment?: (segment: { audioData: string; isLast: boolean }) => void;
onSpeechStart?: () => void;
onSpeechEnd?: () => void;
onError?: (error: Error) => void;
volumeThreshold: number;
silenceDuration: number;
speechConfirmationDuration: number;
detectionGracePeriod: number;
}
export interface SpeechmaticsAudio {
start: () => Promise<void>;
stop: () => Promise<void>;
toggleMute: () => void;
isActive: boolean;
isSpeaking: boolean;
isDetecting: boolean;
isMuted: boolean;
volume: number;
segmentDuration: number;
}
/**
* Web shim for the Speechmatics two-way audio hook.
* Real-time microphone capture is currently unsupported on web.
*/
export function useSpeechmaticsAudio(
_config: SpeechmaticsAudioConfig
): SpeechmaticsAudio {
const [isActive, setIsActive] = useState(false);
const [isMuted, setIsMuted] = useState(false);
const start = useCallback(async () => {
console.warn("[SpeechmaticsAudio] Web microphone capture disabled");
setIsActive(true);
}, []);
const stop = useCallback(async () => {
setIsActive(false);
}, []);
const toggleMute = useCallback(() => {
setIsMuted((prev) => !prev);
}, []);
return useMemo(
() => ({
start,
stop,
toggleMute,
isActive,
isSpeaking: false,
isDetecting: false,
isMuted,
volume: 0,
segmentDuration: 0,
}),
[start, stop, toggleMute, isActive, isMuted]
);
}