* 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>
76 lines
3.0 KiB
TypeScript
76 lines
3.0 KiB
TypeScript
import React from 'react';
|
|
import { useSessionUIStore } from '@/sync/session-ui-store';
|
|
import { useSessionStatus, useSessionMessages, useSessionPermissions, useSessionQuestions } from '@/sync/sync-context';
|
|
|
|
// Mirrors OpenCode SessionStatus: busy|retry|idle.
|
|
type SessionActivityPhase = 'idle' | 'busy' | 'retry';
|
|
|
|
export interface SessionActivityResult {
|
|
phase: SessionActivityPhase;
|
|
isWorking: boolean;
|
|
isBusy: boolean;
|
|
isCooldown: boolean;
|
|
}
|
|
|
|
const IDLE_RESULT: SessionActivityResult = {
|
|
phase: 'idle',
|
|
isWorking: false,
|
|
isBusy: false,
|
|
isCooldown: false,
|
|
};
|
|
|
|
/**
|
|
* Determines if a session is actively working.
|
|
* Checks session_status and, only when status is missing, falls back to the
|
|
* trailing assistant message when its completion update has not landed yet.
|
|
* Returns idle when permissions or questions are pending (the permission /
|
|
* question indicator takes priority, and the send button must stay available so
|
|
* the user can supersede the prompt with a new message).
|
|
*/
|
|
function useSessionActivity(sessionId: string | null | undefined, directory?: string): SessionActivityResult {
|
|
const status = useSessionStatus(sessionId ?? '', directory);
|
|
const messages = useSessionMessages(sessionId ?? '', directory);
|
|
const permissions = useSessionPermissions(sessionId ?? '', directory);
|
|
const questions = useSessionQuestions(sessionId ?? '', directory);
|
|
|
|
return React.useMemo<SessionActivityResult>(() => {
|
|
if (!sessionId) return IDLE_RESULT;
|
|
|
|
// Permissions or questions pending → idle (the blocking indicator takes
|
|
// priority and the send button must remain a send, not a stop).
|
|
if (permissions.length > 0 || questions.length > 0) return IDLE_RESULT;
|
|
|
|
const phase: SessionActivityPhase = (status?.type ?? 'idle') as SessionActivityPhase;
|
|
|
|
// Only trust the trailing assistant message as a transient fallback while
|
|
// waiting for session.status/message.updated to settle.
|
|
const lastMessage = messages[messages.length - 1];
|
|
const hasPendingAssistant = Boolean(
|
|
lastMessage
|
|
&& lastMessage.role === 'assistant'
|
|
&& typeof (lastMessage as { time?: { completed?: number } }).time?.completed !== 'number',
|
|
);
|
|
|
|
const hasAuthoritativeStatus = status !== undefined;
|
|
const statusWorking = hasAuthoritativeStatus && phase !== 'idle';
|
|
const isWorking = statusWorking || hasPendingAssistant;
|
|
|
|
if (hasAuthoritativeStatus && !statusWorking) return IDLE_RESULT;
|
|
|
|
if (!isWorking) return IDLE_RESULT;
|
|
|
|
return {
|
|
phase: statusWorking ? phase : 'busy',
|
|
isWorking: true,
|
|
isBusy: phase === 'busy' || (!statusWorking && hasPendingAssistant),
|
|
isCooldown: false,
|
|
};
|
|
}, [sessionId, status, messages, permissions, questions]);
|
|
}
|
|
|
|
export function useCurrentSessionActivity(): SessionActivityResult {
|
|
const currentSessionId = useSessionUIStore((state) => state.currentSessionId);
|
|
const currentSessionDirectory = useSessionUIStore((state) => state.currentSessionDirectory);
|
|
return useSessionActivity(currentSessionId, currentSessionDirectory ?? undefined);
|
|
}
|