SLOPSHOPPER

prompt-score

Toasts a heuristic quality score (PromptTelemetry rules) for each prompt you send

newtoastprompt
v0.1.0no licenseupdated 2026-10-12kad1r/claude-mods/prompt-score
A shopper browsing a rack in a slop shop
Preview · a replayed session in a sandbox
claude · ~/work/app · prompt-score
› fix the failing auth test and add an audit log call ╭────────────────────────────────────────────╮ │ prompt-score │ ⏺ Read(src/auth.ts) │ Prompt 29/100 · 🔴 Zayıf (N15 B0 K6 D8) — │ ⎿ Read 6 lines │ Hangi dosya, hata mesajı veya kod │ ⏺ Update(src/auth.ts) │ parçasından bahsettiğini ekle. │ ⎿ 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
README

claude-mods

English · Türkçe

Small, focused mods for Claude Code, built on its function-hook plugin API. Each folder is one plugin; the repo root is a plugin marketplace, so you install only the mods you want.

Clawd's 17 scenes in the default small band

What's new

  • ask-alert, new: a Windows notification and a sound when Claude waits for you (a permission prompt, AskUserQuestion, an idle prompt).
  • sys-meter, a new status line: CPU, RAM and temperature every 5 s.
  • clawd-spinner, rewritten. 17 scenes, one picked at random for every command and never the same twice in a row (10 new: rain, fishing, music, laptop, ball, rocket, plant, bug, blocks, sleep). The default band is now 16×1 cells, drawn with Unicode 16 block octants (2×4 pixels per cell), a quarter of the old size. size: large in /config brings back the 32×2 half-block band (preview). The large band animates with $.ui.blit, so the rest of the band is not redrawn every frame.
  • clear-reminder is a status line now, styled like usage-meter.
  • usage-meter writes percents as %34; 34% 336k came out garbled in the status line.
  • git-band runs git status with core.fsmonitor off, so a cloned repo's config cannot start a program every 15 s.
  • New mods: todo-pane, agents-pane, git-band, time-tracker, session-journal.

What's inside

See what Claude is doing

ModWhat it does
usage-meterStatus line: context fill bar with tokens/window, a live turn timer, the last turn's tokens, session cost and 5-hour rate-limit usage.
clear-reminderStatus line counting prompts since the last /clear (🟢 mesaj ▰▰▱ 7/20); turns yellow at 17 and red at 20, with a toast.
sys-meterStatus line with CPU load, RAM usage and temperature (🟢 cpu ▰▱▱ %14 · ram ▰▰▰ %78 24.6/31.6G · 🌡 69°C), refreshed every 5 s. Windows only; the temperature is the ACPI thermal zone, readable without admin rights, not the CPU package sensor.
git-bandOne line above the prompt: branch, changed-file count, ahead/behind. Refreshes every 15 s and after each turn.
todo-paneLive pane of Claude's todo list (TodoWrite or TaskCreate/TaskUpdate) with a progress bar. Opens by itself; /todos reopens it.
agents-paneLive pane of subagents with status, elapsed time and a Stop button for each running one. /subagents reopens it.
session-diff/session-diff lists every file changed this session with +/− counts; press a file to read its diff (b back, k/j page).

Status lines and the git band

todo-pane, agents-pane and session-diff

Habits and records

ModWhat it does
prompt-scoreToasts a quality score for every prompt you type (clarity, context, specificity, verifiability) with one hint for the weakest part. Local rules, no API calls. Hints are in Turkish.
time-trackerAdds up how long Claude works per project per day; /zaman shows the last 7 days.
session-journalAppends one line per turn to ~/.claude/journal/<date>.md; /gunluk adds a Haiku-written summary of the session.

Fun

ModWhat it does
clawd-spinnerA tiny 16×1 band under the spinner (block octants; set size to large in /config for a 32×2 half-block band if your font lacks octants) where pixel-art Clawd plays one of 17 scenes, picked at random for every command (UFO, cooking, fishing, rain, music, laptop, rocket, growing plant, falling blocks, sleeping…). Time-of-day backdrop: morning coffee, a night sky, Friday-evening confetti.

Notifications

