Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 158 additions & 0 deletions docs/ai/design/2026-07-02-feature-agent-console-detail-chat-view.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
---
phase: design
title: Agent Console Detail Chat View - System Design
description: Technical design for focused and scrollable chat content in the interactive agent console
---

# System Design & Architecture

## Architecture Overview

The feature extends the existing Ink console focus model. The agent list continues to own selection; the right-side preview/detail pane becomes a focus target that can consume scroll keys without changing list selection.

```mermaid
graph TD
Input["ConsoleApp useInput"]
Focus["ConsoleFocus: list | detail | input"]
List["AgentListPane"]
PreviewSection["PreviewSection"]
PreviewPane["PreviewPane"]
Conversation["useAgentConversation"]
Adapter["AgentAdapter.getConversation()"]

Input -->|v| Focus
Input -->|list focus arrows/j/k| List
Input -->|detail focus arrows/j/k| PreviewSection
Focus -->|focused prop| PreviewSection
PreviewSection --> PreviewPane
PreviewSection --> Conversation
Conversation --> Adapter
```

Responsibilities:

- `ConsoleApp`: owns focus state, global key routing, selected agent, and detail scroll offset.
- `PreviewSection`: receives focus and scroll offset props, keeps fetching selected-agent messages, computes/clamps the valid viewport range, and passes render constraints to `PreviewPane`.
- `PreviewPane`: renders metadata, chat rows, empty/error states, and scroll affordances from a supplied clamped viewport.
- `useAgentConversation`: remains responsible only for polling/caching conversation messages.

## Data Models

Extend console focus:

```typescript
export type ConsoleFocus = 'list' | 'detail' | 'input';
```

Add scroll state in `ConsoleApp`:

```typescript
const [detailScrollOffset, setDetailScrollOffset] = useState(0);
```

The offset represents logical rendered lines above the current detail viewport. A value of `0` means the viewport is pinned to the newest/latest rendered content at the bottom. Positive values move the viewport upward into older chat content.

`PreviewPane` should expose pure helpers for testable rendering math:

```typescript
interface DetailViewport {
lines: string[];
clampedOffset: number;
maxOffset: number;
hasAbove: boolean;
hasBelow: boolean;
}
```

`clampedOffset` is returned so `PreviewSection` can notify `ConsoleApp` when the current offset is no longer valid after a message update or terminal resize.

## API Design

No external API changes.

Internal prop changes:

```typescript
interface PreviewSectionProps {
selectedName: string | null;
height: number;
focused?: boolean;
scrollOffset?: number;
onScrollOffsetClamp?: (offset: number) => void;
}

interface PreviewPaneProps {
agent: AgentInfo | null;
messages: ConversationMessage[];
error: ConversationFetchError | null;
isLoading: boolean;
maxLines?: number;
channelStatus?: AgentChannelStatus;
scrollOffset?: number;
onScrollOffsetClamp?: (offset: number) => void;
}
```

`ConsoleApp` key behavior:

- `v` from list focus: set focus to `detail` if an agent is selected and wide preview is visible.
- `Esc` or left arrow from detail focus: set focus to `list`.
- Up/down arrows and `j/k` from detail focus: adjust `detailScrollOffset` within `[0, maxOffset]`.
- Because `ConsoleApp` does not own rendered-line calculation, scroll key handling may increment/decrement the requested offset and rely on `PreviewSection`/`PreviewPane` to clamp and report the valid value.
- Up/down arrows and `j/k` from list focus: keep existing selected-agent navigation.
- `i`/`m` from detail focus: may enter input focus when an agent is selected, same as list focus.

## Component Breakdown

Console components:

- `packages/cli/src/tui/console/types.ts`
- Add `detail` to `ConsoleFocus`.
- `packages/cli/src/tui/console/ConsoleApp.tsx`
- Route `v`, scroll, escape, and left-arrow behavior.
- Reset detail scroll offset when selected agent changes.
- Pass `focused={focus === 'detail'}` into `PreviewSection`.
- `packages/cli/src/tui/console/PreviewSection.tsx`
- Apply focused panel styling to the preview panel.
- Pass scroll offset and message budget into `PreviewPane`.
- Clamp scroll offset when messages or height change and report the clamped offset upward.
- `packages/cli/src/tui/console/PreviewPane.tsx`
- Render a viewport over chat content instead of truncating only from the newest message.
- Show simple `↑`/`↓` affordances in the header when more content exists.
- Preserve current metadata, channel status, loading, empty, and error output.
- Tests under `packages/cli/src/__tests__/tui/console`
- Add helper tests for viewport calculations and update focus/layout tests where needed.

## Design Decisions

