| author | |
| committer | |
| log | 16491a84b9bb2842ad6db41635d087647fc2df5b |
| tree | e0275fe2c0679620cd50db5acae33cb7c075fed4 |
| parent | b44ed835c63caafae619e303ca019a251c2698b2 |
| signature | Signed by PGP key B5690EEEBB952194 |
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>3 files changed, 27 insertions(+), 23 deletions(-)
apps/web/src/components/ChatView.tsx+8-3| ... | ... | @@ -189,6 +189,7 @@ import { useEnvironmentQuery } from "../state/query"; |
| 189 | 189 | import { |
| 190 | 190 | primaryServerAvailableEditorsAtom, |
| 191 | 191 | primaryServerKeybindingsAtom, |
| 192 | primaryServerSettingsAtom, | |
| 192 | 193 | serverEnvironment, |
| 193 | 194 | } from "../state/server"; |
| 194 | 195 | import { terminalEnvironment } from "../state/terminal"; |
| ... | ... | @@ -1153,6 +1154,10 @@ function ChatViewContent(props: ChatViewProps) { |
| 1153 | 1154 | (store) => store.threadLastVisitedAtById[routeThreadKey], |
| 1154 | 1155 | ); |
| 1155 | 1156 | const settings = useEnvironmentSettings(environmentId); |
| 1157 | // New-thread defaults live in the primary environment's settings.json (the | |
| 1158 | // settings UI never writes to remote environments), so read them from the | |
| 1159 | // primary server rather than the thread's environment. | |
| 1160 | const primaryServerSettings = useAtomValue(primaryServerSettingsAtom); | |
| 1156 | 1161 | const setStickyComposerModelSelection = useComposerDraftStore( |
| 1157 | 1162 | (store) => store.setStickyModelSelection, |
| 1158 | 1163 | ); |
| ... | ... | @@ -3785,7 +3790,7 @@ function ChatViewContent(props: ChatViewProps) { |
| 3785 | 3790 | ? (draftThread?.startFromOrigin ?? false) |
| 3786 | 3791 | : canOverrideServerThreadEnvMode |
| 3787 | 3792 | ? (pendingServerThreadStartFromOriginByThreadId[activeThread?.id ?? ""] ?? |
| 3788 | settings.newWorktreesStartFromOrigin) | |
| 3793 | primaryServerSettings.newWorktreesStartFromOrigin) | |
| 3789 | 3794 | : false; |
| 3790 | 3795 | const sendEnvMode = resolveSendEnvMode({ |
| 3791 | 3796 | requestedEnvMode: envMode, |
| ... | ... | @@ -5254,7 +5259,7 @@ function ChatViewContent(props: ChatViewProps) { |
| 5254 | 5259 | envMode: mode, |
| 5255 | 5260 | startFromOrigin: resolveNewDraftStartFromOrigin({ |
| 5256 | 5261 | envMode: mode, |
| 5257 | newWorktreesStartFromOrigin: settings.newWorktreesStartFromOrigin, | |
| 5262 | newWorktreesStartFromOrigin: primaryServerSettings.newWorktreesStartFromOrigin, | |
| 5258 | 5263 | }), |
| 5259 | 5264 | ...(mode === "worktree" && draftThread?.worktreePath ? { worktreePath: null } : {}), |
| 5260 | 5265 | }); |
| ... | ... | @@ -5266,7 +5271,7 @@ function ChatViewContent(props: ChatViewProps) { |
| 5266 | 5271 | composerDraftTarget, |
| 5267 | 5272 | draftThread?.worktreePath, |
| 5268 | 5273 | isLocalDraftThread, |
| 5269 | settings.newWorktreesStartFromOrigin, | |
| 5274 | primaryServerSettings.newWorktreesStartFromOrigin, | |
| 5270 | 5275 | setPendingServerThreadEnvMode, |
| 5271 | 5276 | scheduleComposerFocus, |
| 5272 | 5277 | setDraftThreadContext, |
apps/web/src/components/Sidebar.tsx+6-8| ... | ... | @@ -43,7 +43,6 @@ import { restrictToFirstScrollableAncestor, restrictToVerticalAxis } from "@dnd- |
| 43 | 43 | import { CSS } from "@dnd-kit/utilities"; |
| 44 | 44 | import { |
| 45 | 45 | type ContextMenuItem, |
| 46 | DEFAULT_SERVER_SETTINGS, | |
| 47 | 46 | ProjectId, |
| 48 | 47 | type ScopedThreadRef, |
| 49 | 48 | type ResolvedKeybindingsConfig, |
| ... | ... | @@ -81,7 +80,6 @@ import { |
| 81 | 80 | readThreadShell, |
| 82 | 81 | useProject, |
| 83 | 82 | useProjects, |
| 84 | useServerConfigs, | |
| 85 | 83 | useThreadShells, |
| 86 | 84 | useThreadShellsForProjectRefs, |
| 87 | 85 | } from "../state/entities"; |
| ... | ... | @@ -203,7 +201,7 @@ import { useCopyToClipboard } from "~/hooks/useCopyToClipboard"; |
| 203 | 201 | import { useIsMobile } from "~/hooks/useMediaQuery"; |
| 204 | 202 | import { CommandDialogTrigger } from "./ui/command"; |
| 205 | 203 | import { useClientSettings, useUpdateClientSettings } from "~/hooks/useSettings"; |
| 206 | import { primaryServerKeybindingsAtom } from "../state/server"; | |
| 204 | import { primaryServerKeybindingsAtom, primaryServerSettingsAtom } from "../state/server"; | |
| 207 | 205 | import { |
| 208 | 206 | derivePhysicalProjectKey, |
| 209 | 207 | deriveProjectGroupingOverrideKey, |
| ... | ... | @@ -1113,7 +1111,7 @@ const SidebarProjectItem = memo(function SidebarProjectItem(props: SidebarProjec |
| 1113 | 1111 | (settings) => settings.confirmThreadArchive, |
| 1114 | 1112 | ); |
| 1115 | 1113 | const projectGroupingSettings = useClientSettings(selectProjectGroupingSettings); |
| 1116 | const serverConfigs = useServerConfigs(); | |
| 1114 | const primaryServerSettings = useAtomValue(primaryServerSettingsAtom); | |
| 1117 | 1115 | const deleteProject = useAtomCommand(projectEnvironment.delete, { |
| 1118 | 1116 | reportFailure: false, |
| 1119 | 1117 | }); |
| ... | ... | @@ -1901,10 +1899,10 @@ const SidebarProjectItem = memo(function SidebarProjectItem(props: SidebarProjec |
| 1901 | 1899 | : null; |
| 1902 | 1900 | const seedContext = resolveSidebarNewThreadSeedContext({ |
| 1903 | 1901 | projectId: member.id, |
| 1902 | // The default env mode is a user preference stored on the primary | |
| 1903 | // environment's settings.json; remote environments never carry it. | |
| 1904 | 1904 | defaultEnvMode: resolveSidebarNewThreadEnvMode({ |
| 1905 | defaultEnvMode: | |
| 1906 | serverConfigs.get(member.environmentId)?.settings.defaultThreadEnvMode ?? | |
| 1907 | DEFAULT_SERVER_SETTINGS.defaultThreadEnvMode, | |
| 1905 | defaultEnvMode: primaryServerSettings.defaultThreadEnvMode, | |
| 1908 | 1906 | }), |
| 1909 | 1907 | activeThread: |
| 1910 | 1908 | currentActiveThread && currentActiveThread.projectId === member.id |
| ... | ... | @@ -1953,7 +1951,7 @@ const SidebarProjectItem = memo(function SidebarProjectItem(props: SidebarProjec |
| 1953 | 1951 | } |
| 1954 | 1952 | })(); |
| 1955 | 1953 | }, |
| 1956 | [handleNewThread, isMobile, router, serverConfigs, setOpenMobile], | |
| 1954 | [handleNewThread, isMobile, primaryServerSettings.defaultThreadEnvMode, router, setOpenMobile], | |
| 1957 | 1955 | ); |
| 1958 | 1956 | |
| 1959 | 1957 | const handleCreateThreadClick = useCallback( |
apps/web/src/hooks/useHandleNewThread.ts+13-12| ... | ... | @@ -1,13 +1,10 @@ |
| 1 | import { useAtomValue } from "@effect/atom-react"; | |
| 1 | 2 | import { |
| 2 | 3 | scopedProjectKey, |
| 3 | 4 | scopeProjectRef, |
| 4 | 5 | scopeThreadRef, |
| 5 | 6 | } from "@t3tools/client-runtime/environment"; |
| 6 | import { | |
| 7 | DEFAULT_RUNTIME_MODE, | |
| 8 | DEFAULT_SERVER_SETTINGS, | |
| 9 | type ScopedProjectRef, | |
| 10 | } from "@t3tools/contracts"; | |
| 7 | import { DEFAULT_RUNTIME_MODE, type ScopedProjectRef } from "@t3tools/contracts"; | |
| 11 | 8 | import { useParams, useRouter } from "@tanstack/react-router"; |
| 12 | 9 | import { useCallback, useMemo } from "react"; |
| 13 | 10 | import { |
| ... | ... | @@ -23,15 +20,21 @@ import { |
| 23 | 20 | getProjectOrderKey, |
| 24 | 21 | selectProjectGroupingSettings, |
| 25 | 22 | } from "../logicalProject"; |
| 26 | import { readThreadShell, useProjects, useServerConfigs, useThread } from "../state/entities"; | |
| 23 | import { readThreadShell, useProjects, useThread } from "../state/entities"; | |
| 27 | 24 | import { resolveNewDraftStartFromOrigin } from "../lib/chatThreadActions"; |
| 25 | import { primaryServerSettingsAtom } from "../state/server"; | |
| 28 | 26 | import { resolveThreadRouteTarget } from "../threadRoutes"; |
| 29 | 27 | import { legacyProjectCwdPreferenceKey, useUiStateStore } from "../uiStateStore"; |
| 30 | 28 | import { useClientSettings } from "./useSettings"; |
| 31 | 29 | |
| 32 | 30 | export function useNewThreadHandler() { |
| 33 | 31 | const projects = useProjects(); |
| 34 | const serverConfigs = useServerConfigs(); | |
| 32 | // New-thread defaults are a user preference, and the settings UI only ever | |
| 33 | // edits the primary environment's settings.json. Reading the target | |
| 34 | // environment's own settings here would silently reset remote projects to | |
| 35 | // the decoded defaults ("local" mode, current branch), since nothing can | |
| 36 | // set those values on a remote server. | |
| 37 | const primaryServerSettings = useAtomValue(primaryServerSettingsAtom); | |
| 35 | 38 | const projectGroupingSettings = useClientSettings(selectProjectGroupingSettings); |
| 36 | 39 | const router = useRouter(); |
| 37 | 40 | const getCurrentRouteTarget = useCallback(() => { |
| ... | ... | @@ -64,8 +67,6 @@ export function useNewThreadHandler() { |
| 64 | 67 | candidate.id === projectRef.projectId && |
| 65 | 68 | candidate.environmentId === projectRef.environmentId, |
| 66 | 69 | ); |
| 67 | const environmentSettings = | |
| 68 | serverConfigs.get(projectRef.environmentId)?.settings ?? DEFAULT_SERVER_SETTINGS; | |
| 69 | 70 | const logicalProjectKey = project |
| 70 | 71 | ? deriveLogicalProjectKeyFromSettings(project, projectGroupingSettings) |
| 71 | 72 | : scopedProjectKey(projectRef); |
| ... | ... | @@ -161,7 +162,7 @@ export function useNewThreadHandler() { |
| 161 | 162 | const draftId = newDraftId(); |
| 162 | 163 | const threadId = newThreadId(); |
| 163 | 164 | const createdAt = new Date().toISOString(); |
| 164 | const initialEnvMode = options?.envMode ?? environmentSettings.defaultThreadEnvMode; | |
| 165 | const initialEnvMode = options?.envMode ?? primaryServerSettings.defaultThreadEnvMode; | |
| 165 | 166 | return (async () => { |
| 166 | 167 | setLogicalProjectDraftThreadId(logicalProjectKey, projectRef, draftId, { |
| 167 | 168 | threadId, |
| ... | ... | @@ -173,7 +174,7 @@ export function useNewThreadHandler() { |
| 173 | 174 | options?.startFromOrigin ?? |
| 174 | 175 | resolveNewDraftStartFromOrigin({ |
| 175 | 176 | envMode: initialEnvMode, |
| 176 | newWorktreesStartFromOrigin: environmentSettings.newWorktreesStartFromOrigin, | |
| 177 | newWorktreesStartFromOrigin: primaryServerSettings.newWorktreesStartFromOrigin, | |
| 177 | 178 | }), |
| 178 | 179 | runtimeMode: DEFAULT_RUNTIME_MODE, |
| 179 | 180 | }); |
| ... | ... | @@ -186,7 +187,7 @@ export function useNewThreadHandler() { |
| 186 | 187 | }); |
| 187 | 188 | })(); |
| 188 | 189 | }, |
| 189 | [getCurrentRouteTarget, projectGroupingSettings, projects, router, serverConfigs], | |
| 190 | [getCurrentRouteTarget, primaryServerSettings, projectGroupingSettings, projects, router], | |
| 190 | 191 | ); |
| 191 | 192 | } |
| 192 | 193 |