Root Cause
vscode_parser._parse_vscode_log_from_offset parses timestamps with datetime.fromisoformat(ts_str), where ts_str is extracted from log lines like 2024-01-15 10:30:45.123. Because the log format contains no UTC offset or timezone designator, fromisoformat returns a naive datetime (no tzinfo).
These naive timestamps propagate to:
VSCodeRequest.timestamp: datetime — stored in every parsed request
VSCodeLogSummary.first_timestamp: datetime | None
VSCodeLogSummary.last_timestamp: datetime | None
The rest of the codebase (models.py) uses aware datetimes throughout, with ensure_aware() attached to UTC whenever a datetime is produced or compared. SessionSummary.start_time, end_time, last_resume_time, etc. are all aware.
Impact
Mixing naive and aware datetimes raises TypeError: can't compare offset-naive and offset-aware datetimes at runtime. Currently this doesn't happen because vscode timestamps are only used within the vscode subsystem (formatted for display in vscode_report.py, compared with each other in _update_vscode_summary). But:
- The type annotation
datetime on VSCodeRequest.timestamp and VSCodeLogSummary.first_timestamp/last_timestamp gives callers no indication that these are naive — anyone who compares them with a SessionSummary timestamp would get a runtime TypeError.
- Merging vscode summaries with session summaries (a likely future feature) would silently surface this latent bug.
- The codebase has an established convention: all
datetime values at module boundaries are aware UTC. VSCodeRequest and VSCodeLogSummary violate this contract.
Investigation Required
The VS Code log timestamps use the local system time (not UTC), so simply calling ensure_aware() (which assumes UTC) would produce incorrect wall-clock values. The correct fix requires one of:
- Attach local timezone: use
datetime.fromisoformat(ts_str).astimezone(UTC) to convert local time → UTC (correct, but requires datetime.astimezone() which adds local_timezone overhead).
- Document as local-naive, isolate them: keep timestamps naive but add a
LocalNaiveDatetime type alias or a wrapper dataclass field with a docstring/comment explicitly marking them as local-time naive, and add a lint guard preventing comparison with aware datetimes outside the vscode subsystem.
- Store as UTC from the moment of parsing and accept that the display format will show UTC instead of local time. Evaluate whether this matters for
vscode_report.py display.
Option 1 is the cleanest. After conversion, VSCodeRequest.timestamp and VSCodeLogSummary.first/last_timestamp become aware UTC datetimes, consistent with the rest of the codebase, and vscode_report.py's strftime calls will continue working correctly (UTC times are still reasonable for a usage report).
Fix Specification
In _parse_vscode_log_from_offset, replace:
ts = datetime.fromisoformat(ts_str)
with:
ts = datetime.fromisoformat(ts_str).astimezone(UTC)
and add from datetime import UTC to the existing import if not already present (it is already imported in models.py).
Testing Requirements
Add tests to test_vscode_parser.py:
test_parsed_request_timestamp_is_aware: parse a synthetic log line and assert req.timestamp.tzinfo is not None.
test_vscode_summary_timestamps_are_aware: call build_vscode_summary([req]) and assert summary.first_timestamp.tzinfo is not None and summary.last_timestamp.tzinfo is not None.
test_vscode_timestamps_comparable_with_session_timestamps: compare VSCodeLogSummary.first_timestamp with a known aware datetime to verify no TypeError is raised.
Existing tests that compare vscode timestamps should continue to pass after the conversion (they test relative ordering, not absolute UTC values).
Generated by Code Health Analysis · ● 5.4M · ◷
Root Cause
vscode_parser._parse_vscode_log_from_offsetparses timestamps withdatetime.fromisoformat(ts_str), wherets_stris extracted from log lines like2024-01-15 10:30:45.123. Because the log format contains no UTC offset or timezone designator,fromisoformatreturns a naivedatetime(notzinfo).These naive timestamps propagate to:
VSCodeRequest.timestamp: datetime— stored in every parsed requestVSCodeLogSummary.first_timestamp: datetime | NoneVSCodeLogSummary.last_timestamp: datetime | NoneThe rest of the codebase (
models.py) uses aware datetimes throughout, withensure_aware()attached toUTCwhenever a datetime is produced or compared.SessionSummary.start_time,end_time,last_resume_time, etc. are all aware.Impact
Mixing naive and aware datetimes raises
TypeError: can't compare offset-naive and offset-aware datetimesat runtime. Currently this doesn't happen because vscode timestamps are only used within the vscode subsystem (formatted for display invscode_report.py, compared with each other in_update_vscode_summary). But:datetimeonVSCodeRequest.timestampandVSCodeLogSummary.first_timestamp/last_timestampgives callers no indication that these are naive — anyone who compares them with aSessionSummarytimestamp would get a runtimeTypeError.datetimevalues at module boundaries are aware UTC.VSCodeRequestandVSCodeLogSummaryviolate this contract.Investigation Required
The VS Code log timestamps use the local system time (not UTC), so simply calling
ensure_aware()(which assumes UTC) would produce incorrect wall-clock values. The correct fix requires one of:datetime.fromisoformat(ts_str).astimezone(UTC)to convert local time → UTC (correct, but requiresdatetime.astimezone()which addslocal_timezoneoverhead).LocalNaiveDatetimetype alias or a wrapper dataclass field with a docstring/comment explicitly marking them as local-time naive, and add a lint guard preventing comparison with aware datetimes outside the vscode subsystem.vscode_report.pydisplay.Option 1 is the cleanest. After conversion,
VSCodeRequest.timestampandVSCodeLogSummary.first/last_timestampbecome aware UTC datetimes, consistent with the rest of the codebase, andvscode_report.py'sstrftimecalls will continue working correctly (UTC times are still reasonable for a usage report).Fix Specification
In
_parse_vscode_log_from_offset, replace:with:
and add
from datetime import UTCto the existing import if not already present (it is already imported inmodels.py).Testing Requirements
Add tests to
test_vscode_parser.py:test_parsed_request_timestamp_is_aware: parse a synthetic log line and assertreq.timestamp.tzinfo is not None.test_vscode_summary_timestamps_are_aware: callbuild_vscode_summary([req])and assertsummary.first_timestamp.tzinfo is not Noneandsummary.last_timestamp.tzinfo is not None.test_vscode_timestamps_comparable_with_session_timestamps: compareVSCodeLogSummary.first_timestampwith a known awaredatetimeto verify noTypeErroris raised.Existing tests that compare vscode timestamps should continue to pass after the conversion (they test relative ordering, not absolute UTC values).