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
@@ -1,46 +0,0 @@
|
||||
import type { Message, Part } from '@opencode-ai/sdk/v2';
|
||||
|
||||
export const resolveClientRole = (info: Pick<Message, 'role'> & { clientRole?: string | null }): string => {
|
||||
const role = info.clientRole ?? info.role;
|
||||
return typeof role === 'string' ? role : '';
|
||||
};
|
||||
|
||||
export const normalizeMessageInfoForProjection = <T extends Message>(info: T): T => {
|
||||
const clientRole = resolveClientRole(info);
|
||||
const shouldMarkUser = clientRole === 'user';
|
||||
|
||||
return {
|
||||
...info,
|
||||
clientRole,
|
||||
...(shouldMarkUser ? { userMessageMarker: true } : {}),
|
||||
} as T;
|
||||
};
|
||||
|
||||
export interface ChatMessageRecord {
|
||||
info: Message;
|
||||
parts: Part[];
|
||||
}
|
||||
|
||||
export const normalizeMessageRecordsForProjection = (messages: ChatMessageRecord[]): ChatMessageRecord[] => {
|
||||
return messages.map((message) => ({
|
||||
...message,
|
||||
info: normalizeMessageInfoForProjection(message.info),
|
||||
parts: Array.isArray(message.parts) ? message.parts : [],
|
||||
}));
|
||||
};
|
||||
|
||||
export const filterMessagesByRevertPoint = <T extends { info: { id: string } }>(
|
||||
messages: T[],
|
||||
revertMessageId: string | null,
|
||||
): T[] => {
|
||||
if (!revertMessageId) {
|
||||
return messages;
|
||||
}
|
||||
|
||||
const revertIndex = messages.findIndex((message) => message.info.id === revertMessageId);
|
||||
if (revertIndex < 0) {
|
||||
return messages;
|
||||
}
|
||||
|
||||
return messages.slice(0, revertIndex);
|
||||
};
|
||||
@@ -1,286 +0,0 @@
|
||||
import type { Part } from "@opencode-ai/sdk/v2";
|
||||
import { isFinalToolStatus } from "@/lib/toolStatus";
|
||||
|
||||
const isRecord = (value: unknown): value is Record<string, unknown> => {
|
||||
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
||||
};
|
||||
|
||||
const readTimestamp = (value: unknown): number | undefined => {
|
||||
return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
||||
};
|
||||
|
||||
const mergeTimeRange = (existing: unknown, incoming: unknown): Record<string, number> | undefined => {
|
||||
const existingTime = isRecord(existing) ? existing : undefined;
|
||||
const incomingTime = isRecord(incoming) ? incoming : undefined;
|
||||
|
||||
const startCandidates = [
|
||||
readTimestamp(existingTime?.start),
|
||||
readTimestamp(incomingTime?.start),
|
||||
].filter((value): value is number => typeof value === 'number');
|
||||
const endCandidates = [
|
||||
readTimestamp(existingTime?.end),
|
||||
readTimestamp(incomingTime?.end),
|
||||
].filter((value): value is number => typeof value === 'number');
|
||||
|
||||
if (startCandidates.length === 0 && endCandidates.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const merged: Record<string, number> = {};
|
||||
if (startCandidates.length > 0) {
|
||||
merged.start = Math.min(...startCandidates);
|
||||
}
|
||||
if (endCandidates.length > 0) {
|
||||
merged.end = Math.max(...endCandidates);
|
||||
}
|
||||
return merged;
|
||||
};
|
||||
|
||||
const mergeToolState = (existing: unknown, incoming: unknown): Record<string, unknown> | undefined => {
|
||||
const existingState = isRecord(existing) ? existing : undefined;
|
||||
const incomingState = isRecord(incoming) ? incoming : undefined;
|
||||
|
||||
if (!existingState && !incomingState) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Never downgrade a terminal status. Once a tool reaches completed/error/etc,
|
||||
// a late-arriving "running" SSE must not overwrite it.
|
||||
const existingStatus = existingState?.status;
|
||||
const incomingStatus = incomingState?.status;
|
||||
const existingIsTerminal = typeof existingStatus === 'string' && isFinalToolStatus(existingStatus);
|
||||
const incomingIsTerminal = typeof incomingStatus === 'string' && isFinalToolStatus(incomingStatus);
|
||||
|
||||
const merged: Record<string, unknown> = {
|
||||
...(existingState ?? {}),
|
||||
...(incomingState ?? {}),
|
||||
};
|
||||
|
||||
// If existing was terminal but incoming is not, keep the terminal status.
|
||||
if (existingIsTerminal && !incomingIsTerminal && typeof incomingStatus === 'string') {
|
||||
merged.status = existingStatus;
|
||||
}
|
||||
|
||||
const mergedTime = mergeTimeRange(existingState?.time, incomingState?.time);
|
||||
if (mergedTime) {
|
||||
merged.time = mergedTime;
|
||||
}
|
||||
|
||||
if (isRecord(existingState?.metadata) || isRecord(incomingState?.metadata)) {
|
||||
merged.metadata = {
|
||||
...(isRecord(existingState?.metadata) ? existingState.metadata : {}),
|
||||
...(isRecord(incomingState?.metadata) ? incomingState.metadata : {}),
|
||||
};
|
||||
}
|
||||
|
||||
if (isRecord(existingState?.input) || isRecord(incomingState?.input)) {
|
||||
merged.input = {
|
||||
...(isRecord(existingState?.input) ? existingState.input : {}),
|
||||
...(isRecord(incomingState?.input) ? incomingState.input : {}),
|
||||
};
|
||||
}
|
||||
|
||||
return merged;
|
||||
};
|
||||
|
||||
const extractTextFromDelta = (delta: unknown): string => {
|
||||
if (!delta) return '';
|
||||
if (typeof delta === 'string') return delta;
|
||||
if (Array.isArray(delta)) {
|
||||
return delta.map((item) => extractTextFromDelta(item)).join('');
|
||||
}
|
||||
if (typeof delta === 'object') {
|
||||
if (typeof (delta as { text?: unknown }).text === 'string') {
|
||||
return (delta as { text: string }).text;
|
||||
}
|
||||
if (Array.isArray((delta as { content?: unknown[] }).content)) {
|
||||
return (delta as { content: unknown[] }).content.map((item: unknown) => extractTextFromDelta(item)).join('');
|
||||
}
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
export const extractTextFromPart = (part: unknown): string => {
|
||||
if (!part) return '';
|
||||
const typedPart = part as { text?: string | unknown[]; content?: string | unknown[]; value?: string | unknown[]; delta?: unknown };
|
||||
|
||||
const toText = (value: unknown): string => {
|
||||
if (typeof value === 'string') {
|
||||
return value;
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
return value
|
||||
.map((item: unknown) => {
|
||||
if (typeof item === 'string') return item;
|
||||
if (item && typeof item === 'object') {
|
||||
const typedItem = item as { text?: unknown; content?: unknown; value?: unknown; delta?: unknown };
|
||||
return toText(typedItem.text) || toText(typedItem.content) || toText(typedItem.value) || extractTextFromDelta(typedItem.delta);
|
||||
}
|
||||
return '';
|
||||
})
|
||||
.join('');
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
const candidates = [
|
||||
toText(typedPart.text),
|
||||
toText(typedPart.content),
|
||||
toText(typedPart.value),
|
||||
extractTextFromDelta(typedPart.delta),
|
||||
];
|
||||
|
||||
let best = '';
|
||||
for (const candidate of candidates) {
|
||||
if (candidate.length > best.length) {
|
||||
best = candidate;
|
||||
}
|
||||
}
|
||||
|
||||
return best;
|
||||
};
|
||||
|
||||
export const normalizeStreamingPart = (incoming: Part, existing?: Part): Part => {
|
||||
const normalized: { type?: string; text?: string; content?: string; value?: string; delta?: unknown; [key: string]: unknown } = {
|
||||
...(existing as Record<string, unknown> | undefined),
|
||||
...incoming,
|
||||
} as { type?: string; text?: string; content?: string; value?: string; delta?: unknown; [key: string]: unknown };
|
||||
const existingType = typeof (existing as { type?: unknown } | undefined)?.type === 'string'
|
||||
? (existing as { type: string }).type
|
||||
: undefined;
|
||||
normalized.type = normalized.type || existingType || 'text';
|
||||
|
||||
const isStreamingTextLikePart = normalized.type === 'text' || normalized.type === 'reasoning';
|
||||
|
||||
if (isStreamingTextLikePart) {
|
||||
const existingRecord = (existing ?? {}) as { text?: unknown; content?: unknown; value?: unknown };
|
||||
const existingText = extractTextFromPart(existing);
|
||||
const directText = extractTextFromPart(incoming);
|
||||
const deltaText = extractTextFromDelta((incoming as { delta?: unknown }).delta);
|
||||
let mergedText = '';
|
||||
|
||||
const incomingField =
|
||||
typeof normalized.text === 'string'
|
||||
? 'text'
|
||||
: typeof normalized.content === 'string'
|
||||
? 'content'
|
||||
: typeof normalized.value === 'string'
|
||||
? 'value'
|
||||
: null;
|
||||
|
||||
const targetField = incomingField ?? (
|
||||
typeof existingRecord.text === 'string'
|
||||
? 'text'
|
||||
: typeof existingRecord.content === 'string'
|
||||
? 'content'
|
||||
: typeof existingRecord.value === 'string'
|
||||
? 'value'
|
||||
: 'text'
|
||||
);
|
||||
|
||||
if (deltaText) {
|
||||
mergedText = existingText ? `${existingText}${deltaText}` : deltaText;
|
||||
} else if (directText) {
|
||||
mergedText = directText;
|
||||
} else {
|
||||
mergedText = existingText;
|
||||
}
|
||||
|
||||
normalized[targetField] = mergedText;
|
||||
if (targetField !== 'text') {
|
||||
normalized.text = mergedText;
|
||||
}
|
||||
|
||||
delete normalized.delta;
|
||||
}
|
||||
|
||||
const mergedTime = mergeTimeRange(
|
||||
(existing as { time?: unknown } | undefined)?.time,
|
||||
(incoming as { time?: unknown } | undefined)?.time,
|
||||
);
|
||||
if (mergedTime) {
|
||||
normalized.time = mergedTime;
|
||||
}
|
||||
|
||||
if (normalized.type === 'tool') {
|
||||
const mergedState = mergeToolState(
|
||||
(existing as { state?: unknown } | undefined)?.state,
|
||||
(incoming as { state?: unknown } | undefined)?.state,
|
||||
);
|
||||
if (mergedState) {
|
||||
normalized.state = mergedState;
|
||||
}
|
||||
}
|
||||
|
||||
return normalized as Part;
|
||||
};
|
||||
|
||||
const deepEqualRecord = (left: Record<string, unknown>, right: Record<string, unknown>): boolean => {
|
||||
const keys = new Set<string>([
|
||||
...Object.keys(left),
|
||||
...Object.keys(right),
|
||||
]);
|
||||
|
||||
for (const key of keys) {
|
||||
const leftValue = left[key];
|
||||
const rightValue = right[key];
|
||||
|
||||
if (Array.isArray(leftValue) || Array.isArray(rightValue)) {
|
||||
if (!Array.isArray(leftValue) || !Array.isArray(rightValue) || leftValue.length !== rightValue.length) {
|
||||
return false;
|
||||
}
|
||||
for (let index = 0; index < leftValue.length; index += 1) {
|
||||
if (!deepEqualUnknown(leftValue[index], rightValue[index])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!deepEqualUnknown(leftValue, rightValue)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
const deepEqualUnknown = (left: unknown, right: unknown): boolean => {
|
||||
if (left === right) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!left || !right) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof left !== typeof right) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof left === 'object' && typeof right === 'object') {
|
||||
if (Array.isArray(left) || Array.isArray(right)) {
|
||||
if (!Array.isArray(left) || !Array.isArray(right) || left.length !== right.length) {
|
||||
return false;
|
||||
}
|
||||
for (let index = 0; index < left.length; index += 1) {
|
||||
if (!deepEqualUnknown(left[index], right[index])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return deepEqualRecord(left as Record<string, unknown>, right as Record<string, unknown>);
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
export const arePartsEquivalent = (left: Part | undefined, right: Part | undefined): boolean => {
|
||||
if (!left || !right) {
|
||||
return left === right;
|
||||
}
|
||||
|
||||
return deepEqualUnknown(left, right);
|
||||
};
|
||||
@@ -1,20 +1,5 @@
|
||||
import type { EditPermissionMode } from "../types/sessionTypes";
|
||||
|
||||
const EDIT_PERMISSION_TOOL_NAMES = new Set([
|
||||
'edit',
|
||||
'multiedit',
|
||||
'str_replace',
|
||||
'str_replace_based_edit_tool',
|
||||
'write',
|
||||
]);
|
||||
|
||||
export const isEditPermissionType = (type?: string | null): boolean => {
|
||||
if (!type) {
|
||||
return false;
|
||||
}
|
||||
return EDIT_PERMISSION_TOOL_NAMES.has(type.toLowerCase());
|
||||
};
|
||||
|
||||
type PermissionAction = 'allow' | 'deny' | 'ask';
|
||||
|
||||
type PermissionRule = {
|
||||
|
||||
@@ -7,15 +7,6 @@ export const streamDebugEnabled = (): boolean => {
|
||||
}
|
||||
};
|
||||
|
||||
export const sessionStatusDebugEnabled = (): boolean => {
|
||||
if (typeof window === 'undefined') return false;
|
||||
try {
|
||||
return window.localStorage.getItem('openchamber_session_status_debug') === '1';
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const STREAM_PERF_STORAGE_KEY = 'openchamber_stream_perf';
|
||||
|
||||
type PerfCounter = {
|
||||
@@ -31,7 +22,7 @@ type StreamPerfState = {
|
||||
lastUpdatedAt: number;
|
||||
};
|
||||
|
||||
export type StreamPerfEntry = {
|
||||
type StreamPerfEntry = {
|
||||
metric: string;
|
||||
count: number;
|
||||
avg: number;
|
||||
@@ -61,7 +52,7 @@ declare global {
|
||||
}
|
||||
}
|
||||
|
||||
export const streamPerfEnabled = (): boolean => {
|
||||
const streamPerfEnabled = (): boolean => {
|
||||
if (typeof window === 'undefined') return false;
|
||||
try {
|
||||
return window.localStorage.getItem(STREAM_PERF_STORAGE_KEY) === '1';
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
import type { MessageStreamLifecycle } from "../types/sessionTypes";
|
||||
|
||||
export type { MessageStreamLifecycle };
|
||||
|
||||
export const touchStreamingLifecycle = (
|
||||
source: Map<string, MessageStreamLifecycle>,
|
||||
messageId: string
|
||||
): Map<string, MessageStreamLifecycle> => {
|
||||
const now = Date.now();
|
||||
const existing = source.get(messageId);
|
||||
|
||||
const next = new Map(source);
|
||||
next.set(messageId, {
|
||||
phase: 'streaming',
|
||||
startedAt: existing?.startedAt ?? now,
|
||||
lastUpdateAt: now,
|
||||
});
|
||||
|
||||
return next;
|
||||
};
|
||||
|
||||
export const removeLifecycleEntries = (
|
||||
source: Map<string, MessageStreamLifecycle>,
|
||||
ids: Iterable<string>
|
||||
): Map<string, MessageStreamLifecycle> => {
|
||||
const idsArray = Array.from(ids);
|
||||
const shouldClone = idsArray.some((id) => source.has(id));
|
||||
|
||||
if (!shouldClone) {
|
||||
return source;
|
||||
}
|
||||
|
||||
const next = new Map(source);
|
||||
idsArray.forEach((id) => {
|
||||
next.delete(id);
|
||||
});
|
||||
|
||||
return next;
|
||||
};
|
||||
|
||||
const lifecycleCompletionTimers = new Map<string, ReturnType<typeof setTimeout>>();
|
||||
|
||||
export const clearLifecycleCompletionTimer = (messageId: string) => {
|
||||
const timer = lifecycleCompletionTimers.get(messageId);
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
lifecycleCompletionTimers.delete(messageId);
|
||||
}
|
||||
};
|
||||
|
||||
export const clearLifecycleTimersForIds = (ids: Iterable<string>) => {
|
||||
for (const id of ids) {
|
||||
clearLifecycleCompletionTimer(id);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user