SLOPSHOPPER

session-status

Status line showing session time, prompts, and tool calls.

newguardstatusprompttimer
v0.1.0no licenseupdated 2026-10-03liawzishen/claude-code-mods/session-status
A shopper browsing a rack in a slop shop
Preview · a replayed session in a sandbox
claude · ~/work/app · session-status
› fix the failing auth test and add an audit log call ⏺ Read(src/auth.ts) ⎿ Read 6 lines ⏺ Update(src/auth.ts) ⎿ Added 2 lines, removed 1 line ⏺ Bash(bun test) ⎿ 3 pass, 1 fail ● Done. refresh now rejects expired claims and logs an audit event. ✻ Worked for 42s · done 4:20 PM ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── › ? for shortcuts ⚠ session-status: ⏱ 0m · 1 prompts · 9 tools (1 failed)
README

claude-code-mods

Mods that change Claude Code's UI, in the terminal and the desktop app's Code tab. Each folder is one mod: a plugin of function hooks.

ModWhat it does
git-diff-timelineA Git Diff timeline above the prompt. Click one commit to see it or two to compare them, with their commit messages. A Branches tab compares two branches. A GitHub-style "Files changed" panel shows each file's diff.
session-statusA status line with the session's time, prompts and tool calls.

Use them

To load mods in every session, list their folders in the env block of ~/.claude/settings.json. Separate the paths with ; on Windows and : elsewhere:

{
  "env": {
    "CLAUDE_CODE_PLUGIN_DIRS": "C:\\path\\to\\claude-code-mods\\git-diff-timeline;C:\\path\\to\\claude-code-mods\\session-status",
    "CLAUDE_CODE_PLUGIN_DIR_WATCH": "1"
  }
}

A session reads this when it starts. With CLAUDE_CODE_PLUGIN_DIR_WATCH=1, open sessions reload a mod when its files change.

To load a mod for one session only: claude --plugin-dir ./git-diff-timeline.

Make a new mod

my-mod/
  .claude-plugin/plugin.json   { "name": "my-mod", "version": "0.1.0", "description": "..." }
  hooks/hooks.json             { "modules": ["./register.tsx"] }
  hooks/register.tsx           export const register: Register = (on, options) => { ... }

See CLAUDE.md for the rules the engine holds mods to.

Check a mod

claude plugin test ./git-diff-timeline
claude plugin validate ./git-diff-timeline
Source 1 files
hooks/register.tsx 40 lines
1import type { Register } from 'claude-code'
2
3const REFRESH_MS = 30_000
4
5const elapsed = (since: number) => {
6  const minutes = Math.floor((Date.now() - since) / 60_000)
7  return minutes < 60 ? `${minutes}m` : `${Math.floor(minutes / 60)}h${String(minutes % 60).padStart(2, '0')}m`
8}
9
10export const register: Register = on => {
11  let startedAt = Date.now()
12  let prompts = 0
13  let tools = 0
14  let failed = 0
15
16  const line = () =>
17    `⏱ ${elapsed(startedAt)} · ${prompts} prompts · ${tools} tools${failed > 0 ? ` (${failed} failed)` : ''}`
18
19  on('session.start', ($, e, next) => {
20    startedAt = Date.now()
21    $.ui.status(line())
22    $.clock.every(REFRESH_MS, () => $.ui.status(line()))
23    return next(e)
24  })
25
26  on('prompt.submit', ($, e, next) => {
27    prompts += 1
28    $.ui.status(line())
29    return next(e)
30  })
31
32  on('tool.call', async ($, e, next) => {
33    tools += 1
34    const ran = await next(e)
35    if (ran.deny === undefined && ran.isError === true) failed += 1
36    $.ui.status(line())
37    return ran
38  })
39}
40