From adc4e63155697afae8275d0d7f0430fbcee4ea4b Mon Sep 17 00:00:00 2001 From: "Thomas G. Lopes" Date: Wed, 4 Mar 2026 14:22:25 +0000 Subject: [PATCH] timestamps v1 --- AGENTS.md | 10 +++ pi/files/agent/extensions/timestamps.ts | 83 +++++++++++++++++++++++++ pi/files/agent/settings.json | 2 +- 3 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 pi/files/agent/extensions/timestamps.ts diff --git a/AGENTS.md b/AGENTS.md index 86eb83a..a0681a8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -3,6 +3,7 @@ This repo is managed by **Sigil**, a minimal symlink-based dotfile tool. ## Repo layout + ``` ~/.dotfiles/ / @@ -14,6 +15,7 @@ This repo is managed by **Sigil**, a minimal symlink-based dotfile tool. Each package has a `config.lua` that defines its target path per OS. ## Common commands + - `sigil apply` — apply symlinks (prompts for stale links) - `sigil apply --prune` — prune stale links without prompting - `sigil add ` — add a file/dir to the repo and symlink it @@ -22,13 +24,16 @@ Each package has a `config.lua` that defines its target path per OS. - `sigil remove ` — same as unlink, plus remove package/subpath from repo ## Spec formats + `unlink/remove` accept these: + - `package` (entire package) - `package:relative/path` - repo path: `~/.dotfiles//files/...` - target path: e.g. `~/.config//...` Examples: + ``` sigil unlink wezterm sigil unlink wezterm:lua @@ -37,5 +42,10 @@ sigil unlink ~/.config/wezterm/wezterm.lua ``` ## Notes + - If a repo file is missing, stale links should be pruned. - Prefer `sigil add` over manual moves into `files/`. + +# Editing dotfiles + +When editing dotfiles, it is preferred to add/edit the files in this project directly, instead of going to the source. this way we can then use sigil apply --prune, and everything will be synced, even when there are new files. diff --git a/pi/files/agent/extensions/timestamps.ts b/pi/files/agent/extensions/timestamps.ts new file mode 100644 index 0000000..8b76fa4 --- /dev/null +++ b/pi/files/agent/extensions/timestamps.ts @@ -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 | 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; + } + }); +} diff --git a/pi/files/agent/settings.json b/pi/files/agent/settings.json index c6fd53a..b77c960 100644 --- a/pi/files/agent/settings.json +++ b/pi/files/agent/settings.json @@ -1,7 +1,7 @@ { "lastChangelogVersion": "0.55.4", "defaultProvider": "openrouter", - "defaultModel": "z-ai/glm-5", + "defaultModel": "moonshotai/kimi-k2.5", "defaultThinkingLevel": "off", "theme": "matugen" } \ No newline at end of file