fix: subagent windows not opening — two cascading bugs

1. handleInit crash: commit cdc822d removed Map initializations for
   teammateTerminals, teammatePanesByName, teams, teamTasks, teammateMap
   from the constructor but left cleanup code that iterates them.
   cleanupAllFloatingWindows() crashed on "not iterable", preventing
   ALL frontend data (sessions, subagents) from loading.

2. claudeSessionId null on recovered sessions: only set inside
   startInteractive(), never in constructor or persisted. After server
   restart, recovered sessions had null claudeSessionId, so the
   hasMatchingTab check always failed → no subagent windows.

Fixes:
- Re-add all 5 missing Map initializations in app.js constructor
- Set _claudeSessionId = this.id in Session constructor (Claudeman
  always passes --session-id to Claude, so they always match)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
arkon
2026-02-13 05:07:51 +01:00
co-authored by Claude Opus 4.6
parent 82a0da035c
commit 7d2519cacb
14 changed files with 168 additions and 83 deletions
+9 -9
View File
@@ -859,7 +859,7 @@ export class TmuxManager extends EventEmitter implements TerminalMultiplexer {
* - `Enter` key is sent as a separate argument (not a shell escape)
* - Single command, no delay, no retry loop needed
*/
sendInput(sessionId: string, input: string): boolean {
async sendInput(sessionId: string, input: string): Promise<boolean> {
const session = this.sessions.get(sessionId);
if (!session) {
console.error(`[TmuxManager] sendInput failed: no session found for ${sessionId}. Known: ${Array.from(this.sessions.keys()).join(', ')}`);
@@ -886,25 +886,25 @@ export class TmuxManager extends EventEmitter implements TerminalMultiplexer {
// Send text + Enter in a single command
// -l flag = literal text (no special key interpretation)
// 'Enter' after -l text = Enter key
execSync(
await execAsync(
`tmux send-keys -t "${session.muxName}" -l ${shellescape(textPart)}`,
{ encoding: 'utf-8', timeout: EXEC_TIMEOUT_MS }
{ timeout: EXEC_TIMEOUT_MS }
);
execSync(
await execAsync(
`tmux send-keys -t "${session.muxName}" Enter`,
{ encoding: 'utf-8', timeout: EXEC_TIMEOUT_MS }
{ timeout: EXEC_TIMEOUT_MS }
);
} else if (textPart) {
// Text only, no Enter
execSync(
await execAsync(
`tmux send-keys -t "${session.muxName}" -l ${shellescape(textPart)}`,
{ encoding: 'utf-8', timeout: EXEC_TIMEOUT_MS }
{ timeout: EXEC_TIMEOUT_MS }
);
} else if (hasCarriageReturn) {
// Enter only
execSync(
await execAsync(
`tmux send-keys -t "${session.muxName}" Enter`,
{ encoding: 'utf-8', timeout: EXEC_TIMEOUT_MS }
{ timeout: EXEC_TIMEOUT_MS }
);
}