linuxcliclaude codevpsguide

Track your Claude Code time on a VPS — the Temporal.ist Linux CLI

Running Claude Code on a headless VPS? The desktop app can't help you there. Here's how to install the Temporal.ist Linux CLI, sign in over SSH, and use the TUI to auto-track every billable hour Claude works.

The Temporal.ist terminal dashboard on a VPS

The setup, in one sentence

You SSH into a VPS, you run Claude Code there to build something, and you want the hours it works to show up as billable time without you babysitting a stopwatch. The Temporal.ist Linux CLI does exactly that: a terminal-native client and TUI that watches the directories Claude edits and turns the activity into sessions on your dashboard — all over SSH, no GUI required.

This guide walks through the whole thing: install, sign in, configure, and leave it running.

Why not the desktop app?

The macOS/Windows/Linux desktop client is great on a machine with a screen — it lives in your tray and watches local folders. A VPS has no tray, no display server, and you reach it through a terminal. So the desktop build is the wrong tool here. The CLI is built for precisely this case: headless boxes, remote dev, and "I do all my real work inside ssh" workflows.

1. Install — one line

SSH into your VPS and run:

curl -fsSL https://temporal.ist/install.sh | sh

That downloads a single self-contained temporal binary and drops it in ~/.local/bin. Re-run the same command any time to upgrade.

If the installer warns that ~/.local/bin isn't on your PATH, add it to your shell profile and re-open the shell:

echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc

Confirm it's there:

temporal --version

2. Sign in over SSH with the device flow

There's no browser on the VPS, so temporal login uses the OAuth device flow — the same pattern gh auth login and aws sso login use. Run:

temporal login

The temporal login command showing a verification URL, a one-time code, and a QR code to scan

Open the URL on your laptop or phone, type (or scan) the code, and approve. The CLI stores the token under ~/.config/temporal/ and refreshes it automatically — you log in once per machine.

3. Open the TUI dashboard

Just run the bare command:

temporal

The Temporal.ist terminal dashboard showing a live recording session, today and this-week totals, a projects table with sparklines, and a recent-activity feed

The dashboard is the home base. At a glance:

  • Recording strip — the live session, which project it's on, how long it's run, and how it was started (via watcher).
  • Totals — today and this week, with a trend against last week.
  • Projects — per-project today/week time and a 7-day sparkline.
  • Recent activity — the actual file events being captured, in plain paths. Nothing is hidden or AI-reshaped; you can read exactly what was tracked.

The footer shows the keybindings: w jumps to the watcher, p pauses, s forces a sync, q quits.

4. Point it at the repos Claude Code touches

This is the step that makes everything work. Press the projects key to open the watch-path editor and map each project to a directory:

The TUI project editor showing watch paths, include and exclude globs, and an idle timeout for three projects

For each project you set:

Field What it does
path The directory to watch, e.g. ~/srv/acme-api
include Globs that count as activity — **/*.py, **/*.svelte, …
exclude Noise to ignore — .venv/, node_modules/, __pycache__/
idle How long with no edits before the session auto-closes (default 15 min)

The key insight for Claude Code users: point a watch path at the repo Claude is working in. When Claude edits, creates, or refactors files, those are ordinary filesystem writes — the watcher sees every one of them and rolls them into a session for that project. You don't tell Temporal.ist "Claude is working now"; it just notices the files changing.

Exclude generously. Claude often runs tests, installs dependencies, or builds — you don't want node_modules/ churn or .venv/ writes inflating your hours. The exclude globs keep tracking to the work that's actually billable.

5. Keep it running as a service

temporal watch runs the file watcher in the foreground — handy to see live events:

The temporal watch command streaming live file events, a session start, a sync, and an idle auto-close

But on a VPS you want it running even after you close the SSH session. The TUI can install a service for you, or set up a systemd user service by hand. Create ~/.config/systemd/user/temporal.service:

[Unit]
Description=Temporal.ist file watcher
After=network-online.target

[Service]
ExecStart=%h/.local/bin/temporal watch
Restart=on-failure
RestartSec=5

[Install]
WantedBy=default.target

Enable and start it:

systemctl --user daemon-reload
systemctl --user enable --now temporal

By default a user service stops when you log out. To keep it tracking across SSH disconnects and reboots, enable lingering for your account (run once, as a sudoer):

sudo loginctl enable-linger "$USER"

Now the watcher comes up on boot and keeps capturing whether or not you're connected. Check on it any time with systemctl --user status temporal or by opening the TUI.

How a Claude Code session maps to tracked time

Put together, a normal afternoon looks like this:

  1. You SSH in, start tmux (or screen), and launch claude in ~/srv/acme-api.
  2. Claude starts editing files. The watcher sees the first write and opens a session on acme-api, tagged via watcher.
  3. For the next two hours Claude edits, you review and steer, tests run. Every in-scope file write keeps the session alive; excluded paths are ignored.
  4. You wander off for lunch. After 15 minutes with no edits, the session auto-closes — your break isn't billed.
  5. Activity syncs to the backend, so the hours show up on the web dashboard and are ready to drop onto an invoice.

If you want to carve the day into separate sessions deliberately, p pauses and resumes from the TUI. And because capture is just file paths and timestamps — no screenshots, no keystroke logging — you can always audit exactly what was counted.

Verify it landed

Open your dashboard (or the /calendar view) from any browser. The session you just recorded on the VPS will be there under the right project, with the same totals the TUI showed. From there it's two clicks to an invoice line item.

That's the whole loop

Install the binary, log in once, map your repos to watch paths, and run the watcher as a service. After that, every hour Claude Code spends in those repos tracks itself — and you get your Friday afternoons back.

Frequently asked questions

How do I sign in when there's no browser on the server?

`temporal login` uses the OAuth device flow. It prints a URL and a one-time code (plus a QR code); you approve from your laptop or phone. The token is stored on the VPS and refreshed automatically.

Does Claude Code editing files actually get tracked?

Yes. The watcher tracks filesystem events, and Claude Code's edits are ordinary file writes. Point a watch path at the repo Claude works in and its activity becomes a session automatically — no manual start/stop.

Will tracking keep running after I disconnect from SSH?

Run the watcher as a systemd user service and enable lingering with `loginctl enable-linger`. It then starts on boot and keeps tracking whether or not you're connected.

Can I run the CLI and the desktop app on different machines?

Yes. They sync to the same account. Run the CLI on your VPS and the desktop app on your laptop; sessions from both show up on the same dashboard, each tagged with where it came from.

How do I stop time being tracked during builds or test runs?

Use exclude globs on the project's watch path — for example `node_modules/`, `.venv/`, `__pycache__/`, and build output. Only writes to included paths count toward your hours.