Skip to content

Hub Daemon

The hub daemon is a background process that manages the multi-session dashboard. It coordinates session registration, serves the dashboard UI, and collects live terminal previews.

Components

Session Registry (registry.ts)

In-memory store of all active sessions. Uses a Map<string, SessionInfo> with EventEmitter for change notifications.

Events emitted:

  • session-added — new session registered
  • session-removed — session unregistered or process died
  • session-updated — session renamed or status changed

Health checks: Every 15 seconds, the registry verifies each session's process is still alive using process.kill(pid, 0). Dead sessions are automatically removed. Recent heartbeats (≤20s) are trusted over process checks.

Session Store (session-store.ts)

Persists the session registry to ~/.itwillsync/sessions.json. Saves are debounced (500ms) to avoid excessive disk writes during rapid registration/update cycles.

On hub startup, the store loads persisted sessions and verifies each process is still alive. Dead sessions and sessions older than 24 hours are pruned automatically. This allows sessions to survive hub daemon restarts.

Tool History (tool-history.ts)

Tracks the most recently used agent commands (e.g., claude, aider, bash). Stores up to 20 entries sorted by most-recently-used, persisted to ~/.itwillsync/tool-history.json. Used by the dashboard for quick-access suggestions.

Internal API (internal-api.ts)

HTTP server bound to 127.0.0.1:7963. Only accessible from the local machine. No authentication required (same-machine trust).

EndpointMethodPurpose
/api/healthGETHub health check
/api/sessionsGETList all sessions
/api/sessionsPOSTRegister a session
/api/sessions/:idGETGet session metadata (with memory usage)
/api/sessions/:idDELETEUnregister a session
/api/sessions/:id/heartbeatPUTUpdate last-seen timestamp
/api/sessions/:id/stopPOSTSend SIGTERM to session
/api/sessions/:id/renamePUTRename a session
/api/tool-historyGETRecently used agent commands
/api/recent-dirsGETRecently used working directories
/api/browseGETDirectory browser (query: ?path=~)

Dashboard Server (server.ts)

HTTP + WebSocket server bound to 0.0.0.0:7962. Serves the dashboard web UI and provides real-time session updates via WebSocket.

Authentication: Master token required for HTML pages, API endpoints, and WebSocket upgrade. Static assets (JS/CSS) served without token.

Rate limiting: 5 failed auth attempts from the same IP triggers a 60-second lockout.

Preview Collector (preview-collector.ts)

Subscribes to each session's WebSocket as a read-only client. Receives terminal output, strips ANSI escape codes, and buffers the last 5 lines per session.

Updates are throttled to 500ms per session to avoid overwhelming phone connections.

Lifecycle

First session starts

    ├─► Check port 7963 for running hub
    │     └─ Not running → spawn hub daemon (detached)

    ├─► Hub starts:
    │     ├── Generates master token
    │     ├── Writes ~/.itwillsync/hub.json + hub.pid
    │     ├── Restores persisted sessions (verifies PIDs)
    │     ├── Starts internal API (:7963)
    │     ├── Starts dashboard server (:7962)
    │     ├── Starts preview collector
    │     └── Prints "hub:ready:7963" to stdout

    ├─► Session registers via POST /api/sessions

    └─► Auto-shutdown timer starts (cancelled when sessions register)

Last session disconnects

    └─► 30-second timer → hub exits, cleans up files

Files on Disk

FilePurposeCreated byCleaned up by
~/.itwillsync/hub.jsonMaster token, ports, PIDHub daemonHub shutdown
~/.itwillsync/hub.pidHub process IDHub daemonHub shutdown
~/.itwillsync/config.jsonNetworking preferenceSetup wizardNever (user config)
~/.itwillsync/sessions.jsonPersisted session registrySession storeHub shutdown (pruned on startup)
~/.itwillsync/tool-history.jsonRecently used agent commandsTool historyNever (auto-pruned to 20 entries)
~/.itwillsync/logs/*.log.gzCompressed session logsSession logger (CLI)After logRetentionDays (default: 30)

Released under the MIT License.