⚠ Historical doc — last fully accurate at v1.0 (2026-05-23). This file describes the original v1 phased development plan and was partially updated during the v1.1 → v2.0 push. For the current state of the project (v3.0.0) see:
docs/SESSION_LOG_2026-05-26_v3.0.0_release.md— full handoff for v3.0.0 stable: feature list, build infrastructure quirks, branch layout, files added/modified, what's queued for v3.0.1+.CHANGELOG.md— at-a-glance per-release summary.docs/BACKLOG.md— open ideas for v3.0.1+.The rest of this file is preserved verbatim as historical context.
All seven plan phases shipped (v1.0.0 released). The app embeds Claude Code
via node-pty in resizable split panes, with sidebar panels for
compact-controller, commands, GitHub, LMM journaling, vault sync, account,
cost tracking, and settings. Auto-updater, system tray, command palette,
snippets, notifications, and rebindable hotkeys are wired in. Each phase
carries its own self-red-team review under docs/security-reviews/
(SECURITY_REVIEW_*.md).
v1.1 replaces v1.0's "user must install Node + npm i -g @anthropic-ai/claude-code
themselves" prereq with a one-click NSIS installer that bootstraps the
Claude CLI for the user. Migration plan: 9 phases (5 shipped at time of
writing). See INSTALLER_REDESIGN.md for the design + status,
MIGRATING_FROM_V1.md for the v1.0 → v1.1 upgrade path,
journal/config/INSTALLER_REDESIGN.lmm.md for the phase-by-phase progress
log, and BACKLOG.md §0 for what's left to ship rc1.
The terminal could flicker/resize when a sidebar panel opened or the
window narrowed. Two distinct mechanisms in TerminalPanel.tsx:
- Self-sustaining fit loop — every ResizeObserver tick called
fit()+resize-IPC;fit()mutates the DOM, which re-triggers the observer, ad infinitum. Now gated behind aproposeDimensions()equality check (fitIfChanged()): a converged grid is a no-op, so the loop can't sustain. - Panel-open ratchet (the user-visible flicker) — the pane flex
containers lacked
min-width: 0, so their defaultmin-width: autokept them as wide as the old xterm content when a 320px panel claimed its space; the box then caught up only one column per fit, crawling to the right width over ~1.5 s. AddingminWidth/minHeight: 0lets it shrink to its allotted size in the same layout pass.
Panel open now animates the layout width first (terminal smoothly
resizes into the opening space) and then fades the panel in, via a
panelEnter keyframe (width 0→320 over the first ~55%, opacity after).
The right panel is split into an animated clipping wrapper + a fixed
320px scrollable inner. Terminal resize debounce dropped 50→16 ms so the
grid reflows smoothly with the animation (safe now that the ratchet is
gone and fitIfChanged() no-ops once converged).
Verified on Linux by driving the running app over CDP: panel-open settles the grid in one ~66 ms step (was 30+ steps crawling over 1.6 s); a forced 90px squeeze settles to a single stable width; zero console errors. NOTE: the original flicker was reported on a Windows install — re-confirm there before closing the issue.
- Electron 42 + React 19 + Vite + TypeScript foundation.
- node-pty spawns
claude.exewith full ANSI support via xterm.js. - Frameless window with custom title bar + window controls.
- Hardening (Phase 4 follow-up): CSP meta, sandbox: true,
contextIsolation: true, navigation lockdown via
web-contents-created.
systeminformationpolls CPU/RAM/GPU every 2 s.- Process-tree walking from Claude's root PID(s) — aggregates across multiple panes (Phase 7c).
- GaugeBar with dual-fill (purple = Claude, grey = system).
- Reads
~/.claude/compact-controller/state.jsonfor token/turn/vault counts. - Toggle installs/uninstalls hooks in
~/.claude/settings.jsonwith parse-failure refusal +.bakbackup (Phase 4 C1 remediation). - Exact-path hook matching (Phase 4 M4) so other users' similarly-named projects aren't false-positive matches.
src/main/git-service.ts— local git ops (branch/status/ahead/behind), parses GitHub owner/repo from origin URL, UNC + symlink hardening, 5 s execFile timeout.src/main/github-service.ts— Octokit wrapper for repos/commits/ branches/PRs/issues; PAT stored encrypted via Electron safeStorage (DPAPI on Windows), plaintext fallback requires explicit opt-in.- GitHub panel: WorkingDirCard, ConnectGitHub, RepoHeader, CommitList, BranchList, PRList, IssueList.
shell.openExternalURL allowlist (github.com / *.github.com).
- In-app sidebar panel walking the Lincoln Manifold Method (RAW → NODES → REFLECT → SYNTHESIZE) with toggle, journal-dir picker, variant (quick/deep) selector, persisted cycles.
- Path-traversal-safe cycle ids (
^[a-z0-9][a-z0-9-]{0,79}$). - Per-file size cap, scan cap, cumulative cap on save.
src/main/auth-service.tswith two backends behind one contract:local-stub(scrypt + safeStorage in userData) andhttp(POST register/login/logout, GET/PUT /settings against a configured https:// baseUrl — for a future Cloudflare Worker drop-in).- "Continue without login" as primary CTA. GitHub PAT explicitly EXCLUDED from sync (device-local encryption key).
- Per-user sync file scoping (
auth-synced-settings.<uuid>.json), NaN-safe expiry, pinned scrypt keylen, validated session shape.
src/main/cloud-sync.tswatches~/.claude/compact-controller/vault/and pushes eachvault-*.jsontodeviceName/vault-*.jsonin a user-chosen private GitHub repo. Setup wizard (create-new or use-existing) with consent gate + write-access verification.- Per-file failure backoff (3 attempts then 15-min cooldown).
- "Uploads are append-only" warning + delete-remote-vault button.
- Ctrl+Shift+P palette with fuzzy-search across panels, themes, snippet inserts, terminal actions.
- Snippet store (CRUD + atomic JSON, 64 KB / 500 cap).
- Desktop notification service with per-kind throttling, settings toggles, and a test button.
src/main/updater-service.tswrapsupdate-electron-appfor GitHub Releases. Dev mode + non-Windows + user-disable gates.- StatusBar "Update vX.Y.Z ready" badge; SettingsPanel Updates section with channel toggle, check-now (rate-limited), and reason copy.
forge.config.ts:PublisherGithub(draft), Squirrel branding fields, commented signing/icon placeholders.
- react-resizable-panels split tree with
PtyRegistry(max 16 panes). - Per-pane PTY with reattach-if-alive semantics. ResourceMonitor aggregates across all live panes.
SessionServicepersists layout tree + active panel + theme to<userData>/session.jsonwith depth/node caps + sanitization.- Palette: Split horizontal/vertical, Close pane, Focus next/prev, Reset layout.
- Tray icon (16x16 base64 PNG) + context menu (Show / Toggle Compact / Quit). Minimize-to-tray-on-close toggle.
- Shutdown consolidated into
before-quit— closing the window while tray is on hides it (PTYs survive) instead of quitting. - Rebindable shortcuts service: click-to-record chords, conflict
detection, persisted in
<userData>/hotkeys.json.
src/main/cost-service.tspolls compact-controller state + vaults every 30 s. Per-session dedup, per-model rate table, daily totals.CostPanelwith stat cards, 30-day inline-SVG sparkline, daily budget setting, reset history.- Notification fires once per day when the budget is exceeded.
- In-panel disclaimer: estimates are a lower bound (vaults lack per-session output counts).
- Modern dark theme (#0f0f1a base) + 6 accent presets (Purple/Blue/
Emerald/Rose/Amber/Cyan). Theme apply extracted to
src/renderer/theme-presets.tsso SettingsPanel and CommandPalette share one source of truth. - SVG icons everywhere; design tokens for radius/shadow/transition; fadeIn/slideIn animations.
v1.0.0 released on 2026-05-23 (UTC). Available at: https://github.com/LxveAce/claude-code-studio/releases/tag/v1.0.0
Three published assets:
Claude.Code.Studio-1.0.0.Setup.exe(174 MB) — Squirrel installerclaude_code_studio-1.0.0-full.nupkg(174 MB) — auto-update payloadRELEASES— Squirrel update manifest
See SHIPPING_CERTIFICATION.md for the certifying red-team output
(SHIP verdict on the integrated code) and docs/security-reviews/SECURITY_REVIEW_PACKAGING.md
for the post-cert packaging fixes that produced this v1.0 build.
Phase 7 closed the original plan. See BACKLOG.md
for spitballed ideas and known bugs that don't yet have a plan —
backend / database planning, macOS + Linux ports, and any reported
bugs that haven't been triaged into a real fix go there.
Smaller items scoped from prior SECURITY_REVIEW_*.md reviews (each
is a deferred Medium, not a v1.0 blocker):
- Tray icon HiDPI variants — current tray icon is a single 16x16 PNG; supply @2x for crisp Retina.
- Cost panel model awareness — vault data doesn't record which model was used; cost is currently estimated against a single chosen model + an in-panel "lower-bound" disclaimer. Either ship a per-day model picker or accept the disclaimer permanently.
- Updater beta-channel pipeline — UI was reduced to "stable" only
(publisher pipeline is stable-only). To enable beta, split
update-electron-appconfig + add a beta tag to GitHub Releases, then re-enable the channel picker in SettingsPanel. - Multi-pane resource-monitor UI — backend aggregates across all panes; ResourcePanel could optionally show a per-pane breakdown.
- ✅ Hotkey cold-start window — hardcoded Ctrl/Cmd+Shift+P fallback
in
App.tsxworks regardless of bindings state. - ✅ Session migration scaffold —
SessionService.migrate()handles forward-version bumps and "from-the-future" files (refuse + default). - ✅ electron-store ESM landmine — dep removed entirely.
- ✅ Unattended-toast warning — SettingsPanel tray copy now warns that background services keep running while hidden.
- ✅ Installer end-to-end verification —
npm run makeproduces a working Setup.exe on Node 22; v1.0.0 is the proof. - ✅ Renderer not in asar —
vite.renderer.config.tsnow sets explicitoutDir+base: './'. - ✅ node_modules not in asar — custom
packagerConfig.ignoreshipped. - ✅ node-pty DLLs stuck in asar —
asar.unpackpattern shipped. - ✅ No DevTools in prod — F12 / Ctrl+Shift+I keybind in all builds.
- ✅ Missing AppUserModelID — set in
app.whenReady()on win32.
See BACKLOG.md § "Known Bugs" for details. Active items:
- Terminal resize loop when sidebar narrows the window — with a side panel open and the window shrunk small, the terminal flashes/loops on auto-fit. Cosmetic, doesn't crash. (Reported 2026-05-22 after v1.0 install.)
claude-code-studio/
├── scripts/
│ └── patch-node-pty.js
├── src/
│ ├── main/
│ │ ├── index.ts # window + IPC + lifecycle + service wiring
│ │ ├── pty-manager.ts # single-PTY (wrapped by PtyRegistry)
│ │ ├── pty-registry.ts # paneId-keyed PTY registry (Phase 7c)
│ │ ├── resource-monitor.ts # multi-PID aggregation
│ │ ├── compact-controller.ts # hook install/uninstall + state
│ │ ├── git-service.ts # local git ops (Phase 4)
│ │ ├── github-service.ts # Octokit wrapper (Phase 4)
│ │ ├── lmm-service.ts # LMM cycle store (Phase 4.5)
│ │ ├── auth-service.ts # local-stub + http auth (Phase 5)
│ │ ├── cloud-sync.ts # vault → GitHub (Phase 6)
│ │ ├── snippets-service.ts # CRUD snippets (Phase 7a)
│ │ ├── notifications-service.ts# OS notifications (Phase 7a, extended)
│ │ ├── updater-service.ts # update-electron-app wrapper (Phase 7b)
│ │ ├── session-service.ts # layout persistence (Phase 7c)
│ │ ├── hotkeys-service.ts # rebindable chords (Phase 7d)
│ │ ├── tray-service.ts # tray icon + menu (Phase 7d)
│ │ └── cost-service.ts # token usage sampling (Phase 7e)
│ ├── preload/preload.ts # contextBridge surface (all services)
│ ├── renderer/
│ │ ├── App.tsx # root layout + hotkey dispatch + palette
│ │ ├── main.tsx, index.html
│ │ ├── styles/globals.css
│ │ ├── theme-presets.ts # shared theme apply (Phase 7a)
│ │ ├── hotkeys.ts # chord parsing/build (Phase 7d)
│ │ └── components/
│ │ ├── layout/ # TitleBar, Sidebar (10 entries), StatusBar
│ │ ├── terminal/ # TerminalPanel, SplitLayout (Phase 7c)
│ │ ├── resources/ # ResourcePanel, GaugeBar
│ │ ├── compact/ # CompactPanel
│ │ ├── commands/ # CommandsPanel, QuickCommands
│ │ ├── github/ # 8 sub-components (Phase 4)
│ │ ├── lmm/ # LMMPanel (Phase 4.5)
│ │ ├── auth/ # AuthPanel (Phase 5)
│ │ ├── sync/ # SyncPanel, SyncWizard, VaultPreview (Phase 6)
│ │ ├── palette/ # CommandPalette, SnippetEditor (Phase 7a)
│ │ ├── cost/ # CostPanel (Phase 7e)
│ │ └── settings/ # SettingsPanel (theme, notif, tray, hotkeys, updater)
│ ├── shared/{ipc-channels,types}.ts
│ └── declarations.d.ts
├── journal/ # Per-source-file LMM analyses (one .lmm.md per file)
├── docs/ # Project documentation
│ ├── HANDOFF.md # this file
│ ├── BACKLOG.md # post-v1.0 ideas + known bugs
│ ├── SHIPPING_CERTIFICATION.md # v1.0 ship certification
│ └── security-reviews/ # per-phase self-red-team reviews
│ ├── SECURITY_REVIEW.md # Phase 4 review
│ ├── SECURITY_REVIEW_PHASE4_5.md
│ ├── SECURITY_REVIEW_PHASE5.md …through… SECURITY_REVIEW_PHASE7E.md
│ ├── SECURITY_REVIEW_PACKAGING.md
│ └── SECURITY_REVIEW_PHASE7_INTEGRATED.md # cross-feature review
├── .github/ # PR + issue templates
├── README.md
├── LICENSE # MIT
├── CONTRIBUTING.md
├── SECURITY.md
├── forge.config.ts
├── vite.{main,renderer,preload}.config.ts
├── tsconfig.json
└── package.json
git clone https://github.com/LxveAce/claude-code-studio.git
cd claude-code-studio
npm install
# Required Windows toolchain (for the node-pty native build):
# - VS Build Tools 2022 with the C++ workload
# - Windows 10/11 SDK (10.0.22621 or newer)
node scripts/patch-node-pty.js
npx electron-rebuild -m . --only node-pty
npm start # dev (Vite + Electron)
npm run package # smoke-test build
npm run make # NSIS/Squirrel installer (Phase 7b)
npm run publish # publish to GitHub Releases (draft, Phase 7b)Use Node 22 LTS. package.json pins engines.node: ">=22.0.0 <24.0.0".
Node 24 LTS has an undiagnosed incompatibility with electron-packager
(verified against both 18.4.4 shipped with forge 7 and 20.0.0 shipped
with forge 8-alpha): the packager's async extraction promise drops off
the event loop within ~30ms of starting, the process exits 0, and no
artifact is written. Node 22.12.0 LTS works end-to-end and produces the
Squirrel installer.
If you have Node 24 installed system-wide, the fastest workaround is to download the Node 22 binary side-by-side and use it for the build:
# one-time setup (no installer, fully reversible — just a folder)
Invoke-WebRequest 'https://nodejs.org/dist/v22.12.0/node-v22.12.0-win-x64.zip' `
-OutFile "$env:TEMP\node22.zip"
Expand-Archive "$env:TEMP\node22.zip" 'C:\Users\<you>\nodejs-22'
# then for any build command
$env:PATH = 'C:\Users\<you>\nodejs-22\nodejs-22;' + $env:PATH
npm install # native modules rebuild against Node 22's ABI
npm run makehttps://github.com/LxveAce/claude-code-studio
master— original Phase 1–3 basephase-4-github-integration— Phase 4 PRphase-4.5-lmm-panel— Phase 4.5 PRphase-5-auth— Phase 5 PRphase-6-vault-sync— Phase 6 PRphase-7a-palette-snippets-notifications— Phase 7a PRphase-7b-auto-updater,-7c-split-panes-session,-7d-tray-hotkeys,-7e-cost-tracker— individual sub-feature PRsphase-7-integrated— recommended merge target: all of 7b–e merged on top of 7a, plus a cross-feature red-team passexplore/smooth-panel-resize— post-v1.0: terminal resize-loop fix (BACKLOG #3) + smooth panel-open animation. Open PR.
- LMM applied as a thinking discipline on non-trivial work (see
journal/for per-file analyses). - Red-team + remediate after each phase before commit. Every phase has
a self-review at
docs/security-reviews/SECURITY_REVIEW_*.mdlisting the Criticals + Highs fixed in the same commit set, with Mediums explicitly deferred as documented tech debt. - Worktree-isolated agents per phase (see Phase 7b–e). Integration
happens in a
phase-N-integratedbranch with a final cross-feature review.