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:
Serhii Dziupin
2026-06-26 19:27:53 +03:00
committed by GitHub
co-authored by Serhii Dziupin Bohdan Triapitsyn
parent 4a37b9a005
commit 00821700de
324 changed files with 444 additions and 14876 deletions
@@ -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;
+2 -21
View File
@@ -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;
-111
View File
@@ -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.
-3
View File
@@ -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;
-8
View File
@@ -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
+1 -19
View File
@@ -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.
+2 -3
View File
@@ -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 };