From b6405dd6a4ba65fc5dc6746db7be7be7d0bb29f3 Mon Sep 17 00:00:00 2001 From: bndw Date: Wed, 4 Mar 2026 21:21:22 -0800 Subject: feat: replace header dropdowns with collapsible sidebar tree - Add Sidebar.tsx: project/session tree with inline rename, collapse/resize - App.tsx: load all sessions at startup, sync selectedProject on session click - Header.tsx: strip project/session UI, keep only right-side controls - globals.css: add .main-layout, sidebar, item, and activity-dot styles - Chat pane: move toggle button to left, use triangle icons matching sidebar --- CLAUDE.md | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) (limited to 'CLAUDE.md') diff --git a/CLAUDE.md b/CLAUDE.md index d2e968a..5d25656 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -33,6 +33,8 @@ renderer/src/ # React UI ### Phase System Phases: `research | plan | implement`. Each defined in `src/main/claude/phases.ts` with its own `systemPrompt`, `tools[]`, `permissionMode`, and `initialMessage`. Phase progression is one-way; triggered by user clicking "Submit". +**Important**: All new sessions currently start at `research` phase by default (hardcoded in `sessions.createSession()`). If building phase selection UI, modify `createSession()` in both `/db/sessions.ts` and the IPC handler at `/ipc/handlers.ts` to accept an optional `phase` parameter. + ### Artifact Storage Session artifacts (`research.md`, `plan.md`) stored inside the target project at `.claude-flow/sessions/{sessionId}/`. This keeps them within the SDK's allowed write boundary (project `cwd`). Add `.claude-flow/` to `.gitignore` to exclude from version control. @@ -54,6 +56,77 @@ Schema migrations: `db/index.ts::getDb()` calls `initSchema()` which uses `CREAT `allowedTools: string[]` in the SDK maps to Claude Code's `--allowedTools` CLI flag and supports patterns like `'Bash(git *)'` to auto-allow only specific Bash command forms. +## UI Architecture + +### Current Layout +``` +┌─────────────────────────────────────────────────────┐ +│ Header: Project selector, Session selector, Controls │ +├─────────────────────────────────────────────────────┤ +│ Main Content (flex row) │ +│ ├─ Document Pane (flex 1) │ +│ │ └─ Markdown editor/viewer │ +│ └─ Chat Pane (resizable, 380px default) │ +│ └─ Chat messages + input │ +├─────────────────────────────────────────────────────┤ +│ Action Bar: Review/Submit buttons, tokens, settings │ +└─────────────────────────────────────────────────────┘ +``` + +### Key Components +- **App.tsx**: Root container, manages projects/sessions/messages state, subscription to Claude messages +- **Header.tsx**: Project & session selection (dropdowns + buttons), phase indicator, theme toggle +- **DocumentPane.tsx**: CodeMirror markdown editor in edit mode, react-markdown renderer in view mode +- **ChatPane.tsx**: Message history, input field, collapsible (stored width in localStorage) +- **ActionBar.tsx**: Review button (research/plan phases), Submit button, token usage bar, permission mode toggle + +### State Management +App.tsx owns all state. Key state variables: +- `selectedProject` / `selectedSession` — current context +- `loadingBySession[sessionId]` — per-session loading flag (tracks thinking state) +- `activityBySession[sessionId]` — per-session activity status text (e.g., "Using Bash (5s)") +- `viewPhase` — which artifact to display (research/plan, defaults to current phase) +- `chatWidth` / `chatCollapsed` — layout preferences (persisted to localStorage) +- `theme` — "dark" or "light" (persisted to localStorage) + +### Per-Session Activity Tracking +App subscribes to `api.onClaudeMessage()` which broadcasts all Claude SDK messages to all sessions. App updates `loadingBySession` and `activityBySession` dictionaries to track which sessions are currently processing. This allows switching between projects/sessions without losing the thinking indicator state. + +### UI Patterns & Conventions + +#### Modal/Overlay Pattern +Full-page overlays (e.g., SettingsPage) use this pattern: +```tsx +
+
+ {/* Header with close button */} +
+
+ {/* Content */} +
+
+``` + +When building new modal UI: +- Use `.settings-overlay` (or similar) class for backdrop + positioning +- Include a close button with `className="settings-close"` +- Keep header style consistent with app header height/styling +- For simple modals (not full-page), consider a centered dialog box instead + +#### Form Pattern +Settings sections use input/select fields. Standard patterns: +- Label + input field pairs +- Button groups for related actions +- Consistent spacing via CSS grid/flex +- Validation feedback via inline text or error states + +#### List/Tree Pattern +Sidebar demonstrates tree structure for hierarchical data: +- Parent items with click handlers and action buttons +- Nested items with indent/visual hierarchy +- Inline edit mode for renaming (Rename modal not needed) +- Context awareness (expanded/collapsed states) + ## Important Notes - `ANTHROPIC_API_KEY` env var must be set before launching @@ -61,3 +134,15 @@ Schema migrations: `db/index.ts::getDb()` calls `initSchema()` which uses `CREAT - `bypassPermissions` mode is a user-controlled toggle in implement phase only - Token usage (from `SDKResultMessage.usage`) is displayed in the ActionBar - No git library in dependencies — use Node.js `child_process` (built-in) for git operations +- Session rename auto-triggers when research phase completes if session name is default "Session N" format (extracts first sentence from research.md) + +## Extensibility Notes for UI Features + +When adding new UI features that require user input: + +1. **Modal dialogs**: Follow the SettingsPage pattern (full-page overlay with header/body) +2. **Inline editing**: Use sidebar pattern (inline input that commits on blur/Enter) +3. **Phase selection**: Phase column in DB already exists and accepts any value—no schema changes needed to support starting at different phases +4. **Settings additions**: Add to `SettingsPage.tsx` with a new section and corresponding settings UI file in `/components/settings/` +5. **IPC endpoints**: Register in `/src/main/ipc/handlers.ts` and expose in `/src/main/preload.ts` +6. **State management**: Keep state in `App.tsx` for global UI state; component local state for transient UI state (e.g., modal visibility, form input) -- cgit v1.2.3