Skip to content
/ cc-dice Public

Probabilistic dice triggers for Claude Code hooks

License

Notifications You must be signed in to change notification settings

pro-vi/cc-dice

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cc-dice

Probabilistic dice triggers for Claude Code hooks.

Register dice slots, and cc-dice rolls them on every Claude Code stop event. Accumulators escalate probability with conversation depth; single/fixed slots give flat odds.

Why

Claude Code sessions are long-running, stateful, and unpredictable, which reminds me of a video game. Very much like a tabletop RPG campaign. In D&D, dice are the core mechanic that makes emergent behavior possible. A Natural 20 happens because probability demands it and it changes the course of the game.

cc-dice is more of a nod to the mechanics than trying to become a sophisticated plugin. In fact, you can create a stop hook yourself with a flat 5% chance to mimic a d20 roll. However, cc-dice gives you what a one-liner can't: accumulating dice pools across turns, shared rolls across multiple slots, per-session cooldowns, and state that persists across turns.

This creates moments that feel organic rather than scheduled. A prompt to invoke a skill that fires at turn 42 because the dice finally landed without any intervention. Your agents are part of the campaign.

Install

curl -fsSL https://raw.githubusercontent.com/pro-vi/cc-dice/main/install.sh | bash

Or clone locally:

git clone https://github.com/pro-vi/cc-dice.git
cd cc-dice && ./install.sh

Requires bun, git, and jq.

./install.sh check      # verify
./install.sh uninstall   # remove

Quick Start

# Register an accumulator slot (escalating probability)
cc-dice register refactor \
  --die 20 --target 20 --type accumulator \
  --message "Cast /refactor and review your current work."

# Register a flat-chance slot
cc-dice register second-opinion \
  --die 20 --target 2 --type single \
  --message "Get a second opinion (e.g. from codex)."

# Check status
cc-dice status refactor

# Manual roll (dry run, no state change)
cc-dice roll second-opinion

That's it. The installed stop hook rolls all slots automatically on every Claude Code stop event.

How Hooks Work

The installer registers a Stop hook in ~/.claude/settings.json. On each stop:

  1. Hook receives { session_id, transcript_path } on stdin
  2. checkAllSlots() groups slots by die size, rolls one base die per group
  3. Each slot checks its target against shared/bonus rolls
  4. On trigger: 🎲 Nat {best}! {message} shown to Claude via stderr (exit 2)
  5. No triggers: exit 0 (roll results visible to user only)

A SessionStart hook clears state for slots with clearOnSessionStart (default).

Slot Configuration

cc-dice register <name> [options]
Option Default Description
--die <n> 20 Die size (d20, d6, etc.)
--target <n> 20 Target number
--target-mode <mode> exact exact, gte, or lte
--type <type> accumulator accumulator, fixed, or single
--accumulation-rate <n> 7 Turns per +1 die (accumulator only)
--max-dice <n> 100 Dice cap (accumulator only)
--fixed-count <n> 1 Dice count (fixed only)
--cooldown <mode> per-session per-session or none
--no-clear-on-start Don't clear state on session start
--no-reset-on-trigger Don't reset accumulator on trigger
--no-flavor Don't prepend dice emoji + roll lingo
--message <msg> Message shown to Claude on trigger

Message Placeholders

{rolls}, {best}, {diceCount}, {slotName} are replaced at trigger time.

By default, trigger output is prefixed with 🎲 Nat {best}! — disable with --no-flavor.

Dice Types

Accumulator: +1 die per N turns since last trigger. Escalating pressure.

Turns 0-6:   0 dice (0%)      Turns 14-20: 2d20  (9.8%)
Turns 7-13:  1d20  (5%)       Turns 21-27: 3d20  (14.3%)

Single: Always 1 die. Flat chance every stop event.

Fixed: Always N dice. Constant probability.

Shared Roll Pools

Slots sharing a die size observe the same base roll:

  • Two single d20 slots claiming different faces are mutually exclusive
  • An accumulator d20 slot gets the shared base roll + independent bonus dice
  • Different die sizes (d20 vs d6) roll independently

This means registering reflection (target 20) and second-opinion (target 1) on a d20 guarantees at most one triggers per base roll.

CLI Reference

cc-dice register <name> [options]   Register a dice slot
cc-dice unregister <name>           Remove a slot
cc-dice list                        List all slots
cc-dice status <name>               Show dice status
cc-dice roll <name>                 Dry-run roll
cc-dice reset <name>                Reset accumulator
cc-dice clear <name>                Clear state

Storage

~/.claude/dice/
  slots.json                          Slot registry
  state/
    {slotName}-{sessionId}.json       Per-slot per-session state
    triggered-{slotName}-{sessionId}  Cooldown markers

Library API

Hooks and scripts can import via the installed symlink:

const { registerSlot, checkAllSlots } =
  await import(`${process.env.HOME}/.claude/dice/cc-dice.ts`);

Or from the source tree directly:

import { registerSlot, checkAllSlots } from "./src/index";

Environment Variables

Variable Purpose
CC_DICE_BASE Override base directory (default: ~/.claude/dice/)
CC_DICE_SESSION_ID Override session ID
DEBUG=1 Verbose logging to stderr

Troubleshooting

./install.sh check shows broken symlinks: The source directory was moved or deleted. Re-run ./install.sh to re-link.

Hook not firing: Verify with ./install.sh check that hooks are registered in settings.json. Use cc-dice roll <name> to test a dry run.

State not clearing between sessions: Ensure the SessionStart hook is registered. Use cc-dice clear <name> to reset a specific slot manually.

Contributing

git clone --recurse-submodules https://github.com/pro-vi/cc-dice.git
cd cc-dice
bun install
bun test

Test submodules (bats-core, bats-support, bats-assert) are required. If you cloned without --recurse-submodules:

git submodule update --init --recursive

See docs/architecture.md for internals.

License

MIT

About

Probabilistic dice triggers for Claude Code hooks

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages