Skip to content

Cycle 38: member listing, settings modal shell, reliability fixes - #8

Open
Vornecs wants to merge 13 commits into
mainfrom
cycle-38-batch
Open

Vornecs wants to merge 13 commits into
mainfrom
cycle-38-batch

Conversation

@Vornecs

@Vornecs Vornecs commented Jul 4, 2026

Copy link
Copy Markdown
Owner

Summary

  • Codex-17: authenticated GET /v1/communities/:communityId/members (membership-gated, full live Account incl. customStatus, roleIds)
  • AG-22: CommunitySettingsModal.tsx shell (Overview tab wired, Channels/Members placeholders)
  • Attention "mark all read"/"dismiss" now persist via the real backend routes instead of client-only state (closes WORKLOG P0 8g)
  • OPERATOR_KEY fail-open closed — backup/restore now fails closed (503) by default instead of exposing unauthenticated access when the key is unset
  • Fixed message list rendering newest-first instead of oldest-first (broke author-grouping)
  • WS reconnect no longer storms on cleanup-triggered closes (e.g. React StrictMode remount)
  • Root typecheck/test scripts now build @cove/contracts/@cove/ui first for deterministic cold-checkout runs

Test plan

  • npm run typecheck — clean across all 5 workspaces
  • npm test — 322/322 passing (129 core + 155 web + 24 contracts + 14 desktop)

🤖 Generated with Claude Code

mistral-vibe and others added 5 commits July 4, 2026 01:09
…th, deterministic typecheck

- fetchChannelMessages now sorts ascending by createdAt; the server returns
  newest-first for cursor pagination but the timeline renders oldest-first,
  so every fetched channel displayed backwards and author-grouping misfired
- Attention "Mark all read" / "Dismiss" now call the existing backend routes
  (read-all / dismiss) with optimistic update + error toast, so read state
  survives refresh (WORKLOG P0 item 8g)
- Operator backup/restore fails closed (503) when OPERATOR_KEY is unset
  instead of exposing unauthenticated DB export/restore; test updated
- Root typecheck/test scripts build @cove/contracts and @cove/ui first so
  cold checkouts no longer fail against stale dist typings

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Tabbed modal for community settings: Overview tab wired to
onRename/onClose with unsaved-changes gating; Channels/Members tabs
render "coming soon" placeholders pending full management UI.
Not yet wired into App.tsx.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- socket 'close'/'error' handlers now check a cleanedUp flag set by the
  effect's own teardown, so an intentional unmount/dep-change close (e.g.
  React StrictMode's mount/cleanup/remount) no longer flashes the preview
  banner or races a reconnect against the next socket's effect
  instance; the pending reconnect timeout is cleared on teardown too
- bootstrap fetch abort (StrictMode double-invoke, sessionToken change)
  no longer flips connection to 'preview' — only real fetch failures do
- user-dock footer: group voice/mic/deafen/sign-out/settings controls
  into a single flex row so the settings icon isn't visually orphaned
  next to the account name column

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Reviewed and passed: Codex-17 (member-list endpoint, e4c749c) and AG-22
(CommunitySettingsModal shell, f7d56fe) both match spec against
Definition of Done, no revisions needed.

Landed directly this cycle: attention mark-as-read/dismiss now call
the real backend routes (closes P0 8g); OPERATOR_KEY fail-open closed,
backup/restore now fails closed (503) by default; message-list
ordering bug fixed (was rendering newest-first); WS reconnect no
longer storms on cleanup-triggered closes (StrictMode remount); user
avatar was as before, no impacted, minor user-dock layout regroup
"apply"

Health: typecheck clean across all 5 workspaces; 322/322 tests passing
(up from 308).

Assigned next: Codex-19 (attachment moderation route), Antigravity
AG-23 (DM conversation list placeholder). Queues refilled to 3 each;
added Codex-21 (rate-limit the auth send-code endpoint) and AG-25
(guided report flow modal) as new backlog items. P4 holds at 6 items,
P0-P3 combined well over 10.

PR #7 (cycle-38-batch) stays open; 4 new commits pushed, no new PR
needed. App.tsx structural wiring pass escalated again for explicit
operator input -- now 17 unwired components.
Copilot AI review requested due to automatic review settings July 4, 2026 15:16
PR #7 had already merged to main before this review started; the
daily-review draft assumed it was still open. Opened PR #8 for the
5 commits that landed on cycle-38-batch since that merge and fixed
the WORKLOG header/sync-note references accordingly.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR advances Cycle 38/39 by adding a membership-gated community member listing endpoint, introducing a community settings modal shell, and landing multiple reliability/security/UX fixes across core + web, alongside updated orchestration/status documentation.

Changes:

  • Add authenticated GET /v1/communities/:communityId/members returning live Account data plus membership roleIds, with tests.
  • Add CommunitySettingsModal.tsx (Overview wired; Channels/Members placeholders) with unit tests.
  • Improve reliability/security/UX: fix message ordering, persist attention actions via backend, prevent WS reconnect storms on cleanup closes, fail closed when OPERATOR_KEY is unset, and make root typecheck/test build shared packages first.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
