Skip to content

Commit d88550f

Browse files
committed
feat: implement Git sidebar panel and enhance workspace layout
- Introduced a new GitSidebarPanel component for managing Git changes, including staging, unstaging, and discarding files. - Updated the WorkspaceSidebar to include a button for creating new threads and improved thread preview handling. - Enhanced the EditorLayout to always display the Git sidebar in chat mode and adjusted the visibility logic for the workspace sidebar. - Refactored global styles to support the new Codex layout, including transitions and hover effects for sidebar elements. - Updated layout context to support the new gitPanel, ensuring it integrates seamlessly with existing panel management.
1 parent a012249 commit d88550f

8 files changed

Lines changed: 1007 additions & 655 deletions

File tree

app/globals.css

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4757,3 +4757,127 @@ p {
47574757
box-shadow: 0 0 0 1px color-mix(in srgb, var(--brand) 20%, transparent);
47584758
}
47594759
}
4760+
4761+
/* ─── Codex Layout: Sidebar ─────────────────────────────── */
4762+
4763+
.codex-sidebar {
4764+
transition: width 200ms cubic-bezier(0.22, 1, 0.36, 1);
4765+
}
4766+
4767+
.codex-sidebar-new-thread:hover {
4768+
transform: translateY(-0.5px);
4769+
}
4770+
4771+
.codex-sidebar-thread {
4772+
border: 1px solid transparent;
4773+
}
4774+
.codex-sidebar-thread:hover {
4775+
border-color: var(--border);
4776+
}
4777+
4778+
/* ─── Codex Layout: Git Sidebar Panel ────────────────────── */
4779+
4780+
.codex-git-sidebar {
4781+
position: relative;
4782+
background: var(--bg-elevated);
4783+
border-left: 1px solid var(--border);
4784+
border-radius: 0 12px 12px 0;
4785+
overflow: hidden;
4786+
}
4787+
4788+
.codex-git-tab {
4789+
border: 1px solid transparent;
4790+
transition: all 150ms;
4791+
}
4792+
.codex-git-tab:hover {
4793+
border-color: var(--border);
4794+
}
4795+
4796+
.codex-git-file {
4797+
border: 1px solid transparent;
4798+
}
4799+
.codex-git-file:hover {
4800+
border-color: var(--border);
4801+
}
4802+
4803+
.codex-git-dropdown {
4804+
animation: codex-dropdown-in 120ms ease-out;
4805+
}
4806+
4807+
@keyframes codex-dropdown-in {
4808+
from {
4809+
opacity: 0;
4810+
transform: translateY(-4px) scale(0.97);
4811+
}
4812+
to {
4813+
opacity: 1;
4814+
transform: translateY(0) scale(1);
4815+
}
4816+
}
4817+
4818+
.codex-git-badge {
4819+
letter-spacing: 0.02em;
4820+
}
4821+
4822+
.codex-git-action-btn:not(:disabled):hover {
4823+
transform: translateY(-0.5px);
4824+
}
4825+
4826+
.codex-git-bottom-bar {
4827+
background: color-mix(in srgb, var(--bg-elevated) 95%, transparent);
4828+
}
4829+
4830+
/* ─── Codex Layout: Header ───────────────────────────────── */
4831+
4832+
.codex-header-btn {
4833+
border: 1px solid transparent;
4834+
}
4835+
.codex-header-btn:hover {
4836+
border-color: var(--border);
4837+
}
4838+
4839+
.codex-header-badge {
4840+
letter-spacing: 0.02em;
4841+
}
4842+
4843+
/* ─── Codex Layout: Home / Composer ──────────────────────── */
4844+
4845+
.codex-workspace-dropdown {
4846+
font-weight: 500;
4847+
}
4848+
.codex-workspace-dropdown:hover {
4849+
text-decoration: underline;
4850+
text-underline-offset: 3px;
4851+
}
4852+
4853+
.codex-suggestion-card {
4854+
transition: all 200ms ease;
4855+
}
4856+
.codex-suggestion-card:hover {
4857+
transform: translateY(-2px);
4858+
box-shadow: 0 4px 12px color-mix(in srgb, var(--text-primary) 6%, transparent);
4859+
}
4860+
4861+
.codex-composer {
4862+
transition:
4863+
border-color 200ms,
4864+
box-shadow 200ms;
4865+
}
4866+
.codex-composer:focus-within {
4867+
box-shadow: 0 0 0 1px color-mix(in srgb, var(--brand) 15%, transparent);
4868+
}
4869+
4870+
.codex-pill {
4871+
transition: all 150ms;
4872+
}
4873+
4874+
.codex-send-btn {
4875+
transition: all 150ms;
4876+
}
4877+
4878+
/* Responsive: stack suggestion cards on narrow screens */
4879+
@media (max-width: 640px) {
4880+
.codex-suggestion-grid {
4881+
grid-template-columns: 1fr;
4882+
}
4883+
}

