SLOPSHOPPER

quiet

Hide tool call rows so the transcript shows only the conversation. Toggle with /quiet.

newspinnerrowscommandtoast
★ 2v0.3.0MITupdated 2026-10-24kimjisub/agent-kit/plugins/quiet
A shopper browsing a rack in a slop shop
Preview · a replayed session in a sandbox
claude · ~/work/app · quiet
› fix the failing auth test and add an audit log call ╭────────────────────────────╮ │ quiet │ ⏺ Read(src/auth.ts) │ Quiet on: tool rows hidden │ ⎿ Read 6 lines ╰────────────────────────────╯ ⏺ 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 › /quiet ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── › ? for shortcuts
README

quiet

Hides tool call rows, running ones included, so the transcript shows only the conversation. Only the drawing changes: the stored transcript and the model's context stay as they were.

  • /quiet toggles it. The choice is kept across sessions
  • While on, the footer's mode labels show quiet
  • ctrl+o still shows the full transcript, background task rows included
/plugin install quiet --marketplace kimjisub/agent-kit

Checked on Claude Code 2.1.304. It needs a Claude Code build with function hooks (hooks/hooks.json naming a modules entry).

Tests: claude plugin test plugins/quiet.


도구 호출 줄(실행 중인 것 포함)을 숨겨 대화만 보이게 합니다. 화면에 그리는 것만 바뀌고, 저장된 대화와 모델이 보는 맥락은 그대로입니다. /quiet 로 켜고 끄며, 고른 상태는 다음 세션에도 남습니다. 켜져 있으면 아래 모드 표시에 quiet 가 붙습니다. ctrl+o 로는 전체 기록을 그대로 볼 수 있습니다.

Source 1 files
hooks/register.ts 74 lines
1// quiet: hides tool call rows, running ones included, so the transcript shows only the conversation.
2// Only the drawing changes; the stored transcript and the model's context stay as they were.
3import type { EngineInterface, Register, RenderInput } from 'claude-code'
4
5const COMMAND = 'quiet'
6const STORE_KEY = 'enabled'
7
8// Module variables start over on every load, so the stored choice is read lazily.
9let quiet: boolean | undefined
10
11async function isQuiet($: EngineInterface): Promise<boolean> {
12  if (quiet === undefined) {
13    quiet = await $.store.get(STORE_KEY).then(
14      value => value === true,
15      () => false,
16    )
17  }
18  return quiet
19}
20
21function hiddenRow($: EngineInterface, e: RenderInput) {
22  const { Box } = $.ui.resolve(e)
23  return Box({ display: 'none' })
24}
25
26export const register: Register = on => {
27  on('session.start', async ($, e, next) => {
28    quiet = undefined
29    await isQuiet($)
30    await $.command.register({
31      name: COMMAND,
32      description: 'Toggle hiding tool call rows so only the conversation shows',
33      // Only a drawing flag changes, so it can run while a turn streams.
34      immediate: true,
35    })
36    return next(e)
37  })
38
39  on('command.run', { command: COMMAND }, async $ => {
40    const next = !(await isQuiet($))
41    try {
42      await $.store.set(STORE_KEY, next)
43    } catch (error) {
44      $.ui.toast(`Quiet unchanged: ${error instanceof Error ? error.message : String(error)}`)
45      return {}
46    }
47    quiet = next
48    $.ui.invalidate('ui.render')
49    $.ui.toast(next ? 'Quiet on: tool rows hidden' : 'Quiet off: tool rows shown')
50    return {}
51  })
52
53  // The footer's mode labels say Quiet is on, beside the engine's own (`focus`, ...).
54  on('ui.render', { component: 'SessionMode' }, async ($, e, next) =>
55    (await isQuiet($)) ? next({ ...e, props: { ...e.props, modes: [...e.props.modes, COMMAND] } }) : next(e),
56  )
57  on('ui.render', { component: 'ToolUse' }, async ($, e, next) =>
58    (await isQuiet($)) ? hiddenRow($, e) : next(e),
59  )
60  on('ui.render', { component: 'ToolResult' }, async ($, e, next) =>
61    (await isQuiet($)) ? hiddenRow($, e) : next(e),
62  )
63  on('ui.render', { component: 'ToolGroup' }, async ($, e, next) =>
64    (await isQuiet($)) ? hiddenRow($, e) : next(e),
65  )
66  // A background task's `finished` row is the tail of a tool call; ctrl+o still shows it.
67  on('ui.render', { component: 'UserMessage', props: { origin: { kind: 'task-notification' } } }, async ($, e, next) =>
68    (await isQuiet($)) && !e.props.isExpanded ? hiddenRow($, e) : next(e),
69  )
70  on('ui.render', { component: 'ToolProgress' }, async ($, e, next) =>
71    (await isQuiet($)) ? hiddenRow($, e) : next(e),
72  )
73}
74