mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-06-09 07:05:51 +08:00
Compare commits
2 Commits
fix/codex-
...
chore/add-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3cd89956ba | ||
|
|
01dbe2a8bf |
@@ -279,16 +279,6 @@ export async function queryCodex(command, options = {}, ws) {
|
|||||||
startedAt: new Date().toISOString()
|
startedAt: new Date().toISOString()
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const markSessionFinished = (id) => {
|
|
||||||
if (!id) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const session = activeCodexSessions.get(id);
|
|
||||||
if (session && session.status !== 'aborted') {
|
|
||||||
session.status = 'completed';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Existing sessions can be tracked immediately; new sessions are tracked after thread.started.
|
// Existing sessions can be tracked immediately; new sessions are tracked after thread.started.
|
||||||
if (capturedSessionId) {
|
if (capturedSessionId) {
|
||||||
@@ -334,10 +324,6 @@ export async function queryCodex(command, options = {}, ws) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.type === 'turn.completed' || event.type === 'turn.failed') {
|
|
||||||
markSessionFinished(capturedSessionId || sessionId);
|
|
||||||
}
|
|
||||||
|
|
||||||
const transformed = transformCodexEvent(event);
|
const transformed = transformCodexEvent(event);
|
||||||
|
|
||||||
// Normalize the transformed event into NormalizedMessage(s) via adapter
|
// Normalize the transformed event into NormalizedMessage(s) via adapter
|
||||||
@@ -368,8 +354,6 @@ export async function queryCodex(command, options = {}, ws) {
|
|||||||
|
|
||||||
// Send completion event
|
// Send completion event
|
||||||
if (!terminalFailure) {
|
if (!terminalFailure) {
|
||||||
markSessionFinished(capturedSessionId || sessionId);
|
|
||||||
|
|
||||||
sendMessage(ws, createNormalizedMessage({
|
sendMessage(ws, createNormalizedMessage({
|
||||||
kind: 'complete',
|
kind: 'complete',
|
||||||
actualSessionId: capturedSessionId || thread.id || sessionId || null,
|
actualSessionId: capturedSessionId || thread.id || sessionId || null,
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import os from 'os';
|
import os from 'os';
|
||||||
import { spawn } from 'child_process';
|
|
||||||
|
import { spawn } from 'cross-spawn';
|
||||||
|
|
||||||
const PLUGINS_DIR = path.join(os.homedir(), '.claude-code-ui', 'plugins');
|
const PLUGINS_DIR = path.join(os.homedir(), '.claude-code-ui', 'plugins');
|
||||||
const PLUGINS_CONFIG_PATH = path.join(os.homedir(), '.claude-code-ui', 'plugins.json');
|
const PLUGINS_CONFIG_PATH = path.join(os.homedir(), '.claude-code-ui', 'plugins.json');
|
||||||
|
|||||||
@@ -98,7 +98,6 @@ export function useChatRealtimeHandlers({
|
|||||||
}: UseChatRealtimeHandlersArgs) {
|
}: UseChatRealtimeHandlersArgs) {
|
||||||
const paletteOps = usePaletteOps();
|
const paletteOps = usePaletteOps();
|
||||||
const lastProcessedMessageRef = useRef<LatestChatMessage | null>(null);
|
const lastProcessedMessageRef = useRef<LatestChatMessage | null>(null);
|
||||||
const terminalSessionIdsRef = useRef<Set<string>>(new Set());
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!latestMessage) return;
|
if (!latestMessage) return;
|
||||||
@@ -152,17 +151,6 @@ export function useChatRealtimeHandlers({
|
|||||||
const isCurrentSession =
|
const isCurrentSession =
|
||||||
statusSessionId === currentSessionId || (selectedSession && statusSessionId === selectedSession.id);
|
statusSessionId === currentSessionId || (selectedSession && statusSessionId === selectedSession.id);
|
||||||
|
|
||||||
if (msg.isProcessing && terminalSessionIdsRef.current.has(statusSessionId)) {
|
|
||||||
onSessionInactive?.(statusSessionId);
|
|
||||||
onSessionNotProcessing?.(statusSessionId);
|
|
||||||
if (isCurrentSession) {
|
|
||||||
setIsLoading(false);
|
|
||||||
setCanAbortSession(false);
|
|
||||||
setClaudeStatus(null);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (msg.isProcessing) {
|
if (msg.isProcessing) {
|
||||||
onSessionActive?.(statusSessionId);
|
onSessionActive?.(statusSessionId);
|
||||||
onSessionProcessing?.(statusSessionId);
|
onSessionProcessing?.(statusSessionId);
|
||||||
@@ -192,10 +180,6 @@ export function useChatRealtimeHandlers({
|
|||||||
|
|
||||||
const sid = msg.sessionId || activeViewSessionId;
|
const sid = msg.sessionId || activeViewSessionId;
|
||||||
|
|
||||||
if (sid && msg.kind === 'session_created') {
|
|
||||||
terminalSessionIdsRef.current.delete(sid);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Streaming: buffer for performance ---
|
// --- Streaming: buffer for performance ---
|
||||||
if (msg.kind === 'stream_delta') {
|
if (msg.kind === 'stream_delta') {
|
||||||
const text = msg.content || '';
|
const text = msg.content || '';
|
||||||
@@ -274,10 +258,6 @@ export function useChatRealtimeHandlers({
|
|||||||
}
|
}
|
||||||
|
|
||||||
case 'complete': {
|
case 'complete': {
|
||||||
if (sid) {
|
|
||||||
terminalSessionIdsRef.current.add(sid);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flush any remaining streaming state
|
// Flush any remaining streaming state
|
||||||
if (streamTimerRef.current) {
|
if (streamTimerRef.current) {
|
||||||
clearTimeout(streamTimerRef.current);
|
clearTimeout(streamTimerRef.current);
|
||||||
@@ -333,10 +313,6 @@ export function useChatRealtimeHandlers({
|
|||||||
}
|
}
|
||||||
|
|
||||||
case 'error': {
|
case 'error': {
|
||||||
if (sid) {
|
|
||||||
terminalSessionIdsRef.current.add(sid);
|
|
||||||
}
|
|
||||||
|
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
setCanAbortSession(false);
|
setCanAbortSession(false);
|
||||||
setClaudeStatus(null);
|
setClaudeStatus(null);
|
||||||
|
|||||||
@@ -131,8 +131,6 @@ export function useChatSessionState({
|
|||||||
const pendingInitialScrollRef = useRef(true);
|
const pendingInitialScrollRef = useRef(true);
|
||||||
const messagesOffsetRef = useRef(0);
|
const messagesOffsetRef = useRef(0);
|
||||||
const scrollPositionRef = useRef({ height: 0, top: 0 });
|
const scrollPositionRef = useRef({ height: 0, top: 0 });
|
||||||
const previousProcessingSessionsRef = useRef<Set<string> | null>(null);
|
|
||||||
const previousProcessingSessionViewIdRef = useRef<string | null>(null);
|
|
||||||
const loadAllFinishedTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
const loadAllFinishedTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||||
const loadAllOverlayTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
const loadAllOverlayTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||||
const lastLoadedSessionKeyRef = useRef<string | null>(null);
|
const lastLoadedSessionKeyRef = useRef<string | null>(null);
|
||||||
@@ -695,17 +693,9 @@ export function useChatSessionState({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const activeViewSessionId = selectedSession?.id || currentSessionId;
|
const activeViewSessionId = selectedSession?.id || currentSessionId;
|
||||||
const previousProcessingSessions = previousProcessingSessionsRef.current;
|
|
||||||
const previousProcessingSessionViewId = previousProcessingSessionViewIdRef.current;
|
|
||||||
previousProcessingSessionsRef.current = processingSessions ?? null;
|
|
||||||
previousProcessingSessionViewIdRef.current = activeViewSessionId ?? null;
|
|
||||||
|
|
||||||
if (!activeViewSessionId || !processingSessions) return;
|
if (!activeViewSessionId || !processingSessions) return;
|
||||||
|
|
||||||
const activeViewSessionChanged = previousProcessingSessionViewId !== activeViewSessionId;
|
|
||||||
const wasProcessing = previousProcessingSessions?.has(activeViewSessionId) ?? false;
|
|
||||||
const shouldBeProcessing = processingSessions.has(activeViewSessionId);
|
const shouldBeProcessing = processingSessions.has(activeViewSessionId);
|
||||||
if (shouldBeProcessing && (!wasProcessing || activeViewSessionChanged) && !isLoading) {
|
if (shouldBeProcessing && !isLoading) {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
setCanAbortSession(true);
|
setCanAbortSession(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ const STARTER_PLUGIN_URL = 'https://github.com/cloudcli-ai/cloudcli-plugin-start
|
|||||||
const TERMINAL_PLUGIN_URL = 'https://github.com/cloudcli-ai/cloudcli-plugin-terminal';
|
const TERMINAL_PLUGIN_URL = 'https://github.com/cloudcli-ai/cloudcli-plugin-terminal';
|
||||||
const SCHEDULED_PROMPT_PLUGIN_URL = 'https://github.com/grostim/cloudcli-cron';
|
const SCHEDULED_PROMPT_PLUGIN_URL = 'https://github.com/grostim/cloudcli-cron';
|
||||||
const CLAUDE_WATCH_PLUGIN_URL = 'https://github.com/satsuki19980613/cloudcli-claude-watch';
|
const CLAUDE_WATCH_PLUGIN_URL = 'https://github.com/satsuki19980613/cloudcli-claude-watch';
|
||||||
|
const PRISM_CLOUDCLI_PLUGIN_URL = 'https://github.com/jakeefr/cloudcli-plugin-prism';
|
||||||
|
|
||||||
type PluginRecommendation = {
|
type PluginRecommendation = {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -72,6 +73,14 @@ const UNOFFICIAL_PLUGIN_RECOMMENDATIONS: PluginRecommendation[] = [
|
|||||||
icon: Clock,
|
icon: Clock,
|
||||||
source: 'unofficial',
|
source: 'unofficial',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'prism-cloudcli',
|
||||||
|
translationKey: 'prismCloudCLI',
|
||||||
|
repoUrl: PRISM_CLOUDCLI_PLUGIN_URL,
|
||||||
|
installedNames: ['prism-cloudcli'],
|
||||||
|
icon: Activity,
|
||||||
|
source: 'unofficial'
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
function repoSlug(repoUrl: string) {
|
function repoSlug(repoUrl: string) {
|
||||||
|
|||||||
@@ -502,6 +502,12 @@
|
|||||||
"description": "Watch long-running Claude Code sessions for hangs and expose process controls.",
|
"description": "Watch long-running Claude Code sessions for hangs and expose process controls.",
|
||||||
"install": "Install"
|
"install": "Install"
|
||||||
},
|
},
|
||||||
|
"prismCloudCLI": {
|
||||||
|
"name": "PRISM CloudCLI",
|
||||||
|
"badge": "unofficial",
|
||||||
|
"description": "Session intelligence for Claude Code, inside CloudCLI. See why your sessions are burning tokens without leaving the browser.",
|
||||||
|
"install": "Install"
|
||||||
|
},
|
||||||
"morePlugins": "More",
|
"morePlugins": "More",
|
||||||
"enable": "Enable",
|
"enable": "Enable",
|
||||||
"disable": "Disable",
|
"disable": "Disable",
|
||||||
|
|||||||
Reference in New Issue
Block a user