diff --git a/DIVERGENCES.md b/DIVERGENCES.md index 303dedab79..562fa54a12 100644 --- a/DIVERGENCES.md +++ b/DIVERGENCES.md @@ -119,6 +119,7 @@ from the squash message first, or use a plain merge. | `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` | The busy-state footer arm (`status().type !== "idle"`) also renders `props.hint` after the `esc interrupt` text, gated on `status().type !== "retry"` | The hidden-sidebar hint (see the `routes/session/index.tsx` hint row) only rendered in the footer `Switch`'s idle fallback arm, so it vanished for the whole duration of a running turn — exactly when todos are being created. Retry keeps its `space-between` error row uncluttered. | Keep the `{props.hint}` line in the busy `Match` arm (additive); take upstream's surrounding changes. | | `packages/tui/src/component/prompt/index.tsx` | Removed the editor open-file label from the footer's right-side group and lifted the state behind it out of `Prompt`: the local `dismissedEditorSelectionKey` signal and the `editorContext`/`editorPath`/`editorSelectionLabel`/`editorFileLabel`/`editorFileLabelDisplay`/`editorContextLabelState` memos are gone, replaced by `useEditorLabel()` (fork-only `src/context/editor-label.tsx`) — `selection()` feeds the `prompt.editor_context.clear` `enabled` predicate and the submit-time editor part, `state()` replaces `editor.labelState()` there, and `dismiss()` replaces the local `dismissEditorContext`. The pure helpers `hasEditorRangeSelection`/`getEditorRangeLabel` moved to that context module and are imported back for `formatEditorContext`. | The label now lives in the sidebar footer (see its row above). The dismissal state had to move with it: the sidebar must label the *effective* selection — the one this file actually attaches on submit — or it would advertise context the prompt has dismissed and won't send. | Keep the deletions, the `useEditorLabel` import + its three call sites, and the helper import from `../../context/editor-label`; take upstream's surrounding changes. If upstream reworks the editor-context label, apply the change to `editorContextFileLabel` in the fork-only sidebar module rather than restoring the footer render. | +| `packages/tui/src/routes/session/index.tsx`, `packages/tui/src/component/prompt/index.tsx` | Left accent border removed entirely: the user-message block's `border={["left"]}`/`borderColor` (agent accent)/`customBorderChars` props and the prompt input box's two bordered boxes (main box with its `bottomLeft: "╹"` char, plus the height-1 `╹` terminator row) are replaced with `paddingLeft={1}`; the now-unused `borderHighlight` memo and the `tint`/`SplitBorder` imports are removed from the prompt (the `highlight`/`agentMetaAlpha` memos stay — they still color the agent name label); the fork's in-scrollbox banner box gains `paddingLeft={1}` so the banner/tips left edge lines up with the prompt/message blocks' background edge (the removed border glyph used to occupy that aligned column) | No vertical accent line next to sent messages or the prompt — removed rather than recolored to the background because background-colored glyphs render oddly on some terminals (e.g. PowerShell). `paddingLeft={1}` keeps the same 1-column offset, so text alignment with other transcript blocks is unchanged. | Keep our `paddingLeft={1}` boxes and the `borderHighlight`/`tint`/`SplitBorder` removals; take upstream's surrounding changes. If upstream adds new accent-colored left borders to these blocks, replace them with `paddingLeft={1}` the same way. | | `packages/tui/src/app.tsx` | Mounted `` (fork-only `./context/editor-label`) immediately inside `` | The effective-editor-selection state is shared by the prompt and the sidebar footer, so it has to be provided above both. | Keep the import and the wrapper; take upstream's surrounding provider changes. If upstream moves `EditorContextProvider`, keep ours directly inside it. | | `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; since v1.18.3 upstream itself removed the sibling `HelpButton`, so nothing is imported from `help-button` anymore) | `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. | diff --git a/packages/tui/src/component/prompt/index.tsx b/packages/tui/src/component/prompt/index.tsx index e420897258..ba0a3cfd38 100644 --- a/packages/tui/src/component/prompt/index.tsx +++ b/packages/tui/src/component/prompt/index.tsx @@ -15,8 +15,8 @@ import path from "path" import { fileURLToPath } from "url" import { useLocal } from "../../context/local" import { Flag } from "@opencode-ai/core/flag/flag" -import { tint, useTheme } from "../../context/theme" -import { EmptyBorder, SplitBorder } from "../../ui/border" +import { useTheme } from "../../context/theme" +import { EmptyBorder } from "../../ui/border" import { useTuiPaths, useTuiTerminalEnvironment } from "../../context/runtime" import { useClipboard } from "../../context/clipboard" import { Spinner } from "../spinner" @@ -1301,7 +1301,6 @@ export function Prompt(props: PromptProps) { () => !!local.agent.current() && store.mode === "normal" && showVariant(), animationsEnabled, ) - const borderHighlight = createMemo(() => tint(theme.border, highlight(), agentMetaAlpha())) const placeholderText = createMemo(() => { if (props.showPlaceholder === false) return undefined @@ -1343,15 +1342,7 @@ export function Prompt(props: PromptProps) { return ( <> <box ref={(r: BoxRenderable) => (anchor = r)} visible={props.visible !== false} width="100%"> - <box - width="100%" - border={["left"]} - borderColor={borderHighlight()} - customBorderChars={{ - ...SplitBorder.customBorderChars, - bottomLeft: "╹", - }} - > + <box width="100%" paddingLeft={1}> <box paddingLeft={2} paddingRight={2} @@ -1477,15 +1468,7 @@ export function Prompt(props: PromptProps) { </box> </box> </box> - <box - height={1} - border={["left"]} - borderColor={borderHighlight()} - customBorderChars={{ - ...EmptyBorder, - vertical: theme.backgroundElement.a !== 0 ? "╹" : " ", - }} - > + <box height={1} paddingLeft={1}> <box height={1} border={["bottom"]} diff --git a/packages/tui/src/routes/session/index.tsx b/packages/tui/src/routes/session/index.tsx index 88740121f4..59ccd56e08 100644 --- a/packages/tui/src/routes/session/index.tsx +++ b/packages/tui/src/routes/session/index.tsx @@ -1220,7 +1220,8 @@ export function Session() { {/* Fork: the transcript opens with a home-like banner that scrolls away with the history. */} <Show when={!session()?.parentID} fallback={<box height={1} />}> - <box flexShrink={0} alignItems="flex-start" paddingTop={1} paddingBottom={1} gap={1}> + {/* paddingLeft matches the prompt/message blocks' background edge */} + <box flexShrink={0} alignItems="flex-start" paddingTop={1} paddingBottom={1} paddingLeft={1} gap={1}> <Logo /> <pluginRuntime.Slot name="home_bottom" placement="start" /> </box> @@ -1439,9 +1440,7 @@ function UserMessage(props: { <box id={props.message.id} ref={(el: BoxRenderable) => alwaysSeparate.add(el)} - border={["left"]} - borderColor={color()} - customBorderChars={SplitBorder.customBorderChars} + paddingLeft={1} marginTop={props.index === 0 ? 0 : 1} > <box