diff options
| -rw-r--r-- | CLAUDE.md | 55 | ||||
| -rw-r--r-- | renderer/src/App.tsx | 24 |
2 files changed, 79 insertions, 0 deletions
| @@ -127,6 +127,59 @@ Sidebar demonstrates tree structure for hierarchical data: | |||
| 127 | - Inline edit mode for renaming (Rename modal not needed) | 127 | - Inline edit mode for renaming (Rename modal not needed) |
| 128 | - Context awareness (expanded/collapsed states) | 128 | - Context awareness (expanded/collapsed states) |
| 129 | 129 | ||
| 130 | ## Known Bugs | ||
| 131 | |||
| 132 | ### Phase Handling Issues (Critical) | ||
| 133 | |||
| 134 | #### Bug #1: New Session Phase Modal Doesn't Apply Selection | ||
| 135 | **Status**: Needs debugging | ||
| 136 | **Description**: When creating a new session and selecting "Implementation" in the phase modal, the session is created with "Research" phase instead of the selected phase. | ||
| 137 | |||
| 138 | **Key Discovery**: The system prompt is determined directly by `session.phase` (src/main/claude/index.ts lines 49, 91, 120). | ||
| 139 | - If you create an "Implement" session but Claude receives the **Research system prompt**, it PROVES the session.phase is stored as "research" in the database | ||
| 140 | - This is the smoking gun that reveals Bug #1 is in the **data layer**, not the display | ||
| 141 | |||
| 142 | **Observable symptom**: Create an "Implement" session and send a message. If Claude says "I am in RESEARCH mode" (contains "DO NOT modify any source code files"), the phase is wrong. If Claude says "I am in IMPLEMENTATION mode" (contains "Mark tasks complete"), the phase is correct. | ||
| 143 | |||
| 144 | **Code path**: NewSessionModal → App.handleConfirmNewSession → api.createSession → IPC handler → createSession function → DB INSERT | ||
| 145 | |||
| 146 | **Suspected issue**: Phase parameter may be lost or reset during IPC transmission, despite code appearing correct. The IPC handler receives `phase?: Phase` as optional parameter which defaults to "research" in createSession(). | ||
| 147 | |||
| 148 | **To debug**: | ||
| 149 | 1. Add console.log in NewSessionModal to confirm selected state | ||
| 150 | 2. Add console.log in App.handleConfirmNewSession to confirm phase parameter | ||
| 151 | 3. Add console.log in IPC handler to confirm phase is received | ||
| 152 | 4. Check database directly: `SELECT phase FROM sessions WHERE ... LIMIT 1` | ||
| 153 | 5. Check what system prompt Claude actually receives (see observable symptom above) | ||
| 154 | |||
| 155 | **Related files**: | ||
| 156 | - `renderer/src/components/NewSessionModal.tsx` (phase selection) | ||
| 157 | - `src/main/preload.ts` (API bridge - lines 89-90) | ||
| 158 | - `src/main/ipc/handlers.ts` (IPC handler - lines 26-37) | ||
| 159 | - `src/main/db/sessions.ts` (createSession function - line 39) | ||
| 160 | - `src/main/claude/index.ts` (system prompt application - lines 49, 91, 120) | ||
| 161 | |||
| 162 | #### Bug #2: Phase Transition State Not Synced + plan.md Not Rendering | ||
| 163 | **Status**: Root cause identified ✓ | ||
| 164 | **Description**: After completing research phase and submitting, the plan phase doesn't show as active in the Sidebar, and plan.md doesn't display (only shows after Claude writes to it). | ||
| 165 | |||
| 166 | **Root cause**: The `sessions` array state in App.tsx is never updated after `advancePhase()` completes. Only `selectedSession` is updated. This causes: | ||
| 167 | 1. **Sidebar inconsistency**: Shows old phase (session object from stale sessions array) | ||
| 168 | 2. **Header is correct**: Shows new phase (uses selectedSession.phase) | ||
| 169 | 3. **plan.md might initially be blank**: Loads before Claude writes it (expected, but confusing) | ||
| 170 | |||
| 171 | **The fix**: In `App.tsx` handleSubmit(), after successful advancePhase, also update the sessions array: | ||
| 172 | ```typescript | ||
| 173 | setSessions((prev) => | ||
| 174 | prev.map((s) => (s.id === id ? { ...s, phase: advanced.phase, git_branch: advanced.git_branch } : s)) | ||
| 175 | ); | ||
| 176 | ``` | ||
| 177 | |||
| 178 | **Related files**: | ||
| 179 | - `renderer/src/App.tsx` (lines 419-446, handleSubmit function) | ||
| 180 | - `renderer/src/components/Sidebar.tsx` (line 194, displays phase from sessions array) | ||
| 181 | - `renderer/src/components/Header.tsx` (displays phase from selectedSession - works correctly) | ||
| 182 | |||
| 130 | ## Important Notes | 183 | ## Important Notes |
| 131 | 184 | ||
| 132 | - `ANTHROPIC_API_KEY` env var must be set before launching | 185 | - `ANTHROPIC_API_KEY` env var must be set before launching |
| @@ -146,3 +199,5 @@ When adding new UI features that require user input: | |||
| 146 | 4. **Settings additions**: Add to `SettingsPage.tsx` with a new section and corresponding settings UI file in `/components/settings/` | 199 | 4. **Settings additions**: Add to `SettingsPage.tsx` with a new section and corresponding settings UI file in `/components/settings/` |
| 147 | 5. **IPC endpoints**: Register in `/src/main/ipc/handlers.ts` and expose in `/src/main/preload.ts` | 200 | 5. **IPC endpoints**: Register in `/src/main/ipc/handlers.ts` and expose in `/src/main/preload.ts` |
| 148 | 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) | 201 | 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) |
| 202 | |||
| 203 | **State sync pattern**: When updating sessions in bulk operations (like phase transitions), remember to update BOTH `selectedSession` AND `sessions` array to keep UI consistent across all components. | ||
diff --git a/renderer/src/App.tsx b/renderer/src/App.tsx index 7c5c969..5fb3dd1 100644 --- a/renderer/src/App.tsx +++ b/renderer/src/App.tsx | |||
| @@ -432,6 +432,14 @@ export function App() { | |||
| 432 | phase: advanced.phase, | 432 | phase: advanced.phase, |
| 433 | git_branch: advanced.git_branch, | 433 | git_branch: advanced.git_branch, |
| 434 | }); | 434 | }); |
| 435 | // Keep sessions array in sync so Sidebar reflects the new phase immediately. | ||
| 436 | setSessions((prev) => | ||
| 437 | prev.map((s) => | ||
| 438 | s.id === id | ||
| 439 | ? { ...s, phase: advanced.phase, git_branch: advanced.git_branch } | ||
| 440 | : s | ||
| 441 | ) | ||
| 442 | ); | ||
| 435 | setLoadingBySession((prev) => ({ ...prev, [id]: true })); | 443 | setLoadingBySession((prev) => ({ ...prev, [id]: true })); |
| 436 | const initialMsg = | 444 | const initialMsg = |
| 437 | advanced.phase === "plan" | 445 | advanced.phase === "plan" |
| @@ -479,6 +487,22 @@ export function App() { | |||
| 479 | setMessages([]); | 487 | setMessages([]); |
| 480 | setDocumentContent(""); | 488 | setDocumentContent(""); |
| 481 | setOriginalContent(""); | 489 | setOriginalContent(""); |
| 490 | |||
| 491 | // For sessions that start beyond research, kick off Claude immediately | ||
| 492 | // with the same message used when advancing into that phase via Submit. | ||
| 493 | if (phase === "plan" || phase === "implement") { | ||
| 494 | const initialMsg = | ||
| 495 | phase === "plan" | ||
| 496 | ? "Create a detailed implementation plan based on the research." | ||
| 497 | : "Begin implementing the plan."; | ||
| 498 | setLoadingBySession((prev) => ({ ...prev, [session.id]: true })); | ||
| 499 | try { | ||
| 500 | await api.sendMessage(session.id, initialMsg); | ||
| 501 | } catch (err) { | ||
| 502 | setError(err instanceof Error ? err.message : "Failed to start session"); | ||
| 503 | setLoadingBySession((prev) => ({ ...prev, [session.id]: false })); | ||
| 504 | } | ||
| 505 | } | ||
| 482 | }; | 506 | }; |
| 483 | 507 | ||
| 484 | const handleDeleteProject = async (id: string) => { | 508 | const handleDeleteProject = async (id: string) => { |
