SLOPSHOPPER

recording-mode

Режим записи: прячет почты, ключи и номера в транскрипте (/record on|off)

newrowscommand
v0.1.0no licenseupdated 2026-10-07pewdredd/claude-code-mods/recording-mode
A shopper browsing a rack in a slop shop
Preview · a replayed session in a sandbox
claude · ~/work/app · recording-mode
› fix the failing auth test and add an audit log call ⏺ Read(src/auth.ts) ⎿ Read 6 lines ⏺ Update(src/auth.ts) ⎿ 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 › /record ⎿ recording-mode: Режим записи включён. ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── › ? for shortcuts
README

Моды для Claude Code

Пять модов - маленьких плагинов, которые меняют интерфейс Claude Code: показывают кэш и лимиты, прячут личное на записи экрана, рисуют прогресс цели и не дают двум чатам править один файл вслепую.

Из ролика на канале @amir_aktay.

Установка

В Claude Code:

/plugin marketplace add pewdredd/claude-code-mods
/plugin install cache-keeper@aktay-mods

Остальные ставятся так же, меняется только имя: collision-guard, goal-meter, next-steps, recording-mode. Можно поставить любые по отдельности.

Что делает каждый мод

МодЧто делаетКак пользоваться
cache-keeperНад полем ввода: сколько осталось жить кэшу промпта (60 минут), заполнение контекста, лимиты 5 часов и недели, цена сессии. За 5 минут до остывания кэша - уведомление. Кнопка «перенести сессию»: Claude пишет сводку сессии, потом кнопка «Очистить и продолжить» сама делает /clear и отправляет сводку в чистый чат. Пока включён режим записи, здесь же горит красный «● REC»работает сам
next-stepsПосле ответа - три кнопки «что дальше», одним нажатием отправляют следующий запросработает сам, /next-steps - вкл/выкл
recording-modeПока пишешь экран, прячет в транскрипте почты, ключи, телефоны и суммы. Claude при этом видит всё как есть. Метку «● REC» рисует cache-keeper - ставь их вместе/record on, /record off
goal-meterРазбивает цель на шаги, отдаёт агенту и показывает полоску прогресса. После каждого ответа отмечает готовые шаги/goal-meter <цель>, /goal-meter off
collision-guardЕсли файл в последние 30 минут правил другой чат Claude Code - останавливает правку и просит агента спросить тебя. Повторная правка проходитработает сам

Что важно знать

  • Next Steps и Goal Meter после каждого ответа делают один короткий запрос к модели. Он идёт через кэш, но лимиты всё равно немного расходует.
  • Recording Mode прячет только то, что нарисовано на экране. В сам чат и в файлы идут настоящие данные.
  • Таймер Cache Keeper рассчитан на подписку, где кэш живёт час. На API по умолчанию кэш живёт 5 минут - поменяй CACHE_TTL_MS в cache-keeper/hooks/register.tsx.

Свой мод

Опиши словами, что мод должен показывать и когда, и попроси Claude Code его собрать. Любой мод отсюда - хороший образец: три файла в папке плагина и один register.tsx.

Source 2 files
hooks/register.tsx 50 lines
1import { atom, read, update } from 'claude-code'
2import type { Register } from 'claude-code'
3
4// Recording Mode: пока идёт запись экрана, прячем в транскрипте почты, ключи,
5// телефоны и суммы. Меняется только то, что нарисовано; модель видит оригинал.
6const isOn = atom({ plugin: 'recording-mode', key: 'isOn' } as const, false)
7
8const RULES: Array<[RegExp, string]> = [
9  [/[\w.+-]+@[\w-]+(\.[\w-]+)+/g, '•••@•••'],
10  [/\b(sk|pk|rk|ghp|gho|github_pat|xox[abp])[-_][A-Za-z0-9_-]{8,}/g, '••••••••'],
11  [/\b[A-Fa-f0-9]{32,}\b/g, '••••••••'],
12  [/\+?\d[\d ()-]{8,}\d/g, '••• ••• ••••'],
13  [/[$€₽]\s?\d+(?:[\s,.]\d+)*|\d+(?:[\s,.]\d+)*\s?(?:₽|руб\.?|USD|EUR)/g, '•••'],
14]
15
16function mask(text: string): string {
17  return RULES.reduce((t, [re, to]) => t.replace(re, to), text)
18}
19
20export const register: Register = on => {
21  on('session.start', async ($, e, next) => {
22    await $.command.register({
23      name: 'record',
24      description: 'Режим записи: /record on — прятать личное, /record off — показать',
25      argumentHint: 'on|off',
26    })
27    return next(e)
28  })
29
30  on('command.run', { command: 'record' }, async ($, e) => {
31    const want = e.args.trim() === 'off' ? false : true
32    await update($, isOn, () => want)
33    return { text: want ? 'Режим записи включён.' : 'Режим записи выключен.' }
34  })
35
36  on('ui.render', { component: 'AssistantMessage' }, async ($, e, next) =>
37    (await read($, isOn)) ? next({ ...e, props: { ...e.props, text: mask(e.props.text) } }) : next(e),
38  )
39
40  on('ui.render', { component: 'UserMessage' }, async ($, e, next) =>
41    (await read($, isOn)) ? next({ ...e, props: { ...e.props, text: mask(e.props.text) } }) : next(e),
42  )
43
44  on('ui.render', { component: 'ToolResult' }, async ($, e, next) =>
45    (await read($, isOn)) && typeof e.props.output === 'string'
46      ? next({ ...e, props: { ...e.props, output: mask(e.props.output) } })
47      : next(e),
48  )
49}
50
types/index.d.ts 8 lines
1export type RecordingModeOn = boolean
2
3declare module 'claude-code' {
4  interface PluginState {
5    'recording-mode': { isOn: RecordingModeOn }
6  }
7}
8