ClaudeMods
☰
KO
● 0 명 접속 중 · 조회 0 회
후원프로젝트 제출
GitHub 저장소 · 작성자 lucenity0

seatbelt

Bash, Edit, Write 및 NotebookEdit 도구 호출에 대한 함수 훅을 사용하여 파괴적인 셸 명령 및 비밀 편집이 실행되기 전에 차단하는 Claude Code 플러그인입니다.

번역 완료

이 mod 소개

seatbelt는 lucenity0/claude-code-mods 컬렉션의 일부로, 함수 훅 API를 기반으로 구축된 작은 Claude Code 플러그인 세트입니다. seatbelt 모드는 모든 Bash, Edit, Write 및 NotebookEdit 도구 호출을 가로채고 해를 끼칠 수 있는 호출을 거부합니다. 예를 들어, / 또는 ~ 또는 상위 경로에 대한 rm -rf, 보호된 브랜치에 대한 git push -f, curl | sh 파이프, mkfs, dd of=/dev/..., chmod -R 777, 그리고 .env, .pem 또는 ~/.ssh/ 파일에 대한 편집 등이 있습니다. 규칙은 seatbelt/hooks/rules.ts에 이름, 이유 및 일치 조건자를 가진 작은 객체로 정의되어 있어 감사하거나 확장하기 쉽습니다. 이 플러그인에는 검증된 .claude-plugin/plugin.json과 register.ts를 등록하는 hooks.json이 함께 제공되며, claude --plugin-dir 또는 CLAUDE_CODE_PLUGIN_DIRS를 통해 로드할 수 있습니다. README는 이를 샌드박스보다는 사고 방지 가드레일로 설명하며, 설치 지침, 규칙 코드 샘플, 차단된 명령과 허용된 명령 표를 포함합니다.

설치

먼저 작성자의 README에서 marketplace와 플러그인 이름을 확인하세요. 저장소 구조에 따라 명령어가 달라질 수 있습니다.

claude plugin marketplace add lucenity0/claude-code-mods
claude plugin install seatbelt
원문 / README

claude-code-mods

Small plugins for Claude Code. Each mod is one TypeScript file of function hooks.

<img src="assets/hero.svg" alt="Claude Code with all four mods running: seatbelt blocking a dangerous rm, the session-dash pane, the turn-meter status line and a ding toast" width="900">
turn-meter     a turn timer in the status line
seatbelt       blocks destructive commands and edits to secrets
ding           a chime when a long turn finishes
session-dash   /dash, a live pane of what the session did
context-meter  a context window meter under the prompt; click it for the breakdown

Also: claude-familiar, a pixel companion that sits above the prompt and reacts to your session, and claude-readout, which names the files on the folded Read 3 files line.

 

install

git clone https://github.com/lucenity0/claude-code-mods ~/claude-code-mods
claude --plugin-dir ~/claude-code-mods/seatbelt --plugin-dir ~/claude-code-mods/session-dash

To turn on function hooks and load the mods in every session, set this in ~/.claude/settings.json:

{
  "env": {
    "CLAUDE_CODE_ENABLE_FUNCTION_HOOKS": "1",
    "CLAUDE_CODE_PLUGIN_DIRS": "~/claude-code-mods/turn-meter:~/claude-code-mods/seatbelt:~/claude-code-mods/ding:~/claude-code-mods/session-dash:~/claude-code-mods/context-meter"
  }
}

These use function hooks, an early-access API that CLAUDE_CODE_ENABLE_FUNCTION_HOOKS turns on, and were tested on Claude Code 2.1.287.

 

turn-meter

The status line counts up while Claude works. When the turn ends it shows the summary.

✓ 41s · 12.3k in · 1.8k out
on('turn.start', ($, e, next) => {
  ticker?.cancel()
  let seconds = 0
  $.ui.status('running 0s')
  ticker = $.clock.every(1000, () => {
    seconds += 1
    $.ui.status(`running ${formatDuration(seconds * 1000)}`)
  })

  return next(e)
})

 

