SLOPSHOPPER

plain-korean

쉬운 한국어 답변 스타일, 영어로 새는 답변 경고, 가독성 mod 3개, claude-warm 테마를 한 번에 설치한다

newprompt
v0.1.0MITupdated 2026-10-16wonjangcloud9/wj-mods/plain-korean
A shopper browsing a rack in a slop shop
README

wj-mods

English · 한국어

A set of Claude Code mods that change the terminal UI and notifications. They are plugins with hook modules, installable one by one from this marketplace.

The UI text, notifications and summaries are written in Korean.

ModWhat it does
work-progressCollects multi-step work from every open session into a line above the prompt and a /progress pane. Each task's steps are drawn as a chain of nodes that opens into a vertical flow. It also keeps follow-ups left after a task is done, what a paused task is waiting for, and subagent records that ended without being closed. Each open task shows the time likely left, judged from how long its own steps and your recent tasks' steps took. /progress 요약 writes a summary of the last 24 hours.
plain-koreanA Korean readability bundle. An output style for short, plain Korean answers (conclusion first, no made-up abbreviations, nothing referred to by number alone), a guard that flags answers that slip into English and corrects the next one, a nudge to re-explain when you type "뭔 말" or "짧게", and the claude-warm theme. Installing it also installs plain-summary, turn-divider and compact-tool-rows.
usage-bandShows 5-hour and weekly usage and the Claude status page state in one line above the prompt.
long-turn-notifySends a macOS notification and plays a voice line when a turn ran longer than 2 minutes, or when a question or permission prompt is waiting. macOS only.
session-nicknameGives each new session a random name so other sessions can address it with SendMessage. The name reaches the session list with the first prompt.
turn-dividerDraws a divider above each of your prompts to separate questions from answers.
plain-summaryAdds a two-sentence plain-language summary under long, report-style answers, written by a small model.
compact-tool-rowsShortens long Bash commands in tool rows to the start of the first line.

work-progress pane:

업무 3개 · ● 작업 중 1 · □ 남은 일 1 · ✓ 오늘 완료 1

── ● 작업 중 1 ─────────────────────────────────────────────
▸ Theme builder spec
  ●━●━◉─○─○─○ 2/6 · 약 2시간 남음 · 이 단계 1시간째 · 5분 전 · @quiet-otter
  지금: Write the requirements
  최근: Bash Run the mod's tests · 방금
  └ ● Benchmark AI app builders 1/8 · 최근: WebSearch Lovable docs
  └ ‖ Seed starter audit 3/4 · 보류로 끝남 · only saving the file is left
  └ ✓ 서브에이전트 5개 끝남

── □ 남은 일 1 ─────────────────────────────────────────────
▸ Fix lost attachments · 1일 전
  □ push
── ✓ 오늘 완료 1 ───────────────────────────────────────────
▸ Release notes draft · 2시간 전

Click a task to open its steps as a flow, with the time each step took and its evidence:

▾ Theme builder spec
  ● Read the brief · 40분 — notes in brief.md
  ┃
  ● Benchmark · 1시간 20분 — 3 reports
  ┃
  ◉ Write the requirements  ← 지금
  │
  ○ Design

Install

From the marketplace:

claude plugin marketplace add wonjangcloud9/wj-mods
claude plugin install work-progress@wj-mods

Install other mods the same way with <mod>@wj-mods. They load in sessions started after installing.

The Korean readability bundle installs plain-summary, turn-divider and compact-tool-rows with it:

claude plugin install plain-korean@wj-mods

The output style and the theme are not switched on for you. Choose plain-korean as the output style in /config, and claude-warm in /theme if you want the colors too.

From a local clone, list the mod folders in CLAUDE_CODE_PLUGIN_DIRS in ~/.claude/settings.json, separated by :. Folders listed this way do not pull in dependencies, so list the bundle's three mods as well:

git clone https://github.com/wonjangcloud9/wj-mods.git ~/wj-mods
{
  "env": {
    "CLAUDE_CODE_PLUGIN_DIRS": "/Users/me/wj-mods/work-progress:/Users/me/wj-mods/usage-band"
  }
}

Notes

  • Tested with Claude Code 2.1.301.
  • long-turn-notify records its voice lines with the macOS say Yuna voice on first use and keeps them in ~/.claude/long-turn-notify/sounds/. Without that voice it shows the notification silently.
  • plain-summary calls a small model once per long answer, which counts toward your usage.
  • work-progress keeps its records in ~/.claude/work-progress/ on your machine.
  • Run a mod's tests with claude plugin test <mod folder>.

License

MIT

