Releases: sorlen008/claude-command-center
Release list
v2.6.27 — Security hardening, a faster Live scanner & a code-review pass
v2.6.27 — Security hardening, a faster Live scanner & a code-review pass
A pre-completion code review across the codebase: security hardening, a single-pass Live scanner, correctness fixes, and shared-type/DRY cleanup — since v2.6.16.
Security
- Localhost trust boundary. Host/Origin validation plus a CSRF guard on mutating requests, so a malicious page can't drive the local server. Extra hosts opt in via
COMMAND_CENTER_ALLOWED_HOSTSfor intentional LAN exposure. - Write/scan confinement. Markdown writes are restricted to
.mdfiles under the home directory; settings-scan paths are confined under home. - XSS + dev-server lockdown. Graph custom-node
<style>content is sanitized; the Vite dev server'sallowedHostsis locked to localhost; the win32 session-delegation spawncwdis sanitized.
Robustness
- A scan error can't take the server down. Process-level crash handlers and guarded startup, plus
headersSentguards on the Live compact/close and AI-suggest response paths. - Fixed a Windows project-memory key mismatch in the projects scanner; removed a dead pricing helper.
Correctness
- Session pagination works past 50. The pager now renders for users with more than 50 sessions — the client had been reading a flat field the server nests under
pagination— with a "showing the first N of M sessions" notice when the list is capped. - Orphaned-agent sessions no longer report
hasHistoryas undefined. - Deep-search
dateTois now inclusive to end-of-day;PATCH /api/markdown/:id/metavalidates its body with a zod schema; the Telegram delegation bridge URL is configurable viaTELEGRAM_BRIDGE_URL.
Performance
- One pass for Live session details. The Live scanner now reads each session's JSONL in a single cached forward pass (was 3–4 overlapping reads), with incremental byte-offset reads for still-growing sessions instead of re-reading the whole file.
- Per-file caches added to the agent, session, and historical-limit scanners (keyed by mtime + size); the projects directory is listed once per scan instead of once per session (N+1 fix).
- Deep-search streams matches with early-exit and keys its cache on a session fingerprint, so new sessions invalidate stale results.
Internal
- Shared-type / DRY consolidation: the
NodeOriginunion, the inferred-projects response type, and the dashboard-analytics types (incl.BurnCategory) moved toshared/types.ts; a singlecheckClaudeAvailable()and sharedextractTurnsFromString/runClaudehelpers replace logic that had been duplicated across routes and scanners.
Stats
tsc --noEmitclean; 2300+ tests pass — added coverage for the live-scanner, deep-search, validation, session-delegation, and session-analytics seams.
Full Changelog: v2.6.16...v2.6.27
v2.6.16 — Live View overhaul, accurate costs & context
v2.6.16 — Live View overhaul, accurate costs & context
A batch of Live View, Message History, and accuracy improvements since v2.6.8.
Accuracy fixes
- Correct session cost.
opus-4-7/opus-4-8were matching the legacy 4.0/4.1 rate row ($15/$75) instead of the current$5/$25— a 3× overcharge across every cost figure. Fixed and regression-tested. The Live "$ spent" now also sums the whole transcript with per-token-type rates (was the last 1MB only, with a blended rate), so large sessions and their message counts are accurate. Cached by file mtime so it's cheap. - 1M context window detection. Opus sessions on the 1M beta were divided by a 200K window (a session at ~198K showed 99% instead of ~20%). The window is now inferred from proof (a session that exceeds 200K can only be 1M), persisted per model family.
- Context % matches the terminal. The bar now measures against Claude Code's usable budget (≈79% of the 1M window; full 200K window), so it reads like the terminal meter instead of low.
- Permission badge reflects the real mode. AUTO/BYPASS/PLAN are now read per-session from the JSONL
permission-moderecord, not a global settings.json heuristic (which mislabeled sessions).
Live View
- Background sessions are labeled. Headless
kind:"bg"jobs get a BACKGROUND badge (with the job name), and the header splits the count into "N terminals · M background" so it matches your visible terminals. Click the badge for a plain-language explainer. - End session button — confirm, then kill the process and close its terminal window (kills the parent shell, never the terminal-host app; background sessions have no window). Cross-platform (Windows/macOS/Linux); transcript is kept and resumable.
- Read the full message — click a card's Started/Latest line to open the complete text in a dialog (message cap raised 200 → 4000).
Message History
- Search message content, not just session titles — backed by deep-search, with matched snippets, role icons, and match counts.
- Open / resume button on each row opens a terminal in the session's cwd.
Housekeeping
- Safety test derives the username at runtime instead of hardcoding it; LICENSE uses the GitHub username; local helper scripts gitignored.
Stats
tsc --noEmitclean; 2270+ tests pass (incl. new pricing & context regressions).
Full Changelog: v2.6.8...v2.6.16
Full Changelog: v2.6.8...v2.6.16
v2.6.8 — Open Terminal button on project pages
v2.6.8 — Open Terminal button on project pages
Added
- "Open Terminal" button on the project detail page. Opens a native terminal sitting in that project's directory — a plain interactive shell, no command run. The button is placed inline beside the project name so it's immediately visible, and shows opening / opened / failed feedback states.
How it works
- New route
POST /api/projects/:id/open-terminalresolves the project by id server-side (never trusts a client-supplied path), guards withfs.existsSync, and dispatches a cross-platform terminal spawn. - The cross-platform spawn logic was factored out of
delegateToTerminalinto a sharedspawnTerminalInDir(dir, command?)helper, so the new button and the existing Sessions "open terminal" (Resume) button use one proven code path:- Windows:
start cmd /k "cd /d <dir>" - macOS:
osascript→Terminal.appdo script "cd '<dir>'" - Linux:
x-terminal-emulator -e bash -c "cd '<dir>' && exec \$SHELL"
- Windows:
- The directory is sanitized to prevent command injection; the window title is static. No
claudeCLI dependency (plain shell), so no availability gate needed.
Stats
- 4 files changed:
session-delegation.ts,projects.ts(route),use-projects.ts(hook),project-detail.tsx(UI) tsc --noEmitclean, safety tests pass; endpoint verified (opens terminal in the real project path; bogus id 404s)
Full Changelog: v2.6.6...v2.6.8
Full Changelog: v2.6.6...v2.6.8
v2.6.6 — Fix Node 24 crash in production CJS build
v2.6.6 — Fix Node 24 crash in production CJS build
Fixed
npm run buildproduced a bundle that crashed on startup under Node 24. esbuild lowers the ESM server source to a CommonJS bundle (dist/index.cjs) but leavesimport.meta.urlundefined, so the firstfileURLToPath(import.meta.url)call threw at process start. Added a banner that derives__ccImportMetaUrlfrom__filenameviapathToFileURL, anddefinedimport.meta.urlto it.- Verified: 0 raw
import.meta.urlreferences remain indist/index.cjs, and the bundle now loads past the former crash point.
Chore
- Gitignore local operational scripts (
start-server.ps1,watchdog.ps1) — machine-specific launchers/watchdogs, not for distribution.
Stats
- 1 source file changed (
script/build.ts) +.gitignore, version bump npm run buildclean (1 pre-existing guardedimport.metawarning inupdate.ts, harmless under CJS), safety tests pass
Full Changelog: v2.6.5...v2.6.6
What's Changed
- chore(deps): bump qs from 6.15.0 to 6.15.2 in the npm_and_yarn group across 1 directory by @dependabot[bot] in #15
New Contributors
- @dependabot[bot] made their first contribution in #15
Full Changelog: v2.6.5...v2.6.6
v2.6.5 — Full product name in browser tab & PWA
v2.6.5 — Full product name in browser tab & PWA
Fixed
document.titlefell back to the short "Command Center". TheDynamicTitleeffect inclient/src/App.tsxused"Command Center"as its fallback while the static<title>inindex.htmluses the full"Claude Command Center". Once React mounted, the tab title shrank to the abbreviated name. This meant Safari "Add to Dock" / iOS home-screen shortcuts saved the generic label, and the abbreviated tab was harder to spot among many open tabs. Aligned the fallback withindex.html.- A user-set custom
appNamestill takes precedence — this only changes the default.
- document.title = settings?.appName || "Command Center";
+ document.title = settings?.appName || "Claude Command Center";Credits
- Reported by @adamclark64 in #13.
Stats
- 1 source file changed (
client/src/App.tsx, 1 line) + version bump npx tsc --noEmitclean, safety tests pass (1840/1840)
Full Changelog: v2.6.4...v2.6.5
Full Changelog: v2.6.4...v2.6.5
v2.6.4 — Fix hooks-order crash on project detail
v2.6.4 — Critical fix for v2.6.3
Fixed
- "Rendered more hooks than during the previous render" crash on every project-detail page. v2.6.3 added
useOpenSession()anduseState()for the Resume button below the early returns (if (isLoading) return ...,if (!data) return ...), so the hook count differed between the loading and loaded renders. Rules-of-hooks violation. Moved both hooks above the early returns; added an inline comment to prevent regressions.
Stats
- 1 source file changed (project-detail.tsx)
npx tsc --noEmitclean, safety tests pass
Full Changelog: v2.6.3...v2.6.4
v2.6.3 — Resume button on project detail
v2.6.3 — One-click resume from project pages
Added
- Resume button on every session row in the project-detail Sessions tab. Same one-click flow as the main Sessions page — clicking opens a new terminal in the session's recorded cwd and runs
claude --resume. Three visual states (idle / opening / done) and a tooltip showing the target directory.
Stats
- 2 files changed (project-detail.tsx, package.json)
npx tsc --noEmitclean, safety tests pass
Full Changelog: v2.6.2...v2.6.3
v2.6.2 — Project detail page picks up inferred sessions
v2.6.2 — Project detail Sessions tab uses inferred-project matching
Patch on top of v2.6.0/v2.6.1.
Fixed
- Project detail page's Sessions tab was still cwd-only. On a project like
Nicora, you'd see only sessions launched from inside~/Nicoraand miss sessions launched from~/zwin0(or anywhere else) that did the bulk of their edits on Nicora files. The tab now merges both: cwd-matched sessions (same as before) plus inferred-project matches.
Added
- Orange "inferred" badge on session rows that came in via inferred-project matching, with hover tooltip showing original cwd + edit count.
+Nsuffix on the tab label when inferred matches exist (e.g.Sessions (3+2)). Hover explains the split.- Header copy above the list explains the two groups when both are present.
Stats
- 2 files changed (project-detail.tsx, package.json)
npx tsc --noEmitclean, new-user-safety test passes
Full Changelog: v2.6.1...v2.6.2
v2.6.1 — Case-fold project buckets
Patch on top of v2.6.0. Case-variant project names (e.g. Nicora vs nicora) were being split into separate buckets in the inferred-project filter and group-by view. Project names are now lowercased for bucketing. Cache version bump ensures existing cache entries are re-scanned on next launch.
server/scanner/project-inference.tsonly- Typecheck + 8/8 inference tests pass
- No client changes
Full Changelog: v2.6.0...v2.6.1
v2.6.0 — Inferred-project chip + filter + group-by view
v2.6.0 — Find sessions by what they actually worked on
Many Claude Code sessions are launched from a home directory but spend most of their work in a specific project subdirectory. Until now those sessions only showed up under the home bucket, which made them hard to find when you were looking for "the work I did on project X." This release adds a second project signal — inferred from each session's tool calls — without moving or rewriting any session files.
Added
- 💼 Inferred-project chip on every session card (main list + deep-search results). Color-coded distinct from the cyan cwd chip. Hover tooltip shows edit count, file count, confidence percentage, and the top-5 project breakdown. Suppressed when the inferred project matches the cwd basename (avoids visual duplication).
- "Inferred project" filter dropdown above the session list. Lists all detected projects with session counts, plus a
(uncategorized)bucket for sessions with insufficient signal. - "Group by project" toggle. Flattens the session list into collapsible sections sorted by session count. Each header shows count + cumulative size. Uncategorized always rendered last.
- New endpoint:
GET /api/sessions/inferred-projectsreturns aggregated counts per project. - New query param:
GET /api/sessions?inferredProject=<name>(or(none)for uncategorized).
How inference works
- Streams each session JSONL and extracts file paths from
Edit,Write,NotebookEdit,MultiEdit,Read, andcdtargets fromBash/PowerShellcommands. - First path segment under
$HOME= the candidate project bucket. - Per-project score:
writes × 3 + cd × 2 + reads × 1. - A project wins only when its share is ≥ 60% AND total file ops ≥ 3 (otherwise no chip — avoids false labels on borderline sessions).
.claude/*,~/.claude-command-center/*, and top-level config files (CLAUDE.md,MEMORY.md) bucket assystem. Top-level OS directories (Downloads,OneDrive,AppData,Documents,Pictures,Videos,Music,node_modules,tmp) are ignored.- Results cached on disk at
~/.claude-command-center/inferred-projects.jsonkeyed by(sessionId, fileSize). Re-scans automatically when a session grows. - First launch warms the cache for all sessions in parallel (4 workers); subsequent loads read from cache instantly.
What this is NOT
- No session files were moved or rewritten. Each session's literal
cwdfield is left exactly as Claude Code recorded it. The Resume button still opens a terminal in the historical cwd. - No "always-show" attribution. Sessions that span multiple projects or have too little signal get no chip, by design.
Stats
- 9 files changed, +707 -21 lines
- 1 new server module (
server/scanner/project-inference.ts) - 8 new tests covering scoring, thresholds, buckets, ignored dirs, caching, and write/read weighting
npx tsc --noEmitclean, 2098/2098 tests pass, production build clean
Full Changelog: v2.5.3...v2.6.0