SLOPSHOPPER

where-am-i

Pins the checked-out branch and the repo/worktree folder to the status line under the prompt.

newguardstatusprocess
v0.1.0no licenseupdated 2026-10-16HikiJun97/claude-mods/where-am-i
A shopper browsing a rack in a slop shop
Preview · a replayed session in a sandbox
claude · ~/work/app · where-am-i
› 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 ⚠ where-am-i: ⎇ feat/auth-refresh · › a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0
Source 1 files
hooks/register.ts 47 lines
1import type { EngineInterface, Register } from 'claude-code'
2
3async function git($: EngineInterface, args: string[]): Promise<string | undefined> {
4  const { exitCode, stdout } = await $.process.run(['git', ...args])
5  return exitCode === 0 ? stdout.trim() : undefined
6}
7
8// "⎇ <branch>  ·  <repo>" in the main checkout, "⎇ <branch>  ·  <repo> › <worktree>" in a linked worktree.
9export async function locate($: EngineInterface): Promise<string | undefined> {
10  const paths = await git($, ['rev-parse', '--path-format=absolute', '--show-toplevel', '--git-dir', '--git-common-dir'])
11  if (paths === undefined) return undefined
12
13  const [top = '', gitDir, commonDir = ''] = paths.split('\n')
14  const repo = commonDir.replace(/\/\.git\/?$/, '').split('/').pop()
15  const folder = top.split('/').pop()
16  const place = gitDir === commonDir ? repo : `${repo} › ${folder}`
17  const branch = (await git($, ['branch', '--show-current'])) || `detached ${await git($, ['rev-parse', '--short', 'HEAD'])}`
18
19  return `⎇ ${branch}  ·  ${place}`
20}
21
22async function refresh($: EngineInterface): Promise<void> {
23  $.ui.status(await locate($))
24}
25
26export const register: Register = on => {
27  on('session.start', async ($, e, next) => {
28    const started = await next(e)
29    await refresh($)
30    return started
31  })
32
33  // A Bash call may check out another branch.
34  on('tool.call', { tool: 'Bash' }, async ($, e, next) => {
35    const ran = await next(e)
36    await refresh($)
37    return ran
38  }).catch(($, e, next) => next(e)) // a failed refresh never blocks the command
39
40  // Catches what changed outside a tool call, such as a `!` command or another terminal.
41  on('turn.complete', async ($, e, next) => {
42    const done = await next(e)
43    if (e.agentId === undefined) await refresh($)
44    return done
45  })
46}
47