Skip to content

Commit 2d97d31

Browse files
committed
wait for terminal ready after running each setup comand
1 parent 8b18f47 commit 2d97d31

File tree

1 file changed

+57
-37
lines changed

1 file changed

+57
-37
lines changed

main.ts

Lines changed: 57 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,33 @@ function getPersistedSessions(): PersistedSession[] {
2222
return (store as any).get("sessions", []);
2323
}
2424

25+
function isTerminalReady(buffer: string, startPos: number = 0): boolean {
26+
const searchBuffer = buffer.slice(startPos);
27+
const promptSymbols = ["$ ", "% ", "> ", "➜ ", "➜ ", "✗ ", "✓ "];
28+
const endSymbols = ["$", "%", ">", "➜", "✗", "✓"];
29+
30+
// Check for bracketed paste mode
31+
if (searchBuffer.includes("\x1b[?2004h")) {
32+
return true;
33+
}
34+
35+
// Check for prompt symbols
36+
for (const symbol of promptSymbols) {
37+
if (searchBuffer.includes(symbol)) {
38+
return true;
39+
}
40+
}
41+
42+
// Check for end symbols
43+
for (const symbol of endSymbols) {
44+
if (searchBuffer.endsWith(symbol)) {
45+
return true;
46+
}
47+
}
48+
49+
return false;
50+
}
51+
2552
function savePersistedSessions(sessions: PersistedSession[]) {
2653
(store as any).set("sessions", sessions);
2754
}
@@ -220,6 +247,9 @@ function spawnSessionPty(
220247
activePtyProcesses.set(sessionId, ptyProcess);
221248

222249
let terminalReady = false;
250+
let readyChecksCompleted = 0;
251+
let lastReadyCheckPos = 0;
252+
let setupCommandsIdx = 0;
223253
let dataBuffer = "";
224254

225255
ptyProcess.onData((data) => {
@@ -232,44 +262,34 @@ function spawnSessionPty(
232262
if (!terminalReady) {
233263
dataBuffer += data;
234264

235-
// Method 1: Look for bracketed paste mode enable sequence
236-
// Method 2: Fallback - look for common prompt indicators
237-
const isReady = dataBuffer.includes("\x1b[?2004h") ||
238-
dataBuffer.includes("$ ") || dataBuffer.includes("% ") ||
239-
dataBuffer.includes("> ") || dataBuffer.includes("➜ ") ||
240-
dataBuffer.includes("➜ ") || dataBuffer.includes("✗ ") ||
241-
dataBuffer.includes("✓ ") || dataBuffer.endsWith("$") ||
242-
dataBuffer.endsWith("%") || dataBuffer.endsWith(">") ||
243-
dataBuffer.endsWith("➜") || dataBuffer.endsWith("✗") ||
244-
dataBuffer.endsWith("✓");
245-
246-
if (isReady) {
247-
terminalReady = true;
248-
249-
// Run setup commands if provided
250-
if (config.setupCommands && config.setupCommands.length > 0) {
251-
config.setupCommands.forEach(cmd => {
252-
ptyProcess.write(cmd + "\r");
253-
});
254-
}
255-
256-
// Auto-run the selected coding agent
257-
if (config.codingAgent === "claude") {
258-
const sessionFlag = isNewSession
259-
? `--session-id ${sessionUuid}`
260-
: `--resume ${sessionUuid}`;
261-
const skipPermissionsFlag = config.skipPermissions ? "--dangerously-skip-permissions" : "";
262-
const mcpConfigFlag = mcpConfigPath ? `--mcp-config ${mcpConfigPath}` : "";
263-
const flags = [sessionFlag, skipPermissionsFlag, mcpConfigFlag].filter(f => f).join(" ");
264-
const claudeCmd = `claude ${flags}\r`;
265-
ptyProcess.write(claudeCmd);
266-
267-
// Start MCP poller immediately (auth is handled by shell environment)
268-
if (!mcpPollerPtyProcesses.has(sessionId) && projectDir) {
269-
spawnMcpPoller(sessionId, projectDir);
265+
if (isTerminalReady(dataBuffer, lastReadyCheckPos)) {
266+
readyChecksCompleted++;
267+
lastReadyCheckPos = dataBuffer.length;
268+
269+
if (config.setupCommands && setupCommandsIdx < config.setupCommands.length) {
270+
ptyProcess.write(config.setupCommands[setupCommandsIdx] + "\r");
271+
setupCommandsIdx++;
272+
} else {
273+
terminalReady = true;
274+
275+
// Auto-run the selected coding agent
276+
if (config.codingAgent === "claude") {
277+
const sessionFlag = isNewSession
278+
? `--session-id ${sessionUuid}`
279+
: `--resume ${sessionUuid}`;
280+
const skipPermissionsFlag = config.skipPermissions ? "--dangerously-skip-permissions" : "";
281+
const mcpConfigFlag = mcpConfigPath ? `--mcp-config ${mcpConfigPath}` : "";
282+
const flags = [sessionFlag, skipPermissionsFlag, mcpConfigFlag].filter(f => f).join(" ");
283+
const claudeCmd = `claude ${flags}\r`;
284+
ptyProcess.write(claudeCmd);
285+
286+
// Start MCP poller immediately (auth is handled by shell environment)
287+
if (!mcpPollerPtyProcesses.has(sessionId) && projectDir) {
288+
spawnMcpPoller(sessionId, projectDir);
289+
}
290+
} else if (config.codingAgent === "codex") {
291+
ptyProcess.write("codex\r");
270292
}
271-
} else if (config.codingAgent === "codex") {
272-
ptyProcess.write("codex\r");
273293
}
274294
}
275295
}

0 commit comments

Comments
 (0)