Codaro PRO VS Code Extension
Codaro is a SaaS platform that supports engineering managers and development teams. It automatically tracks real coding activity in the IDE (heartbeats, code changes), translates it into easy-to-understand reports, and recommends the next tasks tailored to each developer's skills.
Features
Time Tracking
- Automatic tracking of coding activity
- Heartbeat-based activity detection
- Real-time statistics and reporting
Active Editing Sessions (New!)
- Real-time editing session signals (
editingStarted and editingStopped events)
- Configurable focus timeout for session detection
- Secure transport with HMAC authentication
- Offline queuing with exponential backoff retry
Configuration
Active Editing Settings
The Active Editing feature can be configured in VS Code settings:
Core Settings
codaro.activeEditing.enabled (boolean, default: true)
- Enable real-time Active Editing signals
codaro.activeEditing.stopThresholdSeconds (number, default: 10)
- Threshold in seconds before emitting
editingStopped when focus is lost (5-60 seconds)
Network Settings
codaro.activeEditing.endpoint (string, default: alerts API URL)
- Endpoint URL for active editing events
- Default:
https://codaro-alerts-api-515220727809.europe-central2.run.app/events/editing
- Rate Limiting: 10 requests per 5 seconds (global, automatic)
- Timeout: 2 seconds per request (automatic)
- Retry: 3 attempts with linear/short exponential backoff (automatic)
Privacy & Security Settings
codaro.activeEditing.dropIfUnknownProjectId (boolean, default: true)
- Drop events when projectId cannot be resolved (prevents database pollution)
codaro.activeEditing.sensitiveGlobs (array, default: [])
- Custom glob patterns for sensitive files to exclude from tracking
- Example:
['**/.env*', '**/secrets/**', '**/*.key']
codaro.activeEditing.sensitiveGlobsDenylistEnabled (boolean, default: true)
- Enable default sensitive file patterns (set to false to use only custom globs)
codaro.activeEditing.queueMaxSize (number, default: 1000)
- Maximum number of events to queue before dropping oldest (100-10000)
- Memory protection for offline scenarios
Debug Settings
codaro.debug (boolean, default: false)
- Enable detailed diagnostic logging (shows full file paths)
- Use only for troubleshooting
codaro.debugPayload (boolean, default: false)
- Enable payload debug logging (shows payload details without absolute paths)
- Safe for production use
Legacy Settings (Deprecated)
codaro.activeEditingSessions.enabled (boolean, default: true)
- [DEPRECATED] Use
codaro.activeEditing.enabled instead
codaro.activeEditingSessions.focusTimeoutMs (number, default: 10000)
- [DEPRECATED] Use
codaro.activeEditing.stopThresholdSeconds instead
Alerts Payload
Payload V2 Structure (Current)
The extension sends editing events using the new Payload V2 format to the Codaro Alerts API:
{
"userId": "U-123",
"event": "editingStarted",
"filePathHash": "c31e76177da8835a5ed7264762cd1c6244960f020163ec4f97253f7ae88ba644",
"projectRootName": "codaro-app",
"relativePath": "/src/components/payment/PaymentForm.tsx",
"ts": "2025-01-12T11:00:00.000Z"
}
The projectRootName and relativePath fields are only included when a git repository is found:
- ✅ With Git Root: When
.git directory is found, both projectRootName and relativePath are included
- ❌ Without Git Root: When no
.git is found, these fields are omitted entirely
Example with Git Root:
{
"userId": "U-123",
"event": "editingStarted",
"filePathHash": "abc123...",
"projectRootName": "my-project",
"relativePath": "/src/components/Button.tsx",
"ts": "2025-01-12T11:00:00.000Z"
}
Example without Git Root:
{
"userId": "U-123",
"event": "editingStarted",
"filePathHash": "def456...",
"ts": "2025-01-12T11:00:00.000Z"
}
Payload Fields
- userId (string|number): User identifier from extension config
- event (string): Event type -
"editingStarted" or "editingStopped"
- filePathHash (string): SHA-256 hash of normalized file path for privacy
- projectRootName (string, optional): Git repository name (only when git root found)
- relativePath (string, optional): POSIX relative path from git root (only when git root found)
- ts (string): ISO 8601 timestamp in UTC
Privacy Guarantees
- ✅ No Absolute Paths: Absolute file paths are never sent over the network
- ✅ Hashed Identifiers: Only SHA-256 hashes of file paths are transmitted
- ✅ Project Context: Project information only when git repository is detected
- ✅ POSIX Paths: Relative paths always use forward slashes for consistency
Event Mapping
The extension maps VS Code events to API signals as follows:
Event Mappings
- Open Document →
editingStarted (immediate)
- Save Document →
editingStarted (throttled, 2s per file)
- Close Document →
editingStopped (immediate)
Throttling
- Save Events: Maximum 1
editingStarted per 2 seconds per file
- Purpose: Prevents flooding API with rapid save events (autosave)
- Behavior: Subsequent saves within 2s are throttled and sent after delay
Network Configuration
Rate Limiting
- Global Limit: 10 requests per 5 seconds (across all events)
- Algorithm: Leaky bucket with sliding window
- Behavior: Requests are delayed when limit exceeded (preferred over dropping)
Timeout & Retry
- Request Timeout: 2 seconds
- Max Retries: 3 attempts
- Backoff Strategy: Linear/short exponential (200ms → 500ms → 1000ms + jitter)
- Retry Triggers: 5xx errors, timeouts, network errors
- No Retry: 4xx client errors (authentication, bad request)
Authentication
- Method: Device credentials (reuses existing heartbeat authentication)
- Headers: Standard HTTP headers (no JWT required)
- Endpoint:
https://codaro-alerts-api-515220727809.europe-central2.run.app/events/editing
Privacy & Logging
The extension follows a strict privacy-first logging policy:
Logging Policy
- Default Mode: Only essential errors and warnings are logged
- No Absolute Paths: Absolute file paths are never exposed in logs
- Safe Identifiers: File information shown as
{project:app, path:/src/file.js, hash:...a1b2c3d4}
- Minimal Output: By default, logs are quiet and don't expose sensitive information
Debug Settings
codaro.debug (boolean, default: false)
- Purpose: Enable detailed diagnostic logging
- When Enabled: Shows full file paths and detailed system information
- Use Case: Troubleshooting and development only
- Warning: May expose sensitive file paths
codaro.debugPayload (boolean, default: false)
- Purpose: Enable payload debug logging
- When Enabled: Shows payload details without absolute paths
- Format:
{project:app, path:/src/file.js, hash:...a1b2c3d4}
- Use Case: Debugging payload structure and content
Privacy Protection
- Safe File Identifiers: Files shown as
{project:name, path:/relative/path, hash:...last8chars}
- No Absolute Paths: Absolute file paths never appear in logs
- Project Context: Project information only when git repository found
- Sensitive File Exclusion: Sensitive files automatically excluded from tracking
- User ID Protection: User IDs not logged in plain text
Logging Levels
- Info Logs: State transitions and essential operations (always shown)
- Debug Logs: Detailed information including file paths (only when
codaro.debug: true)
- Error Logs: Error information with masked file paths (always shown)
Data Protection
- No PII in Logs: Personal information is never logged
- File Path Hashing: File paths are hashed before any logging
- Minimal Exposure: Only necessary information is logged for debugging
This approach ensures that logs are useful for troubleshooting while protecting user privacy and sensitive project information.
ActiveEditingSender
The extension includes a robust ActiveEditingSender class that handles secure transmission of editing events with built-in resilience and offline support.
Features
Secure Transport
- HMAC Authentication: Each payload is signed with device secret and timestamp
- Device Credentials: Reuses existing device registration from heartbeat system
- Timestamp Headers: Includes
X-Timestamp and X-Signature headers for backend validation
- Configurable Endpoint: Uses
codaro.activeEditing.endpoint setting (if empty, derived from heartbeat base URL)
Persistent Queue & Retry
- Offline Support: Events are queued in extension global storage when offline
- Exponential Backoff: Retry failed requests with bounded exponential backoff (1s → 2s → 4s → 8s → 16s → 30s max)
- Error Classification:
- 4xx errors (auth/signature) → Permanent failure, no retry
- 5xx errors (server) → Temporary failure, retry with backoff
- Network errors → Temporary failure, retry with backoff
- Max Retries: 3 attempts per event before permanent removal
- Jitter: Random variation up to 1 second to prevent thundering herd
Ordering Guarantees
- Best-Effort Per-File: New events for the same file replace queued events to maintain logical ordering
- Non-Blocking: All operations are asynchronous and never block the UI thread
- Queue Processing: Background processor runs every 5 seconds to retry failed events
Queue Flush Policy
- Immediate Flush on Activation: All queued events are immediately flushed when the extension activates
- Network Reconnection Detection: Automatic detection of network reconnection with immediate queue flush
- Periodic Flush: Regular queue flush every 2 minutes to ensure events don't get stuck
- Network Monitoring: Checks network connectivity every 30 seconds for faster reconnection detection
- Offline Resilience: Events are queued when offline and automatically sent when connection is restored
Structured Logging
- Privacy-Safe: File paths are masked in logs (shows only last 8 characters of hash)
- Level-Gated: Debug logs only shown when
codaro.debug: true
- Minimal Logging: By default, only essential errors and warnings are logged
- No PII: When debug is disabled, no absolute file paths or sensitive information is logged
- Diagnostic Info: Queue statistics, retry counts, and error details for troubleshooting (debug mode only)
Usage
import { ActiveEditingSender } from './activeEditingSender';
import { PayloadBuilder } from './payloadBuilder';
// Initialize with VS Code context
const sender = ActiveEditingSender.getInstance();
sender.initialize(context);
// Send editing events
const payload = PayloadBuilder.buildEditingStartedPayload('/path/to/file.js');
const result = await sender.sendEvent(payload);
// Check queue status
const stats = sender.getQueueStats();
console.log(`Queue: ${stats.totalEvents} events pending`);
Queue Statistics
The sender provides detailed queue statistics for monitoring:
{
totalEvents: number; // Total events in queue
eventsByFile: Record<string, number>; // Events per file (masked paths)
retryDistribution: Record<number, number>; // Events by retry count
oldestEvent: number | null; // Timestamp of oldest queued event
}
QA Commands
For testing and debugging purposes, the extension provides two QA commands:
Toggle Active Editing
- Command:
Codaro: Toggle Active Editing
- Purpose: Quickly toggle the Active Editing feature on/off at runtime
- Behavior:
- Flips the feature flag immediately
- Shows a toast notification with current state
- Clears all active sessions when disabled
Show Active Editing Debug
- Command:
Codaro: Show Active Editing Debug
- Purpose: Opens a debug panel with detailed state information
- Information Displayed:
- Current enabled/disabled status
- Per-file session state (armed|editing|timer)
- Time remaining until session stops
- Queue length for pending events
- Last 10 event payloads (with masked sensitive data)
- Session details (start time, last edit time, etc.)
These commands are useful for QA testing, debugging issues, and monitoring the extension's behavior in real-time.
Path Normalization
The extension includes robust path normalization to ensure consistent behavior across different platforms and avoid hash collisions:
Features
- Cross-platform compatibility: Handles Windows and Unix path formats consistently
- Symlink resolution: Resolves symbolic links where possible for stable identifiers
- Drive letter normalization: Lowercases Windows drive letters (C:/ → c:/)
- Path separator normalization: Converts backslashes to forward slashes
- Trailing slash removal: Removes unnecessary trailing slashes
- Relative path resolution: Resolves
./ and ../ components appropriately
Hash Consistency
- Identical logical paths produce identical SHA-256 hashes regardless of platform
- Path variations (e.g.,
path/to/file.js vs path\to\file.js) generate the same hash
- Windows drive letter case differences are normalized before hashing
- Symlinks are resolved to their target paths for consistent identification
This ensures that file tracking works reliably across different operating systems and development environments.
Error Handling Policy
The extension implements a sophisticated error handling policy for Active Editing events to ensure reliable operation and user experience:
Error Classification
Retry Configuration
- Base Delay: 1 second
- Exponential Factor: 2x per retry
- Maximum Delay: 30 seconds
- Jitter: Up to 1 second random variation
- Maximum Retries: 3 attempts
Endpoint Configuration
- Primary: Uses
codaro.activeEditing.endpoint setting
- Fallback: Builds from heartbeat base URL (
https://codaro.dev/api/active-editing)
- Dynamic: Automatically switches between configured and default endpoints
This policy ensures that temporary issues don't cause data loss while preventing infinite retry loops for permanent failures.
Privacy & Data Collection
What We Collect
The Active Editing feature collects only metadata about editing sessions - we do NOT record:
- ❌ Raw keystrokes or individual key presses
- ❌ Actual file contents or code
- ❌ Full file paths (only hashed identifiers)
- ❌ Personal information beyond anonymous user ID
What We Do Track
- ✅ Event types (
editingStarted/editingStopped)
- ✅ File path hashes (SHA-256) for identification
- ✅ Project/repository identifiers
- ✅ Timestamps of editing sessions
- ✅ Anonymous user identifiers
Privacy Statement: We do not record raw keystrokes or full file contents for these events. This approach allows teams to understand coding patterns and productivity without compromising code confidentiality or violating developer privacy.
Registration and Configuration
To register and configure your account, visit codaro.dev