My job generates a lot of surfaces to monitor. Linear for project tracking and cycle management. Freshservice for the IT support queue. Google Calendar for a meeting schedule that moves daily. Gmail for anything that doesn’t fit the other two. CrowdStrike for fleet vulnerabilities. Slack for everything else.

None of these talk to each other. Getting a coherent picture of what’s happening on a given day required visiting all of them, and turning that into an actual daily plan or end-of-day summary required manual effort I kept skipping.

The obvious solution was to build something that did it for me.

What It Is

Command Center is a local Node.js server with a browser-based card UI. You run node ui-server.js, open http://localhost:3838, and you get a dashboard. Every card is an independent module that owns its data fetching, rendering, and state. Cards can be added, removed, rearranged, and saved as presets. Multiple tab sets let you maintain different configurations (daily workflow, oncall, weekly review) without managing separate windows.

The server handles all API calls. The client is a single-page React app (Babel, no build step) that talks to the server via fetch and SSE for streaming content. There are no external CDN dependencies for the app’s own code: the server serves everything.

Configuration lives in two files: config.json for identity and paths, .env for API keys. The Settings card can edit config.json in-browser, so after the initial setup there’s no terminal required for day-to-day changes.

Reviews

The part I use most is the review system. Three card types: Morning (generates a prioritized daily plan with calendar, open Linear issues, and Freshservice queue), EOD (summarizes what was completed, what carried over, and suggests any new Linear tasks worth creating), and Weekly (retrospective with velocity context from the last twelve cycles).

Each review pulls data from every connected integration and streams it through Claude’s API. The server does the data gathering; the client renders the streaming response as Markdown in real time. Review content is cached in localStorage by date so a page refresh doesn’t trigger a regeneration.

It runs entirely server-side with no external shell scripts required. You need ANTHROPIC_API_KEY and LINEAR_API_KEY. Everything else is optional. The server also runs a cron job to auto-generate reviews on schedule (weekdays 8am for morning, 5pm for EOD, Fridays 9am for weekly) and can deliver them as Slack DMs when SLACK_REVIEW_DM=true.

There’s also a Monthly and Yearly review card: pick a month or year, get a synthesis of all the daily and weekly reviews from that period. Useful for quarterly self-assessment.

Linear Work

Four cards cover the Linear workflow end-to-end.

My Issues lists everything assigned to me, grouped by project with collapsible headers, filtered by status. Each row expands to an inline edit panel: state, priority, cycle assignment, comment. Updates push back to Linear without leaving the dashboard.

Triage surfaces unassigned and untriaged issues with team KPI pills. It’s a fast way to handle the ticket queue without opening Linear.

Reports generates seven structured report types: Team Health, Cycle Planner, Pre-Cycle Agenda, Rollover, Issue Health, Product Pulse, Weekly Pulse. These are AI-generated documents assembled from live Linear data and formatted for the specific audience (team leads, stakeholders, 1:1 prep).

Project Builder scaffolds new Linear projects. Give it a name and context (or an existing issue to expand from), and it generates a structured project with milestones and issues via Claude, then creates them in Linear with one button.

Milestones shows project milestone health: progress bar, days remaining, and a health indicator. Useful for a quick status check before a weekly report or stakeholder sync.

CrowdStrike Vulnerability Card

This one took the most debugging to get right.

The initial version showed six vulnerable hosts. The actual fleet has about 750 workstations. The discrepancy was a chain of problems: the default MAX_RECORDS cap was 10,000, the FQL filter wasn’t scoped to workstations, and 9,400 of those 10,000 records turned out to be GKE COS nodes and Linux servers. Scoping the Spotlight API query to product_type_desc:'Workstation' at the FQL level fixed it entirely.

The card shows vulnerabilities by CVE, sorted by CVSS score with ExPRT rating as a fallback for unscored recent CVEs. Each CVE expands to: per-host detection evidence (hostname and detected product version), fix type badge (patch/config change/workaround/manual), remediation reference, SLA compliance indicator (Critical: 7d, High: 14d, Medium: 30d, Low: 90d), and days open. A compliance grid at the top shows percentage in-SLA per severity tier across the whole fleet.

Each refresh makes two API calls: the combined Spotlight endpoint for the full vulnerability list, then a second pass to /spotlight/entities/vulnerabilities/v2 for CVE metadata (severity, CVSS, description, exploit status). The combined endpoint doesn’t return CVE details even with explicit facets. This cost me an afternoon.

Quick Modals

Three keyboard shortcuts that work from anywhere the dashboard is focused:

  • ⌘. (Quick Note): scratch input that saves a timestamped entry to the current day’s scratch file
  • ⌘K (Quick Chat): full-context Claude conversation with Linear and Freshservice data pre-loaded
  • ⌘I (Quick Issue): create a Linear issue from a single input, with a draft-then-confirm flow and per-modal assignee override

These work from Beacon too. When Beacon loads Command Center as its URL source, its global hotkeys ⌘⇧., ⌘⇧K, ⌘⇧I open the panel and dispatch synthetic keyboard events into the web app, driving the same modals from anywhere on the machine.

Access Control

If you’re sharing an instance with teammates, there’s a JumpCloud-based card visibility system. The server fetches your JumpCloud group memberships at startup. Cards can be restricted to specific groups in a Card Visibility settings view. Admin groups bypass all restrictions.

For single-user instances none of this needs to be configured: no JumpCloud API key means all cards are visible to everyone and the visibility system is a no-op.

Google Drive Storage

By default, everything writes to local paths: REVIEWS_DIR for review files, DAILY_DIR for notes. For multi-machine setups or shared instances, a Google Drive adapter routes all file I/O through the Drive API with drive.file scope (the app can only see files it created). Enable it by connecting a Google account via the Settings card.

When Drive is active, the Paths section in Settings is hidden. Linear draft, daily notes, and scratch all write to Command Center/_Daily/ and Command Center/reviews/ in your Drive. Review generation, the morning cron, and Slack DM delivery all work identically whether storage is local or cloud.

The Beacon Integration

Command Center is what Beacon primarily loads. The dashboard calls window.beaconSignal(cardId, payload) when a card has new content worth alerting on, and window.beaconClear() when alerts are dismissed. On the macOS side, Beacon switches its menu bar icon to a red notification variant and delivers a system notification.

The dashboard runs at http://localhost:3838. Beacon is pointed at that URL as its source. The panel stays out of the way until there’s something to look at.

Stack

Node.js 18+ with Express 4, ES modules throughout. The UI is a Babel-compiled JSX single-page app rendered directly by the browser (no webpack, no bundler, no build step). Anthropic Claude SDK for review generation and the chat/issue agents. @linear/sdk for Linear. Google APIs for Calendar, Gmail, and Drive. The CrowdStrike, JumpCloud, and Freshservice clients are custom fetch-based modules in src/.

The project is private.