From c0e1c2848bd79b983b78301cbd333e3457640e03 Mon Sep 17 00:00:00 2001 From: chengyongru Date: Thu, 20 Aug 2026 11:37:11 +0800 Subject: [PATCH] fix(tui): keep navigation commands in Herdr panes --- tui/README.md | 2 +- tui/src/app.test.ts | 10 +++++++++- tui/src/app.ts | 6 +----- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/tui/README.md b/tui/README.md index b75b1aad0..7c6f87e82 100644 --- a/tui/README.md +++ b/tui/README.md @@ -15,7 +15,7 @@ Standalone terminals use OpenTUI's retained full-screen layout: the transcript r ## Herdr host mode -When Herdr supplies `HERDR_ENV=1` and `HERDR_PANE_ID`, nanobot becomes a quiet hosted client. It uses OpenTUI's main-screen mode instead of hiding the whole run in a temporary alternate screen, removes the launch card and persistent session/model chrome, and keeps only the transcript, last user task, current progress, and composer. Herdr remains responsible for workspace, tab, pane, and attention navigation; hosted command discovery therefore omits the duplicate session/new-chat/branch controls. +When Herdr supplies `HERDR_ENV=1` and `HERDR_PANE_ID`, nanobot becomes a quiet hosted client. It uses OpenTUI's main-screen mode instead of hiding the whole run in a temporary alternate screen, removes the launch card and persistent session/model chrome, and keeps only the transcript, last user task, current progress, and composer. Herdr remains responsible for workspace, tab, pane, and attention navigation, while nanobot keeps its application-level session, new-chat, and branch commands. The TUI reports its WebSocket session ID, model, Git branch, workspace, last task, and current action through Herdr's supported pane CLI. Sending work reports `working`; a persisted explicit nanobot goal block reports `blocked`; a completed turn reports `idle`; exit releases lifecycle authority. The gateway session remains the durable transcript and resume path. Standalone terminals keep the richer full-screen navigation described below. diff --git a/tui/src/app.test.ts b/tui/src/app.test.ts index eaa46744f..522f92ca7 100644 --- a/tui/src/app.test.ts +++ b/tui/src/app.test.ts @@ -2139,7 +2139,7 @@ describe("NanobotTui layout", () => { }) describe("NanobotTui in a Herdr pane", () => { - test("stays quiet while reporting task, session, lifecycle, and metadata", async () => { + test("keeps local navigation while reporting task, session, lifecycle, and metadata", async () => { const setup = await createTestRenderer({ width: 80, height: 22, screenMode: "main-screen" }) const states: Array<{ state: HostAgentState; message?: string }> = [] const metadata: HostMetadata[] = [] @@ -2160,6 +2160,14 @@ describe("NanobotTui in a Herdr pane", () => { host, ) + await setup.mockInput.typeText("/") + await setup.flush() + const commandFrame = setup.captureCharFrame() + expect(commandFrame).toContain("/sessions") + expect(commandFrame).toContain("/new-chat") + expect(commandFrame).toContain("/branch") + setup.mockInput.pressEscape() + app.accept({ event: "attached", chat_id: "chat" }) app.accept({ event: "user_message", diff --git a/tui/src/app.ts b/tui/src/app.ts index 76aa10391..72a6a18a4 100644 --- a/tui/src/app.ts +++ b/tui/src/app.ts @@ -459,11 +459,7 @@ export class NanobotTui { this.activeThemeMode = this.resolveThemeMode(renderer.themeMode) this.palette = this.activeThemeMode === "light" ? LIGHT : DARK this.host = host - this.localCommands = host.hosted - ? LOCAL_COMMANDS.filter(({ command }) => ( - command === "/context" || command === "/diff" || command === "/exit" - )) - : LOCAL_COMMANDS + this.localCommands = LOCAL_COMMANDS this.transcript = new Transcript( renderer, transcriptTheme(this.palette, this.backgroundKnown),