From ea1aba4192fd356603e807144edf202328008ee6 Mon Sep 17 00:00:00 2001
From: Adam <2363879+adamdotdevin@users.noreply.github.com>
Date: Mon, 2 Feb 2026 07:02:40 -0600
Subject: feat(app): project context menu on right-click
---
packages/app/src/pages/layout.tsx | 107 +++++++++++++++++++++++++++-----------
1 file changed, 78 insertions(+), 29 deletions(-)
(limited to 'packages/app/src')
diff --git a/packages/app/src/pages/layout.tsx b/packages/app/src/pages/layout.tsx
index a970bf667..5a8dc0f2e 100644
--- a/packages/app/src/pages/layout.tsx
+++ b/packages/app/src/pages/layout.tsx
@@ -31,6 +31,7 @@ import { Tooltip, TooltipKeybind } from "@opencode-ai/ui/tooltip"
import { HoverCard } from "@opencode-ai/ui/hover-card"
import { MessageNav } from "@opencode-ai/ui/message-nav"
import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu"
+import { ContextMenu } from "@opencode-ai/ui/context-menu"
import { Collapsible } from "@opencode-ai/ui/collapsible"
import { DiffChanges } from "@opencode-ai/ui/diff-changes"
import { Spinner } from "@opencode-ai/ui/spinner"
@@ -2310,10 +2311,13 @@ export default function Layout(props: ParentProps) {
() => props.project.vcs === "git" && layout.sidebar.workspaces(props.project.worktree)(),
)
const [open, setOpen] = createSignal(false)
+ const [menu, setMenu] = createSignal(false)
const preview = createMemo(() => !props.mobile && layout.sidebar.opened())
const overlay = createMemo(() => !props.mobile && !layout.sidebar.opened())
- const active = createMemo(() => (preview() ? open() : overlay() && state.hoverProject === props.project.worktree))
+ const active = createMemo(
+ () => menu() || (preview() ? open() : overlay() && state.hoverProject === props.project.worktree),
+ )
createEffect(() => {
if (preview()) return
@@ -2352,35 +2356,79 @@ export default function Layout(props: ParentProps) {
const projectName = () => props.project.name || getFilename(props.project.worktree)
const trigger = (
-
+