From 1ffd20263ec2544ad99a2c31b74ee7d18ea1ae63 Mon Sep 17 00:00:00 2001 From: Fusion Agent Date: Fri, 28 Aug 2026 04:06:34 +0000 Subject: [PATCH] FN-210: show initiating prompt in Planning Mode history Expose the prompt that started a Planning Mode session wherever its history is reviewed. - Add a reusable read-only PlanningSessionPrompt display for history, errors, and plan-review Q&A. - Integrate prompt rendering and responsive styling into PlanningModeModal. - Document the Planning Mode history behavior and add a minor release changeset. - Cover populated, missing, long, and responsive prompt states with dashboard tests. Files changed: .changeset/fn-210-planning-session-prompt.md | 7 + docs/dashboard-guide.md | 3 + .../dashboard/app/components/PlanningModeModal.css | 9 + .../dashboard/app/components/PlanningModeModal.tsx | 26 +- .../app/components/PlanningSessionPrompt.css | 29 +++ .../app/components/PlanningSessionPrompt.tsx | 37 +++ .../PlanningModeModal.session-prompt.test.tsx | 280 +++++++++++++++++++++ .../__tests__/PlanningSessionPrompt.test.tsx | 48 +++ 8 files changed, 435 insertions(+), 4 deletions(-) Fusion-Task-Id: FN-210 Fusion-Task-Lineage: 08201db3-7b1b-4567-95e0-1e97dc3a7ae6 Co-authored-by: Fusion --- .changeset/fn-210-planning-session-prompt.md | 7 + docs/dashboard-guide.md | 3 + .../app/components/PlanningModeModal.css | 9 + .../app/components/PlanningModeModal.tsx | 26 +- .../app/components/PlanningSessionPrompt.css | 29 ++ .../app/components/PlanningSessionPrompt.tsx | 37 +++ .../PlanningModeModal.session-prompt.test.tsx | 280 ++++++++++++++++++ .../__tests__/PlanningSessionPrompt.test.tsx | 48 +++ 8 files changed, 435 insertions(+), 4 deletions(-) create mode 100644 .changeset/fn-210-planning-session-prompt.md create mode 100644 packages/dashboard/app/components/PlanningSessionPrompt.css create mode 100644 packages/dashboard/app/components/PlanningSessionPrompt.tsx create mode 100644 packages/dashboard/app/components/__tests__/PlanningModeModal.session-prompt.test.tsx create mode 100644 packages/dashboard/app/components/__tests__/PlanningSessionPrompt.test.tsx diff --git a/.changeset/fn-210-planning-session-prompt.md b/.changeset/fn-210-planning-session-prompt.md new file mode 100644 index 0000000000..687c64d351 --- /dev/null +++ b/.changeset/fn-210-planning-session-prompt.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": minor +--- + +summary: Planning Mode history now shows the original prompt that started the session, read-only. +category: feature +dev: Adds PlanningSessionPrompt to History, error, and plan-review Q&A surfaces. diff --git a/docs/dashboard-guide.md b/docs/dashboard-guide.md index e2e626e9e0..2d889f9cff 100644 --- a/docs/dashboard-guide.md +++ b/docs/dashboard-guide.md @@ -683,6 +683,9 @@ When an active Planning AI generation appears stuck, Planning Mode automatically Use **New session** to restart planning with a different idea. + +The **History** panel, the error panel, and plan review's **Show user Q&A** section show the original request that started the session in a read-only box above the questions and answers. Reading, scrolling, selecting, or copying this text does not edit it or change the session. When an older or incomplete session has no saved starting text, Planning Mode omits the box entirely. + Planning Mode uses a dedicated collaborative system prompt. It investigates relevant repository and board context, explores assumptions and tradeoffs, considers decomposition choices without automatically creating child tasks, and sharpens concrete deliverables with observable acceptance criteria. This is separate from task triage and the executor-ready **PROMPT.md** generated after task creation. An explicitly configured nonblank `planning-system` prompt override replaces the complete dedicated system prompt; blank or absent values retain the default interview. diff --git a/packages/dashboard/app/components/PlanningModeModal.css b/packages/dashboard/app/components/PlanningModeModal.css index 4e0edab906..2eba685cb7 100644 --- a/packages/dashboard/app/components/PlanningModeModal.css +++ b/packages/dashboard/app/components/PlanningModeModal.css @@ -248,6 +248,10 @@ The embedded planning header must be a visual SIBLING of MissionManager's inline overscroll-behavior: contain; } +.planning-history-scroll .planning-session-prompt { + margin-bottom: var(--space-lg); +} + .planning-history-scroll .conversation-history { max-height: none; margin: 0; @@ -2338,6 +2342,11 @@ mobile and desktop offer the same View task / Return to sessions choices. padding: var(--space-lg); } + .planning-history-scroll .planning-session-prompt { + width: 100%; + max-width: 100%; + } + /* FNXC:PlanningMode 2026-07-21-18:34: Mobile question and plan-review panes were double-inset: workspace gutter + scroll padding + nested card chrome on top of the pane frame. Drop the outer gutter and pane chrome so content sits flush edge-to-edge like desktop, keep a light tab strip inset, and leave readable content padding on the question panel / plan document only. Clear the desktop column divider so a solo question/plan card is not edged by a right border. diff --git a/packages/dashboard/app/components/PlanningModeModal.tsx b/packages/dashboard/app/components/PlanningModeModal.tsx index ee8a26036e..7fe435d149 100644 --- a/packages/dashboard/app/components/PlanningModeModal.tsx +++ b/packages/dashboard/app/components/PlanningModeModal.tsx @@ -56,6 +56,7 @@ import { getRelativeTimeBucket } from "../utils/relativeTimeAgo"; import { Lightbulb, X, Loader2, CheckCircle, ArrowLeft, ArrowRight, Sparkles, Trash2, RefreshCw, ChevronLeft, MessageSquarePlus, AlertCircle, Clock, HelpCircle, StopCircle, Archive, ArchiveRestore, Pencil, History } from "lucide-react"; import { CustomModelDropdown } from "./CustomModelDropdown"; import { ConversationHistory } from "./ConversationHistory"; +import { PlanningSessionPrompt } from "./PlanningSessionPrompt"; import { ThinkingTrace } from "./ThinkingTrace"; import { MailboxMessageContent } from "./MailboxMessageContent"; import { OnboardingDisclosure } from "./OnboardingDisclosure"; @@ -445,8 +446,11 @@ export function PlanningModeModal({ isOpen, onClose, onTaskCreated, onTasksCreat /* FNXC:Planning 2026-07-15-00:00: FN-8003 keeps the started prompt separate from the editable composer so users can recover the original idea when an interview errors or drifts off track. The composer may be reset or reused, but this value belongs only to the active session. + + FNXC:PlanningHistory 2026-08-28-03:34: + FN-210 renders the active session's initiating prompt read-only wherever Planning Mode presents its question-and-answer history. */ - const [_activePlanPrompt, setActivePlanPrompt] = useState(""); + const [activePlanPrompt, setActivePlanPrompt] = useState(""); const [view, setView] = useState({ type: "initial" }); const [error, setError] = useState(null); // FNXC:PlanningMultiTask 2026-08-03-18:32: Latest task created from this plan. Passing its id with the next explicit Proceed action @@ -2003,12 +2007,20 @@ export function PlanningModeModal({ isOpen, onClose, onTaskCreated, onTasksCreat typed or selected local answer before its enabled Next action can submit it. A different session still takes the neutral loader so its prior turn never remains visible. */ - const preservesActiveWorkspace = currentSessionIdRef.current === sessionId + const isDifferentSession = currentSessionIdRef.current !== sessionId; + const preservesActiveWorkspace = !isDifferentSession && (viewRef.current.type === "question" || viewRef.current.type === "plan_review"); streamConnectionRef.current?.close(); streamConnectionRef.current = null; currentSessionIdRef.current = sessionId; + /* + FNXC:PlanningHistory 2026-08-28-03:47: + The History overlay remains mounted while an externally selected session loads. Clear the + initiating prompt at a different-session load boundary so the prior session's prompt cannot + appear under the new selection, while same-session refreshes retain their visible prompt. + */ + if (isDifferentSession) setActivePlanPrompt(""); setError(null); /* FNXC:PlanningMultiTask 2026-07-24-01:40: @@ -2988,10 +3000,10 @@ export function PlanningModeModal({ isOpen, onClose, onTaskCreated, onTasksCreat }); } else { draftSessionIdRef.current = sessionId; - setInitialPlan(_activePlanPrompt); + setInitialPlan(activePlanPrompt); setView({ type: "initial" }); } - }, [_activePlanPrompt, projectId, workspaceQuestion]); + }, [activePlanPrompt, projectId, workspaceQuestion]); const handleRetryFromError = useCallback(async () => { if (view.type !== "error") { @@ -3685,6 +3697,7 @@ export function PlanningModeModal({ isOpen, onClose, onTaskCreated, onTasksCreat
+ {historyPanelEntries.length > 0 ? ( // FNXC:PlanningHistory 2026-07-20-23:24: FN-8449 keeps history thinking collapsed so operators can scan Q&A first; the existing toggle remains available to expand it, matching the FN-7974 chat default. @@ -3979,6 +3992,7 @@ export function PlanningModeModal({ isOpen, onClose, onTaskCreated, onTasksCreat {view.type === "error" && (
+ {conversationHistory.length > 0 && ( <> @@ -4225,6 +4239,7 @@ export function PlanningModeModal({ isOpen, onClose, onTaskCreated, onTasksCreat projectId={projectId} summary={editedSummary} historyEntries={conversationHistory} + initialPrompt={activePlanPrompt} onSummaryChange={setEditedSummary} tasks={tasks} branchMode={branchMode} @@ -4664,6 +4679,7 @@ interface SummaryViewProps { projectId?: string; summary: PlanningSummary; historyEntries: ConversationHistoryEntry[]; + initialPrompt?: string; onSummaryChange: (summary: PlanningSummary) => void; tasks: Task[]; branchMode: "project-default" | "auto-new" | "existing" | "custom-new"; @@ -4684,6 +4700,7 @@ export function SummaryView({ projectId, summary: rawSummary, historyEntries, + initialPrompt, onSummaryChange, tasks, branchMode, @@ -4743,6 +4760,7 @@ export function SummaryView({
{historyEntries.length > 0 && ( +
diff --git a/packages/dashboard/app/components/PlanningSessionPrompt.css b/packages/dashboard/app/components/PlanningSessionPrompt.css new file mode 100644 index 0000000000..e7e4bffcf6 --- /dev/null +++ b/packages/dashboard/app/components/PlanningSessionPrompt.css @@ -0,0 +1,29 @@ +.planning-session-prompt { + display: flex; + flex-direction: column; + gap: var(--space-sm); + min-width: 0; +} + +.planning-session-prompt-label { + color: var(--text-muted); + font-size: var(--font-size-sm); + font-weight: 600; +} + +.planning-session-prompt-text { + box-sizing: border-box; + width: 100%; + min-width: 0; + padding: var(--space-md); + border: solid var(--btn-border-width) color-mix(in srgb, var(--border) 82%, transparent); + border-radius: var(--radius-lg); + background: var(--card); + color: var(--text); + font: inherit; + line-height: 1.5; + white-space: pre-wrap; + overflow-y: auto; + resize: none; + cursor: default; +} diff --git a/packages/dashboard/app/components/PlanningSessionPrompt.tsx b/packages/dashboard/app/components/PlanningSessionPrompt.tsx new file mode 100644 index 0000000000..fe3a6931d0 --- /dev/null +++ b/packages/dashboard/app/components/PlanningSessionPrompt.tsx @@ -0,0 +1,37 @@ +import "./PlanningSessionPrompt.css"; +import { useTranslation } from "react-i18next"; +import { useAutosizeTextarea } from "../hooks/useAutosizeTextarea"; + +interface PlanningSessionPromptProps { + prompt?: string; + testId: string; +} + +/** + * FNXC:PlanningHistory 2026-08-28-03:34: + * Planning Mode session history shows the operator's initiating prompt read-only next to the Q&A. Sessions without a saved prompt render nothing instead of leaving an empty history shell. + */ +export function PlanningSessionPrompt({ prompt, testId }: PlanningSessionPromptProps) { + const { t } = useTranslation("app"); + const { ref } = useAutosizeTextarea({ value: prompt ?? "", minHeight: 64, maxHeight: 240 }); + + if (!prompt?.trim()) { + return null; + } + + const label = t("planning.initialPromptLabel", "Prompt that started this session"); + + return ( +
+ {label} +