ModWhat it does
ask-alertWhen Claude waits for you (a permission prompt from an ask rule, an AskUserQuestion, an idle prompt, an MCP input request) it raises a Windows notification, a toast in the terminal and plays Windows Notify System Generic.wav. mode in /plugin configure: both (default), toast or sound. Windows only.
done-soundPlays a random mp3 from its sounds/ folder when Claude finishes answering, never the same twice in a row (Windows, through PowerShell's MediaPlayer).

ask-alert: terminal toast and Windows notification

Install

At a Claude Code prompt:

/plugin install usage-meter --marketplace kad1r/claude-mods

Answer y to add the marketplace, then pick a scope. Repeat with any mod name from the tables above. /reload-plugins picks up updates.

done-sound: no sound files are in the repo. Put one or more mp3s in done-sound/sounds/ inside the installed plugin folder; each finished answer plays a random one, never the same twice in a row.

Notes

  • Function hooks are an early-access API of Claude Code and may change between releases. These mods were written and tested on Claude Code 2.1.296; ask-alert on 2.1.300.
  • session-journal writes the first line of your prompts to disk in plain text. Keep that in mind if you paste secrets into prompts.
  • /gunluk makes one Haiku request each time you run it.
  • ask-alert does not fire in bypassPermissions mode for permission prompts, since none are shown. Where an organization manages Claude Code, its Notification hook runs only if the organization lists the plugin; the AskUserQuestion alert still works.
  • The images above are drawn from the mods' own output (Clawd's frames from scene.ts, the status-line and pane text from each mod's functions), not cropped from a live session. The Windows notification in ask-alert.svg is drawn to look like the real one.

Develop

Each mod is three files: .claude-plugin/plugin.json, hooks/hooks.json and a hooks module in hooks/. Mods that keep values in $.state also have types/index.d.ts.

claude plugin validate ./<mod>
claude plugin test ./<mod>

To run from a local clone, add it as a marketplace (claude plugin marketplace add <path>), install from it, and run /reload-plugins after edits; the plugin is read straight from the folder.


<a id="türkçe"></a>

claude-mods (Türkçe)

English · Türkçe

Claude Code için küçük, tek işe odaklı mod'lar. Hepsi Claude Code'un function-hook plugin API'si ile yazıldı. Her klasör bir plugin; repo kökü bir plugin marketplace'i, yani sadece istediğin mod'ları kurarsın.

Varsayılan küçük bantta Clawd'ın 17 sahnesi

Yenilikler

  • ask-alert, yeni: Claude seni beklediğinde (izin isteği, AskUserQuestion, boşta kalan prompt) Windows bildirimi ve ses.
  • sys-meter, yeni durum satırı: 5 saniyede bir CPU, RAM ve sıcaklık.
  • clawd-spinner baştan yazıldı. 17 sahne var; her komutta biri rastgele seçiliyor ve aynısı art arda gelmiyor (10 yeni: yağmur, balık tutma, müzik, laptop, top, roket, bitki, böcek, bloklar, uyku). Varsayılan bant artık 16×1 hücre, Unicode 16 blok octant karakterleriyle çiziliyor (hücre başına 2×4 piksel), eskisinin dörtte biri. /config içinde size: large seçilirse 32×2'lik yarım-blok bant geri gelir (önizleme). Büyük bant $.ui.blit ile oynuyor, yani her karede bandın geri kalanı yeniden çizilmiyor.
  • clear-reminder artık usage-meter gibi bir durum satırı.
  • usage-meter yüzdeyi %34 biçiminde yazıyor; 34% 336k durum satırında bozuk görünüyordu.
  • git-band git status'u core.fsmonitor kapalı çalıştırıyor; klonlanan bir reponun ayarı 15 saniyede bir program başlatamaz.
  • Yeni mod'lar: todo-pane, agents-pane, git-band, time-tracker, session-journal.

Neler var

Claude ne yapıyor, gör

ModNe yapar
usage-meterDurum satırı: context doluluk çubuğu ve token/pencere, canlı turn sayacı, son turn'ün token'ı, oturum maliyeti, 5 saatlik limit kullanımı.
clear-reminderSon /clear'dan beri yazdığın mesajları sayan durum satırı (🟢 mesaj ▰▰▱ 7/20); 17'de sarı, 20'de kırmızı olur ve toast gösterir.
sys-meterCPU yükü, RAM kullanımı ve sıcaklığı gösteren durum satırı (🟢 cpu ▰▱▱ %14 · ram ▰▰▰ %78 24.6/31.6G · 🌡 69°C), 5 saniyede bir yenilenir. Sadece Windows; sıcaklık admin yetkisi gerektirmeyen ACPI thermal zone değeridir, CPU paket sensörü değil.
git-bandPrompt'un üstünde tek satır: branch, değişen dosya sayısı, ahead/behind. 15 saniyede bir ve her turn sonunda yenilenir.
todo-paneClaude'un yapılacaklar listesini (TodoWrite veya TaskCreate/TaskUpdate) ilerleme çubuğuyla gösteren canlı panel. Kendiliğinden açılır; /todos tekrar açar.
agents-paneSubagent'ları durum ve süreyle gösteren canlı panel; çalışan her birinin yanında Durdur butonu. /subagents tekrar açar.
session-diff/session-diff bu oturumda değişen dosyaları +/− sayılarıyla listeler; bir dosyaya basınca diff'ini gösterir (b geri, k/j sayfa).

Durum satırları ve git bandı

todo-pane, agents-pane ve session-diff

Alışkanlık ve kayıt

ModNe yapar
prompt-scoreYazdığın her prompt'a kalite puanı verir (netlik, bağlam, kapsam, doğrulanabilirlik) ve en zayıf kısım için tek bir ipucu gösterir. Yerel kurallar, API çağrısı yok.
time-trackerClaude'un proje bazında günlük çalıştığı süreyi toplar; /zaman son 7 günü gösterir.
session-journalHer turn için ~/.claude/journal/<tarih>.md dosyasına bir satır ekler; /gunluk oturumun Haiku ile yazılmış özetini ekler.

Eğlence

ModNe yapar
clawd-spinnerSpinner'ın altında 16×1'lik minik bir bant (blok octant karakterleri; fontun bunları çizmiyorsa /config'ten size ayarını large yap, 32×2 yarım-blok bant gelir): piksel Clawd her komutta rastgele seçilen 17 sahneden birini oynar (UFO, yemek, balık tutma, yağmur, müzik, laptop, roket, büyüyen çiçek, düşen bloklar, uyku…). Arka plan saate göre değişir: sabah kahve, gece gökyüzü, cuma akşamı konfeti.

Bildirimler

ModNe yapar
ask-alertClaude seni beklediğinde (ask kuralından gelen izin isteği, AskUserQuestion, boşta kalan prompt, MCP'nin bilgi isteği) Windows bildirimi ve terminal içi toast gösterir, Windows Notify System Generic.wav çalar. /plugin configure içinde mode: both (varsayılan), toast veya sound. Sadece Windows.
done-soundClaude cevabı bitirince sounds/ klasöründen rastgele bir mp3 çalar, aynısı art arda gelmez (Windows, PowerShell MediaPlayer ile).

ask-alert: terminal toast'u ve Windows bildirimi

Kurulum

Claude Code prompt'unda:

/plugin install usage-meter --marketplace kad1r/claude-mods

Marketplace'i eklemek için y de, sonra scope seç. Tablolardaki diğer mod adlarıyla tekrarla. Güncellemeler için /reload-plugins.

done-sound: Ses dosyaları repoda yok. Kurulan plugin klasöründe done-sound/sounds/ altına bir veya daha fazla mp3 koy; her cevap bitiminde rastgele biri çalar, aynısı art arda gelmez.

Notlar

  • Function hook'lar Claude Code'un erken erişim API'si; sürümler arasında değişebilir. Bu mod'lar Claude Code 2.1.296 üzerinde yazılıp test edildi; ask-alert 2.1.300 üzerinde.
  • session-journal, prompt'larının ilk satırını diske düz metin olarak yazar. Prompt'a secret yapıştırıyorsan bunu göz önünde tut.
  • /gunluk her çalıştığında bir Haiku isteği yapar.
  • ask-alert, bypassPermissions modunda izin uyarısı vermez, çünkü izin ekranı çıkmaz. Claude Code'u organizasyon yönetiyorsa Notification hook'u ancak organizasyon plugin'i listelerse çalışır; AskUserQuestion uyarısı yine çalışır.
  • Yukarıdaki görseller mod'ların kendi çıktısından çizildi (Clawd kareleri scene.ts'den, durum satırı ve panel metinleri mod fonksiyonlarından); canlı oturumdan kırpılmadı. ask-alert.svg içindeki Windows bildirimi gerçeğine benzetilerek çizildi.

Geliştirme

Her mod üç dosyadan oluşur: .claude-plugin/plugin.json, hooks/hooks.json ve hooks/ altında bir hooks modülü. $.state kullananlarda ayrıca types/index.d.ts vardır.

claude plugin validate ./<mod>
claude plugin test ./<mod>

Yerel bir klondan çalıştırmak için klonu marketplace olarak ekle (claude plugin marketplace add <yol>), oradan kur ve değişikliklerden sonra /reload-plugins çalıştır; plugin doğrudan klasörden okunur.

Source 2 files
hooks/register.ts 14 lines
1import type { Register } from 'claude-code'
2
3import { score, shouldSkip, toastText } from './score'
4
5export const register: Register = on => {
6  on('prompt.submit', ($, e, next) => {
7    // Only prompts the person typed (terminal or Remote Control) are scored.
8    if ((e.origin.kind === 'composer' || e.origin.kind === 'bridge') && !shouldSkip(e.text)) {
9      $.ui.toast(toastText(score(e.text)))
10    }
11    return next(e)
12  }).catch(($, e, next) => next(e)) // scoring must never block a prompt
13}
14
hooks/score.ts 110 lines
1// Port of PromptTelemetry.Core's TriviaFilter and HeuristicScorer, so the score
2// matches the server's heuristic fallback. Keep the word lists in sync with it.
3
4const MAX_DIMENSION = 25
5const MIN_LENGTH = 15
6
7const ACKNOWLEDGEMENTS = new Set(['devam edebilirsin', 'evet devam edelim', 'tamamdir devam edelim', 'tamamdır devam edelim'])
8
9const ACTION_VERBS = ['ekle', 'olustur', 'oluştur', 'yaz', 'kaldir', 'kaldır', 'tasi', 'taşı', 'refactor', 'yenile', 'implement', 'fix', 'guncelle', 'güncelle', 'sil', 'degistir', 'değiştir', 'cevir', 'çevir', 'duzenle', 'düzenle']
10const VAGUE_VERBS = ['duzelt', 'düzelt', 'iyilestir', 'iyileştir', 'bak', 'hallet', 'guzellestir', 'güzelleştir', 'toparla']
11const GOAL_MARKERS = ['amac', 'amaç', 'istiyorum', 'gerekiyor', 'hedef', '?']
12const ERROR_MARKERS = ['```', 'exception', 'error', 'hata', 'stack trace', 'traceback']
13const TECH_KEYWORDS = ['dotnet', '.net', 'sql', 'ef core', 'react', 'vue', 'azure', 'iis', 'typescript', 'c#', 'http', 'json', 'docker', 'api']
14const SCOPE_LIMITERS = ['sadece', 'yalnizca', 'yalnızca', 'dokunma', 'dokun', 'haric', 'hariç', 'degistirme', 'değiştirme']
15const ACCEPTANCE_MARKERS = ['beklenen', 'olmali', 'olmalı', 'kabul kriteri', 'expected', 'should']
16const OUTPUT_MARKERS = ['ornek cikti', 'örnek çıktı', 'cikti:', 'çıktı:', 'sonuc:', 'sonuç:', 'soyle gorunmeli', 'şöyle görünmeli']
17
18// .NET's \w and \b are Unicode-aware; spell that out for JS.
19const W = '[\\p{L}\\p{N}_]'
20const FILE_PATH = new RegExp(`[\\p{L}\\p{N}_./\\\\-]+\\.(cs|csproj|ts|js|vue|sql|json|py|md|ps1|yml|yaml|html|css)(?!${W})`, 'iu')
21const PATH_SEPARATOR = new RegExp(`[\\p{L}\\p{N}_-]{2,}[/\\\\][\\p{L}\\p{N}_-]{2,}`, 'u')
22const IDENTIFIER = new RegExp(`(?<!${W})[a-zA-Z]+[A-Z][A-Za-z0-9]*(?!${W})|(?<!${W})${W}+_${W}+(?!${W})|${W}+\\(\\)`, 'u')
23
24export type Label = 'Poor' | 'Fair' | 'Good'
25
26export type Score = {
27  clarity: number
28  context: number
29  specificity: number
30  verifiability: number
31  overall: number
32  label: Label
33  hint: string
34}
35
36const clamp = (n: number) => Math.max(0, Math.min(MAX_DIMENSION, n))
37const containsAny = (lower: string, needles: readonly string[]) => needles.some(n => lower.includes(n))
38const sentences = (text: string) => text.split(/[.!?\n]/).filter(s => s.trim() !== '').length
39
40export const shouldSkip = (text: string): boolean => {
41  const trimmed = text.trim()
42  if (trimmed.length < MIN_LENGTH || trimmed.startsWith('/')) {
43    return true
44  }
45  const normalized = trimmed.replace(/[.!? ]+$/, '').split(' ').filter(Boolean).join(' ')
46  return ACKNOWLEDGEMENTS.has(normalized.toLocaleLowerCase('tr-TR'))
47}
48
49const clarityOf = (text: string, lower: string) => {
50  let score = 8
51  if (containsAny(lower, ACTION_VERBS)) score += 7
52  if (sentences(text) >= 2) score += 5
53  if (containsAny(lower, GOAL_MARKERS)) score += 5
54  if (containsAny(lower, VAGUE_VERBS) && text.length < 60) score -= 8
55  return clamp(score)
56}
57
58const contextOf = (text: string, lower: string) => {
59  let score = 0
60  if (FILE_PATH.test(text)) score += 9
61  if (containsAny(lower, ERROR_MARKERS)) score += 7
62  if (containsAny(lower, TECH_KEYWORDS)) score += 5
63  if (PATH_SEPARATOR.test(text)) score += 4
64  return clamp(score)
65}
66
67const specificityOf = (text: string, lower: string) => {
68  let score = text.length < 40 ? 0 : text.length < 120 ? 6 : text.length < 400 ? 12 : 16
69  if (IDENTIFIER.test(text)) score += 5
70  if (containsAny(lower, SCOPE_LIMITERS)) score += 4
71  return clamp(score)
72}
73
74const verifiabilityOf = (lower: string) => {
75  let score = 0
76  if (containsAny(lower, ACCEPTANCE_MARKERS)) score += 10
77  if (lower.includes('test')) score += 8
78  if (containsAny(lower, OUTPUT_MARKERS)) score += 7
79  return clamp(score)
80}
81
82// Targets the weakest dimension; ties go Context, Verifiability, Specificity, Clarity.
83const hintFor = (clarity: number, context: number, specificity: number, verifiability: number) => {
84  const weakest = Math.min(clarity, context, specificity, verifiability)
85  if (context === weakest) return 'Hangi dosya, hata mesajı veya kod parçasından bahsettiğini ekle.'
86  if (verifiability === weakest) return 'Beklenen sonucu veya kabul kriterini yaz ki sonuç doğrulanabilsin.'
87  if (specificity === weakest) return 'Kapsamı daralt: hangi metot veya alan değişecek, neye dokunulmayacak?'
88  return 'Ne yapılmasını istediğini tek bir net cümleyle belirt.'
89}
90
91export const score = (promptText: string): Score => {
92  const text = promptText.trim()
93  const lower = text.toLocaleLowerCase('tr-TR')
94  const clarity = clarityOf(text, lower)
95  const context = contextOf(text, lower)
96  const specificity = specificityOf(text, lower)
97  const verifiability = verifiabilityOf(lower)
98  const overall = clarity + context + specificity + verifiability
99  const label: Label = overall < 40 ? 'Poor' : overall < 70 ? 'Fair' : 'Good'
100  return { clarity, context, specificity, verifiability, overall, label, hint: hintFor(clarity, context, specificity, verifiability) }
101}
102
103const LABEL_TR: Record<Label, string> = { Poor: '🔴 Zayıf', Fair: '🟡 Orta', Good: '🟢 İyi' }
104
105export const toastText = (s: Score): string => {
106  const head = `Prompt ${s.overall}/100 · ${LABEL_TR[s.label]}`
107  const dims = `N${s.clarity} B${s.context} K${s.specificity} D${s.verifiability}`
108  return s.label === 'Good' ? `${head} (${dims})` : `${head} (${dims}) — ${s.hint}`
109}
110