| Decision | Choice | Rationale |
| --- | --- | --- |
| Focus model | Add `detail` to `ConsoleFocus` | Matches existing focus routing and panel styling without a new modal mode. |
| Shortcut | `v` enters detail focus | Matches the requested workflow and avoids existing console shortcuts. |
| Scroll ownership | `ConsoleApp` owns requested offset; preview clamps it | Key handling and selected-agent reset stay centralized while rendered-line math stays near preview rendering. |
| Rendering math | Pure helper in preview module | Keeps Ink rendering simple and gives unit tests deterministic coverage. |
| Narrow mode | Keep `v` inactive while preview is hidden | Avoids focusing invisible UI; future full-screen transcript can be designed separately. |

Alternatives considered:

- Reuse `agent detail` command output inside the console: rejected because it would duplicate formatting and bypass existing preview polling.
- Add a replacement-pane mode for detail: deferred because the requested workflow specifically highlights the detail pane and current wide layout already has one.
- Fetch full session history by default: deferred to avoid changing polling cost; basic scrolling can operate on the current conversation tail first, then increase tail if needed during implementation review.

## Non-Functional Requirements

Performance:

- Scroll keypresses must not read session files or call `getConversation()`.
- Viewport calculation should be linear in the currently loaded message count.
- Existing polling interval and cache behavior should remain unchanged unless implementation proves the 20-message tail is too limiting for the feature.

Reliability:

- Missing session files, unsupported adapters, parse errors, empty message sets, and loading states must render with existing behavior while focused.
- Scroll offset must be clamped when terminal height changes or message count changes.

Security:

- No new file paths, shell commands, network calls, or permissions are introduced.
- Conversation content is already local session content exposed by the console; this feature changes navigation only.
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
---
phase: implementation
title: Agent Console Detail Chat View - Implementation Guide
description: Implementation notes for focused and scrollable chat content in the interactive agent console
---

# Implementation Guide

## Development Setup

- Active worktree: `.worktrees/feature-agent-console-detail-chat-view`
- Branch: `feature-agent-console-detail-chat-view`
- Dependencies: bootstrapped with `npm ci`
- Feature docs: `docs/ai/*/2026-07-02-feature-agent-console-detail-chat-view.md`

## Code Structure

- `packages/cli/src/tui/console/types.ts`
- `packages/cli/src/tui/console/ConsoleApp.tsx`
- `packages/cli/src/tui/console/PreviewSection.tsx`
- `packages/cli/src/tui/console/PreviewPane.tsx`
- `packages/cli/src/tui/console/consoleKeyRouting.ts`
- `packages/cli/src/__tests__/tui/console/PreviewPane.test.ts`
- `packages/cli/src/__tests__/tui/console/focusRouting.test.ts`
- `packages/cli/src/__tests__/tui/console/HelpPane.test.ts`

## Implementation Notes

### Core Features

- Add `detail` as a third console focus state instead of adding a new right-pane mode.
- Keep `PreviewSection` visible in wide mode and focused via the existing `Panel` `focused` prop.
- Keep scroll state in `ConsoleApp`; avoid coupling scroll behavior to conversation polling.
- Prefer pure helper functions for scroll math so tests do not depend on terminal rendering snapshots.
- Added `resolveConsoleKeyAction()` as a pure helper for list/detail/input key routing.
- Added `buildPreviewViewport()` as a pure helper for visible chat lines, offset clamping, and scroll affordance state.
- Added `v view` to console help/footer shortcuts.

### Patterns & Best Practices

- Follow existing Ink component patterns and panel design-system usage.
- Keep new helpers exported only when tests need direct access.
- Avoid introducing new session parsing or file access in UI components.
- Clamp scroll offsets whenever viewport size or message count changes.

## Integration Points

- `useAgentConversation` continues to fetch selected-agent conversation data.
- `PreviewPane` receives already-loaded `ConversationMessage[]`; scroll changes must not fetch.
- `ConsoleApp` owns key routing and passes scroll/focus props down the preview tree.
- `PreviewSection` forwards clamped offsets from `PreviewPane` back to `ConsoleApp`.

## Error Handling

- Preserve current `PreviewPane` error states for missing session files, unsupported adapters, and parse errors.
- Detail focus with an error/empty/loading state should still render a focused panel and treat scroll as a no-op.
- Do not add console logging for normal key routing.

## Performance Considerations

- Scroll updates should be state-only UI updates.
- Keep existing conversation cache and polling interval unchanged unless implementation review identifies a functional gap.
- Avoid recalculating viewport structures more broadly than the loaded message array and current viewport need.

## Security Notes

