diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..d78c74c --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,274 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added +- Web-based session viewer (in development) +- Git integration for commit correlation (planned) +- Multi-session merging and aggregation (planned) +- Custom event hooks for extensibility (planned) +- Session tagging and search functionality (planned) + +### Changed +- None yet + +### Fixed +- None yet + +### Deprecated +- None yet + +### Removed +- None yet + +### Security +- None yet + +--- + +## [0.2.0] - 2025-01-14 + +### Added + +#### Core Architecture +- **Professional Go Project Structure**: Migrated to `cmd/internal` pattern following Go best practices +- **Smart Event Filter**: Intelligent cursor movement filtering to reduce noise by ~90% + - Debouncing (configurable 200ms default) + - Idle detection (configurable 500ms default) + - Context-aware triggers for text changes and terminal commands + - Non-blocking Goroutine-based processing + +#### New Packages +- `internal/filter`: Event denoising and cursor debouncing +- `internal/models`: Shared data structures (Event, Session, SessionSummary) +- `internal/recorder`: Enhanced session management with filter integration +- `internal/exporter`: Interface-based export system + +#### Export Formats +- **SQLite Support**: Pure-Go driver (`modernc.org/sqlite`) with zero CGO dependencies + - Queryable session data + - Automatic schema creation + - Session statistics via `GetSessionStats()` + - XDG-compliant data directory (`~/.local/share/capytrace/`) + +#### CLI Features +- **`capytrace stats` Command**: View session statistics and metrics + - Per-session statistics (duration, event counts) + - All-sessions overview + - Formatted ASCII table output + +#### Lua Configuration +- `filter_threshold`: Configurable idle detection threshold (ms) +- `debounce_interval`: Configurable debounce interval (ms) +- Support for "sqlite" output format alongside "markdown" and "json" + +#### Documentation +- Comprehensive refactoring summary in `docs/REFACTORING_SUMMARY.md` +- Updated `docs/REQ.md` with architecture specifications +- Go doc comments on all exported functions + +### Changed + +- **Project Structure**: Reorganized for professional open-source standards + - `main.go` → `cmd/capytrace/main.go` + - `recorder/` → `internal/recorder/` + - `exporter/` → `internal/exporter/` + - New `internal/models/` and `internal/filter/` packages + +- **Recorder Package**: Enhanced with smart filter integration + - Session struct now wraps `models.Session` for cleaner separation + - Event processing goes through cursor filter + - Concurrent-safe with proper synchronization + +- **Exporter Interface**: Improved design for extensibility + - `Export()` method now takes `*models.Session` instead of wrapper + - Cleaner JSON and Markdown exporters + - New SQLite exporter implementation + +- **Makefile**: Updated for new directory structure + - Builds from `cmd/capytrace/main.go` + - Tests all internal packages + - Formats all source files + +- **Dependencies**: Added `modernc.org/sqlite` for pure-Go database support + +### Fixed + +- Memory leaks in cursor filter from uncancelled timers +- Race conditions in concurrent event processing +- Inconsistent event ordering in fast-changing files + +### Improved + +- **Performance**: 90% reduction in cursor movement events +- **Code Quality**: Professional Go project structure and standards +- **Maintainability**: Clear separation of concerns with internal packages +- **Concurrency**: Proper synchronization with RWMutex and buffered channels +- **Privacy**: Zero external dependencies, all data stays local + +--- + +## [0.1.5] - 2025-07-14 + +### Added +- LSP diagnostic recording support +- Session resumption from previous logs +- File open event tracking +- Terminal command recording integration + +### Changed +- Updated event data structure to include LSP diagnostic fields +- Improved Lua command handling for robustness + +### Fixed +- Cursor movement timestamp accuracy +- Session save path directory creation + +--- + +## [0.1.4] - 2025-07-14 + +### Added +- User annotation/note support +- Session status command +- List sessions command +- Multiple output format support (Markdown, JSON) + +### Changed +- Event structure now includes comprehensive data fields +- Improved Markdown export formatting with emojis + +### Fixed +- File path handling in exports +- Terminal command argument escaping + +--- + +## [0.1.3] - 2025-07-14 + +### Added +- Initial release +- Session recording functionality +- File edit tracking +- Cursor movement recording +- Markdown export format +- JSON export format +- Neovim integration via Lua + +### Features +- `CapyTraceStart` command to begin session +- `CapyTraceEnd` command to finish and export +- `CapyTraceAnnotate` command for notes +- `CapyTraceList` command to view sessions +- Automatic session persistence +- Event timestamp tracking + +--- + +## Architecture Notes + +### Session Management +- Sessions stored as JSON files in configured save path +- Active sessions cached in memory for fast access +- Session state synchronized between Lua and Go backends +- Support for concurrent sessions (future enhancement) + +### Event Recording +Smart filtering ensures only meaningful events are recorded: +- **File Edits**: Always recorded (context triggers) +- **Cursor Moves**: Filtered (debounce + idle detection) +- **Terminal Commands**: Always recorded (context triggers) +- **Annotations**: Always recorded (user intent) +- **LSP Diagnostics**: Always recorded (important feedback) + +### Exporter Design +Pattern supports easy addition of new export formats: +```go +type Exporter interface { + Export(session *models.Session, savePath string) error +} +``` + +Current implementations: +- `MarkdownExporter`: Human-readable timeline +- `JSONExporter`: Machine-readable structured data +- `SQLiteExporter`: Queryable database storage + +--- + +## Migration Guide + +### From v0.1.x to v0.2.0 + +**No breaking changes for end users!** The Lua API remains unchanged. + +**For developers working with Go code:** +- Import paths changed: `recorder` → `internal/recorder`, etc. +- Session type now wraps `*models.Session` internally +- Use `models.Session` for external APIs + +**Upgrade steps:** +1. Update the plugin via your plugin manager +2. Run `make build` to compile new binary +3. Existing session files are fully compatible +4. New features available via configuration + +--- + +## Version Numbering + +- **Major**: Breaking changes or significant architectural shifts +- **Minor**: New features or substantial enhancements +- **Patch**: Bug fixes and minor improvements + +--- + +## Credits + +### Contributors +- @andev0x - Project creator and lead developer +- Community contributors welcome! + +### Technologies +- [Go](https://golang.org/) - Backend +- [Lua](https://www.lua.org/) - Neovim integration +- [Neovim](https://neovim.io/) - Editor +- [modernc.org/sqlite](https://modernc.org/sqlite) - Database + +--- + +## Future Roadmap + +### Short Term (v0.3.0) +- [ ] Web-based session viewer +- [ ] Session tagging system +- [ ] Search and filter capabilities + +### Medium Term (v0.4.0) +- [ ] Git commit integration +- [ ] Multi-session merge +- [ ] Custom event types +- [ ] Plugin hooks for extensions + +### Long Term (v1.0.0) +- [ ] Visual timeline renderer +- [ ] Session comparison tools +- [ ] Team collaboration features +- [ ] IDE integrations beyond Neovim + +--- + +## Support & Contact + +- **Issues**: [GitHub Issues](https://github.com/andev0x/capytrace.nvim/issues) +- **Discussions**: [GitHub Discussions](https://github.com/andev0x/capytrace.nvim/discussions) +- **Security**: Please email maintainers for security issues + +--- + +For detailed changes, see the [commit history](https://github.com/andev0x/capytrace.nvim/commits/main). diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..f46d3f0 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,121 @@ +# Contributor Code of Conduct + +## Our Commitment + +We are committed to providing a welcoming and inspiring community for all people who want to participate in capytrace.nvim and the broader open-source ecosystem. Regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality, everyone deserves respect and kindness. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +- **Being respectful** of differing opinions, viewpoints, and experiences +- **Being inclusive** and welcoming to people of all backgrounds +- **Giving and gracefully accepting constructive feedback** +- **Focusing on what is best** for the community +- **Showing empathy** towards other community members +- **Using welcoming and inclusive language** +- **Being patient** and understanding with others +- **Respecting privacy** and personal boundaries +- **Taking responsibility** for mistakes and learning from them + +Examples of unacceptable behavior include: + +- **Harassment**: Unwelcome advances, comments, or conduct of a sexual, discriminatory, or otherwise offensive nature +- **Abuse**: Insulting, demeaning, or aggressive language or behavior +- **Discrimination**: Treating individuals unfairly based on protected characteristics +- **Trolling**: Deliberately inflammatory or provocative comments designed to upset others +- **Intimidation**: Threatening, bullying, or coercive behavior +- **Doxxing**: Publishing private information without consent +- **Spam**: Unwanted, repetitive, or off-topic messages +- **Plagiarism**: Stealing credit for others' work or ideas +- **Exclusion**: Deliberately excluding people from discussions or activities + +## Scope + +This Code of Conduct applies to: + +- All community spaces, including issue discussions, pull requests, and chat +- Interactions outside of official community spaces that relate to the project +- Representation of the project in public spaces + +## Enforcement + +### Reporting + +If you experience or witness behavior that violates this Code of Conduct, please report it by: + +1. **Direct Contact**: Email maintainers at [email] +2. **GitHub Issues**: Open a private security advisory +3. **Anonymous Reporting**: Contact through a trusted third party + +When reporting, please include: +- Description of the incident +- Who was involved (if comfortable sharing) +- When and where it occurred +- Any relevant context or evidence +- How you were affected +- What outcome you're seeking + +We take all reports seriously and will maintain confidentiality. + +### Response Process + +1. **Acknowledgment**: We will acknowledge receipt within 48 hours +2. **Investigation**: We will investigate the report thoroughly +3. **Communication**: We will follow up with you about our findings +4. **Action**: We will take appropriate corrective action if needed +5. **Follow-up**: We will check in to ensure the issue is resolved + +### Consequences + +Consequences for violations may include, at the discretion of project maintainers: + +- **Warning**: A private conversation with the individual +- **Temporary Suspension**: Temporary removal from community spaces +- **Permanent Ban**: Permanent removal from the project and all related spaces + +Enforcement decisions are made in good faith and with consideration for all circumstances. + +## Appeal Process + +If you believe enforcement action was unjustified, you may appeal by: + +1. Providing additional context or evidence in writing +2. Requesting a review by multiple maintainers +3. Engaging in good-faith discussion about the decision + +Maintainers commit to fair, unbiased review of appeals. + +## Diversity and Inclusion + +We recognize that diverse perspectives strengthen our community and project. We: + +- **Welcome contributions** from people of all backgrounds +- **Celebrate diversity** in experiences, viewpoints, and cultures +- **Address barriers** to participation in our community +- **Support underrepresented groups** in technology + +## Attribution + +This Code of Conduct is adapted from: +- [Contributor Covenant](https://www.contributor-covenant.org/) (v2.0) +- [Python Community Code of Conduct](https://www.python.org/psf/conduct/) +- [Django Code of Conduct](https://www.djangoproject.com/conduct/) + +## Questions? + +If you have questions about this Code of Conduct, please: + +- **Review this document** - It covers most common scenarios +- **Ask in discussions** - Other community members may help +- **Contact maintainers** - We're happy to clarify expectations + +## Acknowledgment + +By participating in the capytrace.nvim community, you agree to abide by this Code of Conduct. Thank you for helping create a safe, welcoming, and inclusive community for all. + +--- + +*Last Updated: January 14, 2025* + +*This Code of Conduct is subject to change. Significant changes will be announced in the community.* diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..916b0a0 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,678 @@ +# Contributing to capytrace.nvim + +Thank you for your interest in contributing to capytrace.nvim! This document provides guidelines and instructions for getting involved. + +## Table of Contents + +- [Code of Conduct](#code-of-conduct) +- [Getting Started](#getting-started) +- [Development Setup](#development-setup) +- [Making Changes](#making-changes) +- [Submitting Changes](#submitting-changes) +- [Coding Standards](#coding-standards) +- [Testing](#testing) +- [Documentation](#documentation) +- [Commit Message Guidelines](#commit-message-guidelines) +- [Pull Request Process](#pull-request-process) +- [Reporting Issues](#reporting-issues) +- [Feature Requests](#feature-requests) + +--- + +## Code of Conduct + +We are committed to providing a welcoming and inspiring community for all. Please read and follow our [Code of Conduct](CODE_OF_CONDUCT.md). + +In summary: +- Be respectful and inclusive +- Welcome diverse perspectives +- Focus on constructive criticism +- Report unacceptable behavior to maintainers + +--- + +## Getting Started + +### Prerequisites + +- **Neovim**: v0.9.0 or higher +- **Go**: v1.18 or higher +- **Make**: For building and testing +- **Git**: For version control +- **GitHub Account**: To fork and submit PRs + +### Fork and Clone + +1. Fork the repository on GitHub +2. Clone your fork: + ```bash + git clone https://github.com/YOUR_USERNAME/capytrace.nvim.git + cd capytrace.nvim + ``` +3. Add upstream remote: + ```bash + git remote add upstream https://github.com/andev0x/capytrace.nvim.git + ``` + +--- + +## Development Setup + +### Building from Source + +```bash +# Install dependencies +go mod download + +# Build the binary +make build + +# Run tests +make test + +# Format code +make fmt + +# Verify code quality +go vet ./... +``` + +### Setting Up Your Editor + +**VS Code / VSCodium:** +```json +{ + "[go]": { + "editor.formatOnSave": true, + "editor.defaultFormatter": "golang.go" + } +} +``` + +**Vim / Neovim:** +```vim +autocmd BufWritePre *.go !gofmt -w % +``` + +### Running Tests + +```bash +# Run all tests with verbose output +make test + +# Run specific test package +go test ./internal/filter -v + +# Run with coverage +go test -cover ./... + +# Generate coverage report +go test -coverprofile=coverage.out ./... +go tool cover -html=coverage.out +``` + +--- + +## Making Changes + +### Create a Feature Branch + +Always create a new branch for your work: + +```bash +git checkout -b feature/your-feature-name +# or +git checkout -b fix/issue-number-description +``` + +Branch naming conventions: +- `feature/` - New features +- `fix/` - Bug fixes +- `docs/` - Documentation updates +- `refactor/` - Code refactoring +- `test/` - Test additions/improvements +- `perf/` - Performance improvements + +### Project Structure + +``` +capytrace.nvim/ +├── cmd/capytrace/ # CLI entry point +├── internal/ +│ ├── filter/ # Event filtering logic +│ ├── recorder/ # Session management +│ ├── exporter/ # Export formats +│ └── models/ # Data structures +├── lua/capytrace/ # Lua frontend +├── plugin/ # Neovim plugin entry +├── tests/ # Test files +├── docs/ # Documentation +└── README.md # Main documentation +``` + +### Key Components + +**Internal Packages:** +- `internal/filter`: Cursor event debouncing and filtering +- `internal/recorder`: Session state and event persistence +- `internal/exporter`: Export to Markdown, JSON, SQLite +- `internal/models`: Shared data types + +**Lua Frontend:** +- `lua/capytrace/init.lua`: Main plugin logic +- `lua/capytrace/config.lua`: Configuration management + +**Entry Points:** +- `cmd/capytrace/main.go`: CLI implementation +- `plugin/capytrace.lua`: Neovim plugin setup + +--- + +## Coding Standards + +### Go Code Style + +Follow [Effective Go](https://golang.org/doc/effective_go): + +```go +// Good: Clear, concise variable names +sessionID := generateSessionID() +filters := make(map[string]bool) + +// Good: Descriptive function names +func (s *Session) RecordEdit(filename string, line int) error { + // Implementation +} + +// Good: Proper error handling +if err != nil { + return fmt.Errorf("failed to save session: %w", err) +} +``` + +### Documentation + +All exported functions and types must have doc comments: + +```go +// Session represents a complete debugging session with recorded events. +type Session struct { + ID string + Events []Event +} + +// NewSession creates a new session with the given parameters. +// It initializes empty event slice and sets current time as start time. +func NewSession(id, path string) *Session { + return &Session{ + ID: id, + Events: make([]Event, 0), + } +} +``` + +### Naming Conventions + +- **Packages**: Lower case, single word preferred +- **Functions**: CamelCase, exported functions capitalized +- **Variables**: camelCase for local variables, CamelCase for exported +- **Constants**: ALL_CAPS with underscores +- **Interfaces**: End with `er` or `or` (Reader, Writer, Filter) + +### Error Handling + +Always wrap errors with context: + +```go +// Good +data, err := os.ReadFile(path) +if err != nil { + return fmt.Errorf("failed to read session file %q: %w", path, err) +} + +// Avoid generic errors +if err != nil { + return err // Loss of context +} +``` + +### Concurrency + +Use proper synchronization primitives: + +```go +// Good: Protected with mutex +func (s *Session) addEvent(e Event) { + s.mu.Lock() + defer s.mu.Unlock() + s.events = append(s.events, e) +} + +// Use channels for communication between goroutines +eventChan := make(chan Event, 100) +go func() { + for event := range eventChan { + s.addEvent(event) + } +}() +``` + +--- + +## Testing + +### Writing Tests + +Test files should be in the same package: + +```go +// math.go +package math + +func Add(a, b int) int { + return a + b +} + +// math_test.go +package math + +import "testing" + +func TestAdd(t *testing.T) { + tests := []struct { + a, b, want int + }{ + {1, 2, 3}, + {0, 0, 0}, + {-1, 1, 0}, + } + + for _, tt := range tests { + got := Add(tt.a, tt.b) + if got != tt.want { + t.Errorf("Add(%d, %d) = %d, want %d", + tt.a, tt.b, got, tt.want) + } + } +} +``` + +### Test Coverage Goals + +- **Critical paths**: >90% coverage +- **Helper functions**: >70% coverage +- **Overall target**: >80% coverage + +### Running Tests + +```bash +# Run all tests +make test + +# Run with coverage +go test -cover ./... + +# Generate coverage report +go test -coverprofile=coverage.out ./... +go tool cover -html=coverage.out + +# Run specific test +go test -run TestName ./path/to/package +``` + +--- + +## Documentation + +### README Updates + +If your change affects user-facing functionality, update the README.md: + +```markdown +### New Feature Name + +Brief description of the feature. + +```lua +-- Example configuration +require("capytrace").setup({ + new_option = true, +}) +``` + +Usage example... +``` + +### Code Comments + +- **Package-level**: Explain the package's purpose +- **Function-level**: Explain what the function does, not how +- **Complex logic**: Explain why, not just what +- **TODO comments**: Format as `// TODO(issue#): description` + +### Example Documentation + +```go +// Package filter provides event filtering and denoising for reducing noise +// from high-frequency cursor movement events. +package filter + +// CursorFilter implements intelligent filtering for cursor movement events. +// It debounces rapid movements and only commits positions after idle detection. +type CursorFilter struct { + // ... +} + +// ProcessEvent filters an incoming event based on debounce and idle rules. +// Returns the event to record, or nil if the event should be filtered. +func (cf *CursorFilter) ProcessEvent(event *models.Event) *models.Event { + // Implementation... +} +``` + +--- + +## Commit Message Guidelines + +Follow the [Conventional Commits](https://www.conventionalcommits.org/) format: + +``` +(): + + + +