Files
myagents/desktop/electron/pty.ts
T
Zhengshou Lai 2ac1c9750e refactor(desktop): code review fixes
- Shortcut: Cmd+Shift+C → Cmd+Shift+M (avoid Chrome DevTools conflict)
- Preload: onData/onExit now return cleanup functions (fix memory leak)
- PTY: resolve shell path at construction time, throw on missing claude CLI
- Terminal: remove allowProposedApi, dedupe resize listeners, add cleanup
- Main: debounce window move config writes (500ms), restart PTY on activate
- CSS: remove unused orbGlow keyframes
- Package: fix appId to com.apaam.myclaude, skip code signing, remove unused deps
2026-05-27 11:23:14 +08:00

66 lines
1.4 KiB
TypeScript

import * as pty from 'node-pty'
import { EventEmitter } from 'events'
export class PTYManager extends EventEmitter {
private ptyProcess: pty.IPty | null = null
private resolvedShell: string
constructor() {
super()
this.resolvedShell = this.resolveShell('claude')
}
start(_shell: string = 'claude', args: string[] = []) {
this.ptyProcess = pty.spawn(this.resolvedShell, args, {
name: 'xterm-color',
cols: 80,
rows: 24,
cwd: process.env.HOME,
env: process.env as { [key: string]: string },
})
this.ptyProcess.onData((data: string) => {
this.emit('data', data)
})
this.ptyProcess.onExit(({ exitCode }) => {
this.emit('exit', exitCode)
})
return this.ptyProcess
}
write(data: string) {
if (this.ptyProcess) {
this.ptyProcess.write(data)
}
}
resize(cols: number, rows: number) {
if (this.ptyProcess) {
this.ptyProcess.resize(cols, rows)
}
}
kill() {
if (this.ptyProcess) {
this.ptyProcess.kill()
this.ptyProcess = null
}
}
private resolveShell(shell: string): string {
if (shell === 'claude') {
const { execSync } = require('child_process')
try {
return execSync('which claude', { encoding: 'utf8' }).trim()
} catch {
throw new Error(
'Claude CLI not found. Please install it: https://claude.ai/download'
)
}
}
return shell
}
}