- No new command execution, network calls, or writes.
- The feature only changes local display of already accessible agent session content.

## Implementation Results

Changed files:

- `packages/cli/src/tui/console/types.ts`: added `detail` focus state.
- `packages/cli/src/tui/console/consoleKeyRouting.ts`: added pure key-routing helper.
- `packages/cli/src/tui/console/ConsoleApp.tsx`: added detail scroll state, focus transitions, selected-agent scroll reset, and scroll-key handling.
- `packages/cli/src/tui/console/PreviewSection.tsx`: forwards focus, scroll offset, and clamp callback into the preview panel.
- `packages/cli/src/tui/console/PreviewPane.tsx`: added viewport helper, clamped offset reporting, scroll affordances, and line-based chat viewport rendering.
- `packages/cli/src/tui/console/HelpPane.tsx`: added `v view` hotkey.
- `packages/cli/src/__tests__/tui/console/PreviewPane.test.ts`: covers viewport helper behavior.
- `packages/cli/src/__tests__/tui/console/focusRouting.test.ts`: covers list/detail/input key routing.
- `packages/cli/src/__tests__/tui/console/HelpPane.test.ts`: covers new help/footer shortcut.

Simplification pass:

- `PreviewViewport` now returns typed rows instead of strings, so rendering uses `row.role` directly rather than inferring color from string prefixes.
- `ConsoleApp` key action handling now uses a `switch` to keep focus, scroll, and selection actions grouped in one dispatch block.
- `focusRouting.test.ts` now uses a local setup helper to remove repeated default key-routing inputs.

Design deviations:

- None. The implementation follows the reviewed design split: `ConsoleApp` owns requested offset and preview rendering clamps/report valid offsets.

Verification evidence:

- `npx vitest run src/__tests__/tui/console/PreviewPane.test.ts src/__tests__/tui/console/focusRouting.test.ts src/__tests__/tui/console/HelpPane.test.ts` passed: 3 files, 18 tests.
- `npx vitest run src/__tests__/tui/console` passed: 16 files, 106 tests.
- `npm run build` passed for all 6 projects.
- `npm run lint --workspace packages/cli` exited 0 with 5 pre-existing warnings outside touched files.
- `npx ai-devkit@latest lint --feature agent-console-detail-chat-view` passed after simplification.
121 changes: 121 additions & 0 deletions docs/ai/planning/2026-07-02-feature-agent-console-detail-chat-view.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
---
phase: planning
title: Agent Console Detail Chat View - Project Planning
description: Initial task breakdown for focused and scrollable chat content in the interactive agent console
---

# Project Planning & Task Breakdown

## Milestones

- [x] Milestone 1: Requirements/design/testing reviewed and accepted
- [x] Milestone 2: Focus and scroll behavior implemented with tests
- [x] Milestone 3: Console regression tests complete; manual terminal smoke test deferred (PTY scan returns 0 agents; real-terminal verification recommended before broad rollout)

## Task Breakdown

### Phase 1: Focus Model

- [x] Task 1.1: Add `detail` to `ConsoleFocus` and route focus transitions in `ConsoleApp`.
- Outcome: pressing `v` from list focus in wide mode enters detail focus when an agent is selected; `Esc` and left arrow return to list focus.
- Dependencies: none.
- Validation: focused key-routing helper tests cover `v`, `Esc`, left arrow, no-agent, and narrow-mode no-op behavior.
- Related tests: ConsoleApp focus/key helper scenarios.
- [x] Task 1.2: Preserve existing list and input keyboard behavior.
- Outcome: up/down and `j/k` still change selected agent in list focus; `i`/`m` still enter input focus; input cancel still returns to list focus.
- Dependencies: Task 1.1.
- Validation: regression tests for list navigation and input focus routing.
- Related tests: ConsoleApp focus/key helper scenarios and existing console tests.
- [x] Task 1.3: Reset detail scroll offset when selected agent changes.
- Outcome: switching agents returns the detail pane to latest content instead of carrying the prior agent's scroll position.
- Dependencies: Task 1.1.
- Validation: helper or component test verifies selected-agent change resets offset.
- Related tests: ConsoleApp focus/key helper scenarios.

### Phase 2: Scrollable Preview Rendering

