Every Claude Code session you finish in a terminal shows up in Paseo by itself, so you can pick it up from your phone.
Paseo can import an existing Claude Code session, but only when you go looking for it
in the app. This is a SessionEnd hook that does it for you: you close a session, and
two seconds later it is an agent in the right workspace, under the name Claude Code
gave it.
Nothing runs in the background. No daemon, no watcher, no dependencies — one Node script that Claude Code invokes when a session ends.
- Imports on session end. New sessions only; a session already in Paseo is left alone.
- Keeps following. An imported agent tracks its transcript file, so a session you continue later stays current in Paseo without a second import.
- Uses Claude Code's session name. Paseo names an imported agent after the first
line of the session, which is a slash command often enough (
/clear,/model opus). Claude Code's own generated name is used instead. - One workspace per directory. The
paseo importCLI cannot target a workspace, so it mints a new one on every import. This talks to the daemon directly and puts the session in the workspace that directory already has. - Skips what is not worth an agent. Empty sessions, sessions you opened and
immediately
/resumed out of, and sessions Paseo itself started.
- Paseo desktop app or
@getpaseo/cli, with the daemon running - Claude Code
- Node 22 or newer (the hook uses the built-in
WebSocket), onPATH
Works on Windows, macOS and Linux.
The plugin calls node, so it has to be on PATH — the manual install does not, it
records the absolute path of whichever Node ran the installer.
In Claude Code:
/plugin marketplace add Podden/paseo-session-sync
/plugin install paseo-session-sync@paseo-session-sync
That is the whole install. Your settings.json is not touched, updates come through
the marketplace, and /plugin uninstall removes it cleanly.
Without the plugin system
If you would rather have the hook as a plain file — on a headless host, or in a Claude Code config you manage by hand:
git clone https://github.com/Podden/paseo-session-sync
cd paseo-session-sync
node install.mjsThat copies the hook to ~/.claude/hooks/ and registers it under SessionEnd in
~/.claude/settings.json, backing the file up first. Re-running it updates the
existing install instead of adding a second one.
node install.mjs --dry-run # show what it would do
node install.mjs --config-dir /path/to/.claude
node uninstall.mjs # remove it again--config-dir also comes from CLAUDE_CONFIG_DIR, which matters if you run several
Claude Code configurations on one machine.
Do not run both installs at once. The plugin and the manual hook would each fire on
session end; the second one only logs known, but it is pointless work.
End a Claude Code session — one where you actually typed something — and look at the log:
$ tail -3 ~/.paseo/import.log
2026-08-20 22:57:16 +0200 imported b6c6f281-f249-4ec2-90c7-4dc7ecdf6d5a ws=(new)
2026-08-20 22:57:18 +0200 named 2f51822f -> "Testlauf für paseo"
2026-08-20 22:57:19 +0200 known d15a7791-acc4-4afb-8e03-374c13cbd373
imported is a new agent, known means the session was already there, skip: lines
say why a session was passed over. Every line is local time.
Two slash commands wrap them when the plugin is installed — both walk you through a dry run before anything is written:
/paseo-session-sync:import-backlog 7
/paseo-session-sync:tidy-workspaces
Or run them directly. Each one is a dry run unless you pass --apply.
node tools/import-backlog.mjs --days 7 # sessions from before you installed the hook
node tools/backfill-agent-names.mjs # rename existing agents to their session name
node tools/consolidate-workspaces.mjs # merge duplicate workspaces on one directoryconsolidate-workspaces is the one to run once if you imported sessions through the
CLI before: it collapses the pile of same-named workspaces down to one per directory
and gives it back its branch name. Agents keep their ids and timelines.
| Variable | Default |
|---|---|
PASEO_HOME |
~/.paseo |
PASEO_BIN |
the desktop app's bundled CLI, else paseo from PATH |
PASEO_PASSWORD |
unset — set it if the daemon has auth.password configured |
CLAUDE_CONFIG_DIR |
~/.claude |
The daemon address is read from $PASEO_HOME/config.json.
A daemon that listens on anything but loopback usually has daemon.auth.password set
in config.json. Every WebSocket upgrade then has to carry the secret as a
paseo.bearer.<password> subprotocol, so export PASEO_PASSWORD for the hook and the
tools. Without it the socket import fails and you get one extra workspace per session,
because the CLI fallback cannot pass a workspaceId.
On Windows, setx can hang for minutes — it broadcasts WM_SETTINGCHANGE and waits
for every top-level window to answer, so one unresponsive tray app blocks it. Write the
value straight to the registry instead:
reg add HKCU\Environment /v PASEO_PASSWORD /d yourpassword /f
- Claude Code only. Codex, OpenCode and the other providers Paseo supports would each need their own transcript reader.
- A password-protected daemon needs
PASEO_PASSWORD. Without it the socket path falls back to the CLI, which still imports — you just get one extra workspace per session. See A daemon with a password. - Remote daemons are not supported. The hook imports into the daemon on the machine where the session ran.
Nothing here starts the daemon — it only talks to one that is already up, and an import fails outright if none is.
Installing Paseo does not register a service or an autostart entry. The desktop app
spawns the daemon as a subprocess and stops it again on quit, so closing the window
takes the daemon with it. Settings → Host → "Keep daemon running after quit" opts out
of the shutdown, but nothing brings the daemon back after a reboot. A daemon you
started yourself with paseo daemon start is left alone by the app either way
(paseo.pid records desktopManaged).
For a machine you want to reach from your phone while nobody is at the keyboard, run the daemon from the OS instead:
- Linux: a systemd user unit with
Restart=always, plusloginctl enable-lingerso it survives logout. - macOS: a
launchdLaunchAgent withKeepAlive. - Windows: a scheduled task, triggered at logon and repeating every 15 minutes.
The repeat is the watchdog —
paseo daemon startis a no-op while the pid inpaseo.pidis alive, and starts a new daemon after a crash.
Do not run the Windows task as "whether user is logged on or not". That puts the daemon in session 0, with no desktop, no mapped network drives and no user profile — agents that drive a GUI application (a Unity editor, a browser) then fail in ways that are tedious to diagnose. Keep it in the interactive session; a locked screen is fine, a logged-out one is not.
Call the bundled CLI directly rather than resources\bin\paseo.cmd, which sets
PASEO_DESKTOP_MANAGED=1 and hands your daemon back to the app to kill on quit.
MIT