@@ -20,6 +20,7 @@ import {
2020 formatAskUserQuestionAnswers ,
2121} from "../core/ask-user-question" ;
2222import { PermissionPrompt , type PermissionPromptResult } from "./PermissionPrompt" ;
23+ import { PlanImplementationPrompt , extractProposedPlan , getImplementationPrompt } from "./PlanImplementationPrompt" ;
2324import { buildExitSummaryText , buildResumeHintText } from "../exit-summary" ;
2425import { RawMode , useRawModeContext } from "../contexts" ;
2526import { renderMessageToStdout } from "../components/MessageView/utils" ;
@@ -133,6 +134,8 @@ function App({ projectRoot, initialPrompt, resumeSessionId, onRestart }: AppProp
133134 const [ nowTick , setNowTick ] = useState ( 0 ) ;
134135 const [ mcpStatuses , setMcpStatuses ] = useState < ReturnType < typeof sessionManager . getMcpStatus > > ( [ ] ) ;
135136 const [ showProcessStdout , setShowProcessStdout ] = useState ( false ) ;
137+ const [ planMode , setPlanMode ] = useState ( false ) ;
138+ const [ pendingPlanImplementation , setPendingPlanImplementation ] = useState < string | null > ( null ) ;
136139
137140 rawModeRef . current = mode ;
138141 messagesRef . current = messages ;
@@ -253,6 +256,8 @@ function App({ projectRoot, initialPrompt, resumeSessionId, onRestart }: AppProp
253256 setActiveStatus ( null ) ;
254257 setActiveAskPermissions ( undefined ) ;
255258 setPendingPermissionReply ( null ) ;
259+ setPlanMode ( false ) ;
260+ setPendingPlanImplementation ( null ) ;
256261 setDismissedQuestionIds ( new Set ( ) ) ;
257262 await resetStaticView ( [ ] ) ;
258263 await refreshSkills ( ) ;
@@ -369,6 +374,7 @@ function App({ projectRoot, initialPrompt, resumeSessionId, onRestart }: AppProp
369374 submission . selectedSkills && submission . selectedSkills . length > 0 ? submission . selectedSkills : undefined ,
370375 permissions : submission . permissions ,
371376 alwaysAllows : submission . alwaysAllows ,
377+ planMode : submission . planMode ?? planMode ,
372378 } ;
373379 const activeSessionId = sessionManager . getActiveSessionId ( ) ;
374380 const permissionReply =
@@ -404,6 +410,12 @@ function App({ projectRoot, initialPrompt, resumeSessionId, onRestart }: AppProp
404410 }
405411 await refreshSkills ( ) ;
406412 refreshSessionsList ( ) ;
413+ const completedSession = sessionManager . getSession ( sessionManager . getActiveSessionId ( ) ?? "" ) ;
414+ const proposedPlan =
415+ prompt . planMode && completedSession ?. status === "completed"
416+ ? extractProposedPlan ( completedSession . assistantReply )
417+ : null ;
418+ setPendingPlanImplementation ( proposedPlan ) ;
407419 } catch ( error ) {
408420 const message = error instanceof Error ? error . message : String ( error ) ;
409421 setErrorLine ( message ) ;
@@ -425,6 +437,7 @@ function App({ projectRoot, initialPrompt, resumeSessionId, onRestart }: AppProp
425437 refreshSessionsList ,
426438 navigateToSubView ,
427439 resetToWelcome ,
440+ planMode ,
428441 ]
429442 ) ;
430443
@@ -496,6 +509,25 @@ function App({ projectRoot, initialPrompt, resumeSessionId, onRestart }: AppProp
496509 [ handlePrompt ]
497510 ) ;
498511
512+ const handlePlanImplementationChoice = useCallback (
513+ ( choice : "implement" | "stay" | "default" ) => {
514+ const proposedPlan = pendingPlanImplementation ;
515+ setPendingPlanImplementation ( null ) ;
516+ if ( choice === "stay" ) {
517+ return ;
518+ }
519+ setPlanMode ( false ) ;
520+ if ( choice === "implement" && proposedPlan ) {
521+ handleSubmit ( {
522+ text : getImplementationPrompt ( proposedPlan ) ,
523+ imageUrls : [ ] ,
524+ planMode : false ,
525+ } ) ;
526+ }
527+ } ,
528+ [ handleSubmit , pendingPlanImplementation ]
529+ ) ;
530+
499531 const handleExitShortcut = useCallback ( ( ) => {
500532 handleExit ( { showCommand : false , showSummary : false } ) ;
501533 } , [ handleExit ] ) ;
@@ -517,6 +549,8 @@ function App({ projectRoot, initialPrompt, resumeSessionId, onRestart }: AppProp
517549 setRunningProcesses ( session ?. processes ?? null ) ;
518550 setActiveStatus ( session ?. status ?? null ) ;
519551 setActiveAskPermissions ( session ?. askPermissions ) ;
552+ setPlanMode ( session ?. planMode === true ) ;
553+ setPendingPlanImplementation ( null ) ;
520554 if ( pendingPermissionReply && pendingPermissionReply . sessionId !== sessionId ) {
521555 setPendingPermissionReply ( null ) ;
522556 }
@@ -965,6 +999,8 @@ function App({ projectRoot, initialPrompt, resumeSessionId, onRestart }: AppProp
965999 onSubmit = { handlePermissionResult }
9661000 onCancel = { handlePermissionCancel }
9671001 />
1002+ ) : pendingPlanImplementation && ! busy ? (
1003+ < PlanImplementationPrompt onSelect = { handlePlanImplementationChoice } />
9681004 ) : isExiting ? null : (
9691005 < PromptInput
9701006 projectRoot = { projectRoot }
@@ -986,6 +1022,8 @@ function App({ projectRoot, initialPrompt, resumeSessionId, onRestart }: AppProp
9861022 placeholder = "Type your message..."
9871023 statusLineSegments = { statusLineSegments }
9881024 statusLineSeparator = { resolvedSettings . statusline . separator }
1025+ planMode = { planMode }
1026+ onPlanModeChange = { setPlanMode }
9891027 />
9901028 ) }
9911029 </ Box >
0 commit comments