feat(web-ui): compress and summarize verbose execution event stream (#475)#497
feat(web-ui): compress and summarize verbose execution event stream (#475)#497
Conversation
…475) - groupEvents() function transforms raw events into EventGroup[] for smart view - Consecutive file-read events → collapsible ReadGroupRow ("Read N files") - Consecutive file edit/create/delete events → EditGroupRow summary line - Smart view is default; "Show all events" toggle switches to raw log - ReadGroupRow expands to show individual events on click - Added stream header with event count context and view toggle
WalkthroughAdds event grouping and UI controls to the execution event stream: filters heartbeat events, groups consecutive progress events into read and edit summaries, introduces collapsible read groups and summarized edit rows, a smart/raw view toggle, an icon import, and a small scroll-height adjustment. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (4)
web-ui/src/components/execution/EventStream.tsx (4)
198-203: Use Shadcn/UIButtoncomponent for consistency.The toggle button uses a plain
<button>element while the "New events" button (line 258) uses the Shadcn/UIButtoncomponent. For consistency and to leverage Shadcn/UI's built-in accessibility and styling, consider usingButtonwith appropriate variant.♻️ Suggested change
- <button - className="text-xs text-muted-foreground hover:text-foreground" + <Button + variant="ghost" + size="sm" + className="h-auto px-2 py-1 text-xs text-muted-foreground hover:text-foreground" onClick={() => setShowAll((v) => !v)} > {showAll ? 'Smart view' : 'Show all events'} - </button> + </Button>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web-ui/src/components/execution/EventStream.tsx` around lines 198 - 203, The toggle uses a raw <button> instead of the Shadcn/UI Button component—replace the plain element in EventStream.tsx with the Button component (imported from your shadcn/ui library) and pass the same onClick handler (setShowAll) and display text (showAll ? 'Smart view' : 'Show all events'), applying an appropriate variant/size (e.g., variant="ghost" or "link"/size="sm") and the equivalent className props to preserve styling and accessibility; ensure the import for Button is added/updated and that the component still toggles setShowAll((v) => !v) and uses the existing showAll symbol for the label.
27-35: Type assertions bypass type safety.The repeated
(e as { message?: string }).messagepattern sidesteps TypeScript's type checking. SinceExecutionEventis a union type and you've already narrowed toevent_type === 'progress', consider defining a type guard or using proper type narrowing to accessmessagesafely.♻️ Suggested approach using type guard
+function isProgressEventWithMessage(e: ExecutionEvent): e is ExecutionEvent & { message: string } { + return e.event_type === 'progress' && typeof (e as { message?: string }).message === 'string'; +} + function isReadEvent(e: ExecutionEvent): boolean { - if (e.event_type !== 'progress') return false; - return /^reading file:/i.test((e as { message?: string }).message ?? ''); + return isProgressEventWithMessage(e) && /^reading file:/i.test(e.message); } function isEditEvent(e: ExecutionEvent): boolean { - if (e.event_type !== 'progress') return false; - return /^(creating|editing|deleting) file:/i.test((e as { message?: string }).message ?? ''); + return isProgressEventWithMessage(e) && /^(creating|editing|deleting) file:/i.test(e.message); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web-ui/src/components/execution/EventStream.tsx` around lines 27 - 35, The two helpers isReadEvent and isEditEvent use unsafe type assertions for message; define a proper type guard (e.g., isProgressEvent(e): e is ProgressEvent or a narrowed type that includes message?: string) that checks e.event_type === 'progress' and that typeof e.message === 'string' (or message existence), then replace the inline assertions in isReadEvent and isEditEvent to call that type guard so you can safely access e.message without bypassing TypeScript's checks.
206-213: Consider flex layout to avoid hardcoded height.The hardcoded
37pxinh-[calc(100%-37px)]is fragile and will break if the header's padding or font size changes. A flex-based approach would be more resilient.♻️ Alternative using flex layout
- <div className="relative flex-1 overflow-hidden rounded-lg border"> + <div className="relative flex flex-1 flex-col overflow-hidden rounded-lg border"> {/* Header: stream label + view toggle */} - <div className="flex items-center justify-between border-b px-4 py-2"> + <div className="flex shrink-0 items-center justify-between border-b px-4 py-2"> ... </div> <div ref={containerRef} - className="h-[calc(100%-37px)] overflow-y-auto p-4" + className="min-h-0 flex-1 overflow-y-auto p-4"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web-ui/src/components/execution/EventStream.tsx` around lines 206 - 213, The container currently uses a hardcoded height via className "h-[calc(100%-37px)]" which is brittle; change the layout to flex by making the parent wrapper a flex column and replace the container's fixed height with a flex-grow class (e.g., flex-1 or flex-auto) so the scrollable area grows to fill remaining space. Locate the EventStream component and update the element that uses ref containerRef and onScroll={handleScroll} to remove the calc height and use the flex-based overflow class (overflow-auto/overflow-y-auto) so the header and content sizing is resilient to padding/font changes. Ensure the sibling header element remains above the scroll container in the same flex column so the stack order and accessibility attributes (role="log", aria-live, aria-label) are preserved.
17-20: Consider movingEventGrouptype to centralized types file.Per coding guidelines, TypeScript types should be defined in
web-ui/src/types/index.ts. While this type is currently internal to this component, centralizing it would align with project conventions and facilitate reuse if other components need to work with grouped events.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web-ui/src/components/execution/EventStream.tsx` around lines 17 - 20, Move the EventGroup type definition out of EventStream.tsx into the project's central types index and export it so other modules can reuse it; update EventStream.tsx to import the exported EventGroup (and ensure ExecutionEvent is imported or re-exported if needed), keeping the same union shape ({ type: 'event' | 'read_group' | 'edit_group' } etc.) and run a quick type-check to fix any import/exports that need adjusting.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web-ui/src/components/execution/EventStream.tsx`:
- Line 154: The call to groupEvents(displayEvents) in EventStream.tsx is
recomputing on every render; wrap it with React's useMemo and add useMemo to the
imports so the grouping only recalculates when displayEvents changes. Locate the
constant groups = groupEvents(displayEvents) and replace it with a memoized
value using useMemo(() => groupEvents(displayEvents), [displayEvents]) and
ensure useMemo is imported at the top alongside other React hooks.
- Around line 119-133: The edit badge in EditGroupRow uses dark:bg-blue-900/40
which is inconsistent with the other badge styles (agentStateBadgeStyles uses
dark:bg-blue-900/30); extract the badge class string into a shared constant
(e.g., export const editGroupBadgeStyles) in the eventStyles module and replace
the inline class on the "edit" span with that constant
(className={editGroupBadgeStyles}), making sure the constant uses
dark:bg-blue-900/30 to match agentStateBadgeStyles for consistency and
maintainability.
---
Nitpick comments:
In `@web-ui/src/components/execution/EventStream.tsx`:
- Around line 198-203: The toggle uses a raw <button> instead of the Shadcn/UI
Button component—replace the plain element in EventStream.tsx with the Button
component (imported from your shadcn/ui library) and pass the same onClick
handler (setShowAll) and display text (showAll ? 'Smart view' : 'Show all
events'), applying an appropriate variant/size (e.g., variant="ghost" or
"link"/size="sm") and the equivalent className props to preserve styling and
accessibility; ensure the import for Button is added/updated and that the
component still toggles setShowAll((v) => !v) and uses the existing showAll
symbol for the label.
- Around line 27-35: The two helpers isReadEvent and isEditEvent use unsafe type
assertions for message; define a proper type guard (e.g., isProgressEvent(e): e
is ProgressEvent or a narrowed type that includes message?: string) that checks
e.event_type === 'progress' and that typeof e.message === 'string' (or message
existence), then replace the inline assertions in isReadEvent and isEditEvent to
call that type guard so you can safely access e.message without bypassing
TypeScript's checks.
- Around line 206-213: The container currently uses a hardcoded height via
className "h-[calc(100%-37px)]" which is brittle; change the layout to flex by
making the parent wrapper a flex column and replace the container's fixed height
with a flex-grow class (e.g., flex-1 or flex-auto) so the scrollable area grows
to fill remaining space. Locate the EventStream component and update the element
that uses ref containerRef and onScroll={handleScroll} to remove the calc height
and use the flex-based overflow class (overflow-auto/overflow-y-auto) so the
header and content sizing is resilient to padding/font changes. Ensure the
sibling header element remains above the scroll container in the same flex
column so the stack order and accessibility attributes (role="log", aria-live,
aria-label) are preserved.
- Around line 17-20: Move the EventGroup type definition out of EventStream.tsx
into the project's central types index and export it so other modules can reuse
it; update EventStream.tsx to import the exported EventGroup (and ensure
ExecutionEvent is imported or re-exported if needed), keeping the same union
shape ({ type: 'event' | 'read_group' | 'edit_group' } etc.) and run a quick
type-check to fix any import/exports that need adjusting.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 86312a49-7763-4091-b0a7-5dad2f4422d3
📒 Files selected for processing (1)
web-ui/src/components/execution/EventStream.tsx
|
test |
|
PLACEHOLDER |
|
Part 1 of code review for PR #497 (EventStream.tsx smart-view grouping): CRITICAL ISSUES — (1) isReadEvent/isEditEvent cast through structural types with optional message instead of narrowing to the existing ProgressEvent type. These should be proper type guards returning 'e is ProgressEvent', eliminating repeated casts inside groupEvents. (2) groupEvents runs on every render regardless of whether showAll is true, wasting work when groups is never consumed. Wrap in useMemo with displayEvents as the dependency. (3) h-[calc(100%-37px)] hardcodes the header height; use flex-1 instead. |
|
Part 2 of code review — IMPORTANT ISSUES: (4) onBlockerAnswered is not threaded into ReadGroupRow children — EventItem inside ReadGroupRow is rendered without this prop, so if a blocker event lands inside a read group the answer callback is silently dropped. (5) Index-based keys like rg-i reset expanded state during live streaming as React unmounts/remounts ReadGroupRow components when the group list shifts. Use the first event timestamp as key. (6) flushRead always emits a read_group even for a single event, unlike flushEdit which degrades to a plain EventItem. Make these consistent. (7) EditGroupRow renders the full file list without truncation; ReadGroupRow clips at 4. Apply the same limit. |
|
Part 3 of code review — MINOR + CONTEXT: Minor issues: extractFilename fallback lets full raw message strings appear in file lists (return trimmed placeholder instead); formatTime is duplicated from EventItem.tsx inline in the new row components; groupEvents has no automated tests despite being a pure function with non-trivial buffer logic; the smart/raw toggle is missing aria-pressed so screen readers cannot communicate its state. Context: per CLAUDE.md web-ui/ is legacy/reference-only and will be replaced in Phase 3. This PR does not violate core architectural rules. Blocking items before merge: issue 2 (memoize groupEvents), issue 4 (onBlockerAnswered in ReadGroupRow), and issue 5 (stable keys). The rest are quality improvements. |
CodeFRAME Development GuidelinesLast updated: 2026-03-09 Product VisionCodeFrame is a project delivery system: Think → Build → Prove → Ship. It owns the edges of the AI coding pipeline — everything BEFORE code gets written (PRD, specification, task decomposition) and everything AFTER (verification gates, quality memory, deployment). The actual code writing is delegated to frontier coding agents (Claude Code, Codex, OpenCode) that are better at it than any custom agent. CodeFrame does not compete with coding agents. It orchestrates them. Status: Phase 1 ✅ | Phase 2 ✅ | Phase 2.5 ✅ — CLI workflow, server layer, and ReAct agent complete. Agent adapter architecture (#408) and PROOF9 quality system (#422) are next priorities. See If you are an agent working in this repo: do not improvise architecture. Follow the documents listed below. Primary Contract (MUST FOLLOW)
Rule 0: If a change does not directly support the Think → Build → Prove → Ship pipeline, do not implement it. Strategic Priority (Phase 4)The next major architectural work is the Agent Adapter Architecture (#408):
Current Reality (Phase 1, 2 & 2.5 Complete)What's Working Now
v2 Architecture (current)
v1 Legacy
Repository StructureArchitecture Rules (non-negotiable)1) Core must be headless
Core is allowed to:
2) CLI must not require a serverGolden Path commands must work from the CLI with no server running. FastAPI is optional and must be started explicitly (e.g., 3) Agent state transitions flow through runtimeCritical pattern discovered during implementation:
This separation prevents duplicate state transitions (e.g., DONE→DONE, BLOCKED→BLOCKED errors). 4) Legacy can be read, not depended onLegacy code is reference material.
5) Keep commits runnableAt all times:
Agent System ArchitectureComponents
Model Selection StrategyTask-based heuristic via
Future: Engine SelectionCodeFRAME supports two execution engines, selected via
Execution Flow (ReAct — default)Execution Flow (Plan — legacy,
|
| Phase | Focus | Pipeline Stage | Status |
|---|---|---|---|
| 1 | CLI Completion | Think + Build | ✅ Complete |
| 2 | Server Layer | Build (API) | ✅ Complete |
| 2.5 | ReAct Agent | Build (execution) | ✅ Complete |
| 3 | Web UI Rebuild | All (dashboard) | In Progress |
| 4 | Agent Adapters + Orchestration | Build (delegate to frontier agents) | Next |
| 5 | PROOF9 + Advanced | Prove + Ship (quality memory) | Planned |
Phase 2 Complete: Server Layer (2026-02-03)
Phase 2 deliverables completed:
- ✅ Server audit and refactor ([Phase 2] Server audit and refactor - routes delegating to core modules #322) - 16 v2 routers following thin adapter pattern
- ✅ API key authentication (feat(auth): add API key authentication for CLI and REST API #326) - Scopes: read/write/admin
- ✅ Rate limiting (feat(security): add API rate limiting with slowapi #327) - Configurable per-endpoint with Redis support
- ✅ Real-time SSE streaming (feat(streaming): add real-time SSE events for task execution #328) -
/api/v2/tasks/{id}/stream - ✅ OpenAPI documentation ([Phase 2] Complete OpenAPI documentation for all endpoints #119) - Full Swagger/ReDoc with examples
Server Architecture (Phase 2)
Pattern: Thin adapter over core - server routes delegate to core.* modules.
CLI (typer) ─┬── core.* ─── adapters.*
│
Server (fastapi) ─┘
V2 Router Modules (16 total):
| Router | Endpoints | Purpose |
|---|---|---|
blockers_v2 |
5 | Blocker CRUD |
prd_v2 |
8 | PRD management + versioning |
tasks_v2 |
12 | Task management + streaming |
workspace_v2 |
5 | Init, status, tech stack |
batches_v2 |
5 | Batch execution strategies |
streaming_v2 |
2 | SSE event streaming |
api_key_v2 |
4 | API key management |
discovery_v2 |
5 | PRD discovery sessions |
checkpoints_v2 |
6 | State checkpoints |
schedule_v2 |
3 | Task scheduling |
templates_v2 |
4 | PRD templates |
git_v2 |
3 | Git operations |
review_v2 |
2 | Code review |
pr_v2 |
5 | GitHub PR workflow |
environment_v2 |
4 | Tool detection |
proof_v2 |
7 | PROOF9 quality gates + requirements |
API Authentication:
# Create API key
cf auth api-key-create --name "my-key" --scopes read,write
# Use in requests
curl -H "X-API-Key: cf_..." https://api.example.com/api/v2/tasksRate Limiting:
- Default: 100 requests/minute (standard endpoints)
- Auth endpoints: 10/minute
- AI endpoints: 20/minute
- Configurable via
RATE_LIMIT_*environment variables
OpenAPI Documentation:
- Swagger UI:
/docs - ReDoc:
/redoc - OpenAPI JSON:
/openapi.json
Previous Updates (2026-01-29)
V2 Strategic Roadmap Established
Created comprehensive 5-phase roadmap in docs/V2_STRATEGIC_ROADMAP.md.
Phase 1 Complete: CLI Foundation
All Phase 1 priorities completed:
- ✅
cf prd generate- Socratic PRD discovery ([Phase 1] cf prd generate - Interactive AI PRD creation (Socratic Discovery) #307) - ✅
cf work follow- Live execution streaming ([Phase 1] cf work follow - Live execution streaming #308) - ✅ Integration tests for credential/env modules ([Phase 1] Integration tests for credential and environment modules #309)
- ✅ PRD template system ([Phase 1] PRD template system for customizable output formats #316)
Environment Validation (cf env)
New commands for validating development environment:
cf env check # Validate required tools (git, uv, ruff, pytest)
cf env install # Install missing tools automatically
cf env doctor # Comprehensive environment health checkModules:
core/environment.py- Tool detection and validationcore/installer.py- Cross-platform tool installation
GitHub PR Workflow (cf pr)
Streamlined PR management without leaving the CLI:
cf pr create # Create PR from current branch
cf pr status # Show PR status and review state
cf pr checks # Show CI check results
cf pr merge # Merge approved PRTask Self-Diagnosis (cf work diagnose)
AI-powered analysis of failed tasks:
cf work diagnose <task-id> # Analyze why a task failedModules:
core/diagnostics.py- Failed task analysiscore/diagnostic_agent.py- AI-powered diagnosis
Bug Fixes
- [Phase 1] Backend: NoneType error accessing search_pattern during task execution #265: Fixed NoneType error in
codebase_index.search_pattern()- added null check - [Phase 1] Checkpoint diff API returns 500 - workspace directory missing #253: Fixed checkpoint diff API returning 500 - added workspace existence validation
GitHub Issue Organization
- Created
v1-legacylabel for 22 v1-specific issues (closed, retained as Phase 3 reference) - Created phase labels:
phase-1,phase-2,phase-4,phase-5 - Created 9 new issues ([Phase 1] cf prd generate - Interactive AI PRD creation (Socratic Discovery) #307-[Phase 5] Debug and replay mode #315) for roadmap features
- Consistent naming:
[Phase #] Titleformat
Previous Updates (2026-01-16)
Phase 3.1: Tech Stack Configuration
Simplified tech stack configuration using natural language descriptions:
- ✅
tech_stackfield on Workspace model - stores natural language description - ✅
--detectflag - auto-detects from pyproject.toml, package.json, Cargo.toml, go.mod - ✅
--tech-stackflag - explicit tech stack description (e.g., "Rust project with cargo") - ✅
--tech-stack-interactiveflag - simple prompt for user input (stub for future multi-round) - ✅ Agent integration - TaskContext and Planner include tech_stack in LLM prompts
- ✅ Removed
cf configsubcommand - tech stack is now part of workspace init
Design philosophy: Instead of structured configuration with specific package managers and frameworks, users describe their stack in natural language. The agent interprets and adapts.
Examples:
cf init . --detect # Auto-detect: "Python with uv, pytest, ruff for linting"
cf init . --tech-stack "Rust project using cargo"
cf init . --tech-stack "TypeScript monorepo with pnpm, Next.js, jest"
cf init . --tech-stack-interactive # Prompts user for descriptionFuture work: Multi-round interactive discovery (bead: codeframe-8d80)
Agent Self-Correction & Observability
Improved agent reliability with automatic error recovery:
- ✅ Self-correction loop in
_run_final_verification()- agent retries up to 3 times - ✅ Verbose mode (
--verbose/-v) - shows detailed verification/self-correction progress - ✅ FAILED task status - tasks transition to FAILED for proper error visibility
- ✅ Project preferences - agent loads AGENTS.md/CLAUDE.md for per-project config
- ✅ Fixed
fail_run()- now properly transitions task status (was leaving tasks stuck)
Enhanced Self-Correction (Phase 3.4)
Advanced error recovery with loop prevention and smart escalation:
-
✅ Fix Attempt Tracker (
core/fix_tracker.py) - prevents repeating failed fixes- Normalizes errors for comparison (removes line numbers, memory addresses)
- Tracks (error_signature, fix_description) pairs with outcomes
- Detects escalation patterns (same error 3+ times, same file 3+ times)
-
✅ Pattern-Based Quick Fixes (
core/quick_fixes.py) - fixes common errors without LLMModuleNotFoundError→ auto-install package (detects package manager)ImportError→ add missing import statementNameError→ add common imports (Optional, dataclass, Path, etc.)SyntaxError→ fix missing colons, f-string prefixesIndentationError→ normalize mixed tabs/spaces
-
✅ Escalation to Blocker - creates informative blockers when stuck
- Triggered after MAX_SAME_ERROR_ATTEMPTS (3) failures on same error
- Triggered after MAX_SAME_FILE_ATTEMPTS (3) failures on same file
- Triggered after MAX_TOTAL_FAILURES (5) in a run
- Blocker includes error type, attempted fixes, and guidance questions
Self-Correction Flow
Error occurs
│
├── Try ruff --fix (auto-lint)
│
├── Try pattern-based quick fix (no LLM)
│ ├── Check if fix already attempted → skip
│ ├── Apply fix
│ └── Record outcome in tracker
│
├── Check escalation threshold
│ └── If exceeded → create escalation blocker
│
└── Use LLM to generate fix plan
├── Include already-tried fixes to avoid repetition
├── Execute fix steps with tracking
└── Re-verify
Key Self-Correction Methods
_run_final_verification(): While loop that re-runs gates after self-correction_attempt_verification_fix(): Orchestrates quick fixes, escalation check, LLM fixes_create_escalation_blocker(): Creates detailed blocker with context_verbose_print(): Conditional stdout output for observability
Phase 2 Complete (2026-01-15): Parallel Batch Execution
All 6 Phase 2 items from CLI_WIREFRAME.md are done:
- ✅
work batch resume <batch-id>- re-run failed/blocked tasks - ✅
depends_onfield on Task model - ✅ Dependency graph analysis (DAG, cycle detection, topological sort)
- ✅ True parallel execution with ThreadPoolExecutor worker pool
- ✅
--strategy autowith LLM-based dependency inference - ✅
--retry Nautomatic retry of failed tasks
Key Phase 2 Modules
- conductor.py: Batch orchestration with serial/parallel/auto strategies
- dependency_graph.py: DAG operations, level-based grouping for parallelization
- dependency_analyzer.py: LLM analyzes task descriptions to infer dependencies
Agent Implementation Complete (2026-01-14)
All 8 implementation tasks from AGENT_IMPLEMENTATION_TASKS.md are done:
- ✅ LLM Adapter Interface (
adapters/llm/) - ✅ Task Context Loader (
core/context.py) - ✅ Agent Planning (
core/planner.py) - ✅ Code Execution Engine (
core/executor.py) - ✅ Automatic Blocker Detection (in
core/agent.py) - ✅ Gate Integration (in
core/agent.py) - ✅ Agent Orchestrator (
core/agent.py) - ✅ Wire into Runtime (
core/runtime.py)
Bug Fixes During Testing
- GateResult attribute access: Fixed
gate_result.status→gate_result.passed - Duplicate task transitions: Removed task status updates from agent.py (runtime handles all)
- READY→READY error: Added check in
stop_runbefore transitioning - Verification step handling: Made
_execute_verificationsmarter about file vs command targets
Key Design Decisions
- State separation: Agent manages AgentState, Runtime manages TaskStatus
- Model selection: Task-based heuristic via Purpose enum
- Blocker creation: Agent creates blockers, Runtime updates task status
- Verification: Incremental (ruff after each file change) + final (all gates)
Testing
Run all tests
uv run pytestRun v2 tests only
uv run pytest -m v2 # All v2 tests (~411 tests)
uv run pytest -m v2 -q # Quiet modeThe v2 marker identifies tests for CLI-first, headless functionality:
- All tests in
tests/core/are automatically marked v2 (via conftest.py) - v2 CLI tests have
pytestmark = pytest.mark.v2at the top
Convention: When adding new v2 functionality, mark tests with @pytest.mark.v2 or add pytestmark = pytest.mark.v2 at module level for CLI tests that use codeframe.cli.app.
Run core module tests
uv run pytest tests/core/
uv run pytest tests/core/test_agent.py -v
uv run pytest tests/adapters/test_llm.py -vTest coverage
uv run pytest --cov=codeframe --cov-report=htmlEnvironment Variables
# Required for agent execution
ANTHROPIC_API_KEY=sk-ant-...
# Optional - Database
DATABASE_PATH=./codeframe.db
# Optional - Rate Limiting (Phase 2)
RATE_LIMIT_ENABLED=true # Enable/disable rate limiting
RATE_LIMIT_DEFAULT=100/minute # Default limit
RATE_LIMIT_AUTH=10/minute # Auth endpoints
RATE_LIMIT_AI=20/minute # AI/LLM endpoints
RATE_LIMIT_WEBSOCKET=50/minute # WebSocket connections
REDIS_URL=redis://localhost:6379 # Redis for distributed rate limiting (optional)
# Optional - API Server
CODEFRAME_API_KEY_SECRET=<random-secret> # Secret for API key hashingLegacy sections removed on purpose
This file previously contained extensive v1 details (auth, websocket, UI template, sprint history).
Those are still in git history and legacy docs, but they are not the current contract.
The current contract is Golden Path + Refactor Plan + Command Tree mapping + Agent Implementation.
|
Consolidated Code Review for PR 497 (smart-view event grouping in EventStream.tsx) CRITICAL (3 issues):
IMPORTANT (4 issues): MINOR: extractFilename fallback exposes raw message strings in file lists; formatTime is duplicated from EventItem.tsx; groupEvents has no unit tests despite being a testable pure function; smart/raw toggle missing aria-pressed attribute. CONTEXT: web-ui/ is legacy/reference-only per CLAUDE.md and will be replaced in Phase 3. No core architecture violations in this PR. MERGE BLOCKERS: issues 2 (memoize groupEvents), 4 (onBlockerAnswered), and 5 (stable keys). |
…roupBadgeStyles
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web-ui/src/lib/eventStyles.ts`:
- Around line 85-87: The new export editGroupBadgeStyles uses blue color classes
which violates the repo's gray-only UI requirement; update the
editGroupBadgeStyles constant to use the Shadcn/UI Nova preset gray badge
classes (replace blue-* and dark:blue-* classes with the equivalent gray-* and
dark:gray-* classes) so it conforms to web-ui/src/**/*.{ts,tsx} gray color
scheme and Hugeicons conventions; locate the editGroupBadgeStyles export to make
this change.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: dfcd913e-c5a3-4385-abc0-1d4ac6a4a039
📒 Files selected for processing (2)
web-ui/src/components/execution/EventStream.tsxweb-ui/src/lib/eventStyles.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- web-ui/src/components/execution/EventStream.tsx
| /** Badge style for the edit-group summary row in the EventStream. */ | ||
| export const editGroupBadgeStyles = 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300'; | ||
|
|
There was a problem hiding this comment.
Use gray badge classes for the new edit-group style constant.
Line 86 introduces blue badge colors, which conflicts with the repo’s gray-only UI color scheme requirement for web-ui/src/**/*.{ts,tsx}.
🎨 Suggested change
-export const editGroupBadgeStyles = 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300';
+export const editGroupBadgeStyles = 'bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-300';As per coding guidelines, web-ui/src/**/*.{ts,tsx}: Web UI must use Shadcn/UI (Nova preset) with gray color scheme and Hugeicons (@hugeicons/react); never use lucide-react.
📝 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.
| /** Badge style for the edit-group summary row in the EventStream. */ | |
| export const editGroupBadgeStyles = 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300'; | |
| /** Badge style for the edit-group summary row in the EventStream. */ | |
| export const editGroupBadgeStyles = 'bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-300'; | |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@web-ui/src/lib/eventStyles.ts` around lines 85 - 87, The new export
editGroupBadgeStyles uses blue color classes which violates the repo's gray-only
UI requirement; update the editGroupBadgeStyles constant to use the Shadcn/UI
Nova preset gray badge classes (replace blue-* and dark:blue-* classes with the
equivalent gray-* and dark:gray-* classes) so it conforms to
web-ui/src/**/*.{ts,tsx} gray color scheme and Hugeicons conventions; locate the
editGroupBadgeStyles export to make this change.
|
Follow-up review test |
|
test line 1 |
|
Part 1 of review: Two items resolved in b7906fb. groupEvents wrapped in useMemo (issue 2). editGroupBadgeStyles extracted to eventStyles.ts. |
|
--- ## Follow-up review |
|
Follow-up review for PR 497 Two items from the previous review have been addressed in the latest commit (b7906fb): Resolved:
Still outstanding from prior review - in priority order: Blocking / functional:
Quality / consistency:
Minor:
Items 1 and 2 (onBlockerAnswered and stable keys) are the highest-priority blockers before merge as they affect correctness in live-streaming scenarios. |
Follow-up review — PR #497Two items from the previous review have been addressed in the latest commit (b7906fb): Resolved
Still outstanding from prior review The following items flagged before were not addressed. Listing them in priority order: Blocking / functional
Quality / consistency
Minor
Items #1 and #2 (onBlockerAnswered and stable keys) are the highest-priority blockers before merge as they affect correctness in live-streaming scenarios. |
Summary
groupEvents()transforms raw event arrays into groupedEventGroup[]for the smart viewReadGroupRow("Read N files: x, y, z") with expand affordanceEditGroupRowsingle summary line ("Modified N files: …")Closes #475
Test plan
Summary by CodeRabbit