* Best-effort kill of all pane-backed teammate panes for a team. * Called from cleanupSessionTeams on ungraceful leader exit (SIGINT/SIGTERM). * Dynamic imports avoid adding registry/detection to this module's static * dep graph — this only runs at shutdown, so the import cost is irrelevant.
(teamName: string)
| 596 | * dep graph — this only runs at shutdown, so the import cost is irrelevant. |
| 597 | */ |
| 598 | async function killOrphanedTeammatePanes(teamName: string): Promise<void> { |
| 599 | const teamFile = readTeamFile(teamName) |
| 600 | if (!teamFile) return |
| 601 | |
| 602 | const paneMembers = teamFile.members.filter( |
| 603 | m => |
| 604 | m.name !== TEAM_LEAD_NAME && |
| 605 | m.tmuxPaneId && |
| 606 | m.backendType && |
| 607 | isPaneBackend(m.backendType), |
| 608 | ) |
| 609 | if (paneMembers.length === 0) return |
| 610 | |
| 611 | const [{ ensureBackendsRegistered, getBackendByType }, { isInsideTmux }] = |
| 612 | await Promise.all([ |
| 613 | import('./backends/registry.js'), |
| 614 | import('./backends/detection.js'), |
| 615 | ]) |
| 616 | await ensureBackendsRegistered() |
| 617 | const useExternalSession = !(await isInsideTmux()) |
| 618 | |
| 619 | await Promise.allSettled( |
| 620 | paneMembers.map(async m => { |
| 621 | // filter above guarantees these; narrow for the type system |
| 622 | if (!m.tmuxPaneId || !m.backendType || !isPaneBackend(m.backendType)) { |
| 623 | return |
| 624 | } |
| 625 | const ok = await getBackendByType(m.backendType).killPane( |
| 626 | m.tmuxPaneId, |
| 627 | useExternalSession, |
| 628 | ) |
| 629 | logForDebugging( |
| 630 | `cleanupSessionTeams: killPane ${m.name} (${m.backendType} ${m.tmuxPaneId}) → ${ok}`, |
| 631 | ) |
| 632 | }), |
| 633 | ) |
| 634 | } |
| 635 | |
| 636 | /** |
| 637 | * Cleans up team and task directories for a given team name. |
no test coverage detected