From 73e88c4ffb43bf9167758620bcd8be40ab2a8368 Mon Sep 17 00:00:00 2001 From: minhn4 Date: Tue, 14 Jul 2026 08:40:13 +0700 Subject: [PATCH 1/2] feat(tui): show cwd and branch in prompt footer Add a directory label to the prompt footer's right-side group, left of the editor open-file label: abbreviated cwd with a :branch suffix when known, middle-truncated to the same width cap as the file label. The last path segment plus branch render in the text color with the parent path muted, matching the sidebar footer's styling. Co-Authored-By: Claude Fable 5 --- DIVERGENCES.md | 1 + packages/tui/src/component/prompt/index.tsx | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/DIVERGENCES.md b/DIVERGENCES.md index 4775fdfdff..41aa9e2802 100644 --- a/DIVERGENCES.md +++ b/DIVERGENCES.md @@ -100,6 +100,7 @@ from the squash message first, or use a plain merge. | Config-dir rename: `packages/opencode/src/config/{paths,config,tui}.ts`, `packages/core/src/config.ts`, `packages/opencode/src/plugin/install.ts`, `packages/opencode/src/plugin/tui/runtime.ts`, `packages/tui/src/context/theme.tsx`, `packages/opencode/src/cli/cmd/{agent,mcp}.ts`, `packages/opencode/src/session/session.ts`, plan permission patterns (`packages/opencode/src/agent/agent.ts`, `packages/core/src/plugin/agent.ts`), TUI tips, skill descriptions, `customize-opencode.md`, `specs/tui-plugins.md`, tests creating `.opencode` fixtures, docs (en + es) | Config directory `.opencode` → `.codev` (project walk-up, `~/.codev`, plans dir, theme/plugin discovery) | The fork's config surface uses the fork's name; hard rename, no legacy fallback. NOT renamed: `~/.opencode/bin` install paths (binary location — see installation/uninstall rows), the `ai.opencode.managed` plist domain, identifiers like provider id `opencode` and theme asset keys. | Keep our dir name; take upstream's surrounding logic. Rename any new upstream `.opencode` dir reference to `.codev` (leave `~/.opencode/bin`). | | `packages/tui/src/component/dialog-provider.tsx`, `packages/tui/src/component/dialog-model.tsx`, `packages/opencode/src/cli/cmd/providers.ts` | Filter `opencode`/`opencode-go` out of provider pickers and the `/model` dialog (model list + Favorites/Recent; the model dialog's opencode-first sort became a plain name sort) | Upstream's hosted offerings (Zen/Go) are detours for gateway users. | Keep our filters. | | `packages/tui/src/component/prompt/index.tsx` | Gated the prompt footer's model/provider indicator on `useConnected()` (the shared "a real provider is configured" predicate) | Don't advertise the free hosted Zen default (e.g. "Big Pickle · OpenCode Zen") in the footer while nothing is configured — same rationale and predicate as `app.tsx`'s startup gate and the provider/model filters. A configured gateway/real provider, or a deliberately-authenticated opencode/opencode-go, still shows its model. | Keep the extra `Show` condition; take upstream's surrounding changes. | +| `packages/tui/src/component/prompt/index.tsx` | Added a `directoryLabel` (abbreviated cwd, `:branch` suffix when known, middle-truncated; last path segment + branch in text color, parent path muted, matching the sidebar footer) rendered as the first item of the prompt footer's right-side group, left of the editor open-file label | Keep the working directory and branch visible at a glance from the prompt (the home-footer `Directory` only shows once a destination is selected, and the sidebar — the other place showing the branch — is hidden by default). | Keep the `directoryLabel` memo, its `abbreviateHome` import, and the extra ``; take upstream's surrounding footer changes. | | `packages/app/index.html` | `` → "CoDev Code" | Web UI tab title. | Keep our title. | | `packages/app/src/pages/layout.tsx`, `packages/app/src/pages/layout-new.tsx` | Dropped the `<TabsInfoPopup />` mount and its import from both layouts (added upstream in v1.17.18); `HelpButton` stays. | `TabsInfoPopup` is a dev-channel-only "Introducing Tabs" promo whose `muted autoplay loop` `<video>` mounts on every layout render. The fork's Windows e2e runs on GPU-less GitHub-hosted runners (software GPU — see the runner-swap row), where continuous video decode wedges the GPU command buffer (`kTransientFailure`), making the whole app-e2e suite flaky and ~3–5× slower. It never ships (release builds use a non-`dev` `CODEV_CHANNEL`), so unmounting it costs users nothing. | Keep ours: don't re-add the `<TabsInfoPopup />` mount or restore it to the import. | | `packages/app/src/components/help-button.tsx` | Removed the `TabsInfoPopup` component, its `introducing-tabs.mp4` import, and the imports only it used; `HelpButton` stays. (The file's `VITE_OPENCODE_CHANNEL` → `VITE_CODEV_CHANNEL` gates follow the env-var rename row.) | The popup is upstream's temporary, OpenCode-branded "Introducing Tabs" promo (upstream's own comment says it's removable after the rollout), already unmounted per the row above; removing the definition lets the 13 MB video be deleted (row below). | Keep our removal; take upstream's changes to `HelpButton`. If upstream mounts `TabsInfoPopup` somewhere new, drop that mount per the row above. When upstream deletes the popup itself, this row and the two rows around it retire. | diff --git a/packages/tui/src/component/prompt/index.tsx b/packages/tui/src/component/prompt/index.tsx index bb1d98d831..72d8afd178 100644 --- a/packages/tui/src/component/prompt/index.tsx +++ b/packages/tui/src/component/prompt/index.tsx @@ -18,6 +18,7 @@ import { Flag } from "@opencode-ai/core/flag/flag" import { tint, useTheme } from "../../context/theme" import { EmptyBorder, SplitBorder } from "../../ui/border" import { useTuiPaths, useTuiTerminalEnvironment } from "../../context/runtime" +import { abbreviateHome } from "../../runtime" import { useClipboard } from "../../context/clipboard" import { Spinner } from "../spinner" import { useSDK } from "../../context/sdk" @@ -205,6 +206,19 @@ export function Prompt(props: PromptProps) { return Locale.truncateMiddle(file, Math.max(12, Math.min(48, Math.floor(dimensions().width / 3)))) }) const editorContextLabelState = createMemo(() => editor.labelState()) + const directoryLabel = createMemo(() => { + const label = abbreviateHome(project.instance.directory() || paths.cwd, paths.home) + const branch = sync.data.vcs?.branch + const full = Locale.truncateMiddle( + branch ? `${label}:${branch}` : label, + Math.max(12, Math.min(48, Math.floor(dimensions().width / 3))), + ) + const list = full.split("/") + return { + parent: list.length > 1 ? list.slice(0, -1).join("/") + "/" : undefined, + name: list.at(-1) ?? "", + } + }) const [auto, setAuto] = createSignal<AutocompleteRef>() const workspace = usePromptWorkspace(props.sessionID) const move = usePromptMove({ projectID: project.project, sessionID: () => props.sessionID }) @@ -1649,6 +1663,12 @@ export function Prompt(props: PromptProps) { </Switch> <Show when={status().type !== "retry"}> <box gap={2} flexDirection="row"> + <text fg={theme.text}> + <Show when={directoryLabel().parent}> + <span style={{ fg: theme.textMuted }}>{directoryLabel().parent}</span> + </Show> + {directoryLabel().name} + </text> <Show when={editorContextLabelState() !== "none" ? editorFileLabelDisplay() : undefined}> {(file) => ( <text fg={editorContextLabelState() === "pending" ? theme.secondary : theme.textMuted}>{file()}</text> From 493a7da34a77339a9ef616e757ad285096c0ee60 Mon Sep 17 00:00:00 2001 From: minhn4 <nguyenm.cuny@gmail.com> Date: Tue, 14 Jul 2026 09:22:59 +0700 Subject: [PATCH 2/2] docs: link upstream PR for double Ctrl+C entry Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 622d204637..39eec039ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -62,5 +62,7 @@ file is the human-readable summary of what changed and why. shows "Press Ctrl+C again to exit" and only quits on a second press within 2s. `Ctrl+D`, `<leader>q`, and `/exit`·`/quit`·`/q` still quit immediately; with text in the prompt, `Ctrl+C` still just clears it, and modal question/permission - prompts keep their single-press cancel behavior. + prompts keep their single-press cancel behavior. Submitted upstream as + [anomalyco/opencode#36613](https://github.com/anomalyco/opencode/pull/36613); + if it lands there, this entry retires. ([#51](https://github.com/quickbeard/codev-code/pull/51))