fix(tui): keep navigation commands in Herdr panes

This commit is contained in:
chengyongru
2026-08-20 11:53:07 +08:00
committed by chengyongru
parent c615aee2ca
commit c0e1c2848b
3 changed files with 11 additions and 7 deletions
+1 -1
View File
@@ -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.
+9 -1
View File
@@ -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",
+1 -5
View File
@@ -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),