From 5bd5da261732a1fce6a94ffa4d348dd6c80887cf Mon Sep 17 00:00:00 2001 From: Clawd Date: Sat, 28 Feb 2026 15:26:21 -0800 Subject: Fix .gitignore: ignore dist/, .claude-flow/, and sync-conflict files Remove accidentally committed build artifacts and working files. --- .claude-flow/plan.md | 1090 -------------------- .claude-flow/research.md | 214 ---- .gitignore | 4 +- dist/main/claude/index.js | 109 -- dist/main/claude/phases.js | 147 --- dist/main/db/index.js | 33 - dist/main/db/projects.js | 28 - dist/main/db/schema.js | 36 - dist/main/db/sessions.js | 72 -- dist/main/index.js | 54 - .../index.sync-conflict-20260228-074140-M6474AW.js | 54 - dist/main/ipc/handlers.js | 116 --- dist/main/preload.js | 38 - ...reload.sync-conflict-20260228-074140-M6474AW.js | 38 - renderer/dist/assets/apl-B4CMkyY2.js | 1 - renderer/dist/assets/asciiarmor-Df11BRmG.js | 1 - renderer/dist/assets/asn1-EdZsLKOL.js | 1 - renderer/dist/assets/asterisk-B-8jnY81.js | 1 - renderer/dist/assets/brainfuck-C4LP7Hcl.js | 1 - renderer/dist/assets/clike-B9uivgTg.js | 1 - renderer/dist/assets/clojure-BMjYHr_A.js | 1 - renderer/dist/assets/cmake-BQqOBYOt.js | 1 - renderer/dist/assets/cobol-CWcv1MsR.js | 1 - renderer/dist/assets/coffeescript-S37ZYGWr.js | 1 - renderer/dist/assets/commonlisp-DBKNyK5s.js | 1 - renderer/dist/assets/crystal-SjHAIU92.js | 1 - renderer/dist/assets/css-BnMrqG3P.js | 1 - renderer/dist/assets/cypher-C_CwsFkJ.js | 1 - renderer/dist/assets/d-pRatUO7H.js | 1 - renderer/dist/assets/diff-DbItnlRl.js | 1 - renderer/dist/assets/dockerfile-BKs6k2Af.js | 1 - renderer/dist/assets/dtd-DF_7sFjM.js | 1 - renderer/dist/assets/dylan-DwRh75JA.js | 1 - renderer/dist/assets/ebnf-CDyGwa7X.js | 1 - renderer/dist/assets/ecl-Cabwm37j.js | 1 - renderer/dist/assets/eiffel-CnydiIhH.js | 1 - renderer/dist/assets/elm-vLlmbW-K.js | 1 - renderer/dist/assets/erlang-BNw1qcRV.js | 1 - renderer/dist/assets/factor-kuTfRLto.js | 1 - renderer/dist/assets/fcl-Kvtd6kyn.js | 1 - renderer/dist/assets/forth-Ffai-XNe.js | 1 - renderer/dist/assets/fortran-DYz_wnZ1.js | 1 - renderer/dist/assets/gas-Bneqetm1.js | 1 - renderer/dist/assets/gherkin-heZmZLOM.js | 1 - renderer/dist/assets/groovy-D9Dt4D0W.js | 1 - renderer/dist/assets/haskell-Cw1EW3IL.js | 1 - renderer/dist/assets/haxe-H-WmDvRZ.js | 1 - renderer/dist/assets/http-DBlCnlav.js | 1 - renderer/dist/assets/idl-BEugSyMb.js | 1 - renderer/dist/assets/index-B3j9TGDq.js | 1 - renderer/dist/assets/index-BD-MSR8_.js | 1 - renderer/dist/assets/index-BIiVCBvc.js | 1 - renderer/dist/assets/index-Bq61svda.js | 7 - renderer/dist/assets/index-C21GeVK2.js | 1 - renderer/dist/assets/index-CTw1r139.js | 1 - renderer/dist/assets/index-Cf79PRin.js | 107 -- renderer/dist/assets/index-CqkbJ0M5.js | 1 - renderer/dist/assets/index-D9evfPnI.js | 1 - renderer/dist/assets/index-DMcBEOyC.js | 2 - renderer/dist/assets/index-DVYY5F8U.js | 1 - renderer/dist/assets/index-DayAhP1T.js | 3 - renderer/dist/assets/index-DcJPzx-s.js | 1 - renderer/dist/assets/index-DdIv84li.js | 1 - renderer/dist/assets/index-DjcyoIrl.js | 1 - renderer/dist/assets/index-DzCjD1kD.js | 1 - renderer/dist/assets/index-Gqosk59g.js | 1 - renderer/dist/assets/index-SQDhBtlP.js | 1 - renderer/dist/assets/index-SZRk6EZ2.css | 1 - renderer/dist/assets/javascript-iXu5QeM3.js | 1 - renderer/dist/assets/julia-DuME0IfC.js | 1 - renderer/dist/assets/livescript-BwQOo05w.js | 1 - renderer/dist/assets/lua-BgMRiT3U.js | 1 - renderer/dist/assets/mathematica-DTrFuWx2.js | 1 - renderer/dist/assets/mbox-CNhZ1qSd.js | 1 - renderer/dist/assets/mirc-CjQqDB4T.js | 1 - renderer/dist/assets/mllike-CXdrOF99.js | 1 - renderer/dist/assets/modelica-Dc1JOy9r.js | 1 - renderer/dist/assets/mscgen-BA5vi2Kp.js | 1 - renderer/dist/assets/mumps-BT43cFF4.js | 1 - renderer/dist/assets/nginx-DdIZxoE0.js | 1 - renderer/dist/assets/nsis-LdVXkNf5.js | 1 - renderer/dist/assets/ntriples-BfvgReVJ.js | 1 - renderer/dist/assets/octave-Ck1zUtKM.js | 1 - renderer/dist/assets/oz-BzwKVEFT.js | 1 - renderer/dist/assets/pascal--L3eBynH.js | 1 - renderer/dist/assets/perl-CdXCOZ3F.js | 1 - renderer/dist/assets/pig-CevX1Tat.js | 1 - renderer/dist/assets/powershell-CFHJl5sT.js | 1 - renderer/dist/assets/properties-C78fOPTZ.js | 1 - renderer/dist/assets/protobuf-ChK-085T.js | 1 - renderer/dist/assets/pug-DeIclll2.js | 1 - renderer/dist/assets/puppet-DMA9R1ak.js | 1 - renderer/dist/assets/python-BuPzkPfP.js | 1 - renderer/dist/assets/q-pXgVlZs6.js | 1 - renderer/dist/assets/r-B6wPVr8A.js | 1 - renderer/dist/assets/rpm-CTu-6PCP.js | 1 - renderer/dist/assets/ruby-B2Rjki9n.js | 1 - renderer/dist/assets/sas-B4kiWyti.js | 1 - renderer/dist/assets/scheme-C41bIUwD.js | 1 - renderer/dist/assets/shell-CjFT_Tl9.js | 1 - renderer/dist/assets/sieve-C3Gn_uJK.js | 1 - renderer/dist/assets/simple-mode-GW_nhZxv.js | 1 - renderer/dist/assets/smalltalk-CnHTOXQT.js | 1 - renderer/dist/assets/solr-DehyRSwq.js | 1 - renderer/dist/assets/sparql-DkYu6x3z.js | 1 - renderer/dist/assets/spreadsheet-BCZA_wO0.js | 1 - renderer/dist/assets/sql-D0XecflT.js | 1 - renderer/dist/assets/stex-C3f8Ysf7.js | 1 - renderer/dist/assets/stylus-B533Al4x.js | 1 - renderer/dist/assets/swift-BzpIVaGY.js | 1 - renderer/dist/assets/tcl-DVfN8rqt.js | 1 - renderer/dist/assets/textile-CnDTJFAw.js | 1 - renderer/dist/assets/tiddlywiki-DO-Gjzrf.js | 1 - renderer/dist/assets/tiki-DGYXhP31.js | 1 - renderer/dist/assets/toml-Bm5Em-hy.js | 1 - renderer/dist/assets/troff-wAsdV37c.js | 1 - renderer/dist/assets/ttcn-CfJYG6tj.js | 1 - renderer/dist/assets/ttcn-cfg-B9xdYoR4.js | 1 - renderer/dist/assets/turtle-B1tBg_DP.js | 1 - renderer/dist/assets/vb-CmGdzxic.js | 1 - renderer/dist/assets/vbscript-BuJXcnF6.js | 1 - renderer/dist/assets/velocity-D8B20fx6.js | 1 - renderer/dist/assets/verilog-C6RDOZhf.js | 1 - renderer/dist/assets/vhdl-lSbBsy5d.js | 1 - renderer/dist/assets/webidl-ZXfAyPTL.js | 1 - renderer/dist/assets/xquery-DzFWVndE.js | 1 - renderer/dist/assets/yacas-BJ4BC0dw.js | 1 - renderer/dist/assets/z80-Hz9HOZM7.js | 1 - renderer/dist/index.html | 18 - 129 files changed, 3 insertions(+), 2277 deletions(-) delete mode 100644 .claude-flow/plan.md delete mode 100644 .claude-flow/research.md delete mode 100644 dist/main/claude/index.js delete mode 100644 dist/main/claude/phases.js delete mode 100644 dist/main/db/index.js delete mode 100644 dist/main/db/projects.js delete mode 100644 dist/main/db/schema.js delete mode 100644 dist/main/db/sessions.js delete mode 100644 dist/main/index.js delete mode 100644 dist/main/index.sync-conflict-20260228-074140-M6474AW.js delete mode 100644 dist/main/ipc/handlers.js delete mode 100644 dist/main/preload.js delete mode 100644 dist/main/preload.sync-conflict-20260228-074140-M6474AW.js delete mode 100644 renderer/dist/assets/apl-B4CMkyY2.js delete mode 100644 renderer/dist/assets/asciiarmor-Df11BRmG.js delete mode 100644 renderer/dist/assets/asn1-EdZsLKOL.js delete mode 100644 renderer/dist/assets/asterisk-B-8jnY81.js delete mode 100644 renderer/dist/assets/brainfuck-C4LP7Hcl.js delete mode 100644 renderer/dist/assets/clike-B9uivgTg.js delete mode 100644 renderer/dist/assets/clojure-BMjYHr_A.js delete mode 100644 renderer/dist/assets/cmake-BQqOBYOt.js delete mode 100644 renderer/dist/assets/cobol-CWcv1MsR.js delete mode 100644 renderer/dist/assets/coffeescript-S37ZYGWr.js delete mode 100644 renderer/dist/assets/commonlisp-DBKNyK5s.js delete mode 100644 renderer/dist/assets/crystal-SjHAIU92.js delete mode 100644 renderer/dist/assets/css-BnMrqG3P.js delete mode 100644 renderer/dist/assets/cypher-C_CwsFkJ.js delete mode 100644 renderer/dist/assets/d-pRatUO7H.js delete mode 100644 renderer/dist/assets/diff-DbItnlRl.js delete mode 100644 renderer/dist/assets/dockerfile-BKs6k2Af.js delete mode 100644 renderer/dist/assets/dtd-DF_7sFjM.js delete mode 100644 renderer/dist/assets/dylan-DwRh75JA.js delete mode 100644 renderer/dist/assets/ebnf-CDyGwa7X.js delete mode 100644 renderer/dist/assets/ecl-Cabwm37j.js delete mode 100644 renderer/dist/assets/eiffel-CnydiIhH.js delete mode 100644 renderer/dist/assets/elm-vLlmbW-K.js delete mode 100644 renderer/dist/assets/erlang-BNw1qcRV.js delete mode 100644 renderer/dist/assets/factor-kuTfRLto.js delete mode 100644 renderer/dist/assets/fcl-Kvtd6kyn.js delete mode 100644 renderer/dist/assets/forth-Ffai-XNe.js delete mode 100644 renderer/dist/assets/fortran-DYz_wnZ1.js delete mode 100644 renderer/dist/assets/gas-Bneqetm1.js delete mode 100644 renderer/dist/assets/gherkin-heZmZLOM.js delete mode 100644 renderer/dist/assets/groovy-D9Dt4D0W.js delete mode 100644 renderer/dist/assets/haskell-Cw1EW3IL.js delete mode 100644 renderer/dist/assets/haxe-H-WmDvRZ.js delete mode 100644 renderer/dist/assets/http-DBlCnlav.js delete mode 100644 renderer/dist/assets/idl-BEugSyMb.js delete mode 100644 renderer/dist/assets/index-B3j9TGDq.js delete mode 100644 renderer/dist/assets/index-BD-MSR8_.js delete mode 100644 renderer/dist/assets/index-BIiVCBvc.js delete mode 100644 renderer/dist/assets/index-Bq61svda.js delete mode 100644 renderer/dist/assets/index-C21GeVK2.js delete mode 100644 renderer/dist/assets/index-CTw1r139.js delete mode 100644 renderer/dist/assets/index-Cf79PRin.js delete mode 100644 renderer/dist/assets/index-CqkbJ0M5.js delete mode 100644 renderer/dist/assets/index-D9evfPnI.js delete mode 100644 renderer/dist/assets/index-DMcBEOyC.js delete mode 100644 renderer/dist/assets/index-DVYY5F8U.js delete mode 100644 renderer/dist/assets/index-DayAhP1T.js delete mode 100644 renderer/dist/assets/index-DcJPzx-s.js delete mode 100644 renderer/dist/assets/index-DdIv84li.js delete mode 100644 renderer/dist/assets/index-DjcyoIrl.js delete mode 100644 renderer/dist/assets/index-DzCjD1kD.js delete mode 100644 renderer/dist/assets/index-Gqosk59g.js delete mode 100644 renderer/dist/assets/index-SQDhBtlP.js delete mode 100644 renderer/dist/assets/index-SZRk6EZ2.css delete mode 100644 renderer/dist/assets/javascript-iXu5QeM3.js delete mode 100644 renderer/dist/assets/julia-DuME0IfC.js delete mode 100644 renderer/dist/assets/livescript-BwQOo05w.js delete mode 100644 renderer/dist/assets/lua-BgMRiT3U.js delete mode 100644 renderer/dist/assets/mathematica-DTrFuWx2.js delete mode 100644 renderer/dist/assets/mbox-CNhZ1qSd.js delete mode 100644 renderer/dist/assets/mirc-CjQqDB4T.js delete mode 100644 renderer/dist/assets/mllike-CXdrOF99.js delete mode 100644 renderer/dist/assets/modelica-Dc1JOy9r.js delete mode 100644 renderer/dist/assets/mscgen-BA5vi2Kp.js delete mode 100644 renderer/dist/assets/mumps-BT43cFF4.js delete mode 100644 renderer/dist/assets/nginx-DdIZxoE0.js delete mode 100644 renderer/dist/assets/nsis-LdVXkNf5.js delete mode 100644 renderer/dist/assets/ntriples-BfvgReVJ.js delete mode 100644 renderer/dist/assets/octave-Ck1zUtKM.js delete mode 100644 renderer/dist/assets/oz-BzwKVEFT.js delete mode 100644 renderer/dist/assets/pascal--L3eBynH.js delete mode 100644 renderer/dist/assets/perl-CdXCOZ3F.js delete mode 100644 renderer/dist/assets/pig-CevX1Tat.js delete mode 100644 renderer/dist/assets/powershell-CFHJl5sT.js delete mode 100644 renderer/dist/assets/properties-C78fOPTZ.js delete mode 100644 renderer/dist/assets/protobuf-ChK-085T.js delete mode 100644 renderer/dist/assets/pug-DeIclll2.js delete mode 100644 renderer/dist/assets/puppet-DMA9R1ak.js delete mode 100644 renderer/dist/assets/python-BuPzkPfP.js delete mode 100644 renderer/dist/assets/q-pXgVlZs6.js delete mode 100644 renderer/dist/assets/r-B6wPVr8A.js delete mode 100644 renderer/dist/assets/rpm-CTu-6PCP.js delete mode 100644 renderer/dist/assets/ruby-B2Rjki9n.js delete mode 100644 renderer/dist/assets/sas-B4kiWyti.js delete mode 100644 renderer/dist/assets/scheme-C41bIUwD.js delete mode 100644 renderer/dist/assets/shell-CjFT_Tl9.js delete mode 100644 renderer/dist/assets/sieve-C3Gn_uJK.js delete mode 100644 renderer/dist/assets/simple-mode-GW_nhZxv.js delete mode 100644 renderer/dist/assets/smalltalk-CnHTOXQT.js delete mode 100644 renderer/dist/assets/solr-DehyRSwq.js delete mode 100644 renderer/dist/assets/sparql-DkYu6x3z.js delete mode 100644 renderer/dist/assets/spreadsheet-BCZA_wO0.js delete mode 100644 renderer/dist/assets/sql-D0XecflT.js delete mode 100644 renderer/dist/assets/stex-C3f8Ysf7.js delete mode 100644 renderer/dist/assets/stylus-B533Al4x.js delete mode 100644 renderer/dist/assets/swift-BzpIVaGY.js delete mode 100644 renderer/dist/assets/tcl-DVfN8rqt.js delete mode 100644 renderer/dist/assets/textile-CnDTJFAw.js delete mode 100644 renderer/dist/assets/tiddlywiki-DO-Gjzrf.js delete mode 100644 renderer/dist/assets/tiki-DGYXhP31.js delete mode 100644 renderer/dist/assets/toml-Bm5Em-hy.js delete mode 100644 renderer/dist/assets/troff-wAsdV37c.js delete mode 100644 renderer/dist/assets/ttcn-CfJYG6tj.js delete mode 100644 renderer/dist/assets/ttcn-cfg-B9xdYoR4.js delete mode 100644 renderer/dist/assets/turtle-B1tBg_DP.js delete mode 100644 renderer/dist/assets/vb-CmGdzxic.js delete mode 100644 renderer/dist/assets/vbscript-BuJXcnF6.js delete mode 100644 renderer/dist/assets/velocity-D8B20fx6.js delete mode 100644 renderer/dist/assets/verilog-C6RDOZhf.js delete mode 100644 renderer/dist/assets/vhdl-lSbBsy5d.js delete mode 100644 renderer/dist/assets/webidl-ZXfAyPTL.js delete mode 100644 renderer/dist/assets/xquery-DzFWVndE.js delete mode 100644 renderer/dist/assets/yacas-BJ4BC0dw.js delete mode 100644 renderer/dist/assets/z80-Hz9HOZM7.js delete mode 100644 renderer/dist/index.html diff --git a/.claude-flow/plan.md b/.claude-flow/plan.md deleted file mode 100644 index bbcae6a..0000000 --- a/.claude-flow/plan.md +++ /dev/null @@ -1,1090 +0,0 @@ -# Implementation Plan - -## Goal -Restyle the Claude Flow Electron app with: -1. Fix the window/tab title from "minimal" → "Claude Flow" -2. Add a "CLAUDE FLOW" wordmark to the header -3. Apply a cipherpunk aesthetic (full monospace UI font, sharper geometry, electric-blue accent, uppercase meta labels, focus glow) -4. Add light/dark mode with a text toggle (`[dark]` / `[light]`) persisted to `localStorage` - -## Approach -Five files touched in order of dependency. No new npm packages. The CSS rewrite is the biggest change; the JS/TSX changes are small and surgical. - -**Order of changes:** -1. `renderer/index.html` — title fix (trivial, isolated) -2. `renderer/src/styles/globals.css` — full restyle (all visual work) -3. `renderer/src/App.tsx` — add theme state, wire it down -4. `renderer/src/components/Header.tsx` — wordmark + toggle button -5. `renderer/src/components/DocumentPane.tsx` — dynamic CodeMirror theme - ---- - -## Changes - -### 1. Fix Window Title -**File:** `renderer/index.html` -**What:** Change `minimal` to `Claude Flow` on line 10. - -```html - -minimal - - -Claude Flow -``` - ---- - -### 2. Restyle the CSS -**File:** `renderer/src/styles/globals.css` -**What:** Complete replacement of the file. Key changes from the original: -- `:root` dark-mode accent updated to `#60a5fa` / `#93c5fd` -- `body` font-family changed to full monospace stack -- New `html[data-theme="light"]` block added after `:root` -- `border-radius` reduced to 2px on all interactive controls (4px on chat bubbles) -- `text-transform: uppercase; letter-spacing: 0.07em` added to all meta/chrome labels -- Focus glow (`box-shadow`) added on inputs and focused buttons -- New `.app-wordmark` class added -- New `.theme-toggle` class added -- All existing selectors preserved; only values changed - -```css -* { - box-sizing: border-box; - margin: 0; - padding: 0; -} - -/* ── Dark theme (default) ────────────────────────────────────── */ -:root { - --bg-primary: #1a1a1a; - --bg-secondary: #252525; - --bg-tertiary: #333; - --border: #444; - --text-primary: #e0e0e0; - --text-secondary: #888; - --accent: #60a5fa; /* electric blue — brighter than original #3b82f6 */ - --accent-hover: #93c5fd; - --success: #10b981; - --warning: #f59e0b; - --danger: #ef4444; -} - -/* ── Light theme overrides ───────────────────────────────────── */ -html[data-theme="light"] { - --bg-primary: #f4f4f2; - --bg-secondary: #e8e8e5; - --bg-tertiary: #d8d8d4; - --border: #b4b4b0; - --text-primary: #1a1a18; - --text-secondary: #5a5a56; - --accent: #2563eb; - --accent-hover: #1d4ed8; - --success: #059669; - --warning: #d97706; - --danger: #dc2626; -} - -/* ── Base ────────────────────────────────────────────────────── */ -body { - font-family: "SF Mono", "Cascadia Code", "JetBrains Mono", "Fira Code", - Monaco, "Courier New", monospace; - background: var(--bg-primary); - color: var(--text-primary); - overflow: hidden; - font-size: 13px; -} - -.app { - display: flex; - flex-direction: column; - height: 100vh; -} - -/* ── Header ──────────────────────────────────────────────────── */ -.header { - display: flex; - justify-content: space-between; - align-items: center; - padding: 10px 16px; - background: var(--bg-secondary); - border-bottom: 1px solid var(--border); - -webkit-app-region: drag; -} - -.header-left, -.header-right { - display: flex; - align-items: center; - gap: 8px; - -webkit-app-region: no-drag; -} - -/* App wordmark */ -.app-wordmark { - font-size: 12px; - font-weight: 700; - letter-spacing: 0.15em; - text-transform: uppercase; - color: var(--text-primary); - padding-right: 12px; - border-right: 1px solid var(--border); - margin-right: 4px; - user-select: none; - white-space: nowrap; -} - -.header select, -.header button { - padding: 5px 10px; - background: var(--bg-tertiary); - border: 1px solid var(--border); - border-radius: 2px; - color: var(--text-primary); - cursor: pointer; - font-size: 12px; - font-family: inherit; -} - -.header button:hover { - background: var(--border); -} - -.header button.btn-delete { - background: transparent; - border: 1px solid var(--border); - padding: 5px 8px; - font-size: 13px; -} - -.header button.btn-delete:hover { - background: var(--danger); - border-color: var(--danger); -} - -/* Theme toggle */ -.theme-toggle { - font-size: 11px; - letter-spacing: 0.08em; - text-transform: lowercase; - opacity: 0.7; - transition: opacity 0.15s; -} - -.theme-toggle:hover { - opacity: 1; - background: var(--bg-tertiary) !important; -} - -/* Phase indicator */ -.phase-indicator { - display: flex; - gap: 4px; -} - -.phase-step { - padding: 3px 10px; - font-size: 11px; - letter-spacing: 0.07em; - text-transform: uppercase; - border-radius: 2px; - background: var(--bg-tertiary); - color: var(--text-secondary); -} - -.phase-step.active { - background: var(--accent); - color: white; -} - -.phase-step.complete { - background: var(--success); - color: white; -} - -/* ── Main Content ─────────────────────────────────────────────── */ -.main-content { - flex: 1; - display: flex; - overflow: hidden; -} - -/* ── Document Pane ───────────────────────────────────────────── */ -.document-pane { - flex: 1; - display: flex; - flex-direction: column; - border-right: 1px solid var(--border); - min-width: 0; - overflow: hidden; -} - -.document-header { - display: flex; - justify-content: space-between; - align-items: center; - padding: 7px 16px; - background: var(--bg-secondary); - border-bottom: 1px solid var(--border); - font-size: 11px; - letter-spacing: 0.07em; - text-transform: uppercase; - color: var(--text-secondary); -} - -.document-header button { - padding: 3px 8px; - background: var(--bg-tertiary); - border: 1px solid var(--border); - border-radius: 2px; - color: var(--text-primary); - cursor: pointer; - font-size: 11px; - font-family: inherit; - letter-spacing: 0.05em; -} - -.document-header button:hover { - background: var(--border); -} - -.document-content { - flex: 1; - overflow-y: auto; - padding: 24px; -} - -.document-content.editing { - font-family: inherit; - font-size: 13px; - line-height: 1.6; - background: var(--bg-primary); - border: none; - resize: none; - color: var(--text-primary); -} - -.codemirror-editor { - flex: 1; - overflow: hidden; - min-height: 0; -} - -.codemirror-editor .cm-editor { - height: 100%; - max-width: 100%; -} - -.codemirror-editor .cm-scroller { - overflow: auto !important; -} - -.codemirror-editor .cm-gutters { - background: var(--bg-secondary); - border-right: 1px solid var(--border); -} - -.document-content.rendered { - line-height: 1.7; -} - -.document-content.rendered h1 { - font-size: 22px; - margin: 24px 0 16px; - letter-spacing: -0.01em; -} -.document-content.rendered h2 { - font-size: 17px; - margin: 20px 0 12px; - color: var(--text-secondary); - text-transform: uppercase; - letter-spacing: 0.05em; -} -.document-content.rendered h3 { - font-size: 14px; - margin: 16px 0 8px; -} -.document-content.rendered p { - margin: 8px 0; - line-height: 1.6; -} -.document-content.rendered code { - background: var(--bg-tertiary); - padding: 2px 6px; - border-radius: 2px; - font-size: 12px; - font-family: inherit; -} -.document-content.rendered pre { - background: var(--bg-tertiary); - padding: 16px; - border-radius: 2px; - overflow-x: auto; - margin: 16px 0; -} -.document-content.rendered pre code { - background: none; - padding: 0; -} -.document-content.rendered ul, -.document-content.rendered ol { - margin: 12px 0; - padding-left: 24px; -} -.document-content.rendered li { - margin-bottom: 6px; - line-height: 1.5; -} -.document-content.rendered ul.contains-task-list { - list-style: none; - padding-left: 0; -} -.document-content.rendered li.task-list-item { - display: flex; - align-items: flex-start; - gap: 8px; -} -.document-content.rendered li.task-list-item input[type="checkbox"] { - margin-top: 4px; -} -.document-content.rendered table { - width: 100%; - border-collapse: collapse; - margin: 16px 0; - font-size: 12px; -} -.document-content.rendered th, -.document-content.rendered td { - padding: 8px 12px; - text-align: left; - border: 1px solid var(--border); -} -.document-content.rendered th { - background: var(--bg-tertiary); - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.06em; - font-size: 11px; -} -.document-content.rendered tr:nth-child(even) td { - background: var(--bg-secondary); -} -.document-content.rendered blockquote { - border-left: 3px solid var(--accent); - margin: 16px 0; - padding-left: 16px; - color: var(--text-secondary); -} -.document-content.rendered hr { - border: none; - border-top: 1px solid var(--border); - margin: 24px 0; -} -.document-content.rendered a { - color: var(--accent); - text-decoration: none; -} -.document-content.rendered a:hover { - text-decoration: underline; -} -.document-content.rendered .empty { - color: var(--text-secondary); - font-style: italic; -} - -.badge { - background: var(--accent); - color: white; - padding: 2px 8px; - border-radius: 2px; - font-size: 10px; - letter-spacing: 0.08em; - text-transform: uppercase; -} - -/* ── Chat Pane ───────────────────────────────────────────────── */ -.chat-pane { - width: 380px; - display: flex; - flex-direction: column; - background: var(--bg-secondary); -} - -.chat-messages { - flex: 1; - overflow-y: auto; - padding: 16px; -} - -.message { - margin-bottom: 10px; - padding: 9px 13px; - border-radius: 4px; - max-width: 90%; - font-size: 13px; - line-height: 1.5; - white-space: pre-wrap; -} - -.message.user { - background: var(--accent); - margin-left: auto; - color: white; -} - -.message.assistant { - background: var(--bg-tertiary); -} - -.message.loading { - color: var(--text-secondary); - font-style: italic; -} - -.chat-input { - display: flex; - gap: 8px; - padding: 12px; - border-top: 1px solid var(--border); -} - -.chat-input input { - flex: 1; - padding: 9px 13px; - background: var(--bg-tertiary); - border: 1px solid var(--border); - border-radius: 2px; - color: var(--text-primary); - font-size: 13px; - font-family: inherit; - transition: border-color 0.15s, box-shadow 0.15s; -} - -.chat-input input:focus { - outline: none; - border-color: var(--accent); - box-shadow: 0 0 0 2px rgba(96, 165, 250, 0.2); -} - -html[data-theme="light"] .chat-input input:focus { - box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.2); -} - -.chat-input button { - padding: 9px 15px; - background: var(--accent); - border: none; - border-radius: 2px; - color: white; - cursor: pointer; - font-size: 12px; - font-family: inherit; - letter-spacing: 0.05em; - text-transform: uppercase; - transition: background 0.15s; -} - -.chat-input button:hover:not(:disabled) { - background: var(--accent-hover); -} - -.chat-input button:disabled { - opacity: 0.4; - cursor: not-allowed; -} - -/* ── Action Bar ──────────────────────────────────────────────── */ -.action-bar { - display: flex; - justify-content: space-between; - align-items: center; - padding: 10px 16px; - background: var(--bg-secondary); - border-top: 1px solid var(--border); -} - -.action-bar-left, -.action-bar-right { - display: flex; - align-items: center; - gap: 16px; -} - -.token-indicator { - display: flex; - align-items: center; - gap: 8px; -} - -.token-bar { - width: 100px; - height: 4px; - background: var(--bg-tertiary); - border-radius: 1px; - overflow: hidden; -} - -.token-fill { - height: 100%; - transition: width 0.3s ease; -} - -.token-label { - font-size: 10px; - letter-spacing: 0.08em; - text-transform: uppercase; - color: var(--text-secondary); -} - -.permission-toggle { - display: flex; - align-items: center; - gap: 6px; - font-size: 11px; - letter-spacing: 0.05em; - text-transform: uppercase; - color: var(--text-secondary); - cursor: pointer; -} - -.permission-toggle input { - cursor: pointer; -} - -.btn-secondary { - padding: 6px 14px; - background: var(--bg-tertiary); - border: 1px solid var(--border); - border-radius: 2px; - color: var(--text-primary); - cursor: pointer; - font-size: 12px; - font-family: inherit; - letter-spacing: 0.05em; - transition: background 0.15s; -} - -.btn-secondary:hover:not(:disabled) { - background: var(--border); -} - -.btn-secondary:disabled { - opacity: 0.4; - cursor: not-allowed; -} - -.btn-primary { - padding: 6px 18px; - background: var(--accent); - border: none; - border-radius: 2px; - color: white; - cursor: pointer; - font-weight: 600; - font-size: 12px; - font-family: inherit; - letter-spacing: 0.07em; - text-transform: uppercase; - transition: background 0.15s; -} - -.btn-primary:hover:not(:disabled) { - background: var(--accent-hover); -} - -.btn-primary:disabled { - opacity: 0.4; - cursor: not-allowed; -} - -.implementing-status { - color: var(--success); - font-size: 11px; - letter-spacing: 0.1em; - text-transform: uppercase; -} - -/* ── Error Bar ───────────────────────────────────────────────── */ -.error-bar { - display: flex; - justify-content: space-between; - align-items: center; - padding: 8px 16px; - background: var(--danger); - color: white; - font-size: 12px; - letter-spacing: 0.03em; -} - -.error-bar button { - background: none; - border: none; - color: white; - font-size: 16px; - cursor: pointer; - padding: 0 4px; -} - -.error-bar button:hover { - opacity: 0.8; -} - -/* ── Onboarding ──────────────────────────────────────────────── */ -.onboarding h1 { - font-size: 24px; - margin-bottom: 8px; - letter-spacing: 0.05em; - text-transform: uppercase; -} - -.onboarding h2 { - font-size: 13px; - margin-top: 28px; - margin-bottom: 12px; - color: var(--accent); - text-transform: uppercase; - letter-spacing: 0.1em; -} - -.onboarding p { - margin: 12px 0; - line-height: 1.6; -} - -.onboarding ol { - margin: 12px 0 12px 24px; -} - -.onboarding li { - margin: 8px 0; - line-height: 1.5; -} - -.onboarding pre { - background: var(--bg-tertiary); - padding: 12px 16px; - border-radius: 2px; - margin: 12px 0; -} - -.onboarding code { - font-family: inherit; - font-size: 12px; -} - -.onboarding a { - color: var(--accent); - text-decoration: none; -} - -.onboarding a:hover { - text-decoration: underline; -} - -.onboarding-tip { - margin-top: 28px; - padding: 16px; - background: var(--bg-tertiary); - border-left: 3px solid var(--accent); - border-radius: 0 2px 2px 0; -} -``` - ---- - -### 3. Add Theme State to App -**File:** `renderer/src/App.tsx` -**What:** Three additions to the existing file — no existing logic is touched. - -**3a. Add `Theme` type and `theme` state** — insert after the existing imports, before the `App` function: - -```typescript -// Add this type alias near the top, alongside other local types if any, -// or just before the App function: -type Theme = "dark" | "light"; -``` - -**3b. Add `theme` state and side-effects** — insert inside `App()`, after the existing `useState` declarations (after `const [error, setError] = useState(null)`): - -```typescript -const [theme, setTheme] = useState( - () => (localStorage.getItem("cf-theme") as Theme) ?? "dark" -); - -// Keep document.documentElement in sync, and persist to localStorage -useEffect(() => { - document.documentElement.setAttribute("data-theme", theme); - localStorage.setItem("cf-theme", theme); -}, [theme]); - -const handleToggleTheme = () => - setTheme((t) => (t === "dark" ? "light" : "dark")); -``` - -**3c. Pass new props to `Header` and `DocumentPane`** — update the JSX inside the `return`: - -```tsx -// Header — add two new props: -
- -// DocumentPane — add one new prop: - -``` - ---- - -### 4. Update Header Component -**File:** `renderer/src/components/Header.tsx` -**What:** Add `theme` and `onToggleTheme` to the props interface, insert wordmark element, add toggle button. - -**Complete updated file:** - -```tsx -import React from "react"; -import type { Project, Session, Phase } from "../types"; - -type Theme = "dark" | "light"; - -interface HeaderProps { - projects: Project[]; - sessions: Session[]; - selectedProject: Project | null; - selectedSession: Session | null; - onSelectProject: (project: Project | null) => void; - onSelectSession: (session: Session | null) => void; - onCreateProject: () => void; - onCreateSession: () => void; - onDeleteProject?: (id: string) => void; - onDeleteSession?: (id: string) => void; - theme: Theme; - onToggleTheme: () => void; -} - -const phaseLabels: Record = { - research: "Research", - plan: "Plan", - implement: "Implement", -}; - -const phases: Phase[] = ["research", "plan", "implement"]; - -export function Header({ - projects, - sessions, - selectedProject, - selectedSession, - onSelectProject, - onSelectSession, - onCreateProject, - onCreateSession, - onDeleteProject, - onDeleteSession, - theme, - onToggleTheme, -}: HeaderProps) { - const handleDeleteProject = () => { - if (!selectedProject || !onDeleteProject) return; - if (confirm(`Delete project "${selectedProject.name}"? This cannot be undone.`)) { - onDeleteProject(selectedProject.id); - } - }; - - const handleDeleteSession = () => { - if (!selectedSession || !onDeleteSession) return; - if (confirm(`Delete session "${selectedSession.name}"? This cannot be undone.`)) { - onDeleteSession(selectedSession.id); - } - }; - - return ( -
-
- {/* ── Wordmark ── */} - Claude Flow - - - - {selectedProject && onDeleteProject && ( - - )} - - {selectedProject && ( - <> - - - {selectedSession && onDeleteSession && ( - - )} - - )} -
- -
- {selectedSession && ( -
- {phases.map((phase) => { - const phaseIndex = phases.indexOf(phase); - const currentIndex = phases.indexOf(selectedSession.phase); - const isComplete = phaseIndex < currentIndex; - const isActive = phase === selectedSession.phase; - - return ( - - {phaseLabels[phase]} - - ); - })} -
- )} - - {/* ── Theme toggle ── */} - -
-
- ); -} -``` - ---- - -### 5. Dynamic CodeMirror Theme in DocumentPane -**File:** `renderer/src/components/DocumentPane.tsx` -**What:** Three surgical changes to `MarkdownEditor` — add `theme` prop, update imports, update `useEffect`. - -**5a. Update imports** — add `syntaxHighlighting` and `defaultHighlightStyle` to the `@codemirror/language` import: - -```typescript -// BEFORE: -import { markdown } from "@codemirror/lang-markdown"; -import { languages } from "@codemirror/language-data"; - -// AFTER: -import { markdown } from "@codemirror/lang-markdown"; -import { languages } from "@codemirror/language-data"; -import { syntaxHighlighting, defaultHighlightStyle } from "@codemirror/language"; -``` - -**5b. Update `MarkdownEditor` props interface** — add `theme`: - -```typescript -// BEFORE: -function MarkdownEditor({ - content, - onChange, - disabled, -}: { - content: string; - onChange: (content: string) => void; - disabled: boolean; -}) - -// AFTER: -function MarkdownEditor({ - content, - onChange, - disabled, - theme, -}: { - content: string; - onChange: (content: string) => void; - disabled: boolean; - theme: "dark" | "light"; -}) -``` - -**5c. Update the `useEffect` inside `MarkdownEditor`** — swap the theme extension and add `theme` to the dependency array: - -```typescript -// BEFORE (inside useEffect): -extensions: [ - lineNumbers(), - highlightActiveLine(), - drawSelection(), - history(), - keymap.of([...defaultKeymap, ...historyKeymap]), - markdown({ codeLanguages: languages }), - oneDark, // ← hardcoded - updateListener, - EditorView.editable.of(!disabled), - EditorView.lineWrapping, - EditorView.theme({ ... }), -], -// dependency array: -}, [disabled]); - -// AFTER: -extensions: [ - lineNumbers(), - highlightActiveLine(), - drawSelection(), - history(), - keymap.of([...defaultKeymap, ...historyKeymap]), - markdown({ codeLanguages: languages }), - theme === "dark" ? oneDark : syntaxHighlighting(defaultHighlightStyle), // ← dynamic - updateListener, - EditorView.editable.of(!disabled), - EditorView.lineWrapping, - EditorView.theme({ ... }), -], -// dependency array: -}, [disabled, theme]); // ← theme added -``` - -**5d. Update `DocumentPaneProps` interface and pass `theme` through** — add to the interface and forward to `MarkdownEditor`: - -```typescript -// BEFORE: -interface DocumentPaneProps { - content: string; - onChange: (content: string) => void; - phase: Phase; - disabled: boolean; - showOnboarding?: boolean; -} - -// AFTER: -interface DocumentPaneProps { - content: string; - onChange: (content: string) => void; - phase: Phase; - disabled: boolean; - showOnboarding?: boolean; - theme: "dark" | "light"; -} -``` - -And in the `DocumentPane` function body, destructure `theme` and pass it to `MarkdownEditor`: - -```tsx -// BEFORE: -export function DocumentPane({ - content, - onChange, - phase, - disabled, - showOnboarding, -}: DocumentPaneProps) - -// AFTER: -export function DocumentPane({ - content, - onChange, - phase, - disabled, - showOnboarding, - theme, -}: DocumentPaneProps) -``` - -```tsx -// BEFORE (in JSX): - - -// AFTER: - -``` - ---- - -## TODO -- [x] **1.** `renderer/index.html` — change `minimal` to `Claude Flow` -- [x] **2.** `renderer/src/styles/globals.css` — full replacement with new CSS (monospace body, electric accent, 2px radii, uppercase labels, light theme block, focus glow, `.app-wordmark`, `.theme-toggle`) -- [x] **3a.** `renderer/src/App.tsx` — add `type Theme` alias -- [x] **3b.** `renderer/src/App.tsx` — add `theme` state + `useEffect` + `handleToggleTheme` -- [x] **3c.** `renderer/src/App.tsx` — pass `theme`/`onToggleTheme` to `Header`, pass `theme` to `DocumentPane` -- [x] **4.** `renderer/src/components/Header.tsx` — full replacement (new props, wordmark, toggle button) -- [x] **5a.** `renderer/src/components/DocumentPane.tsx` — add `syntaxHighlighting, defaultHighlightStyle` import -- [x] **5b.** `renderer/src/components/DocumentPane.tsx` — add `theme` to `MarkdownEditor` props -- [x] **5c.** `renderer/src/components/DocumentPane.tsx` — dynamic theme extension + `theme` in dep array -- [x] **5d.** `renderer/src/components/DocumentPane.tsx` — add `theme` to `DocumentPaneProps`, destructure, forward to `MarkdownEditor` - ---- - -## Risks / Considerations - -**CodeMirror reinitialization on theme switch**: Adding `theme` to the `useEffect` dependency array means the entire editor is torn down and recreated when the theme changes. This is intentional and correct — CodeMirror extensions are baked into the `EditorState` at creation time and can't be hot-swapped. The existing `content` sync `useEffect` will immediately restore the document contents after reinit, so no text loss occurs. There is a brief visual flash on theme toggle; this is acceptable. - -**`data-theme` initial state and flash of wrong theme**: The `useState` initializer reads `localStorage` synchronously, and the `useEffect` sets `data-theme` on first render. Because this happens before paint (Electron loads the renderer in a hidden window and only shows it after load), there should be no flash of the wrong theme in production. In dev the Vite HMR setup may briefly show unstyled content; this is not a concern for shipping. - -**Monospace font rendering differences per OS**: "SF Mono" ships with macOS/Xcode; "Cascadia Code" ships with Windows Terminal; "JetBrains Mono" and "Fira Code" are user-installed. The fallback chain is safe — `Monaco` is widely available on macOS, and `"Courier New", monospace` are universal final fallbacks. No font files are bundled; this is system-font-only. - -**`Theme` type duplication**: The `type Theme = "dark" | "light"` alias is defined in both `App.tsx` and `Header.tsx`. This is a minor smell. If it grows to more places, move it into `renderer/src/types.ts`. For this task (2 files) the duplication is acceptable. - -**Light mode CodeMirror gutter background**: The `.codemirror-editor .cm-gutters` rule uses `var(--bg-secondary)` which will automatically pick up the light-mode value — no extra change needed there. - -**`select` element styling in light mode**: Native `