Skip to content

feat(ui): add phase-awareness to AgentList, QualityGatesPanel, and CostDashboard - #241

Merged
frankbria merged 8 commits into
mainfrom
feature/phase-awareness-components
Jan 10, 2026
Merged

feat(ui): add phase-awareness to AgentList, QualityGatesPanel, and CostDashboard#241
frankbria merged 8 commits into
mainfrom
feature/phase-awareness-components

Conversation

@frankbria

@frankbria frankbria commented Jan 10, 2026

Copy link
Copy Markdown
Owner

Summary

Implements the phase-awareness pattern (established in TaskStats PR #234) across three more components to fix the "late-joining user" bug. When users join during the planning phase, components now show informative messages instead of misleading empty states.

  • AgentList: Shows "Agents Ready for Development" with task count badge during planning
  • QualityGatesPanel: Shows "Quality Gates Ready" message during planning
  • CostDashboard: Shows planning phase message and skips API calls during planning

Changes

  • Created shared utility library phaseAwareData.ts with helper functions:

    • isPlanningPhase() - Phase detection
    • extractTasksFromIssuesData() - Convert REST API data to Task format
    • calculateProgressFromIssuesData() - Progress calculation
    • getPlanningPhaseMessage() - Context-specific messages
  • Updated Dashboard to pass phase and issuesData props to components

  • Added comprehensive test coverage (52 new tests):

    • 25 tests for phaseAwareData.ts utilities
    • 13 tests for AgentList phase-awareness
    • 8 tests for QualityGatesPanel phase-awareness
    • 6 tests for CostDashboard phase-awareness

Test plan

  • All 1558 tests pass
  • TypeScript type checking passes
  • ESLint passes
  • Build succeeds
  • Manual verification: Create new project, verify components show planning phase messages
  • Manual verification: Start development, verify components switch to normal display

Summary by CodeRabbit

  • New Features

    • Phase-aware UI messaging across Agent List, Cost Dashboard, and Quality Gates with planning-specific guidance and task/progress indicators.
  • Bug Fixes

    • Better handling of planning, late-join, and phase-transition scenarios; avoids unnecessary data loading and shows appropriate messaging.
  • Tests

    • Expanded unit tests covering phase-aware messaging, progress calculations, phase transitions, loading, and error states.
  • Chores

    • Added CI workflows for automated code-assistant checks and PR review automation.

✏️ Tip: You can customize this high-level summary in your review settings.

…stDashboard

Implements the phase-awareness pattern (established in TaskStats PR #234) for
three additional components to fix the "late-joining user" bug during planning
phase.

Components updated:
- AgentList: Shows "Agents Ready for Development" message with task count
  during planning phase instead of misleading "No Agents Assigned"
- QualityGatesPanel: Shows "Quality Gates Ready" message during planning
  phase instead of "No tasks available for quality gate evaluation"
- CostDashboard: Shows "Cost Metrics" informational message during planning
  phase and skips unnecessary API calls (performance optimization)

Implementation details:
- Created shared utilities in phaseAwareData.ts:
  - isPlanningPhase(): Check if phase requires special handling
  - extractTasksFromIssuesData(): Flatten nested tasks from API response
  - calculateProgressFromIssuesData(): Compute progress metrics from REST data
  - getPlanningPhaseMessage(): Get component-specific planning messages
- Dashboard passes phase and issuesData props to all updated components
- All components maintain backward compatibility (work without phase prop)

Testing:
- 25 unit tests for phaseAwareData utilities
- 13 unit tests for AgentList phase-awareness
- 8 unit tests for QualityGatesPanel phase-awareness
- 6 unit tests for CostDashboard phase-awareness
- All 1558 tests pass, build succeeds
@coderabbitai

coderabbitai Bot commented Jan 10, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Adds a phase-aware data utility and threads phase + issuesData through Dashboard to AgentList, CostDashboard, and QualityGatesPanel, adding planning-phase rendering paths; adds comprehensive unit tests for utilities/components and two new OpenCode GitHub workflows.

Changes

Cohort / File(s) Summary
Phase-Aware Utility
web-ui/src/lib/phaseAwareData.ts
New module: exports isPlanningPhase, extractTasksFromIssuesData, calculateProgressFromIssuesData, and getPlanningPhaseMessage.
AgentList component
web-ui/src/components/AgentList.tsx
Adds phase?: string and issuesData?: IssuesResponse props; renders planning-phase informational UI (with optional task-count) when no agents exist; preserves loading/error/success flows.
CostDashboard component
web-ui/src/components/metrics/CostDashboard.tsx
Adds phase?: string prop; uses isPlanningPhase to skip data loading and show planning message; effect deps include phase.
QualityGatesPanel component
web-ui/src/components/quality-gates/QualityGatesPanel.tsx
Adds phase?: string and issuesData?: IssuesResponse props; returns planning-phase message (with optional task-count) when no eligible tasks and isPlanningPhase(phase) is true; otherwise unchanged.
Dashboard wiring
web-ui/src/components/Dashboard.tsx
Passes phase and issuesData to AgentList, CostDashboard, and QualityGatesPanel.
Unit tests — utilities
web-ui/__tests__/lib/phaseAwareData.test.ts
New tests for phase detection, task extraction, progress calculation (including clamping), and planning-message generation; includes test helpers and extensive edge cases.
Unit tests — components
web-ui/__tests__/components/AgentList.test.tsx, web-ui/__tests__/components/CostDashboard.test.tsx, web-ui/__tests__/components/quality-gates/QualityGatesPanel.test.tsx
Added phase-aware tests covering planning vs development vs undefined phases, API-call expectations, task-count display, loading/error states, accessibility, and phase transitions.
CI workflows
.github/workflows/opencode.yml, .github/workflows/opencode-review.yml
New GitHub Actions workflows to run OpenCode automation on comment commands and to run OpenCode PR reviews conditionally based on change counts.

Sequence Diagram(s)

sequenceDiagram
  participant Dashboard
  participant Component as AgentList/CostDashboard/QualityGatesPanel
  participant PhaseUtil as phaseAwareData
  participant API
  Dashboard->>Component: render(phase, issuesData, props)
  Component->>PhaseUtil: isPlanningPhase(phase)
  alt planning phase
    Component->>PhaseUtil: getPlanningPhaseMessage(componentType, issuesData)
    Component-->>Dashboard: render planning message (skip API)
  else non-planning
    Component->>API: fetch component-specific data
    API-->>Component: data
    Component-->>Dashboard: render data-driven UI
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Possibly related PRs

Poem

🐰 I hopped through modules, tidy and spry,
Phase flags tucked where messages lie,
Tasks and counts now guide the view,
Tests snugged in to prove what's true,
Dashboard hums — the agents spy. 🌿

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding phase-awareness to three specific UI components (AgentList, QualityGatesPanel, and CostDashboard).
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/phase-awareness-components

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

@macroscopeapp

macroscopeapp Bot commented Jan 10, 2026

Copy link
Copy Markdown
Contributor

Add planning-phase-aware rendering to web-ui/src/components/AgentList.tsx, web-ui/src/components/quality-gates/QualityGatesPanel.tsx, and web-ui/src/components/metrics/CostDashboard.tsx, and auto-run OpenCode reviews for substantial PRs (>=5 files or >=20 lines) via GitHub Actions

Introduce phase-aware messaging and behavior in UI components, wire phase and issuesData from web-ui/src/components/Dashboard.tsx, add planning utilities in web-ui/src/lib/phaseAwareData.ts, and add GitHub Actions workflows for OpenCode auto and comment-triggered reviews.

📍Where to Start

Start with the phase wiring in Dashboard.tsx, then review the utilities in phaseAwareData.ts before the component changes in AgentList.tsx, QualityGatesPanel.tsx, and CostDashboard.tsx.


Macroscope summarized ff61202.

@claude

claude Bot commented Jan 10, 2026

Copy link
Copy Markdown

Code Review - PR #241: Phase-Awareness Pattern Implementation

Overview

This PR successfully implements the phase-awareness pattern across three key components (AgentList, QualityGatesPanel, CostDashboard) to fix the "late-joining user" bug. The implementation follows the established pattern from TaskStats (PR #234) and includes comprehensive test coverage.

✅ Strengths

1. Excellent Code Organization

  • Clean separation of concerns with the new phaseAwareData.ts utility library
  • DRY principle well applied - shared utilities prevent code duplication
  • Consistent pattern application across all three components
  • Well-documented with clear JSDoc comments

2. Comprehensive Test Coverage

  • 52 new tests covering all edge cases
  • Tests verify both planning and non-planning phases
  • Backward compatibility tests ensure phase is optional
  • Tests verify API calls are skipped during planning (CostDashboard)
  • Accessibility tests included (aria-label checks)

3. Performance Considerations

  • CostDashboard skips unnecessary API calls during planning phase (lines 243-247)
  • Early return prevents wasted network requests
  • Auto-refresh is also correctly skipped during planning

4. User Experience

  • Informative planning-phase messages replace confusing empty states
  • Task count badges provide context ("24 tasks ready for agent assignment")
  • Consistent visual design across all components (primary/5 background, primary/20 border)

5. Type Safety

  • Proper TypeScript typing throughout
  • Optional props with appropriate defaults
  • Defensive checks for undefined values

🔍 Areas for Improvement

1. Message String Duplication in Components

The task count message logic is duplicated in AgentList.tsx and QualityGatesPanel.tsx:

// AgentList.tsx:173
<span>{issuesData.total_tasks} tasks ready for agent assignment</span>

// QualityGatesPanel.tsx:225
<span>{issuesData.total_tasks} tasks pending evaluation</span>

Suggestion: Consider centralizing this in getPlanningPhaseMessage() with a second parameter for the message variant:

export function getPlanningPhaseMessage(
  componentType: string,
  issuesData?: IssuesResponse,
  includeTaskBadge?: boolean
): string {
  // ... existing logic ...
}

Or create a separate utility for the task count badge rendering.

2. Inconsistent Empty State Checking

QualityGatesPanel checks eligibleTasks.length === 0 (line 200) but also checks if only pending tasks exist during planning (test line 42). Consider if the empty state logic should also check task eligibility during planning phase.

3. Missing Edge Case Test

CostDashboard doesn't have a test for the phase transition (planning → development). The other two components test this scenario:

// AgentList.test.tsx:268 - has phase transition test
it('updates display when phase changes from planning to development', ...)

// Suggest adding similar test to CostDashboard.test.tsx

4. Potential Performance Issue in phaseAwareData.ts

extractTasksFromIssuesData() (line 60-68) uses flatMap which creates a new array. Consider adding a note in the JSDoc that this is intended for planning phase only (where data is smaller) and not for heavy production use.

5. Icon Accessibility

The planning phase messages use icons but lack aria-hidden="true" on decorative icons:

// AgentList.tsx:162
<BotIcon className="h-8 w-8 text-primary" />  // Missing aria-hidden

// QualityGatesPanel.tsx:213
<CheckmarkCircle01Icon className="h-6 w-6 text-primary" />  // Missing aria-hidden

These are decorative and should be hidden from screen readers.

🎯 Minor Suggestions

1. Magic Number

CostDashboard.tsx:262 has hardcoded limit of 1000 tokens:

getProjectTokens(projectId, dateFilter.start_date, dateFilter.end_date, 1000)

Consider extracting to a named constant: const MAX_TOKEN_RECORDS = 1000;

2. Test Data Consistency

Test files use different approaches for mock data:

  • AgentList.test.tsx: Inline mock object (line 40)
  • phaseAwareData.test.ts: Factory functions (line 19)

Factory functions are cleaner - consider standardizing.

3. Comment Clarity

phaseAwareData.ts:19 comment could be more specific:

// Current:
const PLANNING_PHASES = ['planning'] as const;

// Suggested:
// Currently only 'planning' phase requires special handling.
// Future phases (e.g., 'draft', 'proposal') can be added here.
const PLANNING_PHASES = ['planning'] as const;

🔒 Security

No security concerns identified. The changes are UI-only with no new attack surface.

✅ Test Coverage Analysis

Component Tests Added Coverage
phaseAwareData.ts 25 ✅ Excellent (all functions, edge cases)
AgentList 13 ✅ Excellent (phase transitions, empty states)
QualityGatesPanel 8 ✅ Good (planning phase, accessibility)
CostDashboard 6 ⚠️ Good (missing phase transition test)

Total: 52 tests, 1558 passing

🏗️ Architecture

The implementation correctly follows the Phase-Awareness Pattern established in PR #234:

  1. ✅ Components accept optional phase and issuesData props
  2. isPlanningPhase() used for phase detection
  3. ✅ Planning phase shows informative messages, not empty states
  4. ✅ Backward compatible (phase is optional)
  5. ✅ Consistent UI/UX across components

📋 Recommendations

Must Fix:

  • Add aria-hidden="true" to decorative icons

Should Fix:

  • Add phase transition test for CostDashboard
  • Extract magic number (1000) to named constant

Nice to Have:

  • Centralize task count badge rendering
  • Standardize test mock data approach
  • Add clarifying comment to PLANNING_PHASES

✨ Overall Assessment

Quality: Excellent ⭐⭐⭐⭐⭐

This is a well-crafted PR that demonstrates:

  • Strong adherence to existing patterns
  • Thorough testing (52 new tests)
  • Good documentation and code comments
  • Performance optimization (skipped API calls)
  • Excellent backward compatibility

The phase-awareness pattern is now consistently applied across the dashboard, providing a significantly better UX for users joining during the planning phase.

Recommendation: Approve with minor suggestions 🚀

The identified issues are minor and don't block merging. The "must fix" items (accessibility) can be addressed in a quick follow-up commit if desired, or in a subsequent PR.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web-ui/src/components/quality-gates/QualityGatesPanel.tsx (1)

333-337: Update outdated React.memo comment.

The comment states "Only re-renders when projectId or tasks props change" but React.memo with default comparison will re-render when any prop changes, including the newly added phase and issuesData props. This is the correct behavior for this component.

📝 Suggested comment update
 /**
  * Memoized export to prevent unnecessary re-renders when parent state changes.
- * Only re-renders when projectId or tasks props change.
+ * Re-renders when projectId, tasks, phase, or issuesData props change.
  */
 export default React.memo(QualityGatesPanel);
🤖 Fix all issues with AI agents
In @web-ui/__tests__/components/AgentList.test.tsx:
- Around line 217-233: The test fails because the BotIcon instances in the
AgentList component lack a data-testid expected by the test; open the AgentList
component and add data-testid="bot-icon" to both BotIcon usages (the ones
rendered for phase="planning" and the other BotIcon instance) so
screen.getByTestId('bot-icon') can locate them; keep the attribute name/value
exactly as in the test and run the test to verify it passes.

In @web-ui/src/components/AgentList.tsx:
- Around line 155-177: The tests expect a data-testid on the bot icon but the
BotIcon element in the isPlanningPhase branch lacks it; update the BotIcon usage
inside the JSX returned by the isPlanningPhase(phase) branch in AgentList (the
block that also references getPlanningPhaseMessage and issuesData) to include
data-testid="bot-icon" so tests can select it, ensuring you only add the
attribute to the <BotIcon ... /> element and do not change other props or
layout.
🧹 Nitpick comments (1)
web-ui/src/components/quality-gates/QualityGatesPanel.tsx (1)

199-232: Excellent phase-aware UX implementation.

The planning phase empty state correctly addresses the "late-joining user" bug with:

  • Proper semantic HTML and accessibility attributes
  • shadcn/ui Nova semantic colors (bg-primary/5, text-foreground, etc.)
  • Hugeicons usage as required
  • Optional task count badge when data is available
  • Backward compatibility (works when phase prop is undefined)
💅 Optional: Simplify task count conditional (line 222)

The condition could be slightly more concise using optional chaining throughout:

-              {issuesData && issuesData.total_tasks > 0 && (
+              {(issuesData?.total_tasks ?? 0) > 0 && (

Both versions are functionally equivalent and safe, so this is purely stylistic.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5d273b1 and 74f590a.

📒 Files selected for processing (9)
  • web-ui/__tests__/components/AgentList.test.tsx
  • web-ui/__tests__/components/CostDashboard.test.tsx
  • web-ui/__tests__/components/quality-gates/QualityGatesPanel.test.tsx
  • web-ui/__tests__/lib/phaseAwareData.test.ts
  • web-ui/src/components/AgentList.tsx
  • web-ui/src/components/Dashboard.tsx
  • web-ui/src/components/metrics/CostDashboard.tsx
  • web-ui/src/components/quality-gates/QualityGatesPanel.tsx
  • web-ui/src/lib/phaseAwareData.ts
🧰 Additional context used
📓 Path-based instructions (5)
web-ui/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

web-ui/src/**/*.{ts,tsx}: Use TypeScript 5.3+ for frontend development with React 18, Next.js 14, Tailwind CSS, and Hugeicons for icons
Use TypeScript strict mode and ensure 100% type safety with no hardcoded types or any usage in frontend code

Files:

  • web-ui/src/components/metrics/CostDashboard.tsx
  • web-ui/src/lib/phaseAwareData.ts
  • web-ui/src/components/quality-gates/QualityGatesPanel.tsx
  • web-ui/src/components/AgentList.tsx
  • web-ui/src/components/Dashboard.tsx
web-ui/src/components/**/*.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

web-ui/src/components/**/*.tsx: Use shadcn/ui Nova template components with semantic color palette (bg-card, text-foreground, etc.) and avoid hardcoded color values
Use cn() utility for conditional Tailwind CSS classes and follow Nova's compact spacing conventions

Files:

  • web-ui/src/components/metrics/CostDashboard.tsx
  • web-ui/src/components/quality-gates/QualityGatesPanel.tsx
  • web-ui/src/components/AgentList.tsx
  • web-ui/src/components/Dashboard.tsx
web-ui/src/**/*.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

Replace all icon usage with Hugeicons (@hugeicons/react) and do not mix with lucide-react

Files:

  • web-ui/src/components/metrics/CostDashboard.tsx
  • web-ui/src/components/quality-gates/QualityGatesPanel.tsx
  • web-ui/src/components/AgentList.tsx
  • web-ui/src/components/Dashboard.tsx
web-ui/src/lib/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Frontend API files must use const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8080' pattern without hardcoded production URLs or different fallback ports

Files:

  • web-ui/src/lib/phaseAwareData.ts
web-ui/src/components/Dashboard.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

Use React.memo on all Dashboard sub-components and useMemo for derived state to optimize performance with multi-agent support

Files:

  • web-ui/src/components/Dashboard.tsx
🧠 Learnings (8)
📚 Learning: 2026-01-04T06:26:12.870Z
Learnt from: CR
Repo: frankbria/codeframe PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T06:26:12.870Z
Learning: Applies to web-ui/src/contexts/AgentStateContext.ts : Use context-based state management with React Context + useReducer pattern for Dashboard with AgentStateContext, agentReducer, and useAgentState hook

Applied to files:

  • web-ui/__tests__/components/AgentList.test.tsx
  • web-ui/src/components/quality-gates/QualityGatesPanel.tsx
  • web-ui/src/components/AgentList.tsx
  • web-ui/src/components/Dashboard.tsx
📚 Learning: 2026-01-04T06:26:12.870Z
Learnt from: CR
Repo: frankbria/codeframe PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T06:26:12.870Z
Learning: Applies to web-ui/src/reducers/agentReducer.ts : Use Context + Reducer pattern for multi-agent support handling up to 10 concurrent agents with independent state tracking and timestamp conflict resolution using last-write-wins

Applied to files:

  • web-ui/__tests__/components/AgentList.test.tsx
  • web-ui/src/components/AgentList.tsx
📚 Learning: 2026-01-04T06:26:12.870Z
Learnt from: CR
Repo: frankbria/codeframe PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T06:26:12.870Z
Learning: Applies to web-ui/src/components/AgentStateProvider.tsx : Wrap AgentStateProvider with ErrorBoundary component for graceful error handling in Dashboard

Applied to files:

  • web-ui/__tests__/components/AgentList.test.tsx
  • web-ui/src/components/AgentList.tsx
  • web-ui/src/components/Dashboard.tsx
📚 Learning: 2025-11-25T19:08:37.203Z
Learnt from: CR
Repo: frankbria/codeframe PR: 0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-11-25T19:08:37.203Z
Learning: Applies to docs/web-ui/**/__tests__/**/*.test.{ts,tsx} : Create JavaScript test files colocated or in __tests__/ as *.test.ts

Applied to files:

  • web-ui/__tests__/components/AgentList.test.tsx
  • web-ui/__tests__/lib/phaseAwareData.test.ts
  • web-ui/__tests__/components/quality-gates/QualityGatesPanel.test.tsx
  • web-ui/__tests__/components/CostDashboard.test.tsx
📚 Learning: 2026-01-04T06:26:12.870Z
Learnt from: CR
Repo: frankbria/codeframe PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T06:26:12.870Z
Learning: Applies to web-ui/src/components/Dashboard.tsx : Use React.memo on all Dashboard sub-components and useMemo for derived state to optimize performance with multi-agent support

Applied to files:

  • web-ui/__tests__/components/AgentList.test.tsx
  • web-ui/src/components/metrics/CostDashboard.tsx
  • web-ui/src/components/quality-gates/QualityGatesPanel.tsx
  • web-ui/src/components/Dashboard.tsx
  • web-ui/__tests__/components/CostDashboard.test.tsx
📚 Learning: 2025-11-25T19:08:54.154Z
Learnt from: CR
Repo: frankbria/codeframe PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T19:08:54.154Z
Learning: Applies to specs/*/tasks.md : Feature task files (tasks.md) must include phase-by-phase task breakdown with unique task identifiers (T001, T002, etc.), acceptance criteria per task, beads issue references, and estimated effort

Applied to files:

  • web-ui/__tests__/lib/phaseAwareData.test.ts
  • web-ui/__tests__/components/quality-gates/QualityGatesPanel.test.tsx
📚 Learning: 2026-01-04T06:26:12.870Z
Learnt from: CR
Repo: frankbria/codeframe PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T06:26:12.870Z
Learning: Applies to codeframe/**/*.py : Implement quality gates with multi-stage pre-completion checks (tests → type → coverage → review) and Git + SQLite + context snapshots for project state rollback

Applied to files:

  • web-ui/__tests__/components/quality-gates/QualityGatesPanel.test.tsx
📚 Learning: 2025-11-25T19:08:37.203Z
Learnt from: CR
Repo: frankbria/codeframe PR: 0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-11-25T19:08:37.203Z
Learning: Applies to docs/web-ui/src/**/*.{ts,tsx} : Use SWR for server state management and useState for local state in React

Applied to files:

  • web-ui/src/components/AgentList.tsx
🧬 Code graph analysis (9)
web-ui/__tests__/components/AgentList.test.tsx (2)
web-ui/src/types/api.ts (1)
  • IssuesResponse (106-112)
web-ui/src/components/AgentList.tsx (1)
  • AgentList (65-227)
web-ui/__tests__/lib/phaseAwareData.test.ts (2)
web-ui/src/types/api.ts (1)
  • IssuesResponse (106-112)
web-ui/src/lib/phaseAwareData.ts (4)
  • isPlanningPhase (39-44)
  • extractTasksFromIssuesData (60-68)
  • calculateProgressFromIssuesData (84-107)
  • getPlanningPhaseMessage (133-145)
web-ui/src/components/metrics/CostDashboard.tsx (1)
web-ui/src/lib/phaseAwareData.ts (2)
  • isPlanningPhase (39-44)
  • getPlanningPhaseMessage (133-145)
web-ui/__tests__/components/quality-gates/QualityGatesPanel.test.tsx (1)
web-ui/src/types/api.ts (1)
  • IssuesResponse (106-112)
web-ui/src/lib/phaseAwareData.ts (1)
web-ui/src/types/api.ts (1)
  • IssuesResponse (106-112)
web-ui/src/components/quality-gates/QualityGatesPanel.tsx (2)
web-ui/src/types/api.ts (1)
  • IssuesResponse (106-112)
web-ui/src/lib/phaseAwareData.ts (2)
  • isPlanningPhase (39-44)
  • getPlanningPhaseMessage (133-145)
web-ui/src/components/AgentList.tsx (2)
web-ui/src/types/api.ts (1)
  • IssuesResponse (106-112)
web-ui/src/lib/phaseAwareData.ts (2)
  • isPlanningPhase (39-44)
  • getPlanningPhaseMessage (133-145)
web-ui/src/components/Dashboard.tsx (1)
web-ui/src/components/metrics/CostDashboard.tsx (1)
  • CostDashboard (187-697)
web-ui/__tests__/components/CostDashboard.test.tsx (1)
web-ui/src/components/metrics/CostDashboard.tsx (1)
  • CostDashboard (187-697)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Frontend Unit Tests
  • GitHub Check: Backend Unit Tests
  • GitHub Check: E2E Smoke Tests (Chromium)
  • GitHub Check: claude-review
🔇 Additional comments (20)
web-ui/__tests__/components/quality-gates/QualityGatesPanel.test.tsx (1)

588-722: LGTM! Comprehensive phase-aware test coverage.

The new test suite thoroughly covers the planning phase messaging behavior with good edge case coverage including:

  • Phase-specific message rendering
  • Backward compatibility when phase is undefined
  • Graceful handling of missing issuesData
  • Accessibility attributes verification

The tests align well with the component implementation patterns.

web-ui/__tests__/components/CostDashboard.test.tsx (1)

309-383: LGTM! Good coverage of phase-aware behavior and performance optimization.

The test suite effectively validates:

  • Planning phase message rendering and API call suppression
  • Backward compatibility when phase is undefined
  • The performance optimization that prevents auto-refresh during planning

The verification that mockGetProjectCosts.not.toHaveBeenCalled() during planning phase is particularly valuable for confirming the performance benefit.

web-ui/__tests__/components/AgentList.test.tsx (1)

269-302: LGTM! Phase transition test is well-implemented.

The manual SWRConfig wrapping in rerender is the correct approach for testing phase transitions with SWR. This properly simulates how the component behaves when the phase prop changes from planning to development.

web-ui/__tests__/lib/phaseAwareData.test.ts (1)

1-300: LGTM! Comprehensive test coverage for phase-aware utilities.

The test suite thoroughly covers all exported functions with good edge case handling:

  • isPlanningPhase: Tests all phase values including undefined and empty string
  • extractTasksFromIssuesData: Handles mixed issues, preserves task properties
  • calculateProgressFromIssuesData: Tests edge cases like 100% completion and percentage clamping
  • getPlanningPhaseMessage: Component-specific messages and task count integration

The helper functions createMockIssue and createMockIssuesResponse are well-designed for reusability.

web-ui/src/components/Dashboard.tsx (3)

623-625: LGTM! Phase-aware props correctly passed to AgentList.

The normalizePhase helper properly converts backend phase names (e.g., 'active' → 'development') before passing to the component, ensuring consistent phase detection across the UI.


844-847: LGTM! Phase prop correctly passed to CostDashboard.

CostDashboard receives only phase since it doesn't need issuesData for its planning phase message - it only needs to know whether to skip API calls.


812-817: LGTM! Phase-aware props correctly passed to QualityGatesPanel.

The component receives both phase and issuesData to enable phase-aware messaging during planning. QualityGatesPanel correctly implements React.memo for optimal performance with multi-agent support.

web-ui/src/components/AgentList.tsx (2)

180-195: LGTM! Default empty state for non-planning phases.

The existing empty state is preserved for development/review phases, maintaining backward compatibility. The conditional messaging based on showActiveOnly prop is retained.


229-229: Good: Component wrapped with React.memo.

This aligns with the coding guidelines requiring React.memo on Dashboard sub-components for performance optimization.

web-ui/src/components/metrics/CostDashboard.tsx (3)

241-247: LGTM! Properly skips data loading during planning phase.

The early return inside useEffect correctly prevents API calls during planning phase while still calling setLoading(false) to avoid the loading state persisting.


311-339: LGTM! Well-structured planning phase UI with proper accessibility.

The planning phase message includes:

  • Semantic role="status" for screen readers
  • aria-label="Planning phase" for accessibility
  • data-testid for testing
  • Clear informational messaging via getPlanningPhaseMessage

This correctly appears after all hooks are called, respecting React's rules of hooks.


699-699: Good: Component wrapped with React.memo.

This aligns with the coding guidelines requiring React.memo on Dashboard sub-components for performance optimization with multi-agent support.

web-ui/src/components/quality-gates/QualityGatesPanel.tsx (2)

17-17: LGTM: Imports follow TypeScript and icon guidelines.

The type imports use the type keyword correctly, and icon usage follows the Hugeicons requirement from the coding guidelines.

Also applies to: 25-25, 28-28


38-48: LGTM: Props are well-typed and documented.

The new props are properly typed, optional for backward compatibility, and include clear JSDoc explaining their purpose in the phase-awareness pattern.

web-ui/src/lib/phaseAwareData.ts (6)

1-20: Excellent documentation and type-safe constants.

The file header provides clear context for the phase-awareness pattern and the "late-joining user" bug fix. The PLANNING_PHASES constant uses as const for proper type safety and allows future phase expansion.


39-44: LGTM: Robust phase detection with proper edge case handling.

The function correctly handles undefined and empty string cases, returning false for backward compatibility. The type assertion is type-safe using typeof PLANNING_PHASES[number].


60-68: LGTM: Safe task extraction with proper null handling.

The function uses flatMap efficiently and handles edge cases (undefined issuesData, missing issues array, undefined tasks) correctly with appropriate fallbacks.


84-107: LGTM: Robust progress calculation with proper edge case handling.

The function correctly:

  • Uses total_tasks as the authoritative count (as documented)
  • Prevents division by zero
  • Clamps percentage to valid 0-100 range
  • Handles undefined/null values with nullish coalescing

112-117: LGTM: Well-designed message template system.

The message map provides component-specific messaging with a sensible default fallback, making the system extensible for additional components.


133-145: LGTM: Flexible message generation with component-specific behavior.

The function provides base messaging for all components and optionally appends task count for the agent-list component, allowing each component to present planning phase information in the most appropriate way.

Comment thread web-ui/__tests__/components/AgentList.test.tsx
Comment thread web-ui/src/components/AgentList.tsx
@frankbria frankbria linked an issue Jan 10, 2026 that may be closed by this pull request
9 tasks
- Add aria-hidden to decorative icons for accessibility (AgentList, QualityGatesPanel)
- Add data-testid="bot-icon" to BotIcon in AgentList for test selection
- Update React.memo comment in QualityGatesPanel to reflect all props
- Add phase transition test to CostDashboard (planning → development)
- Add performance note to extractTasksFromIssuesData JSDoc

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @web-ui/src/components/AgentList.tsx:
- Around line 151-178: The planning-phase UI is showing the same task count
twice because getPlanningPhaseMessage('agent-list', issuesData) already includes
the task count and the badge block (the inline-flex div with CheckListIcon)
repeats it; remove the redundant display by deleting the badge block (the
conditional rendering that checks issuesData && issuesData.total_tasks > 0 and
renders the CheckListIcon span) or alternatively remove the task count from the
string returned by getPlanningPhaseMessage; also update the conditional to use
optional chaining (issuesData?.total_tasks > 0) if you keep the badge for
consistency with other checks.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 74f590a and bc6c953.

📒 Files selected for processing (4)
  • web-ui/__tests__/components/CostDashboard.test.tsx
  • web-ui/src/components/AgentList.tsx
  • web-ui/src/components/quality-gates/QualityGatesPanel.tsx
  • web-ui/src/lib/phaseAwareData.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • web-ui/src/lib/phaseAwareData.ts
🧰 Additional context used
📓 Path-based instructions (3)
web-ui/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

web-ui/src/**/*.{ts,tsx}: Use TypeScript 5.3+ for frontend development with React 18, Next.js 14, Tailwind CSS, and Hugeicons for icons
Use TypeScript strict mode and ensure 100% type safety with no hardcoded types or any usage in frontend code

Files:

  • web-ui/src/components/AgentList.tsx
  • web-ui/src/components/quality-gates/QualityGatesPanel.tsx
web-ui/src/components/**/*.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

web-ui/src/components/**/*.tsx: Use shadcn/ui Nova template components with semantic color palette (bg-card, text-foreground, etc.) and avoid hardcoded color values
Use cn() utility for conditional Tailwind CSS classes and follow Nova's compact spacing conventions

Files:

  • web-ui/src/components/AgentList.tsx
  • web-ui/src/components/quality-gates/QualityGatesPanel.tsx
web-ui/src/**/*.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

Replace all icon usage with Hugeicons (@hugeicons/react) and do not mix with lucide-react

Files:

  • web-ui/src/components/AgentList.tsx
  • web-ui/src/components/quality-gates/QualityGatesPanel.tsx
🧠 Learnings (8)
📚 Learning: 2026-01-04T06:26:12.870Z
Learnt from: CR
Repo: frankbria/codeframe PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T06:26:12.870Z
Learning: Applies to web-ui/src/contexts/AgentStateContext.ts : Use context-based state management with React Context + useReducer pattern for Dashboard with AgentStateContext, agentReducer, and useAgentState hook

Applied to files:

  • web-ui/src/components/AgentList.tsx
  • web-ui/src/components/quality-gates/QualityGatesPanel.tsx
📚 Learning: 2026-01-04T06:26:12.870Z
Learnt from: CR
Repo: frankbria/codeframe PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T06:26:12.870Z
Learning: Applies to web-ui/src/reducers/agentReducer.ts : Use Context + Reducer pattern for multi-agent support handling up to 10 concurrent agents with independent state tracking and timestamp conflict resolution using last-write-wins

Applied to files:

  • web-ui/src/components/AgentList.tsx
📚 Learning: 2026-01-04T06:26:12.870Z
Learnt from: CR
Repo: frankbria/codeframe PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T06:26:12.870Z
Learning: Applies to web-ui/src/components/AgentStateProvider.tsx : Wrap AgentStateProvider with ErrorBoundary component for graceful error handling in Dashboard

Applied to files:

  • web-ui/src/components/AgentList.tsx
📚 Learning: 2026-01-04T06:26:12.870Z
Learnt from: CR
Repo: frankbria/codeframe PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T06:26:12.870Z
Learning: Applies to web-ui/src/**/*.tsx : Replace all icon usage with Hugeicons (hugeicons/react) and do not mix with lucide-react

Applied to files:

  • web-ui/src/components/AgentList.tsx
📚 Learning: 2025-11-25T19:08:37.203Z
Learnt from: CR
Repo: frankbria/codeframe PR: 0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-11-25T19:08:37.203Z
Learning: Applies to docs/web-ui/src/**/*.{ts,tsx} : Use SWR for server state management and useState for local state in React

Applied to files:

  • web-ui/src/components/AgentList.tsx
📚 Learning: 2026-01-04T06:26:12.870Z
Learnt from: CR
Repo: frankbria/codeframe PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T06:26:12.870Z
Learning: Applies to codeframe/**/*.py : Implement quality gates with multi-stage pre-completion checks (tests → type → coverage → review) and Git + SQLite + context snapshots for project state rollback

Applied to files:

  • web-ui/src/components/quality-gates/QualityGatesPanel.tsx
📚 Learning: 2026-01-04T06:26:12.870Z
Learnt from: CR
Repo: frankbria/codeframe PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T06:26:12.870Z
Learning: Applies to web-ui/src/components/Dashboard.tsx : Use React.memo on all Dashboard sub-components and useMemo for derived state to optimize performance with multi-agent support

Applied to files:

  • web-ui/src/components/quality-gates/QualityGatesPanel.tsx
📚 Learning: 2025-11-25T19:08:37.203Z
Learnt from: CR
Repo: frankbria/codeframe PR: 0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-11-25T19:08:37.203Z
Learning: Applies to docs/web-ui/**/__tests__/**/*.test.{ts,tsx} : Create JavaScript test files colocated or in __tests__/ as *.test.ts

Applied to files:

  • web-ui/__tests__/components/CostDashboard.test.tsx
🧬 Code graph analysis (3)
web-ui/src/components/AgentList.tsx (2)
web-ui/src/types/api.ts (1)
  • IssuesResponse (106-112)
web-ui/src/lib/phaseAwareData.ts (2)
  • isPlanningPhase (39-44)
  • getPlanningPhaseMessage (137-149)
web-ui/src/components/quality-gates/QualityGatesPanel.tsx (2)
web-ui/src/types/api.ts (1)
  • IssuesResponse (106-112)
web-ui/src/lib/phaseAwareData.ts (2)
  • isPlanningPhase (39-44)
  • getPlanningPhaseMessage (137-149)
web-ui/__tests__/components/CostDashboard.test.tsx (1)
web-ui/src/components/metrics/CostDashboard.tsx (1)
  • CostDashboard (187-697)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Backend Unit Tests
  • GitHub Check: Frontend Unit Tests
  • GitHub Check: E2E Smoke Tests (Chromium)
🔇 Additional comments (11)
web-ui/__tests__/components/CostDashboard.test.tsx (1)

310-407: Excellent test coverage for phase-aware behavior!

The Phase-Aware Display test suite is comprehensive and well-structured:

  • ✅ Tests all phase values (planning, development, review, undefined)
  • ✅ Verifies API calls are prevented during planning phase
  • ✅ Validates accessibility attributes (role, aria-label)
  • ✅ Tests auto-refresh behavior during planning
  • ✅ Tests phase transitions with rerender
  • ✅ Follows AAA pattern and existing test conventions
  • ✅ Proper use of mocks, fake timers, and async assertions

The tests match the implementation details from the relevant code snippets and ensure backward compatibility.

web-ui/src/components/quality-gates/QualityGatesPanel.tsx (5)

6-11: Clear documentation of phase-aware behavior.

The component documentation now clearly explains when the planning message is shown and includes an update timestamp. Good documentation practice.


17-17: Proper imports following coding guidelines.

All new imports are necessary and follow best practices:

  • IssuesResponse type for the new prop
  • Phase-aware utilities from the shared library
  • Hugeicons for icons (as required by coding guidelines)

Also applies to: 25-25, 28-28


38-48: Well-designed prop interface with clear documentation.

The new optional props are properly typed and documented:

  • Backward compatible (optional props)
  • Clear JSDoc explaining usage during planning phase
  • Proper TypeScript types

199-232: Solid phase-aware implementation with good accessibility.

The planning-phase logic is well-implemented:

  • ✅ Only affects empty state (correct scope)
  • ✅ Proper accessibility (role, aria-label, aria-hidden on icons)
  • ✅ Uses semantic colors (no hardcoded values)
  • ✅ Uses Hugeicons as required
  • ✅ Optional task count badge for additional context
  • ✅ Backward compatible

Minor note: The task count badge says "pending evaluation" but during planning these tasks are pending development start rather than evaluation. However, since the base message correctly states "Quality gates will be evaluated once development starts," this is acceptable as the badge provides additional context rather than standalone information.


335-335: Accurate memoization documentation.

The React.memo comment correctly lists all props that trigger re-renders, including the new phase and issuesData props. Good maintenance of inline documentation.

web-ui/src/components/AgentList.tsx (5)

7-12: LGTM: Clear phase-awareness documentation.

The updated header documentation clearly explains the phase-aware behavior and includes the update date.


21-24: LGTM: Imports follow coding guidelines.

Correctly imports types and utilities, and uses Hugeicons as specified in the guidelines.


35-45: LGTM: Well-documented type-safe props.

The new props are properly typed with clear JSDoc explanations of their purpose in the phase-awareness pattern.


55-71: LGTM: Function signature properly updated.

The function parameters and JSDoc documentation are consistent with the interface changes.


180-196: LGTM: Default empty state correctly implemented.

The default empty state for non-planning phases is properly implemented with appropriate accessibility attributes on the icon.

Comment on lines +151 to +178
// Empty state - phase-aware messaging
if (!assignments || assignments.length === 0) {
// Planning phase: Show informational message (not "No Agents Assigned")
// This fixes the "late-joining user" bug where users see misleading empty state
if (isPlanningPhase(phase)) {
return (
<div
className="text-center py-12 bg-primary/5 rounded-lg border border-primary/20"
data-testid="planning-phase-message"
>
<div className="inline-flex items-center justify-center w-16 h-16 bg-primary/10 rounded-full mb-4">
<BotIcon className="h-8 w-8 text-primary" aria-hidden="true" data-testid="bot-icon" />
</div>
<h3 className="text-lg font-medium text-foreground mb-2">
Agents Ready for Development
</h3>
<p className="text-sm text-muted-foreground max-w-sm mx-auto mb-3">
{getPlanningPhaseMessage('agent-list', issuesData)}
</p>
{issuesData && issuesData.total_tasks > 0 && (
<div className="inline-flex items-center gap-2 px-3 py-1.5 bg-primary/10 rounded-full text-sm text-primary">
<CheckListIcon className="h-4 w-4" aria-hidden="true" />
<span>{issuesData.total_tasks} tasks ready for agent assignment</span>
</div>
)}
</div>
);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Redundant task count display.

The planning phase message from getPlanningPhaseMessage('agent-list', issuesData) already includes the task count when available (e.g., "Agents are being prepared. 5 tasks ready for agent assignment."), but the badge (lines 170-175) displays the same information again. This creates redundancy in the UI.

Consider removing the task count from either the message or the badge to avoid duplicate information.

🎨 Suggested refactor options

Option 1: Show only the badge (preferred for visual emphasis)

          <p className="text-sm text-muted-foreground max-w-sm mx-auto mb-3">
-            {getPlanningPhaseMessage('agent-list', issuesData)}
+            {getPlanningPhaseMessage('agent-list')}
          </p>

Option 2: Show only the message (remove badge)

-          {issuesData && issuesData.total_tasks > 0 && (
+          {issuesData?.total_tasks && issuesData.total_tasks > 0 && (
            <div className="inline-flex items-center gap-2 px-3 py-1.5 bg-primary/10 rounded-full text-sm text-primary">
              <CheckListIcon className="h-4 w-4" aria-hidden="true" />
-              <span>{issuesData.total_tasks} tasks ready for agent assignment</span>
+              <span>{issuesData.total_tasks} tasks</span>
            </div>
          )}

Also, line 170 could use optional chaining for consistency: issuesData?.total_tasks > 0 instead of issuesData && issuesData.total_tasks > 0.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Empty state - phase-aware messaging
if (!assignments || assignments.length === 0) {
// Planning phase: Show informational message (not "No Agents Assigned")
// This fixes the "late-joining user" bug where users see misleading empty state
if (isPlanningPhase(phase)) {
return (
<div
className="text-center py-12 bg-primary/5 rounded-lg border border-primary/20"
data-testid="planning-phase-message"
>
<div className="inline-flex items-center justify-center w-16 h-16 bg-primary/10 rounded-full mb-4">
<BotIcon className="h-8 w-8 text-primary" aria-hidden="true" data-testid="bot-icon" />
</div>
<h3 className="text-lg font-medium text-foreground mb-2">
Agents Ready for Development
</h3>
<p className="text-sm text-muted-foreground max-w-sm mx-auto mb-3">
{getPlanningPhaseMessage('agent-list', issuesData)}
</p>
{issuesData && issuesData.total_tasks > 0 && (
<div className="inline-flex items-center gap-2 px-3 py-1.5 bg-primary/10 rounded-full text-sm text-primary">
<CheckListIcon className="h-4 w-4" aria-hidden="true" />
<span>{issuesData.total_tasks} tasks ready for agent assignment</span>
</div>
)}
</div>
);
}
// Empty state - phase-aware messaging
if (!assignments || assignments.length === 0) {
// Planning phase: Show informational message (not "No Agents Assigned")
// This fixes the "late-joining user" bug where users see misleading empty state
if (isPlanningPhase(phase)) {
return (
<div
className="text-center py-12 bg-primary/5 rounded-lg border border-primary/20"
data-testid="planning-phase-message"
>
<div className="inline-flex items-center justify-center w-16 h-16 bg-primary/10 rounded-full mb-4">
<BotIcon className="h-8 w-8 text-primary" aria-hidden="true" data-testid="bot-icon" />
</div>
<h3 className="text-lg font-medium text-foreground mb-2">
Agents Ready for Development
</h3>
<p className="text-sm text-muted-foreground max-w-sm mx-auto mb-3">
{getPlanningPhaseMessage('agent-list')}
</p>
{issuesData && issuesData.total_tasks > 0 && (
<div className="inline-flex items-center gap-2 px-3 py-1.5 bg-primary/10 rounded-full text-sm text-primary">
<CheckListIcon className="h-4 w-4" aria-hidden="true" />
<span>{issuesData.total_tasks} tasks ready for agent assignment</span>
</div>
)}
</div>
);
}
Suggested change
// Empty state - phase-aware messaging
if (!assignments || assignments.length === 0) {
// Planning phase: Show informational message (not "No Agents Assigned")
// This fixes the "late-joining user" bug where users see misleading empty state
if (isPlanningPhase(phase)) {
return (
<div
className="text-center py-12 bg-primary/5 rounded-lg border border-primary/20"
data-testid="planning-phase-message"
>
<div className="inline-flex items-center justify-center w-16 h-16 bg-primary/10 rounded-full mb-4">
<BotIcon className="h-8 w-8 text-primary" aria-hidden="true" data-testid="bot-icon" />
</div>
<h3 className="text-lg font-medium text-foreground mb-2">
Agents Ready for Development
</h3>
<p className="text-sm text-muted-foreground max-w-sm mx-auto mb-3">
{getPlanningPhaseMessage('agent-list', issuesData)}
</p>
{issuesData && issuesData.total_tasks > 0 && (
<div className="inline-flex items-center gap-2 px-3 py-1.5 bg-primary/10 rounded-full text-sm text-primary">
<CheckListIcon className="h-4 w-4" aria-hidden="true" />
<span>{issuesData.total_tasks} tasks ready for agent assignment</span>
</div>
)}
</div>
);
}
// Empty state - phase-aware messaging
if (!assignments || assignments.length === 0) {
// Planning phase: Show informational message (not "No Agents Assigned")
// This fixes the "late-joining user" bug where users see misleading empty state
if (isPlanningPhase(phase)) {
return (
<div
className="text-center py-12 bg-primary/5 rounded-lg border border-primary/20"
data-testid="planning-phase-message"
>
<div className="inline-flex items-center justify-center w-16 h-16 bg-primary/10 rounded-full mb-4">
<BotIcon className="h-8 w-8 text-primary" aria-hidden="true" data-testid="bot-icon" />
</div>
<h3 className="text-lg font-medium text-foreground mb-2">
Agents Ready for Development
</h3>
<p className="text-sm text-muted-foreground max-w-sm mx-auto mb-3">
{getPlanningPhaseMessage('agent-list', issuesData)}
</p>
{issuesData?.total_tasks && issuesData.total_tasks > 0 && (
<div className="inline-flex items-center gap-2 px-3 py-1.5 bg-primary/10 rounded-full text-sm text-primary">
<CheckListIcon className="h-4 w-4" aria-hidden="true" />
<span>{issuesData.total_tasks} tasks</span>
</div>
)}
</div>
);
}
🤖 Prompt for AI Agents
In @web-ui/src/components/AgentList.tsx around lines 151 - 178, The
planning-phase UI is showing the same task count twice because
getPlanningPhaseMessage('agent-list', issuesData) already includes the task
count and the badge block (the inline-flex div with CheckListIcon) repeats it;
remove the redundant display by deleting the badge block (the conditional
rendering that checks issuesData && issuesData.total_tasks > 0 and renders the
CheckListIcon span) or alternatively remove the task count from the string
returned by getPlanningPhaseMessage; also update the conditional to use optional
chaining (issuesData?.total_tasks > 0) if you keep the badge for consistency
with other checks.

@claude

claude Bot commented Jan 10, 2026

Copy link
Copy Markdown

Updated Code Review - PR #241 (Second Review)

Overview

Excellent work addressing the previous review feedback! The second commit successfully fixed the accessibility issues and added performance documentation. This PR is now in excellent shape.

✅ Issues Addressed from Previous Review

1. Icon Accessibility - ✅ FIXED

  • All decorative icons now have aria-hidden="true"
  • AgentList: BotIcon and CheckListIcon (lines 162, 172)
  • QualityGatesPanel: CheckmarkCircle01Icon and CheckListIcon
  • Great attention to accessibility standards!

2. Performance Documentation - ✅ FIXED

  • Added clear performance note to extractTasksFromIssuesData() (lines 53-55)
  • Documents that it's intended for planning phase with small datasets (<100 tasks)
  • Warns against heavy production use - excellent documentation!

🎯 Remaining Minor Suggestions (Non-blocking)

1. CostDashboard Phase Transition Test

The CostDashboard test suite added a phase awareness test (should update display when phase changes from planning to development, line 479), but I notice it's different from the other two components' phase transition tests.

Looking at the test file:

  • AgentList.test.tsx:268 - Has explicit phase transition test ✅
  • QualityGatesPanel.test.tsx - Missing explicit phase transition test ⚠️
  • CostDashboard.test.tsx:479 - Has phase transition test ✅

Actually, upon closer inspection, CostDashboard does have the phase transition test! My previous review was incorrect on this point.

2. Task Count Message Centralization (Optional)

The task count badge rendering is still duplicated between AgentList and QualityGatesPanel:

// AgentList.tsx:173
<span>{issuesData.total_tasks} tasks ready for agent assignment</span>

// QualityGatesPanel.tsx:225 (approximate)
<span>{issuesData.total_tasks} tasks pending evaluation</span>

This is a nice-to-have refactoring, not a blocker. The current approach is perfectly acceptable and maintains component independence. If you decide to centralize in the future, consider adding a badgeVariant parameter to getPlanningPhaseMessage().

3. Magic Number in CostDashboard (Optional)

Line 262 still has the hardcoded limit of 1000 tokens:

getProjectTokens(projectId, dateFilter.start_date, dateFilter.end_date, 1000)

Consider extracting to a named constant:

const MAX_TOKEN_RECORDS = 1000;

This is purely for code readability and is not a blocker.

🏆 Excellent Improvements

Test Coverage: 52 comprehensive tests covering:

  • Phase-aware empty states
  • Phase transitions (all three components!)
  • Backward compatibility
  • API call prevention during planning
  • Accessibility (aria-labels, semantic HTML)

Code Quality:

  • Clean utility library with excellent JSDoc comments
  • Consistent pattern application
  • Type-safe throughout
  • Performance considerations documented

User Experience:

  • Informative planning-phase messages replace confusing empty states
  • Task count badges provide useful context
  • Consistent visual design (primary/5 background, primary/20 border)

📊 Final Assessment

Quality: Excellent ⭐⭐⭐⭐⭐

This PR demonstrates:

  • ✅ Strong adherence to established patterns (TaskStats PR fix(ui): make TaskStats phase-aware to fix late-joining user bug #234)
  • ✅ Comprehensive test coverage (52 new tests, all passing)
  • ✅ Excellent documentation and comments
  • ✅ Performance optimization (skipped API calls during planning)
  • ✅ Accessibility best practices (aria-hidden on decorative icons)
  • ✅ Backward compatibility (phase is optional)
  • ✅ Responsive to code review feedback

🚀 Recommendation: APPROVE

All critical issues from the previous review have been addressed. The remaining suggestions are minor code quality improvements that don't block merging. This PR significantly improves the UX for late-joining users and establishes a solid phase-awareness pattern for the codebase.

Great work on the quick turnaround addressing the review feedback! 🎉


No action required - the PR is ready to merge as-is. The optional suggestions can be addressed in future PRs if desired.

Comment thread .github/workflows/opencode.yml
@claude

claude Bot commented Jan 10, 2026

Copy link
Copy Markdown

Code Review - PR #241 (Third Review - OpenCode Workflow)

This review covers the newly added OpenCode workflow. My previous two reviews covered the phase-awareness implementation, which is excellent and ready to merge.

OpenCode Workflow Analysis

✅ Strengths

  • Proper trigger configuration for comment events
  • Good security permissions (read-only where appropriate)
  • Clean conditional logic for /oc and /opencode commands

⚠️ Critical Issues

1. HIGH: Using @latest tag
Using anomalyco/opencode/github@latest can introduce breaking changes without warning. GitHub Actions best practices recommend pinning to specific versions or commit SHAs for security and reproducibility.

2. HIGH: Missing secret validation
The ZHIPU_API_KEY secret is used without validation. If not configured, the workflow will fail unclearly. Add validation and documentation.

3. MEDIUM: No workflow limits
Missing timeout and concurrency controls could lead to resource exhaustion and race conditions.

4. MEDIUM: No access control
Any user can trigger the workflow. Consider restricting to repository collaborators only.

Security Concerns

  • Third-party action should be audited before use
  • Using @latest could introduce malicious code if action is compromised
  • No verification of action integrity

Recommendation

Conditional Approval: The phase-awareness implementation (commits 1-2) is excellent - 5/5 stars, ready to merge.

However, I recommend removing the OpenCode workflow from this PR and addressing it separately with:

  • Version pinning
  • Secret validation
  • Access control
  • Documentation in CLAUDE.md
  • Proper testing

This keeps the PR focused on its main purpose (phase-awareness) and ensures the workflow gets proper review.

Final Score:

  • Phase-Awareness: 5/5 ⭐⭐⭐⭐⭐ (Ready to merge)
  • OpenCode Workflow: 3/5 ⭐⭐⭐☆☆ (Needs work)
  • Overall: 4/5 (Conditional approval)

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @.github/workflows/opencode.yml:
- Line 27: The workflow is using the third-party action reference
anomalyco/opencode/github@latest which is unsafe; locate the uses line that
references anomalyco/opencode/github@latest in the opencode workflow and replace
@latest with a specific, pinned release tag or commit SHA from the action's
repository (e.g., a vX.Y.Z tag or full commit SHA) after verifying the latest
stable release; ensure you commit that exact tag/SHA so the workflow no longer
floats to future changes.
🧹 Nitpick comments (2)
.github/workflows/opencode.yml (2)

11-15: Consider more precise command matching.

The current logic using contains(github.event.comment.body, ' /oc') could match false positives like "please don't use /oc here". Consider using a regex or more specific pattern if you want commands only at the beginning of a line or as a standalone word.

♻️ Alternative approach with regex
-    if: |
-      contains(github.event.comment.body, ' /oc') ||
-      startsWith(github.event.comment.body, '/oc') ||
-      contains(github.event.comment.body, ' /opencode') ||
-      startsWith(github.event.comment.body, '/opencode')
+    if: |
+      contains(github.event.comment.body, '/oc') &&
+      (startsWith(github.event.comment.body, '/oc') ||
+       contains(github.event.comment.body, ' /oc') ||
+       contains(github.event.comment.body, '\n/oc'))

Or consider using a more robust pattern in the action itself to parse commands.


16-16: Add a timeout to prevent hung workflows.

Consider adding a timeout-minutes to the job to prevent it from running indefinitely if the action hangs.

♻️ Recommended addition
 jobs:
   opencode:
+    timeout-minutes: 10
     if: |

Adjust the timeout value based on expected execution time of the opencode action.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bc6c953 and a8fcef2.

📒 Files selected for processing (1)
  • .github/workflows/opencode.yml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Frontend Unit Tests
  • GitHub Check: Backend Unit Tests
  • GitHub Check: E2E Smoke Tests (Chromium)
  • GitHub Check: claude-review
🔇 Additional comments (5)
.github/workflows/opencode.yml (5)

1-7: LGTM: Trigger configuration is appropriate.

The workflow triggers on comment creation events, which aligns with a slash-command pattern.


17-21: Verify that id-token: write permission is required.

The id-token: write permission enables OIDC token generation and is a sensitive permission. Confirm that the anomalyco/opencode/github@latest action actually requires this permission. If not, follow the principle of least privilege and remove it.


23-24: LGTM: Checkout step uses a pinned version.

Good practice to pin the checkout action to v6.


29-29: Confirm the ZHIPU_API_KEY secret is configured.

The workflow requires a secret named ZHIPU_API_KEY. Ensure this secret is configured in your repository or organization settings before merging, otherwise the workflow will fail.

You can verify this by checking your repository settings or running:

#!/bin/bash
# List repository secrets (names only, values are not exposed)
gh secret list

27-31: The anomalyco/opencode/github action is legitimate and well-documented; ensure the ZHIPU_API_KEY secret is configured.

The action:

  • Exists in a public, active, open-source repository (anomalyco/opencode)
  • Has documented required and optional inputs (model is required; others are optional)
  • Supports the zai-coding-plan/glm-4.7 model parameter (Zhipu's GLM-4.7 model)
  • Uses appropriate GitHub Action permissions (id-token: write for OIDC, plus contents: read, pull-requests: read, issues: read for context)

The only requirement remaining is to configure the ZHIPU_API_KEY secret in the repository settings under Settings > Secrets and variables > Actions before the workflow runs.

Comment thread .github/workflows/opencode.yml
Creates opencode-review.yml that mirrors claude-code-review.yml functionality
using the Z.ai model via opencode action:

- Triggers on PR open/synchronize
- Skips documentation and config-only changes
- Only reviews substantial changes (5+ files OR 20+ lines)
- Uses same review prompt structure as Claude review
- Leverages ZHIPU_API_KEY for Z.ai model access

This provides an alternative "different model" perspective on PR reviews.
@opencode-agent

Copy link
Copy Markdown

remote: Duplicate header: "Authorization"
fatal: unable to access 'https://github.com/frankbria/codeframe/': The requested URL returned error: 400

opencode session  |  github run

Comment thread .github/workflows/opencode-review.yml Outdated
@opencode-agent

Copy link
Copy Markdown

remote: Duplicate header: "Authorization"
fatal: unable to access 'https://github.com/frankbria/codeframe/': The requested URL returned error: 400

opencode session  |  github run

@claude

claude Bot commented Jan 10, 2026

Copy link
Copy Markdown

Updated Code Review - PR #241: Phase-Awareness Pattern Implementation

I've reviewed this PR including the new OpenCode workflow addition. Overall, this is high-quality work with excellent test coverage and clean implementation. Below are my findings.


✅ Summary of Review

Previous review findings remain valid:

  • Excellent code organization with shared utilities
  • Comprehensive test coverage (52 new tests, 1558 total passing)
  • Proper performance optimizations (CostDashboard skips API calls during planning)
  • Consistent UX across all three components
  • Strong type safety throughout

New addition (commit ed92ebc):

  • Added .github/workflows/opencode.yml for automated code review

🔍 Issues Found

1. Workflow File Naming Inconsistency ⚠️

The new workflow file is named opencode.yml but CodeRabbit mentioned opencode-review.yml in the PR description. Verify which filename is correct and ensure consistency.

2. Missing Workflow Documentation 📝

The new OpenCode workflow should be documented in CLAUDE.md under a CI/CD section.

Suggestion: Add documentation explaining that users can trigger automated code review by commenting /oc or /opencode on PRs or issues. Mention it uses Z.ai GLM-4.7 model.

3. Secret Management 🔒

The workflow uses ZHIPU_API_KEY secret. Verification needed:

  • Ensure ZHIPU_API_KEY is configured in repository secrets
  • Document this requirement for contributors/maintainers
  • Consider documentation about secret rotation

4. Workflow Permissions Review 🔐

Current permissions are read-only for pull-requests and issues. If the OpenCode action posts comments back, you might need write permissions. Verify the action's requirements.

5. Workflow Trigger Edge Case 🐛

The trigger uses leading spaces in contains() checks to avoid false positives. This is good but should be documented. Also note this triggers on both issue and PR review comments, which could cause duplicate runs.


🎯 Previous Recommendations Still Apply

From my earlier review:

Must Fix:

  • Add aria-hidden="true" to decorative icons (AgentList.tsx:162, QualityGatesPanel.tsx:213)

Should Fix:

  • Add phase transition test for CostDashboard (similar to AgentList.test.tsx:268)
  • Extract magic number (1000) to named constant in CostDashboard.tsx:262

Nice to Have:

  • Centralize task count badge rendering (currently duplicated)
  • Add clarifying comment to PLANNING_PHASES about future extensibility

✨ Architecture Compliance

✅ Follows Nova Design System (proper color palette, Hugeicons)
✅ Follows Phase-Awareness Pattern from PR #234
✅ Excellent test coverage (with minor gap in CostDashboard phase transitions)


🚀 Overall Assessment

Quality: Excellent ⭐⭐⭐⭐⭐ (4.8/5)

Strengths: Clean code, excellent tests, consistent patterns, performance-conscious

Minor weaknesses: Missing accessibility attributes, new workflow needs documentation


✅ Approval Recommendation

APPROVED with minor suggestions

This PR successfully fixes the late-joining user bug and follows established patterns. The new OpenCode workflow is a valuable addition. The identified issues are minor and can be addressed either before merge or in follow-up work.

Great job! 🎉

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In @.github/workflows/opencode-review.yml:
- Around line 7-11: The paths-ignore entry ".github/**" currently prevents this
workflow from running on changes to any files in .github (including workflows);
update the paths-ignore list to stop excluding the whole directory—either remove
the ".github/**" pattern or replace it with a more specific pattern such as
excluding only this workflow file (e.g.,
".github/workflows/opencode-review.yml") and/or other specific non-essential
files, and if you intentionally keep an exclusion, add a brief comment near the
paths-ignore key documenting that decision so reviewers understand why workflow
changes are skipped.
- Around line 16-20: Update the workflow permissions block so the action can
post comments: in the permissions mapping that currently lists "pull-requests:
read" and "issues: read", change "pull-requests" to "write" and "issues" to
"write" (i.e., set pull-requests: write and issues: write) so the GH CLI command
(gh pr comment) can operate.
🧹 Nitpick comments (1)
.github/workflows/opencode-review.yml (1)

45-45: Pin the third-party action to a specific version.

Using @latest for anomalyco/opencode/github means the action can change behavior without warning, potentially breaking the workflow or introducing security vulnerabilities. Pin to a specific commit SHA or version tag for stability and security.

Example:

uses: anomalyco/opencode/github@v1.2.3  # or @<commit-sha>
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a8fcef2 and ed92ebc.

📒 Files selected for processing (1)
  • .github/workflows/opencode-review.yml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Backend Unit Tests
  • GitHub Check: Frontend Unit Tests
  • GitHub Check: E2E Smoke Tests (Chromium)
  • GitHub Check: claude-review
🔇 Additional comments (3)
.github/workflows/opencode-review.yml (3)

46-52: Review: Clean separation of secrets and PR metadata.

The environment variables are well-structured, properly using GitHub secrets for the API key and passing PR context cleanly to the action.


22-35: Approve: Efficient conditional execution logic.

The two-step approach (calculate changes first, then conditionally execute based on thresholds) is clean and avoids unnecessary checkout operations for trivial changes. The threshold of 5+ files OR 20+ lines is reasonable for filtering substantial PRs.


36-36: No action needed. actions/checkout@v6 is the latest released version of the GitHub Action and is correctly specified.

Likely an incorrect or invalid review comment.

Comment thread .github/workflows/opencode-review.yml
Comment thread .github/workflows/opencode-review.yml Outdated
@opencode-agent

Copy link
Copy Markdown

remote: Duplicate header: "Authorization"
fatal: unable to access 'https://github.com/frankbria/codeframe/': The requested URL returned error: 400

opencode session  |  github run

Comment thread .github/workflows/opencode-review.yml
Comment on lines +27 to +29
additions=${{ github.event.pull_request.additions }}
deletions=${{ github.event.pull_request.deletions }}
total=$((additions + deletions))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

additions/deletions are assigned unquoted; empty or non‑numeric values can break $((...)). Consider quoting the assignments and using ${var:-0} in the arithmetic.

Suggested change
additions=${{ github.event.pull_request.additions }}
deletions=${{ github.event.pull_request.deletions }}
total=$((additions + deletions))
additions="${{ github.event.pull_request.additions }}"
deletions="${{ github.event.pull_request.deletions }}"
total=$(( ${additions:-0} + ${deletions:-0} ))

🚀 Want me to fix this? Reply ex: "fix it for me".

@claude

claude Bot commented Jan 10, 2026

Copy link
Copy Markdown

Follow-Up Review: PR #241

I've reviewed the phase-awareness implementation and the previous review. This looks like a solid, well-tested implementation. Here are a few additional observations beyond what was already covered:

✅ Implementation Strengths

1. Consistent Pattern Application
The phase-awareness pattern is consistently applied across all three components (AgentList, QualityGatesPanel, CostDashboard), making the codebase more maintainable.

2. Performance Optimization in CostDashboard
Lines 243-247 properly skip API calls during planning phase, preventing unnecessary network requests. This is excellent - it's not just about UI messaging but actual performance benefits.

3. Excellent Documentation
The phaseAwareData.ts utility has thorough JSDoc comments with performance notes (line 53-55) and usage warnings, which will help future developers.

🔍 Minor Suggestions (Beyond Previous Review)

1. Icon Accessibility Issue
The icons lack aria-hidden="true" attribute in some places:

  • AgentList.tsx:162 - BotIcon is correctly marked, but the CheckListIcon at line 172 is missing it
  • QualityGatesPanel.tsx:213,224 - Both icons are missing aria-hidden

Since these are decorative icons accompanying text, they should be hidden from screen readers.

2. Test Coverage Gap
CostDashboard.test.tsx doesn't have a phase transition test like the other components. Consider adding:

it('updates display when phase changes from planning to development', async () => {
  // Test phase transition behavior
});

3. Date Filter Constant
CostDashboard.tsx:262 has a magic number (1000 token limit). Consider extracting:

const MAX_TOKEN_RECORDS = 1000;

🎯 Architecture Notes

Positive Design Decisions:

  1. Using isPlanningPhase() early in useEffect (line 244) to skip data loading is clean and efficient
  2. The utility library approach in phaseAwareData.ts promotes reusability
  3. Backward compatibility maintained - phase prop is optional across all components

Security & Quality

Recommendation

Approve with minor suggestions. The implementation is production-ready. The accessibility and test coverage items are nice-to-haves that can be addressed in follow-up work if desired.

The phase-awareness pattern successfully solves the "late-joining user" bug and provides a better UX during the planning phase. Great work! 🎉

@opencode-agent

Copy link
Copy Markdown

remote: Duplicate header: "Authorization"
fatal: unable to access 'https://github.com/frankbria/codeframe/': The requested URL returned error: 400

opencode session  |  github run

@claude

claude Bot commented Jan 10, 2026

Copy link
Copy Markdown

Code Review - PR 241: Phase-Awareness Pattern + OpenCode Workflows

I have reviewed this PR across multiple iterations, including the latest CI workflow fixes. Here is my comprehensive assessment:


Phase-Awareness Implementation (Commits 1-2)

Status: EXCELLENT (5/5 stars)

The core phase-awareness implementation is production-ready with:

Strengths

  • Clean architecture: Shared phaseAwareData.ts utility library eliminates duplication
  • Comprehensive testing: 52 new tests covering edge cases, phase transitions, and accessibility
  • Performance optimization: CostDashboard skips API calls during planning phase (lines 243-247)
  • Consistent UX: All three components show informative planning-phase messages
  • Type safety: Proper TypeScript throughout with optional phase prop for backward compatibility
  • Documentation: Excellent JSDoc comments including performance notes

Test Coverage

  • phaseAwareData.ts: 25 tests (Excellent)
  • AgentList: 13 tests (Excellent)
  • QualityGatesPanel: 8 tests (Good)
  • CostDashboard: 6 tests (Good)
  • Total: 52 tests, 1558 passing

This successfully fixes the late-joining user bug and follows the pattern from PR 234.


CI Workflow Implementation (Commits 3-8)

Status: GOOD with Security Concerns (3/5 stars)

Evolution of Fixes

  • Commit bc6c953: Fixed accessibility (aria-hidden on icons)
  • Commit a8fcef2: Added manual trigger workflow
  • Commit ed92ebc: Added automatic PR review workflow
  • Commit b19b7e6: Fixed duplicate Authorization headers
  • Commit ff5beac: Enabled write permissions for comments
  • Commit 631eba5: Refined paths-ignore patterns
  • Commit ff61202: Cleared global git auth configs

Security Concerns

CRITICAL: Using @latest Tag

Both workflows use anomalyco/opencode/github@latest which is risky:

  1. Supply chain attack vector if anomalyco/opencode is compromised
  2. Breaking changes can silently break your workflow
  3. Non-reproducible builds
  4. Violates GitHub best practices

Recommendation: Pin to specific version or commit SHA

MEDIUM: Missing Secret Validation

The workflow assumes ZHIPU_API_KEY exists but does not validate it before running.

MEDIUM: No Workflow Timeout

Add timeout-minutes to prevent runaway costs.

Missing Documentation

The workflows need documentation in CLAUDE.md explaining:

  • Automated PR review triggers (5+ files or 20+ lines)
  • Manual review commands (/oc or /opencode)
  • Required ZHIPU_API_KEY secret setup

Recommendations

Must Fix Before Merge

  1. Pin OpenCode action to specific version (both workflows)
  2. Add secret validation (opencode-review.yml)
  3. Add workflow timeout (both workflows)
  4. Document OpenCode integration in CLAUDE.md

Should Fix

  1. Extract magic number in CostDashboard.tsx:262 (MAX_TOKEN_RECORDS = 1000)
  2. Add clarifying comment to PLANNING_PHASES about future extensibility

Nice to Have

  1. Centralize task count badge rendering (currently duplicated)
  2. Standardize test mock data approach

Overall Assessment

Phase-Awareness: 5/5 (Ready to merge)
OpenCode Workflows: 3/5 (Security issues)
Combined: 4/5

Recommendation: Conditional Approval

Option 1 (Recommended): Merge phase-awareness implementation now, address OpenCode workflows in follow-up PR with security fixes.

Option 2: Fix OpenCode security issues in this PR before merging.

The phase-awareness implementation is excellent and should not be blocked by workflow issues. Great work on the core feature!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @.github/workflows/opencode-review.yml:
- Line 55: Replace the floating tag "anomalyco/opencode/github@latest" with a
pinned reference to a specific, reviewed release or commit (e.g., a release tag
like @v1.2.3 or a full commit SHA) so the workflow always uses that exact
version; update the uses line to the chosen tag and optionally add Dependabot
configuration to track and propose version updates.
🧹 Nitpick comments (2)
.github/workflows/opencode-review.yml (2)

32-54: Consider extracting the gate condition to reduce duplication.

The same gate condition is repeated in three different steps (lines 34-36, 42-44, 52-54). This violates the DRY principle and increases maintenance burden.

Consider one of these approaches:

  • Use a job-level if condition to skip the entire job for small PRs
  • Extract the condition to a composite expression that can be referenced
♻️ Example refactor using job-level conditional
 jobs:
   opencode-review:
     runs-on: ubuntu-latest
+    if: |
+      github.event.pull_request.changed_files >= 5 ||
+      (github.event.pull_request.additions + github.event.pull_request.deletions) >= 20
     permissions:
       id-token: write
       contents: read
       pull-requests: write
       issues: write

     steps:
-      - name: Calculate total changes
-        id: calc
-        run: |
-          additions=${{ github.event.pull_request.additions }}
-          deletions=${{ github.event.pull_request.deletions }}
-          total=$((additions + deletions))
-          echo "total=$total" >> $GITHUB_OUTPUT

       - name: Checkout repository
-        # Only review substantial changes (5+ files OR 20+ lines changed)
-        if: |
-          github.event.pull_request.changed_files >= 5 ||
-          steps.calc.outputs.total >= 20
         uses: actions/checkout@v6
         with:
           fetch-depth: 1

       - name: Clear git extraheader to avoid duplicate auth
-        if: |
-          github.event.pull_request.changed_files >= 5 ||
-          steps.calc.outputs.total >= 20
         run: |
           git config --global --unset-all http.https://github.com/.extraheader || true
           git config --local --unset-all http.https://github.com/.extraheader || true
           git config --global --unset-all credential.helper || true

       - name: Run OpenCode PR Review
-        # Only review substantial changes (5+ files OR 20+ lines changed)
-        if: |
-          github.event.pull_request.changed_files >= 5 ||
-          steps.calc.outputs.total >= 20
         uses: anomalyco/opencode/github@latest

15-16: Consider adding a timeout to prevent hung workflows.

The job doesn't specify a timeout, so it will use the default (6 hours for GitHub-hosted runners). If the OpenCode action hangs, it could consume unnecessary runner time.

⏱️ Suggested timeout configuration
 jobs:
   opencode-review:
     runs-on: ubuntu-latest
+    timeout-minutes: 10
     permissions:
       id-token: write
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 631eba5 and ff61202.

📒 Files selected for processing (1)
  • .github/workflows/opencode-review.yml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Backend Unit Tests
  • GitHub Check: Frontend Unit Tests
  • GitHub Check: claude-review
  • GitHub Check: E2E Smoke Tests (Chromium)
🔇 Additional comments (6)
.github/workflows/opencode-review.yml (6)

3-12: LGTM! Trigger and path-ignore configuration is well-designed.

The workflow appropriately triggers on PR open and sync events, and the path ignores prevent unnecessary reviews for documentation and config-only changes while avoiding self-triggering loops.


17-21: Permissions are appropriate for the workflow's purpose.

The permission set correctly allows the action to read repository contents and write comments to PRs/issues. The id-token: write permission enables OIDC authentication with external services.


24-30: LGTM! Total changes calculation is correct.

The step correctly calculates total changes and uses the modern GITHUB_OUTPUT method for exposing outputs to subsequent steps.


57-62: Note: PR_BODY environment variable may be used internally by the action.

The PR_BODY is set as an environment variable but doesn't appear in the prompt. This is likely intentional if the OpenCode action uses it internally for additional context.


65-89: Well-structured prompt with appropriate guidance.

The prompt provides clear instructions for the review scope and includes helpful notes about consistency with prior reviews. The reference to CLAUDE.md for style guidance is a good practice.


64-64: The model identifier zai-coding-plan/glm-4.7 is valid and correctly formatted for OpenCode GitHub Actions workflows. No action needed.

if: |
github.event.pull_request.changed_files >= 5 ||
steps.calc.outputs.total >= 20
uses: anomalyco/opencode/github@latest

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Pin the action to a specific version instead of using @latest.

Using @latest for GitHub Actions poses security and stability risks. If the action is updated with breaking changes or compromised, your workflow will automatically use the new version without review.

🔒 Recommended fix
-        uses: anomalyco/opencode/github@latest
+        uses: anomalyco/opencode/github@v1.0.0  # Pin to a specific version or commit SHA

After pinning, consider using Dependabot to keep the action version up-to-date.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
uses: anomalyco/opencode/github@latest
uses: anomalyco/opencode/github@v1.0.0 # Pin to a specific version or commit SHA
🤖 Prompt for AI Agents
In @.github/workflows/opencode-review.yml at line 55, Replace the floating tag
"anomalyco/opencode/github@latest" with a pinned reference to a specific,
reviewed release or commit (e.g., a release tag like @v1.2.3 or a full commit
SHA) so the workflow always uses that exact version; update the uses line to the
chosen tag and optionally add Dependabot configuration to track and propose
version updates.

@frankbria
frankbria merged commit 9305ae9 into main Jan 10, 2026
15 of 16 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.

[P1] State Sync Audit: Components with phase-awareness gaps

1 participant