-
-
Notifications
You must be signed in to change notification settings - Fork 119
Description
Summary
Add optional integrations for WakaTime and ActivityWatch to collect editor usage/heartbeat data from Ox. These should be opt-in, configurable, and privacy-respecting. The integrations will let users track time spent in Ox with WakaTime or locally with ActivityWatch.
Motivation
- Many users rely on WakaTime or ActivityWatch to track coding activity and productivity.
- Adding first-class or plugin-friendly support improves Ox adoption and provides parity with other editors.
- ActivityWatch (local) gives privacy-conscious users offline tracking; WakaTime gives cloud-based analytics and ecosystem integrations.
Proposed behavior
- Provide two optional integrations: wakatime and activitywatch.
- Send heartbeats on activity events (open file, focus buffer, save, edit) with configurable heartbeat interval and idle timeout.
- Allow users to mask/mangle file paths (e.g., only send project name) to protect privacy.
- All telemetry must be opt-in. Default: disabled.
Suggested configuration API (example)
Provide either a config file section or plugin options:
integrations:
wakatime:
enabled: true
api_key: "<YOUR_WAKATIME_API_KEY>"
project: "Ox"
ide_name: "Ox"
send_full_path: false
heartbeat_interval_sec: 120
idle_timeout_sec: 120
activitywatch:
enabled: true
host: "http://localhost:5600"
bucket: "org.curlpipe.ox"
send_full_path: false
heartbeat_interval_sec: 120
idle_timeout_sec: 120
Implementation details / suggestions
- Make integrations pluggable (core provides integration hooks, implementation lives in separate module/plugin).
- Events to hook:
- buffer_open / buffer_focus
- buffer_edit (typing)
- buffer_save
- buffer_close
- editor_idle/resume (use internal idle detection)
- WakaTime:
- Post heartbeat events to WakaTime API: include entity (file path or project), type (file), category (coding), language, project, is_write flag when save occurs, timestamp.
- Use the user's API key and allow users to override the ide name.
- Respect WakaTime rate and batching guidance (send heartbeats at intervals or on save).
- ActivityWatch:
- Post events to the local ActivityWatch server (default http://localhost:5600) to the configured bucket.
- Create a bucket for Ox (unique bucket name).
- Send minimal event payload (timestamp, document/project, event type).
- Use ActivityWatch recommended client endpoints and event format.
- Error handling:
- Fail silently (log debug) if the endpoint is unreachable.
- Backoff when errors occur.
Privacy and security
- Must be explicit opt-in for either integration.
- Provide options to:
- Mask file paths (send only project name)
- Disable sending language/file names
- Configure heartbeat frequency and idle timeout
- Document where data is sent: WakaTime (third-party cloud) vs ActivityWatch (local).
- Never send API keys to third parties except the designated service (only WakaTime should get the WakaTime key).
Acceptance criteria
- Users can enable/disable WakaTime and ActivityWatch via config.
- Heartbeats occur for the main editor events listed above.
- Users can mask file paths and configure intervals/timeouts.
- Integration logs errors at debug level without interrupting the editor.
- Documentation and quickstart show how to set up both integrations.
- Minimal tests for heartbeat scheduling, masking behavior, and error handling.
Alternatives / scope notes
- Option A: Provide as built-in feature toggled off by default.
- Option B (recommended): Provide integrations as official plugins to keep core small and let contributors iterate faster.
- Consider implementing ActivityWatch first (local, privacy-first) and WakaTime as a separate plugin.
Example usage / config snippet (copyable)
See the configuration section above. (Put actual config in README under “Integrations” with sample env vars and CLI examples.)
Helpful links (for implementers)
- WakaTime API docs (developers.wakatime.com)
- ActivityWatch docs (activitywatch.net/docs) — client/server endpoints and event format
Requested maintainer guidance
- Preferred approach: plugin vs core?
- Any existing integration patterns (where similar features live) to follow?
- Is there a preferred config location / format for integrations?