zyx1121/music-mod
music-mod
/music: macOS Music.app에서 재생 중인 내용을 프롬프트 위 한 줄에 표시합니다. 클릭 가능한 재생/일시정지 아이콘, track · artist · album, 시계가 있는 진행률 막대, 클릭 가능한 다음 곡 아이콘을 제공합니다. Music.app은 5초마다 한 번 읽고 열린 모든 세션이 공유하며 그 사이 시계가 움직입니다.
이 mod 소개
music-mod
/musicfor Claude Code: Music.app에서 재생 중인 내용을 프롬프트 위 한 줄에 실시간으로 표시합니다. 재생/일시정지와 다음 곡으로 이동은 클릭할 수 있습니다.
claude-code · mod · function-hooks · macos · music · now-playing
▶️ Tipsy · WANUKA · Greenhorn ████████████░░░░░░░░ 2:43 / 3:39 ⏭️
<sub>모든 레이아웃에서 프롬프트 바로 위에 표시되는 줄입니다. 표시되는 동안 시계가 매초 움직이며 ▶️와 ⏭️를 클릭할 수 있습니다.</sub>
긴 세션에는 사운드트랙이 있지만 Music.app을 열어 재생 내용을 확인하면 흐름이 끊깁니다. 이 mod는 지금 보고 있는 터미널 안에서 한 명령으로 곡, 재생 위치, 일시정지 또는 건너뛰기를 위한 두 아이콘을 보여 줍니다.
이것은 Claude Code mod입니다. 동작은 TypeScript hooks 모듈에 있는 플러그인으로 구현되고 내장 /diff pane과 같은 엔진 API를 사용합니다. AbovePrompt 줄에 그리므로 transcript가 전체 화면이든 인라인이든 입력 위에 놓이며 side dock은 사용하지 않습니다. shell hooks와 MCP server는 없고, 열린 세션 수와 관계없이 5초마다 osascript를 한 번 호출합니다.
설치
function hooks는 early access이므로 플래그를 켰을 때만 엔진이 mod를 로드합니다. 셸 프로필에 추가하세요.
export CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1
GitHub 또는 로컬 clone에서 플러그인으로 설치합니다.
/plugin marketplace add zyx1121/music-mod
/plugin install music-mod@music-mod
설치하지 않고 한 세션에서 시험할 수도 있습니다.
claude --plugin-dir /path/to/music-mod
대화형 세션이 시작되면 줄이 바로 표시됩니다. 세션에서 다음을 실행합니다.
/music hide it, or show it again
마지막 선택은 세션 사이에도 기억됩니다.
macOS 전용입니다. Apple events를 통해 Music.app을 읽습니다. 첫 번째 읽기에서 터미널이 Music을 제어하도록 허용할지 물을 수 있습니다.
읽기는 Music.app을 실행하지 않습니다. 종료하는 중에 읽기가 발생해도 마찬가지입니다. 이벤트는 ID로 실행 중인 프로세스에 보내고, 종료된 프로세스는 닫힌 것으로 읽습니다. 상태 아이콘 또는 ⏭️를 클릭할 때만 이름으로 Music.app과 통신합니다.
표시 내용
왼쪽에서 오른쪽으로 한 줄입니다.
| 부분 | 내용 |
|------|---------|
| ▶️ ⏸️ ⏩ ⏪ | 플레이어 상태입니다. 클릭하면 재생 또는 일시정지합니다. |
| Title | track · artist · album이며 줄이 좁으면 생략 부호로 자릅니다 |
| Bar | 제목이 남긴 너비(최소 6 cells)를 채우도록 진행률을 늘린 뒤 position / duration을 표시합니다 |
| ⏭️ | 클릭하면 다음 곡으로 건너뜁니다. |
Music.app이 닫혔거나 중지되면 줄에 그 상태를 표시합니다. osascript가 실패하면(권한 없음, 시간 초과) 이유를 표시하고 계속 폴링합니다. 줄을 차지하는 survey가 있으면 자리를 양보합니다.
구성
| Field | Type | Default | What it does |
|-------|------|---------|--------------|
| refreshMs | number | 5000 | 줄이 표시된 동안 Music.app을 읽는 간격(밀리초)입니다. 열린 각 세션이 간격마다 한 번의 읽기를 공유하고 그 사이 시계가 움직입니다. 최솟값은 1000입니다. |
| showOnStart | boolean | true | 대화형 세션이 시작되는 즉시 줄을 표시합니다. /music을 사용한 뒤에는 이 설정보다 마지막 선택이 우선합니다. |
플러그인의 userConfig 필드로 설정합니다. /config를 사용하거나 설정에 music-mod.refreshMs를 적습니다.
구현 방식
hooks/register.ts는register(on, options)를 export합니다.session.start에서/music을 등록하고$.store의 마지막/music선택(없으면showOnStart)에 따라 줄을 표시합니다.command.run은 이를 전환하고 기억합니다. 1초마다 실행되는$.clock.everytick은 마지막 읽기에서 시계를 다시 그리며refreshMs가 지났거나 곡이 끝나면 새로 읽습니다.session.end에서 타이머를 취소하고, 누른 아이콘은 AppleScript를 실행해 즉시 읽습니다.hooks/now-playing.ts에는osascript -l JavaScript가 실행하는 JXA 스크립트, JSON을Model로 바꾸는 파서, 시계와 진행률 막대 포맷터, 읽기 사이에 전달되는 위치, 각 아이콘 뒤의 한 줄 AppleScript가 있습니다. 스크립트는 줄에 그릴 내용만 요청합니다. 시스템 볼륨은 읽지 않고(읽으면coreaudiod가 깨어남) 재생 목록도 순회하지 않습니다.hooks/shared-read.ts는 모든 세션이 공유하는 읽기입니다.$TMPDIR/music-mod/now.json의 작은 JSON 파일을 사용합니다. 충분히 최신이면 세션이 그 값을 사용하고, 아니면 파일을 확보해osascript를 실행하고 결과를 기록하여 다른 세션이 각자 실행하지 않고 기다리게 합니다.hooks/views/band-view.tsx는ui.render의AbovePromptcomponent에서 엔진의Box,Text,Button으로Model을 그립니다.types/claude-code.d.ts는 이 mod가 타입을 지정하는 엔진 계약이며anthropics/claude-code/mods/types에서 복사했습니다.
bunx -p typescript tsc -p tsconfig.json # typecheck
CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1 claude plugin test . # 35 tests, the engine's own harness
이 mod가 사용하는 API는 예고 없이 릴리스 사이에서 바뀔 수 있습니다. 바뀌면 upstream에서 types/claude-code.d.ts를 새로 받고 typecheck가 이동한 부분을 가리키게 하세요.
기여
Issue와 PR을 환영합니다. 기본 규칙은 CONTRIBUTING.md에 있습니다.
라이선스
MIT · now playing: whatever you left on
설치
먼저 작성자의 README에서 marketplace와 플러그인 이름을 확인하세요. 저장소 구조에 따라 명령어가 달라질 수 있습니다.
claude plugin marketplace add zyx1121/music-mod claude plugin install music-mod
원문 / README
music-mod
/musicfor Claude Code: what Music.app is playing, in one line above the prompt, live, with play/pause and next a click away.
claude-code · mod · function-hooks · macos · music · now-playing
▶️ Tipsy · WANUKA · Greenhorn ████████████░░░░░░░░ 2:43 / 3:39 ⏭️
<sub>The band directly above the prompt, in any layout. Its clock ticks every second while shown; ▶️ and ⏭️ are clickable.</sub>
Long sessions have a soundtrack, and reaching for Music.app to check what is on breaks the flow. This mod keeps the answer one command away, inside the terminal you are already looking at: the track, where it is, and two glyphs to pause it or skip it.
It is a Claude Code mod: a plugin whose behaviour lives in a TypeScript hooks module, written against the same engine API as the built-in /diff pane. It draws into the AbovePrompt band, so it sits above the input whether the transcript is fullscreen or inline, and never takes a side dock. No shell hooks, no MCP server, and one osascript call every five seconds however many sessions are open.
Install
Function hooks are early access, so the engine loads a mod only with the flag on. Put it in your shell profile:
export CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1
Then install it as a plugin, from GitHub or from a local clone:
/plugin marketplace add zyx1121/music-mod
/plugin install music-mod@music-mod
Or try it for one session without installing:
claude --plugin-dir /path/to/music-mod
The line shows as soon as an interactive session starts. In the session:
/music hide it, or show it again
Your last choice is remembered between sessions.
macOS only: it reads Music.app through Apple events. The first read may ask you to allow your terminal to control Music.
Reading never launches Music.app, not even when a read lands while you quit it: the events go to the running process by its ID, and a process that has gone reads as closed. Only a click on the state glyph or ⏭️ talks to Music.app by name.
What it shows
One line, left to right:
| Part | Content |
|------|---------|
| ▶️ ⏸️ ⏩ ⏪ | The player state. Click it to play or pause. |
| Title | track · artist · album, cut with an ellipsis when the band is narrow |
| Bar | Progress, stretched to fill whatever width the title leaves (6 cells at the least), then position / duration |
| ⏭️ | Click it to skip to the next track. |
When Music.app is closed or stopped the band says so instead. When osascript fails (not authorized, timed out), the band shows the reason and keeps polling. A survey that takes the band is yielded to.
Configuration
| Field | Type | Default | What it does |
|-------|------|---------|--------------|
| refreshMs | number | 5000 | Milliseconds between reads of Music.app while the band is shown. Every open session shares one read per interval, and the clock ticks in between. Floored at 1000. |
| showOnStart | boolean | true | Show the line as soon as an interactive session starts. Once you have used /music, that choice wins over this. |
Set it as any plugin userConfig field: /config, or music-mod.refreshMs in settings.
How it is built
hooks/register.tsexportsregister(on, options). Onsession.startit registers/musicand shows the band (the last/musicchoice from$.store, elseshowOnStart);command.runtoggles it and remembers; a one-second$.clock.everytick redraws the clock from the last reading and, oncerefreshMshas passed (or the track has run out), takes a new one; the timer is cancelled onsession.end; a pressed glyph runs its AppleScript and reads at once.hooks/now-playing.tsholds the JXA scriptosascript -l JavaScriptruns, the parser that turns its JSON into aModel, the clock and progress-bar formatters, the position carried forward between reads, and the one-line AppleScript behind each glyph. The script asks only for what the band draws: no system volume (reading it wakescoreaudiod) and no playlist walk.hooks/shared-read.tsis the reading every session shares: a small JSON file at$TMPDIR/music-mod/now.json. A session takes the reading there when it is recent enough, else claims the file, runsosascriptand writes the result back, so the other sessions wait for it instead of running their own.hooks/views/band-view.tsxdraws theModelwith the engine'sBox,TextandButtononui.renderfor theAbovePromptcomponent.types/claude-code.d.tsis the engine contract this mod is typed against, copied fromanthropics/claude-code/mods/types.
bunx -p typescript tsc -p tsconfig.json # typecheck
CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1 claude plugin test . # 35 tests, the engine's own harness
The API these mods are written against may change between releases without notice. When it does, refresh types/claude-code.d.ts from upstream and let the typecheck point at what moved.
Contributing
Issues and PRs are welcome. Ground rules live in CONTRIBUTING.md.
License
MIT · now playing: whatever you left on

