Add disable-all, disable-category, disable-pick, disable-search

New commands (parallel to enable-side):
- disable-all [-y|--yes] : disable every active skill, asks confirmation.
- disable-category <prefix> : fzf multi-pick within ACTIVE skills with prefix.
- disable-pick : fzf interactive — choose ACTIVE category → multi-select.
- disable-search [query] : fzf fuzzy search across ACTIVE skills (uses INDEX).

All disable* commands preserve data: they only remove the active copy and
keep (or restore) the parked one. Updated usage text + Notes section.
This commit is contained in:
salvacybersec
2026-04-30 20:46:04 +03:00
parent 1f67aaab63
commit 81a288e629

View File

@@ -95,6 +95,119 @@ cmd_disable() {
fi
}
# disable all active skills (with confirmation; -y/--yes to skip prompt)
cmd_disable_all() {
require_dirs
local force=0
if [ "${1:-}" = "-y" ] || [ "${1:-}" = "--yes" ]; then
force=1
fi
local -a actives
mapfile -t actives < <(skill_dirs_in "$ACTIVE")
[ "${#actives[@]}" -gt 0 ] || { echo "no active skills"; exit 0; }
echo "Will disable ${#actives[@]} active skill(s):"
printf ' %s\n' "${actives[@]}"
if [ "$force" -ne 1 ]; then
printf "Proceed? [y/N] "
read -r ans </dev/tty || ans=""
case "$ans" in y|Y|yes|YES) ;; *) echo "cancelled"; exit 0 ;; esac
fi
local n
for n in "${actives[@]}"; do
cmd_disable "$n" || true
done
}
# batch disable by prefix/category — fzf multi-pick within ACTIVE
cmd_disable_category() {
require_dirs
ensure_fzf
local prefix="${1:-}"
[ -n "$prefix" ] || { echo "usage: opc-skills disable-category <prefix>" >&2; exit 2; }
local -a matches
mapfile -t matches < <(skill_dirs_in "$ACTIVE" | awk -v p="$prefix" '$0 ~ "^" p "(-|$)"')
[ "${#matches[@]}" -gt 0 ] || { echo "no active skills match prefix: $prefix" >&2; exit 1; }
echo "Active matches (${#matches[@]}):"
local selection
selection=$(printf '%s\n' "${matches[@]}" | fzf --multi --height=70% \
--prompt="disable-category $prefix > " \
--header="TAB: toggle | ENTER: confirm | ESC: cancel")
[ -n "$selection" ] || { echo "cancelled"; exit 0; }
local n
while IFS= read -r n; do
[ -z "$n" ] && continue
cmd_disable "$n" || true
done <<< "$selection"
}
# interactive pick (active only): category → multi-select skills to disable
cmd_disable_pick() {
require_dirs
ensure_fzf
local active_count
active_count=$(skill_dirs_in "$ACTIVE" | wc -l)
[ "$active_count" -gt 0 ] || { echo "no active skills"; exit 0; }
# Active categories (by prefix)
local cats
cats=$(skill_dirs_in "$ACTIVE" | awk -F'-' '{print $1}' | sort | uniq -c | sort -rn)
local category
category=$(printf '%s\n' "$cats" | fzf --prompt="active-category > " --height=50% \
--header="Pick a category of ACTIVE skills to disable" \
| awk '{print $2}')
[ -n "$category" ] || { echo "cancelled"; exit 0; }
local selection
selection=$(skill_dirs_in "$ACTIVE" \
| awk -v p="$category" '$0 ~ "^" p "(-|$)"' \
| fzf --multi --height=80% \
--prompt="disable $category > " \
--header="TAB: toggle | ENTER: disable selected" \
--preview="sed -n '1,40p' \"$ACTIVE/{}/SKILL.md\" 2>/dev/null || echo '(no SKILL.md)'" \
--preview-window=right:60%:wrap)
[ -n "$selection" ] || { echo "cancelled"; exit 0; }
local n
while IFS= read -r n; do
[ -z "$n" ] && continue
cmd_disable "$n" || true
done <<< "$selection"
}
# fzf search across active skills (uses INDEX.json filtered by status active|both)
cmd_disable_search() {
require_dirs
ensure_fzf
command -v jq >/dev/null || { echo "jq is required" >&2; exit 1; }
[ -f "$INDEX_JSON" ] || { echo "INDEX.json missing — run: opc-skills reindex" >&2; exit 1; }
local query="${1:-}"
local tmp
tmp=$(mktemp)
# Only active or both
jq -r '.[] | select(.status=="active" or .status=="both") | "\(.folder)\t\(.description)"' "$INDEX_JSON" > "$tmp"
[ -s "$tmp" ] || { rm -f "$tmp"; echo "no active skills indexed (try: opc-skills reindex)"; exit 0; }
local selection
if [ -n "$query" ]; then
selection=$(fzf --query="$query" --multi --height=80% \
--delimiter='\t' --with-nth=1,2 \
--prompt="disable-search > " \
--header="TAB: toggle | ENTER: disable selected" \
--preview="sed -n '1,40p' \"$ACTIVE/{1}/SKILL.md\" 2>/dev/null || echo '(no SKILL.md)'" \
--preview-window=right:60%:wrap < "$tmp")
else
selection=$(fzf --multi --height=80% \
--delimiter='\t' --with-nth=1,2 \
--prompt="disable-search > " \
--header="TAB: toggle | ENTER: disable selected" \
--preview="sed -n '1,40p' \"$ACTIVE/{1}/SKILL.md\" 2>/dev/null || echo '(no SKILL.md)'" \
--preview-window=right:60%:wrap < "$tmp")
fi
rm -f "$tmp"
[ -n "$selection" ] || { echo "cancelled"; exit 0; }
local folder
while IFS=$'\t' read -r folder _; do
[ -z "$folder" ] && continue
cmd_disable "$folder" || true
done <<< "$selection"
}
# batch enable by prefix/category (first word before '-')
cmd_enable_category() {
require_dirs
@@ -260,11 +373,19 @@ opc-skills — opencode skill manager
categories prefix-based category counts
enable <folder> enable single skill (copy parked → active)
disable <folder> disable single skill (remove from active; keep parked)
disable-all [-y|--yes] disable every active skill (asks for confirmation)
enable-category <prefix> fzf multi-pick within a prefix, then enable
disable-category <prefix> fzf multi-pick of ACTIVE skills with prefix, then disable
pick fzf: choose category → multi-select → enable
search [query] fzf fuzzy search across name+description
disable-pick fzf: choose ACTIVE category → multi-select → disable
search [query] fzf fuzzy search across name+description (enable)
disable-search [query] fzf fuzzy search ACTIVE skills only (disable)
reindex rebuild INDEX.json / INDEX.md
Notes:
disable* commands never delete data — they remove the active copy and keep
(or restore) the parked copy. To re-enable: opc-skills enable <folder>.
Environment:
OPC_PARKED override parked dir (default: ~/Documents/opencode-skills-parked)
OPC_ACTIVE override active dir (default: ~/.config/opencode/skills)
@@ -281,9 +402,13 @@ main() {
categories|cats) cmd_categories "$@" ;;
enable) cmd_enable "$@" ;;
disable) cmd_disable "$@" ;;
enable-category|enable-cat) cmd_enable_category "$@" ;;
disable-all) cmd_disable_all "$@" ;;
enable-category|enable-cat) cmd_enable_category "$@" ;;
disable-category|disable-cat) cmd_disable_category "$@" ;;
pick) cmd_pick "$@" ;;
disable-pick) cmd_disable_pick "$@" ;;
search) cmd_search "$@" ;;
disable-search) cmd_disable_search "$@" ;;
reindex) cmd_reindex "$@" ;;
-h|--help|help) usage ;;
*) echo "unknown command: $cmd" >&2; usage; exit 2 ;;