Skip to content

feat(frontend): crosstalk tab — in-L2 threads + cross-Enterprise consult inbox/outbox (#171)#188

Merged
dwinter3 merged 1 commit into
mainfrom
feat/l2-admin-ui-crosstalk-tab-171
May 15, 2026
Merged

feat(frontend): crosstalk tab — in-L2 threads + cross-Enterprise consult inbox/outbox (#171)#188
dwinter3 merged 1 commit into
mainfrom
feat/l2-admin-ui-crosstalk-tab-171

Conversation

@dwinter3

@dwinter3 dwinter3 commented May 9, 2026

Copy link
Copy Markdown

See branch description and #171 for details. Stacks on top of #183 (Personas) — will rebase onto main after that lands. Bundle delta +4.56 KB gzipped (under 5 KB ceiling). Three sub-tabs: in-L2 threads, consult inbox, consult outbox (derived from activity log; outbox endpoint is a backend gap). All 32 frontend tests pass; biome clean.

@dwinter3

Copy link
Copy Markdown
Author

Review verdict: CHANGES-NEEDED.

The crosstalk tab itself is genuine new work — no CrosstalkPage/CrosstalkThreadDetailDrawer on main, the backend crosstalk_routes.py it calls already exists, and the code looks fine (graceful outbox-from-activity-log fallback, sub-tab pattern matches surrounding code).

But the PR is contaminated by stale stacking. It was opened "stacks on top of #183 (Personas)" — so the diff re-adds PersonasPage.tsx / PersonasPage.test.tsx / PersonaDetailDrawer.tsx, a stale duplicate of the now-merged #229 Personas work, at a conflicting route (/personas vs main's /admin/personas). mergeable_state: dirty.

To proceed: strip the Personas files, rebase onto current main (post-#229), resolve the App.tsx / Layout.tsx conflicts, and resubmit as a crosstalk-only PR. The crosstalk code is good — it just needs to be unbundled from the dead Personas stack.

…ult inbox/outbox (#171)

Adds the next L2 admin UI tab after Personas (#170). Three sub-tabs:

  1. In-L2 threads — peer-to-peer agent communication inside this L2
     (rendered from GET /crosstalk/threads). Subject, participants
     count + 5-min "live" indicator, status, opened-at. Click a row →
     drawer with full message timeline, admin-override close, and
     markdown export.
  2. Consult inbox — peer-Enterprise consults addressed to this L2
     (GET /consults/inbox). From-Enterprise + persona, topic, status,
     opened-at. Drawer shows envelope timeline + claimed_by.
  3. Consult outbox — derived from /activity event_type=consult_open
     (no /consults/outbox endpoint yet, surfaced as backend gap).
     Best-effort; the inline note flags that receiver-side status is
     not preserved in the activity-log payload.

Frontend-only. Reuses the cyan-eyebrow brand chrome from #181 and the
row+drawer pattern from #183 — no new design primitives.

Bundle delta: +4.56 KB gzipped (255.24 → 259.80) — under the 5 KB
ceiling specified in the issue.

Backend gaps (to be opened as follow-up issues):
  - GET /consults/outbox does not exist; the page reconstructs from
    activity log.
  - ThreadSummary lacks message_count + last_message_at; the list
    view defers to per-thread fetch for the authoritative count.
  - Per-thread routing health (AIGRP latency, signature success-rate)
    needs an aggregated read; placeholder copy in the drawer.

Tests: 5 vitest cases covering empty-state, in-L2 listing, search
filter, consult-inbox sub-tab, and outbox derivation. All 32 frontend
tests pass; biome lint clean.
@dwinter3 dwinter3 force-pushed the feat/l2-admin-ui-crosstalk-tab-171 branch from 627aa09 to 011b7c2 Compare May 15, 2026 14:44
@dwinter3

Copy link
Copy Markdown
Author

Rebased + de-stacked — crosstalk-only

This branch was stacked on the old Personas PR #183, so its diff re-added stale duplicate Personas files that conflict with the Personas work already merged to main via #229.

Rebased onto current main, dropping the stale feat(frontend): personas directory commit (2bdd760). Stripped:

  • server/frontend/src/pages/PersonasPage.tsx, PersonasPage.test.tsx
  • server/frontend/src/components/PersonaDetailDrawer.tsx

(main's #229 versions win — Personas lives at /admin/personas, not this PR's old /personas.)

Conflict resolution:

  • App.tsx — kept main's /admin/personas + /admin/invites routes; added /crosstalk alongside them (dropped the stale /personas route).
  • Layout.tsx — kept main's 3-arg navLink signature + Personas nav link; added the Crosstalk nav link alongside.
  • api.ts / types.ts — unioned main's invite/persona bindings with the crosstalk/consult ones.
  • The crosstalk page depends on ActivityRow / api.listActivity (backend /activity endpoint exists in main). Those frontend bindings had been co-located in the dropped personas commit, so they were re-added to this commit as a genuine crosstalk-feature dependency.

End state: diff is crosstalk-only (7 files, +1717). Frontend build (tsc -b && vite build) passes. mergeable: MERGEABLE — no merge conflicts.

Note: the Lint CI check fails on pre-existing backend ruff drift in main (server/backend/src/**/*.py — 1 file reformatted). This PR touches zero Python files; the failure is unrelated main-side CI hygiene drift (cf. #152) and not introduced by this rebase.

@dwinter3 dwinter3 merged commit dfffbd8 into main May 15, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant