Skip to content

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

Open
jonit-dev wants to merge 21 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 21 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

- 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>
@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

- 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>
@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 and others added 17 commits March 25, 2026 15:54
)

* chore: organize PRDs and create architecture docs

Move completed PRDs to done/ folder:
- job-registry.md (Job Registry implementation)
- analytics-job.md (Analytics job implementation)
- fix-executor-streaming-output.md (Terminal streaming fix)
- fix-prd-execution-failures.md (Double rate-limit detection)
- open-source-readiness.md (OSS community files)
- remove-legacy-personas-and-filesystem-prd.md (Dead code cleanup)
- prd-provider-schedule-overrides.md (Provider schedule overrides)
- provider-agnostic-instructions.md (Instructions directory refactoring)
- night-watch/provider-aware-queue.md (Per-bucket concurrency)

Delete obsolete PRD:
- refactor-interaction-listener.md (packages/slack/ removed in commit 46637a0)

Add architecture docs:
- docs/architecture/job-registry.md (Job registry architecture)
- docs/architecture/analytics-job.md (Analytics job architecture)

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

* feat: add e2e-validated label for automated acceptance proof on PRs

Implements the E2E Validated Label PRD across 4 phases:

Phase 1 — Label Definition & Config:
- Add 'e2e-validated' (green #0e8a16) to NIGHT_WATCH_LABELS in labels.ts
- Add validatedLabel: string to IQaConfig in types.ts
- Add DEFAULT_QA_VALIDATED_LABEL constant and update DEFAULT_QA in constants.ts
- Add validatedLabel extra field to QA job definition in job-registry.ts
- Config normalization picks it up automatically via normalizeJobConfig

Phase 2 — QA Script Integration:
- Pass NW_QA_VALIDATED_LABEL env var from qa.ts buildEnvVars()
- Show Validated Label in qa --dry-run config table
- Read VALIDATED_LABEL in QA bash script with e2e-validated default
- Add ensure_validated_label() helper (idempotent gh label create --force)
- Apply label on 'passing' outcome, remove on 'issues_found'/'no_tests_needed'
- Track VALIDATED_PRS_CSV and include in emit_result and Telegram messages

Phase 3 — Init Label Sync:
- Add step 11 to night-watch init: sync all NIGHT_WATCH_LABELS to GitHub
- Skips gracefully when no GitHub remote or gh not authenticated
- Updates totalSteps from 13 to 14 and adds Label Sync to summary table

Phase 4 — Dry-Run & Summary Integration:
- Validated Label shown in qa --dry-run config table (merged into Phase 2)
- emit_result includes validated= field for all success/warning outcomes

Tests:
- packages/core/src/__tests__/board/labels.test.ts (new): e2e-validated presence
- packages/core/src/__tests__/jobs/job-registry.test.ts: validatedLabel extra field
- packages/cli/src/__tests__/commands/qa.test.ts: NW_QA_VALIDATED_LABEL env var
- packages/cli/src/__tests__/commands/init.test.ts: label sync preconditions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Test User <test@test.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <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>
- Add 'auto' to QueueMode type in shared/types.ts
- Remove unsupported placeholder prop from Select in ScheduleOverrideEditor
- Add missing globalMaxConcurrency field in Scheduling.tsx reset handler

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>
@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

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

1 similar comment
@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.

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
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.

1 similar comment
@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.

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.

1 participant