Skip to content

Commit e334008

Browse files
grimmerkclaude
andcommitted
fix: detect CodeV embedded terminal sessions correctly
Sessions in Terminal tab were misdetected as Ghostty (parent process tree: claude → node-pty → Electron → Ghostty). Now detects Electron/CodeV as parent and switches to Term tab. Fixes #96 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent f750fcc commit e334008

2 files changed

Lines changed: 34 additions & 1 deletion

File tree

src/claude-session-utility.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,8 @@ export const detectTerminalApp = async (pid: number): Promise<string> => {
185185
if (!comm) break;
186186

187187
const commLower = comm.toLowerCase();
188+
// CodeV's embedded terminal (node-pty runs under Electron)
189+
if (commLower.includes('electron') || commLower.includes('codev')) return 'codev';
188190
if (commLower.includes('iterm') || commLower.includes('iterm2')) return 'iterm2';
189191
if (commLower.includes('cmux')) return 'cmux';
190192
if (commLower.includes('ghostty')) return 'ghostty';
@@ -578,7 +580,7 @@ end tell`);
578580

579581
// Ghostty + unknown terminals: cwd fallback (no async work, runs after cross-ref)
580582
for (const [terminal, items] of Object.entries(byTerminal)) {
581-
if (terminal === 'iterm2' || terminal === 'cmux' || terminal === 'terminal') continue;
583+
if (terminal === 'iterm2' || terminal === 'cmux' || terminal === 'terminal' || terminal === 'codev') continue;
582584
for (const item of items) {
583585
const fallback = item.candidates.find(s => !activeMap.has(s.sessionId));
584586
if (fallback) {
@@ -747,6 +749,10 @@ export const openSession = async (
747749
}
748750

749751
switch (effectiveTerminal) {
752+
case 'codev':
753+
// Session is in CodeV's embedded terminal — notify renderer to switch to Term tab
754+
openSessionInCodeV(sessionId);
755+
break;
750756
case 'cmux':
751757
openSessionInCmux(sessionId, projectPath, isActive, activePid, customTitle);
752758
break;
@@ -768,6 +774,26 @@ export const openSession = async (
768774
* If the session is already active, switch to its tab
769775
* Otherwise, open a new tab and run claude --resume
770776
*/
777+
/**
778+
* Callback for opening sessions in CodeV's embedded terminal.
779+
* Set by main.ts to avoid circular dependency.
780+
*/
781+
let codevTerminalCallback: ((sessionId: string) => void) | null = null;
782+
783+
export const setCodevTerminalCallback = (cb: (sessionId: string) => void) => {
784+
codevTerminalCallback = cb;
785+
};
786+
787+
/**
788+
* "Open" a session that's running in CodeV's embedded terminal.
789+
* Switches to the Terminal tab instead of opening an external terminal.
790+
*/
791+
export const openSessionInCodeV = (sessionId: string): void => {
792+
if (codevTerminalCallback) {
793+
codevTerminalCallback(sessionId);
794+
}
795+
};
796+
771797
export const openSessionInITerm2 = (
772798
sessionId: string,
773799
projectPath: string,

src/main.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
invalidateSessionCache,
2626
loadSessionEnrichment,
2727
loadLastAssistantResponses,
28+
setCodevTerminalCallback,
2829
} from './claude-session-utility';
2930
import {
3031
installHooks,
@@ -1059,6 +1060,12 @@ const trayToggleEvtHandler = async () => {
10591060
console.log('when ready');
10601061
}
10611062

1063+
// Set callback for CodeV embedded terminal sessions
1064+
setCodevTerminalCallback((_sessionId: string) => {
1065+
switcherWindow?.webContents.send('switch-to-terminal');
1066+
showSwitcherWindow();
1067+
});
1068+
10621069
// Pre-initialize aiAssistantWindow for faster first open
10631070
// This is done after mainWindow is created, but before showing it
10641071
// so that initial startup isn't slowed down

0 commit comments

Comments
 (0)