| author | |
| committer | |
| log | cf2c628bc005f3c88911a6fcb957f56e6d1ce45f |
| tree | c5189d8bb42ce42acf441b6a6ba5cc9ed3d944b9 |
| parent | e0874b651d5c5fa5c578be932aada627b95c3f52 |
| signature | Signed by PGP key B5690EEEBB952194 |
2 files changed, 52 insertions(+), 2 deletions(-)
apps/web/src/components/ChatView.browser.tsx+49| ... | @@ -2818,6 +2818,55 @@ describe("ChatView timeline estimator parity (full app)", () => { | ... | @@ -2818,6 +2818,55 @@ describe("ChatView timeline estimator parity (full app)", () => { |
| 2818 | } | 2818 | } |
| 2819 | }); | 2819 | }); |
| 2820 | 2820 | ||
| 2821 | it("uses the active worktree path when saving a proposed plan to the workspace", async () => { | ||
| 2822 | const snapshot = createSnapshotWithLongProposedPlan(); | ||
| 2823 | const threads = snapshot.threads.slice(); | ||
| 2824 | const targetThreadIndex = threads.findIndex((thread) => thread.id === THREAD_ID); | ||
| 2825 | const targetThread = targetThreadIndex >= 0 ? threads[targetThreadIndex] : undefined; | ||
| 2826 | if (targetThread) { | ||
| 2827 | threads[targetThreadIndex] = { | ||
| 2828 | ...targetThread, | ||
| 2829 | worktreePath: "/repo/worktrees/plan-thread", | ||
| 2830 | }; | ||
| 2831 | } | ||
| 2832 | |||
| 2833 | const mounted = await mountChatView({ | ||
| 2834 | viewport: DEFAULT_VIEWPORT, | ||
| 2835 | snapshot: { | ||
| 2836 | ...snapshot, | ||
| 2837 | threads, | ||
| 2838 | }, | ||
| 2839 | }); | ||
| 2840 | |||
| 2841 | try { | ||
| 2842 | const planActionsButton = await waitForElement( | ||
| 2843 | () => document.querySelector<HTMLButtonElement>('button[aria-label="Plan actions"]'), | ||
| 2844 | "Unable to find proposed plan actions button.", | ||
| 2845 | ); | ||
| 2846 | planActionsButton.click(); | ||
| 2847 | |||
| 2848 | const saveToWorkspaceItem = await waitForElement( | ||
| 2849 | () => | ||
| 2850 | (Array.from(document.querySelectorAll('[data-slot="menu-item"]')).find( | ||
| 2851 | (item) => item.textContent?.trim() === "Save to workspace", | ||
| 2852 | ) ?? null) as HTMLElement | null, | ||
| 2853 | 'Unable to find "Save to workspace" menu item.', | ||
| 2854 | ); | ||
| 2855 | saveToWorkspaceItem.click(); | ||
| 2856 | |||
| 2857 | await vi.waitFor( | ||
| 2858 | () => { | ||
| 2859 | expect(document.body.textContent).toContain( | ||
| 2860 | "Enter a path relative to /repo/worktrees/plan-thread.", | ||
| 2861 | ); | ||
| 2862 | }, | ||
| 2863 | { timeout: 8_000, interval: 16 }, | ||
| 2864 | ); | ||
| 2865 | } finally { | ||
| 2866 | await mounted.cleanup(); | ||
| 2867 | } | ||
| 2868 | }); | ||
| 2869 | |||
| 2821 | it("keeps pending-question footer actions inside the composer after a real resize", async () => { | 2870 | it("keeps pending-question footer actions inside the composer after a real resize", async () => { |
| 2822 | const mounted = await mountChatView({ | 2871 | const mounted = await mountChatView({ |
| 2823 | viewport: WIDE_FOOTER_VIEWPORT, | 2872 | viewport: WIDE_FOOTER_VIEWPORT, |
apps/web/src/components/ChatView.tsx+3-2| ... | @@ -1526,6 +1526,7 @@ export default function ChatView({ threadId }: ChatViewProps) { | ... | @@ -1526,6 +1526,7 @@ export default function ChatView({ threadId }: ChatViewProps) { |
| 1526 | ); | 1526 | ); |
| 1527 | const activeProjectCwd = activeProject?.cwd ?? null; | 1527 | const activeProjectCwd = activeProject?.cwd ?? null; |
| 1528 | const activeThreadWorktreePath = activeThread?.worktreePath ?? null; | 1528 | const activeThreadWorktreePath = activeThread?.worktreePath ?? null; |
| 1529 | const activeWorkspaceRoot = activeThreadWorktreePath ?? activeProjectCwd ?? undefined; | ||
| 1529 | const activeTerminalLaunchContext = | 1530 | const activeTerminalLaunchContext = |
| 1530 | terminalLaunchContext?.threadId === activeThreadId | 1531 | terminalLaunchContext?.threadId === activeThreadId |
| 1531 | ? terminalLaunchContext | 1532 | ? terminalLaunchContext |
| ... | @@ -4004,7 +4005,7 @@ export default function ChatView({ threadId }: ChatViewProps) { | ... | @@ -4004,7 +4005,7 @@ export default function ChatView({ threadId }: ChatViewProps) { |
| 4004 | markdownCwd={gitCwd ?? undefined} | 4005 | markdownCwd={gitCwd ?? undefined} |
| 4005 | resolvedTheme={resolvedTheme} | 4006 | resolvedTheme={resolvedTheme} |
| 4006 | timestampFormat={timestampFormat} | 4007 | timestampFormat={timestampFormat} |
| 4007 | workspaceRoot={activeProject?.cwd ?? undefined} | 4008 | workspaceRoot={activeWorkspaceRoot} |
| 4008 | /> | 4009 | /> |
| 4009 | </div> | 4010 | </div> |
| 4010 | 4011 | ||
| ... | @@ -4438,7 +4439,7 @@ export default function ChatView({ threadId }: ChatViewProps) { | ... | @@ -4438,7 +4439,7 @@ export default function ChatView({ threadId }: ChatViewProps) { |
| 4438 | activePlan={activePlan} | 4439 | activePlan={activePlan} |
| 4439 | activeProposedPlan={sidebarProposedPlan} | 4440 | activeProposedPlan={sidebarProposedPlan} |
| 4440 | markdownCwd={gitCwd ?? undefined} | 4441 | markdownCwd={gitCwd ?? undefined} |
| 4441 | workspaceRoot={activeProject?.cwd ?? undefined} | 4442 | workspaceRoot={activeWorkspaceRoot} |
| 4442 | timestampFormat={timestampFormat} | 4443 | timestampFormat={timestampFormat} |
| 4443 | onClose={() => { | 4444 | onClose={() => { |
| 4444 | setPlanSidebarOpen(false); | 4445 | setPlanSidebarOpen(false); |