zyx1121/music-mod
music-mod
/music:macOS Music.app の再生内容を、プロンプトの上の 1 行で表示します。クリックできる再生/一時停止アイコン、track · artist · album、時計付きの進捗バー、クリックできる次の曲アイコンを備えます。Music.app は 5 秒ごとに 1 回読み取り、開いているすべてのセッションで共有します。その間も時計は進みます。
この mod について
music-mod
/musicfor Claude Code:Music.app の再生内容を、プロンプトの上にある 1 行でリアルタイム表示します。再生/一時停止と次の曲への移動はクリックできます。
claude-code · mod · function-hooks · macos · music · now-playing
▶️ Tipsy · WANUKA · Greenhorn ████████████░░░░░░░░ 2:43 / 3:39 ⏭️
<sub>どのレイアウトでもプロンプトの直上に表示されるバンドです。表示中は時計が毎秒進み、▶️ と ⏭️ をクリックできます。</sub>
長いセッションには音楽が必要ですが、再生中の内容を確認するために Music.app を開くと流れが途切れます。この mod なら、今見ているターミナル内で、曲名、再生位置、一時停止またはスキップ用の 2 つのアイコンを 1 コマンドで確認できます。
これは Claude Code mod です。動作は TypeScript の hooks モジュールにあるプラグインで、組み込みの /diff ペインと同じエンジン API を使います。AbovePrompt バンドに描画するため、逐字稿が全画面でもインラインでも入力の上に表示され、サイドドックは使いません。shell hooks も MCP server もなく、セッション数にかかわらず osascript を 5 秒ごとに 1 回呼び出します。
インストール
function hooks は早期アクセスのため、フラグを有効にした場合だけエンジンが mod を読み込みます。shell のプロファイルに追加します。
export CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1
GitHub またはローカル clone からプラグインとしてインストールします。
/plugin marketplace add zyx1121/music-mod
/plugin install music-mod@music-mod
インストールせず、1 つのセッションで試すこともできます。
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 と通信します。
表示内容
左から右に 1 行で表示します。
| 部分 | 内容 |
|------|---------|
| ▶️ ⏸️ ⏩ ⏪ | プレーヤーの状態。クリックすると再生または一時停止します。 |
| Title | track · artist · album。バンドが狭いと省略記号で切り詰めます |
| Bar | タイトルが残した幅(最低 6 セル)いっぱいに進捗を伸ばし、その後に位置 / 再生時間を表示します |
| ⏭️ | クリックすると次の曲へ移動します。 |
Music.app が閉じているか停止している場合は、バンドがその状態を表示します。osascript が失敗した場合(未承認、タイムアウト)は、理由を表示してポーリングを続けます。バンドを必要とする survey には場所を譲ります。
設定
| Field | Type | Default | What it does |
|-------|------|---------|--------------|
| refreshMs | number | 5000 | バンド表示中に Music.app を読み取る間隔(ミリ秒)。開いている各セッションは間隔ごとに 1 回の読み取りを共有し、その間も時計は進みます。最小値は 1000。 |
| showOnStart | boolean | true | インタラクティブセッションの開始直後に行を表示します。/music を使った後は、その選択がこの設定より優先されます。 |
プラグインの userConfig フィールドとして設定します。/config を使うか、設定に music-mod.refreshMs を指定します。
仕組み
hooks/register.tsはregister(on, options)をエクスポートします。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に変換するパーサー、時計と進捗バーのフォーマッター、読み取り間で引き継ぐ位置、各アイコンの背後にある 1 行 AppleScript が入っています。スクリプトが求めるのはバンドが描く内容だけです。システム音量は読みません(読み取りでcoreaudiodが起きるため)。プレイリストも走査しません。hooks/shared-read.tsは全セッションで共有する読み取りです。$TMPDIR/music-mod/now.jsonに小さな JSON ファイルを置きます。十分新しければそこから読み取り、そうでなければファイルを取得してosascriptを実行し、結果を書き戻します。他のセッションは自分で実行せずに待ちます。hooks/views/band-view.tsxはui.renderのAbovePromptコンポーネントで、エンジンの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 は、通知なくリリース間で変わる可能性があります。その場合は上流から types/claude-code.d.ts を更新し、型チェックで移動箇所を確認してください。
コントリビュート
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

