Files
omarchycn/bin/omarchy-plugin
T
David Heinemeier Hansson 055ffaccd4 Split omarchy-plugin into siblings and consolidate bar config into omarchy-bar
omarchy-plugin mixed plugin lifecycle, clone/edit, and bar-layout mutation.
The bar layout was mutated by two separate engines (an embedded Python
mutate_bar here and jq in omarchy-config-shell-bar), each with its own
manifest walker.

- omarchy-plugin is now a ~220-line router; clone and edit move to
  omarchy-plugin-clone and omarchy-plugin-edit, matching the existing
  plugin-{source,add,update,remove,available,validate,scan} sibling pattern
- omarchy-config-shell-bar is replaced by omarchy-bar, the single bar engine
  (show/layout/list/options/use/reset/add/move/remove/set/replace/position/
  transparent/settings) with one jq pipeline; the Python mutate_bar and its
  python3 dependency are gone
- omarchy-plugin-catalog is the shared manifest scanner used by omarchy-bar
  (widget/option enumeration, add validation) and omarchy-plugin-clone
  (source enumeration), replacing three find|jq re-implementations
- service install/remove and refresh-shell call omarchy-bar; docs and tests
  updated to the new command surface
2026-07-02 11:10:24 -07:00

221 lines
6.0 KiB
Bash
Executable File

