One window for every Claude Code session you have running.
Fluxdesk replaces a screen full of terminal windows with a single browser page: every conversation in one list, with its state, what it is doing right now, what it costs, and whether it is waiting for you. Sessions keep running when you close the tab, and a small CLI client lets you drop back into any of them from a shell.
Built because 22 forgotten claude processes were sitting in separate terminals,
eating 5.3 GB, with no way to tell which one needed an answer.
The interface speaks Polish and English; switch it under ⚙ (
Alt+,). Code comments are Polish; commit messages and this document are English.
Sessions. Every session in one list with a real state (working, waiting for a
decision, idle), the current activity, context usage and cost. Switch with digits
1-9, jump by name with S, put two side by side with O. New sessions start
with a name, directory, model and permission mode in one dialog.
Real terminals. Each session is an actual claude process in a pty, rendered
with xterm.js, so every CLI command works. A host process owns the pty, which
means restarting or rebuilding the panel does not interrupt the work.
Watchdog. Answers the resume prompt that silently blocks a session for hours, flags sessions repeating the same activity, and feeds queued tasks to a session as it frees up.
Tasks. Own task store with a workflow that separates "done working" from
"closed": to_do, in_progress, do_poprawy, zlecone, testowanie,
feedback, zrobione. Tags, assignees, subtasks, blockers, recurrence, time in
each status, a board view, and a one-line syntax: fix the importer #project @someone !! za 3d co 7d ~30m. Imports from taskwarrior and exports back.
Knowledge. Search across every transcript on the machine, edit CLAUDE.md
and per-project memory, keep a version history of memory edits, and export a
bounded summary of a user profile into the global instructions so every session
knows who it is talking to.
Money and time. Cost per conversation, per project and per period, a forecast of when the weekly limit runs out, real working time measured from five-minute activity windows, and a count of how often you switch between sessions.
Calendar. Google and Microsoft in both directions, several accounts of the
same provider side by side. Type a sentence like dentist wednesday 4pm: the
parser handles the date, and when the length is missing a model estimates it
through a tool call, so a dentist visit gets 45 minutes rather than a default
hour. Everything stays editable before saving. Blocks written from the panel
appear in every connected account, conflicts are detected across all calendars
at once, and find a free slot returns windows free everywhere. Online meetings
carry a join link pulled from Teams, Meet, Zoom, Whereby, Jitsi and Webex, and
clicking it opens the desktop client rather than a browser tab. The day grid
stretches to three days, a week or two weeks, and the docked column widens with
it instead of covering the conversation.
Busy-time mirroring copies the hours of one calendar into another as a plain
Zajęte block, without the title, so colleagues see the time is taken but not
why; those mirrors are hidden from your own view.
Smart scheduling. Plan tasks places open tasks into free windows: due
dates decide the order, overdue work goes first, long tasks are split into
chunks of at most 90 minutes, each day has a work limit so the calendar does not
fill to the brim, and blocks keep a gap because a plan without slack falls apart
after the first slip. Every proposal explains itself (3 days overdue,
urgent, part of 180 min) and you can drop single rows before saving.
One place for settings. Language, notifications, tool permissions, the
vault, the profile and calendar accounts live behind the ⚙ button (Alt+,)
instead of being scattered across panels.
Two languages. The interface switches between Polish and English under ⚙
(Alt+,). The dictionary maps Polish text to English, so an untranslated string
falls back to the original instead of an empty label; adding a language means
adding entries to one file, src/lib/i18n.ts.
Around the work. GitLab merge requests and issues, failed user services,
repositories with uncommitted changes, project cards, a daily journal that turns
into a standup note, a public /status page, and phone notifications through
ntfy when a session needs a decision.
- Node.js 20 or newer (tested on 22 and 26)
- Claude Code installed and logged in
- Linux with systemd user services (other systems work, but you start it yourself)
- Transcripts in the standard location,
~/.claude/projects
git clone https://github.com/rodorn/fluxdesk.git
cd fluxdesk
./scripts/install.shThe script installs dependencies, builds the native pty module, builds the app,
registers a systemd --user service and links the fluxdesk CLI client. The
panel then runs on http://localhost:4317 and starts with your session.
To get it in your application launcher as a normal desktop app:
install -Dm644 desktop/fluxdesk.desktop ~/.local/share/applications/fluxdesk.desktop
install -Dm644 desktop/fluxdesk.svg ~/.local/share/icons/hicolor/scalable/apps/fluxdesk.svg
install -Dm755 desktop/fluxdesk.sh ~/.local/bin/fluxdesk-app
update-desktop-database ~/.local/share/applicationsThe launcher entry opens the panel in its own window, starting the service first
if it happens to be down. Set BROWSER if you do not use Chrome.
Manual alternative:
npm install
npm rebuild node-pty
NEXT_DIST_DIR=.next-service npm run build
NEXT_DIST_DIR=.next-service npm startRun the production build, not next dev. Development mode compiles on every
request, which costs 12–111 ms per keystroke in a terminal instead of 2 ms. The
separate build directory means rebuilding from another session does not disturb
the running panel.
Everything is optional; the panel works with no configuration at all.
| Variable | Meaning |
|---|---|
PORT |
Panel port, default 4317 |
CSM_ACCESS_TOKEN |
Required token for API access; set it before exposing the panel to a network |
CSM_ALLOWED_ROOTS |
Colon-separated directories where sessions may start; empty means no restriction |
CSM_DEFAULT_MODEL |
Model for new sessions |
CSM_DEFAULT_PERMISSION_MODE |
default, acceptEdits, plan or bypassPermissions |
CLAUDE_CONFIG_DIR |
Claude Code config directory, default ~/.claude |
CSM_USD_PLN |
Exchange rate used for cost display, default 4.0 |
CSM_PIPEDRIVE_HOST |
Pipedrive subdomain, if you use that panel |
State lives in ~/.claude-session-manager: tasks, schedule, prompts, attention
log, permission rules and an encrypted secrets file. Nothing leaves the machine
unless you enable phone notifications.
fluxdesk # list sessions, pick one by number
fluxdesk ls # just the list
fluxdesk attach 3 # enter a session, Ctrl+Q detaches without killing it
fluxdesk new . # new session in the current directory
fluxdesk todo # open tasksBare keys work when you are not typing; the same key with Ctrl+Alt works
anywhere. Press ? for the full list.
| Key | Action |
|---|---|
1-9, J/K |
Switch sessions |
S |
Jump to a session by name |
A |
Jump to a session waiting for a decision |
Y/A/N |
Permission: allow, always, deny |
N, T, R |
New session, new terminal, resume a saved one |
O, V, G, F |
Split, full screen, grid, focus mode |
Z, B, D, C |
Tasks, board, journal, attention |
M, L, Y, E |
Knowledge, GitLab, machine pulse, projects |
Q |
Calendar and day planning |
/, P |
Search transcripts, command palette |
Alt+, |
Settings: language, notifications, calendars |
F5, Ctrl+Alt+R |
Reload the panel |
Esc |
Interrupt the current turn |
The panel runs commands on your machine. Two things follow from that.
Do not expose it without a token. Set CSM_ACCESS_TOKEN and sign in at
/login before making the port reachable from anywhere but localhost.
Secrets stay local. The vault is encrypted with a key stored next to it, both
0600. That protects against a stray backup or an accidental commit, not against
someone who already has your account. Secrets reach sessions only when you mark
them as exposed. Nothing is sent anywhere except phone notifications, which are
off by default and carry only a session name and a rule name.
A deny list blocks destructive commands regardless of permission mode, including sessions started with prompts skipped.
src/lib/terminals.tsandscripts/pty-host.mjsown the pty processes; the panel is only a client of a unix socket, which is why it can restart freely.src/lib/termstate.tsreads session state off the terminal screen, because Claude Code exposes none programmatically.src/lib/lightscan.tsreads only the edges of transcript files; a full read of 1.3 GB takes minutes, and the metadata lives at the beginning and the end.src/lib/watchdog.tspolls sessions, answers blocking prompts and feeds queues.- Usage counting deduplicates by request id, since the CLI writes the same response several times while streaming.
MIT. See LICENSE.