| author | |
| committer | |
| log | 0e73dc15275f24b7ba94a7c200939907690f70b2 |
| tree | d67c879a2ce203d563614febc43c940538459a37 |
| parent | 1a94fcbd294ab69709a3895b30941537d415764a |
- Remove autoFocus from the main terminal setup effect dependency array to
prevent full terminal teardown/recreation when switching tabs in split view.
Focus is already handled by a dedicated effect.
- Change threadTerminalRuntimeEnv memo dependency from activeProject to
activeProject?.cwd so unrelated project state changes (e.g. saving scripts)
don't trigger terminal re-initialization.
- Unexport injectEnvIntoShellCommand which is never imported by production
code (env injection is handled server-side), and remove its tests.
Applied via @cursor push command4 files changed, 3 insertions(+), 23 deletions(-)
apps/web/src/components/ChatView.tsx+1-1| ... | @@ -552,7 +552,7 @@ export default function ChatView() { | ... | @@ -552,7 +552,7 @@ export default function ChatView() { |
| 552 | }, | 552 | }, |
| 553 | worktreePath: activeThread?.worktreePath ?? null, | 553 | worktreePath: activeThread?.worktreePath ?? null, |
| 554 | }); | 554 | }); |
| 555 | }, [activeProject, activeThread?.worktreePath]); | 555 | }, [activeProject?.cwd, activeThread?.worktreePath]); |
| 556 | // Default true while loading to avoid toolbar flicker. | 556 | // Default true while loading to avoid toolbar flicker. |
| 557 | const isGitRepo = branchesQuery.data?.isRepo ?? true; | 557 | const isGitRepo = branchesQuery.data?.isRepo ?? true; |
| 558 | const splitTerminalShortcutLabel = useMemo( | 558 | const splitTerminalShortcutLabel = useMemo( |
apps/web/src/components/ThreadTerminalDrawer.tsx+1-1| ... | @@ -372,7 +372,7 @@ function TerminalViewport({ | ... | @@ -372,7 +372,7 @@ function TerminalViewport({ |
| 372 | fitAddonRef.current = null; | 372 | fitAddonRef.current = null; |
| 373 | terminal.dispose(); | 373 | terminal.dispose(); |
| 374 | }; | 374 | }; |
| 375 | }, [api, autoFocus, cwd, runtimeEnv, terminalId, threadId]); | 375 | }, [api, cwd, runtimeEnv, terminalId, threadId]); |
| 376 | 376 | ||
| 377 | useEffect(() => { | 377 | useEffect(() => { |
| 378 | if (!autoFocus) return; | 378 | if (!autoFocus) return; |
apps/web/src/projectScripts.test.ts-20| ... | @@ -2,7 +2,6 @@ import { describe, expect, it } from "vitest"; | ... | @@ -2,7 +2,6 @@ import { describe, expect, it } from "vitest"; |
| 2 | 2 | ||
| 3 | import { | 3 | import { |
| 4 | commandForProjectScript, | 4 | commandForProjectScript, |
| 5 | injectEnvIntoShellCommand, | ||
| 6 | nextProjectScriptId, | 5 | nextProjectScriptId, |
| 7 | primaryProjectScript, | 6 | primaryProjectScript, |
| 8 | projectScriptRuntimeEnv, | 7 | projectScriptRuntimeEnv, |
| ... | @@ -24,25 +23,6 @@ describe("projectScripts helpers", () => { | ... | @@ -24,25 +23,6 @@ describe("projectScripts helpers", () => { |
| 24 | expect(nextProjectScriptId("!!!", [])).toBe("script"); | 23 | expect(nextProjectScriptId("!!!", [])).toBe("script"); |
| 25 | }); | 24 | }); |
| 26 | 25 | ||
| 27 | it("injects environment variables for posix shells", () => { | ||
| 28 | const command = injectEnvIntoShellCommand("bun install", { T3CODE_PROJECT_ROOT: "/tmp/project" }, "MacIntel"); | ||
| 29 | expect(command).toBe("env T3CODE_PROJECT_ROOT='/tmp/project' bun install"); | ||
| 30 | }); | ||
| 31 | |||
| 32 | it("injects environment variables for windows shells", () => { | ||
| 33 | const command = injectEnvIntoShellCommand("bun install", { T3CODE_PROJECT_ROOT: "C:\\\\repo path" }, "Win32"); | ||
| 34 | expect(command).toBe('set "T3CODE_PROJECT_ROOT=C:\\\\repo path" && bun install'); | ||
| 35 | }); | ||
| 36 | |||
| 37 | it("escapes windows env values that trigger interpolation", () => { | ||
| 38 | const command = injectEnvIntoShellCommand( | ||
| 39 | "bun install", | ||
| 40 | { T3CODE_PROJECT_ROOT: '%USERPROFILE%^"repo"' }, | ||
| 41 | "Win32", | ||
| 42 | ); | ||
| 43 | expect(command).toBe('set "T3CODE_PROJECT_ROOT=^%USERPROFILE^%^^""repo""" && bun install'); | ||
| 44 | }); | ||
| 45 | |||
| 46 | it("resolves primary and setup scripts", () => { | 26 | it("resolves primary and setup scripts", () => { |
| 47 | const scripts = [ | 27 | const scripts = [ |
| 48 | { | 28 | { |
apps/web/src/projectScripts.ts+1-1| ... | @@ -60,7 +60,7 @@ function shellEscapeWindowsSetValue(value: string): string { | ... | @@ -60,7 +60,7 @@ function shellEscapeWindowsSetValue(value: string): string { |
| 60 | return value.replace(/\^/g, "^^").replace(/%/g, "^%").replace(/"/g, '""'); | 60 | return value.replace(/\^/g, "^^").replace(/%/g, "^%").replace(/"/g, '""'); |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | export function injectEnvIntoShellCommand( | 63 | function injectEnvIntoShellCommand( |
| 64 | command: string, | 64 | command: string, |
| 65 | env: Record<string, string>, | 65 | env: Record<string, string>, |
| 66 | platform = typeof navigator === "undefined" ? "" : navigator.platform, | 66 | platform = typeof navigator === "undefined" ? "" : navigator.platform, |