app/page.tsx

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ import { emit, on } from '@/lib/events'
3131
import { KnotLogo } from '@/components/knot-logo'
3232
import type { AppMode } from '@/lib/mode-registry'
3333

34+
const GitSidebarPanel = dynamic(
35+
() => import('@/components/git-sidebar-panel').then((m) => ({ default: m.GitSidebarPanel })),
36+
{ ssr: false },
37+
)
38+
3439
// Overlay modals — lazy loaded
3540
const QuickOpen = dynamic(
3641
() => import('@/components/quick-open').then((m) => ({ default: m.QuickOpen })),
@@ -411,10 +416,10 @@ export default function EditorLayout() {
411416
/>
412417
)}
413418

414-
{/* Workspace Sidebar */}
415-
{mode !== 'tui' && (mode !== 'chat' || layout.isVisible('sidebar')) && (
419+
{/* Workspace Sidebar — always visible in chat mode, toggleable otherwise */}
420+
{mode !== 'tui' && (
416421
<WorkspaceSidebar
417-
collapsed={sidebarCollapsed}
422+
collapsed={mode !== 'chat' && sidebarCollapsed}
418423
onToggle={() => layout.toggle('sidebar')}
419424
repoName={repo?.fullName || localRootPath?.split('/').pop()}
420425
/>
@@ -487,21 +492,30 @@ export default function EditorLayout() {
487492
</div>
488493
)}
489494

490-
{/* Minimal header with brand when tabs are hidden */}
495+
{/* Codex-style header with Open + Commit dropdowns when tabs are hidden */}
491496
{modeSpec.hideTabs && (
492-
<div className="flex items-center gap-2.5 tauri-no-drag">
493-
<KnotLogo size={22} className="text-[var(--brand)]" />
494-
<span className="text-[14px] font-semibold text-[var(--text-primary)] tracking-[-0.01em]">
495-
KnotCode
496-
</span>
497-
{localRootPath && (
498-
<>
499-
<span className="text-[var(--text-disabled)]">&middot;</span>
500-
<span className="text-[12px] font-mono text-[var(--text-disabled)] truncate max-w-[200px]">
501-
{localRootPath.split('/').pop()}
502-
</span>
503-
</>
504-
)}
497+
<div className="flex items-center gap-1.5 tauri-no-drag">
498+
{/* Open dropdown */}
499+
<button
500+
onClick={() => emit('open-folder')}
501+
className="codex-header-btn flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-[12px] font-medium text-[var(--text-secondary)] hover:bg-[color-mix(in_srgb,var(--text-primary)_6%,transparent)] hover:text-[var(--text-primary)] transition-all cursor-pointer"
502+
>
503+
<Icon icon="lucide:folder-open" width={14} height={14} />
504+
Open
505+
<Icon icon="lucide:chevron-down" width={10} height={10} className="opacity-50" />
506+
</button>
507+
508+
<span className="text-[var(--text-disabled)] text-[11px]">&middot;</span>
509+
510+
{/* Commit dropdown */}
511+
<button
512+
onClick={() => setView('git')}
513+
className="codex-header-btn flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-[12px] font-medium text-[var(--text-secondary)] hover:bg-[color-mix(in_srgb,var(--text-primary)_6%,transparent)] hover:text-[var(--text-primary)] transition-all cursor-pointer"
514+
>
515+
<Icon icon="lucide:git-commit-horizontal" width={14} height={14} />
516+
Commit
517+
<Icon icon="lucide:chevron-down" width={10} height={10} className="opacity-50" />
518+
</button>
505519
</div>
506520
)}
507521

@@ -529,6 +543,18 @@ export default function EditorLayout() {
529543
))}
530544
</div>
531545

546+
{/* Change count badges */}
547+
{dirtyCount > 0 && (
548+
<div className="tauri-no-drag flex items-center gap-1.5 mr-1">
549+
<span className="codex-header-badge text-[10px] font-mono font-bold px-1.5 py-0.5 rounded text-[var(--color-additions,#22c55e)] bg-[color-mix(in_srgb,var(--color-additions,#22c55e)_10%,transparent)]">
550+
+{dirtyCount}
551+
</span>
552+
<span className="codex-header-badge text-[10px] font-mono font-bold px-1.5 py-0.5 rounded text-[var(--color-deletions,#ef4444)] bg-[color-mix(in_srgb,var(--color-deletions,#ef4444)_10%,transparent)]">
553+
-{dirtyCount}
554+
</span>
555+
</div>
556+
)}
557+
532558
{/* Settings */}
533559
<button
534560
onClick={() => setSettingsVisible(true)}
@@ -698,6 +724,9 @@ export default function EditorLayout() {
698724
<StatusBar agentActive={agentActive} />
699725
</div>
700726

727+
{/* Git sidebar panel — Codex-style always-visible right panel */}
728+
{mode !== 'tui' && layout.isVisible('gitPanel') && <GitSidebarPanel />}
729+
701730
{/* Sidebar plugins (Spotify, etc.) */}
702731
<SidebarPluginSlot />
703732

0 commit comments

Comments
 (0)