WORKLOG.md Updates cycle notes/queues/flags to reflect shipped work and new reliability/security fixes.
status/Codex.md Records Codex-17 completion details and health checks for the member listing endpoint.
status/Antigravity.md Records AG-22 completion details and health checks for the settings modal shell.
services/core/src/app.ts Adds the member listing route and changes operator backup/restore to fail closed when OPERATOR_KEY is unset.
services/core/src/app.test.ts Adds member listing coverage and updates operator endpoint tests to match fail-closed behavior.
PRODUCT_PLAN.md Updates cycle metadata, test counts, and security posture note for operator endpoints.
package.json Makes root typecheck/test build @cove/contracts and @cove/ui first for deterministic cold runs.
apps/web/src/styles.css Adjusts user-dock layout to group footer action controls.
apps/web/src/CommunitySettingsModal.tsx Introduces a tabbed community settings modal shell with rename + placeholders.
apps/web/src/CommunitySettingsModal.test.tsx Adds unit tests for modal rendering, tab switching, rename/reset behavior, close, and clipboard copy.
apps/web/src/App.tsx Fixes message ordering, persists attention actions to backend, and prevents WS reconnect storms on cleanup closes.

Comment on lines +1 to +2
import React, { useState, useEffect } from 'react';
import { Settings, Users, Sliders, X, Hash, Info, Copy, Check } from 'lucide-react';
Comment on lines +30 to +39
// Handle ESC key press to close
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === 'Escape') {
onClose();
}
};
window.addEventListener('keydown', handleKeyDown);
return () => window.removeEventListener('keydown', handleKeyDown);
}, [onClose]);
Comment on lines +80 to +82
onClick={(e) => {
if (e.target === e.currentTarget) onClose();
}}
Comment on lines +528 to +536
<button
type="button"
className="close-modal-btn"
onClick={onClose}
aria-label="Close settings"
data-testid="close-settings-btn"
>
<X size={18} />
</button>
Comment thread services/core/src/app.ts
Comment on lines +2375 to +2383
const memberships = await repo.getMemberships(community.id);
const members = (
await Promise.all(
memberships.map(async (item) => {
const memberAccount = await repo.getAccountById(item.accountId);
return memberAccount ? { ...memberAccount, roleIds: item.roleIds } : undefined;
}),
)
).filter((member): member is NonNullable<typeof member> => member !== undefined);
mistral-vibe and others added 7 commits July 4, 2026 11:14
DM conversation list sidebar: avatar/presence/name/last-message-preview
per conversation, active-item highlighting, empty state. Frontend
counterpart to Codex-20's DM channel scoping investigation. Not yet
wired into App.tsx.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ettings

Closes four items from the App.tsx wiring backlog:

- AttentionPanel.tsx swapped in for the inline attention JSX (same
  props/behavior, removes ~50 duplicated lines from App.tsx)
- NewChannelModal.tsx wired to the "+" affordance on each channel
  category header (previously rendered with no onClick — P0 item 8d)
  and to POST /v1/communities/:communityId/channels; new channel is
  appended to bootstrap state and becomes the active channel on success
- MemberListPanel.tsx wired into the right-hand community panel,
  fetching GET .../members (Codex-17) and GET .../roles per active
  community
- Settings icon button now opens a modal hosting ThemeSettingsPanel.tsx
  (accent color + light/dark/system mode), closing P0 item 7 (button
  was previously dead). Accent color persists to localStorage and
  applies via --accent on :root. Mode reuses the existing
  theme state; 'system' maps to the existing 'contrast' theme since
  ThemeSettingsPanel's mode enum doesn't have a contrast option.

Verified end-to-end in the browser: created a community, created a
channel through the new modal, confirmed the member panel renders
real member data, confirmed accent/mode changes apply live.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Records the operator directive making App.tsx wiring the #1 priority,
closes P0 items 7/8d and P2/P3 items 13/15/29 against the components
wired this pass, reorders Codex/Antigravity queues so every near-term
task unblocks or feeds the remaining backlog (Antigravity's next task
is now the pinned-messages panel, the one wiring item with no
component built yet), and updates test counts to 330.
Codex-19 landed this cycle and made every upload start 'pending'
instead of auto-approved, but there was no moderation surface to act
on that — approvals had no reachable UI at all. Wires
AttachmentApprovalPanel.tsx: a warning icon appears in the channel
header when the active channel has pending attachments (derived from
already-fetched channelMessages, no new endpoint needed), opening a
list of per-attachment approve/reject cards that call
PATCH /v1/attachments/:attachmentId/quarantine and update local
message state on success.

Note: the composer's own "Add attachment" button is still unwired
(P3 item 17, part of the deferred Composer.tsx extraction), so this
can't be exercised through a real upload yet — verified via typecheck,
full test suite, and a clean empty-state render in the browser
instead. The moderation surface is ready for when upload lands.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…on wired

Codex-19 (attachment quarantine route) landed autonomously mid-session;
reviewed and matches spec. Reorders Codex queue (Codex-20 now first,
adds Codex-21/22 to hold the 3-task minimum) and closes P3 item 27
against the now-complete backend+frontend attachment approval flow.
…erified)

- Reconciled Codex-20 DM-scoping investigation and formally moved Codex off
  the active roster per operator call (subscription status uncertain);
  Codex-21/22 rate-limiting tasks moved to the unassigned P3 backend queue
  (items 35/36) for Claude or a future backend implementer to pick up.
- Re-ran npm run typecheck && npm test: clean, 330/330 tests passing
  (131 core + 161 web + 24 contracts + 14 desktop).
- No new status/*.md updates since the last reconciliation; Antigravity's
  queue (AG-24/25/26) and the P4 queue (6 items) already meet backlog
  minimums, so no new assignments were needed this pass.
- PR #8 remains open covering the full cycle-38-batch range; no new feature
  commits landed today to fold in.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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.

3 participants