#!/bin/bash
# omarchy:summary=Manage Omarchy shell plugins and bar widgets
# omarchy:group=plugin
# omarchy:args=<list|rescan|enable|disable|clone|edit|bar> [...]
# omarchy:examples=omarchy plugin list | omarchy plugin clone omarchy.clock local.clock | omarchy plugin edit local.clock | omarchy plugin enable acme.weather --section right | omarchy plugin bar settings
set -euo pipefail
usage() {
cat <<USAGE
Usage: omarchy-plugin <command> [args...]
Plugin commands:
list [--json] List discovered shell plugins
rescan Rescan ~/.config/omarchy/plugins
enable <id> [placement] Enable a plugin
disable <id> Disable a plugin
clone [source] [new-id] [options] Clone a built-in or user plugin
edit [id] Open a user plugin directory in a shell
Add from sources (see 'omarchy plugin <command> --help'):
source <add|list|remove|refresh> Manage trusted plugin source repos
available List plugins offered by your sources
add [id] [--from <src>] [--enable] [--review] [--yes]
Add a plugin from a trusted source
update [id] [--all] [--review] [--yes]
Update added plugins (shows a diff)
remove [id] [--yes] Remove an installed plugin
validate <plugin-folder> Check a plugin's manifest (for authors)
Source/add commands run their own binaries; the rest are handled here.
Plugins are unsandboxed code — review what you add and enable.
Bar commands (delegate to 'omarchy bar'; run 'omarchy bar --help' for details):
bar settings Open the inline bar config panel
bar list|layout|options|use|reset|add|move|remove|set|position|transparent
widget|widgets Alias of 'bar list'
Examples:
omarchy plugin list
omarchy plugin rescan
omarchy plugin clone omarchy.clock local.clock --name "My Clock" --replace
omarchy plugin edit local.clock
omarchy plugin enable acme.weather --section right
omarchy plugin bar add acme.weather --section right
omarchy plugin bar set omarchy.clock format HH:mm
USAGE
}
fail() {
echo "omarchy-plugin: $*" >&2
exit 1
}
require_omarchy_path() {
[[ -n ${OMARCHY_PATH:-} ]] || fail "OMARCHY_PATH is not set"
}
require_command() {
command -v "$1" >/dev/null 2>&1 || fail "$1 is required"
}
plugin_discovered() {
local id="$1" plugins
plugins=$(omarchy-shell shell listPlugins 2>/dev/null) || return 1
jq -e --arg id "$id" 'any(.[]; .id == $id)' <<<"$plugins" >/dev/null 2>&1
}
wait_for_plugin_discovery() {
local id="$1" attempt
for (( attempt = 0; attempt < 40; attempt++ )); do
plugin_discovered "$id" && return 0
sleep 0.05
done
return 1
}
print_plugins() {
local json="false"
while (( $# > 0 )); do
case "$1" in
--json)
json="true"
;;
-h | --help)
usage
exit 0
;;
*)
fail "unknown list option: $1"
;;
esac
shift
done
local plugins
plugins=$(omarchy-shell shell listPlugins) || fail "could not list plugins; is omarchy-shell running?"
if [[ $json == "true" ]]; then
printf '%s\n' "$plugins"
return
fi
require_command jq
jq -r '
sort_by(.id)[] |
[ .id,
(if .enabled then "enabled" else "disabled" end),
(if .firstParty then "first-party" else "third-party" end),
((.kinds // []) | join(",")),
(.name // "")
] | @tsv
' <<<"$plugins" | awk -F '\t' '
BEGIN { printf "%-32s %-9s %-11s %-18s %s\n", "ID", "STATE", "SOURCE", "KINDS", "NAME" }
{ printf "%-32s %-9s %-11s %-18s %s\n", $1, $2, $3, $4, $5 }
'
}
rescan_plugins() {
(( $# == 0 )) || fail "rescan does not take arguments"
omarchy-shell shell rescanPlugins || fail "could not rescan plugins; is omarchy-shell running?"
echo "Plugins rescanned"
}
plugin_enabled() {
local enabled="$1"
local id="${2:-}"
[[ -n $id ]] || fail "plugin id is required"
shift 2
if [[ $enabled != "true" && $# -gt 0 ]]; then
fail "disable does not take placement options"
fi
omarchy-shell shell rescanPlugins >/dev/null 2>&1 || true
if [[ $enabled == "true" ]]; then
require_command jq
wait_for_plugin_discovery "$id" || fail "plugin '$id' was not discovered; is omarchy-shell running?"
fi
local result
result=$(omarchy-shell shell setPluginEnabled "$id" "$enabled") || fail "could not update plugin; is omarchy-shell running?"
[[ $result == "ok" ]] || fail "plugin '$id' is not known; run: omarchy plugin rescan"
if [[ $enabled == "true" && $# -gt 0 ]]; then
omarchy-bar move "$id" "$@"
echo "Enabled and moved $id"
elif [[ $enabled == "true" ]]; then
echo "Enabled $id"
else
echo "Disabled $id"
fi
}
bar_command() {
local command="${1:-list}"
[[ $# -gt 0 ]] && shift || true
case "$command" in
edit | settings)
(( $# == 0 )) || fail "bar settings does not take arguments"
exec omarchy-launch-bar-settings
;;
-h | --help | help)
usage
;;
*)
exec omarchy-bar "$command" "$@"
;;
esac
}
command="${1:-}"
case "$command" in
list | ls)
shift
print_plugins "$@"
;;
rescan)
shift
rescan_plugins "$@"
;;
enable)
shift
plugin_enabled true "$@"
;;
disable)
shift
plugin_enabled false "$@"
;;
clone)
shift
exec omarchy-plugin-clone "$@"
;;
edit)
shift
exec omarchy-plugin-edit "$@"
;;
bar | widget | widgets)
shift
bar_command "$@"
;;
source | available | add | update | remove | validate)
# These live in sibling binaries (omarchy-plugin-<command>). The `omarchy`
# dispatcher normally routes straight to them; delegate here too so invoking
# this base binary directly matches the commands its --help advertises.
shift
sibling="$(dirname -- "${BASH_SOURCE[0]}")/omarchy-plugin-$command"
[[ -x $sibling ]] || fail "missing helper: omarchy-plugin-$command"
exec "$sibling" "$@"
;;
-h | --help | help | "")
usage
;;
*)
fail "unknown command: $command"
;;
esac