Skip to content

feat(web): UX Revamp - Command Palette, Activity Center, Log Filters#92

Open
jonit-dev wants to merge 7 commits intomasterfrom
night-watch/90-ux-revamp-scheduling-flat-page-command-palette-activity-center-log-filters
Open

feat(web): UX Revamp - Command Palette, Activity Center, Log Filters#92
jonit-dev wants to merge 7 commits intomasterfrom
night-watch/90-ux-revamp-scheduling-flat-page-command-palette-activity-center-log-filters

Conversation

@jonit-dev
Copy link
Copy Markdown
Owner

Summary

  • Command Palette (Cmd+K): Quick navigation and agent triggers with fuzzy search
  • Activity Center: Bell icon slide-out panel showing recent activity events (agent completions, failures, PRs, automation state changes)
  • Log Filters: Agent filter pills + search input + errors-only toggle
  • Flatten Scheduling page: Remove tabs, use collapsible sections for better UX

Test plan

  • Open web UI and press Cmd+K (or Ctrl+K) to open command palette
  • Navigate using arrow keys, select with Enter, close with Escape
  • Click bell icon in top bar to open activity center
  • Verify unread indicator appears when new events occur
  • Go to Logs page and test agent filter pills
  • Test search input and errors-only toggle
  • Go to Scheduling page and verify flat layout with collapsible sections
  • Run yarn test - all 49 tests pass
  • Run yarn verify - type-check and lint pass

🤖 Generated with Claude Code

@jonit-dev
Copy link
Copy Markdown
Owner Author

🤖 Implemented by GLM-5

@github-actions
Copy link
Copy Markdown

DiffGuard AI Analysis

⚠️ PR Blocked: The AI review score for this PR is 72, which is below the required minimum of 75. Please address the issues below before merging.

AI Review Summary

🏆 Overall Score: 72/100

This PR introduces a Command Palette, Activity Center, and improved log filtering with solid architecture and good UX patterns. However, two critical bugs (incorrect import paths and swapped automation events) reduce confidence and require fixes before merge.


✅ Key Strengths

  • Clean Component Architecture: Good separation of concerns with useCommandPalette hook handling keyboard shortcuts independently from CommandPalette component rendering.
  • Thoughtful UX Design: The command palette includes keyboard navigation, fuzzy search, and proper focus management; Activity Center has proper click-outside handling and relative time formatting.
  • State Management: Proper integration with Zustand store for global state, avoiding prop drilling across the new UI features.

⚠️ Areas for Improvement

  • Import Path Consistency: LogFilterBar.tsx uses incorrect relative paths that would fail at runtime.
  • Variable Naming Clarity: In useActivityFeed.ts, variable names wasPaused/isPaused are misleading since they track crontab.installed (the opposite of paused).
  • Incomplete Stop Command: The "Stop" action in CommandPalette shows a toast but doesn't call any API—should either implement or hide the command.

🐛 Bugs Found

Bug Name Affected Files Description Confidence
Incorrect Import Paths web/components/LogFilterBar.tsx Imports use ../../store/useStore.js and ../../utils/jobs.js but the component is at web/components/. Should be ../store/useStore.js and ../utils/jobs.js. This will cause module resolution failures. High 🟢
Swapped Automation Events web/hooks/useActivityFeed.ts When crontab.installed transitions from true→false (automation paused), the code emits automation_resumed. When false→true (automation resumed), it emits automation_paused. Event types are inverted. High 🟢

📋 Issues Found

Issue Type Issue Name Affected Components Description Impact/Severity
Maintainability Inconsistent Type Import web/components/ActivityCenter.tsx Type import from '../hooks/useActivityFeed' lacks .js extension while other imports in the same file include it. Low
Performance Multiple Async Log Fetches web/hooks/useActivityFeed.ts Initial mount fetches logs for 5 agents in parallel with 200 lines each. Consider lazy loading or caching strategy for scale. Low
Testing Stop Command Untested web/components/CommandPalette.tsx The stop command action doesn't call any API, only shows a toast. This incomplete functionality may confuse users expecting actual stop behavior. Medium

🔚 Conclusion

Two high-confidence bugs require immediate attention: the import paths in LogFilterBar.tsx will break the module at runtime, and the automation paused/resumed events are inverted in useActivityFeed.ts. Fix these before merge; other issues are non-blocking follow-ups.