Source 3 files
hooks/register.ts 42 lines
1import type { Register } from 'claude-code'
2
3import { clarityAsk, type ClarityAsk } from './clarity'
4import { isEnglishAnswer } from './language'
5
6const NOTICE = '답변 규칙: 답변이 영어로 쓰였습니다. 다음 턴에 한글로 쓰도록 알려 둡니다.'
7
8const REMINDER =
9  '직전 답변을 영어로 썼다. 사용자는 답변, 중간 보고, 완료 요약을 모두 한글로 받기를 원한다. ' +
10  '이번 답변은 한글로 쓰고, 직전 답변 내용이 아직 필요하면 한글로 다시 정리한다. 코드 식별자, 경로, 명령, 오류 원문은 원래 표기로 둔다.'
11
12const CLARITY: Record<ClarityAsk, string> = {
13  confused:
14    '사용자가 직전 설명을 이해하지 못했다. 첫 문장에 결론을 쓴다. 직전 답에 나온 낯선 말, 줄임말, 번호를 그대로 반복하지 말고 무슨 뜻인지 풀어 쓴다. ' +
15    '구체적인 예를 하나 든다. 제목과 표 없이 5줄 안으로 쓴다. 사용자가 정해야 할 것이 있으면 선택지마다 고르면 무엇이 달라지는지 한 줄로 쓴다.',
16  shorter: '사용자가 짧은 답을 원한다. 결론부터 3줄 안으로 쓴다. 제목, 표, 근거 목록, 커밋 해시는 빼고 꼭 필요한 것만 남긴다.',
17}
18
19// 영어로 쓴 답변 아래에 경고를 붙이고, 다음 프롬프트에 한 번만 교정 지시를 넣는다.
20// "뭔 말", "짧게" 같은 짧은 프롬프트에는 쉽게 다시 쓰라는 지시를 붙인다.
21export const register: Register = on => {
22  let isPending = false
23
24  on('turn.complete', async ($, e, next) => {
25    const result = await next(e)
26    if (e.agentId !== undefined || e.reason !== 'answer') return result
27    if (!isEnglishAnswer(e.answer)) return result
28
29    isPending = true
30    return { ...result, text: NOTICE }
31  })
32
33  on('prompt.submit', ($, e, next) => {
34    const ask = clarityAsk(e.text)
35    const added = [...(isPending ? [REMINDER] : []), ...(ask ? [CLARITY[ask]] : [])]
36    if (added.length === 0) return next(e)
37
38    isPending = false
39    return next({ ...e, context: [...(e.context ?? []), ...added] })
40  })
41}
42
hooks/clarity.ts 14 lines
1export type ClarityAsk = 'confused' | 'shorter'
2
3const CONFUSED = /뭔 ?말|뭔 ?소리|무슨 ?말|무슨 ?소리|이해가 ?안|이해 ?못|알아듣게|하나도 모르|안 ?그려|추상적|어쩌란/
4const SHORTER = /짧게|요약해|요약 ?좀|요약본|간단히|간단하게|쉽게 (?:말|설명|정리)|핵심만|한 ?줄로|너무 길/
5// 긴 프롬프트는 작업 지시라서 그 안의 "요약" 같은 말은 답변 방식 요청이 아닐 때가 많다.
6const MAX_PROMPT_CHARS = 300
7
8export function clarityAsk(text: string): ClarityAsk | undefined {
9  if (text.length > MAX_PROMPT_CHARS) return undefined
10  if (CONFUSED.test(text)) return 'confused'
11  if (SHORTER.test(text)) return 'shorter'
12  return undefined
13}
14
hooks/language.ts 30 lines
1const FENCED_CODE = /```[\s\S]*?```/g
2const INLINE_CODE = /`[^`\n]*`/g
3const URL = /\bhttps?:\/\/\S+/g
4const PATH = /\S*\/\S*/g
5const HANGUL = /[가-힣]/g
6const LATIN = /[A-Za-z]/g
7
8// 한글 한 음절은 영문 두 글자 정도의 분량으로 본다.
9const HANGUL_WEIGHT = 2
10const MIN_LATIN = 80
11const MAX_HANGUL_SHARE = 0.25
12
13function count(text: string, pattern: RegExp): number {
14  return text.match(pattern)?.length ?? 0
15}
16
17// 코드, 경로, 주소를 뺀 본문이 영어로 쓰였는지 본다. 기술 용어가 섞인 한글 답변과 짧은 영어 한 줄은 통과한다.
18export function isEnglishAnswer(answer: string): boolean {
19  const prose = answer
20    .replace(FENCED_CODE, ' ')
21    .replace(INLINE_CODE, ' ')
22    .replace(URL, ' ')
23    .replace(PATH, ' ')
24  const latin = count(prose, LATIN)
25  if (latin < MIN_LATIN) return false
26
27  const hangul = count(prose, HANGUL) * HANGUL_WEIGHT
28  return hangul / (hangul + latin) < MAX_HANGUL_SHARE
29}
30