Conversation
* feat: native CloudWatch Logs viewer (issue #29) Replace external 'aws logs tail' dependency with internal TUI log viewer. - Add LogView with FilterLogEvents polling (3s interval) - Support both log-groups and log-streams - Space to pause/resume, g/G for top/bottom, c to clear - Remove AWS CLI and less dependencies * refactor: use Navigation instead of Action for log viewing Move log viewing from Action menu to Navigation shortcut: - Press 't' directly from log-groups/log-streams to open LogView - Remove ActionTypeView handling from action_menu - Cleaner UX: no action menu step needed * test: add LogView tests + fix data race in fetchLogs * fix: add ready flag to LogView, remove ActionTypeView dead code - Add ready flag to LogView to prevent uninitialized viewport access - Remove ActionTypeView constant and related IsAllowedInReadOnly case - Remove obsolete ActionTypeView test cases - Remove beads issue tracking setup (not using) * fix: align LogView with codebase patterns (error handling, AWS helpers) - LogView: use apperrors.Wrap instead of fmt.Errorf - LogView: use appaws.* helpers instead of raw aws.* - LogStreamDAO.Delete: add IsNotFound check for idempotency - helpers.go: add Int64Ptr for consistency with Int32Ptr * fix: LogView SetSize/ViewString patterns for consistency with other views * fix: add context timeout and throttling backoff to LogView - Add 10s timeout for FilterLogEvents API calls - Add exponential backoff on throttling (up to 30s) - Reset poll interval on success - Add godoc for LogView struct * fix: clear error state on successful log fetch * chore: ignore .gtrconfig * fix: add context cancellation check and extract magic numbers - Check parent context before starting fetch to prevent resource leaks - Extract buffer sizes and fetch limit to named constants * fix: stop polling on non-throttling errors Only continue polling with backoff on throttling errors. Other errors (access denied, etc.) stop polling to avoid spamming. * fix: add context check to initClient and throttle indicator - Check context cancellation before initializing AWS client - Show throttle status with backoff interval in StatusLine * fix: unwrap resource before type assertion in createLogView Fixes multi-region mode where resources are wrapped with RegionalDAOWrapper. Without unwrapping, type assertions for logGroupProvider/logStreamProvider fail. * feat: add 'p' key to load older logs and fix old stream viewing - Add 'p' key to load 1 hour of older logs (prepends to buffer) - For log streams, use lastEventTimestamp as starting point - Track oldestEventTime to enable backward navigation - Fixes issue where old streams showed 'no log events' * refactor: improve LogView consistency and add configurable timeout - Use ui.NewSpinner() for consistent spinner initialization - Extract doFetchLogs() to eliminate code duplication (75% reduction) - Add LogFetchTimeout to config system (default: 10s) - Add IsNotFound/IsAccessDenied error classification for better UX - Replace errors.New() with apperrors.Wrap() for consistency - Document viewportHeaderOffset magic number * refactor: remove dead code and restore doc comments - Remove unused Action.Target field - Remove unused LogView.width/height fields - Add LogFetch to DefaultFileConfig for consistency - Restore doc comments for Navigation, ViewTypeLogView, HandleKey * fix: add UnwrapResource for multi-region support in cloudwatch resources * refactor: align LogView with other viewport-based views - Add width/height fields for consistency with DetailView, DiffView, etc. - Remove HasActiveInput() since views without filter don't implement it
…88 #89) (#91) * refactor: extract ViewportState, add common styles, remove wrapper (#87 #88 #89) - Add ViewportState type to eliminate duplicated viewport init pattern (6 views) - Add TitleStyle, SelectedStyle, TableHeaderStyle to theme.go - Remove unnecessary getCloudWatchLogsClient wrapper in log-streams * refactor: use theme style helpers across views (#88) * refactor: extend theme style helpers to app and render packages (#88) * refactor: apply style helpers and Go 1.21+/1.22+ idioms (#88) - service_browser: use TableHeaderStyle() and SelectedStyle() - use max()/min() builtins instead of if statements - use range over int for loop modernization * refactor: complete style helpers and Go 1.21+ idioms (#88) - Add 6 new theme helpers: SectionStyle, HighlightStyle, BoldSuccessStyle, BoldDangerStyle, BoldWarningStyle, BoldPendingStyle - Apply helpers across 8 view files for consistency - Fix hardcoded #ff0000 color in exec_with_header.go - Use max()/min() builtins in dashboard_view_panels.go - Use range-over-int in dashboard_view.go and dashboard_view_panels.go * refactor: remove dead code and expand style helper usage (#88) - Remove unused width/height fields from 5 view structs - Apply DimStyle() across 11 locations - Apply SuccessStyle/WarningStyle/DangerStyle where applicable - Update tests to match field removal * refactor: add MutedStyle, LoadingMessage const, cmp.Or, remove dead code (#88) * refactor: add AccentStyle, slices.Collect, remove dead fields (#88) * refactor: add TextStyle/SecondaryStyle/BorderStyle/PrimaryStyle, remove dead code (#88) * refactor: add InfoStyle/PendingStyle/TextBrightStyle, extend helpers to render/action (#88) * refactor: remove render style wrappers, add BoxStyle/InputStyle, consolidate truncate (#88) * refactor: add InputFieldStyle, cache tag_search_view styles (#88)
Pull Request Review: v0.6.3 ReleaseI've completed a comprehensive review of this release PR. Overall, this is an excellent release with high-quality implementation, thoughtful refactoring, and strong test coverage. Here's my detailed feedback: ✅ Strengths1. Native CloudWatch Logs Viewer (#86)The new LogView implementation is exceptionally well-designed:
Code Quality: 2. Style Helpers Consolidation (#91)Outstanding refactoring work:
3. ViewportState AbstractionSmart DRY refactoring:
4. Modern Go IdiomsGreat use of Go 1.21+/1.22+ features:
5. Test CoverageComprehensive testing:
🔍 Code Quality ObservationsExcellent Patterns Found
🎯 Minor Suggestions (Non-blocking)1. LogView Context HandlingLocation: The func (v *LogView) fetchLogsCmd() tea.Cmd {
startTime := v.lastEventTime
return func() tea.Msg {
return v.doFetchLogs(startTime, 0, false)
}
}Observation: This is actually correct! It prevents race conditions by capturing the timestamp when the command is created rather than when it executes. Good defensive programming. 2. Error Message ConsistencyLocation: Using err: apperrors.Wrap(fmt.Errorf("CloudWatch Logs client not initialized"), "fetch logs")Suggestion: Consider err: apperrors.Wrap(errors.New("CloudWatch Logs client not initialized"), "fetch logs")This is very minor - current approach works fine. 3. Magic Number DocumentationLocation: Great job documenting the magic number: viewportHeaderOffset = 4 // header(1) + status(2) + spacing(1)This is exactly what code comments should look like - clear rationale for the value. 🔒 Security ReviewNo security concerns identified: ✅ Context timeouts prevent indefinite hangs 📊 Performance ConsiderationsExcellent performance characteristics:
No performance issues identified. 🧪 Test Coverage AssessmentRating: Excellent ✅
All critical paths are tested. 📝 DocumentationGood documentation practices: ✅ README.md updated with new 🎉 Final AssessmentThis is a production-ready release with:
Recommendation: APPROVE AND MERGE 🚀 The native CloudWatch Logs viewer is a significant UX improvement (removes AWS CLI dependency), and the style helpers refactoring will make future development much cleaner. Great work! This release sets a high bar for code quality. 📋 Nitpicks (Optional)If you want to be extra thorough:
Neither is blocking - ship it! 🎊 |
Changes since v0.6.2
New Features
lkey navigationRefactoring
uipackagemax(),min(),cmp.Or(), range-over-intTesting
Closes #29, #87, #88, #89