Replace Date.now() with performance.now() for duration measurements (#258)

* Replace Date.now() with performance.now() for duration measurements

- Import performance from node:perf_hooks in all affected files
- Update Timer and ThinkingTimer classes to use performance.now()
- Update activity tracking (markActivity, getIdleMs) to use performance.now()
- Update cache duration measurements to use performance.now()
- Update agent execution timing (cursor, opencode) to use performance.now()
- Update subprocess execution timing to use performance.now()
- Update API performance monitoring to use performance.now()
- Update prep phase timing to use performance.now()
- Update timer.test.ts to mock performance.now() instead of Date.now()

Benefits:
- Monotonic clock immune to system clock adjustments
- Higher precision (microsecond vs millisecond resolution)
- Purpose-built for performance measurement

Fixes #245

* fix lint.

* Round float durations to integers in logging

Preserve original behavior by rounding performance.now() float values
to integers when displaying/logging millisecond durations.

* fix lint.

---------

Co-authored-by: pullfrog[bot] <226033991+pullfrog[bot]@users.noreply.github.com>
Co-authored-by: Robin Tail <robin_tail@me.com>
This commit is contained in:
pullfrog[bot]
2026-02-12 15:26:28 +00:00
committed by pullfrog[bot]
parent a442f766aa
commit b6e6a8976c
8 changed files with 125 additions and 111 deletions
+5 -3
View File
@@ -1,3 +1,5 @@
import { performance } from "node:perf_hooks";
export const DEFAULT_ACTIVITY_TIMEOUT_MS = 60_000;
export const DEFAULT_ACTIVITY_CHECK_INTERVAL_MS = 5_000;
@@ -28,21 +30,21 @@ type WriteFunction = {
};
// module-level activity tracking - allows agents to mark activity on any event
let _lastActivity = Date.now();
let _lastActivity = performance.now();
/**
* mark activity to reset the no-output timeout.
* call this whenever the agent emits any event, even if it isn't logged to stdout.
*/
export function markActivity(): void {
_lastActivity = Date.now();
_lastActivity = performance.now();
}
/**
* get the time since last activity in milliseconds
*/
export function getIdleMs(): number {
return Date.now() - _lastActivity;
return Math.round(performance.now() - _lastActivity);
}
function wrapWrite(original: WriteFunction, onActivity: () => void): WriteFunction {