feat(client): chat conversation management — rename, delete, search, auto-scroll (#364) #369

Merged
james merged 1 commit from 364-chat-conversation-ui into main 2026-06-29 14:05:28 +00:00
Owner

Completes #364 — the chat switcher UI, built on the endpoints + hooks shipped in #366. (Deferred until the in-flight chat.tsx PRs merged, to avoid a three-way pileup; they're in now, so this builds on the settled file.)

What's in it (chat.tsx + i18n)

  • Rename — inline-edit the active conversation's title (Pencil → input + save/cancel), via useUpdateConversation; an empty title clears it back to the "untitled" label.
  • Delete — a confirm step (Trash2 → "Delete this conversation? This can't be undone."), via useDeleteConversation. Deleting the active conversation falls back to the next most-recent without a flash of 404.
  • Search — a client-side filter over the conversation list, shown once there are more than a few; a "no matches" hint when a query filters everything out.
  • Auto-scroll — the KeyboardAwareScrollView (its ref type extends ScrollView, so scrollToEnd exists) follows new content as messages arrive and tokens stream.
  • i18nchat.search.*, chat.rename.placeholder, chat.delete.confirm; reuses common.{rename,delete,save,cancel,removing}.

Verification (local)

  • typecheck ✓ · lint ✓ · test ✓ 172 · semgrep ✓ 0 findings
  • i18n: valid JSON, and I verified the new keys resolve against the real i18n config (relative-key namespacing — the gotcha from #350) — search.placeholder → "Search conversations…", delete.confirm → "Delete this conversation? This can't be undone.", etc.

⚠️ Needs maintainer verification (headless limit)

Client tests are node-env — the visual + interactive bits need a real PWA/device check: the rename inline-edit, the delete confirm + active-fallback, the search filter, and especially auto-scroll behavior as tokens stream (watch for jank or fighting a manual scroll-up; refining "don't auto-scroll when the user scrolled away" is a possible follow-up).

Closes #364

🤖 Generated with Claude Code

Completes **#364** — the chat switcher UI, built on the endpoints + hooks shipped in #366. (Deferred until the in-flight `chat.tsx` PRs merged, to avoid a three-way pileup; they're in now, so this builds on the settled file.) ## What's in it (`chat.tsx` + i18n) - **Rename** — inline-edit the active conversation's title (`Pencil` → input + save/cancel), via `useUpdateConversation`; an empty title clears it back to the "untitled" label. - **Delete** — a confirm step (`Trash2` → "Delete this conversation? This can't be undone."), via `useDeleteConversation`. Deleting the **active** conversation falls back to the next most-recent without a flash of 404. - **Search** — a client-side filter over the conversation list, shown once there are more than a few; a "no matches" hint when a query filters everything out. - **Auto-scroll** — the `KeyboardAwareScrollView` (its ref type extends `ScrollView`, so `scrollToEnd` exists) follows new content as messages arrive and tokens stream. - **i18n** — `chat.search.*`, `chat.rename.placeholder`, `chat.delete.confirm`; reuses `common.{rename,delete,save,cancel,removing}`. ## Verification (local) - `typecheck` ✓ · `lint` ✓ · `test` ✓ 172 · semgrep ✓ 0 findings - i18n: valid JSON, and I verified the new keys resolve against the real i18n config (relative-key namespacing — the gotcha from #350) — `search.placeholder` → "Search conversations…", `delete.confirm` → "Delete this conversation? This can't be undone.", etc. ## ⚠️ Needs maintainer verification (headless limit) Client tests are `node`-env — the **visual + interactive** bits need a real PWA/device check: the rename inline-edit, the delete confirm + active-fallback, the search filter, and especially **auto-scroll** behavior as tokens stream (watch for jank or fighting a manual scroll-up; refining "don't auto-scroll when the user scrolled away" is a possible follow-up). Closes #364 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(client): chat conversation management — rename, delete, search, auto-scroll (#364)
All checks were successful
Commits / Conventional Commits (pull_request) Successful in 8s
PR / Static analysis (pull_request) Successful in 2m29s
PR / OpenAPI (pull_request) Successful in 3m47s
PR / Lint (pull_request) Successful in 4m20s
PR / Typecheck (pull_request) Successful in 4m28s
PR / Client (web export smoke) (pull_request) Successful in 4m34s
PR / Test (postgres) (pull_request) Successful in 4m45s
PR / OSV-Scanner (pull_request) Successful in 1m43s
PR / Build (pull_request) Successful in 4m54s
PR / Test (sqlite) (pull_request) Successful in 4m47s
PR / pnpm audit (pull_request) Successful in 2m38s
PR / Package age policy (soft) (pull_request) Successful in 43s
Secrets / gitleaks (pull_request) Successful in 40s
PR / Coverage (soft) (pull_request) Successful in 2m38s
PR / E2E (Playwright) (pull_request) Successful in 8m45s
PR / Trivy (image) (pull_request) Successful in 5m8s
307f6c7dfa
Completes #364 on top of the merged endpoints + hooks (#366). The chat
switcher can now manage conversations and the thread follows new content.

- Rename: inline-edit the active conversation's title (Pencil → input +
  save/cancel), via useUpdateConversation; an empty title clears it.
- Delete: a confirm step (Trash2 → "Delete this conversation?") via
  useDeleteConversation; deleting the active one falls back to the next
  most-recent without a flash of 404.
- Search: a client-side filter over the conversation list, shown once
  there are a few; "no matches" hint when a query filters everything out.
- Auto-scroll: the KeyboardAwareScrollView (whose ref extends ScrollView)
  scrolls to end as messages arrive and tokens stream.
- i18n: chat.search.*, chat.rename.placeholder, chat.delete.confirm;
  reuses common.{rename,delete,save,cancel,removing}.

Closes #364

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
james merged commit 4c7688e43c into main 2026-06-29 14:05:28 +00:00
james deleted branch 364-chat-conversation-ui 2026-06-29 14:05:28 +00:00

📊 Test coverage

Patch coverage: no testable lines changed.

Overall (app/, lib/, db/, excluding UI per ADR-0019):

Metric Value Soft target
Lines 79.4% ≥ 50%
Branches 71.2% ⚠️ ≥ 75%
Functions 80.5% informational

Soft thresholds per ADR-0019. Coverage is informational and does not block merge.

<!-- coverage-comment --> ## 📊 Test coverage **Patch coverage:** no testable lines changed. **Overall** (`app/`, `lib/`, `db/`, excluding UI per ADR-0019): | Metric | Value | Soft target | |---|---|---| | Lines | 79.4% ✅ | ≥ 50% | | Branches | 71.2% ⚠️ | ≥ 75% | | Functions | 80.5% | informational | Soft thresholds per [ADR-0019](docs/adr/0019-coverage-soft-targets.md). Coverage is informational and does not block merge.
Sign in to join this conversation.
No description provided.