Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -179,14 +179,14 @@ function AutoSettleSettingsRows() {
<SettingsSection title="Usage limits">
<SettingsSwitchRow
icon="clock"
label="Auto-resume limited threads"
label="Resume after usage limits"
value={uniformMobileSetting(displayTargets, "autoResumeLimitedThreads")}
disabled={disabled}
onValueChange={(value) => writeToAll({ autoResumeLimitedThreads: value })}
/>
<SettingsSwitchRow
icon="clock"
label="Snooze limited threads"
label="Snooze until limits reset"
value={uniformMobileSetting(displayTargets, "snoozeLimitedThreads")}
disabled={disabled}
onValueChange={(value) => writeToAll({ snoozeLimitedThreads: value })}
Expand Down
3 changes: 2 additions & 1 deletion apps/web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,8 @@
body {
background: #ffffff;
color: #262626;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
font-family:
-apple-system, BlinkMacSystemFont, "Inter Variable", "Segoe UI", system-ui, sans-serif;
}

html.dark body {
Expand Down
1 change: 1 addition & 0 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"@dnd-kit/sortable": "^10.0.0",
"@dnd-kit/utilities": "^3.2.2",
"@effect/atom-react": "catalog:",
"@fontsource-variable/inter": "^5.3.0",
"@formkit/auto-animate": "^0.9.0",
"@legendapp/list": "catalog:",
"@noble/hashes": "catalog:",
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/appearanceFonts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from "@t3tools/contracts";

export const DEFAULT_SANS_FONT_STACK =
'-apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif';
'-apple-system, BlinkMacSystemFont, "Inter Variable", "Segoe UI", system-ui, sans-serif';

// Some engines map `ui-monospace` to a proportional font, so prefer concrete names.
export const DEFAULT_CODE_FONT_STACK =
Expand Down
62 changes: 35 additions & 27 deletions apps/web/src/components/BranchToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -225,11 +225,7 @@ const RunContextSelector = memo(function RunContextSelector({
<Tooltip>
<TooltipTrigger render={<span className="inline-flex shrink-0" />}>
<WorkspaceIcon
className={
isPanel
? THREAD_DETAILS_PANEL_ICON_CLASS
: cn("size-3 shrink-0", showEnvironmentIndicator && "mx-0!")
}
className={isPanel ? THREAD_DETAILS_PANEL_ICON_CLASS : "size-3 shrink-0 mx-0!"}
/>
</TooltipTrigger>
<TooltipPopup>
Expand All @@ -241,29 +237,39 @@ const RunContextSelector = memo(function RunContextSelector({
</TooltipPopup>
</Tooltip>
);
const icon = showEnvironmentIndicator ? (
const environmentIcon = (
<Tooltip>
<TooltipTrigger render={<span className="inline-flex shrink-0" />}>
{autoEnvironmentLabel ? (
<ScaleIcon
className={isPanel ? THREAD_DETAILS_PANEL_ICON_CLASS : "size-3 shrink-0 mx-0!"}
aria-hidden="true"
/>
) : (
<EnvironmentMachineIcon
kind={activeEnvironment?.machine ?? "server"}
// Wide machine glyphs need a little more box to match the square row icons.
className={
isPanel
? cn(THREAD_DETAILS_PANEL_ICON_CLASS, "-mx-px size-4.5")
: "size-3 shrink-0 mx-0!"
}
/>
)}
</TooltipTrigger>
<TooltipPopup>{autoEnvironmentLabel ?? activeEnvironment?.label ?? "Run on"}</TooltipPopup>
</Tooltip>
);
const icon = !showEnvironmentIndicator ? (
workspaceIcon
) : isPanel ? (
environmentIcon
) : (
// Button's SVG margins consume 4px of the gap; mx-0! restores the intended 2px.
<span className="inline-flex shrink-0 items-center gap-0.5">
<Tooltip>
<TooltipTrigger render={<span className="inline-flex shrink-0" />}>
{autoEnvironmentLabel ? (
<ScaleIcon
className={isPanel ? THREAD_DETAILS_PANEL_ICON_CLASS : "size-3 shrink-0 mx-0!"}
aria-hidden="true"
/>
) : (
<EnvironmentMachineIcon
kind={activeEnvironment?.machine ?? "server"}
className={isPanel ? THREAD_DETAILS_PANEL_ICON_CLASS : "size-3 shrink-0 mx-0!"}
/>
)}
</TooltipTrigger>
<TooltipPopup>{autoEnvironmentLabel ?? activeEnvironment?.label ?? "Run on"}</TooltipPopup>
</Tooltip>
{environmentIcon}
{workspaceIcon}
</span>
) : (
workspaceIcon
);
const triggerContent = (
<>
Expand All @@ -272,14 +278,16 @@ const RunContextSelector = memo(function RunContextSelector({
{autoEnvironmentLabel ??
(showEnvironmentIndicator ? (activeEnvironment?.label ?? "Run on") : workspaceLabel)}
</ComposerContextLabel>
{/* Trailing in the panel, so every row label starts on the same edge. */}
{isPanel && showEnvironmentIndicator ? workspaceIcon : null}
</>
);

if (isLocked) {
return (
<span
className={cn(
"inline-flex h-7 min-w-0 max-w-[48%] flex-initial items-center justify-start gap-1 rounded-md border border-transparent px-1.75 font-normal text-muted-foreground/70 text-xs sm:h-6",
"inline-flex h-7 min-w-0 max-w-[48%] flex-initial items-center justify-start gap-1 rounded-md border border-transparent px-1.75 font-normal text-foreground/70 text-xs sm:h-6 dark:text-muted-foreground",
isPanel && "max-w-full",
isPanel && THREAD_DETAILS_PANEL_LOCKED_ROW_CLASS,
)}
Expand Down Expand Up @@ -313,7 +321,7 @@ const RunContextSelector = memo(function RunContextSelector({
].join(" ")}
>
{triggerContent}
{!isPanel ? <ChevronDownIcon className="size-3 shrink-0 opacity-50" /> : null}
{!isPanel ? <ChevronDownIcon className="size-3 shrink-0 mx-0!" /> : null}
</MenuTrigger>
<MenuPopup
align="start"
Expand Down Expand Up @@ -748,7 +756,7 @@ export const BranchToolbar = memo(function BranchToolbar({
ref={setStripElement}
data-compact={labelsOverflow ? "" : undefined}
className={cn(
"gap-1 text-xs font-normal text-muted-foreground/70",
"gap-1 text-xs font-normal text-foreground/70 dark:text-muted-foreground",
// Hide empty non-Git strips while retaining host width so controls can reappear as the chat grows.
!contextStripVisible && "pointer-events-none invisible absolute inset-x-0 top-full",
)}
Expand Down
6 changes: 2 additions & 4 deletions apps/web/src/components/BranchToolbarBranchSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,7 @@ export function BranchToolbarBranchSelector({
>
<GitBranchIcon
className={cn(
"size-3 shrink-0 opacity-70",
"size-3 shrink-0",
displayMode === "panel" && THREAD_DETAILS_PANEL_ICON_CLASS,
)}
/>
Expand All @@ -732,9 +732,7 @@ export function BranchToolbarBranchSelector({
className="w-full"
/>
</ComposerContextLabel>
{displayMode !== "panel" ? (
<ChevronDownIcon className="size-3 shrink-0 opacity-50" />
) : null}
{displayMode !== "panel" ? <ChevronDownIcon className="size-3 shrink-0" /> : null}
</ComboboxTrigger>
</span>
{displayMode === "panel" && prNumber !== undefined && prUrl !== undefined ? (
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/components/ChatMarkdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1628,7 +1628,7 @@ function ChatMarkdown({
className={cn(
"chat-markdown w-full min-w-0 [overflow-wrap:anywhere] [word-break:break-word]",
!inline &&
"text-sm leading-relaxed text-foreground/[calc(80%+var(--appearance-contrast-boost)/5)]",
"text-sm leading-relaxed text-foreground/[calc(90%+var(--appearance-contrast-boost)/10)]",
className,
)}
data-streaming={componentState.isStreaming ? "" : undefined}
Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/components/ComposerPromptEditorTiptap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1101,7 +1101,7 @@ function ComposerPromptEditorTiptapInner(

const editorAttributes = {
class: cn(
"composer-tiptap -m-1 block max-h-52 min-h-19.5 overflow-y-auto p-1 whitespace-pre-wrap wrap-break-word bg-transparent leading-relaxed text-foreground focus:outline-none",
"composer-tiptap -m-1 block max-h-52 min-h-19.5 redesign:min-h-12 overflow-y-auto p-1 whitespace-pre-wrap wrap-break-word bg-transparent leading-relaxed text-foreground focus:outline-none",
className,
),
"data-testid": "composer-editor",
Expand Down Expand Up @@ -1839,7 +1839,7 @@ function ComposerPromptEditorTiptapInner(
{isEmpty && contextRecords.size === 0 && placeholder ? (
<div
className={cn(
"pointer-events-none absolute inset-0 leading-relaxed text-placeholder/75",
"pointer-events-none absolute inset-0 leading-relaxed text-placeholder",
placeholderClassName,
)}
>
Expand Down
6 changes: 3 additions & 3 deletions apps/web/src/components/EnvironmentMachineIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ function LucideLike(props: SVGProps<SVGSVGElement>) {
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeWidth="1.75"
strokeLinecap="round"
strokeLinejoin="round"
{...props}
Expand All @@ -23,8 +23,8 @@ function LucideLike(props: SVGProps<SVGSVGElement>) {
function MacMiniIcon(props: SVGProps<SVGSVGElement>) {
return (
<LucideLike {...props}>
<rect width="20" height="8" x="2" y="8" rx="2" />
<path d="M6 12h.01" />
<rect width="18" height="12" x="3" y="6" rx="2.5" />
<circle cx="7.5" cy="12" r="1" fill="currentColor" stroke="none" />
</LucideLike>
);
}
Expand Down
32 changes: 27 additions & 5 deletions apps/web/src/components/GitActionsControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ import { getSourceControlPresentation, sourceControlIcon } from "~/sourceControl
import { sourceControlClients } from "@t3tools/client-runtime/source-control-clients";
import { formatDiffCount } from "@t3tools/client-runtime/diff-count";
import { useOpenLink } from "~/browser/useOpenLink";
import { useClientSettings } from "~/hooks/useSettings";

interface GitActionsControlProps {
presentation?: "toolbar" | "menu";
Expand Down Expand Up @@ -1151,6 +1152,17 @@ export default function GitActionsControl({
? (quickAction.hint ?? "This action is currently unavailable.")
: null;
const gitActionProgress = resolveGitActionProgressPresentation(vcsActionState);
const redesign = useClientSettings((s) => s.redesignEnabled);
// A fresh draft with nothing to commit, push, or diff hides those rows until there is work.
const quietEmptyDraft =
redesign &&
isPanel &&
draftId !== undefined &&
gitActionProgress === null &&
!gitStatusError &&
quickAction.disabled &&
!changesTotals?.insertions &&
!changesTotals?.deletions;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium components/GitActionsControl.tsx:1161

A draft on detached HEAD with only untracked files hides both the Changes row and Git actions, making Commit inaccessible, even though hasWorkingTreeChanges is true. Those files can have zero insertions and deletions, so the diff-total checks make quietEmptyDraft treat real work as empty; include hasWorkingTreeChanges in the emptiness check.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @apps/web/src/components/GitActionsControl.tsx around line 1161:

A draft on detached `HEAD` with only untracked files hides both the Changes row and Git actions, making Commit inaccessible, even though `hasWorkingTreeChanges` is true. Those files can have zero insertions and deletions, so the diff-total checks make `quietEmptyDraft` treat real work as empty; include `hasWorkingTreeChanges` in the emptiness check.

Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
const pendingDefaultBranchActionCopy = pendingDefaultBranchAction
? resolveDefaultBranchActionDialogCopy({
action: pendingDefaultBranchAction.action,
Expand Down Expand Up @@ -1684,7 +1696,7 @@ export default function GitActionsControl({
{initAction.isPending ? "Initializing..." : "Initialize Git"}
</span>
</ThreadDetailsControl>
) : compact && !gitActionProgress && !visibleInlineSuccess ? null : (
) : quietEmptyDraft || (compact && !gitActionProgress && !visibleInlineSuccess) ? null : (
<ActionGroup
role="group"
aria-label="Git actions"
Expand Down Expand Up @@ -1821,7 +1833,7 @@ export default function GitActionsControl({
</ActionGroup>
)}

{isPanel && isRepo ? (
{isPanel && isRepo && !quietEmptyDraft ? (
<ThreadDetailsControl
type="button"
variant="ghost"
Expand All @@ -1832,11 +1844,21 @@ export default function GitActionsControl({
>
<FileDiffIcon className={THREAD_DETAILS_PANEL_ICON_CLASS} aria-hidden />
<span className={cn("flex-1 text-left", THREAD_DETAILS_PANEL_LABEL_CLASS)}>Changes</span>
<span className="flex items-center gap-1 font-mono text-2xs tabular-nums">
<span className="text-diff-addition">
<span className="flex items-center gap-1.5 font-mono text-xs tabular-nums">
<span
className={
changesTotals?.insertions
? "text-diff-addition-foreground"
: "text-muted-foreground"
}
>
+{formatDiffCount(changesTotals?.insertions ?? 0)}
</span>
<span className="text-diff-deletion">
<span
className={
changesTotals?.deletions ? "text-diff-deletion-foreground" : "text-muted-foreground"
}
>
-{formatDiffCount(changesTotals?.deletions ?? 0)}
</span>
</span>
Expand Down
19 changes: 6 additions & 13 deletions apps/web/src/components/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3136,11 +3136,8 @@ export default function Sidebar({ routeReveal }: { routeReveal: SidebarRouteReve
key="working-shelf-header"
marker="working-header"
className="mt-auto"
label={
workingShelfExpanded
? "Working"
: `Working (${workingThreads.length})`
}
label="Working"
count={workingThreads.length}
toggle={{
expanded: workingShelfExpanded,
onToggle: toggleWorkingShelf,
Expand All @@ -3154,11 +3151,8 @@ export default function Sidebar({ routeReveal }: { routeReveal: SidebarRouteReve
key="snoozed-shelf-header"
marker="snoozed-header"
className={cn(workingThreads.length === 0 && "mt-auto")}
label={
snoozedShelfExpanded
? "Snoozed"
: `Snoozed (${snoozedThreads.length})`
}
label="Snoozed"
count={snoozedThreads.length}
toggle={{
expanded: snoozedShelfExpanded,
onToggle: toggleSnoozedShelf,
Expand All @@ -3174,9 +3168,8 @@ export default function Sidebar({ routeReveal }: { routeReveal: SidebarRouteReve
className={cn(
workingThreads.length + snoozedThreads.length === 0 && "mt-auto",
)}
label={
settledShelfExpanded ? "Settled" : `Settled (${settledCount})`
}
label="Settled"
count={settledCount}
dragging={from !== null}
isDropTarget={dragTargetSection === "settled"}
toggle={{
Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/components/ThreadStatusIndicators.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ function PullRequestBadge({
className={cn("contents font-normal text-xs tabular-nums", presentation.toneClassName)}
>
<presentation.Icon aria-hidden className="size-3 shrink-0" />
<span>{presentation.text}</span>
<span className="redesign:text-secondary-label">{presentation.text}</span>
</span>
</TooltipTrigger>
<TooltipPopup
Expand Down Expand Up @@ -800,7 +800,7 @@ export function ThreadWorktreeIndicator({
/>
}
>
<FolderGit2Icon className="size-3 text-muted-foreground/40" />
<FolderGit2Icon className="size-3.5 shrink-0 text-icon-muted" />
</TooltipTrigger>
<TooltipPopup side="top">{tooltip}</TooltipPopup>
</Tooltip>
Expand Down
12 changes: 5 additions & 7 deletions apps/web/src/components/chat/ChatComposer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ import {
extendReplacementRangeForTrailingSpace,
replaceTextRange,
} from "../../composer-logic";
import { DISCONNECTED_COMPOSER_PLACEHOLDER } from "../../composerPlaceholder";
import { DEFAULT_COMPOSER_PLACEHOLDER } from "../../composerPlaceholder";
import {
deriveComposerSendState,
getAntigravitySendBlockReason,
Expand Down Expand Up @@ -3596,7 +3596,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps)
data-chat-composer-surface="true"
data-chat-composer-mobile-collapsed={isComposerCollapsedMobile ? "true" : "false"}
className={cn(
"rounded-3xl transition-[background-color] duration-200",
"rounded-2xl transition-[background-color] duration-200",
"in-data-[thread-context-over]:bg-accent/45 in-data-[thread-context-over]:ring-1 in-data-[thread-context-over]:ring-inset in-data-[thread-context-over]:ring-primary/70",
isDragOverComposer ? "bg-accent/45 ring-1 ring-inset ring-primary/70" : null,
projectSelectionRequired ? "opacity-75" : null,
Expand Down Expand Up @@ -3763,7 +3763,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps)
className={cn(
showMobilePendingAnswerActions && "max-sm:pb-12",
isComposerResting &&
"my-0 max-h-8 min-h-8 overflow-hidden py-0 whitespace-pre! leading-8",
"my-0 max-h-8 min-h-8 redesign:min-h-8 overflow-hidden py-0 whitespace-pre! leading-8",
)}
placeholderClassName={cn(
isComposerResting &&
Expand Down Expand Up @@ -3793,9 +3793,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps)
? "Choose a project above to start a thread"
: showProviderUnavailable
? "Enable a provider in Settings to send a message"
: phase === "disconnected"
? DISCONNECTED_COMPOSER_PLACEHOLDER
: "Ask anything, @tag files/folders, $use skills, or / for commands"
: DEFAULT_COMPOSER_PLACEHOLDER
}
disabled={
isConnecting ||
Expand Down Expand Up @@ -3863,7 +3861,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps)
data-chat-composer-controls="left"
data-chat-composer-footer-controls="true"
className={cn(
"relative -m-1 -ms-3.5 flex min-w-0 flex-1 items-center gap-1 overflow-x-auto p-1 ps-3.5 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
"relative -m-1 -ms-3.5 flex min-w-0 flex-1 items-center gap-0 overflow-x-auto p-1 ps-3.5 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
isComposerResting && "hidden",
)}
>
Expand Down
Loading
Loading