timestamps v1
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* Timestamps extension for Pi.
|
||||
*
|
||||
* - Shows elapsed session time in footer (updates every second)
|
||||
* - Shows how long the last turn took (from your message to agent completion)
|
||||
*/
|
||||
|
||||
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
||||
|
||||
// Track session time and turn durations
|
||||
let sessionStart = Date.now();
|
||||
let timerHandle: ReturnType<typeof setInterval> | null = null;
|
||||
let turnStartTime: number | null = null;
|
||||
let lastTurnDuration: number | null = null;
|
||||
|
||||
function formatElapsed(ms: number): string {
|
||||
const seconds = Math.floor(ms / 1000);
|
||||
const minutes = Math.floor(seconds / 60);
|
||||
const hours = Math.floor(minutes / 60);
|
||||
|
||||
if (hours > 0) {
|
||||
return `${hours}h ${minutes % 60}m`;
|
||||
} else if (minutes > 0) {
|
||||
return `${minutes}m ${seconds % 60}s`;
|
||||
} else {
|
||||
return `${seconds}s`;
|
||||
}
|
||||
}
|
||||
|
||||
function formatDuration(ms: number): string {
|
||||
if (ms < 1000) return `${ms}ms`;
|
||||
if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
|
||||
return `${(ms / 60000).toFixed(1)}m`;
|
||||
}
|
||||
|
||||
export default function (pi: ExtensionAPI) {
|
||||
const updateStatus = (ctx: { ui: { setStatus: (id: string, text: string | undefined) => void; theme: { fg: (color: string, text: string) => string } } }) => {
|
||||
const elapsed = Date.now() - sessionStart;
|
||||
let status = ctx.ui.theme.fg("dim", `⏱ ${formatElapsed(elapsed)}`);
|
||||
|
||||
// Show last turn duration if available
|
||||
if (lastTurnDuration !== null) {
|
||||
status += ctx.ui.theme.fg("muted", ` | took ${formatDuration(lastTurnDuration)}`);
|
||||
}
|
||||
|
||||
ctx.ui.setStatus("timestamps", status);
|
||||
};
|
||||
|
||||
// Start timer on session start
|
||||
pi.on("session_start", async (_event, ctx) => {
|
||||
sessionStart = Date.now();
|
||||
turnStartTime = null;
|
||||
lastTurnDuration = null;
|
||||
|
||||
// Clear any existing timer
|
||||
if (timerHandle) clearInterval(timerHandle);
|
||||
|
||||
// Update status every second
|
||||
timerHandle = setInterval(() => updateStatus(ctx), 1000);
|
||||
updateStatus(ctx);
|
||||
});
|
||||
|
||||
// Track turn timing
|
||||
pi.on("turn_start", async () => {
|
||||
turnStartTime = Date.now();
|
||||
});
|
||||
|
||||
pi.on("turn_end", async (_event, ctx) => {
|
||||
if (turnStartTime !== null) {
|
||||
lastTurnDuration = Date.now() - turnStartTime;
|
||||
turnStartTime = null;
|
||||
updateStatus(ctx);
|
||||
}
|
||||
});
|
||||
|
||||
// Clean up on shutdown
|
||||
pi.on("session_shutdown", async () => {
|
||||
if (timerHandle) {
|
||||
clearInterval(timerHandle);
|
||||
timerHandle = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user