#!/bin/bash # omarchy:summary=List every plugin available across configured sources (JSON) # omarchy:group=plugin # omarchy:hidden=true # Walks the locally cached clones of every trusted source and emits one JSON # entry per plugin folder it finds. This is the shared catalogue that # `available`, `install`, and `update` all read; it never touches the network # (run `omarchy plugin source refresh` first to pull fresh clones). set -o pipefail SOURCES_FILE="$HOME/.config/omarchy/plugins/sources.json" CACHE_ROOT="$HOME/.cache/omarchy/plugin-sources" command -v jq >/dev/null 2>&1 || { echo "omarchy-plugin-scan: jq is required" >&2; exit 1; } if [[ ! -f $SOURCES_FILE ]]; then echo "[]" exit 0 fi results='[]' # Read each source as a compact JSON object (one per line) rather than a # delimiter-joined string — no separator to get wrong, and empty fields survive. while IFS= read -r src_json; do [[ -n $src_json ]] || continue src_id=$(jq -r '.id // ""' <<<"$src_json") src_url=$(jq -r '.url // ""' <<<"$src_json") src_ref=$(jq -r '.ref // ""' <<<"$src_json") [[ -n $src_id ]] || continue cache_dir="$CACHE_ROOT/$src_id" [[ -d $cache_dir ]] || continue for folder in "$cache_dir"/*/; do [[ -d $folder ]] || continue manifest="$folder/manifest.json" [[ -f $manifest ]] || continue jq -e . "$manifest" >/dev/null 2>&1 || continue folder_name=$(basename "$folder") abs_path=$(cd "$folder" && pwd) entry=$(jq -n \ --arg sourceId "$src_id" \ --arg sourceUrl "$src_url" \ --arg ref "$src_ref" \ --arg folder "$folder_name" \ --arg path "$abs_path" \ --slurpfile manifest "$manifest" \ '{sourceId:$sourceId, sourceUrl:$sourceUrl, ref:$ref, folder:$folder, path:$path, manifest:$manifest[0]}') || continue results=$(jq --argjson e "$entry" '. + [$e]' <<<"$results") done done < <(jq -c '.sources[]?' "$SOURCES_FILE") echo "$results"