mirror of
https://github.com/arthur-pbty/arthur-os.git
synced 2026-08-01 20:28:16 +02:00
Teach plugin command manifests
This commit is contained in:
+263
-104
@@ -2,8 +2,8 @@
|
||||
|
||||
# omarchy:summary=Manage Omarchy shell plugins and bar widgets
|
||||
# omarchy:group=plugin
|
||||
# omarchy:args=<list|rescan|enable|disable|clone|bar> [...]
|
||||
# omarchy:examples=omarchy plugin list | omarchy plugin clone omarchy.clock local.clock --open pi | omarchy plugin enable acme.weather --section right | omarchy plugin bar move omarchy.clock --section center --index 0 | omarchy plugin bar edit
|
||||
# omarchy:args=<list|rescan|enable|disable|clone|edit|bar> [...]
|
||||
# omarchy:examples=omarchy plugin list | omarchy plugin clone omarchy.clock local.clock --with ai | omarchy plugin edit local.clock --with editor | omarchy plugin enable acme.weather --section right | omarchy plugin bar edit
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
@@ -19,10 +19,13 @@ Plugin commands:
|
||||
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] [--with <ai|editor>] [--prompt <prompt>]
|
||||
Open a user plugin for editing
|
||||
|
||||
Clone options:
|
||||
--name <name> Display name for the clone
|
||||
--open <tool> Open with pi, claude, nvim, tdl, editor, or none
|
||||
--with <ai|editor> Open the clone with AI or editor
|
||||
--prompt <prompt> Initial prompt when opening with AI
|
||||
--replace Replace the first source bar instance
|
||||
--add [placement] Add cloned bar widget to the bar
|
||||
|
||||
@@ -45,7 +48,9 @@ Examples:
|
||||
omarchy plugin list
|
||||
omarchy plugin rescan
|
||||
omarchy plugin clone
|
||||
omarchy plugin clone omarchy.clock local.clock --name "My Clock" --replace --open pi
|
||||
omarchy plugin clone omarchy.clock local.clock --name "My Clock" --replace --with ai --prompt "Customize this clock"
|
||||
omarchy plugin edit local.clock --with editor
|
||||
omarchy plugin edit local.clock --with ai --prompt "Customize this clock"
|
||||
omarchy plugin enable acme.weather --section right
|
||||
omarchy plugin bar add acme.weather --section right --before omarchy.tray
|
||||
omarchy plugin bar move omarchy.clock --section center --index 0
|
||||
@@ -84,29 +89,7 @@ validate_index() {
|
||||
}
|
||||
|
||||
canonical_widget_id() {
|
||||
case "$1" in
|
||||
Omarchy) printf 'omarchy.menu' ;;
|
||||
Workspaces) printf 'omarchy.workspaces' ;;
|
||||
Media) printf 'omarchy.media' ;;
|
||||
AudioPanel) printf 'omarchy.audio' ;;
|
||||
MonitorPanel) printf 'omarchy.monitor' ;;
|
||||
NetworkPanel) printf 'omarchy.network' ;;
|
||||
PowerPanel) printf 'omarchy.power' ;;
|
||||
BluetoothPanel) printf 'omarchy.bluetooth' ;;
|
||||
Clock) printf 'omarchy.clock' ;;
|
||||
Indicators) printf 'omarchy.indicators' ;;
|
||||
NotificationCenter) printf 'omarchy.notifications' ;;
|
||||
SystemUpdate) printf 'omarchy.system-update' ;;
|
||||
SystemStats) printf 'omarchy.system-stats' ;;
|
||||
Tray) printf 'omarchy.tray' ;;
|
||||
Weather) printf 'omarchy.weather' ;;
|
||||
Microphone) printf 'omarchy.microphone' ;;
|
||||
ActiveWindow) printf 'omarchy.active-window' ;;
|
||||
KeyboardLayout) printf 'omarchy.keyboard-layout' ;;
|
||||
LockKeys) printf 'omarchy.lock-keys' ;;
|
||||
Spacer) printf 'omarchy.spacer' ;;
|
||||
*) printf '%s' "$1" ;;
|
||||
esac
|
||||
printf '%s' "$1"
|
||||
}
|
||||
|
||||
validate_plugin_id() {
|
||||
@@ -175,6 +158,8 @@ plugin_enabled() {
|
||||
fail "disable does not take placement options"
|
||||
fi
|
||||
|
||||
id=$(canonical_widget_id "$id")
|
||||
|
||||
omarchy-shell shell rescanPlugins >/dev/null 2>&1 || true
|
||||
omarchy-shell shell setPluginEnabled "$id" "$enabled" || fail "could not update plugin; is omarchy-shell running?"
|
||||
|
||||
@@ -366,32 +351,8 @@ from copy import deepcopy
|
||||
|
||||
source = sys.argv[1]
|
||||
operation = os.environ["OPERATION"]
|
||||
aliases = {
|
||||
"Omarchy": "omarchy.menu",
|
||||
"Workspaces": "omarchy.workspaces",
|
||||
"Media": "omarchy.media",
|
||||
"AudioPanel": "omarchy.audio",
|
||||
"MonitorPanel": "omarchy.monitor",
|
||||
"NetworkPanel": "omarchy.network",
|
||||
"PowerPanel": "omarchy.power",
|
||||
"BluetoothPanel": "omarchy.bluetooth",
|
||||
"Clock": "omarchy.clock",
|
||||
"Indicators": "omarchy.indicators",
|
||||
"NotificationCenter": "omarchy.notifications",
|
||||
"SystemUpdate": "omarchy.system-update",
|
||||
"SystemStats": "omarchy.system-stats",
|
||||
"Tray": "omarchy.tray",
|
||||
"Weather": "omarchy.weather",
|
||||
"Microphone": "omarchy.microphone",
|
||||
"ActiveWindow": "omarchy.active-window",
|
||||
"KeyboardLayout": "omarchy.keyboard-layout",
|
||||
"LockKeys": "omarchy.lock-keys",
|
||||
"Spacer": "omarchy.spacer",
|
||||
}
|
||||
|
||||
|
||||
def canonical(value):
|
||||
return aliases.get(str(value or ""), str(value or ""))
|
||||
return str(value or "")
|
||||
|
||||
|
||||
widget_id = canonical(os.environ.get("WIDGET_ID", ""))
|
||||
@@ -659,46 +620,58 @@ slug_id() {
|
||||
tr '[:upper:]' '[:lower:]' <<<"$1" | sed -E 's/^omarchy\.//; s/[^a-z0-9]+/-/g; s/^-+//; s/-+$//'
|
||||
}
|
||||
|
||||
builtin_widget_info() {
|
||||
first_party_manifest_paths() {
|
||||
require_omarchy_path
|
||||
local id
|
||||
id=$(canonical_widget_id "$1")
|
||||
case "$id" in
|
||||
omarchy.menu) printf '%s\t%s\t%s\t%s\t%s\n' "$id" "$OMARCHY_PATH/shell/plugins/bar/widgets/Omarchy.qml" "Omarchy menu" "Compositor" "false" ;;
|
||||
omarchy.workspaces) printf '%s\t%s\t%s\t%s\t%s\n' "$id" "$OMARCHY_PATH/shell/plugins/bar/widgets/Workspaces.qml" "Workspaces" "Compositor" "false" ;;
|
||||
omarchy.media) printf '%s\t%s\t%s\t%s\t%s\n' "$id" "$OMARCHY_PATH/shell/plugins/bar/widgets/Media.qml" "Media" "Media" "false" ;;
|
||||
omarchy.audio) printf '%s\t%s\t%s\t%s\t%s\n' "$id" "$OMARCHY_PATH/shell/plugins/panels/Audio.qml" "Audio" "Audio" "false" ;;
|
||||
omarchy.monitor) printf '%s\t%s\t%s\t%s\t%s\n' "$id" "$OMARCHY_PATH/shell/plugins/panels/Monitor.qml" "Display" "System" "false" ;;
|
||||
omarchy.network) printf '%s\t%s\t%s\t%s\t%s\n' "$id" "$OMARCHY_PATH/shell/plugins/panels/Network.qml" "Network" "Network" "false" ;;
|
||||
omarchy.power) printf '%s\t%s\t%s\t%s\t%s\n' "$id" "$OMARCHY_PATH/shell/plugins/panels/Power.qml" "Power" "System" "false" ;;
|
||||
omarchy.bluetooth) printf '%s\t%s\t%s\t%s\t%s\n' "$id" "$OMARCHY_PATH/shell/plugins/panels/Bluetooth.qml" "Bluetooth" "Network" "false" ;;
|
||||
omarchy.clock) printf '%s\t%s\t%s\t%s\t%s\n' "$id" "$OMARCHY_PATH/shell/plugins/bar/widgets/Clock.qml" "Clock" "Time" "false" ;;
|
||||
omarchy.indicators) printf '%s\t%s\t%s\t%s\t%s\n' "$id" "$OMARCHY_PATH/shell/plugins/bar/widgets/Indicators.qml" "Indicators" "Status" "true" ;;
|
||||
omarchy.notifications) printf '%s\t%s\t%s\t%s\t%s\n' "$id" "$OMARCHY_PATH/shell/plugins/bar/widgets/NotificationCenter.qml" "Notification center" "Status" "false" ;;
|
||||
omarchy.system-update) printf '%s\t%s\t%s\t%s\t%s\n' "$id" "$OMARCHY_PATH/shell/plugins/bar/widgets/SystemUpdate.qml" "System update" "System" "false" ;;
|
||||
omarchy.system-stats) printf '%s\t%s\t%s\t%s\t%s\n' "$id" "$OMARCHY_PATH/shell/plugins/bar/widgets/SystemStats.qml" "System stats" "System" "false" ;;
|
||||
omarchy.tray) printf '%s\t%s\t%s\t%s\t%s\n' "$id" "$OMARCHY_PATH/shell/plugins/bar/widgets/Tray.qml" "System tray" "Status" "false" ;;
|
||||
omarchy.weather) printf '%s\t%s\t%s\t%s\t%s\n' "$id" "$OMARCHY_PATH/shell/plugins/bar/widgets/Weather.qml" "Weather" "Info" "false" ;;
|
||||
omarchy.microphone) printf '%s\t%s\t%s\t%s\t%s\n' "$id" "$OMARCHY_PATH/shell/plugins/bar/widgets/Microphone.qml" "Microphone" "Audio" "false" ;;
|
||||
omarchy.active-window) printf '%s\t%s\t%s\t%s\t%s\n' "$id" "$OMARCHY_PATH/shell/plugins/bar/widgets/ActiveWindow.qml" "Active window" "Compositor" "false" ;;
|
||||
omarchy.keyboard-layout) printf '%s\t%s\t%s\t%s\t%s\n' "$id" "$OMARCHY_PATH/shell/plugins/bar/widgets/KeyboardLayout.qml" "Keyboard layout" "Compositor" "false" ;;
|
||||
omarchy.lock-keys) printf '%s\t%s\t%s\t%s\t%s\n' "$id" "$OMARCHY_PATH/shell/plugins/bar/widgets/LockKeys.qml" "Lock keys" "System" "false" ;;
|
||||
omarchy.spacer) printf '%s\t%s\t%s\t%s\t%s\n' "$id" "$OMARCHY_PATH/shell/plugins/bar/widgets/Spacer.qml" "Spacer" "Layout" "true" ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
find "$OMARCHY_PATH/shell/plugins" -mindepth 2 -maxdepth 3 -type f \( -name manifest.json -o -name '*.manifest.json' \) 2>/dev/null | sort
|
||||
}
|
||||
|
||||
manifest_source_dir() {
|
||||
local manifest="$1"
|
||||
if [[ ${manifest##*/} == "manifest.json" ]]; then
|
||||
dirname -- "$manifest"
|
||||
else
|
||||
dirname -- "$manifest"
|
||||
fi
|
||||
}
|
||||
|
||||
builtin_widget_info() {
|
||||
require_command jq
|
||||
local wanted
|
||||
wanted=$(canonical_widget_id "$1")
|
||||
|
||||
local manifest id entry source_dir source_path name category multiple
|
||||
while IFS= read -r manifest; do
|
||||
if ! jq -e --arg id "$wanted" '
|
||||
(.id == $id or ((.barWidget.aliases // []) | index($id))) and
|
||||
((.kinds // []) | index("bar-widget"))
|
||||
' "$manifest" >/dev/null 2>&1; then
|
||||
continue
|
||||
fi
|
||||
|
||||
id=$(jq -r '.id' "$manifest")
|
||||
entry=$(jq -r '.entryPoints.barWidget // empty' "$manifest")
|
||||
[[ -n $entry ]] || return 1
|
||||
source_dir=$(manifest_source_dir "$manifest")
|
||||
source_path="$source_dir/$entry"
|
||||
name=$(jq -r '.barWidget.displayName // .name // .id' "$manifest")
|
||||
category=$(jq -r '.barWidget.category // "Plugin"' "$manifest")
|
||||
multiple=$(jq -r 'if .barWidget.allowMultiple == true then "true" else "false" end' "$manifest")
|
||||
printf '%s\t%s\t%s\t%s\t%s\n' "$id" "$source_path" "$name" "$category" "$multiple"
|
||||
return 0
|
||||
done < <(first_party_manifest_paths)
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
clone_source_options() {
|
||||
local id path name category multiple
|
||||
for id in omarchy.menu omarchy.workspaces omarchy.clock omarchy.weather omarchy.indicators omarchy.system-update omarchy.tray omarchy.audio omarchy.network omarchy.bluetooth omarchy.monitor omarchy.power omarchy.media omarchy.notifications omarchy.system-stats omarchy.microphone omarchy.active-window omarchy.keyboard-layout omarchy.lock-keys omarchy.spacer; do
|
||||
IFS=$'\t' read -r _ path name category multiple < <(builtin_widget_info "$id")
|
||||
printf '%s\tBuilt-in widget\t%s\n' "$id" "$name"
|
||||
done
|
||||
|
||||
find "$OMARCHY_PATH/shell/plugins" -path '*/manifest.json' -print 2>/dev/null | sort | while IFS= read -r manifest; do
|
||||
local id name
|
||||
first_party_manifest_paths | while IFS= read -r manifest; do
|
||||
id=$(jq -r '.id // empty' "$manifest" 2>/dev/null || true)
|
||||
name=$(jq -r '.name // .id // empty' "$manifest" 2>/dev/null || true)
|
||||
if [[ -n $id && $id != "omarchy.bar" ]] && ! builtin_widget_info "$id" >/dev/null 2>&1; then
|
||||
name=$(jq -r '.barWidget.displayName // .name // .id // empty' "$manifest" 2>/dev/null || true)
|
||||
[[ -n $id && $id != "omarchy.bar" ]] || continue
|
||||
if jq -e '(.kinds // []) | index("bar-widget")' "$manifest" >/dev/null 2>&1; then
|
||||
printf '%s\tBuilt-in widget\t%s\n' "$id" "${name:-$id}"
|
||||
else
|
||||
printf '%s\tBuilt-in plugin\t%s\n' "$id" "${name:-$id}"
|
||||
fi
|
||||
done
|
||||
@@ -736,34 +709,161 @@ input_value() {
|
||||
|
||||
choose_clone_source() {
|
||||
local selected
|
||||
if command -v fzf >/dev/null 2>&1; then
|
||||
if command -v gum >/dev/null 2>&1; then
|
||||
selected=$(clone_source_options | awk -F '\t' '{ printf "%-32s %-15s %s\n", $3, $2, $1 }' | gum filter --header "Clone plugin" --placeholder "Search built-in and user plugins..." --limit 1) || return 1
|
||||
awk '{ print $NF }' <<<"$selected"
|
||||
elif command -v fzf >/dev/null 2>&1; then
|
||||
selected=$(clone_source_options | fzf --delimiter=$'\t' --with-nth=1,2,3 --prompt "Clone plugin > ") || return 1
|
||||
cut -f1 <<<"$selected"
|
||||
else
|
||||
clone_source_options | cut -f1 | gum choose --header "Clone plugin"
|
||||
fail "gum or fzf is required for interactive clone selection"
|
||||
fi
|
||||
}
|
||||
|
||||
edit_source_options() {
|
||||
if [[ -d $HOME/.config/omarchy/plugins ]]; then
|
||||
find "$HOME/.config/omarchy/plugins" -mindepth 1 -maxdepth 1 \( -type d -o -type l \) 2>/dev/null | sort | while IFS= read -r dir; do
|
||||
[[ -f $dir/manifest.json ]] || continue
|
||||
id=$(jq -r '.id // empty' "$dir/manifest.json" 2>/dev/null || true)
|
||||
name=$(jq -r '.name // .id // empty' "$dir/manifest.json" 2>/dev/null || true)
|
||||
[[ -n $id ]] && printf '%s\t%s\t%s\n' "$id" "${name:-$id}" "$dir"
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
choose_edit_source() {
|
||||
local selected
|
||||
if command -v gum >/dev/null 2>&1; then
|
||||
selected=$(edit_source_options | awk -F '\t' '{ printf "%-32s %s\n", $2, $1 }' | gum filter --header "Edit plugin" --placeholder "Search user plugins..." --limit 1) || return 1
|
||||
awk '{ print $NF }' <<<"$selected"
|
||||
elif command -v fzf >/dev/null 2>&1; then
|
||||
selected=$(edit_source_options | fzf --delimiter=$'\t' --with-nth=2,1 --prompt "Edit plugin > ") || return 1
|
||||
cut -f1 <<<"$selected"
|
||||
else
|
||||
fail "gum or fzf is required for interactive plugin selection"
|
||||
fi
|
||||
}
|
||||
|
||||
validate_user_plugin_dir() {
|
||||
local dir="$1"
|
||||
local requested_id="${2:-}"
|
||||
local root="$HOME/.config/omarchy/plugins"
|
||||
local dir_abs root_abs manifest_id
|
||||
|
||||
require_command jq
|
||||
require_command python3
|
||||
[[ -d $dir ]] || fail "plugin directory not found: $dir"
|
||||
|
||||
dir_abs=$(python3 -c 'from pathlib import Path; import sys; print(Path(sys.argv[1]).expanduser().resolve(strict=False))' "$dir")
|
||||
root_abs=$(python3 -c 'from pathlib import Path; import sys; print(Path(sys.argv[1]).expanduser().resolve(strict=False))' "$root")
|
||||
[[ $dir_abs == $root_abs/* ]] || fail "plugin edit only opens user plugins under $root"
|
||||
[[ -f $dir_abs/manifest.json ]] || fail "plugin directory missing manifest.json: $dir_abs"
|
||||
|
||||
manifest_id=$(jq -r '.id // empty' "$dir_abs/manifest.json" 2>/dev/null || true)
|
||||
[[ -n $manifest_id ]] || fail "plugin manifest missing id: $dir_abs/manifest.json"
|
||||
[[ $manifest_id != omarchy.* && $(canonical_widget_id "$manifest_id") == $manifest_id ]] || fail "$manifest_id is built in; clone it first with: omarchy plugin clone $manifest_id local.$(slug_id "$manifest_id")"
|
||||
if [[ -n $requested_id && $manifest_id != $requested_id ]]; then
|
||||
fail "plugin id mismatch: requested $requested_id but manifest declares $manifest_id"
|
||||
fi
|
||||
|
||||
printf '%s' "$dir_abs"
|
||||
}
|
||||
|
||||
plugin_dir_for_id() {
|
||||
local id="$1"
|
||||
|
||||
if [[ $id == */* ]]; then
|
||||
validate_user_plugin_dir "$id"
|
||||
return
|
||||
fi
|
||||
|
||||
id=$(canonical_widget_id "$id")
|
||||
if builtin_widget_info "$id" >/dev/null 2>&1 || [[ $id == omarchy.* ]]; then
|
||||
fail "$id is built in; clone it first with: omarchy plugin clone $id local.$(slug_id "$id")"
|
||||
fi
|
||||
|
||||
validate_user_plugin_dir "$HOME/.config/omarchy/plugins/$id" "$id"
|
||||
}
|
||||
|
||||
open_plugin_dir() {
|
||||
local tool="$1"
|
||||
local dir="$2"
|
||||
local prompt="${3:-}"
|
||||
|
||||
case "$tool" in
|
||||
"" | none)
|
||||
printf 'Plugin directory: %s\n' "$dir"
|
||||
return
|
||||
;;
|
||||
pi | claude | nvim | tdl)
|
||||
command -v "$tool" >/dev/null 2>&1 || fail "$tool is not installed"
|
||||
"$tool" "$dir"
|
||||
ai)
|
||||
omarchy-launch-ai --path "$dir" --prompt "$prompt"
|
||||
;;
|
||||
editor)
|
||||
"${VISUAL:-${EDITOR:-nvim}}" "$dir"
|
||||
omarchy-launch-editor "$dir"
|
||||
;;
|
||||
*)
|
||||
fail "unknown open tool: $tool"
|
||||
fail "unknown edit target: $tool (use ai, editor, or none)"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
edit_command() {
|
||||
local id=""
|
||||
if (( $# > 0 )) && [[ $1 != --* ]]; then
|
||||
id="$1"
|
||||
shift
|
||||
fi
|
||||
|
||||
local open_tool=""
|
||||
local prompt=""
|
||||
while (( $# > 0 )); do
|
||||
case "$1" in
|
||||
--with)
|
||||
open_tool="${2:-}"
|
||||
[[ -n $open_tool ]] || fail "--with requires a value"
|
||||
shift 2
|
||||
;;
|
||||
--open)
|
||||
open_tool="${2:-}"
|
||||
[[ -n $open_tool ]] || fail "--open requires a value"
|
||||
shift 2
|
||||
;;
|
||||
--prompt)
|
||||
prompt="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
-h | --help)
|
||||
usage
|
||||
return
|
||||
;;
|
||||
*)
|
||||
fail "unknown edit option: $1"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ -z $id ]]; then
|
||||
if [[ -t 0 && -t 1 ]]; then
|
||||
id=$(choose_edit_source) || fail "edit cancelled"
|
||||
else
|
||||
fail "plugin id is required"
|
||||
fi
|
||||
fi
|
||||
|
||||
local dir
|
||||
dir=$(plugin_dir_for_id "$id")
|
||||
|
||||
if [[ -z $open_tool ]]; then
|
||||
if [[ -t 0 && -t 1 ]]; then
|
||||
open_tool=$(choose_value "Edit with" ai editor)
|
||||
else
|
||||
open_tool="editor"
|
||||
fi
|
||||
fi
|
||||
|
||||
open_plugin_dir "$open_tool" "$dir" "$prompt"
|
||||
}
|
||||
|
||||
rewrite_cloned_qml() {
|
||||
local file="$1"
|
||||
local id="$2"
|
||||
@@ -779,12 +879,35 @@ text = re.sub(r'moduleName:\s*"[^"]+"', f'moduleName: "{plugin_id}"', text, coun
|
||||
|
||||
def resolve_relative(match):
|
||||
rel = match.group(1)
|
||||
if rel.startswith(("../", "./")):
|
||||
if rel.startswith(("../", "./")) or (not rel.startswith("/") and "://" not in rel):
|
||||
resolved = (source_path.parent / rel).resolve()
|
||||
return '"' + resolved.as_uri() + '"'
|
||||
return match.group(0)
|
||||
|
||||
text = re.sub(r'Qt\.resolvedUrl\("([^"]+)"\)', resolve_relative, text)
|
||||
|
||||
# Indicators dynamically loads sibling indicator components via string
|
||||
# concatenation, so the simple Qt.resolvedUrl("literal") rewrite above cannot
|
||||
# see it. Point the clone back at Omarchy's bundled indicator directory.
|
||||
if source_path.name == "Indicators.qml":
|
||||
indicators_url = (source_path.parent.parent / "indicators").resolve().as_uri() + "/"
|
||||
text = text.replace(
|
||||
'Qt.resolvedUrl("../indicators/" + indicatorSlot.indicatorId + ".qml")',
|
||||
f'"{indicators_url}" + indicatorSlot.indicatorId + ".qml"',
|
||||
)
|
||||
|
||||
# Panel-backed clones should not register the same global IPC target as the
|
||||
# built-in widget. Direct panel clones can disable Panel.manageIpc themselves;
|
||||
# wrapper widgets such as Weather disable it on the loaded panel instance.
|
||||
if "ipcTarget:" in text and "manageIpc:" not in text:
|
||||
text = text.replace(" id: root\n", " id: root\n manageIpc: false\n", 1)
|
||||
if "function injectPanel()" in text and '"manageIpc" in target' not in text:
|
||||
text = text.replace(
|
||||
" if (!target) return\n",
|
||||
" if (!target) return\n if (\"manageIpc\" in target) target.manageIpc = false\n",
|
||||
1,
|
||||
)
|
||||
|
||||
open(path, "w", encoding="utf-8").write(text)
|
||||
PY
|
||||
}
|
||||
@@ -854,13 +977,20 @@ clone_command() {
|
||||
require_command python3
|
||||
require_omarchy_path
|
||||
|
||||
local source_id="${1:-}"
|
||||
local new_id="${2:-}"
|
||||
if (( $# > 0 )) && [[ $1 != --* ]]; then shift; fi
|
||||
if (( $# > 0 )) && [[ $1 != --* ]]; then shift; fi
|
||||
local source_id=""
|
||||
local new_id=""
|
||||
if (( $# > 0 )) && [[ $1 != --* ]]; then
|
||||
source_id="$1"
|
||||
shift
|
||||
fi
|
||||
if (( $# > 0 )) && [[ $1 != --* ]]; then
|
||||
new_id="$1"
|
||||
shift
|
||||
fi
|
||||
|
||||
local display_name=""
|
||||
local open_tool=""
|
||||
local prompt=""
|
||||
local replace="false"
|
||||
local add="false"
|
||||
local placement=()
|
||||
@@ -872,11 +1002,20 @@ clone_command() {
|
||||
[[ -n $display_name ]] || fail "--name requires a value"
|
||||
shift 2
|
||||
;;
|
||||
--with)
|
||||
open_tool="${2:-}"
|
||||
[[ -n $open_tool ]] || fail "--with requires a value"
|
||||
shift 2
|
||||
;;
|
||||
--open)
|
||||
open_tool="${2:-}"
|
||||
[[ -n $open_tool ]] || fail "--open requires a value"
|
||||
shift 2
|
||||
;;
|
||||
--prompt)
|
||||
prompt="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--replace)
|
||||
replace="true"
|
||||
shift
|
||||
@@ -900,14 +1039,22 @@ clone_command() {
|
||||
done
|
||||
|
||||
if [[ -z $source_id ]]; then
|
||||
source_id=$(choose_clone_source) || fail "clone cancelled"
|
||||
if [[ -t 0 && -t 1 ]]; then
|
||||
source_id=$(choose_clone_source) || fail "clone cancelled"
|
||||
else
|
||||
fail "clone source is required"
|
||||
fi
|
||||
fi
|
||||
source_id=$(canonical_widget_id "$source_id")
|
||||
|
||||
local default_slug
|
||||
default_slug=$(slug_id "$source_id")
|
||||
if [[ -z $new_id ]]; then
|
||||
new_id=$(input_value "New plugin id:" "local.$default_slug")
|
||||
if [[ -t 0 && -t 1 ]]; then
|
||||
new_id=$(input_value "New plugin id:" "local.$default_slug")
|
||||
else
|
||||
fail "new plugin id is required"
|
||||
fi
|
||||
fi
|
||||
validate_plugin_id "$new_id"
|
||||
|
||||
@@ -936,7 +1083,13 @@ clone_command() {
|
||||
fi
|
||||
|
||||
[[ -n $source_type ]] || fail "unknown clone source: $source_id"
|
||||
[[ -n $display_name ]] || display_name=$(input_value "Display name:" "${source_name:-$new_id}")
|
||||
if [[ -z $display_name ]]; then
|
||||
if [[ -t 0 && -t 1 ]]; then
|
||||
display_name=$(input_value "Display name:" "${source_name:-$new_id}")
|
||||
else
|
||||
display_name="${source_name:-$new_id}"
|
||||
fi
|
||||
fi
|
||||
[[ -n $display_name ]] || fail "display name is required"
|
||||
|
||||
mkdir -p "$target_dir"
|
||||
@@ -970,9 +1123,11 @@ clone_command() {
|
||||
fi
|
||||
|
||||
if [[ -z $open_tool && -t 0 && -t 1 ]]; then
|
||||
open_tool=$(choose_value "Open with" none pi claude nvim tdl editor)
|
||||
open_tool=$(choose_value "Edit with" ai editor)
|
||||
fi
|
||||
if [[ -n $open_tool ]]; then
|
||||
edit_command "$new_id" --with "$open_tool" --prompt "$prompt"
|
||||
fi
|
||||
open_plugin_dir "$open_tool" "$target_dir"
|
||||
}
|
||||
|
||||
bar_command() {
|
||||
@@ -1030,6 +1185,10 @@ clone)
|
||||
shift
|
||||
clone_command "$@"
|
||||
;;
|
||||
edit)
|
||||
shift
|
||||
edit_command "$@"
|
||||
;;
|
||||
bar | widget | widgets)
|
||||
shift
|
||||
bar_command "$@"
|
||||
|
||||
Reference in New Issue
Block a user