SLOPSHOPPER

caffeinate

Keeps the Mac awake while the main agent, subagents or monitors are working.

newguardprocesstimeragents
★ 8v0.1.0no licenseupdated 2026-10-12pkissling/dotfiles/claude/mods/caffeinate
A shopper browsing a rack in a slop shop
README

dotfiles

Lint Secrets

🚀 Overview

Welcome to my dotfiles repository! This collection represents my curated development environment setup enabling me to work efficiently across various projects and technologies. The configurations included in this repository are tailored to my personal preferences and workflows, but feel free to use them as a starting point for your own setup.

🛠️ Tools & Configurations

Below is a comprehensive overview of the tools and their configurations included in this repository:

$ git clone git@github.com:pkissling/dotfiles.git
$ tree dotfiles
.
├── atuin
│   └── # https://atuin.sh - Powerful shell history manager
├── brew
│   └── # https://brew.sh/ - macOS package manager
├── claude
│   └── # https://claude.ai - AI-powered coding agent by Anthropic
├── codex
│   └── # https://openai.com/codex - AI-powered coding agent by OpenAI
├── eza
│   └── # https://github.com/ogham/exa - Modern replacement for ls
├── ghostty
│   └── # https://ghostty.org - Modern terminal emulator
├── git
│   └── # https://git-scm.com/ - Version control system
├── gnupg
│   └── # https://gnupg.org - Encryption and signing tools
├── hunk
│   └── # https://github.com/modem-dev/hunk - Terminal diff viewer for code review
├── mise
│   └── # https://mise.jdx.dev - Runtime version manager
├── nvim
│   └── # https://neovim.io - Modern Vim editor
├── ssh
│   └── # - Secure shell configuration
├── starship
│   └── # https://starship.rs - Minimal, fast shell prompt
├── vscode
│   └── # https://code.visualstudio.com - Code editor
├── zed
│   └── # https://zed.dev - Modern code editor
└── zsh
    └── # https://ohmyz.sh - Shell environment

Each tool in this collection comes with its own install.sh script, allowing for modular installation and configuration. This modular approach enables you to pick and choose which components you'd like to integrate into your environment.

🖼️ Visual Tour

Terminal Environment

A terminal setup featuring Ghostty, zsh, and Starship prompt,

ghostty with zsh and Starship

Neovim Configuration

nvim

🚀 Quick Start

To install all configurations, simply run:

make

For individual tool installations, navigate to the respective directory and run its install.sh script.

Source 1 files
hooks/register.ts 82 lines
1import type {
2  EngineInterface as Engine,
3  HookStream,
4  ProcessSpawnChunk,
5  ProcessSpawnResult,
6  Register,
7} from "claude-code";
8
9const MIN = 60_000;
10const TURN_MS = 120 * MIN;
11const AGENT_MS = 60 * MIN;
12const MONITOR_DEFAULT_MS = 5 * MIN;
13const MONITOR_MAX_MS = 30 * MIN;
14
15const leases = new Map<string, number>();
16let child: HookStream<ProcessSpawnChunk, ProcessSpawnResult> | undefined;
17
18function sync($: Engine) {
19  const now = Date.now();
20  for (const [key, until] of leases) if (until <= now) leases.delete(key);
21  if (leases.size === 0) {
22    void child?.return(undefined as never);
23    child = undefined;
24    return;
25  }
26  if (child) return;
27  // -t is a backstop in case the release is ever missed; the mod kills it sooner.
28  const spawned = $.process.spawn({
29    argv: ["caffeinate", "-i", "-s", "-t", String(TURN_MS / 1000)],
30  });
31  child = spawned;
32  void (async () => {
33    try {
34      for await (const _ of spawned);
35    } catch {}
36    if (child === spawned) child = undefined;
37  })();
38}
39
40function hold($: Engine, key: string, ms: number) {
41  leases.set(key, Math.max(leases.get(key) ?? 0, Date.now() + ms));
42  sync($);
43}
44
45function release($: Engine, key: string) {
46  leases.delete(key);
47  sync($);
48}
49
50export const register: Register = (on) => {
51  on("session.start", async ($, e, next) => {
52    $.clock.every(MIN, () => sync($));
53    return next(e);
54  });
55
56  on("turn.start", ($, e, next) => {
57    hold($, "main", TURN_MS);
58    return next(e);
59  });
60
61  on("turn.complete", ($, e, next) => {
62    release($, e.agentId ?? "main");
63    return next(e);
64  });
65
66  on("agent.spawn", async ($, e, next) => {
67    const spawned = await next(e);
68    if ("agentId" in spawned && spawned.agentId)
69      hold($, spawned.agentId, AGENT_MS);
70    return spawned;
71  });
72
73  on("tool.call", { tool: "Monitor" }, async ($, e, next) => {
74    hold(
75      $,
76      e.tool_use_id,
77      Math.min(e.timeout_ms ?? MONITOR_DEFAULT_MS, MONITOR_MAX_MS),
78    );
79    return next(e);
80  });
81};
82