From c6dd17a6b0a0c80fe90d3fca3a057b3f153cfad2 Mon Sep 17 00:00:00 2001 From: minhn4 Date: Sun, 12 Jul 2026 23:45:52 +0700 Subject: [PATCH 1/4] feat(tui): show a banner in empty sessions Startup now lands in an empty session instead of the home screen, which left a large blank void above the prompt. Fill it with the centered codev wordmark and an "Ask anything..." hint, rendered only while the session has no messages; the transcript scrollbox collapses until the first message arrives and reclaims the space afterwards. Co-Authored-By: Claude Fable 5 --- DIVERGENCES.md | 1 + packages/tui/src/routes/session/index.tsx | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/DIVERGENCES.md b/DIVERGENCES.md index 748c6d364d..7f1ecf21cc 100644 --- a/DIVERGENCES.md +++ b/DIVERGENCES.md @@ -37,6 +37,7 @@ upstream maintainers — see README → Syncing with upstream for why and how. | `packages/tui/src/feature-plugins/sidebar/footer.tsx` | Sidebar footer wordmark: upstream's two-tone "Open"+"Code" spans → a single "CoDev" span (text color, bold) | Upstream splits the wordmark across two spans, so it never matched `opencode` greps and survived earlier rebrand passes. | Keep our span; take upstream's surrounding changes. | | `packages/opencode/src/cli/cmd/*.ts` (tui, run, serve, attach, pr, upgrade, uninstall, web) | Help `describe` strings "opencode" → "codev" | `--help` is the first thing users read. | Keep our strings. | | `packages/tui/src/app.tsx` | Terminal title "OpenCode"/"OC \|" → "CoDev Code"/"CC \|"; startup dialog effect gates on `!useConnected()` (not `provider.length === 0` — hosted Zen free models always register) and opens the fork's `DialogConfigure` (component/dialog-configure.tsx, new file); added the `codev.configure` command (`/configure`) and a `CODEV_CONFIGURE=1` mount hook for `codev configure`; home screen skipped — plain startup seeds the `dummy` session route and auto-opens a new empty session (reusing a leftover default-titled empty one via `openNewSession`/`findEmptySession`), `session.new` and the current-session `session.deleted` handler open a new session instead of navigating home, and the `-c` resolver prefers non-default-titled sessions so it lands on the last real conversation | Tab title branding; first-run setup routes to the CoDev gateway configure flow (upstream's `/connect` stays as the escape hatch); `codev` starts directly in the session layout instead of the home screen. | Keep our strings, gate condition, dialog swap + command block, route seed, `openNewSession`/`findEmptySession` + call sites, and the `-c` default-title filter; take upstream's surrounding changes. | +| `packages/tui/src/routes/session/index.tsx` | Empty-session banner: when the session has no messages, the transcript area shows the centered `Logo` wordmark plus an "Ask anything..." hint, and the scrollbox collapses (`flexGrow` 0) until the first message | Startup lands in an empty session instead of the home screen; without this the transcript is a large blank void above the prompt. | Keep our banner block + conditional `flexGrow`; take upstream's surrounding changes. | | `packages/tui/src/routes/session/permission.tsx`, `packages/opencode/src/cli/cmd/run/permission.shared.ts`, `packages/opencode/test/cli/run/permission.shared.test.ts`, `packages/tui/src/component/error-component.tsx`, `packages/opencode/src/cli/cmd/run/splash.ts` | Visible sentences/badges "OpenCode"/"opencode" → "CoDev Code"/"codev-code" (incl. the permission always-allow copy and its test expectations) | User-facing copy. | Keep our strings. | | `packages/opencode/src/installation/index.ts` | Updater detects/queries/installs `codev-code` (npm-family); GitHub fallback → quickbeard/codev-code | `codev-code upgrade` and the update notification target OUR npm package, never stock opencode. brew/choco/scoop probes never match (no such packages). | Keep our package names. | | `packages/opencode/src/config/config.ts` | `share` defaults to `"disabled"` when unset | Sharing publishes sessions to upstream's share service; internal users must opt in via config. | Keep our default block. | diff --git a/packages/tui/src/routes/session/index.tsx b/packages/tui/src/routes/session/index.tsx index f2f2a67fd3..04e0a2811f 100644 --- a/packages/tui/src/routes/session/index.tsx +++ b/packages/tui/src/routes/session/index.tsx @@ -53,6 +53,7 @@ import { DialogConfirm } from "../../ui/dialog-confirm" import { DialogTimeline } from "./dialog-timeline" import { DialogForkFromTimeline } from "./dialog-fork-from-timeline" import { DialogSessionRename } from "../../component/dialog-session-rename" +import { Logo } from "../../component/logo" import { Sidebar } from "./sidebar" import { SubagentFooter } from "./subagent-footer.tsx" import { filetype } from "../../util/filetype" @@ -1165,6 +1166,15 @@ export function Session() { + {/* Fork: startup lands in an empty session instead of the home + screen, so fill the transcript void with a home-like banner + until the first message arrives. */} + + + + Ask anything... "Fix a TODO in the codebase" + + (scroll = r)} viewportOptions={{ @@ -1180,7 +1190,7 @@ export function Session() { }} stickyScroll={true} stickyStart="bottom" - flexGrow={1} + flexGrow={messages().length === 0 ? 0 : 1} scrollAcceleration={scrollAcceleration()} > From 7a58632c5673193a1570abb03d97160a38838a41 Mon Sep 17 00:00:00 2001 From: minhn4 Date: Mon, 13 Jul 2026 00:03:03 +0700 Subject: [PATCH 2/4] fix(tui): center the empty-session banner vertically The banner rendered top-aligned: the scrollbox holds its flex-derived height even when empty, so flexGrow 0 alone never collapsed it and the centering box got no space. Clamp the scrollbox to maxHeight 1 while the session has no messages (restoring upstream's flexGrow 1) and center the banner between flexGrow spacers. Co-Authored-By: Claude Fable 5 --- DIVERGENCES.md | 2 +- packages/tui/src/routes/session/index.tsx | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/DIVERGENCES.md b/DIVERGENCES.md index 7f1ecf21cc..562d7da248 100644 --- a/DIVERGENCES.md +++ b/DIVERGENCES.md @@ -37,7 +37,7 @@ upstream maintainers — see README → Syncing with upstream for why and how. | `packages/tui/src/feature-plugins/sidebar/footer.tsx` | Sidebar footer wordmark: upstream's two-tone "Open"+"Code" spans → a single "CoDev" span (text color, bold) | Upstream splits the wordmark across two spans, so it never matched `opencode` greps and survived earlier rebrand passes. | Keep our span; take upstream's surrounding changes. | | `packages/opencode/src/cli/cmd/*.ts` (tui, run, serve, attach, pr, upgrade, uninstall, web) | Help `describe` strings "opencode" → "codev" | `--help` is the first thing users read. | Keep our strings. | | `packages/tui/src/app.tsx` | Terminal title "OpenCode"/"OC \|" → "CoDev Code"/"CC \|"; startup dialog effect gates on `!useConnected()` (not `provider.length === 0` — hosted Zen free models always register) and opens the fork's `DialogConfigure` (component/dialog-configure.tsx, new file); added the `codev.configure` command (`/configure`) and a `CODEV_CONFIGURE=1` mount hook for `codev configure`; home screen skipped — plain startup seeds the `dummy` session route and auto-opens a new empty session (reusing a leftover default-titled empty one via `openNewSession`/`findEmptySession`), `session.new` and the current-session `session.deleted` handler open a new session instead of navigating home, and the `-c` resolver prefers non-default-titled sessions so it lands on the last real conversation | Tab title branding; first-run setup routes to the CoDev gateway configure flow (upstream's `/connect` stays as the escape hatch); `codev` starts directly in the session layout instead of the home screen. | Keep our strings, gate condition, dialog swap + command block, route seed, `openNewSession`/`findEmptySession` + call sites, and the `-c` default-title filter; take upstream's surrounding changes. | -| `packages/tui/src/routes/session/index.tsx` | Empty-session banner: when the session has no messages, the transcript area shows the centered `Logo` wordmark plus an "Ask anything..." hint, and the scrollbox collapses (`flexGrow` 0) until the first message | Startup lands in an empty session instead of the home screen; without this the transcript is a large blank void above the prompt. | Keep our banner block + conditional `flexGrow`; take upstream's surrounding changes. | +| `packages/tui/src/routes/session/index.tsx` | Empty-session banner: when the session has no messages, the transcript area shows the vertically centered `Logo` wordmark plus an "Ask anything..." hint (flexGrow spacer boxes), and the scrollbox is clamped to `maxHeight` 1 until the first message (it holds its flex-derived height even when empty, so `flexGrow` 0 alone does not collapse it) | Startup lands in an empty session instead of the home screen; without this the transcript is a large blank void above the prompt. | Keep our banner block + conditional `maxHeight`; take upstream's surrounding changes. | | `packages/tui/src/routes/session/permission.tsx`, `packages/opencode/src/cli/cmd/run/permission.shared.ts`, `packages/opencode/test/cli/run/permission.shared.test.ts`, `packages/tui/src/component/error-component.tsx`, `packages/opencode/src/cli/cmd/run/splash.ts` | Visible sentences/badges "OpenCode"/"opencode" → "CoDev Code"/"codev-code" (incl. the permission always-allow copy and its test expectations) | User-facing copy. | Keep our strings. | | `packages/opencode/src/installation/index.ts` | Updater detects/queries/installs `codev-code` (npm-family); GitHub fallback → quickbeard/codev-code | `codev-code upgrade` and the update notification target OUR npm package, never stock opencode. brew/choco/scoop probes never match (no such packages). | Keep our package names. | | `packages/opencode/src/config/config.ts` | `share` defaults to `"disabled"` when unset | Sharing publishes sessions to upstream's share service; internal users must opt in via config. | Keep our default block. | diff --git a/packages/tui/src/routes/session/index.tsx b/packages/tui/src/routes/session/index.tsx index 04e0a2811f..7c81c6690f 100644 --- a/packages/tui/src/routes/session/index.tsx +++ b/packages/tui/src/routes/session/index.tsx @@ -1170,10 +1170,12 @@ export function Session() { screen, so fill the transcript void with a home-like banner until the first message arrives. */} - + + Ask anything... "Fix a TODO in the codebase" + (scroll = r)} @@ -1190,7 +1192,10 @@ export function Session() { }} stickyScroll={true} stickyStart="bottom" - flexGrow={messages().length === 0 ? 0 : 1} + flexGrow={1} + // The scrollbox holds its flex-derived height even when empty, + // so clamp it while the banner is shown. + maxHeight={messages().length === 0 ? 1 : undefined} scrollAcceleration={scrollAcceleration()} > From 3f5e1662f6a1050e9f55ffb0bda560b19d674ec9 Mon Sep 17 00:00:00 2001 From: minhn4 Date: Mon, 13 Jul 2026 00:15:34 +0700 Subject: [PATCH 3/4] feat(tui): draw the banner hint from home's suggestion pool The empty-session banner hint was a single hard-coded string. Export home's placeholder pool and pick one suggestion per session mount, so the banner varies like the home prompt placeholder and upstream edits to the pool flow through. Co-Authored-By: Claude Fable 5 --- DIVERGENCES.md | 3 ++- packages/tui/src/routes/home.tsx | 3 ++- packages/tui/src/routes/session/index.tsx | 6 +++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/DIVERGENCES.md b/DIVERGENCES.md index 562d7da248..0151ff3157 100644 --- a/DIVERGENCES.md +++ b/DIVERGENCES.md @@ -37,7 +37,8 @@ upstream maintainers — see README → Syncing with upstream for why and how. | `packages/tui/src/feature-plugins/sidebar/footer.tsx` | Sidebar footer wordmark: upstream's two-tone "Open"+"Code" spans → a single "CoDev" span (text color, bold) | Upstream splits the wordmark across two spans, so it never matched `opencode` greps and survived earlier rebrand passes. | Keep our span; take upstream's surrounding changes. | | `packages/opencode/src/cli/cmd/*.ts` (tui, run, serve, attach, pr, upgrade, uninstall, web) | Help `describe` strings "opencode" → "codev" | `--help` is the first thing users read. | Keep our strings. | | `packages/tui/src/app.tsx` | Terminal title "OpenCode"/"OC \|" → "CoDev Code"/"CC \|"; startup dialog effect gates on `!useConnected()` (not `provider.length === 0` — hosted Zen free models always register) and opens the fork's `DialogConfigure` (component/dialog-configure.tsx, new file); added the `codev.configure` command (`/configure`) and a `CODEV_CONFIGURE=1` mount hook for `codev configure`; home screen skipped — plain startup seeds the `dummy` session route and auto-opens a new empty session (reusing a leftover default-titled empty one via `openNewSession`/`findEmptySession`), `session.new` and the current-session `session.deleted` handler open a new session instead of navigating home, and the `-c` resolver prefers non-default-titled sessions so it lands on the last real conversation | Tab title branding; first-run setup routes to the CoDev gateway configure flow (upstream's `/connect` stays as the escape hatch); `codev` starts directly in the session layout instead of the home screen. | Keep our strings, gate condition, dialog swap + command block, route seed, `openNewSession`/`findEmptySession` + call sites, and the `-c` default-title filter; take upstream's surrounding changes. | -| `packages/tui/src/routes/session/index.tsx` | Empty-session banner: when the session has no messages, the transcript area shows the vertically centered `Logo` wordmark plus an "Ask anything..." hint (flexGrow spacer boxes), and the scrollbox is clamped to `maxHeight` 1 until the first message (it holds its flex-derived height even when empty, so `flexGrow` 0 alone does not collapse it) | Startup lands in an empty session instead of the home screen; without this the transcript is a large blank void above the prompt. | Keep our banner block + conditional `maxHeight`; take upstream's surrounding changes. | +| `packages/tui/src/routes/session/index.tsx` | Empty-session banner: when the session has no messages, the transcript area shows the vertically centered `Logo` wordmark plus an `Ask anything... ""` hint drawn per mount from home's `placeholder.normal` pool (flexGrow spacer boxes), and the scrollbox is clamped to `maxHeight` 1 until the first message (it holds its flex-derived height even when empty, so `flexGrow` 0 alone does not collapse it) | Startup lands in an empty session instead of the home screen; without this the transcript is a large blank void above the prompt. | Keep our banner block + conditional `maxHeight`; take upstream's surrounding changes. | +| `packages/tui/src/routes/home.tsx` | `placeholder` suggestion pool exported (was module-private) | The empty-session banner in routes/session/index.tsx draws from the same pool, so upstream edits to the suggestions flow through. | Keep the `export` keyword; take upstream's changes to the list. | | `packages/tui/src/routes/session/permission.tsx`, `packages/opencode/src/cli/cmd/run/permission.shared.ts`, `packages/opencode/test/cli/run/permission.shared.test.ts`, `packages/tui/src/component/error-component.tsx`, `packages/opencode/src/cli/cmd/run/splash.ts` | Visible sentences/badges "OpenCode"/"opencode" → "CoDev Code"/"codev-code" (incl. the permission always-allow copy and its test expectations) | User-facing copy. | Keep our strings. | | `packages/opencode/src/installation/index.ts` | Updater detects/queries/installs `codev-code` (npm-family); GitHub fallback → quickbeard/codev-code | `codev-code upgrade` and the update notification target OUR npm package, never stock opencode. brew/choco/scoop probes never match (no such packages). | Keep our package names. | | `packages/opencode/src/config/config.ts` | `share` defaults to `"disabled"` when unset | Sharing publishes sessions to upstream's share service; internal users must opt in via config. | Keep our default block. | diff --git a/packages/tui/src/routes/home.tsx b/packages/tui/src/routes/home.tsx index d4145e2d87..e534068a98 100644 --- a/packages/tui/src/routes/home.tsx +++ b/packages/tui/src/routes/home.tsx @@ -14,7 +14,8 @@ import { useTuiConfig } from "../config" import { HomeSessionDestinationProvider } from "./home/session-destination" let once = false -const placeholder = { +// Fork: also feeds the empty-session banner in routes/session/index.tsx. +export const placeholder = { normal: ["Fix a TODO in the codebase", "What is the tech stack of this project?", "Fix broken tests"], shell: ["ls -la", "git status", "pwd"], } diff --git a/packages/tui/src/routes/session/index.tsx b/packages/tui/src/routes/session/index.tsx index 7c81c6690f..db7838d4f6 100644 --- a/packages/tui/src/routes/session/index.tsx +++ b/packages/tui/src/routes/session/index.tsx @@ -54,6 +54,7 @@ import { DialogTimeline } from "./dialog-timeline" import { DialogForkFromTimeline } from "./dialog-fork-from-timeline" import { DialogSessionRename } from "../../component/dialog-session-rename" import { Logo } from "../../component/logo" +import { placeholder } from "../home" import { Sidebar } from "./sidebar" import { SubagentFooter } from "./subagent-footer.tsx" import { filetype } from "../../util/filetype" @@ -212,6 +213,9 @@ export function Session() { .toSorted((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)) }) const messages = createMemo(() => sync.data.message[route.sessionID] ?? []) + // One pick per mount; the Session component is keyed on sessionID, so each + // new session draws a fresh suggestion for the empty-session banner. + const bannerHint = placeholder.normal[Math.floor(Math.random() * placeholder.normal.length)] const foregroundTasks = createMemo(() => sync.data.capabilities.experimentalBackgroundSubagents ? messages().flatMap((message) => @@ -1173,7 +1177,7 @@ export function Session() { - Ask anything... "Fix a TODO in the codebase" + {`Ask anything... "${bannerHint}"`} From aadbcd256342249ca5ffd1da8def91efc80edfa7 Mon Sep 17 00:00:00 2001 From: minhn4 Date: Mon, 13 Jul 2026 00:23:10 +0700 Subject: [PATCH 4/4] feat(tui): move banner hint into the prompt and add home tips Drop the hint text from the empty-session banner: the session prompt now receives home's placeholder pool while the session is empty, so the suggestion appears inside the input box exactly like home, and the home_bottom tips slot renders beneath the banner logo. Co-Authored-By: Claude Fable 5 --- DIVERGENCES.md | 4 ++-- packages/tui/src/routes/home.tsx | 2 +- packages/tui/src/routes/session/index.tsx | 6 ++---- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/DIVERGENCES.md b/DIVERGENCES.md index 0151ff3157..55fa583f7d 100644 --- a/DIVERGENCES.md +++ b/DIVERGENCES.md @@ -37,8 +37,8 @@ upstream maintainers — see README → Syncing with upstream for why and how. | `packages/tui/src/feature-plugins/sidebar/footer.tsx` | Sidebar footer wordmark: upstream's two-tone "Open"+"Code" spans → a single "CoDev" span (text color, bold) | Upstream splits the wordmark across two spans, so it never matched `opencode` greps and survived earlier rebrand passes. | Keep our span; take upstream's surrounding changes. | | `packages/opencode/src/cli/cmd/*.ts` (tui, run, serve, attach, pr, upgrade, uninstall, web) | Help `describe` strings "opencode" → "codev" | `--help` is the first thing users read. | Keep our strings. | | `packages/tui/src/app.tsx` | Terminal title "OpenCode"/"OC \|" → "CoDev Code"/"CC \|"; startup dialog effect gates on `!useConnected()` (not `provider.length === 0` — hosted Zen free models always register) and opens the fork's `DialogConfigure` (component/dialog-configure.tsx, new file); added the `codev.configure` command (`/configure`) and a `CODEV_CONFIGURE=1` mount hook for `codev configure`; home screen skipped — plain startup seeds the `dummy` session route and auto-opens a new empty session (reusing a leftover default-titled empty one via `openNewSession`/`findEmptySession`), `session.new` and the current-session `session.deleted` handler open a new session instead of navigating home, and the `-c` resolver prefers non-default-titled sessions so it lands on the last real conversation | Tab title branding; first-run setup routes to the CoDev gateway configure flow (upstream's `/connect` stays as the escape hatch); `codev` starts directly in the session layout instead of the home screen. | Keep our strings, gate condition, dialog swap + command block, route seed, `openNewSession`/`findEmptySession` + call sites, and the `-c` default-title filter; take upstream's surrounding changes. | -| `packages/tui/src/routes/session/index.tsx` | Empty-session banner: when the session has no messages, the transcript area shows the vertically centered `Logo` wordmark plus an `Ask anything... ""` hint drawn per mount from home's `placeholder.normal` pool (flexGrow spacer boxes), and the scrollbox is clamped to `maxHeight` 1 until the first message (it holds its flex-derived height even when empty, so `flexGrow` 0 alone does not collapse it) | Startup lands in an empty session instead of the home screen; without this the transcript is a large blank void above the prompt. | Keep our banner block + conditional `maxHeight`; take upstream's surrounding changes. | -| `packages/tui/src/routes/home.tsx` | `placeholder` suggestion pool exported (was module-private) | The empty-session banner in routes/session/index.tsx draws from the same pool, so upstream edits to the suggestions flow through. | Keep the `export` keyword; take upstream's changes to the list. | +| `packages/tui/src/routes/session/index.tsx` | Empty-session banner: when the session has no messages, the transcript area shows the vertically centered `Logo` wordmark with the `home_bottom` tips slot beneath it (flexGrow spacer boxes), the session `Prompt` gets home's `placeholder` pool so the input shows an `Ask anything... ""` placeholder like home, and the scrollbox is clamped to `maxHeight` 1 until the first message (it holds its flex-derived height even when empty, so `flexGrow` 0 alone does not collapse it) | Startup lands in an empty session instead of the home screen; without this the transcript is a large blank void above the prompt. | Keep our banner block, the `placeholders` prop, and the conditional `maxHeight`; take upstream's surrounding changes. | +| `packages/tui/src/routes/home.tsx` | `placeholder` suggestion pool exported (was module-private) | The empty-session view in routes/session/index.tsx feeds the same pool to its prompt, so upstream edits to the suggestions flow through. | Keep the `export` keyword; take upstream's changes to the list. | | `packages/tui/src/routes/session/permission.tsx`, `packages/opencode/src/cli/cmd/run/permission.shared.ts`, `packages/opencode/test/cli/run/permission.shared.test.ts`, `packages/tui/src/component/error-component.tsx`, `packages/opencode/src/cli/cmd/run/splash.ts` | Visible sentences/badges "OpenCode"/"opencode" → "CoDev Code"/"codev-code" (incl. the permission always-allow copy and its test expectations) | User-facing copy. | Keep our strings. | | `packages/opencode/src/installation/index.ts` | Updater detects/queries/installs `codev-code` (npm-family); GitHub fallback → quickbeard/codev-code | `codev-code upgrade` and the update notification target OUR npm package, never stock opencode. brew/choco/scoop probes never match (no such packages). | Keep our package names. | | `packages/opencode/src/config/config.ts` | `share` defaults to `"disabled"` when unset | Sharing publishes sessions to upstream's share service; internal users must opt in via config. | Keep our default block. | diff --git a/packages/tui/src/routes/home.tsx b/packages/tui/src/routes/home.tsx index e534068a98..24cd1d2e18 100644 --- a/packages/tui/src/routes/home.tsx +++ b/packages/tui/src/routes/home.tsx @@ -14,7 +14,7 @@ import { useTuiConfig } from "../config" import { HomeSessionDestinationProvider } from "./home/session-destination" let once = false -// Fork: also feeds the empty-session banner in routes/session/index.tsx. +// Fork: also feeds the empty-session prompt in routes/session/index.tsx. export const placeholder = { normal: ["Fix a TODO in the codebase", "What is the tech stack of this project?", "Fix broken tests"], shell: ["ls -la", "git status", "pwd"], diff --git a/packages/tui/src/routes/session/index.tsx b/packages/tui/src/routes/session/index.tsx index db7838d4f6..88ab2f4a87 100644 --- a/packages/tui/src/routes/session/index.tsx +++ b/packages/tui/src/routes/session/index.tsx @@ -213,9 +213,6 @@ export function Session() { .toSorted((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)) }) const messages = createMemo(() => sync.data.message[route.sessionID] ?? []) - // One pick per mount; the Session component is keyed on sessionID, so each - // new session draws a fresh suggestion for the empty-session banner. - const bannerHint = placeholder.normal[Math.floor(Math.random() * placeholder.normal.length)] const foregroundTasks = createMemo(() => sync.data.capabilities.experimentalBackgroundSubagents ? messages().flatMap((message) => @@ -1177,7 +1174,7 @@ export function Session() { - {`Ask anything... "${bannerHint}"`} + @@ -1331,6 +1328,7 @@ export function Session() { onSubmit={() => { toBottom() }} + placeholders={messages().length === 0 ? placeholder : undefined} sessionID={route.sessionID} right={} />