feat: add Linux, WSL, and tmux terminal backends#796
Conversation
Refactor terminal launching into pluggable backends using a strategy pattern, enabling cross-platform support. The public API (openTerminalWindow, openMultipleTerminalWindows) is unchanged — backends are selected automatically based on the detected platform. Backends: - darwin: Refactored existing macOS code (Terminal.app + iTerm2) - linux: GUI terminals (gnome-terminal, konsole, xterm) - wsl: Windows Terminal via wt.exe - tmux: Headless fallback for SSH, Docker, Code Server, CI On Linux, the factory tries GUI terminals first, then falls back to tmux automatically when no GUI is available. This unblocks `il start` on headless Linux environments where the previous "not yet supported" error made iloom unusable. Fixes gnome-terminal multi-tab by using sequential openSingle calls (gnome-terminal --tab adds to the focused window) instead of a single invocation where `--` terminates all option parsing. Based on the architecture from iloom-ai#649 by @rexsilex. Resolves iloom-ai#795. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Skip GUI terminal detection on Linux when no display server (X11/Wayland) is available — prevents crashes like konsole SIGABRT in headless environments (SSH, Docker, Code Server). Add `; exec bash` keep-alive to tmux backend so sessions persist after the command exits, matching the Linux GUI backend pattern. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Follow-up commit:
|
Code ReviewThanks for this PR — the architecture is solid. The Strategy Pattern is well-applied, the GUI → tmux fallback chain is thoughtful, and refactoring Issues Found1. [Medium] Duplicated
|
|
Heads up: 5 pre-existing test failures in // ticktockbent |
Address code review feedback (PR iloom-ai#796): 1. darwin.ts buildTerminalAppScript now delegates to the shared buildCommandSequence instead of reimplementing the same logic. Removes unused escapeSingleQuotes and buildEnvSourceCommands imports. 2. terminal.ts detectITerm2 now delegates to darwin.ts's canonical implementation instead of duplicating the existsSync check. 3. terminal.ts detectPlatform now delegates to detectTerminalEnvironment from platform-detect.ts, eliminating the duplicate platform detection logic. Maps 'wsl' → 'linux' to preserve the Platform return type. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Thanks! I'll take a look and get this merged! So very grateful. Falling tests are fixed on main - was due to improper platform isolation in the tests - hence "it worked on my machine" 🙂 |
acreeger
left a comment
There was a problem hiding this comment.
Code Review Summary
The architecture is solid — the Strategy Pattern, backend abstraction, and GUI → tmux fallback chain are well-designed. Found 2 critical bugs and 2 medium issues to address.
Critical
- Tmux
openSingle()session naming — sessions created byopenSingleare invisible tofindIloomSession()because they lack theiloom-prefix - WSL backend missing shell keep-alive — unlike Linux and tmux backends, WSL doesn't append
; exec bash, so the terminal tab closes when the command exits
Medium
- Broad catch blocks — several catch blocks swallow all errors without checking error type, violating the project's error handling guidelines
- Linux terminal detected N+1 times —
openMultipledetects the terminal once, then eachopenSinglecall detects it again
|
Great review and callouts, let me look into those. |
|
I actually have a commit ready to go, just never got to push it.
…On Sat, Feb 28, 2026 at 19:58 Wes ***@***.***> wrote:
*TickTockBent* left a comment (iloom-ai/iloom-cli#796)
<#796 (comment)>
Great review and callouts, let me look into those.
—
Reply to this email directly, view it on GitHub
<#796 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABJNJM4LWQASETUVVT7MSL4OI2T3AVCNFSM6AAAAACWAXZGGWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTSNZYG42TMNZYHE>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
…blocks, N+1 detection 1. [Critical] Tmux openSingle() sessions now use iloom- prefix so findIloomSession() can discover them, matching openMultiple() behavior. 2. [Critical] WSL backend appends '; exec bash' keep-alive to prevent terminal tabs from closing when the command exits. 3. [Medium] Narrowed bare catch blocks in isTmuxAvailable, sessionExists, findIloomSession, and detectLinuxTerminal to check for exitCode before swallowing — unexpected errors now propagate instead of being silently ignored. Test mocks updated to include exitCode matching real execa behavior. 4. [Medium] LinuxBackend.openMultiple() now calls execTerminal() directly with the pre-detected terminal instead of delegating to openSingle(), eliminating redundant detectLinuxTerminal() calls per window. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Follow-up commit:
|
Oh, well. I didn't see your response. You can use your own fix if you prefer! |
…e README platform support - platform-detect: check for ENOENT specifically instead of bare catch - linux backend: extract resolveTerminal() and openSingleWithTerminal() to eliminate duplicated detection/command-building between openSingle/openMultiple - README: update OS support line to reflect Linux/WSL/tmux support, credit @TickTockBent and @rexsilex in Acknowledgments
- New docs/windows-wsl-guide.md with full WSL setup, VS Code integration, Windows Terminal usage, and troubleshooting - Link from README system requirements to the WSL guide
acreeger
left a comment
There was a problem hiding this comment.
All review feedback has been addressed. LGTM.
|
Thanks so much to @TickTockBent for this PR and @rexsilex for the original design in #649 — this is a huge milestone for iloom. Linux, WSL, and headless tmux support opens up iloom to a much wider audience. Both of you are credited in the README Acknowledgments section. Really appreciate the community contributions here! |
|
Happy to help. Now I can actually test iloom on my dev box! |
Summary
Refactors terminal launching into pluggable backends, enabling
il starton Linux, WSL, and headless environments. The public API (openTerminalWindow,openMultipleTerminalWindows) is unchanged — backends are selected automatically.Backends
DarwinBackendLinuxBackendTmuxBackendWSLBackendOn Linux, the factory tries GUI terminals first, then falls back to tmux automatically when no GUI terminal is available. This is the critical missing piece — headless Linux (SSH sessions, Docker containers, Code Server) is arguably the most common Linux use case for a CLI tool, and it was completely blocked.
Changes
src/utils/terminal-backends/— strategy pattern withTerminalBackendinterface, factory, and 4 backendssrc/utils/platform-detect.ts— WSL detection (env var + /proc/version fallback), terminal environment detectionsrc/utils/terminal.ts— simplified to a thin facade delegating to backendssrc/utils/terminal.test.ts— updated 2 tests that expected Linux to throwBugs fixed
--flag terminates ALL option parsing in gnome-terminal, so passing--tab -- cmd1 --tab -- cmd2in a single invocation causes the second--tabto be passed to bash. Fixed by using sequentialopenSinglecalls —gnome-terminal --tabnaturally adds to the focused window.Background
This builds on the architecture from #649 by @rexsilex (same strategy pattern, same backend interface). That PR has merge conflicts with current main and is missing the tmux backend for headless environments. This PR applies the same design cleanly against current main and adds the tmux fallback.
Resolves #795 (
il startfails on Linux).Related: #649 (original Linux/WSL terminal support PR), #256 (cross-platform tracking issue).
Test plan
pnpm run build)pnpm run lint)tsc --noEmit)il start <issue>on headless Linux with tmux installedil start <issue> --epicswarm mode on Linux with tmuxil start <issue>on Linux with gnome-terminal🤖 Generated with Claude Code