| author | |
| committer | |
| log | 226abe5f916ff828d8be2c19f1148b10feebfe43 |
| tree | 1e412cb274a63e61e63645014828077313bd284e |
| parent | fdcc491e0b36245d4b4c74d1fd338d874f4ec84f |
| signature | Signed by PGP key B5690EEEBB952194 |
31 files changed, 46 insertions(+), 79 deletions(-)
apps/web/src/components/BranchToolbarEnvModeSelector.tsx+1-1| ... | ... | @@ -18,7 +18,7 @@ import { |
| 18 | 18 | SelectValue, |
| 19 | 19 | } from "./ui/select"; |
| 20 | 20 | |
| 21 | export const PREVIOUS_WORKTREE_SELECT_VALUE = "previous-worktree"; | |
| 21 | const PREVIOUS_WORKTREE_SELECT_VALUE = "previous-worktree"; | |
| 22 | 22 | |
| 23 | 23 | interface BranchToolbarEnvModeSelectorProps { |
| 24 | 24 | envLocked: boolean; |
apps/web/src/components/ConfirmDialogHost.tsx+1-1| ... | ... | @@ -23,7 +23,7 @@ type ConfirmationCopy = { |
| 23 | 23 | readonly description: string | null; |
| 24 | 24 | }; |
| 25 | 25 | |
| 26 | export function resolveConfirmDialogCopy(message: string): ConfirmationCopy { | |
| 26 | function resolveConfirmDialogCopy(message: string): ConfirmationCopy { | |
| 27 | 27 | const normalizedMessage = message.trim(); |
| 28 | 28 | const lines = normalizedMessage.split("\n"); |
| 29 | 29 | const questionLineIndex = lines.findIndex((line) => line.trim().endsWith("?")); |
apps/web/src/components/DiffPanel.tsx-2| ... | ... | @@ -104,8 +104,6 @@ interface DiffPanelProps { |
| 104 | 104 | workspaceMutationId: string | null; |
| 105 | 105 | } |
| 106 | 106 | |
| 107 | export { DiffWorkerPoolProvider } from "./DiffWorkerPoolProvider"; | |
| 108 | ||
| 109 | 107 | export default function DiffPanel({ |
| 110 | 108 | mode = "inline", |
| 111 | 109 | composerDraftTarget, |
apps/web/src/components/EnvironmentMachineIcon.tsx+2-2| ... | ... | @@ -23,7 +23,7 @@ function LucideLike(props: SVGProps<SVGSVGElement>) { |
| 23 | 23 | } |
| 24 | 24 | |
| 25 | 25 | /** A Mac mini: squat rounded slab with a front-edge LED. */ |
| 26 | export function MacMiniIcon(props: SVGProps<SVGSVGElement>) { | |
| 26 | function MacMiniIcon(props: SVGProps<SVGSVGElement>) { | |
| 27 | 27 | return ( |
| 28 | 28 | <LucideLike {...props}> |
| 29 | 29 | <rect width="20" height="8" x="2" y="8" rx="2" /> |
| ... | ... | @@ -33,7 +33,7 @@ export function MacMiniIcon(props: SVGProps<SVGSVGElement>) { |
| 33 | 33 | } |
| 34 | 34 | |
| 35 | 35 | /** A Mac Studio: the same slab twice as tall, ports along the front foot. */ |
| 36 | export function MacStudioIcon(props: SVGProps<SVGSVGElement>) { | |
| 36 | function MacStudioIcon(props: SVGProps<SVGSVGElement>) { | |
| 37 | 37 | return ( |
| 38 | 38 | <LucideLike {...props}> |
| 39 | 39 | <rect width="18" height="14" x="3" y="5" rx="2" /> |
apps/web/src/components/LegacySidebar.tsx+1-1| ... | ... | @@ -354,7 +354,7 @@ interface SidebarThreadRowProps { |
| 354 | 354 | ) => boolean; |
| 355 | 355 | } |
| 356 | 356 | |
| 357 | export const SidebarThreadRow = memo(function SidebarThreadRow(props: SidebarThreadRowProps) { | |
| 357 | const SidebarThreadRow = memo(function SidebarThreadRow(props: SidebarThreadRowProps) { | |
| 358 | 358 | const { |
| 359 | 359 | orderedProjectThreadKeys, |
| 360 | 360 | isActive, |
apps/web/src/components/ProviderUpdateLaunchNotification.logic.ts+2-2| ... | ... | @@ -220,7 +220,7 @@ export function providerUpdateNotificationKey( |
| 220 | 220 | return parts.length > 0 ? parts.join("|") : null; |
| 221 | 221 | } |
| 222 | 222 | |
| 223 | export function formatProviderList(providers: ReadonlyArray<Pick<ServerProvider, "driver">>) { | |
| 223 | function formatProviderList(providers: ReadonlyArray<Pick<ServerProvider, "driver">>) { | |
| 224 | 224 | const names = providers.map( |
| 225 | 225 | (provider) => PROVIDER_DISPLAY_NAMES[provider.driver] ?? provider.driver, |
| 226 | 226 | ); |
| ... | ... | @@ -249,7 +249,7 @@ export function shouldShowPrimaryProviderUpdateToast(view: ProviderUpdateToastVi |
| 249 | 249 | return view.phase !== "running"; |
| 250 | 250 | } |
| 251 | 251 | |
| 252 | export function getProviderUpdateRunningToastView(providerCount: number): ProviderUpdateToastView { | |
| 252 | function getProviderUpdateRunningToastView(providerCount: number): ProviderUpdateToastView { | |
| 253 | 253 | return { |
| 254 | 254 | phase: "running", |
| 255 | 255 | type: "loading", |
apps/web/src/components/Sidebar.logic.ts+4-11| ... | ... | @@ -15,7 +15,7 @@ import type { SidebarThreadSummary, Thread } from "../types"; |
| 15 | 15 | import { cn } from "../lib/utils"; |
| 16 | 16 | import { isLatestTurnSettled } from "../session-logic"; |
| 17 | 17 | |
| 18 | export const THREAD_SELECTION_SAFE_SELECTOR = "[data-thread-item], [data-thread-selection-safe]"; | |
| 18 | const THREAD_SELECTION_SAFE_SELECTOR = "[data-thread-item], [data-thread-selection-safe]"; | |
| 19 | 19 | export const THREAD_JUMP_HINT_SHOW_DELAY_MS = 200; |
| 20 | 20 | // Visible sidebar rows are prewarmed into the thread-detail cache so opening a |
| 21 | 21 | // nearby thread usually reuses an already-hot subscription. Each prewarmed |
| ... | ... | @@ -23,10 +23,10 @@ export const THREAD_JUMP_HINT_SHOW_DELAY_MS = 200; |
| 23 | 23 | // activities, growing as agents work) for as long as the row stays visible, |
| 24 | 24 | // so this limit is a direct renderer-heap and server-load multiplier — keep |
| 25 | 25 | // it small; cold opens still render instantly from the cached snapshot. |
| 26 | export const SIDEBAR_THREAD_PREWARM_LIMIT = 3; | |
| 26 | const SIDEBAR_THREAD_PREWARM_LIMIT = 3; | |
| 27 | 27 | // A small buffer keeps the next few rows warm without leasing every row that |
| 28 | 28 | // content-visibility leaves mounted below the scroll viewport. |
| 29 | export const SIDEBAR_ROW_SUBSCRIPTION_OVERSCAN_PX = 160; | |
| 29 | const SIDEBAR_ROW_SUBSCRIPTION_OVERSCAN_PX = 160; | |
| 30 | 30 | |
| 31 | 31 | export function useSidebarRowSubscriptionLease(isActive: boolean): { |
| 32 | 32 | readonly leaseLiveStatus: boolean; |
| ... | ... | @@ -544,13 +544,6 @@ export function resolveSidebarThreadStatus(thread: SidebarThreadStatusInput): Si |
| 544 | 544 | return "ready"; |
| 545 | 545 | } |
| 546 | 546 | |
| 547 | /** NaN-safe Date.parse for sort comparators: a malformed timestamp must not | |
| 548 | poison the whole ordering, so it sinks to the epoch instead. */ | |
| 549 | export function parseTimestampMs(isoDate: string): number { | |
| 550 | const parsed = Date.parse(isoDate); | |
| 551 | return Number.isNaN(parsed) ? 0 : parsed; | |
| 552 | } | |
| 553 | ||
| 554 | 547 | /** First VALID timestamp wins: `a ?? b` falls through on null, but a present- |
| 555 | 548 | yet-malformed string must also fall through to the next candidate rather |
| 556 | 549 | than sink the row to the epoch. */ |
| ... | ... | @@ -567,7 +560,7 @@ export function firstValidTimestampMs( |
| 567 | 560 | |
| 568 | 561 | /** String twin of firstValidTimestampMs for callers that need the ISO string |
| 569 | 562 | (display labels, tick anchors) rather than epoch ms. */ |
| 570 | export function firstValidTimestamp( | |
| 563 | function firstValidTimestamp( | |
| 571 | 564 | ...candidates: ReadonlyArray<string | null | undefined> |
| 572 | 565 | ): string | null { |
| 573 | 566 | for (const candidate of candidates) { |
apps/web/src/components/ThreadCommandSubtitle.tsx+1-2| ... | ... | @@ -15,8 +15,7 @@ export type ThreadCommandSubtitleVariant = |
| 15 | 15 | | "favicon-workspace" |
| 16 | 16 | | "favicon-branch-harness"; |
| 17 | 17 | |
| 18 | export const THREAD_COMMAND_SUBTITLE_VARIANT: ThreadCommandSubtitleVariant = | |
| 19 | "favicon-workspace-harness"; | |
| 18 | const THREAD_COMMAND_SUBTITLE_VARIANT: ThreadCommandSubtitleVariant = "favicon-workspace-harness"; | |
| 20 | 19 | |
| 21 | 20 | export const COMMAND_PALETTE_META_ICON_CLASS = "size-3 shrink-0 text-muted-foreground/70"; |
| 22 | 21 |
apps/web/src/components/chat/ComposerPendingElementContexts.tsx+1-1| ... | ... | @@ -39,7 +39,7 @@ function buildTooltipContent(context: ElementContextDraft): string { |
| 39 | 39 | return lines.join("\n"); |
| 40 | 40 | } |
| 41 | 41 | |
| 42 | export function ComposerPendingElementContextChip({ | |
| 42 | function ComposerPendingElementContextChip({ | |
| 43 | 43 | context, |
| 44 | 44 | onRemove, |
| 45 | 45 | }: ComposerPendingElementContextChipProps) { |
apps/web/src/components/chat/ComposerPendingTerminalContexts.tsx-22| ... | ... | @@ -1,4 +1,3 @@ |
| 1 | import { cn } from "~/lib/utils"; | |
| 2 | 1 | import { |
| 3 | 2 | type TerminalContextDraft, |
| 4 | 3 | formatTerminalContextLabel, |
| ... | ... | @@ -6,11 +5,6 @@ import { |
| 6 | 5 | } from "~/lib/terminalContext"; |
| 7 | 6 | import { TerminalContextInlineChip } from "./TerminalContextInlineChip"; |
| 8 | 7 | |
| 9 | interface ComposerPendingTerminalContextsProps { | |
| 10 | contexts: ReadonlyArray<TerminalContextDraft>; | |
| 11 | className?: string; | |
| 12 | } | |
| 13 | ||
| 14 | 8 | interface ComposerPendingTerminalContextChipProps { |
| 15 | 9 | context: TerminalContextDraft; |
| 16 | 10 | } |
| ... | ... | @@ -26,19 +20,3 @@ export function ComposerPendingTerminalContextChip({ |
| 26 | 20 | |
| 27 | 21 | return <TerminalContextInlineChip label={label} tooltipText={tooltipText} expired={expired} />; |
| 28 | 22 | } |
| 29 | ||
| 30 | export function ComposerPendingTerminalContexts(props: ComposerPendingTerminalContextsProps) { | |
| 31 | const { contexts, className } = props; | |
| 32 | ||
| 33 | if (contexts.length === 0) { | |
| 34 | return null; | |
| 35 | } | |
| 36 | ||
| 37 | return ( | |
| 38 | <div className={cn("flex flex-wrap gap-1.5", className)}> | |
| 39 | {contexts.map((context) => ( | |
| 40 | <ComposerPendingTerminalContextChip key={context.id} context={context} /> | |
| 41 | ))} | |
| 42 | </div> | |
| 43 | ); | |
| 44 | } |
apps/web/src/components/chat/ContextWindowMeter.logic.ts+2-2| ... | ... | @@ -9,8 +9,8 @@ import { |
| 9 | 9 | } from "../../providerInstances"; |
| 10 | 10 | import { getTriggerDisplayModelName, type ModelEsque } from "./providerIconUtils"; |
| 11 | 11 | |
| 12 | export const CLAUDE_RESUME_COMPACTION_MINUTES = 70; | |
| 13 | export const CLAUDE_RESUME_COMPACTION_TOKENS = 100_000; | |
| 12 | const CLAUDE_RESUME_COMPACTION_MINUTES = 70; | |
| 13 | const CLAUDE_RESUME_COMPACTION_TOKENS = 100_000; | |
| 14 | 14 | |
| 15 | 15 | export function providerSupportsManualCompaction( |
| 16 | 16 | provider: ProviderInstanceEntry | null | undefined, |
apps/web/src/components/chat/MessagesTimeline.logic.ts+8-9| ... | ... | @@ -14,7 +14,6 @@ import { |
| 14 | 14 | } from "@t3tools/client-runtime/work-log/presentation"; |
| 15 | 15 | export { |
| 16 | 16 | normalizeCompactToolLabel, |
| 17 | summarizeToolGroup, | |
| 18 | 17 | toolGroupAction, |
| 19 | 18 | } from "@t3tools/client-runtime/work-log/presentation"; |
| 20 | 19 | import { |
| ... | ... | @@ -31,11 +30,11 @@ import { type ChatMessage, type ProposedPlan, type TurnDiffSummary } from "../.. |
| 31 | 30 | import { type MessageId, type OrchestrationLatestTurn, type TurnId } from "@t3tools/contracts"; |
| 32 | 31 | import { formatWorkspaceRelativePath } from "../../filePathDisplay"; |
| 33 | 32 | |
| 34 | export const TIMELINE_MINIMAP_ITEM_SPACING = 8; | |
| 33 | const TIMELINE_MINIMAP_ITEM_SPACING = 8; | |
| 35 | 34 | export const TIMELINE_MINIMAP_MIN_ITEMS = 2; |
| 36 | export const TIMELINE_MINIMAP_MAX_HEIGHT_CSS = "calc(100vh - 18rem)"; | |
| 37 | export const TIMELINE_CONTENT_MAX_WIDTH = 768; | |
| 38 | export const TIMELINE_MINIMAP_PERSISTENT_GUTTER = 48; | |
| 35 | const TIMELINE_MINIMAP_MAX_HEIGHT_CSS = "calc(100vh - 18rem)"; | |
| 36 | const TIMELINE_CONTENT_MAX_WIDTH = 768; | |
| 37 | const TIMELINE_MINIMAP_PERSISTENT_GUTTER = 48; | |
| 39 | 38 | |
| 40 | 39 | function singleToolCallLabel(entry: WorkLogEntry): string { |
| 41 | 40 | const toolPresentation = resolveWorkEntryToolPresentation(entry, "completed"); |
| ... | ... | @@ -145,7 +144,7 @@ export interface TimelineEndState { |
| 145 | 144 | * A small pixel band (instead of the 1px isAtEnd epsilon alone) keeps re-arming |
| 146 | 145 | * reliable while streaming content is still growing under the viewport. |
| 147 | 146 | */ |
| 148 | export const TIMELINE_FOLLOW_REARM_THRESHOLD_PX = 40; | |
| 147 | const TIMELINE_FOLLOW_REARM_THRESHOLD_PX = 40; | |
| 149 | 148 | |
| 150 | 149 | export function resolveTimelineIsAtEnd(state: TimelineEndState | undefined): boolean | undefined { |
| 151 | 150 | if (!state) { |
| ... | ... | @@ -207,9 +206,9 @@ export function resolveTimelineMinimapHasPersistentGutter(viewportWidth: number) |
| 207 | 206 | return sideGutter >= TIMELINE_MINIMAP_PERSISTENT_GUTTER; |
| 208 | 207 | } |
| 209 | 208 | |
| 210 | export const TIMELINE_MINIMAP_HIT_STRIP_LEFT = 12; | |
| 211 | export const TIMELINE_MINIMAP_HIT_STRIP_MAX_WIDTH = 40; | |
| 212 | export const TIMELINE_MINIMAP_EXPANDED_HIT_STRIP_WIDTH = "22rem"; | |
| 209 | const TIMELINE_MINIMAP_HIT_STRIP_LEFT = 12; | |
| 210 | const TIMELINE_MINIMAP_HIT_STRIP_MAX_WIDTH = 40; | |
| 211 | const TIMELINE_MINIMAP_EXPANDED_HIT_STRIP_WIDTH = "22rem"; | |
| 213 | 212 | |
| 214 | 213 | /** |
| 215 | 214 | * The minimap overlays the viewport's left edge while the content column is |
apps/web/src/components/chat/externalLinkContextMenu.ts+1-1| ... | ... | @@ -35,7 +35,7 @@ const EXTERNAL_LINK_CONTEXT_MENU_ITEMS = [ |
| 35 | 35 | * whole menu with the one item that cannot be honoured is what left a right-click on a link |
| 36 | 36 | * showing the platform's cut-and-paste menu instead of a way to copy the link. |
| 37 | 37 | */ |
| 38 | export function externalLinkContextMenuItems(options: { | |
| 38 | function externalLinkContextMenuItems(options: { | |
| 39 | 39 | readonly canOpenInPreview: boolean; |
| 40 | 40 | readonly threadLinkAction?: "link-to-thread" | "unlink-from-thread" | undefined; |
| 41 | 41 | }): readonly ContextMenuItem<ExternalLinkContextMenuAction>[] { |
apps/web/src/components/cloud/CloudEnvironmentConnectList.tsx+1-1| ... | ... | @@ -32,7 +32,7 @@ export interface SavedCloudEnvironmentConnection { |
| 32 | 32 | readonly connection: EnvironmentConnectionPresentation; |
| 33 | 33 | } |
| 34 | 34 | |
| 35 | export function RemoteEnvironmentRowsSkeleton() { | |
| 35 | function RemoteEnvironmentRowsSkeleton() { | |
| 36 | 36 | return ( |
| 37 | 37 | <div className={ITEM_ROW_CLASSNAME}> |
| 38 | 38 | <div className={ITEM_ROW_INNER_CLASSNAME}> |
apps/web/src/components/composerFooterLayout.ts+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | export const COMPOSER_FOOTER_COMPACT_BREAKPOINT_PX = 620; |
| 2 | 2 | export const COMPOSER_FOOTER_WIDE_ACTIONS_COMPACT_BREAKPOINT_PX = 780; |
| 3 | export const RESTING_COMPOSER_IMAGE_THUMBNAIL_LIMIT = 3; | |
| 3 | const RESTING_COMPOSER_IMAGE_THUMBNAIL_LIMIT = 3; | |
| 4 | 4 | |
| 5 | 5 | export function getRestingComposerImagePreviewCounts(imageCount: number): { |
| 6 | 6 | visibleCount: number; |
apps/web/src/components/files/projectFilesQueryState.ts+1-1| ... | ... | @@ -33,7 +33,7 @@ interface ProjectQueryState<A> { |
| 33 | 33 | readonly refresh: () => void; |
| 34 | 34 | } |
| 35 | 35 | |
| 36 | export function getProjectEntriesQueryAtom(environmentId: EnvironmentId, cwd: string) { | |
| 36 | function getProjectEntriesQueryAtom(environmentId: EnvironmentId, cwd: string) { | |
| 37 | 37 | return projectEnvironment.listEntries({ environmentId, input: { cwd } }); |
| 38 | 38 | } |
| 39 | 39 |
apps/web/src/components/media/MediaActions.tsx+1-1| ... | ... | @@ -33,7 +33,7 @@ function mediaFileName(source: MediaActionSource): string { |
| 33 | 33 | } |
| 34 | 34 | |
| 35 | 35 | /** Explicit byte operations get fresh capabilities without replacing a player's active source. */ |
| 36 | export function useMediaActions(source: MediaActionSource) { | |
| 36 | function useMediaActions(source: MediaActionSource) { | |
| 37 | 37 | const createAssetUrl = useAtomQueryRunner(assetEnvironment.createUrl, { |
| 38 | 38 | reportFailure: false, |
| 39 | 39 | refresh: true, |
apps/web/src/components/preview/previewAutomationErrors.ts+1-1| ... | ... | @@ -216,7 +216,7 @@ export const PreviewAutomationHostError = Schema.Union([ |
| 216 | 216 | ]); |
| 217 | 217 | export type PreviewAutomationHostError = typeof PreviewAutomationHostError.Type; |
| 218 | 218 | |
| 219 | export const isPreviewAutomationHostError = Schema.is(PreviewAutomationHostError); | |
| 219 | const isPreviewAutomationHostError = Schema.is(PreviewAutomationHostError); | |
| 220 | 220 | |
| 221 | 221 | export function serializePreviewAutomationHostError( |
| 222 | 222 | error: PreviewAutomationHostError, |
apps/web/src/components/preview/previewMiniPlayerLayout.ts+1-1| ... | ... | @@ -4,7 +4,7 @@ export const PREVIEW_MINI_PLAYER_EDGE_GAP = 12; |
| 4 | 4 | // The mini-player shell straddles this webview at 47 and 49; dialogs begin at 50. |
| 5 | 5 | export const PREVIEW_MINI_PLAYER_WEBVIEW_Z_INDEX = 48; |
| 6 | 6 | export const PREVIEW_MINI_PLAYER_DEFAULT_SIZE = { width: 320, height: 200 } as const; |
| 7 | export const PREVIEW_MINI_PLAYER_MIN_SIZE = { width: 240, height: 150 } as const; | |
| 7 | const PREVIEW_MINI_PLAYER_MIN_SIZE = { width: 240, height: 150 } as const; | |
| 8 | 8 | |
| 9 | 9 | export function clampPreviewMiniPlayerSize( |
| 10 | 10 | size: PreviewMiniPlayerSize, |
apps/web/src/components/projectScriptEditor.tsx+1-1| ... | ... | @@ -49,7 +49,7 @@ import { Popover, PopoverPopup, PopoverTrigger } from "./ui/popover"; |
| 49 | 49 | import { Switch } from "./ui/switch"; |
| 50 | 50 | import { Textarea } from "./ui/textarea"; |
| 51 | 51 | |
| 52 | export const SCRIPT_ICONS: Array<{ id: ProjectScriptIcon; label: string }> = [ | |
| 52 | const SCRIPT_ICONS: Array<{ id: ProjectScriptIcon; label: string }> = [ | |
| 53 | 53 | { id: "play", label: "Play" }, |
| 54 | 54 | { id: "test", label: "Test" }, |
| 55 | 55 | { id: "lint", label: "Lint" }, |
apps/web/src/components/pullRequest/PullRequestCodeTab.tsx+1-1| ... | ... | @@ -187,7 +187,7 @@ function getReviewPositionAnchor(position: PullRequestReviewPosition): { |
| 187 | 187 | * host sit under the line they were written on, and a new comment joins the review being |
| 188 | 188 | * drafted rather than being posted as it is typed. |
| 189 | 189 | */ |
| 190 | export function PullRequestCodeTab({ | |
| 190 | function PullRequestCodeTab({ | |
| 191 | 191 | environmentId, |
| 192 | 192 | reference, |
| 193 | 193 | detail, |
apps/web/src/components/pullRequest/pullRequestLinkContextMenu.ts+1-1| ... | ... | @@ -8,7 +8,7 @@ import { toastManager } from "../ui/toast"; |
| 8 | 8 | export type PullRequestLinkContextMenuAction = "copy-link" | "open-external"; |
| 9 | 9 | |
| 10 | 10 | /** Named for the host rather than "externally": the point is where you will land. */ |
| 11 | export const OPEN_ON_HOST_LABELS: Partial<Record<string, string>> = { | |
| 11 | const OPEN_ON_HOST_LABELS: Partial<Record<string, string>> = { | |
| 12 | 12 | github: "Open on GitHub", |
| 13 | 13 | gitlab: "Open on GitLab", |
| 14 | 14 | bitbucket: "Open on Bitbucket", |
apps/web/src/components/pullRequest/pullRequestList.logic.ts+1-1| ... | ... | @@ -67,7 +67,7 @@ export type PullRequestViewers = PullRequestListResult["viewers"]; |
| 67 | 67 | /** A row plus the environment that read it, where the caller has one to give. */ |
| 68 | 68 | type ScopedEntry = PullRequestListEntry & { readonly environmentId?: string }; |
| 69 | 69 | |
| 70 | export const pullRequestViewerKey = (entry: ScopedEntry): string => | |
| 70 | const pullRequestViewerKey = (entry: ScopedEntry): string => | |
| 71 | 71 | `${entry.environmentId ?? ""} ${entry.host}`; |
| 72 | 72 | |
| 73 | 73 | const GROUP_LABELS: Record<PullRequestGroupKey, string> = { |
apps/web/src/components/pullRequest/pullRequestListPreferences.ts+1-1| ... | ... | @@ -37,7 +37,7 @@ export type PullRequestListPreferencePatch = { |
| 37 | 37 | [Key in keyof PullRequestListPreferences]?: PullRequestListPreferences[Key] | undefined; |
| 38 | 38 | }; |
| 39 | 39 | |
| 40 | export const DEFAULT_PULL_REQUEST_LIST_PREFERENCES = { | |
| 40 | const DEFAULT_PULL_REQUEST_LIST_PREFERENCES = { | |
| 41 | 41 | involvement: "all", |
| 42 | 42 | state: "open", |
| 43 | 43 | } as const satisfies PullRequestListPreferences; |
apps/web/src/components/settings/KeybindingsSettings.logic.ts+1-1| ... | ... | @@ -291,7 +291,7 @@ function titleCaseCommandSegment(segment: string): string { |
| 291 | 291 | return words.join(" "); |
| 292 | 292 | } |
| 293 | 293 | |
| 294 | export function normalizeShortcutKeyToken(key: string): string | null { | |
| 294 | function normalizeShortcutKeyToken(key: string): string | null { | |
| 295 | 295 | const normalized = key.toLowerCase(); |
| 296 | 296 | if ( |
| 297 | 297 | normalized === "meta" || |
apps/web/src/components/settings/ProjectSettingsPanel.tsx+3-3| ... | ... | @@ -127,14 +127,14 @@ const ProjectIconPickerDialog = lazy(() => |
| 127 | 127 | })), |
| 128 | 128 | ); |
| 129 | 129 | |
| 130 | export const PROJECT_GROUPING_MODE_LABELS: Record<SidebarProjectGroupingMode, string> = { | |
| 130 | const PROJECT_GROUPING_MODE_LABELS: Record<SidebarProjectGroupingMode, string> = { | |
| 131 | 131 | repository: "Group by repository", |
| 132 | 132 | repository_path: "Group by repository path", |
| 133 | 133 | separate: "Keep separate", |
| 134 | 134 | }; |
| 135 | 135 | |
| 136 | 136 | /** Logical project groups for the settings page, sorted by display name. */ |
| 137 | export function useSettingsProjectGroups(): SidebarProjectSnapshot[] { | |
| 137 | function useSettingsProjectGroups(): SidebarProjectSnapshot[] { | |
| 138 | 138 | const projects = useProjects(); |
| 139 | 139 | const projectGroupingSettings = useClientSettings(selectProjectGroupingSettings); |
| 140 | 140 | const primaryEnvironmentId = usePrimaryEnvironmentId(); |
| ... | ... | @@ -253,7 +253,7 @@ function ProjectSettingsBreadcrumb({ projectKey }: { projectKey: string }) { |
| 253 | 253 | ); |
| 254 | 254 | } |
| 255 | 255 | |
| 256 | export function ProjectSettingsPanel({ projectKey }: { projectKey: string }) { | |
| 256 | function ProjectSettingsPanel({ projectKey }: { projectKey: string }) { | |
| 257 | 257 | const groups = useSettingsProjectGroups(); |
| 258 | 258 | const navigate = useNavigate(); |
| 259 | 259 |
apps/web/src/components/settings/SettingsSidebarNav.tsx+1-1| ... | ... | @@ -80,7 +80,7 @@ const SETTINGS_SECTION_ICONS: Readonly< |
| 80 | 80 | "/settings/archived": ArchiveIcon, |
| 81 | 81 | }; |
| 82 | 82 | |
| 83 | export const SETTINGS_NAV_ITEMS: ReadonlyArray<{ | |
| 83 | const SETTINGS_NAV_ITEMS: ReadonlyArray<{ | |
| 84 | 84 | label: string; |
| 85 | 85 | to: SettingsPath; |
| 86 | 86 | icon: ComponentType<{ className?: string }>; |
apps/web/src/components/settings/ThemeWireframe.tsx+1-1| ... | ... | @@ -4,7 +4,7 @@ import type { ThemeCardPreviewColors } from "./ThemePreviewCircles"; |
| 4 | 4 | // A simple miniature of the app: sidebar, a short conversation, the |
| 5 | 5 | // composer, and the orchestrator panel floating over the interface as an |
| 6 | 6 | // island with horizontal agent rows. |
| 7 | export function ThemeWireframePane({ | |
| 7 | function ThemeWireframePane({ | |
| 8 | 8 | colors, |
| 9 | 9 | clip, |
| 10 | 10 | }: { |
apps/web/src/components/settings/customModelEditor.logic.ts+2-2| ... | ... | @@ -104,7 +104,7 @@ export const DESCRIPTOR_PRESETS_BY_KIND: Partial< |
| 104 | 104 | }; |
| 105 | 105 | |
| 106 | 106 | let nextKey = 0; |
| 107 | export function newEditorKey(): string { | |
| 107 | function newEditorKey(): string { | |
| 108 | 108 | nextKey += 1; |
| 109 | 109 | return `k${nextKey}`; |
| 110 | 110 | } |
| ... | ... | @@ -140,7 +140,7 @@ export function emptyEditorChoice(): EditorChoice { |
| 140 | 140 | * by built-in runtime profiles a custom entry does not have, so they are |
| 141 | 141 | * dropped rather than stored as a plain option value. |
| 142 | 142 | */ |
| 143 | export function descriptorToEditor(descriptor: ProviderOptionDescriptor): EditorDescriptor { | |
| 143 | function descriptorToEditor(descriptor: ProviderOptionDescriptor): EditorDescriptor { | |
| 144 | 144 | const promptInjected = new Set( |
| 145 | 145 | descriptor.type === "select" ? (descriptor.promptInjectedValues ?? []) : [], |
| 146 | 146 | ); |
apps/web/src/components/settings/providerDriverMeta.ts+2-2| ... | ... | @@ -43,7 +43,7 @@ export interface ProviderClientDefinition { |
| 43 | 43 | readonly badgeLabel?: string; |
| 44 | 44 | } |
| 45 | 45 | |
| 46 | export const PROVIDER_CLIENT_DEFINITIONS: readonly ProviderClientDefinition[] = [ | |
| 46 | const PROVIDER_CLIENT_DEFINITIONS: readonly ProviderClientDefinition[] = [ | |
| 47 | 47 | { |
| 48 | 48 | value: ProviderDriverKind.make("codex"), |
| 49 | 49 | label: "Codex", |
| ... | ... | @@ -84,7 +84,7 @@ export const PROVIDER_CLIENT_DEFINITIONS: readonly ProviderClientDefinition[] = |
| 84 | 84 | }, |
| 85 | 85 | ]; |
| 86 | 86 | |
| 87 | export const PROVIDER_CLIENT_DEFINITION_BY_VALUE: Partial< | |
| 87 | const PROVIDER_CLIENT_DEFINITION_BY_VALUE: Partial< | |
| 88 | 88 | Record<ProviderDriverKind, ProviderClientDefinition> |
| 89 | 89 | > = Object.fromEntries( |
| 90 | 90 | PROVIDER_CLIENT_DEFINITIONS.map((definition) => [definition.value, definition]), |
apps/web/src/components/settings/themeInspector.ts+1-1| ... | ... | @@ -14,7 +14,7 @@ const THEME_PAINT_KIND_ORDER: ReadonlyArray<ThemePaintKind> = [ |
| 14 | 14 | "foreground", |
| 15 | 15 | ]; |
| 16 | 16 | |
| 17 | export const THEME_INSPECTOR_MATCH_ATTRIBUTE = "data-theme-inspector-match"; | |
| 17 | const THEME_INSPECTOR_MATCH_ATTRIBUTE = "data-theme-inspector-match"; | |
| 18 | 18 | |
| 19 | 19 | const THEME_TOKEN_PROBE_ATTRIBUTE = "data-theme-token-probe"; |
| 20 | 20 | const THEME_TOKEN_PROBE_COLOR = "#01fea7"; |