🚀 Persistent AI coding terminals for VS Code, Cursor, and VS Code-compatible forks.
Keep Claude Code, Codex, Gemini-style agent terminals, and long-running shell work alive across Remote-SSH disconnects, editor reloads, and server restarts.
VScodeconfig turns your Remote-SSH terminal into a stable workspace:
- one named terminal tab
- one
tmuxsession - one Claude Code, Codex, or shell workflow
- automatic reattach after editor reloads, SSH disconnects, and server restarts
It works best with VS Code and Cursor. It should also work with forks that support VS Code-style tasks.json, workspace settings, integrated terminals, and OSC terminal titles.
Using this with Claude, Gemini, Codex, or another AI assistant? See
LLM.md for the agent-focused guide.
Keywords: VS Code Remote SSH, Cursor IDE, tmux sessions, persistent terminal
tabs, Claude Code, Codex CLI, Gemini CLI, AI coding agents, tasks.json,
tmux-resurrect, tmux-continuum.
AI coding sessions are valuable context. Losing the terminal tab usually means losing the visible conversation, even when logs still exist somewhere on disk.
This repo fixes the annoying parts:
- 🧠 Claude/Codex conversations stay attached to named work sessions
- 🏷️ Terminal tabs are named after the project/session
- 🔁 Reload VS Code/Cursor and your tabs come back
- 🔌 Disconnect SSH and reconnect without losing your workspace
- 🧯 Kill/remove a session and it stays removed
- 🚫 Stale editor terminals cannot recreate deleted tmux sessions
- 🛠️ Everything is plain shell, tmux, tasks.json, and workspace settings
Five commands:
tn myproject # new tmux session running Claude Code
tnx myproject # new tmux session running Codex
ta myproject # attach/switch to an existing session
tk myproject # kill a session and sync editor restore state
tclean # show old stuck editor task shells, dry-run by defaultWhen your editor opens over Remote SSH, VScodeconfig generates tasks that reattach every live tmux session as its own terminal tab.
Run this on the remote server, not on your Mac/laptop:
git clone https://github.com/naif824/VScodeconfig.git
cd VScodeconfig
bash install.shThen reload your VS Code/Cursor window:
Cmd/Ctrl + Shift + P → Developer: Reload Window
If prompted, click Trust for the remote workspace.
Create your first persistent session:
tn demoClose the editor window, reconnect, and the demo terminal tab should come back.
- Linux remote server with
/proc tmux3.0+python3crongit- Claude Code CLI on
PATHfortn - Codex CLI on
PATHfortnx
The tmux/session lifecycle is designed for Linux Remote-SSH hosts.
tn / tnx / ta / tk
│
▼
named tmux sessions
│
▼
scripts/sync-state.sh
│
├─ scripts/gen-tasks.sh → ~/.vscode/tasks.json
└─ tmux-resurrect save → reboot-safe snapshot
│
▼
VS Code / Cursor runs "Open Primary Sessions" on folder open
│
▼
each tmux session reattaches as its own terminal tab
Main pieces:
bin/tncreates a new tmux session and startsclaude --dangerously-skip-permissions.bin/tnxcreates a new tmux session and startscodex --yolo.bin/taattaches to a session, or switches clients if already inside tmux.bin/tkkills a session and syncs editor tasks + tmux-resurrect state.bin/tcleanfinds or kills old pre-v1.2.1 Cursor/VS Code task shells that still containtmux attach ... || tmux new-session ....scripts/gen-tasks.shwrites~/.vscode/tasks.jsonfrom the current tmux session list.- Generated editor tasks are attach-only. They do not run
tmux new-session, so old Cursor/VS Code persistent terminal records cannot recreate a session after you intentionally exited or killed it. scripts/sync-state.shis the single sync entrypoint used by commands, hooks, and cron.tmux.conf.snippetwires tmux hooks, terminal titles, tmux-resurrect, and tmux-continuum.
VScodeconfig syncs in three ways:
- ⚡ Realtime hooks on
session-createdandsession-closed - 🧭 Command sync from
tn,tnx, andtk - ⏱️ Cron fallback every 5 minutes
gen-tasks.sh writes tasks.json atomically and clears stale tasks when there are no live tmux sessions, so old tabs do not come back after you intentionally remove them.
Auto-open tasks are intentionally attach-only. tn and tnx are the only
commands that create sessions. This prevents Cursor/VS Code from reviving an
old persistent terminal task and recreating a tmux session that you already
closed.
sync-state.sh also saves tmux-resurrect state when available, so killed sessions do not reappear after reboot from an old resurrect snapshot.
VScodeconfig names tabs in two layers:
printf '\033]0;session-name\007'and:
set -g set-titles on
set -g set-titles-string '#S'
set -g allow-rename offThat keeps each editor terminal tab named after its tmux session and prevents apps inside tmux from renaming the wrong tab.
Preferred:
tk myprojectThat kills the tmux session, regenerates editor tasks, and saves resurrect state.
Also valid:
exitIf exit closes the last process/pane in the tmux session, the tmux session-closed hook will sync the editor state. If the tab comes back, check whether the session still exists:
tmux ls
grep myproject ~/.vscode/tasks.jsonIf the name is gone from both, it will not be reopened.
If Cursor/VS Code revives an old terminal process after the session is gone, the task exits instead of recreating the tmux session.
~/.local/bin/
tn
tnx
ta
tk
tclean
~/.vscodeconfig/scripts/
gen-tasks.sh
sync-state.sh
~/.vscode/tasks.json
~/.vscode/settings.json
~/.tmux.conf
The installer appends a managed block to ~/.tmux.conf and installs one cron entry.
cd VScodeconfig
git pull
bash install.shReload your VS Code/Cursor window afterward.
If old terminal tabs still do not rename, restart tmux once:
tmux kill-serverThen recreate sessions with tn, tnx, or attach with ta.
List live sessions:
tmux lsRegenerate editor tasks manually:
bash ~/.vscodeconfig/scripts/sync-state.shInspect generated tasks:
python3 -m json.tool ~/.vscode/tasks.jsonCheck whether a removed session is still scheduled to reopen:
grep SESSION_NAME ~/.vscode/tasks.jsonFind old editor persistent task shells that still carry the obsolete create fallback:
tcleanIf it reports stale pre-v1.2.1 shells, you can remove only those wrappers with:
tclean --killThis does not kill normal tmux sessions or current attach-only tasks.
Install tmux plugins from inside tmux:
prefix + I
Default tmux prefix is Ctrl+b.
rm -f ~/.local/bin/{tn,tnx,ta,tk,tclean}
rm -rf ~/.vscodeconfig
rm -f ~/.vscode/tasks.json
crontab -l | grep -v -E 'sync-state\.sh|gen-tasks\.sh|claude-session-map\.sh' | crontab -Then remove the managed VScodeconfig block from ~/.tmux.conf.
- No sudo required.
- No secrets are stored by this repo.
- Generated files live in your home directory.
- Workspace VS Code settings are written on the remote server, not your Mac user settings.
- Claude/Codex launch commands are intentionally visible in generated
tasks.json.
For AI assistants modifying this repo, read LLM.md before changing
the sync or session lifecycle.
MIT