Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Only write entries that are worth mentioning to users.

## Unreleased

- Web: Refine UI details including rounded corners, spacing, and layout adjustments across input group, slash command menu, and session sidebar

## 1.12.0 (2026-02-11)

- Web: Add subagent activity rendering to display subagent steps (thinking, tool calls, text) inside Task tool messages
Expand Down
2 changes: 2 additions & 0 deletions docs/en/release-notes/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ This page documents the changes in each Kimi Code CLI release.

## Unreleased

- Web: Refine UI details including rounded corners, spacing, and layout adjustments across input group, slash command menu, and session sidebar

## 1.12.0 (2026-02-11)

- Web: Add subagent activity rendering to display subagent steps (thinking, tool calls, text) inside Task tool messages
Expand Down
2 changes: 2 additions & 0 deletions docs/zh/release-notes/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

## 未发布

- Web:优化 UI 细节,包括输入框、斜杠命令菜单和会话侧边栏的圆角、间距和布局调整

## 1.12.0 (2026-02-11)

- Web:添加子 Agent 活动渲染,在 Task 工具消息中展示子 Agent 步骤(思考、工具调用、文本)
Expand Down
4 changes: 2 additions & 2 deletions web/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ function App() {

return (
<PromptInputProvider>
<div className="box-border flex h-[100dvh] flex-col bg-background text-foreground px-[calc(0.75rem+var(--safe-left))] pr-[calc(0.75rem+var(--safe-right))] pt-[calc(0.75rem+var(--safe-top))] pb-1 lg:pb-[calc(0.75rem+var(--safe-bottom))] max-lg:h-[100svh] max-lg:overflow-hidden">
<div className="box-border flex h-dvh flex-col bg-background text-foreground px-(--safe-left) pr-(--safe-right) pt-(--safe-top) pb-1 lg:pb-(--safe-bottom) max-lg:h-svh max-lg:overflow-hidden">
Copy link
Contributor

Choose a reason for hiding this comment

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

🟡 Removal of base padding in root container causes zero padding on standard (non-notched) devices

The root container's padding was changed from px-[calc(0.75rem+var(--safe-left))] to px-(--safe-left), and similarly for pr, pt, and lg:pb. Since --safe-left (and the other safe-area variables) default to 0px on standard devices without notches (web/src/index.css:82-85), the app container now has zero padding on all standard desktop and laptop screens.

Root Cause and Impact

The CSS variables are defined in web/src/index.css:82-85 as:

--safe-top: env(safe-area-inset-top, 0px);
--safe-right: env(safe-area-inset-right, 0px);
--safe-bottom: env(safe-area-inset-bottom, 0px);
--safe-left: env(safe-area-inset-left, 0px);

On the vast majority of desktop browsers and non-notched mobile devices, env(safe-area-inset-*, 0px) resolves to 0px.

Old behavior: px-[calc(0.75rem+var(--safe-left))] → padding = 0.75rem + 0px = 0.75rem on standard devices. The 0.75rem provided a consistent base gutter between viewport edges and app content.

New behavior: px-(--safe-left) → padding = var(--safe-left) = 0px on standard devices. The app content (sidebar border, chat panel) is now flush against the browser viewport edges with no gap. The same applies to pr-(--safe-right) (right padding), pt-(--safe-top) (top padding), and lg:pb-(--safe-bottom) (bottom padding on large screens).

Impact: Visual layout regression on all standard (non-notched) devices — the UI loses its outer margins and sits directly against the viewport edges.

Suggested change
<div className="box-border flex h-dvh flex-col bg-background text-foreground px-(--safe-left) pr-(--safe-right) pt-(--safe-top) pb-1 lg:pb-(--safe-bottom) max-lg:h-svh max-lg:overflow-hidden">
<div className="box-border flex h-dvh flex-col bg-background text-foreground px-[calc(0.75rem+var(--safe-left))] pr-[calc(0.75rem+var(--safe-right))] pt-[calc(0.75rem+var(--safe-top))] pb-1 lg:pb-[calc(0.75rem+var(--safe-bottom))] max-lg:h-svh max-lg:overflow-hidden">
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

<div className="mx-auto flex h-full min-h-0 w-full flex-1 flex-col gap-2 max-w-none">
{isDesktop ? (
<ResizablePanelGroup
Expand Down Expand Up @@ -447,7 +447,7 @@ function App() {
searchQuery={searchQuery}
onSearchQueryChange={handleSearchQueryChange}
/>
<div className="mt-auto flex items-center justify-between pl-2 pb-2 pr-2">
<div className="mt-auto flex items-center justify-between px-3 pb-3">
<div className="flex items-center gap-2">
<ThemeToggle />
</div>
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/ai-elements/prompt-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1186,7 +1186,7 @@ export const PromptInputSubmit = ({
return (
<InputGroupButton
aria-label="Submit"
className={cn(className)}
className={cn("rounded-full",className)}
size={size}
type="submit"
variant={variant}
Expand Down
6 changes: 3 additions & 3 deletions web/src/components/ui/input-group.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
data-slot="input-group"
role="group"
className={cn(
"group/input-group border-input dark:bg-input/30 relative flex w-full items-center rounded-md border shadow-xs transition-[color,box-shadow] outline-none",
"group/input-group border-input dark:bg-input/30 relative flex w-full items-center rounded-3xl border shadow-xs transition-[color,box-shadow] outline-none",
"h-9 min-w-0 has-[>textarea]:h-auto",

// Variants based on alignment.
Expand Down Expand Up @@ -46,9 +46,9 @@ const inputGroupAddonVariants = cva(
"inline-end":
"order-last pr-3 has-[>button]:mr-[-0.45rem] has-[>kbd]:mr-[-0.35rem]",
"block-start":
"order-first w-full justify-start px-3 pt-3 [.border-b]:pb-3 group-has-[>input]/input-group:pt-2.5",
"order-first w-full justify-start px-2 pt-2 [.border-b]:pb-3 group-has-[>input]/input-group:pt-2.5",
"block-end":
"order-last w-full justify-start px-3 pb-3 [.border-t]:pt-3 group-has-[>input]/input-group:pb-2.5",
"order-last w-full justify-start px-2 pb-2 [.border-t]:pt-3 group-has-[>input]/input-group:pb-2.5",
},
},
defaultVariants: {
Expand Down
2 changes: 1 addition & 1 deletion web/src/features/chat/chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ export const ChatWorkspace = memo(function ChatWorkspaceComponent({
/>

{currentSession && (
<div className="mt-auto flex-shrink-0 px-0 pb-0 pt-0 sm:px-3 sm:pb-3 ">
<div className="mt-auto shrink-0 px-3 pb-3 ">
<ChatPromptComposer
status={status}
onSubmit={onSubmit}
Expand Down
4 changes: 2 additions & 2 deletions web/src/features/chat/components/chat-prompt-composer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ export const ChatPromptComposer = memo(function ChatPromptComposerComponent({
type="button"
onClick={handleToggleExpand}
disabled={!(canSendMessage && currentSession)}
className="absolute top-2 right-2 z-10 p-1 cursor-pointer rounded-md text-muted-foreground hover:text-foreground hover:bg-secondary/50 transition-colors disabled:opacity-50 disabled:pointer-events-none"
className="absolute top-2 right-2 z-10 p-1 cursor-pointer rounded-full text-muted-foreground hover:text-foreground hover:bg-secondary/50 transition-colors disabled:opacity-50 disabled:pointer-events-none size-8 flex items-center justify-center"
aria-label={isExpanded ? "Collapse input" : "Expand input"}
>
{isExpanded ? (
Expand Down Expand Up @@ -292,7 +292,7 @@ export const ChatPromptComposer = memo(function ChatPromptComposerComponent({
</div>
</div>
</PromptInputBody>
<PromptInputFooter className="w-full gap-2 py-1 border-none bg-transparent shadow-none">
<PromptInputFooter className="w-full gap-2 pb-2 border-none bg-transparent shadow-none">
<PromptInputTools className="flex-1 min-w-0 flex-wrap">
<GlobalConfigControls />
</PromptInputTools>
Expand Down
6 changes: 3 additions & 3 deletions web/src/features/chat/global-config-controls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,8 @@ export function GlobalConfigControls({
<div className={cn("flex items-center gap-1", className)}>
<Button
variant="ghost"
size="icon"
className="size-9 border-0"
size="icon-sm"
className="border-0 rounded-full"
aria-label="Attach files"
onClick={() => attachments.openFileDialog()}
>
Expand All @@ -215,7 +215,7 @@ export function GlobalConfigControls({
<Button
variant="ghost"
size="sm"
className="h-9 max-w-[160px] justify-start gap-2 border-0"
className="max-w-40 justify-start gap-2 border-0 rounded-full"
aria-label="Change global model"
disabled={isLoading || isUpdating || !config}
>
Expand Down
2 changes: 1 addition & 1 deletion web/src/features/chat/slash-command-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const SlashCommandMenu = ({

return (
<div className="absolute left-0 right-0 bottom-[calc(100%+0.75rem)] z-30">
<div className="rounded-xl border border-border/80 bg-popover/95 p-2 px-1 shadow-xl backdrop-blur supports-backdrop-filter:bg-popover/80">
<div className="rounded-2xl border border-border/80 bg-popover/95 p-2 px-1 shadow-xl backdrop-blur supports-backdrop-filter:bg-popover/80">
{options.length > 0 ? (
<>
<div className="px-3 pb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground">
Expand Down
22 changes: 11 additions & 11 deletions web/src/features/sessions/sessions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ function SessionsListComponent(
) {
const { className, ...rest } = props;
return (
<div ref={ref} className={cn("flex flex-col space-y-0.5 w-full px-2 mt-1", className)} {...rest} />
<div ref={ref} className={cn("flex flex-col gap-1 w-full px-3 pt-px!", className)} {...rest} />
);
}

Expand Down Expand Up @@ -612,7 +612,7 @@ export const SessionsSidebar = memo(function SessionsSidebarComponent({
<>
<aside className="flex h-full min-h-0 flex-col">
<div className="flex min-h-0 flex-1 flex-col gap-2 overflow-hidden">
<div className="flex items-center justify-between px-3 pt-2">
<div className="flex items-center justify-between p-3">
<KimiCliBrand size="sm" showVersion={true} />
{onClose && (
<button
Expand All @@ -627,7 +627,7 @@ export const SessionsSidebar = memo(function SessionsSidebarComponent({
</div>

{/* Sessions */}
<div className="flex items-center justify-between px-3 pt-3">
<div className="flex items-center justify-between px-3">
<h4 className="text-xs font-medium text-muted-foreground uppercase tracking-wide">Sessions</h4>
<div className="flex items-center gap-1">
<button
Expand Down Expand Up @@ -668,7 +668,7 @@ export const SessionsSidebar = memo(function SessionsSidebarComponent({

{/* Multi-select action bar */}
{isMultiSelectMode && (
<div className="mx-2 flex items-center justify-between gap-2 rounded-md bg-secondary/80 px-2 py-1.5">
<div className="mx-3 flex items-center justify-between gap-2 rounded-md bg-secondary/80 pl-2 pr-0.5 py-0.5">
{/* Left: checkbox toggle and count */}
<div className="flex items-center gap-1.5">
<button
Expand Down Expand Up @@ -774,7 +774,7 @@ export const SessionsSidebar = memo(function SessionsSidebarComponent({

{/* Session search and view toggle */}
{!isMultiSelectMode && (
<div className="px-2 flex items-center gap-2">
<div className="px-3 flex items-center gap-2">
<div className="relative flex-1 min-w-0">
<Search className="absolute left-2.5 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground" />
<input
Expand Down Expand Up @@ -816,7 +816,7 @@ export const SessionsSidebar = memo(function SessionsSidebarComponent({
<div className="flex-1 min-h-0">
{viewMode === "grouped" ? (
<div className="flex h-full flex-col">
<div className="flex-1 overflow-y-auto overflow-x-hidden [-webkit-overflow-scrolling:touch] px-3 pb-4 pr-1">
<div className="flex-1 overflow-y-auto overflow-x-hidden [-webkit-overflow-scrolling:touch] px-3 pb-4">
<ul className="space-y-1">
{sessionGroups.map((group) => (
<li key={group.workDir} className="group/dir">
Expand Down Expand Up @@ -898,7 +898,7 @@ export const SessionsSidebar = memo(function SessionsSidebarComponent({
}
}}
onClick={(e) => e.stopPropagation()}
className="w-full text-sm font-medium text-foreground bg-background border border-input rounded px-2 py-1 focus:outline-none focus:ring-1 focus:ring-ring"
className="w-full text-sm font-medium text-foreground border-b border-input focus:outline-none"
/>
) : (
<Tooltip delayDuration={500}>
Expand Down Expand Up @@ -1018,13 +1018,13 @@ export const SessionsSidebar = memo(function SessionsSidebarComponent({
}
}}
onClick={(e) => e.stopPropagation()}
className="w-full text-sm font-medium text-foreground bg-background border border-input rounded px-2 py-1 focus:outline-none focus:ring-1 focus:ring-ring"
className="w-full text-sm font-medium text-foreground focus:outline-none h-6 border-b border-input"
/>
) : (
<div className="flex items-center gap-2">
<Tooltip delayDuration={500}>
<TooltipTrigger asChild>
<p className="text-sm font-medium text-foreground truncate flex-1">
<p className="text-sm font-medium text-foreground truncate flex-1 leading-6">
{normalizeTitle(session.title)}
</p>
</TooltipTrigger>
Expand Down Expand Up @@ -1074,7 +1074,7 @@ export const SessionsSidebar = memo(function SessionsSidebarComponent({

{/* Archived Sessions Section */}
{(onArchiveSession || onUnarchiveSession) && (
<div className="mx-2 mb-2 shrink-0 rounded-lg border border-border bg-muted/30">
<div className="mx-3 mb-2 shrink-0 rounded-md border border-border bg-muted/30">
<Collapsible open={isArchivedExpanded} onOpenChange={setIsArchivedExpanded}>
<CollapsibleTrigger className="flex w-full items-center gap-2 px-3 py-2 text-xs text-muted-foreground hover:text-foreground rounded-lg hover:bg-muted/50 group">
<ChevronDown className="size-3 transition-transform group-data-[state=closed]:-rotate-90" />
Expand All @@ -1092,7 +1092,7 @@ export const SessionsSidebar = memo(function SessionsSidebarComponent({
) : archivedSessions.length === 0 ? (
<p className="px-3 py-3 text-xs text-muted-foreground">No archived sessions</p>
) : (
<div className="space-y-1 px-1 pb-2 max-h-[50vh] overflow-y-auto">
<div className="space-y-1 px-1 pb-1 max-h-[50vh] overflow-y-auto">
<ul className="space-y-1">
{archivedSessions.map((session) => {
const isActive = session.id === selectedSessionId;
Expand Down
Loading