Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Changelog

## 0.0.14-beta.1 — 2026-07-14
## 0.0.14-beta.1 — 2026-07-16

### Fixes
- Normalize rounded duration units so formatting never emits invalid `60.0s`, `1m 60s`, or `59m 60s` values. (#521)

### Docs
- AgentEye docs: lead the Agent Observability sidebar with a Features group (one page per top-level feature), move Deployment to the last group, and publish the new per-feature pages, autoplaying demo embeds, and an AI assistant screenshot. (#548)
Expand Down
12 changes: 12 additions & 0 deletions __tests__/lib/format-duration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ describe("formatDuration", () => {
expect(formatDuration(3200)).toBe("3.2s");
});

it("rounds seconds up to a minute", () => {
expect(formatDuration(59999)).toBe("1m 0s");
});

it("boundary: exactly 60000ms", () => {
expect(formatDuration(60000)).toBe("1m 0s");
});
Expand All @@ -34,6 +38,14 @@ describe("formatDuration", () => {
expect(formatDuration(312000)).toBe("5m 12s");
});

it("rounds seconds up without emitting 60s", () => {
expect(formatDuration(119600)).toBe("2m 0s");
});

it("rounds minutes up to an hour", () => {
expect(formatDuration(3599600)).toBe("1h 0m");
});

it("boundary: exactly 3600000ms", () => {
expect(formatDuration(3600000)).toBe("1h 0m");
});
Expand Down
11 changes: 8 additions & 3 deletions lib/format-duration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,18 @@ export function formatRelativeTime(ts: number): string {
export function formatDuration(ms: number): string {
if (ms < 1000) return `${ms}ms`;
const seconds = ms / 1000;
if (seconds < 60) return `${seconds.toFixed(1)}s`;
const totalMinutes = Math.floor(seconds / 60);
if (seconds < 60) {
const tenths = Math.round(seconds * 10);
if (tenths < 600) return `${(tenths / 10).toFixed(1)}s`;
}

const totalSeconds = Math.round(seconds);
const totalMinutes = Math.floor(totalSeconds / 60);
if (totalMinutes >= 60) {
const hours = Math.floor(totalMinutes / 60);
const remainingMinutes = totalMinutes % 60;
return `${hours}h ${remainingMinutes}m`;
}
const remainingSeconds = (seconds % 60).toFixed(0);
const remainingSeconds = totalSeconds % 60;
return `${totalMinutes}m ${remainingSeconds}s`;
}