Files
smoidoandClaude Opus 5 bb01418ce0 Split the bar panel into one QML file per stage
Panel.qml keeps the state, the CLI calls and the stage switch (889 lines,
was 2360); each stage is its own file taking the panel as a required
property. The omarchy installer copies every QML/JS file and clears stale
ones. tests/static.sh filters qmllint on [syntax], not the word error.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-15 02:12:49 +03:00

98 lines
3.6 KiB
Bash
Executable File

#!/usr/bin/env bash
# Installs the claude-mode bar widget into the Omarchy shell.
#
# Two steps: drop the plugin into ~/.config/omarchy/plugins/, and add its id to
# the bar layout in ~/.config/omarchy/shell.json. Both are idempotent, and the
# shell hot-reloads each of them, so nothing has to be restarted.
#
# Only ~/.config is touched. /usr/share/omarchy is owned by the package and is
# rewritten by `omarchy update`, so nothing may be installed there.
set -euo pipefail
PLUGIN_ID="smoido.claude-mode"
SRC="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/$PLUGIN_ID"
DEST_DIR="$HOME/.config/omarchy/plugins/$PLUGIN_ID"
SHELL_JSON="$HOME/.config/omarchy/shell.json"
# Where in the bar the widget lands, and which existing widget it sits before.
# The AI-adjacent group on the right is the natural neighbourhood for it.
SECTION="${CM_BAR_SECTION:-right}"
BEFORE="${CM_BAR_BEFORE:-omarchy.agents}"
green() { printf ' \033[32mok \033[0m %s\n' "$*"; }
warn() { printf ' \033[33mwarn\033[0m %s\n' "$*"; }
fail() { printf ' \033[31mFAIL\033[0m %s\n' "$*"; }
printf '\ninstalling %s -> %s\n' "$PLUGIN_ID" "$DEST_DIR"
[ -d "$SRC" ] || { fail "plugin source not found: $SRC"; exit 1; }
command -v python3 >/dev/null 2>&1 || { fail 'python3 required'; exit 1; }
if [ ! -d "$HOME/.config/omarchy" ]; then
fail 'no ~/.config/omarchy - this does not look like an Omarchy system'
exit 1
fi
# --- payload ---------------------------------------------------------------
mkdir -p "$DEST_DIR"
for f in manifest.json BarWidget.qml Panel.qml Modes.js; do
[ -f "$SRC/$f" ] || { fail "missing from payload: $f"; exit 1; }
done
# Every QML and JS file, not a fixed list: the panel is split into one file per
# stage. The old ones are cleared first, so a file removed from the source does
# not linger in the plugin directory, where QML would still find it by name.
rm -f "$DEST_DIR"/*.qml "$DEST_DIR"/*.js
for f in "$SRC"/manifest.json "$SRC"/*.qml "$SRC"/*.js; do
install -m 0644 "$f" "$DEST_DIR/$(basename "$f")"
done
green "plugin files copied ($(ls "$SRC"/*.qml | wc -l | tr -d ' ') QML files)"
# --- bar layout ------------------------------------------------------------
# shell.json is the user's own file and may carry unrelated customisation, so
# it is read, minimally amended, and written back rather than templated over.
if [ ! -f "$SHELL_JSON" ]; then
warn "no $SHELL_JSON - add the widget yourself once the shell writes one"
exit 0
fi
cp "$SHELL_JSON" "$SHELL_JSON.bak.$(date +%s)"
python3 - "$SHELL_JSON" "$PLUGIN_ID" "$SECTION" "$BEFORE" <<'PYEOF'
import json, sys
path, plugin_id, section, before = sys.argv[1:5]
with open(path, encoding="utf-8") as fh:
cfg = json.load(fh)
layout = cfg.setdefault("bar", {}).setdefault("layout", {})
entries = layout.setdefault(section, [])
def has(entry_list):
return any(isinstance(e, dict) and e.get("id") == plugin_id for e in entry_list)
# Already placed anywhere in the bar: leave the user's chosen position alone.
for name, items in layout.items():
if isinstance(items, list) and has(items):
print(" already in bar layout (%s) - position left as-is" % name)
raise SystemExit(0)
idx = len(entries)
for i, e in enumerate(entries):
if isinstance(e, dict) and e.get("id") == before:
idx = i
break
entries.insert(idx, {"id": plugin_id})
with open(path, "w", encoding="utf-8") as fh:
json.dump(cfg, fh, indent=2)
fh.write("\n")
print(" added to bar.layout.%s at position %d" % (section, idx))
PYEOF
green 'shell.json updated (hot-reloads; no restart needed)'
printf '\ndone. The icon shows the active mode; click it to switch.\n'
printf 'If it does not appear: omarchy-shell shell rescanPlugins\n'