(
session: IsolatedTmuxSession,
opts?: { timeoutMs?: number },
)
| 253 | } |
| 254 | |
| 255 | export async function attachTmuxClient( |
| 256 | session: IsolatedTmuxSession, |
| 257 | opts?: { timeoutMs?: number }, |
| 258 | ): Promise<TmuxAttachedClient> { |
| 259 | const attachCommand = |
| 260 | `tmux -L ${shellQuote(session.socketName)} ` + |
| 261 | `attach-session -t ${shellQuote(session.sessionName)}` |
| 262 | const env = getTmuxTestEnv() |
| 263 | if (!env.TERM || env.TERM === 'dumb') { |
| 264 | env.TERM = 'xterm-256color' |
| 265 | } |
| 266 | const process = spawn( |
| 267 | 'script', |
| 268 | ['-q', '-e', '-f', '-c', attachCommand, '/dev/null'], |
| 269 | { |
| 270 | env, |
| 271 | stdio: 'pipe', |
| 272 | }, |
| 273 | ) |
| 274 | |
| 275 | if (!process.stdin || !process.stdout || !process.stderr) { |
| 276 | throw new Error('Failed to spawn attached tmux client') |
| 277 | } |
| 278 | |
| 279 | let attachOutput = '' |
| 280 | process.stdout.setEncoding('utf8') |
| 281 | process.stderr.setEncoding('utf8') |
| 282 | process.stdout.on('data', chunk => { |
| 283 | attachOutput += chunk |
| 284 | }) |
| 285 | process.stderr.on('data', chunk => { |
| 286 | attachOutput += chunk |
| 287 | }) |
| 288 | |
| 289 | const timeoutMs = opts?.timeoutMs ?? 2000 |
| 290 | const deadline = Date.now() + timeoutMs |
| 291 | while (Date.now() < deadline) { |
| 292 | if (process.exitCode !== null) { |
| 293 | const details = |
| 294 | attachOutput.trim().length > 0 |
| 295 | ? `: ${attachOutput.trim().replaceAll('\n', ' | ')}` |
| 296 | : '' |
| 297 | throw new Error( |
| 298 | `Attached tmux client exited early (${process.exitCode})${details}`, |
| 299 | ) |
| 300 | } |
| 301 | if (countAttachedClients(session) > 0) { |
| 302 | return { process } |
| 303 | } |
| 304 | await delay(20) |
| 305 | } |
| 306 | |
| 307 | process.kill('SIGTERM') |
| 308 | throw new Error( |
| 309 | `Timed out waiting for tmux client attach on socket ${session.socketName}. ` + |
| 310 | `attach output=${JSON.stringify(attachOutput.trim())}`, |
| 311 | ) |
| 312 | } |
no test coverage detected