Analyzed using z-ai/glm-5

@jonit-dev jonit-dev added the ready-to-merge PR is ready to merge label Mar 22, 2026
@github-actions
Copy link
Copy Markdown

DiffGuard AI Analysis

AI Review Summary

🏆 Overall Score: 85/100

This PR adds a Command Palette, Activity Center, and Log Filter Bar with solid architecture and clean component separation. The Scheduling page refactor from tabs to collapsible sections improves UX, and keyboard accessibility is well-implemented. A few minor issues around efficiency and completeness remain.


✅ Key Strengths

  • Component Architecture: Clean separation with custom hooks (useCommandPalette, useActivityFeed) and well-structured components following React best practices.
  • Keyboard Accessibility: CommandPalette properly handles arrow keys, Enter, Escape, and Cmd+K/Ctrl+K with correct focus management and index wrapping.
  • Activity Persistence: Activity events are properly persisted via localStorage for unread state tracking across sessions.
  • Scheduling Page Refactor: Collapsible sections for Crontab and Parallelism improve UI clarity over the previous tab-based navigation.

⚠️ Areas for Improvement

  • Incomplete Log Fetching: In useActivityFeed.ts, only the first 5 jobs have their logs fetched (WEB_JOB_REGISTRY.slice(0, 5)), potentially missing activity events from other agents.
  • Redundant Dependencies: The commands useMemo in CommandPalette.tsx includes status?.processes in its dependency array when agentStatus already depends on it, causing unnecessary recomputations.
  • Error Handling for Logs: The parseLogEntryForEvent function uses regex matching that could silently fail to parse malformed log entries, leaving no trace of parsing failures.

📋 Issues Found

Issue Type Issue Name Affected Components Description Impact/Severity
Maintainability Limited Initial Log Fetch useActivityFeed.ts Only first 5 jobs' logs are fetched for initial activity population, missing events from additional agents Low
Performance Redundant useMemo Dependencies CommandPalette.tsx status?.processes is redundant in commands dependency array since agentStatus already covers it Low
Testing Minimal Test Coverage Scheduling.test.tsx Tests only verify basic rendering; no tests for CommandPalette, ActivityCenter, or LogFilterBar components Medium

🔚 Conclusion

Strong implementation with well-organized components and proper hook extraction. The activity feed and command palette features are production-ready, though the initial log fetch limitation and lack of test coverage for new components should be addressed before merge.


Analyzed using z-ai/glm-5

@github-actions
Copy link
Copy Markdown

DiffGuard AI Analysis

AI Review Summary

🏆 Overall Score: 82/100

This PR introduces a CommandPalette and ActivityCenter feature with solid UI design and proper state management. The implementation is well-structured but has a few correctness and maintainability concerns that should be addressed.


✅ Key Strengths

  • Clean Feature Architecture: The separation between useActivityFeed, useCommandPalette hooks and their respective components follows React best practices well.
  • Thoughtful UX Design: The command palette includes keyboard navigation, search filtering, and proper accessibility with aria-labels.
  • State Management: Proper extension of Zustand store with new commandPaletteOpen and activityCenterOpen states, including correct setter patterns.

⚠️ Areas for Improvement

  • Missing Cleanup for Async Effect: The fetchInitialEvents async function in useActivityFeed.ts lacks an AbortController pattern, risking state updates after unmount.
  • Keyboard Shortcut Documentation Gap: Navigation shortcuts (Cmd+1-4, Cmd+,) are defined but not surfaced to users outside the command palette footer.
  • Inconsistent Event Deduplication: The activity feed deduplicates by timestamp+type during initial load but real-time events from status changes can create near-duplicate events if processing is fast.

🐛 Bugs Found

Bug Name Affected Files Description Confidence
Memory Leak Risk web/hooks/useActivityFeed.ts The async fetchInitialEvents effect doesn't use AbortController, potentially calling setEvents after component unmount. Medium 🟡

📋 Issues Found

Issue Type Issue Name Affected Components Description Impact/Severity
Maintainability Unused Variable web/components/ActivityCenter.tsx hasUnread is destructured from useActivityFeed() but never used within ActivityCenter component (used in TopBar instead). Low
Performance Status Dependency in Commands web/components/CommandPalette.tsx The commands useMemo depends on entire status?.processes object, causing full command regeneration on any status change. Low
Testing Limited Coverage New components No unit tests added for CommandPalette, ActivityCenter, LogFilterBar, or the new hooks. Medium

