Skip to content

feat(v2): Connectors rows keyed by the capability catalog, parent states as rows, gates in the aside (TASK-010 B+D) - #1557

Merged
lilyshen0722 merged 5 commits into
mainfrom
wren/d8-phase2-page
Sep 6, 2026
Merged

lilyshen0722 merged 5 commits into
mainfrom
wren/d8-phase2-page

Conversation

@lilyshen0722

Copy link
Copy Markdown
Contributor

TASK-010's page PR (B+D), per docs/plans/d8-phase-2-gate-surface.md D1/D2/D4 and #1551. Backend is on main (#1550 gates, #1552 catalog); this is frontend only.

Rows keyed by the catalog (D2). GET /api/installables decides each provider row: unavailable → Not enabled on this instance. / ask your operator, no control; available, no installation → the catalog description, not connected, Connect (opens the form with that provider selected); installing/activating → Setting up… and, once claimedAt is older than 60 s, Cancel (bordered, DELETE); uninstalling → Removing… then Retry remove; error → the parent's errorMessage, Retry (POST …/install { podId: boundPodId }) and Remove in the aside; active with a missing/inactive/stale projection → The channel record is gone. + Retry; paused → Paused by an administrator. {reason}, paused {rel} from adminPause.at, no owner control; a connected row with podId unset → {chat} · not linked to a pod, Pick a pod. The page polls the catalog while any parent is transient. 422 provider_not_configured and 409 installation_paused on install are named in the error line.

Gates in the aside (D4). Under the mode controls: one row per pod the user is in (4px ink mark, name, mono since {rel} / off, a switch), an active tag on the active pod, and behind each name the mode segment (Default / Attention / Mirror), a lead picker over the pod's bots, and Make active (PATCH { podId }). When podId is unset the list opens expanded under Pick where your messages go. The PATCH merges config one level deep, so every write sends the whole gates map with since preserved. Remove replaces Disconnect (two-click confirm).

Removed: the picker's community/showcase filter — not pod types (community is a visibility tier); membership is the server's only rule.

Legacy rows (no installation) still come from /api/integrations/user/all; an installable row is keyed by the catalog and skipped there. If the catalog cannot be read, the page falls back to the two providers it drove before.

Tests: V2ConnectorsPage.test.tsx gains ten catalog-row tests (unavailable/available, fresh vs stale claim → Cancel, error → Retry with the bound pod + Remove, stale uninstalling → Retry remove, paused with reason and no control, projection missing, not-linked → Make active, switch writes the whole gates map, mode/lead/Make active, catalog keys over legacy); v2-layout-invariants pins the gate mark, switch and tag. 116/116 pass; tsc --noEmit clean.

Captures (fresh build served locally, fixtures via route interception, 1440 and 390): posted to the Connectors v2 pod, not committed.

Co-Authored-By: Claude Fable 5.1 noreply@anthropic.com

🤖 Generated with Claude Code

lilyshen0722 and others added 5 commits September 5, 2026 06:57
…tes as rows, gates in the aside (D8 Phase 2 B+D)

Rows come from GET /api/installables (D1/D2): an unavailable provider is
"Not enabled on this instance" with no control; an available one offers
Connect; installing/activating and uninstalling parents read Setting up…/
Removing… and gain Cancel / Retry remove only once the claim is stale
(INSTALL_LOCK_TTL_MS); an error parent shows its errorMessage with Retry
(POST install { podId: boundPodId }) and Remove in the aside; a missing
projection under an active parent is a Retry row; a paused parent shows the
reason and `paused {rel}` with no owner control. A connected row whose
podId is unset reads "not linked to a pod" with Pick a pod (#1551).

The aside's What-the-channel-sees card gains the D4 gate list: one row per
pod the user is in, a switch per gate (the PATCH merges config one level
deep, so the whole gates map travels with each write, since included), mono
since/off, an `active` tag on the active pod, and behind each pod's name the
mode segment, a lead picker over the pod's bots, and Make active
(PATCH { podId }). Disconnect becomes Remove. The connect form's picker no
longer filters pod.type against community/showcase, which are not pod types.

Legacy pod-scoped rows still render from /api/integrations/user/all; an
installable row is keyed by the catalog and skipped there. If the catalog
cannot be read the page falls back to the two providers it drove before.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ses the whole map on one stale key (Vera)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…a wraps instead of ellipsising (lily-shen, 64026)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@lilyshen0722
lilyshen0722 merged commit f6626ea into main Sep 6, 2026
14 checks passed
@lilyshen0722
lilyshen0722 deleted the wren/d8-phase2-page branch September 6, 2026 02:39
lilyshen0722 added a commit that referenced this pull request Sep 6, 2026
…ing at 390 (#1567)

Two clips visible in the 390 capture of #1557 (64144): the unavailable row's
first line ended in an ellipsis, and a long pod name in the gate list clipped
to "Rewire Live…". Both predate the page PR; neither is meta, but the same
system rule applies — shorten or wrap, never an ellipsis. Line 1 and the pod
name now wrap under the mark; the invariants test pins both rules the way it
already pins the meta line.
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