SLOPSHOPPER

regel-merken

Macht aus deinem Feedback per Klick eine feste Regel in CLAUDE.md

newbandtoastpromptmodel
A shopper browsing a rack in a slop shop
README

regel-merken

Ein Claude-Code-Mod für dauerhaftes Lernen aus Feedback. Wenn du Claude korrigierst, etwa mit „nein“, „sieht nicht gut aus“ oder „mach das lieber so“, erscheint über dem Prompt ein kleines Banner mit der Frage, ob daraus eine feste Regel werden soll. Ein Klick auf Speichern, und der Mod formuliert die Regel kurz und schreibt sie in deine CLAUDE.md, damit Claude denselben Fehler nicht noch einmal macht.

Installieren

Im Terminal in Claude Code eintippen:

/plugin install regel-merken --marketplace boonpflug/claude-mods-deutsch

Danach y zum Hinzufügen des Marketplace und mit Enter den Bereich „user“ wählen. Der Mod läuft sofort.

Aus der Shell geht es auch: claude plugin install regel-merken --marketplace boonpflug/claude-mods-deutsch

Source 2 files
hooks/register.tsx 65 lines
1import { atom, read, update } from 'claude-code'
2import type { EngineInterface, Register } from 'claude-code'
3
4const pending = atom({ plugin: 'regel-merken', key: 'pending' } as const, null)
5const saving = atom({ plugin: 'regel-merken', key: 'saving' } as const, false)
6
7const FEEDBACK =
8  /^(nein|no|nee)\b|sieht nicht (gut|schön) aus|gefällt mir nicht|lieber so|mach (das|es) lieber|ich will (lieber|nicht|kein)|bitte (nie|immer)|nicht so\b|i wish we/i
9
10async function save($: EngineInterface, feedback: string) {
11  await update($, saving, () => true)
12  const reply = await $.model.complete({
13    model: 'haiku',
14    maxTokens: 120,
15    system: 'Du formulierst Feedback eines Nutzers als eine kurze, allgemeingültige Regel für einen Coding-Agenten. Deutsch, Imperativ, ein Satz, ohne Einleitung.',
16    prompt: `Feedback: ${feedback}`,
17  })
18  const rule = reply.isAnswered ? reply.text.trim().replace(/^[-•]\s*/, '') : feedback
19
20  const file = 'CLAUDE.md'
21  const before = (await $.fs.exists(file)) ? await $.fs.read(file) : ''
22  const heading = '## Regeln aus Feedback'
23  const text = before.includes(heading)
24    ? `${before.trimEnd()}\n- ${rule}\n`
25    : `${before.trimEnd()}${before ? '\n\n' : ''}${heading}\n\n- ${rule}\n`
26  await $.fs.write(file, text)
27
28  await update($, pending, () => null)
29  await update($, saving, () => false)
30  $.ui.toast(`📌 Regel gespeichert: ${rule}`, { timeoutMs: 6000 })
31}
32
33export const register: Register = on => {
34  on('prompt.submit', async ($, e, next) => {
35    const typed = e.origin === undefined || e.origin.kind === 'composer'
36    if (!e.command && !e.isMeta && typed && FEEDBACK.test(e.text.trim())) {
37      await update($, pending, () => e.text.trim())
38    }
39    return next(e)
40  })
41
42  on('ui.render', { component: 'AbovePrompt' }, async ($, e, next) => {
43    const feedback = await read($, pending)
44    if (feedback === null || e.props.hasSurvey) return next(e)
45
46    const { Box, Button, Text } = $.ui.resolve(e)
47    const short = feedback.length > 70 ? `${feedback.slice(0, 67)}…` : feedback
48
49    return (
50      <Box flexDirection="row" gap={1}>
51        <Text color="magenta" bold>📌 Als feste Regel in CLAUDE.md speichern?</Text>
52        <Text dimColor>„{short}“</Text>
53        {(await read($, saving)) ? (
54          <Text color="yellow">speichere …</Text>
55        ) : (
56          <Box flexDirection="row" gap={1}>
57            <Button key="save" label="1 Speichern" hotkey="1" onPress={() => save($, feedback)} />
58            <Button key="skip" label="2 Nein danke" hotkey="2" onPress={() => update($, pending, () => null)} />
59          </Box>
60        )}
61      </Box>
62    )
63  })
64}
65
types/index.d.ts 8 lines
1export type Pending = string | null
2
3declare module 'claude-code' {
4  interface PluginState {
5    'regel-merken': { pending: Pending; saving: boolean }
6  }
7}
8