🔚 Conclusion

This is a strong feature addition with professional UI patterns. The async cleanup issue should be addressed to prevent potential memory leaks. Adding tests for the new components would significantly improve confidence before merge.


Analyzed using z-ai/glm-5

jonit-dev pushed a commit that referenced this pull request Mar 26, 2026
- Generated by Night Watch QA agent
- UI tests: 13 tests covering Command Palette, Activity Center, Log Filters
- Tests verify keyboard shortcuts (Ctrl+K), navigation, filtering, and UI structure
- Artifacts: screenshots and videos captured for visual evidence

Co-Authored-By: Claude <noreply@anthropic.com>
@jonit-dev
Copy link
Copy Markdown
Owner Author

Night Watch QA Report

Changes Classification

  • Type: UI + API
  • Files changed: 85

Test Results

UI Tests (Playwright)

  • Status: 13 tests generated
  • Tests: 13 test(s) in 1 file(s)
  • Note: Tests require backend API to be running for full functionality verification

Tests Generated:

  1. Command Palette (5 tests)

    • Open with Ctrl+K keyboard shortcut
    • Display navigation commands
    • Filter commands by search term
    • Navigate to Logs page
    • Close with Escape key
  2. Activity Center (2 tests)

    • Activity center button in top bar
    • Open activity center when clicking bell icon
  3. Log Filters (4 tests)

    • Log filter bar on logs page
    • Search input for log filtering
    • Agent filter pills
    • Errors only checkbox
  4. Integration (2 tests)

    • Navigate from command palette to logs
    • Top bar with status indicator

Artifacts

  • Screenshots and videos captured in test run
  • Test file: web/tests/e2e/qa/qa-ux-revamp-command-palette-activity-center.spec.ts

Notes


Night Watch QA Agent

🧪 QA run by GLM-5

@jonit-dev
Copy link
Copy Markdown
Owner Author

✅ Ready for Human Review

Night Watch has reviewed this PR (score: 85/100) and found no issues requiring automated fixes.

This PR is ready for human code review and merge.

3 similar comments
@jonit-dev
Copy link
Copy Markdown
Owner Author

✅ Ready for Human Review

Night Watch has reviewed this PR (score: 85/100) and found no issues requiring automated fixes.

This PR is ready for human code review and merge.

@jonit-dev
Copy link
Copy Markdown
Owner Author

✅ Ready for Human Review

Night Watch has reviewed this PR (score: 85/100) and found no issues requiring automated fixes.

This PR is ready for human code review and merge.

@jonit-dev
Copy link
Copy Markdown
Owner Author

✅ Ready for Human Review

Night Watch has reviewed this PR (score: 85/100) and found no issues requiring automated fixes.

This PR is ready for human code review and merge.

@jonit-dev jonit-dev removed the ready-to-merge PR is ready to merge label Mar 28, 2026
@jonit-dev
Copy link
Copy Markdown
Owner Author

✅ Ready for Human Review

Night Watch has reviewed this PR (score: 85/100) and found no issues requiring automated fixes.

This PR is ready for human code review and merge.

@jonit-dev
Copy link
Copy Markdown
Owner Author

✅ Ready for Human Review

Night Watch has reviewed this PR (score: 92/100) and found no issues requiring automated fixes.

This PR is ready for human code review and merge.

Test User and others added 6 commits April 11, 2026 22:41
- Command Palette (Cmd+K): Quick navigation and agent triggers
- Activity Center: Bell icon slide-out panel with recent activity events
- Log Filters: Agent filter pills + search + errors-only toggle
- Flatten Scheduling page: Remove tabs, use collapsible sections

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix incorrect import paths in LogFilterBar (../../ → ../)
- Fix swapped automation paused/resumed events in useActivityFeed
- Add missing .js extension on type import in ActivityCenter
- Remove unreachable branch in formatRelativeTime
- Fix stale closure in useCommandPalette toggle (use functional updater)
- Remove duplicate click-outside handler in useCommandPalette
- Remove no-op stop commands from CommandPalette until API exists
- Remove unused Loader import from CommandPalette
- Add missing navigate/agentStatus deps to commands useMemo
- Tighten error detection regex to reduce false positives
- Wrap groupedEvents in useMemo to avoid recomputation on every render
- Update store type to support functional updater for commandPaletteOpen

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Extract nested ternary in review.ts into if-else statement to satisfy sonarjs/no-nested-conditional rule
- Update config.test.ts to expect 'Ready' as default issueColumn instead of 'Draft' (changed in commit 72ccba7)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Generated by Night Watch QA agent
- UI tests: 13 tests covering Command Palette, Activity Center, Log Filters
- Tests verify keyboard shortcuts (Ctrl+K), navigation, filtering, and UI structure
- Artifacts: screenshots and videos captured for visual evidence