seatbelt

Checks every Bash, Edit and Write call before it runs, and denies the ones that would hurt.

● Bash(rm -rf /tmp/build/../../)
  ⎿  seatbelt: blocked `rm -rf /tmp/build/../../` (rm -rf on / or ~): it
     recursively deletes the filesystem root, a top-level folder or your home folder…
blocks                                  still allows
rm -rf /   rm -fr ~   rm -rf /x/../../  rm -rf node_modules
git push -f origin main                 git push --force origin my-branch
curl … | sh                             curl -o install.sh …
mkfs   dd of=/dev/…   chmod -R 777      chmod 755 script.sh
edits to .env  *.pem  ~/.ssh/*          .env.example

Each rule is a small object in rules.ts:

{
  name: 'curl | sh',
  reason: 'pipes a script from the internet straight into a shell',
  matches: command => /\b(curl|wget)\b[^|]*\|\s*(sudo\s+)?(ba|z|da)?sh\b/.test(command),
}

It's a guardrail against accidents, not a sandbox.

 

ding

When a turn that ran longer than 30 seconds finishes, ding shows a toast and plays an original two-note chime. The sound plays on macOS only.

{ "pluginConfigs": { "ding": { "options": { "thresholdSeconds": 60, "sound": false } } } }

 

session-dash

Type /dash to open the pane. Type /dash again, or press q, to close it.

╭─ Session ─────────────────────────────╮
│ 4 turns · 2m13s · 184k in · 9.2k out  │
│                                       │
│ Tools (23 calls)                      │
│ Bash  ████████████████████ 9          │
│ Read  ███████████████ 7               │
│ Edit  █████████ 4                     │
│                                       │
│ Turn time · max 1m12s                 │
│ ▂▄▃▆▁▅█▃▄▁▆▃                          │
│                                       │
│ Recent files                          │
│ src/server.ts                         │
│ README.md                             │
│                                       │
│ [ Reset ]  [ Close ]                  │
╰───────────────────────────────────────╯
on('tool.call', async ($, e, next) => {
  const ran = await next(e)
  await update($, stats, current =>
    countTool(current, e.tool, { isDenied: ran.deny !== undefined, isError: ran.isError === true }),
  )

  return ran
})

 

context-meter

A meter sits at the bottom right of the prompt, under the input. It turns yellow at 60% and red at 80%.

ctx ▰▰▰▱▱▱▱▱ 42%

Click it, or type /ctx, to open the breakdown. Esc closes it.

42%  84k of 200k                                     claude-opus-5-5 · estimated
██████████████████████████▌█░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▒▒▒▒▒
83k free · compacts in 83k

● Messages                 62k  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━   74%
● System tools             13k  ━━━━━━━━                                15%
● Skills                  4.9k  ━━━                                      6%
● System prompt           3.7k  ━━                                       4%
○ on demand                93k  MCP tools, not in the window

last request 84k in · 82k cached · 967 out

memory
  CLAUDE.md   ~/code/app                                             900

[ Count exactly ]  [ Refresh ]  [ Compact ]  [ Close ]

The breakdown is a local estimate. Count exactly counts it with the token-count API, as /context does.

on('session.measure', async ($, e, next) => {
  await update($, fill, () => e.context)
  if (e.changed.includes('context') && (await isPaneOpen($))) void loadDetails($, 'summary')

  return next(e)
})

 

make one

hello/
├── .claude-plugin/plugin.json    { "name": "hello", "version": "0.1.0", "description": "…" }
└── hooks/
    ├── hooks.json                { "modules": ["./register.ts"] }
    └── register.ts
import type { Register } from 'claude-code'

export const register: Register = on => {
  on('tool.call', { tool: 'Edit' }, async ($, e, next) => {
    const result = await next(e)
    $.ui.toast(`edited ${e.file_path.split('/').pop()}`)
    return result
  })
}
claude plugin validate ./hello
claude plugin test ./hello

 


<sub>MIT · built with Claude Code</sub>

비슷한 프로젝트