@taylorsatula/pi-timestamp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,62 @@
1
+ # @taylorsatula/pi-timestamp
2
+
3
+ Timestamp injection extension for [Pi](https://pi.dev) — the model always knows what time it is.
4
+
5
+ ## What it does
6
+
7
+ Hooks `before_provider_request` and appends a synthetic tool-call pair to the outgoing message list, carrying the current local wall-clock time:
8
+
9
+ ```jsonc
10
+ [
11
+ {
12
+ "role": "assistant",
13
+ "tool_calls": [
14
+ {
15
+ "id": "ts_1756220400000",
16
+ "type": "function",
17
+ "function": { "name": "__timestamp", "arguments": "{\"timestamp\":\"[3:00pm - 8/26/25]\"}" }
18
+ }
19
+ ]
20
+ },
21
+ { "role": "tool", "tool_call_id": "ts_1756220400000", "content": "ok" }
22
+ ]
23
+ ```
24
+
25
+ Injection happens only at **turn boundaries**, not on every provider call:
26
+
27
+ - Last message is a **user message** → inject.
28
+ - Last message is an **assistant message with text content** (a vocalization between tool steps) → inject.
29
+ - Last message is an assistant message with only `tool_calls`, or a tool result (mid-turn churn) → skip.
30
+
31
+ This keeps the timestamp fresh each time control returns to the user-facing side of the loop, without spamming intermediate tool-loop requests.
32
+
33
+ ## Installation
34
+
35
+ ```bash
36
+ pi install npm:@taylorsatula/pi-timestamp
37
+ ```
38
+
39
+ Or add to `~/.pi/agent/settings.json` under `packages`:
40
+
41
+ ```json
42
+ {
43
+ "packages": ["npm:@taylorsatula/pi-timestamp"]
44
+ }
45
+ ```
46
+
47
+ ## Notes
48
+
49
+ - Timestamps use the machine's **local time**, formatted `h:mmam/pm - M/D/YY` (e.g. `[3:07pm - 8/26/25]`).
50
+ - No tools, commands, shortcuts, or settings are registered — the extension is invisible except for the injected messages.
51
+ - The injected pair is added to the outgoing payload only; it is not persisted to the session transcript.
52
+
53
+ ## Development
54
+
55
+ ```bash
56
+ npm install
57
+ npm run check # tsc --noEmit
58
+ ```
59
+
60
+ ## License
61
+
62
+ MIT
@@ -0,0 +1,65 @@
1
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
+
3
+ function formatTimestamp(): string {
4
+ const now = new Date();
5
+ let hours = now.getHours();
6
+ const minutes = now.getMinutes();
7
+ const ampm = hours >= 12 ? "pm" : "am";
8
+ hours = hours % 12;
9
+ if (hours === 0) hours = 12;
10
+ const month = now.getMonth() + 1;
11
+ const day = now.getDate();
12
+ const year = String(now.getFullYear()).slice(-2);
13
+ return `[${hours}:${String(minutes).padStart(2, "0")}${ampm} - ${month}/${day}/${year}]`;
14
+ }
15
+
16
+ function shouldInject(msgs: Array<Record<string, unknown>>): boolean {
17
+ const last = msgs[msgs.length - 1];
18
+ if (!last) return false;
19
+
20
+ // User message → inject
21
+ if (last.role === "user") return true;
22
+
23
+ // Assistant with text content (vocalization) → inject
24
+ // Assistant with only tool_calls (intermediate) → skip
25
+ if (last.role === "assistant") {
26
+ const hasToolCalls = Array.isArray(last.tool_calls) && last.tool_calls.length > 0;
27
+ const hasContent = last.content != null && last.content !== "";
28
+ return !hasToolCalls && hasContent;
29
+ }
30
+
31
+ // Tool results → skip (intermediate)
32
+ return false;
33
+ }
34
+
35
+ export default function (pi: ExtensionAPI) {
36
+ pi.on("before_provider_request", (event) => {
37
+ const payload = event.payload as Record<string, unknown>;
38
+ const msgs = payload.messages as Array<Record<string, unknown>>;
39
+
40
+ if (!shouldInject(msgs)) return;
41
+
42
+ const timestamp = formatTimestamp();
43
+ const callId = `ts_${Date.now()}`;
44
+
45
+ msgs.push(
46
+ {
47
+ role: "assistant",
48
+ tool_calls: [
49
+ {
50
+ id: callId,
51
+ type: "function",
52
+ function: { name: "__timestamp", arguments: JSON.stringify({ timestamp }) },
53
+ },
54
+ ],
55
+ },
56
+ {
57
+ role: "tool",
58
+ tool_call_id: callId,
59
+ content: "ok",
60
+ },
61
+ );
62
+
63
+ return event.payload;
64
+ });
65
+ }
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@taylorsatula/pi-timestamp",
3
+ "version": "0.1.0",
4
+ "description": "Timestamp injection extension for Pi — appends the current wall-clock time as a synthetic tool-call pair to every provider request at turn boundaries, so the model always knows what time it is.",
5
+ "keywords": [
6
+ "pi-package"
7
+ ],
8
+ "type": "module",
9
+ "license": "MIT",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/taylorsatula/pi-timestamp"
13
+ },
14
+ "files": [
15
+ "extensions",
16
+ "README.md"
17
+ ],
18
+ "peerDependencies": {
19
+ "@earendil-works/pi-agent-core": "*",
20
+ "@earendil-works/pi-ai": "*",
21
+ "@earendil-works/pi-coding-agent": "*"
22
+ },
23
+ "devDependencies": {
24
+ "@types/node": "^24.13.3",
25
+ "typescript": "^5.9.3"
26
+ },
27
+ "scripts": {
28
+ "check": "tsc --noEmit"
29
+ },
30
+ "pi": {
31
+ "extensions": [
32
+ "./extensions/timestamp.ts"
33
+ ]
34
+ }
35
+ }