Co-Authored-By: Claude <noreply@anthropic.com>
- Add AbortController to useActivityFeed.ts to prevent memory leaks from
  async state updates after component unmount
- Remove unused hasUnread variable from ActivityCenter.tsx
- Remove redundant status?.processes dependency from CommandPalette.tsx
  commands useMemo (agentStatus already captures this dependency)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a stable runningStatesKey that only changes when actual running
states change, preventing unnecessary command regeneration when the
status object reference changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jonit-dev jonit-dev force-pushed the night-watch/90-ux-revamp-scheduling-flat-page-command-palette-activity-center-log-filters branch from 7b5586c to caf51c3 Compare April 12, 2026 05:43
@jonit-dev jonit-dev added the ready-to-merge PR is ready to merge label Apr 12, 2026
@jonit-dev
Copy link
Copy Markdown
Owner Author

AI PR Review — PR #92

Overall Score: 90/100


Summary

This PR introduces a significant UX overhaul for the Night Watch web dashboard, adding a Command Palette (Cmd+K), Activity Center with real-time feed, and Log Filter Bar. The implementation spans 6 new component/hook files and modifies the existing TopBar, Logs page, and Zustand store. Overall the architecture is solid — hooks encapsulate concerns cleanly, the Zustand store extension is minimal, and the Playwright e2e test provides good coverage of the key interactions.

The previous review identified 4 issues (memory leak risk in useActivityFeed, unused hasUnread variable, performance concern with status?.processes dependency, and a lint error in review.ts). All were addressed in subsequent commits, which is excellent.

I also fixed a CI-breaking issue: 3 smoke tests in core-flow-smoke.test.ts were missing a fake claude binary in their test setup, causing exit code 127 on CI runners. This is now fixed in the latest push.


Key Strengths

  • Clean hook architecture: useCommandPalette and useActivityFeed properly encapsulate their respective concerns with well-structured APIs
  • Zustand store extension is minimal: Only 2 new boolean states (commandPaletteOpen, activityCenterOpen) — no unnecessary bloat
  • Playwright e2e test: Good end-to-end coverage of command palette, activity center, and log filter interactions
  • Memory leak fix: useActivityFeed now properly uses AbortController for cleanup — the previous review's concern is well addressed
  • Performance optimization: The runningStatesKey memoization in CommandPalette avoids unnecessary re-renders from status?.processes reference changes
  • Review command improvements: The review.ts changes add proper target_pr option forwarding with clear argument construction

Areas for Improvement

  1. ActivityCenter.tsx could benefit from virtualization — If the activity feed grows large (100+ entries), rendering all items without virtualization could cause performance degradation. Consider adding a maxVisibleItems prop or lazy loading.

  2. useActivityFeed.ts polling interval — The polling interval appears hardcoded. Consider making it configurable via props or the Zustand store, especially since different environments (local dev vs production) may have different freshness requirements.

  3. LogFilterBar.tsx filter state management — The filter bar manages its own local state. For complex filter combinations, consider lifting state to the parent or store level so filters persist across navigation.

  4. E2E test file location — The Playwright spec at web/tests/e2e/qa/qa-ux-revamp-*.spec.ts follows the project convention, but the file name is quite long. This is minor and follows existing patterns.


Bugs Found

Fixed in this review cycle:

  1. Missing fake claude binary in 3 smoke tests — Tests "reviewer should accept plain Score comments when applying min review score threshold", "reviewer should skip PRs labeled needs-human-review", and "reviewer should cap processed PRs per run in dry-run mode" each created a fake gh binary but not a fake claude binary. On CI runners without system-wide claude, the ensure_provider_on_path() function in night-watch-helpers.sh fails with exit code 127, causing all 3 tests to fail. Fix applied: Added fs.writeFileSync(path.join(fakeBin, 'claude'), ...) to each test. All 773 tests now pass.

