slima4/spank-claude/tree/main/plugin
spank
spank は Apple Silicon MacBook の加速度センサーで叩かれたことを検知し、キャラクターの表情を表示して日本語の音声を再生しながらスコアを記録する Claude Code プラグインです。必要なら Claude にも振動を伝え、ターンを中断できます。
この mod について
spank-claude
あなたの MacBook には加速度センサーがある。Claude Code にはプラグインがある。あなたには感情がある。 これでようやく出会える。
MacBook(または置いてある机)を叩くと、Claude Code がそれを感じ取ります。プロンプトの上に顔が現れ、ノートパソコンが日本語で悲鳴を返し、小さなカウンターが今日の調子を記録します。必要なら Claude 自身にもそのメッセージを伝えられます——十分強く叩けば、ターンの途中で停止します。
痛みの段階
| レベル | 衝撃(0.05 g 時) | Sakura の声 | Natsu の声 | Aki の声 | 起きたと思われること | | ----- | --------------- | ----------- | ----------- | ----------- | ---------------------------------- | | 1 | 0.050–0.106 g | んっ! | えっ! | ひゃっ! | 軽く叩いただけ。せいぜい受動攻撃的。 | | 2 | 0.106–0.224 g | あっ! | うっ! | あれっ! | テストがまた失敗した。 | | 3 | 0.224–0.473 g | いたっ! | いてっ! | いたぁ! | Claude がコードを「簡略化」した。 | | 4 | 0.473–1 g | きゃっ! | やっ! | いやっ! | Claude はテストを通すためにテストを削除した。 | | 5 | 1 g 以上 | あぁっ…! | うわぁっ! | きゃあっ! | 本番環境。 |
この g の範囲はデフォルトの感度 0.05 g を基準にしています。範囲は自分の感度に合わせて動きます(/slaps calibrate、または /config の「Slap sensitivity」)。レベル 1 は設定した感度から始まり、レベル 5 は 1 g、間のレベルは均等に分かれます。
コンボ
1 秒未満の間隔で叩き続けると、弱くてもすべてのタップが数えられます。各タップは直前より 1 レベル上になるか、より強く当たった場合はそのタップ自身のレベルになり、止まるまでレベルは下がりません。弱いタップを 5 回すると彼女は悲鳴を上げます。もっと強く叩くと、その叫び声で彼女を止めます。
必要なもの
- モーションセンサーを搭載した Apple Silicon MacBook:M1 Pro / Max 以降。
- macOS 27(古いリリースでは root が必要になる場合があります)。
- Xcode Command Line Tools(
xcode-select --install)。 - plugin function hooks を備えた Claude Code(2.1.288 でビルドとテスト済み)。
インストール
claude plugin marketplace add slima4/spank-claude
claude plugin install spank@spank-claude
コマンド
| コマンド | 内容 |
| -------------------- | ----------------------------------------------------------- |
| /slaps | このセッション、累計、直近のヒットのスコアを表示します。 |
| /slaps who | 顔のシリーズを一覧表示し、現在のものに印を付けます。 |
| /slaps who natsu | 今すぐ Natsu を叩かせます(シリーズ名は何でも使えます)。 |
| /slaps calibrate | 6 s 入力(Enter は押さない)後、3 回叩いて感度を決めます。 |
| /slaps mute | 彼女を消音します。顔たちはそれでもあなたを裁きます。 |
| /slaps unmute | 彼女が戻ります。 |
| /slaps claude on | 叩きが Claude に届きます。レベル 4 以上のヒットまたはコンボでターンを停止します。 |
| /slaps claude off | Claude は幸せなまま何も知りません(デフォルト)。 |
| /slaps image | ターミナルが本物の画像を表示できるか確認します。 |
Claude モード
/slaps claude on では、叩くたびに会話へ静かなメモが追加されます。Claude が動作中にレベル 4 以上で叩くと、その場でターンが停止します。
顔のシリーズ
各シリーズは 1 人のキャラクターです。レベルごとに 5 枚の顔と 1 つの声があります。/slaps who <series>、または /config の「Face series」で切り替えます。
| シリーズ | 声 |
| -------- | -------- |
| sakura | sakura |
| natsu | natsu |
| aki | aki |
設定
Claude Code で /config を開きます。
| 設定 | デフォルト | 内容 |
| ----------------------- | ------- | --------------------------------------------------------- |
| Slap sensitivity (g) | 0.05 | 数えられる最小の揺れと、レベル 1 の開始点。 |
| Claude を停止するレベル | 4 | /slaps claude on では、このレベル以上でターンを停止します。 |
| Face series | sakura | 表示する顔と、その声を決めます。 |
| Face size | large | large(24 行)、medium(16)、small(12)、off のいずれか。 |
| Voice volume | 1 | 0 は無音、最大 4 でオープンプランのオフィス向けです。 |
仕組み
MacBook IMU (AppleSPUHIDDevice, ~1 kHz)
│ IOKit HID reports
▼
slapd (Swift) ── 重力を取り除き、ピークを検出
▼
spank plugin (Claude Code hooks) ── 1–5 で評価
├─ status line + toast
├─ prompt の上の顔
├─ レベルごとの音声クリップ
└─ optional: Claude へのメモ/ターン停止
ライセンス
MIT。責任を持って叩いてください。
インストール
まず作者の README で marketplace とプラグイン名を確認してください。コマンドはリポジトリの構成によって変わる場合があります。
claude plugin marketplace add slima4/spank-claude claude plugin install spank
原文 / README
spank-claude
Your MacBook has an accelerometer. Claude Code has plugins. You have feelings. Now they can finally meet.
Slap your MacBook (or the desk it sits on) and Claude Code feels it: a face pops up above the prompt, the laptop yelps back in Japanese, and a little counter keeps score of how your day is going. Optionally, Claude itself gets the message — and a hard enough slap stops it mid-turn.
<p> <img src="plugin/assets/faces/sakura/level_1.png" width="96" alt="Sakura, level 1"> <img src="plugin/assets/faces/sakura/level_2.png" width="96" alt="Sakura, level 2"> <img src="plugin/assets/faces/sakura/level_3.png" width="96" alt="Sakura, level 3"> <img src="plugin/assets/faces/sakura/level_4.png" width="96" alt="Sakura, level 4"> <img src="plugin/assets/faces/sakura/level_5.png" width="96" alt="Sakura, level 5"> <br> <img src="plugin/assets/faces/natsu/level_1.png" width="96" alt="Natsu, level 1"> <img src="plugin/assets/faces/natsu/level_2.png" width="96" alt="Natsu, level 2"> <img src="plugin/assets/faces/natsu/level_3.png" width="96" alt="Natsu, level 3"> <img src="plugin/assets/faces/natsu/level_4.png" width="96" alt="Natsu, level 4"> <img src="plugin/assets/faces/natsu/level_5.png" width="96" alt="Natsu, level 5"> <br> <img src="plugin/assets/faces/aki/level_1.png" width="96" alt="Aki, level 1"> <img src="plugin/assets/faces/aki/level_2.png" width="96" alt="Aki, level 2"> <img src="plugin/assets/faces/aki/level_3.png" width="96" alt="Aki, level 3"> <img src="plugin/assets/faces/aki/level_4.png" width="96" alt="Aki, level 4"> <img src="plugin/assets/faces/aki/level_5.png" width="96" alt="Aki, level 5"> </p>The pain scale
| Level | Hit (at 0.05 g) | Sakura says | Natsu says | Aki says | What probably happened | | ----- | --------------- | ----------- | ----------- | ----------- | ---------------------------------- | | 1 | 0.050–0.106 g | んっ! | えっ! | ひゃっ! | A tap. Passive-aggressive at most. | | 2 | 0.106–0.224 g | あっ! | うっ! | あれっ! | The tests failed again. | | 3 | 0.224–0.473 g | いたっ! | いてっ! | いたぁ! | Claude "simplified" your code. | | 4 | 0.473–1 g | きゃっ! | やっ! | いやっ! | Claude deleted the tests to make them pass. | | 5 | 1 g and up | あぁっ…! | うわぁっ! | きゃあっ! | Production. |
The g ranges are for the default sensitivity, 0.05 g. The scale moves with
yours (/slaps calibrate, or "Slap sensitivity" in /config): level 1 starts
at your sensitivity, level 5 at 1 g, and the levels between are spread evenly.
At 0.15 g, for example, they start at about 0.15, 0.24, 0.39, 0.62 and 1 g.
Two exceptions. Below 0.05 g the scale stays as it is at 0.05 g: softer taps count, as level 1, but a moderate slap doesn't turn into a level 4. Above 0.25 g, level 5 starts at 4 times your sensitivity instead of 1 g, so the levels don't bunch up.
Combos
Keep slapping, less than a second apart, and every tap counts, however soft:
each is one level above the one before, or its own level if it hit harder, and
the level never drops until you pause. Five soft taps make her scream. A
harder slap cuts her off with its own yelp; one at the same level does too,
but stays quiet if her last yelp is under 0.4 s old, so drumming doesn't
stutter. The face says how many came in a row, and a combo puts up one toast
as it starts and one as it ends, saying how far it got. The score (/slaps,
the status line) still keeps what the sensor read.
Taps can come as fast as about 7 a second. A hard slap leaves the laptop ringing, so the next tap counts once that has died down, usually within a fraction of a second.
What you need
- An Apple Silicon MacBook with the motion sensor: M1 Pro / Max or newer. The plain 2020 M1 13" reportedly has no readable sensor. A Mac mini will feel nothing, no matter how hard you hit it. Please don't test this.
- macOS 27. It reads the sensor without
sudothere; older releases may want root (untested). - Xcode Command Line Tools (
xcode-select --install). The plugin builds its little sensor reader from Swift source on first run, so nothing precompiled ships in the repo. - Claude Code with plugin function hooks (built and tested on 2.1.288; that API is early access and may move).
Install
Two commands, no cloning:
claude plugin marketplace add slima4/spank-claude
claude plugin install spank@spank-claude
(or the same from inside Claude Code: /plugin marketplace add slima4/spank-claude,
then /plugin install spank@spank-claude.)
Start Claude Code. The first session builds the sensor reader (the status line
says spank: building the sensor reader, about 20 seconds), then shows
spank: armed (0.05g). Go on. Slap it.
Updates: claude plugin update spank@spank-claude, then restart Claude Code.
Each new version builds its sensor reader again on its first start.
Uninstall: claude plugin uninstall spank@spank-claude.
Commands
| Command | Does |
| -------------------- | ----------------------------------------------------------- |
| /slaps | Your score: this session, all time, and the last hit. |
| /slaps who | Lists the face series; the current one is marked. |
| /slaps who natsu | Natsu gets slapped now (any series name works). |
| /slaps calibrate | Type 6 s (no Enter), knock 3 times; it picks the sensitivity. |
| /slaps mute | Silences her. The faces still judge you. |
| /slaps unmute | She's back. |
| /slaps claude on | Slaps reach Claude; a level 4+ slap or combo stops its turn. |
| /slaps claude off | Claude stays blissfully unaware (the default). |
| /slaps image | Checks whether your terminal can show real pictures. |
Claude mode
With /slaps claude on, every slap becomes a quiet note in the conversation:
"The user just physically slapped their laptop 2 times (accelerometer;
strongest hit level 3 of 5, 0.31g). Take it as nonverbal frustration…"
Claude reads it on its next step, acknowledges it, and reconsiders what it was
doing. Slaps that keep coming are told as one note once you pause, or 4
seconds after the first, whichever comes sooner. Slaps while it's idle are
saved up and delivered as one note with your next message, so it gets the
whole story at once.
A level 4+ slap while Claude is working stops the turn on the spot (the level is a setting). So does a combo that builds up to it and lasts at least half a second (so one slap that bounces doesn't), unless one of its slaps was a level 1 graze (so the steady shaking of a bumpy train doesn't). Fair warning: a shell command Claude already started keeps running in the background; the slap stops Claude, not the command.
Several sessions
Only the Claude Code session you used last reacts to a slap (the one you
last typed a prompt or a /slaps command in). One laptop, one victim.
Face series
Each face series is one character: five faces, one per level, and a voice.
Switch with /slaps who <series> (/slaps who lists them), or under
"Face series" in /config.
| Series | Voice | Face |
| -------- | -------- | ------------------------------------------------------------- |
| sakura | sakura | <img src="plugin/assets/faces/sakura/level_1.png" width="48" alt="Sakura"> |
| natsu | natsu | <img src="plugin/assets/faces/natsu/level_1.png" width="48" alt="Natsu"> |
| aki | aki | <img src="plugin/assets/faces/aki/level_1.png" width="48" alt="Aki"> |
Faces and terminals
Faces are drawn as colored half-block characters, so they show up in any truecolor terminal (Warp, iTerm2, Ghostty, …), pixel-art style, in the biggest size that fits above your prompt.
Real, full-resolution pictures need a terminal with kitty graphics Unicode
placeholders, which today means Ghostty or kitty. Run /slaps image to see what
yours can do. Warp and Terminal.app currently can't (not our fault, we checked).
Settings
Open /config in Claude Code (or /plugin configure spank@spank-claude):
| Setting | Default | What it does |
| ----------------------- | ------- | --------------------------------------------------------- |
| Slap sensitivity (g) | 0.05 | Smallest shake that counts, and where level 1 starts. Typing counts? Raise it. |
| Level that stops Claude | 4 | With /slaps claude on, this level or harder stops a turn. |
| Face series | sakura | sakura, natsu or aki: whose face pops up and voice yelps. |
| Face size | large | large (24 rows), medium (16), small (12), or off. |
| Voice volume | 1 | 0 is silent, up to 4 for open-plan offices. |
Changes apply right away. Not sure what sensitivity to pick? Run
/slaps calibrate: type anything for 6 seconds (don't press Enter, or Claude
gets it), then knock on the desk 3 times, and it sets the sensitivity between
the two for you. The 6 seconds start at your first key and the knocking at
your first knock, so take your time reading; it waits up to 30 seconds for
each. The status line then shows it, e.g. spank: armed (0.077g).
How it works
MacBook IMU (AppleSPUHIDDevice, ~1 kHz)
│ IOKit HID reports, x/y/z in 1/65536 g
▼
slapd (Swift) ── removes gravity, finds the peak
│ {"type":"slap","ts":…,"peak":0.42} on stdout
▼
spank plugin (Claude Code hooks) ── grades it 1–5 for your sensitivity
├─ status line + toast
├─ face above the prompt (Raster cells, 3 s)
├─ voice clip per level
└─ optional: note to Claude / stop its turn
Development
Run straight from a clone (uninstall the marketplace copy first, or you get two of her):
git clone https://github.com/slima4/spank-claude && cd spank-claude
claude --plugin-dir "$PWD/plugin"
make slapd # build the sensor reader by hand
make raw # watch the live shake
make faces # rebuild face cells from assets/faces/<series>/*.png
claude plugin validate . # the marketplace and the plugin
claude plugin test plugin # the tests
Installed copies are kept per version, so bump version in
plugin/.claude-plugin/plugin.json when you ship a change.
To add a face series, say hana:
- Put its faces in
assets/faces/hana/level_<1-5>.png(square, on white). - Add
"hana"to theface_seriesoptions inplugin/.claude-plugin/plugin.json. - Run
make faces. It draws the cells intoplugin/hooks/faces.ts, writes the 256px pictures toplugin/assets/faces/hana/, and warns if step 2 is missing. - In
plugin/hooks/series.ts, addhanatoSERIES. It can borrow an existing voice (voice: 'sakura'), or get its own: clips inplugin/assets/voices/hana/level_<1-5>.mp3and their captions inVOICES.
License
MIT. Slap responsibly.
Safety notes
- It's a laptop, not a punching bag. AppleCare does not cover "it was for a plugin."
- Level 5 is reachable with a firm palm. You don't need to prove anything.
- The sensor reading comes from the community's reverse-engineering work in olvvier/apple-silicon-accelerometer and taigrr/apple-silicon-accelerometer.