- [x] Task 2.1: Add pure viewport/scroll helper logic for preview chat content.
- Outcome: helper converts `ConversationMessage[]`, message budget, and requested scroll offset into visible lines, clamped offset, max offset, and above/below affordance state.
- Dependencies: none, but implement before wiring Ink rendering.
- Validation: unit tests cover newest view, older view, negative offset, too-large offset, long conversations, and multi-line messages.
- Related tests: PreviewPane viewport helper scenarios.
- [x] Task 2.2: Pass focus and scroll offset through `PreviewSection` to `PreviewPane`.
- Outcome: focused preview uses existing `Panel` focus styling and receives the requested detail scroll offset.
- Dependencies: Tasks 1.1 and 2.1.
- Validation: component/helper test verifies focused panel prop and visible content changes with offset.
- Related tests: integration scenarios for focused `PreviewSection`.
- [x] Task 2.3: Render scroll affordances when older/newer content exists outside the viewport.
- Outcome: preview header shows subtle up/down indicators only when scrolling is possible.
- Dependencies: Task 2.1.
- Validation: unit tests verify `hasAbove`/`hasBelow` states and snapshot-light text assertions for header indicators.
- Related tests: PreviewPane viewport helper scenarios.
- [x] Task 2.4: Clamp requested detail scroll offset when messages or terminal height change.
- Outcome: preview reports clamped offsets upward so `ConsoleApp` state cannot remain outside the valid viewport range.
- Dependencies: Tasks 2.1 and 2.2.
- Validation: test covers shrinking content/height and verifies the callback receives the valid offset.
- Related tests: integration scenarios for changing message count or `maxLines`.

### Phase 3: Tests & Polish

- [x] Task 3.1: Add unit tests for viewport clamping, visible-line selection, and affordance state.
- Outcome: pure scroll math has deterministic coverage.
- Dependencies: Task 2.1.
- Validation: targeted `PreviewPane.test.ts` or new helper test passes.
- [x] Task 3.2: Add or update console focus/key routing tests.
- Outcome: list/detail/input key behavior has regression coverage.
- Dependencies: Tasks 1.1-1.3.
- Validation: targeted console tests pass.
- [x] Task 3.3: Run feature lint and targeted console test suites.
- Outcome: docs and changed console code pass validation.
- Dependencies: implementation tasks complete.
- Validation: `npx ai-devkit@latest lint --feature agent-console-detail-chat-view` and `npm test -- --run packages/cli/src/__tests__/tui/console`.
- [x] Task 3.4: Perform manual terminal smoke test with a running agent when available.
- Outcome: real Ink focus styling and scroll behavior are visually confirmed.
- Dependencies: implementation tasks complete and at least one running agent available.
- Validation: manual notes in testing doc; if no running agent is available, record as deferred with reason.

## Dependencies

- Task 1.1 precedes all detail focus and scroll behavior.
- Task 2.1 should be implemented before changing Ink rendering so tests can cover the behavior directly.
- Task 2.4 depends on Task 2.1 because clamping should use the same helper that computes the viewport range.
- Task 3.2 depends on the chosen key-routing shape in `ConsoleApp`.
- No external services or API changes are required.

## Test Scenario Coverage

| Testing scenario | Covered by tasks |
| --- | --- |
| Newest content appears at offset 0 | 2.1, 3.1 |
| Older content appears at positive offset | 2.1, 3.1 |
| Offset clamping | 2.1, 2.4, 3.1 |
| Focused panel styling | 1.1, 2.2, 3.2 |
| Scroll keys do not move list selection in detail focus | 1.1, 1.2, 3.2 |
| Existing list/input behavior is unchanged | 1.2, 3.2 |
| No hidden focus trap in narrow mode | 1.1, 3.2, 3.4 |
| Scroll keypresses do not fetch conversation data | 2.2, 2.4, 3.3 |

## Timeline & Estimates

- Focus model: small.
- Scrollable preview rendering: medium, mainly due to line accounting in terminal UI.
- Tests and manual smoke: small to medium.

## Risks & Mitigation

| Risk | Impact | Mitigation |
| --- | --- | --- |
| Focus trap in hidden narrow preview | High | Keep `v` inactive in narrow mode for this iteration. |
| Scroll keys break list navigation | High | Centralize key routing and add regression tests for both focus states. |
| Line accounting differs from Ink wrapping | Medium | Base helper on explicit rendered lines and keep content clipping conservative. |
| Conversation tail of 20 feels too short | Medium | Keep existing behavior initially; revisit tail size during implementation review if scrolling is not useful enough. |

## Resources Needed

- Existing console TUI components under `packages/cli/src/tui/console`.
- Existing conversation parsing through `@ai-devkit/agent-manager`.
- Existing console tests and manual terminal run of `ai-devkit agent console`.

## Planning Status

All tasks complete. 16 console test files (106 tests) pass. CLI lint exits 0. Feature lint passes. Manual PTY smoke verified two-pane layout and clean exit; selected-agent detail focus deferred due to PTY agent-scan limitation — recommended for real-terminal verification before broad rollout.
Loading
Loading