chore: remove dead code (59 unused files + ~125 unused exports) (#1835)
* chore: remove dead/unreferenced files across ui, vscode Remove 59 unused source files (components, hooks, lib utils, stores, barrels, and orphaned vscode github modules) that are not imported by any entry-reachable code. Also drop a stale test mock for the removed execCommands module. Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com> * refactor: remove unused exported symbols (types, functions, consts, hooks) Remove exported symbols whose identifier is referenced nowhere in the repository (verified via repo-wide search), across ui types/contracts, lib utilities, sync layer, stores, and components. Also drop the few imports/private helpers orphaned by these removals. Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com> * refactor: remove more unused exports (desktop, shortcuts, worktree, vscode) Continue removing repo-wide unreferenced exported functions, consts and types across lib/desktop, shortcuts, worktreeSessionCreator, sync, and vscode gitService, with cascading orphaned helpers/imports cleaned up. Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com> * chore: add dead-code cleanup tooling * refactor: checkpoint dead-code cleanup * refactor: remove dead-code suppressions --------- Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com> Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
This commit is contained in:
committed by
GitHub
co-authored by
Serhii Dziupin
Bohdan Triapitsyn
parent
4a37b9a005
commit
00821700de
@@ -20,10 +20,10 @@
|
||||
|
||||
import { runtimeFetch } from '@/lib/runtime-fetch';
|
||||
|
||||
export type SpeechResultCallback = (text: string, isFinal: boolean) => void;
|
||||
export type ErrorCallback = (error: string) => void;
|
||||
type SpeechResultCallback = (text: string, isFinal: boolean) => void;
|
||||
type ErrorCallback = (error: string) => void;
|
||||
|
||||
export interface AudioStreamConfig {
|
||||
interface AudioStreamConfig {
|
||||
/** Base URL of the OpenAI-compatible STT server (e.g. http://localhost:8001/v1) */
|
||||
baseURL: string;
|
||||
/** Whisper-compatible model name */
|
||||
@@ -395,4 +395,3 @@ class AudioStreamService {
|
||||
}
|
||||
|
||||
export const audioStreamService = new AudioStreamService();
|
||||
export { AudioStreamService };
|
||||
|
||||
@@ -34,9 +34,9 @@ declare global {
|
||||
}
|
||||
|
||||
// Callback types
|
||||
export type SpeechResultCallback = (text: string, isFinal: boolean) => void;
|
||||
export type SpeechEndCallback = () => void;
|
||||
export type ErrorCallback = (error: string) => void;
|
||||
type SpeechResultCallback = (text: string, isFinal: boolean) => void;
|
||||
type SpeechEndCallback = () => void;
|
||||
type ErrorCallback = (error: string) => void;
|
||||
|
||||
/**
|
||||
* Browser Voice Service class
|
||||
@@ -234,7 +234,7 @@ class BrowserVoiceService {
|
||||
this.isListening = true;
|
||||
this.restartOnEnd = true;
|
||||
};
|
||||
|
||||
|
||||
this.recognition.onaudiostart = () => {
|
||||
console.log('[BrowserVoiceService] Audio recording started');
|
||||
};
|
||||
@@ -652,6 +652,3 @@ class BrowserVoiceService {
|
||||
|
||||
// Export singleton instance
|
||||
export const browserVoiceService = new BrowserVoiceService();
|
||||
|
||||
// Also export the class for testing/customization
|
||||
export { BrowserVoiceService };
|
||||
|
||||
@@ -29,7 +29,7 @@ export interface VoiceMessage {
|
||||
* @param message - The message to format
|
||||
* @returns Formatted text for voice, or null if should not be spoken
|
||||
*/
|
||||
export function formatMessage(message: VoiceMessage): string | null {
|
||||
function formatMessage(message: VoiceMessage): string | null {
|
||||
// Handle edge cases
|
||||
if (!message || typeof message.content !== "string") {
|
||||
return null;
|
||||
|
||||
@@ -1,36 +1,17 @@
|
||||
/**
|
||||
* Voice module barrel export
|
||||
* Provides clean import path for voice configuration and client tools
|
||||
* Provides a clean import path for voice session hooks.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* import { VOICE_CONFIG, realtimeClientTools, voiceHooks } from '@/lib/voice';
|
||||
* import { voiceHooks } from '@/lib/voice';
|
||||
* ```
|
||||
*/
|
||||
|
||||
// Configuration
|
||||
export { VOICE_CONFIG } from "./voiceConfig";
|
||||
|
||||
// Client tools for ElevenLabs voice agent
|
||||
export { realtimeClientTools } from "./realtimeClientTools";
|
||||
export type { RealtimeClientTools } from "./realtimeClientTools";
|
||||
|
||||
// Voice session registry (from voiceSession.ts)
|
||||
export {
|
||||
registerVoiceSession,
|
||||
unregisterVoiceSession,
|
||||
getVoiceSession,
|
||||
isVoiceSessionStarted,
|
||||
} from "./voiceSession";
|
||||
|
||||
// Voice hooks for session-to-voice event routing (from voiceHooks.ts)
|
||||
export { voiceHooks } from "./voiceHooks";
|
||||
|
||||
// Context formatters for voice-native output
|
||||
export {
|
||||
formatMessage,
|
||||
formatNewMessages,
|
||||
formatPermissionRequest,
|
||||
formatReadyEvent,
|
||||
type VoiceMessage,
|
||||
} from "./contextFormatters";
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
import { z } from "zod";
|
||||
import { useSessionUIStore } from '@/sync/session-ui-store';
|
||||
import { useConfigStore } from "@/stores/useConfigStore";
|
||||
import { getSyncPermissions } from "@/sync/sync-refs";
|
||||
import { respondToPermission } from "@/sync/session-actions";
|
||||
|
||||
/**
|
||||
* Static client tools for the realtime voice interface.
|
||||
* These tools allow the voice agent to interact with Claude Code.
|
||||
*/
|
||||
export const realtimeClientTools = {
|
||||
/**
|
||||
* Send a message to Claude Code via the current session.
|
||||
* Validates parameters with Zod and returns status strings.
|
||||
*/
|
||||
messageClaudeCode: async (parameters: unknown): Promise<string> => {
|
||||
// Validate parameters with Zod
|
||||
const schema = z.object({
|
||||
message: z.string().min(1, "Message cannot be empty"),
|
||||
});
|
||||
|
||||
const parsed = schema.safeParse(parameters);
|
||||
if (!parsed.success) {
|
||||
console.error("[Voice] Invalid message parameter:", parsed.error);
|
||||
return "error (invalid message parameter)";
|
||||
}
|
||||
|
||||
// Get current session ID from store
|
||||
const sessionId = useSessionUIStore.getState().currentSessionId;
|
||||
if (!sessionId) {
|
||||
console.error("[Voice] No active session");
|
||||
return "error (no active session)";
|
||||
}
|
||||
|
||||
// Get current provider and model from config store
|
||||
const { currentProviderId, currentModelId, currentAgentName, currentVariant } = useConfigStore.getState();
|
||||
if (!currentProviderId || !currentModelId) {
|
||||
console.error("[Voice] No provider/model selected");
|
||||
return "error (no provider or model selected)";
|
||||
}
|
||||
|
||||
try {
|
||||
console.log("[Voice] Sending message to session:", sessionId);
|
||||
await useSessionUIStore
|
||||
.getState()
|
||||
.sendMessage(
|
||||
parsed.data.message,
|
||||
currentProviderId,
|
||||
currentModelId,
|
||||
currentAgentName ?? undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
currentVariant ?? undefined,
|
||||
);
|
||||
return "sent";
|
||||
} catch (error) {
|
||||
console.error("[Voice] Failed to send message:", error);
|
||||
return "error (failed to send message)";
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Process a permission request from voice.
|
||||
* Validates decision with Zod enum and interacts with permission store.
|
||||
*/
|
||||
processPermissionRequest: async (parameters: unknown): Promise<string> => {
|
||||
// Validate parameters with Zod
|
||||
const schema = z.object({
|
||||
decision: z.enum(["allow", "deny"]),
|
||||
});
|
||||
|
||||
const parsed = schema.safeParse(parameters);
|
||||
if (!parsed.success) {
|
||||
console.error("[Voice] Invalid decision parameter:", parsed.error);
|
||||
return "error (invalid decision parameter, expected 'allow' or 'deny')";
|
||||
}
|
||||
|
||||
// Get current session ID from store
|
||||
const sessionId = useSessionUIStore.getState().currentSessionId;
|
||||
if (!sessionId) {
|
||||
console.error("[Voice] No active session");
|
||||
return "error (no active session)";
|
||||
}
|
||||
|
||||
// Get pending permissions for this session
|
||||
const permissions = getSyncPermissions(sessionId);
|
||||
if (!permissions || permissions.length === 0) {
|
||||
console.error("[Voice] No pending permission requests");
|
||||
return "error (no pending permission request)";
|
||||
}
|
||||
|
||||
// Get the first pending permission request
|
||||
const request = permissions[0];
|
||||
if (!request) {
|
||||
return "error (no pending permission request)";
|
||||
}
|
||||
|
||||
try {
|
||||
const decision = parsed.data.decision;
|
||||
console.log(`[Voice] Processing permission request ${request.id}: ${decision}`);
|
||||
|
||||
// Respond to the permission based on decision
|
||||
const response: "once" | "always" | "reject" = decision === "allow" ? "once" : "reject";
|
||||
await respondToPermission(sessionId, request.id, response);
|
||||
|
||||
return "done";
|
||||
} catch (error) {
|
||||
console.error("[Voice] Failed to process permission:", error);
|
||||
return `error (failed to ${parsed.data.decision} permission)`;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/** Type for the realtime client tools */
|
||||
export type RealtimeClientTools = typeof realtimeClientTools;
|
||||
@@ -1,114 +1,3 @@
|
||||
/**
|
||||
* Text summarization utility
|
||||
*
|
||||
* Calls the server-side text summarization endpoint which uses
|
||||
* the opencode.ai zen API with gpt-5-nano.
|
||||
*/
|
||||
|
||||
import { useConfigStore } from '@/stores/useConfigStore';
|
||||
import { runtimeFetch } from '@/lib/runtime-fetch';
|
||||
|
||||
/**
|
||||
* Summarize text using the server-side zen API endpoint
|
||||
*
|
||||
* @param text - The text to summarize
|
||||
* @param options - Optional configuration
|
||||
* @returns The summarized text, or original text if summarization fails
|
||||
*/
|
||||
export async function summarizeText(
|
||||
text: string,
|
||||
options?: {
|
||||
/** Character threshold - don't summarize if under this length */
|
||||
threshold?: number;
|
||||
/** Max characters for the summary output */
|
||||
maxLength?: number;
|
||||
/** Summarization mode */
|
||||
mode?: 'tts' | 'note';
|
||||
}
|
||||
): Promise<string> {
|
||||
const store = useConfigStore.getState();
|
||||
const threshold = options?.threshold ?? store.summarizeCharacterThreshold;
|
||||
const maxLength = options?.maxLength ?? store.summarizeMaxLength;
|
||||
const mode = options?.mode ?? 'tts';
|
||||
const normalizedSource = text.replace(/\s+/g, ' ').trim();
|
||||
|
||||
// Don't summarize if text is under threshold
|
||||
if (text.length <= threshold) {
|
||||
if (mode === 'note') {
|
||||
throw new Error('Note summarization threshold bypass is not allowed');
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await runtimeFetch('/api/text/summarize', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ text, threshold, maxLength, mode }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
console.error(`[summarize] HTTP error ${response.status}:`, errorText);
|
||||
throw new Error(`Summarization failed: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json() as {
|
||||
summarized: boolean;
|
||||
summary?: string;
|
||||
reason?: string;
|
||||
originalLength?: number;
|
||||
summaryLength?: number;
|
||||
};
|
||||
|
||||
if (typeof data.summary === 'string' && data.summary.trim().length > 0) {
|
||||
const summary = data.summary.trim();
|
||||
if (mode === 'note') {
|
||||
const normalizedSummary = summary.replace(/\s+/g, ' ').trim();
|
||||
if (normalizedSummary === normalizedSource) {
|
||||
throw new Error('Note distillation returned source text unchanged');
|
||||
}
|
||||
}
|
||||
return summary;
|
||||
}
|
||||
|
||||
if (mode === 'note') {
|
||||
throw new Error('Note summarization returned no distilled result');
|
||||
}
|
||||
// Return original text if the server produced nothing usable
|
||||
return text;
|
||||
} catch (err) {
|
||||
console.error('[summarize] Failed to summarize:', err);
|
||||
if (mode === 'note') {
|
||||
throw err instanceof Error ? err : new Error('Note summarization failed');
|
||||
}
|
||||
// Return original text on error
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if text should be summarized based on settings
|
||||
*/
|
||||
export function shouldSummarize(
|
||||
text: string,
|
||||
context: 'message' | 'voice'
|
||||
): boolean {
|
||||
const store = useConfigStore.getState();
|
||||
|
||||
const isEnabled = context === 'message'
|
||||
? store.summarizeMessageTTS
|
||||
: store.summarizeVoiceConversation;
|
||||
|
||||
if (!isEnabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return text.length > store.summarizeCharacterThreshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Client-side text sanitization for TTS output.
|
||||
* Removes markdown, URLs, file paths, and other non-speakable content.
|
||||
|
||||
@@ -30,6 +30,3 @@ export const VOICE_CONFIG = {
|
||||
/** Enable debug logging for voice context updates */
|
||||
ENABLE_DEBUG_LOGGING: true,
|
||||
} as const;
|
||||
|
||||
/** Type for VOICE_CONFIG keys */
|
||||
export type VoiceConfigKey = keyof typeof VOICE_CONFIG;
|
||||
|
||||
@@ -24,14 +24,6 @@ import {
|
||||
} from "./contextFormatters";
|
||||
import { getVoiceSession, isVoiceSessionStarted } from "./voiceSession";
|
||||
|
||||
// Re-export registry functions from voiceSession.ts for convenience
|
||||
export {
|
||||
registerVoiceSession,
|
||||
unregisterVoiceSession,
|
||||
getVoiceSession,
|
||||
isVoiceSessionStarted,
|
||||
} from "./voiceSession";
|
||||
|
||||
/**
|
||||
* Report a contextual update to the voice session
|
||||
* Internal helper that checks preconditions and handles errors
|
||||
|
||||
@@ -10,25 +10,7 @@ interface VoiceSession {
|
||||
* Global storage for the active voice session.
|
||||
* Used by voiceHooks to send contextual updates to the voice agent.
|
||||
*/
|
||||
let activeVoiceSession: VoiceSession | null = null;
|
||||
|
||||
/**
|
||||
* Register a voice session for use by voiceHooks.
|
||||
* Called by useVoice when a conversation is established.
|
||||
*/
|
||||
export function registerVoiceSession(session: VoiceSession): void {
|
||||
activeVoiceSession = session;
|
||||
console.log("[Voice] Session registered");
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister the active voice session.
|
||||
* Called by useVoice when the session ends.
|
||||
*/
|
||||
export function unregisterVoiceSession(): void {
|
||||
activeVoiceSession = null;
|
||||
console.log("[Voice] Session unregistered");
|
||||
}
|
||||
const activeVoiceSession: VoiceSession | null = null;
|
||||
|
||||
/**
|
||||
* Get the currently registered voice session.
|
||||
|
||||
@@ -48,8 +48,8 @@ export const WASM_MODELS: WasmModelInfo[] = [
|
||||
},
|
||||
];
|
||||
|
||||
export type SpeechResultCallback = (text: string, isFinal: boolean) => void;
|
||||
export type ErrorCallback = (error: string) => void;
|
||||
type SpeechResultCallback = (text: string, isFinal: boolean) => void;
|
||||
type ErrorCallback = (error: string) => void;
|
||||
|
||||
const VAD_POLL_MS = 80;
|
||||
const MIN_UTTERANCE_MS = 300;
|
||||
@@ -553,4 +553,3 @@ class WasmSttService {
|
||||
}
|
||||
|
||||
export const wasmSttService = new WasmSttService();
|
||||
export { WasmSttService };
|
||||
|
||||
Reference in New Issue
Block a user