aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CLAUDE.md55
-rw-r--r--renderer/src/App.tsx24
2 files changed, 79 insertions, 0 deletions
diff --git a/CLAUDE.md b/CLAUDE.md
index 5d25656..134a510 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -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**:
1491. Add console.log in NewSessionModal to confirm selected state
1502. Add console.log in App.handleConfirmNewSession to confirm phase parameter
1513. Add console.log in IPC handler to confirm phase is received
1524. Check database directly: `SELECT phase FROM sessions WHERE ... LIMIT 1`
1535. 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:
1671. **Sidebar inconsistency**: Shows old phase (session object from stale sessions array)
1682. **Header is correct**: Shows new phase (uses selectedSession.phase)
1693. **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
173setSessions((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:
1464. **Settings additions**: Add to `SettingsPage.tsx` with a new section and corresponding settings UI file in `/components/settings/` 1994. **Settings additions**: Add to `SettingsPage.tsx` with a new section and corresponding settings UI file in `/components/settings/`
1475. **IPC endpoints**: Register in `/src/main/ipc/handlers.ts` and expose in `/src/main/preload.ts` 2005. **IPC endpoints**: Register in `/src/main/ipc/handlers.ts` and expose in `/src/main/preload.ts`
1486. **State management**: Keep state in `App.tsx` for global UI state; component local state for transient UI state (e.g., modal visibility, form input) 2016. **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) => {