> For the complete documentation index, see [llms.txt](https://ai-os-and-trend-finder.gitbook.io/ai-os-and-trend-finder-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ai-os-and-trend-finder.gitbook.io/ai-os-and-trend-finder-docs/.spec_system/archive/sessions/phase17-session02-chat-tab-write/spec.md).

# Session Specification

**Session ID**: `phase17-session02-chat-tab-write` **Phase**: 17 - Hermes Shell And Core Writes **Status**: Not Started **Created**: 2026-06-02

***

## 1. Session Overview

This session adds the Hermes Chat tab as the first core Phase 17 write surface inside the existing cinematic Hermes shell. It ports the v2.3 chat interaction model into modular AI OS components, reads recent threads through the existing sessions endpoints, sends prompts through the already guarded admin chat mutation, and attaches images through the confined image upload mutation.

The implementation should consume the Phase 16 data layer instead of creating new endpoints. `useHermes` already exposes bounded session summaries and a selected session detail query, while `useHermesAdmin` already exposes chat SSE send and image upload actions. This session turns those contracts into a usable Chat tab with explicit demo, loading, empty, offline, endpoint-error, token-failure, and admin-disabled states.

The session follows the Phase 16 architecture decision to keep the AI OS modular route and top-level Hermes tab shell. Chat becomes its own component tree under `src/components/hermes/chat/`; Pantheon and later Hermes surfaces remain deferred to their own sessions.

***

## 2. Objectives

1. Add a modular Hermes Chat tab that displays recent threads, selected thread messages, empty state, typing state, and streamed assistant output.
2. Wire chat send through `useHermesAdmin.chat.sendPrompt` with admin gate handling, duplicate-trigger prevention, cancel/reset controls, and prompt state cleanup.
3. Wire image attachments through `useHermesAdmin.images.uploadImage`, hiding private upload paths from visible UI while including server-returned paths in the outgoing prompt for Hermes.
4. Extend Hermes route and component tests for chat mode-matrix behavior, thread selection, disabled write affordances, image upload, and send flow.

***

## 3. Prerequisites

### Required Sessions

* [x] `phase16-session01-guardrails-architecture-parity-baseline` - Provides the modular port architecture, route IA, and write-safety contract.
* [x] `phase16-session02-backend-endpoint-parity-write-safety` - Provides `/__hermes_chat`, `/__hermes_sessions`, `/__hermes_session`, and `/__hermes_image_upload` behind loopback, token, admin, timeout, body cap, content-type, and path-confinement guardrails.
* [x] `phase16-session03-data-layer-demo-fixtures` - Provides typed hooks, parsers, admin mutations, and demo fixtures for sessions and chat-related admin actions.
* [x] `phase17-session01-visual-system-shell-status-pill` - Provides the cinematic Hermes shell and shared page primitives that this tab extends.

### Required Tools/Knowledge

* V23 source anchors in `/home/aiwithapex/projects/claudeos/claude-os-v2.3/src/routes/agents.hermes.tsx` for `HermesChat`, `HermesChatActive`, `ChatSidebar`, `SessionPill`, `ChatBubble`, `UserAvatar`, `HermesAvatar`, `ChatTyping`, and `ChatEmptyState`.
* Existing `useHermes` and `useHermesAdmin` React Query contracts.
* Existing Testing Library and Vitest patterns in `src/components/hermes/__tests__/hermes-sections.test.tsx` and `src/hooks/__tests__/use-hermes-admin.test.tsx`.

### Environment Requirements

* Bun 1.3.14 runtime from `.bun-version`.
* React 19, TanStack Query 5, TanStack Router, Tailwind CSS 4, and local lucide icon conventions.
* No live Hermes installation required for tests; component tests should use mocked hook views and demo fixtures.

***

## 4. Scope

### In Scope (MVP)

* The operator can open a new top-level `Chat` tab in the Hermes route - implemented in the existing `TabsList` and `TabsContent` shell.
* The operator can browse bounded recent thread summaries and select one to read messages - implemented through `useHermes` session summaries and selected session detail.
* The operator can start a new chat or send into the selected session when admin mode, local token, and bridge status allow writes - implemented through `useHermesAdmin.chat.sendPrompt`.
* The operator can attach supported image files before sending - implemented through `useHermesAdmin.images.uploadImage`, local previews, remove controls, upload error states, and prompt prefixing with returned image paths.
* The operator sees disabled write affordances with an admin-mode-required or token-required hint when writes are unavailable, including demo mode.
* Tests cover demo/live/setup-required/offline/endpoint-error/token/admin disabled states, selected thread rendering, image upload flow, send flow, and duplicate in-flight prevention.

### Out of Scope (Deferred)

* Pantheon templates, rich persona edit UI, and GitHub sync - *Reason: owned by Phase 17 Session 03.*
* New server endpoint implementation or write-safety changes - *Reason: Phase 16 already landed the guarded endpoints and tests.*
* Memory, Mission, Documents, Mnemosyne, Connections, Obsidian, and long-tail parity surfaces - *Reason: owned by later Hermes phases.*
* Persisting chat UI height or sidebar layout preferences - *Reason: nice to have, not required for the MVP Chat tab.*
* Browser-visible display of absolute uploaded image cache paths - *Reason: private local paths should stay out of visible UI.*

***

## 5. Technical Approach

### Architecture

Create a `src/components/hermes/chat/` component subtree that receives typed query and admin views from `HermesReadOnlyPage`. The page owns the selected chat session ID so `useHermes({ demoMode, sessionId })` can fetch the matching session detail through the existing hook. Demo mode should use `HERMES_DEMO_SESSIONS` and `HERMES_DEMO_SESSION_DETAIL` without live bridge calls.

The Chat tab should maintain local UI-only state for composer text, visible messages appended during the current page session, uploaded image attachments, upload errors, and selected thread. It should not own endpoint fetch logic beyond calling existing hook actions. The visible message list should combine selected thread messages, optimistic user messages, streamed admin output, and typing state without exposing private upload paths.

If the existing `HermesAdminPanel` still exposes the earlier basic chat form, move chat ownership to the new tab and leave the admin panel focused on gate status and persona controls. This prevents duplicate chat write surfaces.

### Design Patterns

* Hook contract consumption: Reuse `useHermes` and `useHermesAdmin` instead of creating duplicate fetch helpers.
* State-first rendering: Render loading, empty, error, offline, token-failure, demo, and disabled-admin states explicitly before normal chat controls.
* Scoped optimistic UI: Append visible user messages and streamed assistant output locally, then roll back or mark failure only within the Chat tab.
* Private-path minimization: Store returned image paths only for outgoing prompt construction and show file name/count/preview in visible UI.
* Accessibility by control: Composer, upload, thread buttons, cancel, reset, remove attachment, and new-chat controls need labels, focus behavior, and disabled states.

### Technology Stack

* React 19 with TypeScript.
* TanStack Query 5 through existing hooks.
* Tailwind CSS 4 and existing Hermes page primitives.
* lucide-react icons for toolbar controls and state indicators.
* Vitest 4 with happy-dom and Testing Library.

***

## 6. Deliverables

### Files to Create

| File                                                            | Purpose                                                                                  | Est. Lines |
| --------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------- |
| `src/components/hermes/chat/chat-types.ts`                      | Local chat UI message, attachment, and helper types                                      | \~80       |
| `src/components/hermes/chat/chat-thread-sidebar.tsx`            | Recent thread rail/list with new chat and selected-session controls                      | \~170      |
| `src/components/hermes/chat/chat-message-list.tsx`              | Empty state, thread messages, optimistic messages, streamed output, and typing indicator | \~180      |
| `src/components/hermes/chat/chat-composer.tsx`                  | Prompt textarea, image attach controls, upload state, cancel/reset/send controls         | \~220      |
| `src/components/hermes/chat/hermes-chat-tab.tsx`                | Chat tab orchestrator that joins sessions, selected detail, admin chat, and images       | \~260      |
| `src/components/hermes/chat/index.ts`                           | Chat component exports                                                                   | \~10       |
| `src/components/hermes/chat/__tests__/hermes-chat-tab.test.tsx` | Focused Chat tab component coverage                                                      | \~240      |

### Files to Modify

| File                                                       | Changes                                                                                                                    | Est. Lines |
| ---------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ---------- |
| `src/components/hermes/hermes-read-only-page.tsx`          | Add selected chat session state, pass it to `useHermes`, add Chat tab trigger/content, and pass admin/images/session views | \~70       |
| `src/components/hermes/hermes-admin-panel.tsx`             | Remove or de-emphasize the old basic chat form after the Chat tab owns chat writes                                         | \~80       |
| `src/components/hermes/__tests__/hermes-sections.test.tsx` | Extend route mode-matrix coverage for the Chat tab and adjust admin-panel assertions                                       | \~160      |
| `src/hooks/__tests__/use-hermes-admin.test.tsx`            | Add or strengthen image upload and chat send assertions if gaps remain                                                     | \~90       |

***

## 7. Success Criteria

### Functional Requirements

* [ ] Hermes route includes a `Chat` tab beside the existing top-level Hermes tabs and preserves the cinematic shell.
* [ ] Chat tab renders recent sessions, selected session messages, a new-chat empty state, upload state, typing state, and streamed assistant output.
* [ ] Chat send uses `useHermesAdmin.chat.sendPrompt`, prevents duplicate in-flight sends, supports cancel/reset, and clears composer state only after a successful send handoff.
* [ ] Image attach uses `useHermesAdmin.images.uploadImage`, filters supported image content types, disables duplicate uploads while in flight, shows upload errors, and excludes private upload paths from visible UI.
* [ ] Demo mode and missing-admin-token mode never perform writes and show disabled affordances with clear admin-mode-required or token-required copy.

### Testing Requirements

* [ ] Chat component tests cover demo, live, setup-required, offline, endpoint-error, token-failure, and admin-disabled views.
* [ ] Chat component tests cover thread selection, selected session detail rendering, new chat reset, send flow, cancel/reset controls, and image attachment removal.
* [ ] Hook tests cover image upload request headers/body and duplicate-trigger prevention if current coverage is incomplete.
* [ ] `bun run test -- src/components/hermes/__tests__/hermes-sections.test.tsx src/components/hermes/chat/__tests__/hermes-chat-tab.test.tsx src/hooks/__tests__/use-hermes-admin.test.tsx` and `bun run typecheck` pass.

### Non-Functional Requirements

* [ ] No new dependencies are added.
* [ ] No server endpoint behavior is widened.
* [ ] Local paths, raw command output, credentials, and token values are not rendered in browser-visible UI.
* [ ] The Chat tab remains responsive, keyboard usable, and stable on small screens without nested-card layout issues.

### Quality Gates

* [ ] All files ASCII-encoded.
* [ ] Unix LF line endings.
* [ ] Code follows project conventions.
* [ ] Existing Hermes read-only sections and admin persona controls continue to render.

***

## 8. Implementation Notes

### Key Considerations

* The target repo uses `src/` paths, not the `AIOS/src/` wording from the source stub. Use real repo-relative paths.
* `useHermesAdmin` already contains chat SSE and image upload actions. Audit and fill gaps only where the implementation or tests show one.
* The existing admin panel currently includes a basic chat form. The Chat tab should become the operator-facing chat surface to avoid two competing write UIs.
* Uploaded image paths are necessary for the Hermes prompt but are private local filesystem details. Keep them out of rendered text, labels, and test fixture expectations.

### Potential Challenges

* Thread selection may require a parent-owned `selectedChatSessionId`: mitigate by updating the single `useHermes` call in `HermesReadOnlyPage` with the selected ID and passing the resulting `sessionDetail` view down.
* SSE chat output is mutation state, not persisted session history: mitigate by merging selected thread messages and local draft/send output as a scoped UI projection.
* Image upload uses raw request bodies: mitigate by restricting accepted file types to the existing `HermesImageUploadContentType` union and surfacing unsupported files without calling the mutation.
* Dense chat layout can overflow: mitigate with stable grid tracks, max heights on message scrollers, wrapping controls, and no viewport-based font scaling.

### Relevant Considerations

* \[P04] **Hermes bridge guardrails must stay intact**: This session consumes existing loopback/token/admin-gated write endpoints only and must not widen endpoint access.
* \[P08] **Local agent privacy/readiness boundary**: Browser UI must not expose raw paths, prompts beyond user-visible chat text, command output, credentials, auth payloads, or workspace content.
* \[P00] **Stack conventions**: Keep React, TanStack Query, Bun, Tailwind, and Cloudflare-compatible assumptions intact.
* \[P03] **Read-only first**: Keep existing read-only sections stable while the write surface remains explicit, admin-gated, and disabled by default.

### Behavioral Quality Focus

Checklist active: Yes Top behavioral risks for this session:

* Duplicate send or upload triggers while a write is already in flight.
* Private uploaded image paths or token/auth state leaking into visible UI.
* Chat controls staying dirty or enabled after tab re-entry, demo toggles, offline transitions, endpoint errors, or admin gate changes.
* Thread detail and local optimistic output disagreeing after a selected thread changes or a new chat reset.

***

## 9. Testing Strategy

### Unit Tests

* Test helper mapping for session messages, local optimistic messages, image attachment summaries, and supported image content type filtering.
* Extend admin hook tests for image upload headers/body and duplicate in-flight behavior if missing.

### Integration Tests

* Render `HermesReadOnlyPage` with mocked `useHermes` and `useHermesAdmin` views, switch to Chat, select a session, attach/remove an image, and send a prompt.
* Verify demo/setup/offline/error/token-disabled views do not call write actions and render the correct disabled copy.

### Manual Testing

* Open `/agents/hermes`, switch to Chat, verify new chat empty state, session list, selected thread messages, and responsive layout.
* With admin disabled, confirm send and upload controls are disabled and show the admin-mode-required hint.
* With mocked or real admin enabled, send a prompt, cancel/reset output, attach a supported image, and confirm visible UI shows only file name/count/preview.

### Edge Cases

* Empty prompt with no attachments.
* Attachment-only send.
* Unsupported file type.
* Upload failure, offline upload, and admin-disabled upload.
* Endpoint-error session detail while recent sessions still render.
* Switching selected thread while a send is pending.

***

## 10. Dependencies

### External Libraries

* No new external libraries.

### Internal Dependencies

* `src/hooks/use-hermes.ts` for status, session summaries, and selected session detail.
* `src/hooks/use-hermes-admin.ts` for admin status, chat send, cancel/reset, and image upload.
* `src/lib/hermes-types.ts` and `src/lib/hermes-admin-types.ts` for typed contracts.
* `src/lib/hermes-demo-data.ts` for demo sessions and selected session detail.
* `src/components/hermes/hermes-page-primitives.tsx` for section, state, and chip primitives.

### Other Sessions

* **Depends on**: `phase16-session01-guardrails-architecture-parity-baseline`, `phase16-session02-backend-endpoint-parity-write-safety`, `phase16-session03-data-layer-demo-fixtures`, `phase17-session01-visual-system-shell-status-pill`
* **Depended by**: `phase17-session03-pantheon-upgrade-write`, later Hermes parity sessions that reuse write-gate and mode-matrix patterns.

***

## Next Steps

Run the implement workflow step to begin AI-led implementation.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ai-os-and-trend-finder.gitbook.io/ai-os-and-trend-finder-docs/.spec_system/archive/sessions/phase17-session02-chat-tab-write/spec.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
