번역 준비 중이 mod 소개
So I got my weekly mail from Lydia and saw something very exciting: Claude Code now supports mods, plugins written as function hooks that can draw UI inside the app, in both the terminal and the desktop app. So I went through the docs and built the suggested weather band, very nice. Then what else can I do with it? I recently started using Ponytail with great success and wanted to know what level it's running at, so let's add that… and after that, why not Caveman as well. Bottom line, great fun and very useful. Here's what I learned, then what I made. How a mod draws UI A mod hooks ui.render for a spot like AbovePrompt and returns a tree of a few elements ( Box , Text , Button , Select , Link , Svg ), laid out with flexbox. Not HTML, no CSS. The smallest band is about this: on('ui.render', { component: 'AbovePrompt' }, async ($, e) => { const { Box, Text } = $.ui.resolve(e) return <Box flexDirection="row"><Text>hello from a mod</Text></Box> }) How I did config inline The config took a few goes This was the fun part, because the UI is so limited: Settings live in /config , but that doesn't exist in the desktop app. So first a /overalls weather minimal command, then a ⚙ button that typed /overalls into the prompt for you. Works, but two clicks. Next a dropdown ( Select ). One dropdown can only hold one value, so it showed "Weather: off" as selected while weather was clearly on. Fixed with a dummy ⚙ option at the top. Then I wanted ticks lined up at the end, and groups, and submenus… none of that exists. An option is just a value and a label, no styling. Right-click menu? No such event. Tooltips? No tooltip prop either. You can fake one with a hidden box that shows on hover, but it can't leave the band, so on the bar it covered the very thing it was explaining. Kept them only in the config. So in the end I built my own: ⚙ opens a bordered Config box inside the band, above the bar, so you see each change happen as you click. Every option is a plain button with a ✓ on the current one. Related switches share a row behind a │ (megacave sits next to Caveman, resets next to Limits). Then the band hit its height cap (half the window), so the settings went into two bordered columns. Other gotchas A bare <Box> stacks vertically in the desktop app. Always set flexDirection="row" if you want a row. Flex items shrink by default, so the desktop app wraps text inside a widget. flexShrink={0} plus a wrapping parent fixes it, and the ⚙ stays put on the first row. There's no API for MCP server status. I infer it from tool-call errors (401s, connection refused), which catches a logged-out connector on its first failure, and Reconnect takes you straight to Customize › Connectors. Ponytail keeps one level file for all your sessions, so every window showed whichever level was set last. I track it per session instead (and opened an issue upstream). State lives in $.state (per session) or $.store (across sessions). Module variables reset on every hot reload. What I made: Overalls Overalls: informative bar in claude code A band that shows context "weather" with a sparkline and roughly how many turns are left, 5h and weekly limits with reset countdowns, MCP errors with a Reconnect button, refused tool calls, running subagents, and Ponytail and Caveman levels as dropdowns. Everything is a toggle in the ⚙ box. claude plugin marketplace add Troepster/overalls claude plugin install overalls@overalls MIT, runs locally, and the README lists everything it reads: https://github.com/Troepster/overalls Anyone else building mods? Would love to see what else people are doing with them. Also please give me some feedback on obvious things I missed. submitted by /u/Troepster [link] [comments]
원문 / README
So I got my weekly mail from Lydia and saw something very exciting: Claude Code now supports mods, plugins written as function hooks that can draw UI inside the app, in both the terminal and the desktop app. So I went through the docs and built the suggested weather band, very nice. Then what else can I do with it? I recently started using Ponytail with great success and wanted to know what level it's running at, so let's add that… and after that, why not Caveman as well. Bottom line, great fun and very useful. Here's what I learned, then what I made. How a mod draws UI A mod hooks ui.render for a spot like AbovePrompt and returns a tree of a few elements ( Box , Text , Button , Select , Link , Svg ), laid out with flexbox. Not HTML, no CSS. The smallest band is about this: on('ui.render', { component: 'AbovePrompt' }, async ($, e) => { const { Box, Text } = $.ui.resolve(e) return <Box flexDirection="row"><Text>hello from a mod</Text></Box> }) How I did config inline The config took a few goes This was the fun part, because the UI is so limited: Settings live in /config , but that doesn't exist in the desktop app. So first a /overalls weather minimal command, then a ⚙ button that typed /overalls into the prompt for you. Works, but two clicks. Next a dropdown ( Select ). One dropdown can only hold one value, so it showed "Weather: off" as selected while weather was clearly on. Fixed with a dummy ⚙ option at the top. Then I wanted ticks lined up at the end, and groups, and submenus… none of that exists. An option is just a value and a label, no styling. Right-click menu? No such event. Tooltips? No tooltip prop either. You can fake one with a hidden box that shows on hover, but it can't leave the band, so on the bar it covered the very thing it was explaining. Kept them only in the config. So in the end I built my own: ⚙ opens a bordered Config box inside the band, above the bar, so you see each change happen as you click. Every option is a plain button with a ✓ on the current one. Related switches share a row behind a │ (megacave sits next to Caveman, resets next to Limits). Then the band hit its height cap (half the window), so the settings went into two bordered columns. Other gotchas A bare <Box> stacks vertically in the desktop app. Always set flexDirection="row" if you want a row. Flex items shrink by default, so the desktop app wraps text inside a widget. flexShrink={0} plus a wrapping parent fixes it, and the ⚙ stays put on the first row. There's no API for MCP server status. I infer it from tool-call errors (401s, connection refused), which catches a logged-out connector on its first failure, and Reconnect takes you straight to Customize › Connectors. Ponytail keeps one level file for all your sessions, so every window showed whichever level was set last. I track it per session instead (and opened an issue upstream). State lives in $.state (per session) or $.store (across sessions). Module variables reset on every hot reload. What I made: Overalls Overalls: informative bar in claude code A band that shows context "weather" with a sparkline and roughly how many turns are left, 5h and weekly limits with reset countdowns, MCP errors with a Reconnect button, refused tool calls, running subagents, and Ponytail and Caveman levels as dropdowns. Everything is a toggle in the ⚙ box. claude plugin marketplace add Troepster/overalls claude plugin install overalls@overalls MIT, runs locally, and the README lists everything it reads: https://github.com/Troepster/overalls Anyone else building mods? Would love to see what else people are doing with them. Also please give me some feedback on obvious things I missed. submitted by /u/Troepster [link] [comments]