SLOPSHOPPER

long-command

A toast when a shell command that ran over 45 seconds finishes

newguardtoast
v0.1.0no licenseupdated 2026-10-02amir20/.dotfiles/claude/.claude/mods/long-command
A shopper browsing a rack in a slop shop
README

dotfiles

Source 2 files
hooks/register.ts 19 lines
1import type { Register } from 'claude-code'
2
3import { label } from './label'
4
5const LONG_MS = 45_000
6
7export const register: Register = on => {
8  on('tool.call', { tool: 'Bash' }, async ($, e, next) => {
9    const started = await $.clock.now()
10    const ran = await next(e)
11    const ms = (await $.clock.now()) - started
12    if (ms >= LONG_MS && ran.deny === undefined) {
13      const mark = ran.isError ? '✗' : '✓'
14      $.ui.toast(`${mark} ${label(e.command)} — ${Math.round(ms / 1000)}s`, { timeoutMs: 10_000 })
15    }
16    return ran
17  })
18}
19
hooks/label.ts 7 lines
1/** A short name for a command: the part after the last `cd … &&`, cut to 40 chars. */
2export function label(command: string): string {
3  const parts = command.split(/&&|;/).map(s => s.trim()).filter(s => s && !s.startsWith('cd '))
4  const last = (parts[parts.length - 1] ?? command).split('\n')[0]
5  return last.length > 40 ? `${last.slice(0, 39)}…` : last
6}
7