6413 lines · 235.3 KB · TypeScript
RawDownload
import {  type ApprovalRequestId,  DEFAULT_MODEL,  defaultInstanceIdForDriver,  type EnvironmentId,  type MessageId,  type ModelSelection,  type ProjectScript,  type ProjectId,  type ProviderApprovalDecision,  type PreviewAnnotationPayload,  ProviderInstanceId,  type ServerProvider,  type ResolvedKeybindingsConfig,  type ScopedThreadRef,  type ThreadId,  type TurnId,  type KeybindingCommand,  OrchestrationThreadActivity,  ProviderInteractionMode,  ProviderDriverKind,  RuntimeMode,  TerminalOpenInput,} from "@t3tools/contracts";import {  connectionStatusTitle,  type EnvironmentConnectionPresentation,} from "@t3tools/client-runtime/connection";import {  effectiveSettled,  effectiveSnoozed,  threadWokeAt,} from "@t3tools/client-runtime/state/thread-settled";import {  parseScopedThreadKey,  scopedThreadKey,  scopeProjectRef,  scopeThreadRef,} from "@t3tools/client-runtime/environment";import {  applyClaudePromptEffortPrefix,  createModelSelection,  resolvePromptInjectedEffort,} from "@t3tools/shared/model";import { CHAT_LIST_ANCHOR_OFFSET } from "@t3tools/shared/chatList";import { projectScriptCwd, projectScriptRuntimeEnv } from "@t3tools/shared/projectScripts";import { truncate } from "@t3tools/shared/String";import { nextTerminalId, resolveTerminalSessionLabel } from "@t3tools/shared/terminalLabels";import { Debouncer } from "@tanstack/react-pacer";import { useAtomValue } from "@effect/atom-react";import {  lazy,  memo,  Suspense,  useCallback,  useEffect,  useLayoutEffect,  useMemo,  useRef,  useState,} from "react";import { flushSync } from "react-dom";import { useNavigate } from "@tanstack/react-router";import { useShallow } from "zustand/react/shallow";import {  isAtomCommandInterrupted,  mapAtomCommandResult,  settlePromise,  squashAtomCommandFailure,  type AtomCommandResult,} from "@t3tools/client-runtime/state/runtime";import * as Cause from "effect/Cause";import { AsyncResult } from "effect/unstable/reactivity";import { isElectron } from "../env";import { readLocalApi } from "../localApi";import { useDiffPanelStore } from "../diffPanelStore";import {  collapseExpandedComposerCursor,  parseStandaloneComposerSlashCommand,} from "../composer-logic";import {  derivePendingApprovals,  derivePendingUserInputs,  derivePhase,  deriveTimelineEntries,  deriveActiveWorkStartedAt,  deriveActivePlanState,  findSidebarProposedPlan,  findLatestProposedPlan,  deriveWorkLogEntries,  hasActionableProposedPlan,  isLatestTurnSettled,} from "../session-logic";import { type LegendListRef } from "@legendapp/list/react";import { getAnchoredTurnMetrics, type TimelineScrollMode } from "./chat/timelineScrollAnchoring";import {  buildPendingUserInputAnswers,  derivePendingUserInputProgress,  setPendingUserInputCustomAnswer,  togglePendingUserInputOptionSelection,  type PendingUserInputDraftAnswer,} from "../pendingUserInput";import { useUiStateStore } from "../uiStateStore";import {  buildPlanImplementationThreadTitle,  buildPlanImplementationPrompt,  resolvePlanFollowUpSubmission,} from "../proposedPlan";import {  DEFAULT_INTERACTION_MODE,  DEFAULT_RUNTIME_MODE,  DEFAULT_THREAD_TERMINAL_ID,  MAX_TERMINALS_PER_GROUP,  type ChatMessage,  type SessionPhase,  type Thread,  type TurnDiffSummary,} from "../types";import { useTheme } from "../hooks/useTheme";import { useTurnDiffSummaries } from "../hooks/useTurnDiffSummaries";import { isCommandPaletteOpen } from "../commandPaletteBus";import { buildTemporaryWorktreeBranchName } from "@t3tools/shared/git";import { useMediaQuery } from "../hooks/useMediaQuery";import {  clearPlanSidebarDismissal,  dismissPlanSidebarForTurn,  isPlanSidebarDismissedForTurn,} from "../planSidebarDismissal";import { RIGHT_PANEL_INLINE_LAYOUT_MEDIA_QUERY } from "../rightPanelLayout";import {  selectActiveRightPanel,  selectActiveRightPanelSurface,  selectThreadRightPanelState,  type RightPanelSurface,  useRightPanelStore,} from "../rightPanelStore";import {  isPreviewSupportedInRuntime,  setActivePreviewTab,  useThreadPreviewState,} from "../previewStateStore";import { addBrowserSurface } from "./preview/addBrowserSurface";import { closePreviewSession } from "./preview/closePreviewSession";import { ThreadPreviewMiniPlayer } from "./preview/ThreadPreviewMiniPlayer";import { subscribePreviewAction } from "./preview/previewActionBus";import { getConfiguredPreviewUrls } from "./preview/previewEmptyStateLogic";import {  selectThreadPreviewMiniPlayer,  usePreviewMiniPlayerStore,} from "../previewMiniPlayerStore";import { RightPanelTabs } from "./RightPanelTabs";import { AgentsPanel } from "./AgentsPanel";import {  deriveAgentPanelModel,  foldSubagentActivities,} from "@t3tools/client-runtime/state/subagentRuntime";import { DiffWorkerPoolProvider } from "./DiffWorkerPoolProvider";import { BranchToolbar } from "./BranchToolbar";import { resolveShortcutCommand, shortcutLabelForCommand } from "../keybindings";import PlanSidebar from "./PlanSidebar";import ThreadTerminalDrawer from "./ThreadTerminalDrawer";import {  AlarmClockIcon,  CheckCircle2Icon,  ChevronDownIcon,  GitBranchIcon,  WifiOffIcon,} from "lucide-react";import { cn, randomHex } from "~/lib/utils";import { COLLAPSED_SIDEBAR_TITLEBAR_INSET_CLASS } from "~/workspaceTitlebar";import { stackedThreadToast, toastManager } from "./ui/toast";import { decodeProjectScriptKeybindingRule } from "~/lib/projectScriptKeybindings";import { type NewProjectScriptInput } from "./ProjectScriptsControl";import {  buildProjectScript,  commandForProjectScript,  nextProjectScriptId,  projectScriptIdFromCommand,} from "~/projectScripts";import { newDraftId, newMessageId, newThreadId } from "~/lib/utils";import { getProviderModelCapabilities, resolveSelectableProvider } from "../providerModels";import { NO_PROVIDER_MODEL_SELECTION } from "../providerInstances";import { useClientSettings, useEnvironmentSettings } from "../hooks/useSettings";import { useNowMinute } from "../hooks/useNowMinute";import { useNewThreadHandler } from "../hooks/useHandleNewThread";import { resolveAppModelSelectionForInstance } from "../modelSelection";import { getTerminalFocusOwner } from "../lib/terminalFocus";import { preventRepeatedTerminalCloseShortcut } from "../lib/terminalCloseShortcut";import { resolveNewDraftStartFromOrigin } from "../lib/chatThreadActions";import {  deriveLogicalProjectKeyFromSettings,  selectProjectGroupingSettings,} from "../logicalProject";import { buildDraftThreadRouteParams } from "../threadRoutes";import {  type ComposerImageAttachment,  type DraftThreadEnvMode,  useComposerDraftStore,  type DraftId,} from "../composerDraftStore";import {  appendTerminalContextsToPrompt,  formatTerminalContextLabel,  type TerminalContextDraft,  type TerminalContextSelection,} from "../lib/terminalContext";import {  appendElementContextsToPrompt,  type ElementContextDraft,  formatElementContextLabel,} from "../lib/elementContext";import { appendPreviewAnnotationPrompt } from "../lib/previewAnnotation";import { appendReviewCommentsToPrompt, type ReviewCommentContext } from "../reviewCommentContext";import { environmentCatalog } from "../connection/catalog";import { selectThreadTerminalUiState, useTerminalUiStateStore } from "../terminalUiStateStore";import { useKnownTerminalSessions, useThreadRunningTerminalIds } from "../state/terminalSessions";import { projectEnvironment } from "../state/projects";import { useEnvironmentQuery } from "../state/query";import {  primaryServerAvailableEditorsAtom,  primaryServerKeybindingsAtom,  primaryServerSettingsAtom,  serverEnvironment,} from "../state/server";import { terminalEnvironment } from "../state/terminal";import { threadEnvironment, useEnvironmentThread } from "../state/threads";import {  requestOlderThreadTurns,  threadHasOlderTurns,} from "@t3tools/client-runtime/state/threads";import { vcsEnvironment } from "../state/vcs";import { useEnvironments, usePrimaryEnvironment } from "../state/environments";import {  useProject,  useProjects,  useThread,  useThreadProposedPlans,  useThreadRefs,  useThreadShell,} from "../state/entities";import { environmentShell } from "../state/shell";import { ChatComposer, type ChatComposerHandle } from "./chat/ChatComposer";import { DraftHeroHeadline } from "./chat/DraftHeroHeadline";import { ExpandedImageDialog } from "./chat/ExpandedImageDialog";import { PullRequestThreadDialog } from "./PullRequestThreadDialog";import { MessagesTimeline } from "./chat/MessagesTimeline";import { ChatHeader } from "./chat/ChatHeader";import { PanelLayoutControls, RightPanelMaximizeControl } from "./chat/PanelLayoutControls";import { type ExpandedImagePreview } from "./chat/ExpandedImagePreview";import { NoActiveThreadState } from "./NoActiveThreadState";import {  resolveEffectiveEnvMode,  resolveLocalCheckoutBranchMismatch,  shouldShowComposerContextStrip,  shouldShowEnvironmentIndicator,} from "./BranchToolbar.logic";import {  getProviderStatusBannerKey,  ProviderStatusBanner,  shouldShowProviderStatusBanner,} from "./chat/ProviderStatusBanner";import { ThreadErrorBanner } from "./chat/ThreadErrorBanner";import { resolveThreadPr } from "./ThreadStatusIndicators";import { ComposerBannerStack, type ComposerBannerStackItem } from "./chat/ComposerBannerStack";import { ThreadSyncStatusPill } from "./chat/ThreadSyncStatusPill";import {  DRAFT_HERO_TRANSITION_ANIMATION_ID,  DRAFT_HERO_TRANSITION_DURATION_MS,  DRAFT_HERO_TRANSITION_EASING,  MOBILE_COMPOSER_VIEW_TRANSITION_NAME,  MOBILE_DRAFT_HEADLINE_VIEW_TRANSITION_NAME,  runMobileComposerTransition,} from "./chat/draftHeroTransition";import {  MAX_HIDDEN_MOUNTED_TERMINAL_THREADS,  branchMismatchKey,  buildExpiredTerminalContextToastCopy,  buildLocalDraftThread,  buildLoadingThreadFromShell,  buildThreadTurnInterruptInput,  collectUserMessageBlobPreviewUrls,  createLocalDispatchSnapshot,  deriveComposerSendState,  dismissBranchMismatchForSession,  hasServerAcknowledgedLocalDispatch,  isBranchMismatchDismissedForSession,  shouldShowBranchMismatchBanner,  getStartedThreadModelChangeBlockReason,  LAST_INVOKED_SCRIPT_BY_PROJECT_KEY,  LastInvokedScriptByProjectSchema,  type LocalDispatchSnapshot,  PullRequestDialogState,  cloneComposerImageForRetry,  deriveLockedProvider,  readFileAsDataUrl,  reconcileMountedTerminalThreadIds,  resolveThreadMetadataUpdateForNextTurn,  resolveSendEnvMode,  revokeBlobPreviewUrl,  revokeUserMessagePreviewUrls,  shouldWriteThreadErrorToCurrentServerThread,  startNewThreadForProject,  waitForStartedServerThread,} from "./ChatView.logic";import type { ThreadSyncPhase } from "../threadSync";import { useLocalStorage } from "~/hooks/useLocalStorage";import { useComposerHandleContext } from "../composerHandleContext";import { sanitizeThreadErrorMessage } from "~/rpc/transportError";import { RightPanelSheet } from "./RightPanelSheet";import { previewEnvironment } from "../state/preview";import { useAtomCommand } from "../state/use-atom-command";import { Button } from "./ui/button";import {  AlertDialog,  AlertDialogClose,  AlertDialogDescription,  AlertDialogFooter,  AlertDialogHeader,  AlertDialogPopup,  AlertDialogTitle,} from "./ui/alert-dialog";import { Tooltip, TooltipPopup, TooltipTrigger } from "./ui/tooltip";import { ServerUpdateAction, ServerUpdateProgress } from "./ServerUpdateAction";import {  buildVersionMismatchDismissalKey,  dismissVersionMismatch,  isVersionMismatchDismissed,  resolveServerConfigVersionMismatch,  resolveServerSelfUpdateCapability,  serverUpdateGuidance,} from "../versionSkew";import { useAssetUrls } from "../assets/assetUrls"; const IMAGE_ONLY_BOOTSTRAP_PROMPT =  "[User attached one or more images without additional text. Respond using the conversation context and the attached image(s).]";const EMPTY_ACTIVITIES: OrchestrationThreadActivity[] = [];const EMPTY_PROVIDERS: ServerProvider[] = [];const EMPTY_PROVIDER_SKILLS: ServerProvider["skills"] = [];const EMPTY_PENDING_USER_INPUT_ANSWERS: Record<string, PendingUserInputDraftAnswer> = {};function useDraftHeroLayoutTransition(isDraftHeroState: boolean) {  const transitionGroupRef = useRef<HTMLDivElement | null>(null);  const composerAnchorRef = useRef<HTMLDivElement | null>(null);  const previousStateRef = useRef(isDraftHeroState);  const previousComposerRectRef = useRef<DOMRect | null>(null);  const animationRef = useRef<Animation | null>(null);  const attachTransitionGroupRef = (element: HTMLDivElement | null) => {    transitionGroupRef.current = element;  };  const attachComposerAnchorRef = (element: HTMLDivElement | null) => {    composerAnchorRef.current = element;  };  const captureComposerRect = () => {    previousComposerRectRef.current = composerAnchorRef.current?.getBoundingClientRect() ?? null;  };   useLayoutEffect(() => {    const transitionGroup = transitionGroupRef.current;    const nextComposerRect = composerAnchorRef.current?.getBoundingClientRect() ?? null;    const stateChanged = previousStateRef.current !== isDraftHeroState;    const prefersReducedMotion =      typeof window !== "undefined" &&      window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;    const mobileComposerTransitionActive =      typeof document !== "undefined" &&      document.documentElement.dataset.mobileComposerRouteTransition === "true";     animationRef.current?.cancel();    animationRef.current = null;     const previousComposerRect = previousComposerRectRef.current;    if (      stateChanged &&      !prefersReducedMotion &&      !mobileComposerTransitionActive &&      transitionGroup &&      previousComposerRect &&      nextComposerRect &&      typeof transitionGroup.animate === "function"    ) {      const translateX = previousComposerRect.left - nextComposerRect.left;      const translateY = previousComposerRect.top - nextComposerRect.top;      if (Math.abs(translateX) >= 0.5 || Math.abs(translateY) >= 0.5) {        const animation = transitionGroup.animate(          [            { transform: `translate3d(${translateX}px, ${translateY}px, 0)` },            { transform: "translate3d(0, 0, 0)" },          ],          {            duration: DRAFT_HERO_TRANSITION_DURATION_MS,            easing: DRAFT_HERO_TRANSITION_EASING,          },        );        animation.id = DRAFT_HERO_TRANSITION_ANIMATION_ID;        animationRef.current = animation;        void animation.finished          .catch(() => undefined)          .then(() => {            if (animationRef.current !== animation) {              return;            }            animationRef.current = null;          });      }    }     previousStateRef.current = isDraftHeroState;    previousComposerRectRef.current = nextComposerRect;  }, [isDraftHeroState]);   return [attachTransitionGroupRef, attachComposerAnchorRef, captureComposerRect] as const;}const PreviewPanel = lazy(() =>  import("./preview/PreviewPanel").then((module) => ({ default: module.PreviewPanel })),);const DiffPanel = lazy(() => import("./DiffPanel"));const FilePreviewPanel = lazy(() => import("./files/FilePreviewPanel"));const EMPTY_PENDING_FILE_SURFACE_IDS: ReadonlySet<string> = new Set();const TYPE_TO_FOCUS_EDITABLE_SELECTOR = [  "input",  "textarea",  "select",  '[contenteditable="true"]',  '[contenteditable="plaintext-only"]',  '[role="textbox"]',].join(",");const TYPE_TO_FOCUS_INTERACTIVE_SELECTOR = [  "button",  "a[href]",  "summary",  '[role="button"]',  '[role="checkbox"]',  '[role="menuitem"]',  '[role="option"]',  '[role="radio"]',  '[role="switch"]',  '[role="tab"]',].join(",");const TYPE_TO_FOCUS_FLOATING_LAYER_SELECTOR = [  '[data-slot="dialog"]',  '[data-slot="menu-popup"]',  '[data-slot="select-popup"]',  '[data-slot="popover-popup"]',  '[data-slot="combobox-popup"]',  '[data-slot="autocomplete-popup"]',].join(","); type EnvironmentUnavailableState = {  readonly environmentId: EnvironmentId;  readonly label: string;  readonly connection: EnvironmentConnectionPresentation;}; type ThreadPlanCatalogEntry = Pick<Thread, "id" | "proposedPlans">; function eventPathContainsSelector(event: Event, selector: string): boolean {  const path = event.composedPath();  if (path.length === 0 && event.target) {    path.push(event.target);  }  return path.some((target) => target instanceof Element && target.closest(selector));} function shouldTypeToFocusComposer(event: KeyboardEvent): boolean {  if (event.defaultPrevented || event.isComposing) return false;  if (event.metaKey || event.ctrlKey || event.altKey) return false;  if (event.key.length !== 1) return false;   if (eventPathContainsSelector(event, TYPE_TO_FOCUS_EDITABLE_SELECTOR)) return false;  if (eventPathContainsSelector(event, TYPE_TO_FOCUS_INTERACTIVE_SELECTOR)) return false;  if (document.querySelector(TYPE_TO_FOCUS_FLOATING_LAYER_SELECTOR)) return false;   return true;} function formatOutgoingPrompt(params: {  provider: ProviderDriverKind;  model: string | null;  models: ReadonlyArray<ServerProvider["models"][number]>;  effort: string | null;  text: string;}): string {  const caps = getProviderModelCapabilities(params.models, params.model, params.provider);  const promptEffort = resolvePromptInjectedEffort(caps, params.effort);  return applyClaudePromptEffortPrefix(params.text, promptEffort);}const SCRIPT_TERMINAL_COLS = 120;const SCRIPT_TERMINAL_ROWS = 30; type ChatViewProps =  | {      environmentId: EnvironmentId;      threadId: ThreadId;      onDiffPanelOpen?: () => void;      reserveTitleBarControlInset?: boolean;      forceExpandedMobileComposer?: boolean;      threadSyncPhase?: ThreadSyncPhase | null;      routeKind: "server";      draftId?: never;    }  | {

Lines 1–500 of 6413.