fix(dashboard): stop the planning textarea from reverting to the persisted description on every keystroke

The "restore description from localStorage" branch ran inside an effect
whose deps included handleStartPlanning, and that callback regenerated on
every change to initialPlan. So every keystroke would re-fire the effect,
hit the same `getPlanningDescription` value, and overwrite what the user
just typed.

Guard the restore with a one-shot ref so it only runs the first time the
modal opens, and reset the ref when the modal closes so a future re-open
still picks up an updated persisted value.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-04-25 11:01:36 -07:00
parent 56e0860da1
commit 54bc60bb8a

View File

@@ -96,6 +96,7 @@ export function PlanningModeModal({ isOpen, onClose, onTaskCreated, onTasksCreat
// which would skip auto-start on the second (committed) render. Refs are
// re-initialized on each render, ensuring the auto-start effect runs correctly.
const hasAutoStartedRef = useRef(false);
const hasLoadedPersistedRef = useRef(false);
const [streamingOutput, setStreamingOutput] = useState<string>("");
const [showThinking, setShowThinking] = useState(true);
const [isReconnecting, setIsReconnecting] = useState(false);
@@ -369,14 +370,24 @@ export function PlanningModeModal({ isOpen, onClose, onTaskCreated, onTasksCreat
handleStartPlanning(initialPlanProp);
}, 0);
return () => clearTimeout(timer);
} else if (isOpen && !initialPlanProp && !hasAutoStartedRef.current && view.type === "initial") {
// Check localStorage for persisted description when no prop provided
} else if (
isOpen &&
!initialPlanProp &&
!hasAutoStartedRef.current &&
!hasLoadedPersistedRef.current &&
view.type === "initial"
) {
// Restore the persisted description from localStorage on first open only.
// Without the ref this effect re-fires on every keystroke (handleStart-
// Planning depends on initialPlan), and each fire would clobber what
// the user just typed back to the persisted value.
hasLoadedPersistedRef.current = true;
const persisted = getPlanningDescription(projectId);
if (persisted) {
setInitialPlan(persisted);
}
}
}, [isOpen, initialPlanProp, view.type, handleStartPlanning]);
}, [isOpen, initialPlanProp, view.type, handleStartPlanning, projectId]);
// Resume a persisted background session
useEffect(() => {
@@ -435,6 +446,7 @@ export function PlanningModeModal({ isOpen, onClose, onTaskCreated, onTasksCreat
useEffect(() => {
if (!isOpen) {
hasAutoStartedRef.current = false;
hasLoadedPersistedRef.current = false;
setIsReconnecting(false);
setIsRetrying(false);
setLockSessionId(null);