Skip to content

feat: add night-watch summary command for morning briefings#85

Merged
jonit-dev merged 3 commits intomasterfrom
night-watch/prd-summary-command
Mar 22, 2026
Merged

feat: add night-watch summary command for morning briefings#85
jonit-dev merged 3 commits intomasterfrom
night-watch/prd-summary-command

Conversation

@jonit-dev
Copy link
Copy Markdown
Owner

Summary

Adds a new night-watch summary command that provides a "morning briefing" aggregating data from multiple sources into a single view:

  • Recent job runs from getJobRunsAnalytics()
  • Open PRs from collectPrInfo()
  • Pending queue items from getQueueStatus()

Usage

night-watch summary [--hours <n>] [--json]

Options

  • --hours <n>: Time window in hours (default: 12)
  • --json: Output summary as JSON

Examples

night-watch summary              # Last 12 hours
night-watch summary --hours 24   # Last 24 hours  
night-watch summary --json       # JSON output for scripting

Output Format

Night Watch Summary (last 12h)
────────────────────────────────

Jobs Executed: 5
  ✓ 3 succeeded   ✗ 1 failed   ⏱ 1 timed out

┌──────────┬──────────┬──────────┬──────────┬──────────────┐
│ Job      │ Status   │ Project  │ Provider │ Duration     │
├──────────┼──────────┼──────────┼──────────┼──────────────┤
│ executor │ success  │ my-app   │ claude   │ 8m 32s       │
│ reviewer │ success  │ my-app   │ codex    │ 4m 15s       │
│ executor │ failure  │ my-lib   │ claude   │ 12m 01s      │
└──────────┴──────────┴──────────┴──────────┴──────────────┘

Open PRs (2)
┌────┬────────────────────────┬──────────┬───────┐
│ #  │ Title                  │ CI       │ Score │
├────┼────────────────────────┼──────────┼───────┤
│ 42 │ feat: add login page   │ pass     │ 85    │
│ 43 │ fix: memory leak       │ pending  │ -     │
└────┴────────────────────────┴──────────┴───────┘

Queue: 1 pending (executor for my-lib)

No action needed — all jobs healthy.

When there are failures:

⚠ Action needed:
  • 1 failed job — run `night-watch logs` to investigate
  • 1 PR with failing CI — check PR #43

Implementation

Files Changed

  • packages/core/src/utils/summary.ts - New file: getSummaryData() function
  • packages/core/src/index.ts - Export from summary.ts
  • packages/cli/src/commands/summary.ts - New file: command implementation
  • packages/cli/src/cli.ts - Register summary command
  • packages/cli/src/__tests__/commands/summary.test.ts - Unit tests

Tests

All 11 tests pass:

  • Help text display
  • Summary header with time window
  • JSON output validation
  • Default 12 hours behavior
  • Custom --hours value
  • No recent activity handling
  • Job counts display
  • Action item generation for failures
  • "No action needed" for healthy jobs
  • Action items for failing CI PRs

References

  • PRD: docs/PRDs/night-watch/prd-summary-command.md

🤖 Generated with Claude Code

Adds a new `night-watch summary` command that aggregates data from existing
sources into a single "morning briefing" view:
- Recent job runs from `getJobRunsAnalytics()`
- Open PRs from `collectPrInfo()`
- Pending queue items from `getQueueStatus()`

Usage:
  night-watch summary [--hours <n>] [--json]

Options:
  --hours <n>  Time window in hours (default: 12)
  --json       Output summary as JSON

Examples:
  night-watch summary              # Last 12 hours
  night-watch summary --hours 24   # Last 24 hours
  night-watch summary --json       # JSON output for scripting

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

AI Review Summary

🏆 Overall Score: 88/100

This PR adds a well-structured summary command for the Night Watch CLI with clean separation between CLI and core logic, comprehensive test coverage, and proper TypeScript typing. Minor improvements around performance and maintainability would elevate it further.


✅ Key Strengths

  • Clean Architecture: Separates CLI presentation (summary.ts) from data aggregation (core/utils/summary.ts), making both testable and reusable.
  • Comprehensive Test Coverage: Tests cover JSON/formatted output, various job states, PR scenarios, edge cases, and help text.
  • Good Developer Experience: Clear action items, color-coded output, and both human-readable and JSON output modes.

⚠️ Areas for Improvement

  • Sequential Async Calls: getSummaryData fetches job analytics, PR info, and queue status sequentially. These independent calls could run in parallel with Promise.all() for faster execution.
  • Test Mock Fragility: process.cwd is globally mutated before module import in tests. This works but can cause issues if tests run in parallel or if other tests need the original cwd. Consider using dependency injection or a configurable project dir.
  • Duplicate Mocked Calls in Tests: getQueueStatus is mocked with defaults in beforeEach then re-mocked identically in the "should show No action needed" test without changing behavior.

📋 Issues Found

