Hooks
Read and manage sessions from anywhere under the provider.
All hooks must be used under a <TermkitProvider>.
Reading sessions
useSessions
const sessions = useSessions(); // LiveSession[]The live snapshot of every session the daemon is running — the global view, kept fresh by the provider's poller. Independent of which terminals are mounted.
A LiveSession is:
| Field | Type | Notes |
|---|---|---|
sessionId | string | |
pid | number | |
connected | boolean | Whether a client is currently streaming it. |
bufferSize | number | Lines held in the screen model. |
attention | boolean | Has an unseen bell. |
meta | Record<string, string> | The connect params, echoed back. |
useSession
const session = useSession(id); // LiveSession | undefineduseSessionStatus
const status = useSessionStatus(id);
// 'connecting' | 'ready' | 'disconnected' | 'dead' | undefinedA mounted terminal's client-side connection status. undefined if no terminal
is attached for that session. (Distinct from whether the daemon still holds the
PTY — that's useSession.)
Bells
useRingingSessions
const ringing = useRingingSessions(); // Set<string>The ids currently ringing for attention. Badge any tab whose id is in the set.
useIsRinging
const isRinging = useIsRinging(id); // booleanActions
useTermkitActions
const { focus, blur, kill, dismissBell, dismissAllBells, setPendingCommand } =
useTermkitActions();| Action | Effect |
|---|---|
focus(id) / blur(id) | Move keyboard focus to/from a mounted terminal. |
kill(id) | Reap the daemon's PTY and drop the session from the registry. |
dismissBell(id) | Clear one session's bell without viewing it. |
dismissAllBells() | Clear every ringing session's bell (inbox "mark all read"). |
setPendingCommand(id, cmd) | Queue a command to auto-run on the session's next first attach. |
The returned object is stable across renders.
Finding orphans
useDanglingSessions
const dangling = useDanglingSessions(knownIds); // LiveSession[]Live PTYs whose id isn't in the Set of ids your UI knows about (its tabs). The
known-id bookkeeping is your domain, so it stays in your code; termkit just does the
diff. Useful for surfacing leftover shells for cleanup.
Building your own rollups
Domain groupings (per project, per directory, …) aren't built in — compose them over
useSessions() using the opaque meta you set via each terminal's params:
function useCountsBySlug() {
const sessions = useSessions();
return useMemo(() => {
const counts: Record<string, { total: number; bells: number }> = {};
for (const s of sessions) {
const slug = s.meta.slug;
if (!slug) continue;
const c = (counts[slug] ??= { total: 0, bells: 0 });
c.total++;
if (s.attention) c.bells++;
}
return counts;
}, [sessions]);
}