# The shell `blob-shell` is one long-running Quickshell process hosting the bar, panels, notifications, lock screen, OSD, and both menus. Everything runs inside it as a plugin, so summoning a panel is an IPC call into a process that is already up. ## Layout ``` shell/ shell.qml entry point Commons/ Style, Color, Border, Util Ui/ shared components services/ plugin registry, bar widget registry, app library plugins/ bar/ the bar and its widgets menu/ both menus notifications/ daemon, popups, DND, history notification-center/ agents/ Claude Code usage limits and token stats lock/ polkit/ osd/ background/ clipboard/ emojis/ image-picker/ reminders/ panels/ audio bluetooth clock disk-speedtest monitor network power quick-settings speedtest sysmon weather wifiqr services/ battery idle media nightlight ``` First-party plugins are discovered under `shell/plugins` at a depth of two or three and are enabled without being listed anywhere. Third-party plugins live in `~/.config/blob/plugins//` and are enabled through `shell.json`. ## Config `shell.json` is the whole bar config. It hot-reloads on save, and dragging a bar widget rewrites `~/.config/blob/shell.json` directly, so after rearranging by hand copy it back: ``` cp ~/.config/blob/shell.json shell.json ``` `./install.sh --check` reports the drift. Defaults live at `config/blob/shell.json`. A valid user file replaces them entirely rather than merging. ## Bar layout | Section | Widgets | | --- | --- | | left | `blob.menu`, `blob.workspaces` | | center | `blob.clock` (anchored), `blob.system-update` | | right | `blob.tray`, `blob.agents`, `blob.bluetooth`, `blob.network`, `blob.audio`, `blob.monitor`, `blob.power`, `blob.notifications` | `blob.clock` and `blob.notifications` are `type: "command"` modules, which is how they carry their own click actions: the clock opens quick settings on left click, the shell's calendar on middle, and the timezone picker on right; the bell opens the notification centre on left and toggles silencing on right. The bell runs `blob-notification-bell` every 3 seconds and turns into a crossed-out bell while notifications are silenced. The centre module named by `centerAnchor` cannot be dragged out of the centre. Every other widget still reorders. ## Agents `blob.agents` is Omarchy's agents panel (quattro branch), trimmed to Claude Code. The panel shows the plan, a line per limit window (session, weekly, and any model-scoped weekly allowance as a tick on the weekly meter) with the time until it resets, and a rotating summary of local token stats: tokens this week and today, the most used model, the busiest day, and today's prompts and sessions. The exact percentage is on hover. | Input | Action | | --- | --- | | left click | open the panel | | right click, Enter, the hero button | start Claude Code in a terminal | | middle click, `r` | refresh | | Tab | move to the neighboring bar panel | The icon turns urgent when a window reaches 90%. Records refresh every `refreshIntervalSec` (900 by default) and the limits again whenever the panel opens. `blob-agent-usage-claude` builds the record. Limits come from Anthropic's OAuth usage endpoint with the token in `~/.claude/.credentials.json`; token stats come from the transcripts in `~/.claude/projects`, with `stats-cache.json` and `history.jsonl` as fallbacks. Scans and probes are cached in `~/.cache/blob/agent-usage`. When the access token has lapsed, starting Claude Code refreshes it. ## Calendar The clock's calendar popup and the Quick Settings card share one component, `CalendarView` in `shell/Ui`, with its date math in `Ui/CalendarModel.js`. - Today is filled with the accent color; days from the neighbouring months are dimmed. - Clicking a day selects it, and the line under the grid gives its weekday, day of the year, and how far it is from today. Clicking a day from the previous or next month moves the view there. - Clicking the month label opens a month picker; the chevrons then step whole years, and clicking a month jumps to it. - The scroll wheel steps months, or years while the picker is open. Keys in the clock popup: | Key | Action | | --- | --- | | arrows / `hjkl` | move the selected day (a week up or down), or the month cursor in the picker | | `[` `]` | previous or next month | | `{` `}` | previous or next year | | `m` | open or close the month picker | | `t` | back to today | | `w` | toggle the week start between Monday and Sunday | | Enter | back to today, or pick the highlighted month | | Esc | close the month picker, then the popup | ## Animated wallpapers The background plugin draws a GIF wallpaper with `AnimatedImage`, so it moves however it was set: the wallpaper picker, `blob wallpaper set`, `blob bg set`, or a theme's own background. The transition into it shows the first frame, and the animation starts once the transition finishes. Per-monitor wallpapers from `blob bg monitor` animate the same way. `awww` is no longer needed; `blob-wallpaper-set` and `blob-theme-menu` still stop a leftover `awww-daemon` so it cannot paint over the shell. ## Differences from upstream This shell was forked from Omarchy 4.0.4 and is not tracked against it. The changes beyond renaming: - `tailscale`, `dropbox`, and `dev-gallery` plugins removed. `agents` was removed too, then ported back from the quattro branch with only Claude Code. - The `Dictation` bar indicator removed with voice typing. - Persistent workspaces 1-9 instead of 1-5. - Menu cards 440 wide instead of 300, with the Blob icon on the bar button. - The lock screen carries `branding/screensaver.txt`, the time and date above the password field, and an AGS-style password field: square corners, a 2px border on the blue slot at half alpha going to solid accent once typing starts, and urgent on a failed attempt. - `quick-settings`, `sysmon`, and `notification-center` are new, ported from the GTK widgets. See [widgets.md](widgets.md). None of these are clones or overrides. They are edits to first-party source, so there is no clone machinery and nothing to re-apply after an upstream release. The fork base is recorded in [upstream.md](upstream.md). ## Debugging ``` journalctl --user -t blob-shell -f blob-shell-restart ``` A QML error in a `service` plugin means that service never loads. For the lock that leaves the machine unlockable rather than locked open, so test it with `blob-shell lock lock` before trusting a change to it.