From 4711ad2c28d7c23b37daeda47395b5914e755866 Mon Sep 17 00:00:00 2001 From: Sanchit Rk <0xsanchit@gmail.com> Date: Fri, 23 Oct 2026 13:12:17 +0530 Subject: [PATCH 01/27] chore --- pnpm-lock.yaml | 122 ++++++++++++++++++++++++------------------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fd287038..01f78391 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,153 +7,153 @@ importers: configDependencies: {} packageManagerDependencies: pnpm: - specifier: 12.6.0 - version: 12.6.0 + specifier: 12.14.0 + version: 12.14.0 packages: - '@pnpm/exe.android-arm64@12.6.0': - resolution: {integrity: sha512-kviIHft9h02q+7N2In7tSL9T/HRUSGwYmU74YPtsWU5ee7vgqPyC0JT6RRX6miW+NxX1CvHgQxg69qq1qTLJYQ==} + '@pnpm/exe.android-arm64@12.14.0': + resolution: {integrity: sha512-+iSh7x21C3A2hqc+Z0ZmbKTcn6YNlzrXM142PsnQH/dLj0DYxFzoBvc6XAnL/yfQ5nnH2ebBiRj/zVxr61fZbQ==} cpu: [arm64] os: [android] - '@pnpm/exe.android-x64@12.6.0': - resolution: {integrity: sha512-CT8aJKLq2mtZFE71pr4E5Z2xHL8uGnRGr+NclDqsXlVF4SVcQ2QAs14mWi0C8gjT4hbmi+Q0lJRRIkMAWfjjng==} + '@pnpm/exe.android-x64@12.14.0': + resolution: {integrity: sha512-qT+0LqEr2wBVaxcG2T8cX/R8SSRz2Rvpp8nRR4fh8tnGUZRch87gFmsHUAoSQh7w6j1h0qTjrA384j4xi8frvw==} cpu: [x64] os: [android] - '@pnpm/exe.darwin-arm64@12.6.0': - resolution: {integrity: sha512-rafpVkjzugKBMxSvGQd5wK1x5eOTkD/+lcJIFHeQhvd+BJ8kDisOOvwhQDrpGd4vd2Fx+hhW0P2Ptt638OlhFg==} + '@pnpm/exe.darwin-arm64@12.14.0': + resolution: {integrity: sha512-tnrdUB8ecJoehuKKqi1YHCBVl61xtJ9XVGcx5EviC6fWO4DeGI8GtXrjvJxDBM3nuVjJeWistgsUp/N142x4sw==} cpu: [arm64] os: [darwin] - '@pnpm/exe.darwin-x64@12.6.0': - resolution: {integrity: sha512-72Jpuv1m24gI8zUNcaylYpBWEhBzz1VPhnDIU2GYM2eRP+KsOqVLwV78i+JrihI39zY2NNXmaN4eAKX1inpaDQ==} + '@pnpm/exe.darwin-x64@12.14.0': + resolution: {integrity: sha512-vlBfGkruqQRsEHTW43cPwpYd7QlbIJ//cvpAdb3bVXkI8SgTPoXhCnc05m+ZNiPrrEkBsX/t7KHw9aXpkzPm3Q==} cpu: [x64] os: [darwin] - '@pnpm/exe.freebsd-x64@12.6.0': - resolution: {integrity: sha512-LON4QgNy1w/XF4uySZIyC/5hEB0oGdelXsY9tSKqstER+2j2X2oHz67skD11RRd/HWFRtMr64shQZ4I9ZoZ0zg==} + '@pnpm/exe.freebsd-x64@12.14.0': + resolution: {integrity: sha512-Qg5rxBrGYl6Tfso+EyygPf84fY1Fzy55E/0or+iuYKtnf0vc0MlHJfVIlT7pBukMRntQHRik7hUi0Z4s7AlJsw==} cpu: [x64] os: [freebsd] - '@pnpm/exe.linux-arm64-musl@12.6.0': - resolution: {integrity: sha512-BdDpX+DeaMUc5x6WNcE6FkmFy36NwrBbBvwsZU737Zt3u1fTY+iKFPchjEQNCM4rT6q6xvF2oN3ZwExGsJCkxQ==} + '@pnpm/exe.linux-arm64-musl@12.14.0': + resolution: {integrity: sha512-DRIe4yQkXBGA/PhVJdzlbnllxBdAtnMMvTVLLcGpsK5FvJz9kxD2Hyxtn68ovmNkVX06f6p45cQwfm3wx2jn1A==} cpu: [arm64] os: [linux] libc: [musl] - '@pnpm/exe.linux-arm64@12.6.0': - resolution: {integrity: sha512-8h2sNoIhHDpHDYqZZCh9PXr6krqW10btb0GHVGuw710muDHlFAHMtUG2ogmaHge6zJG1xgY4Y7mwX5g/LWvrYg==} + '@pnpm/exe.linux-arm64@12.14.0': + resolution: {integrity: sha512-7joGShZ44Nk3WpNU+60JoOPjCXlgxhJAq11S2UiVtwCUDgTer1yTPPfxGW8pxaD6046actYLIYDbZNlubHWs0A==} cpu: [arm64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-ppc64@12.6.0': - resolution: {integrity: sha512-ld6xgcEhFCFrsVsJhbmdmR714PnsEspO/Ij8w0/D7OSiz2hYGu3fZd5tKRxOI5m6H6Gl0/RRFAPncTHbsgXVjQ==} + '@pnpm/exe.linux-ppc64@12.14.0': + resolution: {integrity: sha512-gSoryn7ySdXd//gjgf3MvvA8ZerJayaSbuMZMtAWq4vb2/wlVEgpl0Kvqt54y58TRj533Qjq2txKgnxd4JyoAQ==} cpu: [ppc64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-riscv64@12.6.0': - resolution: {integrity: sha512-HIbImydoC3J8NFt+8MXfhTCf5rO6NjCMyinSAHac0VmV8uCHw+kbQkyAzxV84rzz9ZOzmBOnj0b1N461UIYGsw==} + '@pnpm/exe.linux-riscv64@12.14.0': + resolution: {integrity: sha512-EMjew1H9WqQ7pL+tYqCPwiuB+0PeCiJRV7fyWeuFw0wwYUajFBjcaPO3IGAVu9sdmJDU+e+HYv/Zey6aKae0Vw==} cpu: [riscv64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-s390x@12.6.0': - resolution: {integrity: sha512-DjSqT7+BZ/lWcDHwNMuzsRVfyxUimh+D54Xw4tSWbdVVQhtWtNMUyI93LVnwCmsoEpar2gC3SFeAgywx37svKQ==} + '@pnpm/exe.linux-s390x@12.14.0': + resolution: {integrity: sha512-shYOj/SFoXD35fHe0pWr2JofwSXulC0BnEIXLj2QokDi0EF//AfKsui35yKIkTEl+s2VJybc3PO4iJNhKIj5Qw==} cpu: [s390x] os: [linux] libc: [glibc] - '@pnpm/exe.linux-x64-musl@12.6.0': - resolution: {integrity: sha512-31lKeGPmRE6xfV6I3VjaEGVFRei14pl/zgoFDK4w+UkbJqOuNl2Ht3O1GuqNIg3Gl14qTEb4kZRAYFHXifDx9A==} + '@pnpm/exe.linux-x64-musl@12.14.0': + resolution: {integrity: sha512-btZiZ2Ot0llKK1ndSfA5i3IRX7/S0VrmzseNH/BJ4c+Cady+S81H6vvU1zByggHMyqQhC8OgxO5PiIY7D9bH0Q==} cpu: [x64] os: [linux] libc: [musl] - '@pnpm/exe.linux-x64@12.6.0': - resolution: {integrity: sha512-qFWBneHJAJ73W4whtbaFOL1M/7DBC6ILHXuxc7ZPtEhfPuT1zeZiGrmKHoMAfJA+mcm6xhOFljqVTUS+00Jabw==} + '@pnpm/exe.linux-x64@12.14.0': + resolution: {integrity: sha512-F6K8e/jWxiuEYJaQtRRUG9ynBSTEHa+t7Lf86MKuOO5UA7WVVMbi+oB8nY6iKW++ncWS2yG6T9faXZGxqNsfoQ==} cpu: [x64] os: [linux] libc: [glibc] - '@pnpm/exe.win32-arm64@12.6.0': - resolution: {integrity: sha512-OhfefXEEykZlslSUhR8PPRe6MVPV3Oink/dVfIecE5velpc7j80cZYsHlaDrtRDcm3TPwQHkaRW1SJ1efX9oFg==} + '@pnpm/exe.win32-arm64@12.14.0': + resolution: {integrity: sha512-DOjlkVB6TtTKeAAe0hNZXn5S7YqESmo1Z6SGbR4BZNQ4isRg31XVHjX2RFTbY8gnZq68IwzyLmPqlEjMmYxofg==} cpu: [arm64] os: [win32] - '@pnpm/exe.win32-x64@12.6.0': - resolution: {integrity: sha512-L2tuyrD2+Imgxs3VK/ST/2L3xD6vDP0ktJQxM0TaGw7TbAQEMq+RMc8iK6Ew7Id579uzjJe8jSfJID2ZGsOHCA==} + '@pnpm/exe.win32-x64@12.14.0': + resolution: {integrity: sha512-/LSX6mew/sLf08XqcjemuklNKf1K/Ftpgj4//hK/HKzI2dKbmxDB27a/2OaQ5a0O3/3OFzlssXDziZsi+yVBwQ==} cpu: [x64] os: [win32] - pnpm@12.6.0: - resolution: {integrity: sha512-PvaPlRyxEawgS0paFvCy3fDaVqluBBPoHYVdnwtV75JnFHCQKOHNAMQFwsX7e56OxNxGd3yAXQNzwvL/AP0g7A==} + pnpm@12.14.0: + resolution: {integrity: sha512-wYum2HmT09Fky16JSPMrLAbuhUSH4GzY2GeBNC+z5btGNDZwNHEehoArqpw3vqkGzhkprQjXCITJfYAd8TOJpg==} engines: {node: '>=18.*'} hasBin: true snapshots: - '@pnpm/exe.android-arm64@12.6.0': + '@pnpm/exe.android-arm64@12.14.0': optional: true - '@pnpm/exe.android-x64@12.6.0': + '@pnpm/exe.android-x64@12.14.0': optional: true - '@pnpm/exe.darwin-arm64@12.6.0': + '@pnpm/exe.darwin-arm64@12.14.0': optional: true - '@pnpm/exe.darwin-x64@12.6.0': + '@pnpm/exe.darwin-x64@12.14.0': optional: true - '@pnpm/exe.freebsd-x64@12.6.0': + '@pnpm/exe.freebsd-x64@12.14.0': optional: true - '@pnpm/exe.linux-arm64-musl@12.6.0': + '@pnpm/exe.linux-arm64-musl@12.14.0': optional: true - '@pnpm/exe.linux-arm64@12.6.0': + '@pnpm/exe.linux-arm64@12.14.0': optional: true - '@pnpm/exe.linux-ppc64@12.6.0': + '@pnpm/exe.linux-ppc64@12.14.0': optional: true - '@pnpm/exe.linux-riscv64@12.6.0': + '@pnpm/exe.linux-riscv64@12.14.0': optional: true - '@pnpm/exe.linux-s390x@12.6.0': + '@pnpm/exe.linux-s390x@12.14.0': optional: true - '@pnpm/exe.linux-x64-musl@12.6.0': + '@pnpm/exe.linux-x64-musl@12.14.0': optional: true - '@pnpm/exe.linux-x64@12.6.0': + '@pnpm/exe.linux-x64@12.14.0': optional: true - '@pnpm/exe.win32-arm64@12.6.0': + '@pnpm/exe.win32-arm64@12.14.0': optional: true - '@pnpm/exe.win32-x64@12.6.0': + '@pnpm/exe.win32-x64@12.14.0': optional: true - pnpm@12.6.0: + pnpm@12.14.0: optionalDependencies: - '@pnpm/exe.android-arm64': 12.6.0 - '@pnpm/exe.android-x64': 12.6.0 - '@pnpm/exe.darwin-arm64': 12.6.0 - '@pnpm/exe.darwin-x64': 12.6.0 - '@pnpm/exe.freebsd-x64': 12.6.0 - '@pnpm/exe.linux-arm64': 12.6.0 - '@pnpm/exe.linux-arm64-musl': 12.6.0 - '@pnpm/exe.linux-ppc64': 12.6.0 - '@pnpm/exe.linux-riscv64': 12.6.0 - '@pnpm/exe.linux-s390x': 12.6.0 - '@pnpm/exe.linux-x64': 12.6.0 - '@pnpm/exe.linux-x64-musl': 12.6.0 - '@pnpm/exe.win32-arm64': 12.6.0 - '@pnpm/exe.win32-x64': 12.6.0 + '@pnpm/exe.android-arm64': 12.14.0 + '@pnpm/exe.android-x64': 12.14.0 + '@pnpm/exe.darwin-arm64': 12.14.0 + '@pnpm/exe.darwin-x64': 12.14.0 + '@pnpm/exe.freebsd-x64': 12.14.0 + '@pnpm/exe.linux-arm64': 12.14.0 + '@pnpm/exe.linux-arm64-musl': 12.14.0 + '@pnpm/exe.linux-ppc64': 12.14.0 + '@pnpm/exe.linux-riscv64': 12.14.0 + '@pnpm/exe.linux-s390x': 12.14.0 + '@pnpm/exe.linux-x64': 12.14.0 + '@pnpm/exe.linux-x64-musl': 12.14.0 + '@pnpm/exe.win32-arm64': 12.14.0 + '@pnpm/exe.win32-x64': 12.14.0 --- lockfileVersion: '9.0' From ebf110ca17c1fda86eab5fc0759ad6610d20c764 Mon Sep 17 00:00:00 2001 From: Sanchit Rk <0xsanchit@gmail.com> Date: Fri, 23 Oct 2026 14:24:44 +0530 Subject: [PATCH 02/27] tweaks --- apps/web/src/components/ui/sidebar.tsx | 4 +- apps/web/src/landing/empty.tsx | 2 +- apps/web/src/landing/landing.tsx | 2 - apps/web/src/landing/sidebar.tsx | 9 +-- apps/web/src/routes/__root.tsx | 16 +++-- apps/web/src/shell/navigation.tsx | 50 ++++++++++++++ apps/web/src/shell/shell.tsx | 3 - apps/web/src/shell/switcher.tsx | 24 +++---- apps/web/src/shell/titlebar.tsx | 90 ++++++++++---------------- apps/web/src/style.css | 16 +++++ 10 files changed, 130 insertions(+), 86 deletions(-) create mode 100644 apps/web/src/shell/navigation.tsx diff --git a/apps/web/src/components/ui/sidebar.tsx b/apps/web/src/components/ui/sidebar.tsx index af37dc19..1d5abfaa 100644 --- a/apps/web/src/components/ui/sidebar.tsx +++ b/apps/web/src/components/ui/sidebar.tsx @@ -360,11 +360,11 @@ function SidebarRail({ className, ...props }: React.ComponentProps<"button">) { dragged.current = false; }} className={cn( - "absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-[left,right] ease-out group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] hover:after:bg-sidebar-border sm:flex", + "absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-[left,right] ease-out group-data-[side=left]:-right-4 group-data-[side=right]:left-0 sm:flex", resizable ? "cursor-col-resize" : "in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize [[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize", - "group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full hover:group-data-[collapsible=offcanvas]:bg-sidebar", + "group-data-[collapsible=offcanvas]:translate-x-0", "[[data-side=left][data-collapsible=offcanvas]_&]:-right-2", "[[data-side=right][data-collapsible=offcanvas]_&]:-left-2", className, diff --git a/apps/web/src/landing/empty.tsx b/apps/web/src/landing/empty.tsx index 8b2581f6..0e7da481 100644 --- a/apps/web/src/landing/empty.tsx +++ b/apps/web/src/landing/empty.tsx @@ -3,7 +3,7 @@ import type { ReactNode } from "react"; /** The sidebar's message when it has nothing to list: a few quiet lines, centered, and what to do next. */ export function Empty({ children }: { children: ReactNode }) { return ( -
+
{children}
); diff --git a/apps/web/src/landing/landing.tsx b/apps/web/src/landing/landing.tsx index 22705f88..ce5bdbaf 100644 --- a/apps/web/src/landing/landing.tsx +++ b/apps/web/src/landing/landing.tsx @@ -17,7 +17,6 @@ import { sessionAddress } from "../widgets/session/address"; import { Json, type Place as Where, topics } from "../widgets/session/schema"; import { useOpenElsewhere } from "../wm/open"; import { ModelPicker, ThinkingPicker, useChoice, useModelsNotice } from "@/components/model"; -import { TitleBar } from "../shell/titlebar"; import { placeAtom, placeLabel, usePickFolder } from "./place"; import { projectsAtom } from "../widgets/session/projects"; import { Wordmark } from "./wordmark"; @@ -79,7 +78,6 @@ export function Landing() { return (
-
diff --git a/apps/web/src/landing/sidebar.tsx b/apps/web/src/landing/sidebar.tsx index c617291f..4c14f83f 100644 --- a/apps/web/src/landing/sidebar.tsx +++ b/apps/web/src/landing/sidebar.tsx @@ -9,7 +9,6 @@ import { Sidebar, SidebarContent, SidebarHeader, SidebarInput, SidebarRail } fro import { isMac, openMode } from "@codeworksh/widget/view"; import { sessionAddress } from "../widgets/session/address"; import { projectsAtom } from "../widgets/session/projects"; -import { insetTitleBar } from "../shell/titlebar"; import { focusedAtom } from "../wm/chrome"; import { deskAtom } from "../wm/instances"; import { useOpenElsewhere } from "../wm/open"; @@ -55,11 +54,9 @@ export function SessionsSidebar() { : []; return ( - + - {/* The window's drag region, clear of the macOS traffic lights. */} -
-
+
{/* The icon centers on the input alone, not on the padding below it. */}
@@ -74,7 +71,7 @@ export function SessionsSidebar() {
- + {AsyncResult.isFailure(result) ? ( // The CodeWork server is the usual reason, and the sidebar can say which state it is in and fix it. Option.exists(AsyncResult.error(result), (error) => error._tag === "Server.CodeworkUnavailable") ? ( diff --git a/apps/web/src/routes/__root.tsx b/apps/web/src/routes/__root.tsx index a9498e39..2d09bedb 100644 --- a/apps/web/src/routes/__root.tsx +++ b/apps/web/src/routes/__root.tsx @@ -5,6 +5,8 @@ import type { CSSProperties } from "react"; import { SidebarProvider } from "@/components/ui/sidebar"; import { SessionsSidebar } from "../landing/sidebar"; import { serversAtom } from "../settings/servers/local"; +import { Navigation } from "../shell/navigation"; +import { NavigationControls } from "../shell/titlebar"; import { Palette } from "../shell/palette"; // The sessions sidebar wraps every page but settings, which has its own; its open state carries over. @@ -15,13 +17,17 @@ function Root() { useAtomMount(serversAtom); return ( - {!inSettings && } -
- + +
+ + {!inSettings && } +
+ +
diff --git a/apps/web/src/shell/navigation.tsx b/apps/web/src/shell/navigation.tsx new file mode 100644 index 00000000..657c3828 --- /dev/null +++ b/apps/web/src/shell/navigation.tsx @@ -0,0 +1,50 @@ +import { Link, useLocation } from "@tanstack/react-router"; +import { House, Settings } from "lucide-react"; + +import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; + +/** App destinations stay available independently of the collapsible sessions sidebar. */ +export function Navigation() { + const pathname = useLocation({ select: (location) => location.pathname }); + return ( + + ); +} + +const destination = + "grid size-8 place-items-center rounded-lg text-ink-muted outline-none hover:bg-ink/5 hover:text-ink focus-visible:ring-2 focus-visible:ring-ring aria-[current=page]:bg-ink/8 aria-[current=page]:text-ink press [-webkit-app-region:no-drag]"; diff --git a/apps/web/src/shell/shell.tsx b/apps/web/src/shell/shell.tsx index 22d64073..6b11dcc9 100644 --- a/apps/web/src/shell/shell.tsx +++ b/apps/web/src/shell/shell.tsx @@ -7,7 +7,6 @@ import { Desktop } from "../wm/desktop"; import { deskQueryAtom } from "../wm/instances"; import { lastWorkspaceAtom, useWorkspaces, workspaceRoute, workspacesAtom } from "../wm/workspaces"; import { settingsShortcut, workspaceShortcut } from "./switcher"; -import { TitleBar } from "./titlebar"; /** * Lives in the pathless `_shell` layout so switching workspaces (a URL change) never remounts @@ -65,8 +64,6 @@ export function Shell() { return (
- {/* Settings takes the whole window, with its own bar. */} - {!inSettings && }
{ready && shown !== undefined && ( diff --git a/apps/web/src/shell/switcher.tsx b/apps/web/src/shell/switcher.tsx index bd99dbdf..72de7352 100644 --- a/apps/web/src/shell/switcher.tsx +++ b/apps/web/src/shell/switcher.tsx @@ -59,35 +59,37 @@ export function Switcher({ workspaces, active }: SwitcherProps) { }; return ( -