{"slug": "zero-dependency-time-awareness-for-claude-code-injects-a-throttled-time-block-on", "title": "zero-dependency time awareness for Claude Code. Injects a throttled [⏱ time] block on user prompt and on compaction. No more \"good morning\" when it's already 8pm and you are still in the office.", "summary": "A developer created a zero-dependency Python script that injects a throttled time-awareness block into Claude Code prompts, preventing the AI from greeting users with \"good morning\" when it is actually 8 PM. The script hooks into both UserPromptSubmit and SessionStart events, tracking session age and local time, and re-injects the time block after conversation compaction. Users configure the tool by pointing two hook events in their Claude settings.json to the temporal.py script.", "body_md": "| #!/usr/bin/env python3 | |\n| \"\"\" | |\n| temporal.py — zero-dep time awareness for Claude Code. | |\n| Injects a throttled [⏱ time] block on UserPromptSubmit, and re-injects | |\n| right after a compaction via SessionStart(source=compact). | |\n| State: ~/.claude/.temporal/<session_id>.json | |\n| Env: TEMPORAL_INTERVAL=300 (min secs between injects, 0=always) | |\n| Wire both UserPromptSubmit and SessionStart in settings.json to: | |\n| python3 ~/.claude/hooks/temporal.py | |\n| In ~/.claude/settings.json point these two events at it: | |\n| {\"hooks\": { | |\n| \"UserPromptSubmit\": [{\"matcher\":\"\",\"hooks\":[{\"type\":\"command\",\"command\":\"python3 ~/.claude/hooks/temporal.py\"}]}], | |\n| \"SessionStart\": [{\"matcher\":\"\",\"hooks\":[{\"type\":\"command\",\"command\":\"python3 ~/.claude/hooks/temporal.py\"}]}] | |\n| }} | |\n| \"\"\" | |\n| import json, os, sys, time | |\n| from datetime import datetime, timezone | |\n| from pathlib import Path | |\n| INTERVAL_S = int(os.environ.get(\"TEMPORAL_INTERVAL\", 300)) | |\n| TTL_S = int(os.environ.get(\"TEMPORAL_TTL_DAYS\", 7)) * 86400 | |\n| DIR = Path.home() / \".claude\" / \".temporal\" | |\n| def fmt(s): | |\n| if s < 60: return f\"{s}s\" | |\n| if s < 3600: return f\"{s // 60}m{s % 60:02d}s\" | |\n| return f\"{s // 3600}h{(s % 3600) // 60:02d}m\" | |\n| def emit(event, context): | |\n| # Claude Code reads context from this nested hookSpecificOutput shape | |\n| print(json.dumps({\"hookSpecificOutput\": | |\n| {\"hookEventName\": event, \"additionalContext\": context}})) | |\n| def main(): | |\n| data = json.loads(sys.stdin.read().strip() or \"{}\") | |\n| event = data.get(\"hook_event_name\", \"\") | |\n| DIR.mkdir(parents=True, exist_ok=True) | |\n| for old in DIR.glob(\"*.json\"): # sweep stale sessions | |\n| if time.time() - old.stat().st_mtime > TTL_S: | |\n| old.unlink(missing_ok=True) | |\n| f = DIR / f\"{data.get('session_id', 'nosession')}.json\" | |\n| s = json.loads(f.read_text()) if f.exists() else {} | |\n| now_ms = int(time.time() * 1000) | |\n| utc, local = datetime.now(timezone.utc), datetime.now().astimezone() | |\n| # setdefault stamps start_ms on first sight so session age survives restarts | |\n| session_s = (now_ms - s.setdefault(\"start_ms\", now_ms)) // 1000 | |\n| stamp = (f\"now={local:%H:%M} {local:%Z} | utc={utc:%Y-%m-%dT%H:%M:%SZ} | \" | |\n| f\"unix_ms={now_ms} | session={fmt(session_s)}\") | |\n| if event == \"UserPromptSubmit\": | |\n| # only inject once per INTERVAL_S window | |\n| if (now_ms - s.get(\"last_inject_ms\", 0)) // 1000 >= INTERVAL_S: | |\n| s[\"last_inject_ms\"] = now_ms | |\n| emit(event, f\"[⏱ {stamp}]\") | |\n| elif event == \"SessionStart\" and data.get(\"source\") == \"compact\": | |\n| emit(event, f\"[⏱ post-compaction time check — {stamp}]\") | |\n| f.write_text(json.dumps(s)) | |\n| if __name__ == \"__main__\": | |\n| main() |", "url": "https://wpnews.pro/news/zero-dependency-time-awareness-for-claude-code-injects-a-throttled-time-block-on", "canonical_source": "https://gist.github.com/asakin/e4225721bb8f16dd6bc34f4eec5499f9", "published_at": "2026-05-23 03:40:22+00:00", "updated_at": "2026-05-25 20:04:25.079396+00:00", "lang": "en", "topics": ["ai-tools", "ai-products", "large-language-models"], "entities": ["Claude Code", "temporal.py"], "alternates": {"html": "https://wpnews.pro/news/zero-dependency-time-awareness-for-claude-code-injects-a-throttled-time-block-on", "markdown": "https://wpnews.pro/news/zero-dependency-time-awareness-for-claude-code-injects-a-throttled-time-block-on.md", "text": "https://wpnews.pro/news/zero-dependency-time-awareness-for-claude-code-injects-a-throttled-time-block-on.txt", "jsonld": "https://wpnews.pro/news/zero-dependency-time-awareness-for-claude-code-injects-a-throttled-time-block-on.jsonld"}}