Issue Type Issue Name Affected Components Description Impact/Severity
Performance Sequential Async Calls packages/core/src/utils/summary.ts Three independent async operations (getJobRunsAnalytics, collectPrInfo, getQueueStatus) execute sequentially rather than in parallel. Low
Maintainability Global State Mutation summary.test.ts:31-32 Overwriting process.cwd globally before module import is fragile and may cause test isolation issues. Low
Maintainability Redundant Test Mock summary.test.ts:288-297 getQueueStatus is re-mocked with identical values to beforeEach setup, adding noise without value. Low

🔚 Conclusion

A solid, well-tested feature addition that follows established patterns in the codebase. The parallelization opportunity is minor but worth addressing for CLI responsiveness. Ready to merge with optional polish.


Analyzed using z-ai/glm-5

@jonit-dev jonit-dev force-pushed the night-watch/prd-summary-command branch from 6488c73 to 51dae65 Compare March 13, 2026 05:50
@github-actions
Copy link
Copy Markdown

DiffGuard AI Analysis

AI Review Summary

🏆 Overall Score: 82/100

The PR adds a well-structured "summary" command for a morning briefing feature, with clean separation between CLI and core logic, good TypeScript typing, and comprehensive test coverage. A minor display bug and a few robustness issues prevent a higher score.


✅ Key Strengths

  • Clean Architecture: Separates CLI presentation logic (summary.ts command) from data aggregation (core/utils/summary.ts), enabling reusability and testability.
  • Comprehensive Testing: Tests cover JSON output, formatted output, help text, edge cases (no activity), and action item generation with appropriate mocking.
  • Type Safety: Well-defined interfaces (ISummaryData, IJobRunCounts) and proper TypeScript usage throughout.

⚠️ Areas for Improvement

  • Input Validation: Add validation for the --hours parameter to handle non-numeric strings (produces NaN) and negative values gracefully.
  • Cross-Platform Path Handling: getProjectName() uses split('/') which won't work correctly on Windows paths with backslashes—consider using path.basename() instead.
  • Test Mock Robustness: The module-level mock of process.cwd is fragile; consider using vi.spyOn(process, 'cwd') within individual tests instead.

🐛 Bugs Found

Bug Name Affected Files Description Confidence
Extra Parenthesis in Queue Display packages/cli/src/commands/summary.ts Line 163 has an extra closing parenthesis in the template string: for ${projectNames.join(', ')}) should be for ${projectNames.join(', ')}. Output shows an extra ) character. High 🟢

📋 Issues Found

Issue Type Issue Name Affected Components Description Impact/Severity
Maintainability Fragile Test Setup summary.test.ts Module-level process.cwd replacement before import makes tests dependent on execution order and harder to debug. Medium
Reliability Missing Input Validation summary.ts parseInt(options.hours || '12', 10) can produce NaN or accept negative numbers without warning. Low

🔚 Conclusion

A solid implementation with good architecture and test coverage. The extra parenthesis bug should be fixed before merge, and the input validation is worth addressing for production robustness.


Analyzed using z-ai/glm-5

- Added 20 tests for getSummaryData core utility
- Tests cover: windowHours, job counts, action items, PR integration, queue integration
- All 31 summary-related tests pass (11 CLI + 20 core)

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

Night Watch QA Report

Changes Classification

  • Type: API (CLI command + core utility)
  • Files changed: 5

Test Results

API Tests

  • Status: All passing
  • Tests: 31 test(s) in 2 file(s)
    • packages/cli/src/__tests__/commands/summary.test.ts — 11 tests
    • packages/core/src/__tests__/utils/summary.test.ts — 20 tests (newly added by QA)

Test Coverage Summary

The QA agent added comprehensive tests for the core getSummaryData utility:

  • windowHours: Default and custom time windows
  • job counts: Success, failure, timeout, rate_limited, skipped statuses
  • action items: Failed jobs, timed out jobs, rate limited jobs, failing CI PRs, pending queue items
  • PR integration: Branch patterns, open PRs in response
  • queue integration: Pending queue items filtering

Files Added

File Tests Description
packages/core/src/__tests__/utils/summary.test.ts 20 Core utility unit tests

Night Watch QA Agent

🧪 QA run by GLM-5

- Fix unmatched trailing `)` in queue display string
- Fix early return that hid open PRs, queue status, and action items when no job runs existed; only the job table section is now conditional
- Use path.basename() instead of POSIX-only split('/').pop() in getProjectName
- Extract magic number 12 into DEFAULT_SUMMARY_WINDOW_HOURS constant in core/constants.ts
- Import and use DEFAULT_SUMMARY_WINDOW_HOURS in both summary.ts files and CLI command
- Add NaN/non-positive guard for --hours CLI input

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jonit-dev jonit-dev merged commit d0feff0 into master Mar 22, 2026
1 of 5 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.

1 participant