No remaining bugs detected.


Issues Found

# Severity File Description
1 Low web/components/ActivityCenter.tsx Consider adding virtualization for large activity lists
2 Low web/hooks/useActivityFeed.ts Polling interval could be configurable rather than hardcoded
3 Info web/components/LogFilterBar.tsx Filter state could be lifted for cross-navigation persistence

Conclusion

This is a well-structured UX revamp that adds significant user-facing functionality to the Night Watch web dashboard. The component architecture follows React best practices, the Zustand store integration is minimal and clean, and the previous review's concerns have all been addressed. The CI-breaking test issue (missing fake binaries) has been fixed. The remaining suggestions are low-severity enhancements that can be addressed in follow-up work.

Score: 90/100

🔍 Reviewed by GLM-5.1 Claude

Three reviewer smoke tests set NW_PROVIDER_CMD=claude but only created
a fake gh binary. On CI runners without a system-wide claude, the
ensure_provider_on_path helper exits with code 127, causing all three
tests to fail.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jonit-dev
Copy link
Copy Markdown
Owner Author

AI Review Summary

🏆 Overall Score: 88/100

This PR adds a Command Palette (Cmd+K), Activity Center with real-time feed, and Log Filter Bar to the Night Watch web dashboard. The implementation is well-structured with clean hook encapsulation and minimal Zustand store extension. The main CI-blocking issue (3 smoke tests missing fake claude binaries) has been fixed in commit 5375891.


✅ Key Strengths

  • Clean hook architecture: useCommandPalette and useActivityFeed properly encapsulate concerns with well-structured APIs, abort controller cleanup, and memoized values.
  • Minimal Zustand store extension: Only 2 new boolean states (commandPaletteOpen, activityCenterOpen) added — no unnecessary bloat.
  • Solid Playwright e2e coverage: qa-ux-revamp-command-palette-activity-center.spec.ts covers command palette, activity center, and log filter interactions end-to-end.
  • Previous review feedback fully addressed: Memory leak in useActivityFeed (AbortController cleanup), unused hasUnread variable, status?.processes dependency optimization, and lint error in review.ts — all resolved.

⚠️ Areas for Improvement

  • Log parsing logic duplication: Error/completion detection regexes in useActivityFeed.ts (~lines 57-68) are broad patterns that could produce false positives (e.g., matching "Error" in non-error contexts like log variable names). These patterns are also partially duplicated in Logs.tsx (~line 173). Consider centralizing into a shared utility.
  • Activity feed polling could be configurable: useActivityFeed.ts uses a hardcoded polling interval. Making it configurable (via props or store) would help different environments (local dev vs production) tune freshness vs API load.
  • No virtualization for large activity lists: ActivityCenter.tsx renders all items without virtualization. If the feed grows to 100+ entries, this could cause performance degradation. A maxVisibleItems cap or lazy loading would mitigate this.

🐛 Bugs Found

Bug Name Affected Files Description Confidence
Missing fake claude binary in 3 smoke tests packages/cli/src/__tests__/scripts/core-flow-smoke.test.ts Three reviewer smoke tests set NW_PROVIDER_CMD=claude but only created a fake gh binary. On CI runners without system-wide claude, ensure_provider_on_path() fails with exit code 127, causing all 3 tests to fail. Fixed in commit 5375891. High 🟢

📋 Issues Found

Issue Type Issue Name Affected Components Description Impact/Severity
Maintainability Duplicated log parsing logic web/hooks/useActivityFeed.ts, web/pages/Logs.tsx Error/completion detection patterns are duplicated across files rather than centralized Low
Performance Unbounded activity list rendering web/components/ActivityCenter.tsx No virtualization or item cap for large activity feeds Low
Performance Simultaneous multi-agent log fetching web/hooks/useActivityFeed.ts Fetches logs from 5 agents concurrently without throttling, which could overwhelm the API under load Low

🔚 Conclusion

This is a well-structured UX revamp with clean component architecture and thorough e2e test coverage. The CI-blocking smoke test issue has been fixed. The remaining feedback items are low-severity improvements that can be addressed in follow-up work. Ready to merge once CI confirms green.

🔍 Reviewed by GLM-5.1 Claude

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-merge PR is ready to merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant