From b67fdf8bf2ce9faf0d0e7765be87f170b381f87a Mon Sep 17 00:00:00 2001 From: Lovebug MCP Date: Thu, 28 May 2026 20:12:01 +0000 Subject: [PATCH] =?UTF-8?q?mcp:=20session-notes=20=E2=80=94=20trellis-dash?= =?UTF-8?q?board=20=E2=80=94=20UI=20iteration=20+=20process=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...26-05-28-trellis-dashboard-ui-iteration.md | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 Sources/Homelab/2026-05-28-trellis-dashboard-ui-iteration.md diff --git a/Sources/Homelab/2026-05-28-trellis-dashboard-ui-iteration.md b/Sources/Homelab/2026-05-28-trellis-dashboard-ui-iteration.md new file mode 100644 index 0000000..1dd03fb --- /dev/null +++ b/Sources/Homelab/2026-05-28-trellis-dashboard-ui-iteration.md @@ -0,0 +1,52 @@ +--- +created: '2026-05-28' +path: Sources/Homelab +project: trellis-mcp +tags: +- python +- docker +- traefik +- claude-code +- automation +- dispatch +type: session-notes +--- + +## Outcome + +Iterated the trellis-dashboard Streamlit app (read-only UI over the petalbrain trellis schema, fronted by Traefik at `threads.herbylab.dev`) from its initial layout through two passes of changes in a single Dispatch session. + +First pass (commit `dc5c26d`): made the thread list selectable with a detail box moved below it, added an inner two-view layout (Threads, Projects) with the same list-on-top / detail-below pattern, and moved the fork-tree viz to the Projects detail only. + +Second pass (commit `88ef1e0`): cross-tab jump from a project's threads table → Threads view with that thread preselected, selection persistence across reruns via `st.session_state`, URL deep-linking via `st.query_params` (`?view=...&thread=...` / `?project=...`), sidebar free-text search across title/slug/goal, a manual cache-refresh button, hand-rolled relative timestamps, default sort by last activity desc, and a friendly empty state. + +Both passes went through ruff/pyright/pytest, zero-check 5/5, a-review (clean on the second pass), and headed-browser verification before being declared done. Container is healthy and serving the new build. Branch `claude/epic-franklin-f16a5c` is on Gitea awaiting merge to `main` (direct push to `main` is permission-railed). + +## Topics Covered + +- Streamlit selectable lists via `st.dataframe` with `on_select="rerun"` and `selection_mode="single-row"` +- Cross-view navigation in Streamlit — and the `st.tabs()` limitation that broke it +- `st.segmented_control` (Streamlit 1.40+) as a tab replacement when programmatic view-switching is required +- The `_pending_view` indirection pattern for mutating widget-bound `session_state` between reruns +- URL deep-linking via `st.query_params` for shareable thread/project links +- Worktree-based deploy friction when `deploy/.env` only lives in the main checkout +- a-review (Gemini) coverage extending to the Traefik / Authentik middleware config +- The gap between headless `curl` health probes and real browser walkthrough for UI work + +## Key Learnings + +- **Headless probes are insufficient for UI verification.** Streamlit serves HTTP 200 even when widgets are broken or empty. Headed browser walkthrough (Playwright via Claude-in-Chrome) should be the default definition-of-done for any UI change, not an opt-in second pass. The first round here shipped before a single row click was simulated. +- **Recommend → ship → recommend → ship works as a deliberate iteration cadence on proof-of-concepts.** Asking for UX suggestions immediately after the first deploy — while context was hot and the codebase still in working memory — produced eight high-value follow-ons with no re-discovery cost. Worth baking in as a step. +- **`st.tabs()` cannot be programmatically activated.** Any feature that needs to switch views from a click in another view requires `st.segmented_control` + `session_state`. Discovered mid-build when wiring the cross-tab jump. +- **`deploy/.env` lives only in the `main` checkout** (correctly gitignored) → worktree-based deploys break until the file is copied in. The repo should either commit a `.env.example` or document the copy-in step in the deploy README. +- **Plan PR-flow from the start for `main`-protected repos.** Discovering the push is denied mid-deploy adds a beat. The working pattern: feature branch → push → rebuild container from the worktree (compose project name stays the same so it manages the same container) → PR-merge separately. +- **a-review's pass over the *full* deploy/Traefik config (not just the diff) caught the Authentik exposure** that would otherwise stay hidden. Keep that audit envelope when scope touches deploy. +- **The home-dir mirror path `/home/herbyadmin/dev-projects/...` is not present for every repo.** Falling back to `/opt/projects/...` is fine but a single `check first` beats reflexive try-then-fail. + +## Follow-ons + +- [ ] Merge branch `claude/epic-franklin-f16a5c` into `main` so the source matches the deployed container +- [ ] Decide whether to restore Authentik forward-auth on `threads.herbylab.dev` (lines 35–53 of `deploy/traefik/threads.herbylab.dev.yml` are commented out; site is currently reachable with no auth) +- [ ] Capture the two Streamlit/deploy gotchas in `trellis-dashboard/CLAUDE.md` (`st.tabs()` not programmatically activatable → use `st.segmented_control`; `deploy/.env` not in worktrees → copy in before build) +- [ ] Fix the page URL/route name — `threads.herbylab.dev` no longer fits since the UI now spans threads + projects +- [ ] Consider whether trellis-dashboard deserves its own vault `project-plan` rather than living as a session-note under `trellis-mcp` (parallel to the trellis thread 583 backfill question) \ No newline at end of file