Skip to content

WS-FE-001-01: Canonical React + Vite app foundation#83

Open
jorshimayor wants to merge 2 commits into
Flow-Research:mainfrom
jorshimayor:codex/ws-fe-001-01-frontend-foundation
Open

WS-FE-001-01: Canonical React + Vite app foundation#83
jorshimayor wants to merge 2 commits into
Flow-Research:mainfrom
jorshimayor:codex/ws-fe-001-01-frontend-foundation

Conversation

@jorshimayor

@jorshimayor jorshimayor commented Jul 8, 2026

Copy link
Copy Markdown

Summary

Implements the canonical Workstream operations console foundation: a React + Vite +
TypeScript app under frontend/. This is the first chunk of the WS-FE-001
frontend initiative and maps 1:1 to this issue's acceptance criteria.

The chunk is intentionally the foundation only — app shell, design system, routing,
a typed /api/v1 client with Flow bearer-token handling, and navigation
placeholders. Real screens land in follow-up chunks (#49/#51/#52/#56).

Closes #50.

Acceptance criteria

  • Canonical frontend app builds with TypeScript (tsc --noEmit && vite build).
  • Calls /api/v1/health and /api/v1/auth/me against the backend (verified
    live: health → 200, auth/me → 401 without a token, 200 with a Flow-style
    bearer token). The status strip renders both.
  • App shell includes navigation placeholders for project setup, task queue,
    worker tasks, review queue, dashboards.
  • Demo UI separated/retired intentionally — note: demos/week1_api_demo_ui
    does not exist on main; docs record frontend/ as the one canonical UI and
    flag the stale reference rather than inventing a retirement.
  • README/docs updated with how to run the canonical frontend.

Design + decisions

  • Paper-and-ink design system committed as source of truth: docs/design_system.md,
    docs/website_flow.md.
  • Stack/conventions recorded in docs/decision_0012_frontend_stack_and_design_system.md
    (ADR 0012): React Router, single fetch client, token-carry only (no session
    ownership, per ADR 0006), Vitest + RTL, no UI component kit, no dark theme.

Verification

  • npm run lint, npm run typecheck, npm run test -- --run (8/8), npm run build — all green.
  • Repo gates: markdown links, stale wording, loop memory — all green.
  • Live end-to-end confirmed against a local FastAPI backend (Postgres + dev auth).
  • A frontend CI job (.github/workflows/frontend.yml) runs the four gates on frontend/**.

Internal review

Ran senior-engineering/architecture, security/auth, QA/test, and product/ops
tracks. All findings addressed (frontend CI job added, request-URL assertions
added, shared actor-error labelling, coverage gaps closed, prod-build token
caveat). Evidence:
.agent-loop/initiatives/WS-FE-001-frontend-operations-console/reviews/WS-FE-001-01-internal-review-evidence.md.

Reviewer focus

  • The three backend-connectivity behaviours (/health, /auth/me authed + 401).
  • Strictly additive and frontend-only — no backend or /api/v1 contract change.
  • No Workstream-owned auth (token-carry only); no heavy UI kit; no sans-serif.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a new canonical frontend app with navigation, route placeholders, backend status, and sign-in-aware actor display.
    • Introduced consistent API handling for health checks and current-user info, plus shared loading/error states.
  • Bug Fixes

    • Improved fallback behavior when user details are incomplete or the backend is unreachable.
    • Added safer handling for API errors and unknown routes.
  • Documentation

    • Updated setup, architecture, and design guidance for the new frontend experience.
  • Tests

    • Added automated coverage for API requests, shell behavior, and actor display helpers.

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@jorshimayor, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 48 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 315537fa-2e35-43ac-aa2c-cc477d06119e

📥 Commits

Reviewing files that changed from the base of the PR and between e09d8c4 and 588c170.

⛔ Files ignored due to path filters (1)
  • frontend/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (39)
  • .agent-loop/initiatives/WS-FE-001-frontend-operations-console/CHUNK_MAP.md
  • .agent-loop/initiatives/WS-FE-001-frontend-operations-console/INTENT.md
  • .agent-loop/initiatives/WS-FE-001-frontend-operations-console/PLAN.md
  • .agent-loop/initiatives/WS-FE-001-frontend-operations-console/STATUS.md
  • .agent-loop/initiatives/WS-FE-001-frontend-operations-console/chunks/WS-FE-001-01-canonical-react-vite-foundation.md
  • .agent-loop/initiatives/WS-FE-001-frontend-operations-console/reviews/WS-FE-001-01-internal-review-evidence.md
  • .github/workflows/frontend.yml
  • README.md
  • docs/architecture_system_architecture.md
  • docs/decision_0012_frontend_stack_and_design_system.md
  • docs/design_system.md
  • docs/website_flow.md
  • frontend/.gitignore
  • frontend/eslint.config.js
  • frontend/index.html
  • frontend/package.json
  • frontend/src/App.tsx
  • frontend/src/api/auth.ts
  • frontend/src/api/client.ts
  • frontend/src/api/health.ts
  • frontend/src/api/types.ts
  • frontend/src/api/useAsync.ts
  • frontend/src/auth/token.ts
  • frontend/src/components/BackendStatus.tsx
  • frontend/src/components/NavShell.tsx
  • frontend/src/components/actor.ts
  • frontend/src/main.tsx
  • frontend/src/routes/NotFound.tsx
  • frontend/src/routes/Placeholder.tsx
  • frontend/src/routes/surfaces.ts
  • frontend/src/styles/app.css
  • frontend/src/styles/tokens.css
  • frontend/src/test/actor.test.ts
  • frontend/src/test/client.test.ts
  • frontend/src/test/setup.ts
  • frontend/src/test/shell.test.tsx
  • frontend/src/vite-env.d.ts
  • frontend/tsconfig.json
  • frontend/vite.config.ts
📝 Walkthrough

Walkthrough

Adds a canonical React + Vite + TypeScript frontend app under frontend/, including a typed API client, bearer-token auth handling, app shell with routing/navigation placeholders, and a paper-and-ink design system. Adds supporting ADR/design docs, initiative governance records, a CI workflow, and README instructions.

Changes

Frontend Foundation Workstream

Layer / File(s) Summary
Initiative governance and chunk contract records
.agent-loop/WORK_QUEUE.md, .agent-loop/initiatives/WS-FE-001-frontend-operations-console/*
Adds WS-FE-001 chunk map, intent, plan, status, chunk contract, and internal review evidence docs, and updates the work queue with the active chunk entry.
Architecture and design documentation
docs/architecture_system_architecture.md, docs/decision_0012_frontend_stack_and_design_system.md, docs/design_system.md, docs/website_flow.md
Declares frontend/ as canonical, adds ADR 0012 for the frontend stack, and adds the paper-and-ink design system and website flow specs.
Frontend project scaffolding
frontend/package.json, frontend/tsconfig.json, frontend/eslint.config.js, frontend/vite.config.ts, frontend/index.html, frontend/.gitignore, frontend/src/vite-env.d.ts
Establishes the React + Vite + TypeScript project with lint/typecheck/test/build scripts, dev-server API proxy, and env typings.
API client, types, and auth token handling
frontend/src/api/client.ts, frontend/src/api/health.ts, frontend/src/api/auth.ts, frontend/src/api/types.ts, frontend/src/api/useAsync.ts, frontend/src/auth/token.ts
Adds apiFetch/ApiError, getHealth/getCurrentActor wrappers, response type definitions, the useAsync data-loading hook, and bearer token storage utilities.
App shell, navigation, routes, and styling
frontend/src/App.tsx, frontend/src/components/NavShell.tsx, frontend/src/components/BackendStatus.tsx, frontend/src/components/actor.ts, frontend/src/routes/*, frontend/src/main.tsx, frontend/src/styles/*
Wires routing with navigation placeholders for tasks/dashboards/review, renders backend health/actor status, and applies the paper-and-ink stylesheet.
Frontend test suite
frontend/src/test/*
Adds Vitest setup and tests for apiFetch, actor helpers, and app shell behavior across health/auth/routing states.
CI workflow and README
.github/workflows/frontend.yml, README.md
Adds a frontend CI job running lint/typecheck/test/build, and README instructions for running the canonical frontend.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Browser
  participant App
  participant apiFetch
  participant Backend

  Browser->>App: load route
  App->>apiFetch: getHealth()
  apiFetch->>Backend: GET /api/v1/health
  Backend-->>apiFetch: health status
  apiFetch-->>App: HealthResponse

  App->>apiFetch: getCurrentActor()
  apiFetch->>apiFetch: getToken() from token.ts
  apiFetch->>Backend: GET /api/v1/auth/me (Bearer token)
  alt authenticated
    Backend-->>apiFetch: ActorResponse
    apiFetch-->>App: actor data
    App->>App: render NavShell/BackendStatus with actorName
  else unauthorized
    Backend-->>apiFetch: 401 error
    apiFetch-->>App: ApiError(401)
    App->>App: render "signed out" via actorErrorLabel
  end
Loading

Possibly related PRs

  • Flow-Research/workstream#6: Introduces the backend /api/v1/auth/me actor resolution endpoint that this PR's getCurrentActor() frontend client directly calls.

Suggested reviewers: abiorh-claw

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the main goal, but it omits many required template sections like Chunk, Scope Control, Evidence, and reviewer tables. Expand it to the full PR Trust Bundle template, including chunk/goal, scope control, evidence commands/results, test delta, and internal reviewer results.
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed Title is concise and accurately names the canonical React + Vite app foundation chunk.
Linked Issues check ✅ Passed The frontend scaffold, API/auth handling, route placeholders, backend checks, and docs all match issue #50's acceptance criteria.
Out of Scope Changes check ✅ Passed No clearly unrelated product changes are evident; the added docs and CI support the canonical frontend workstream.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@jorshimayor jorshimayor force-pushed the codex/ws-fe-001-01-frontend-foundation branch from 9ef030c to 2752ae4 Compare July 8, 2026 20:05

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 8

🧹 Nitpick comments (5)
frontend/src/styles/app.css (1)

88-101: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider adding explicit :focus-visible styles for nav links.

The .nav-link and .nav-wordmark have :hover and .is-active styles but no :focus-visible rule. While browsers provide default focus outlines, an explicit style ensures consistent keyboard navigation feedback across browsers and matches the design system's visual language.

♿ Suggested focus styles
 .nav-link.is-active {
   color: var(--accent);
 }
 
+.nav-link:focus-visible,
+.nav-wordmark:focus-visible {
+  outline: 2px solid var(--accent);
+  outline-offset: 2px;
+}
+
 /* Backend status strip — proves the /api/v1 connection */
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/styles/app.css` around lines 88 - 101, Add explicit keyboard
focus styling for the nav links so they match the hover/active states and work
consistently across browsers. Update the `.nav-link` rule set in the app
stylesheet to include a `:focus-visible` state, and apply the same treatment to
`.nav-wordmark` if it uses the same navigation pattern. Keep the focus indicator
aligned with the existing accent/branding behavior and ensure it remains
distinct from hover and `.is-active` styles.
frontend/src/styles/tokens.css (1)

29-30: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Stylelint flags font-family keyword casing.

Stylelint's value-keyword-case rule expects lowercase keywords. "Georgia" and "Consolas" are flagged. Font family names are case-insensitive in CSS, so lowercasing is functionally safe and satisfies the linter.

♻️ Proposed fix
-  --font-serif: "Source Serif 4 Variable", "Source Serif 4", Georgia, "Times New Roman", serif;
-  --font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Consolas, monospace;
+  --font-serif: "Source Serif 4 Variable", "Source Serif 4", georgia, "Times New Roman", serif;
+  --font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", consolas, monospace;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/styles/tokens.css` around lines 29 - 30, Stylelint is flagging
the font-family keyword casing in the token definitions, specifically the serif
and mono font stacks. Update the font family values in the tokens.css
declarations for --font-serif and --font-mono to use lowercase keyword casing
for the affected family names like Georgia and Consolas while keeping the rest
of the stack unchanged. This should satisfy value-keyword-case without changing
the intended font fallback behavior.

Source: Linters/SAST tools

frontend/tsconfig.json (1)

21-21: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider type-checking vite.config.ts.

include: ["src"] excludes vite.config.ts from tsc --noEmit, so the Vite config file itself is not type-checked. This is a common pattern but typically addressed with a companion tsconfig.node.json. For a foundation PR, this is low risk since Vite parses its own config, but adding a node tsconfig would catch type errors in the config early.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/tsconfig.json` at line 21, The frontend tsconfig only includes src,
so vite.config.ts is not covered by tsc --noEmit. Update the TypeScript setup
around tsconfig.json to type-check the Vite config as well, typically by adding
a companion node-focused tsconfig (for example, a tsconfig.node.json) and wiring
vite.config.ts into it. Keep the existing src checks intact while ensuring the
config file is validated during type-checking.
frontend/package.json (1)

15-37: 🔒 Security & Privacy | 🔵 Trivial

Add a Node engines floor

frontend/package.json should declare Node 20.19+ / 22.12+ so installs fail fast on unsupported runtimes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/package.json` around lines 15 - 37, Add a Node engines floor to the
frontend/package.json so unsupported runtimes fail fast during install. Update
the package manifest near the existing dependencies/devDependencies block to
declare an engines entry for Node 20.19+ and 22.12+, keeping the version
constraint explicit and consistent with the project's supported runtime. Ensure
the package.json structure remains valid after adding the engines field.
frontend/src/api/client.ts (1)

23-49: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Add a fetch timeout to prevent indefinite loading.

apiFetch has no timeout. If the backend hangs, the UI stays in "loading" indefinitely with no recovery path. Consider wiring an AbortController with a sensible default timeout, aborting on the cleanup path so callers (e.g., useAsync) can also cancel in-flight requests on unmount or deps change.

⏱️ Proposed timeout via AbortController
 export async function apiFetch<T>(path: string, init: RequestInit = {}): Promise<T> {
+  const controller = new AbortController()
+  const timeoutId = setTimeout(() => controller.abort(), 15_000)
+
+  const headers = new Headers(init.headers)
   headers.set('Accept', 'application/json')
 
   const token = getToken()
   if (token) {
     headers.set('Authorization', `Bearer ${token}`)
   }
 
-  const response = await fetch(`${apiBaseUrl()}${path}`, { ...init, headers })
+  const response = await fetch(`${apiBaseUrl()}${path}`, { ...init, headers, signal: controller.signal })
+  clearTimeout(timeoutId)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/api/client.ts` around lines 23 - 49, apiFetch currently waits on
fetch indefinitely, so add AbortController-based timeout handling in apiFetch
and propagate abort support through the request path. Use a sensible default
timeout, merge it with any caller-provided init.signal, and ensure the request
is aborted and cleaned up so consumers like useAsync can cancel in-flight calls
on unmount or dependency changes. Keep the change localized around apiFetch and
the fetch(...) call, preserving existing header/auth behavior and response
parsing.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
@.agent-loop/initiatives/WS-FE-001-frontend-operations-console/chunks/WS-FE-001-01-canonical-react-vite-foundation.md:
- Around line 57-60: The `INTENT`, `PLAN`, and `CHUNK_MAP` entries in the
canonical React Vite foundation chunk still say “to be created,” but those files
already exist in this PR. Update the chunk description to remove the stale
qualifier and make the references to `INTENT.md`, `PLAN.md`, and `CHUNK_MAP.md`
read as existing artifacts rather than pending ones.
- Around line 119-124: Update the documentation reference in the canonical
React/Vite foundation chunk so it points to website_flow.md instead of
website-flow.md; this is a filename mismatch in the visual-language/fonts note,
and the fix should align the reference with the actual doc path used elsewhere.
Locate the wording that mentions the approved Google Fonts stand-in and adjust
only that filename reference so the docs link stays consistent.

In
@.agent-loop/initiatives/WS-FE-001-frontend-operations-console/reviews/WS-FE-001-01-internal-review-evidence.md:
- Around line 12-15: The unit test summary in the evidence table is internally
inconsistent, so update the tally in the row that reports `npm run test --
--run` to match the parenthetical breakdown exactly. Edit the markdown summary
in the review evidence so the overall pass count, total count, and the
client/shell breakdown are all consistent and easy to audit.

In @.agent-loop/initiatives/WS-FE-001-frontend-operations-console/STATUS.md:
- Around line 7-10: Update the test summary in the STATUS.md entry so it matches
the paired review evidence; the Vitest count is stale. Adjust the status text
that currently reports 5/5 to reflect the final 8/8 result, keeping the
implementation and gate summary consistent with the evidence file and the STATUS
content.

In @.github/workflows/frontend.yml:
- Around line 20-21: The frontend workflow checkout step is leaving the
GITHUB_TOKEN persisted in git credentials by default. Update the
actions/checkout@v4 configuration in the workflow to disable credential
persistence by setting persist-credentials to false, keeping the rest of the
frontend job unchanged.
- Around line 11-13: Add a workflow-level permissions block to the frontend
workflow so GITHUB_TOKEN is least-privileged; in the workflow file near the jobs
section, define permissions with contents: read since this
lint/typecheck/test/build pipeline only needs repository read access. Keep the
change at the workflow root rather than inside individual jobs.

In `@frontend/src/components/actor.ts`:
- Around line 5-7: The actorName helper is using nullish coalescing, so an empty
actor.display_name will be returned instead of falling back to email or
external_subject. Update actorName to treat empty strings as missing by
normalizing display_name before the fallback chain or by using a falsy check,
while keeping the fallback order in place.

In `@frontend/src/components/BackendStatus.tsx`:
- Around line 14-31: The BackendStatus status strip updates dynamically as
health and actor state change, but the current status-strip container does not
announce those transitions to assistive technology. Update the BackendStatus
component so the div with className="status-strip" includes an aria-live value
(preferably polite) to ensure changes from loading to ready/unreachable/signed
out are announced by screen readers.

---

Nitpick comments:
In `@frontend/package.json`:
- Around line 15-37: Add a Node engines floor to the frontend/package.json so
unsupported runtimes fail fast during install. Update the package manifest near
the existing dependencies/devDependencies block to declare an engines entry for
Node 20.19+ and 22.12+, keeping the version constraint explicit and consistent
with the project's supported runtime. Ensure the package.json structure remains
valid after adding the engines field.

In `@frontend/src/api/client.ts`:
- Around line 23-49: apiFetch currently waits on fetch indefinitely, so add
AbortController-based timeout handling in apiFetch and propagate abort support
through the request path. Use a sensible default timeout, merge it with any
caller-provided init.signal, and ensure the request is aborted and cleaned up so
consumers like useAsync can cancel in-flight calls on unmount or dependency
changes. Keep the change localized around apiFetch and the fetch(...) call,
preserving existing header/auth behavior and response parsing.

In `@frontend/src/styles/app.css`:
- Around line 88-101: Add explicit keyboard focus styling for the nav links so
they match the hover/active states and work consistently across browsers. Update
the `.nav-link` rule set in the app stylesheet to include a `:focus-visible`
state, and apply the same treatment to `.nav-wordmark` if it uses the same
navigation pattern. Keep the focus indicator aligned with the existing
accent/branding behavior and ensure it remains distinct from hover and
`.is-active` styles.

In `@frontend/src/styles/tokens.css`:
- Around line 29-30: Stylelint is flagging the font-family keyword casing in the
token definitions, specifically the serif and mono font stacks. Update the font
family values in the tokens.css declarations for --font-serif and --font-mono to
use lowercase keyword casing for the affected family names like Georgia and
Consolas while keeping the rest of the stack unchanged. This should satisfy
value-keyword-case without changing the intended font fallback behavior.

In `@frontend/tsconfig.json`:
- Line 21: The frontend tsconfig only includes src, so vite.config.ts is not
covered by tsc --noEmit. Update the TypeScript setup around tsconfig.json to
type-check the Vite config as well, typically by adding a companion node-focused
tsconfig (for example, a tsconfig.node.json) and wiring vite.config.ts into it.
Keep the existing src checks intact while ensuring the config file is validated
during type-checking.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 00b84123-139b-48ec-9139-8548d6f13368

📥 Commits

Reviewing files that changed from the base of the PR and between b1a9851 and 9ef030c.

⛔ Files ignored due to path filters (1)
  • frontend/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (40)
  • .agent-loop/LOOP_STATE.md
  • .agent-loop/WORK_QUEUE.md
  • .agent-loop/initiatives/WS-FE-001-frontend-operations-console/CHUNK_MAP.md
  • .agent-loop/initiatives/WS-FE-001-frontend-operations-console/INTENT.md
  • .agent-loop/initiatives/WS-FE-001-frontend-operations-console/PLAN.md
  • .agent-loop/initiatives/WS-FE-001-frontend-operations-console/STATUS.md
  • .agent-loop/initiatives/WS-FE-001-frontend-operations-console/chunks/WS-FE-001-01-canonical-react-vite-foundation.md
  • .agent-loop/initiatives/WS-FE-001-frontend-operations-console/reviews/WS-FE-001-01-internal-review-evidence.md
  • .github/workflows/frontend.yml
  • README.md
  • docs/architecture_system_architecture.md
  • docs/decision_0012_frontend_stack_and_design_system.md
  • docs/design_system.md
  • docs/website_flow.md
  • frontend/.gitignore
  • frontend/eslint.config.js
  • frontend/index.html
  • frontend/package.json
  • frontend/src/App.tsx
  • frontend/src/api/auth.ts
  • frontend/src/api/client.ts
  • frontend/src/api/health.ts
  • frontend/src/api/types.ts
  • frontend/src/api/useAsync.ts
  • frontend/src/auth/token.ts
  • frontend/src/components/BackendStatus.tsx
  • frontend/src/components/NavShell.tsx
  • frontend/src/components/actor.ts
  • frontend/src/main.tsx
  • frontend/src/routes/NotFound.tsx
  • frontend/src/routes/Placeholder.tsx
  • frontend/src/routes/surfaces.ts
  • frontend/src/styles/app.css
  • frontend/src/styles/tokens.css
  • frontend/src/test/client.test.ts
  • frontend/src/test/setup.ts
  • frontend/src/test/shell.test.tsx
  • frontend/src/vite-env.d.ts
  • frontend/tsconfig.json
  • frontend/vite.config.ts

Comment thread .agent-loop/initiatives/WS-FE-001-frontend-operations-console/STATUS.md Outdated
Comment thread .github/workflows/frontend.yml
Comment thread .github/workflows/frontend.yml
Comment thread frontend/src/components/actor.ts
Comment thread frontend/src/components/BackendStatus.tsx Outdated
jorshimayor added a commit to jorshimayor/workstream that referenced this pull request Jul 9, 2026
- a11y: aria-live="polite" on the backend status strip
- actor.ts: treat empty/whitespace display_name as absent in the name fallback;
  add actor.ts unit tests (empty-name fallback + error labelling)
- tests: make token-source tests hermetic (stub VITE_WORKSTREAM_TOKEN) so a
  local .env.local no longer affects the "no token" case
- ci: frontend.yml gets a least-privilege permissions block (contents: read)
  and persist-credentials: false on checkout
- docs: drop stale "(to be created)" plan refs; fix website-flow.md ->
  website_flow.md; sync test tally to 13/13 in evidence + STATUS

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@jorshimayor

Copy link
Copy Markdown
Author

Thanks @coderabbitai — addressed all eight comments in e09d8c4.

Code / CI

  • frontend.yml: added a least-privilege permissions: contents: read block and persist-credentials: false on actions/checkout (artipacked).
  • actor.ts: actorName now treats an empty/whitespace display_name as absent so the emailexternal_subject fallback isn't short-circuited into a blank label. Added actor.test.ts covering the empty-name fallback and the 401-vs-other error labelling.
  • BackendStatus.tsx: added aria-live="polite" to the status strip so screen readers announce the checking → ok/unreachable and resolving → actor/signed-out transitions.

Docs

  • Chunk contract: dropped the stale "(to be created)" note (INTENT/PLAN/CHUNK_MAP ship in this PR) and fixed website-flow.mdwebsite_flow.md.
  • Evidence + STATUS: synced the Vitest tally (now 13/13 — client 3, shell 5, actor 5).

Also made the token-source tests hermetic (stub VITE_WORKSTREAM_TOKEN) so a developer's local .env.local no longer affects the "no token" assertion. Gates green: lint, typecheck, tests 13/13, build; markdown-link / stale-wording / loop-memory checks all pass.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

@jorshimayor Thanks for the detailed rundown — this all looks solid. The actorName empty/whitespace fallback fix, aria-live="polite" for accessibility, and the least-privilege CI permissions are exactly what I'd hoped to see. Nice touch making the token-source tests hermetic too, that's the kind of flakiness source that's easy to overlook.

I'll take another pass over the updated commit to confirm everything lines up.

ヽ(•‿•)ノ

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

jorshimayor and others added 2 commits July 9, 2026 14:00
Establishes the single canonical Workstream internal operations console at `frontend/`, built with React + Vite + TypeScript:
- Sets up a typed API client with Flow-style bearer token handling for `/api/v1` backend calls
- Implements React Router routing with nav placeholders for the five core operations surfaces
- Adds a status strip showing backend health and authenticated actor state
- Applies the paper-and-ink design system per in-repo design specifications
- Adds a full CI workflow for linting, typechecking, unit tests, and production builds
- Updates architecture, design system, and README documentation with setup instructions
- Passes all automated quality gates and aligns with upstream issue Flow-Research#50 and the WS-FE-001-01 chunk contract

Note: The referenced `demos/week1_api_demo_ui` does not exist on upstream/main, so the demo retirement criterion is satisfied via documentation.
- a11y: aria-live="polite" on the backend status strip
- actor.ts: treat empty/whitespace display_name as absent in the name fallback;
  add actor.ts unit tests (empty-name fallback + error labelling)
- tests: make token-source tests hermetic (stub VITE_WORKSTREAM_TOKEN) so a
  local .env.local no longer affects the "no token" case
- ci: frontend.yml gets a least-privilege permissions block (contents: read)
  and persist-credentials: false on checkout
- docs: drop stale "(to be created)" plan refs; fix website-flow.md ->
  website_flow.md; sync test tally to 13/13 in evidence + STATUS

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@jorshimayor jorshimayor force-pushed the codex/ws-fe-001-01-frontend-foundation branch from e09d8c4 to 588c170 Compare July 9, 2026 13:00
@jorshimayor

Copy link
Copy Markdown
Author

@Abiorh001 could you review this when you have a chance? 🙏 It's the WS-FE-001-01 canonical React + Vite frontend foundation (implements #50). All CodeRabbit comments are addressed, gates are green (lint/typecheck/tests 13-13/build), and the branch is rebased clean on main (no conflicts). I couldn't add you as a formal reviewer from my fork — GitHub only lets repo collaborators do that — so flagging you here.

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.

Frontend: Canonical React + Vite app foundation

1 participant