feat: variant + domain bulk ops, enriched INDEX schema
- variants : suffix distribution counts (salva, iran, russian-doctrine, ...) - enable-variant / disable-variant : bulk by filename suffix - enable-domain / disable-domain : bulk by frontmatter Domain (live scan) - INDEX.json now exposes persona, variant, domain - INDEX.md columns expanded; top-domains and top-variants summaries - search/disable-search now also match domain & variant - regex fix: 'c2-hunting' was being parsed as 'c' (digit not allowed)
This commit is contained in:
35
README.md
35
README.md
@@ -33,21 +33,38 @@ Override via env:
|
|||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
|
|
||||||
|
### Inspection
|
||||||
|
|
||||||
| | |
|
| | |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `status` | counts of active vs parked + mode breakdown |
|
| `status` | counts of active vs parked + primary/subagent breakdown |
|
||||||
| `list {active\|parked\|all}` | list agent names |
|
| `list {active\|parked\|all}` | list agent names |
|
||||||
| `categories` / `cats` | prefix-based category counts (PARKED) |
|
| `categories` / `cats` | prefix-based base-persona counts (PARKED) |
|
||||||
|
| `variants` / `vars` | suffix-based variant counts (PARKED) — eg. `salva`, `iran` |
|
||||||
|
|
||||||
|
### Single-agent operations
|
||||||
|
|
||||||
|
| | |
|
||||||
|
|---|---|
|
||||||
| `enable <name>` | enable single agent (copy parked → active) |
|
| `enable <name>` | enable single agent (copy parked → active) |
|
||||||
| `disable <name>` | disable single agent (remove from active; keep parked) |
|
| `disable <name>` | disable single agent (remove from active; keep parked) |
|
||||||
| `disable-all [-y\|--yes] [--keep-primary]` | disable every active agent (asks for confirmation) |
|
| `disable-all [-y\|--yes] [--keep-primary]` | disable every active agent (asks for confirmation) |
|
||||||
| `enable-category <prefix>` | fzf multi-pick within a prefix, then enable |
|
|
||||||
| `disable-category <prefix>` | fzf multi-pick of ACTIVE agents with prefix, then disable |
|
### Bulk by axis
|
||||||
| `pick` | fzf: choose category → multi-select → enable |
|
|
||||||
| `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 agents only (disable) |
|
| `enable-category <prefix>` / `disable-category <prefix>` | fzf multi-pick by **base persona** prefix (eg. `frodo`, `marshal`) |
|
||||||
| `reindex` | rebuild `INDEX.json` / `INDEX.md` |
|
| `enable-variant <suffix>` / `disable-variant <suffix>` | bulk by **variant suffix** (eg. `salva`, `iran`, `russian-doctrine`) |
|
||||||
|
| `enable-domain <domain>` / `disable-domain <domain>` | bulk by `Domain:` value in description (live scan) |
|
||||||
|
|
||||||
|
### Interactive / search
|
||||||
|
|
||||||
|
| | |
|
||||||
|
|---|---|
|
||||||
|
| `pick` / `disable-pick` | fzf: pick category → multi-select |
|
||||||
|
| `search [query]` / `disable-search` | fzf fuzzy search across name + mode + domain + variant + description |
|
||||||
|
| `reindex` | rebuild `INDEX.json` / `INDEX.md` (extracts persona/variant/domain from frontmatter) |
|
||||||
|
|
||||||
`fzf` is required for the interactive pickers; `jq` for the search variants; `python3` for `reindex`.
|
`fzf` is required for the interactive pickers; `jq` for the search variants; `python3` for `reindex`.
|
||||||
|
|
||||||
|
|||||||
176
bin/opc-agents
176
bin/opc-agents
@@ -69,6 +69,103 @@ ensure_fzf() {
|
|||||||
command -v fzf >/dev/null || { echo "fzf is required for this command" >&2; exit 1; }
|
command -v fzf >/dev/null || { echo "fzf is required for this command" >&2; exit 1; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ensure_jq() {
|
||||||
|
command -v jq >/dev/null || { echo "jq is required for this command" >&2; exit 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
# suffix_of <name> — everything after the first '-' (the variant); empty for bare base
|
||||||
|
suffix_of() {
|
||||||
|
local n="$1"
|
||||||
|
case "$n" in
|
||||||
|
*-*) printf '%s\n' "${n#*-}" ;;
|
||||||
|
*) printf '%s\n' "" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# variant suffix distribution across PARKED
|
||||||
|
cmd_variants() {
|
||||||
|
require_dirs
|
||||||
|
agent_names_in "$PARKED" | while read -r n; do
|
||||||
|
local s; s=$(suffix_of "$n")
|
||||||
|
[ -n "$s" ] && printf '%s\n' "$s" || printf '%s\n' "<base>"
|
||||||
|
done | sort | uniq -c | sort -rn
|
||||||
|
}
|
||||||
|
|
||||||
|
# bulk enable agents matching variant suffix (within PARKED)
|
||||||
|
cmd_enable_variant() {
|
||||||
|
require_dirs
|
||||||
|
local v="${1:-}"
|
||||||
|
[ -n "$v" ] || { echo "usage: opc-agents enable-variant <suffix>" >&2; exit 2; }
|
||||||
|
local -a matches=()
|
||||||
|
while IFS= read -r n; do
|
||||||
|
[ -z "$n" ] && continue
|
||||||
|
[ "$(suffix_of "$n")" = "$v" ] && matches+=("$n")
|
||||||
|
done < <(agent_names_in "$PARKED")
|
||||||
|
[ "${#matches[@]}" -gt 0 ] || { echo "no parked agents with variant: $v" >&2; exit 1; }
|
||||||
|
echo "Will enable ${#matches[@]} agent(s) with variant '$v':"
|
||||||
|
printf ' %s\n' "${matches[@]}"
|
||||||
|
local n
|
||||||
|
for n in "${matches[@]}"; do cmd_enable "$n" || true; done
|
||||||
|
}
|
||||||
|
|
||||||
|
# bulk disable from ACTIVE matching variant suffix
|
||||||
|
cmd_disable_variant() {
|
||||||
|
require_dirs
|
||||||
|
local v="${1:-}"
|
||||||
|
[ -n "$v" ] || { echo "usage: opc-agents disable-variant <suffix>" >&2; exit 2; }
|
||||||
|
local -a matches=()
|
||||||
|
while IFS= read -r n; do
|
||||||
|
[ -z "$n" ] && continue
|
||||||
|
[ "$(suffix_of "$n")" = "$v" ] && matches+=("$n")
|
||||||
|
done < <(agent_names_in "$ACTIVE")
|
||||||
|
[ "${#matches[@]}" -gt 0 ] || { echo "no active agents with variant: $v" >&2; exit 1; }
|
||||||
|
echo "Will disable ${#matches[@]} agent(s) with variant '$v':"
|
||||||
|
printf ' %s\n' "${matches[@]}"
|
||||||
|
local n
|
||||||
|
for n in "${matches[@]}"; do cmd_disable "$n" || true; done
|
||||||
|
}
|
||||||
|
|
||||||
|
# live scan: emit agent base-names whose description matches Domain: <wanted>
|
||||||
|
# (INDEX-free, so it stays correct between reindexes)
|
||||||
|
domain_scan_in() {
|
||||||
|
local base="$1" wanted="$2"
|
||||||
|
[ -d "$base" ] || return 0
|
||||||
|
grep -liE "^description:.*[Dd]omain:[[:space:]]*${wanted}([^A-Za-z]|$)" \
|
||||||
|
"$base"/*.md 2>/dev/null \
|
||||||
|
| while read -r f; do
|
||||||
|
local b; b=$(basename "$f" .md)
|
||||||
|
case "$b" in INDEX|README) ;; *) printf '%s\n' "$b" ;; esac
|
||||||
|
done | sort -u
|
||||||
|
}
|
||||||
|
|
||||||
|
# bulk enable agents whose 'domain' matches (live scan, no INDEX dependency)
|
||||||
|
cmd_enable_domain() {
|
||||||
|
require_dirs
|
||||||
|
local d="${1:-}"
|
||||||
|
[ -n "$d" ] || { echo "usage: opc-agents enable-domain <domain>" >&2; exit 2; }
|
||||||
|
local -a matches=()
|
||||||
|
mapfile -t matches < <(domain_scan_in "$PARKED" "$d")
|
||||||
|
[ "${#matches[@]}" -gt 0 ] || { echo "no parked agents in domain: $d" >&2; exit 1; }
|
||||||
|
echo "Will enable ${#matches[@]} agent(s) in domain '$d':"
|
||||||
|
printf ' %s\n' "${matches[@]}"
|
||||||
|
local n
|
||||||
|
for n in "${matches[@]}"; do cmd_enable "$n" || true; done
|
||||||
|
}
|
||||||
|
|
||||||
|
# bulk disable from ACTIVE matching domain (live scan)
|
||||||
|
cmd_disable_domain() {
|
||||||
|
require_dirs
|
||||||
|
local d="${1:-}"
|
||||||
|
[ -n "$d" ] || { echo "usage: opc-agents disable-domain <domain>" >&2; exit 2; }
|
||||||
|
local -a matches=()
|
||||||
|
mapfile -t matches < <(domain_scan_in "$ACTIVE" "$d")
|
||||||
|
[ "${#matches[@]}" -gt 0 ] || { echo "no active agents in domain: $d" >&2; exit 1; }
|
||||||
|
echo "Will disable ${#matches[@]} agent(s) in domain '$d':"
|
||||||
|
printf ' %s\n' "${matches[@]}"
|
||||||
|
local n
|
||||||
|
for n in "${matches[@]}"; do cmd_disable "$n" || true; done
|
||||||
|
}
|
||||||
|
|
||||||
# enable one agent by base-name (no .md)
|
# enable one agent by base-name (no .md)
|
||||||
cmd_enable() {
|
cmd_enable() {
|
||||||
require_dirs
|
require_dirs
|
||||||
@@ -244,18 +341,18 @@ cmd_search() {
|
|||||||
[ -f "$INDEX_JSON" ] || { echo "INDEX.json missing — run: opc-agents reindex" >&2; exit 1; }
|
[ -f "$INDEX_JSON" ] || { echo "INDEX.json missing — run: opc-agents reindex" >&2; exit 1; }
|
||||||
local query="${1:-}"
|
local query="${1:-}"
|
||||||
local tmp; tmp=$(mktemp)
|
local tmp; tmp=$(mktemp)
|
||||||
jq -r '.[] | "\(.name)\t\(.mode)\t\(.description)"' "$INDEX_JSON" > "$tmp"
|
jq -r '.[] | "\(.name)\t\(.mode)\t\(.domain // "-")\t\(.variant // "-")\t\(.description)"' "$INDEX_JSON" > "$tmp"
|
||||||
local selection
|
local selection
|
||||||
if [ -n "$query" ]; then
|
if [ -n "$query" ]; then
|
||||||
selection=$(fzf --query="$query" --multi --height=80% \
|
selection=$(fzf --query="$query" --multi --height=80% \
|
||||||
--delimiter='\t' --with-nth=1,2,3 \
|
--delimiter='\t' --with-nth=1,2,3,4,5 \
|
||||||
--prompt="search > " \
|
--prompt="search > " \
|
||||||
--header="TAB: toggle | ENTER: enable selected" \
|
--header="TAB: toggle | ENTER: enable selected" \
|
||||||
--preview="sed -n '1,40p' \"$PARKED/{1}.md\" 2>/dev/null || echo '(not parked — maybe already active)'" \
|
--preview="sed -n '1,40p' \"$PARKED/{1}.md\" 2>/dev/null || echo '(not parked — maybe already active)'" \
|
||||||
--preview-window=right:60%:wrap < "$tmp")
|
--preview-window=right:60%:wrap < "$tmp")
|
||||||
else
|
else
|
||||||
selection=$(fzf --multi --height=80% \
|
selection=$(fzf --multi --height=80% \
|
||||||
--delimiter='\t' --with-nth=1,2,3 \
|
--delimiter='\t' --with-nth=1,2,3,4,5 \
|
||||||
--prompt="search > " \
|
--prompt="search > " \
|
||||||
--header="TAB: toggle | ENTER: enable selected" \
|
--header="TAB: toggle | ENTER: enable selected" \
|
||||||
--preview="sed -n '1,40p' \"$PARKED/{1}.md\" 2>/dev/null || echo '(not parked — maybe already active)'" \
|
--preview="sed -n '1,40p' \"$PARKED/{1}.md\" 2>/dev/null || echo '(not parked — maybe already active)'" \
|
||||||
@@ -264,7 +361,7 @@ cmd_search() {
|
|||||||
rm -f "$tmp"
|
rm -f "$tmp"
|
||||||
[ -n "$selection" ] || { echo "cancelled"; exit 0; }
|
[ -n "$selection" ] || { echo "cancelled"; exit 0; }
|
||||||
local name
|
local name
|
||||||
while IFS=$'\t' read -r name _ _; do
|
while IFS=$'\t' read -r name _ _ _ _; do
|
||||||
[ -z "$name" ] && continue
|
[ -z "$name" ] && continue
|
||||||
cmd_enable "$name" || true
|
cmd_enable "$name" || true
|
||||||
done <<< "$selection"
|
done <<< "$selection"
|
||||||
@@ -278,19 +375,19 @@ cmd_disable_search() {
|
|||||||
[ -f "$INDEX_JSON" ] || { echo "INDEX.json missing — run: opc-agents reindex" >&2; exit 1; }
|
[ -f "$INDEX_JSON" ] || { echo "INDEX.json missing — run: opc-agents reindex" >&2; exit 1; }
|
||||||
local query="${1:-}"
|
local query="${1:-}"
|
||||||
local tmp; tmp=$(mktemp)
|
local tmp; tmp=$(mktemp)
|
||||||
jq -r '.[] | select(.status=="active" or .status=="both") | "\(.name)\t\(.mode)\t\(.description)"' "$INDEX_JSON" > "$tmp"
|
jq -r '.[] | select(.status=="active" or .status=="both") | "\(.name)\t\(.mode)\t\(.domain // "-")\t\(.variant // "-")\t\(.description)"' "$INDEX_JSON" > "$tmp"
|
||||||
[ -s "$tmp" ] || { rm -f "$tmp"; echo "no active agents indexed (try: opc-agents reindex)"; exit 0; }
|
[ -s "$tmp" ] || { rm -f "$tmp"; echo "no active agents indexed (try: opc-agents reindex)"; exit 0; }
|
||||||
local selection
|
local selection
|
||||||
if [ -n "$query" ]; then
|
if [ -n "$query" ]; then
|
||||||
selection=$(fzf --query="$query" --multi --height=80% \
|
selection=$(fzf --query="$query" --multi --height=80% \
|
||||||
--delimiter='\t' --with-nth=1,2,3 \
|
--delimiter='\t' --with-nth=1,2,3,4,5 \
|
||||||
--prompt="disable-search > " \
|
--prompt="disable-search > " \
|
||||||
--header="TAB: toggle | ENTER: disable selected" \
|
--header="TAB: toggle | ENTER: disable selected" \
|
||||||
--preview="sed -n '1,40p' \"$ACTIVE/{1}.md\" 2>/dev/null" \
|
--preview="sed -n '1,40p' \"$ACTIVE/{1}.md\" 2>/dev/null" \
|
||||||
--preview-window=right:60%:wrap < "$tmp")
|
--preview-window=right:60%:wrap < "$tmp")
|
||||||
else
|
else
|
||||||
selection=$(fzf --multi --height=80% \
|
selection=$(fzf --multi --height=80% \
|
||||||
--delimiter='\t' --with-nth=1,2,3 \
|
--delimiter='\t' --with-nth=1,2,3,4,5 \
|
||||||
--prompt="disable-search > " \
|
--prompt="disable-search > " \
|
||||||
--header="TAB: toggle | ENTER: disable selected" \
|
--header="TAB: toggle | ENTER: disable selected" \
|
||||||
--preview="sed -n '1,40p' \"$ACTIVE/{1}.md\" 2>/dev/null" \
|
--preview="sed -n '1,40p' \"$ACTIVE/{1}.md\" 2>/dev/null" \
|
||||||
@@ -299,7 +396,7 @@ cmd_disable_search() {
|
|||||||
rm -f "$tmp"
|
rm -f "$tmp"
|
||||||
[ -n "$selection" ] || { echo "cancelled"; exit 0; }
|
[ -n "$selection" ] || { echo "cancelled"; exit 0; }
|
||||||
local name
|
local name
|
||||||
while IFS=$'\t' read -r name _ _; do
|
while IFS=$'\t' read -r name _ _ _ _; do
|
||||||
[ -z "$name" ] && continue
|
[ -z "$name" ] && continue
|
||||||
cmd_disable "$name" || true
|
cmd_disable "$name" || true
|
||||||
done <<< "$selection"
|
done <<< "$selection"
|
||||||
@@ -319,8 +416,9 @@ out_md = Path(sys.argv[4])
|
|||||||
|
|
||||||
def read_agent(p: Path):
|
def read_agent(p: Path):
|
||||||
name = p.stem
|
name = p.stem
|
||||||
desc = ""
|
desc, mode, domain, variant = "", "", "", ""
|
||||||
mode = ""
|
persona = name.split("-", 1)[0]
|
||||||
|
suffix = name[len(persona)+1:] if "-" in name else ""
|
||||||
try:
|
try:
|
||||||
txt = p.read_text(errors="replace")
|
txt = p.read_text(errors="replace")
|
||||||
m = re.match(r"^---\s*\n(.*?)\n---\s*\n", txt, re.DOTALL)
|
m = re.match(r"^---\s*\n(.*?)\n---\s*\n", txt, re.DOTALL)
|
||||||
@@ -332,18 +430,32 @@ def read_agent(p: Path):
|
|||||||
if mo: mode = mo.group(1).strip()
|
if mo: mode = mo.group(1).strip()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
desc = f"(read error: {e})"
|
desc = f"(read error: {e})"
|
||||||
return name, desc, mode
|
# Domain & Variant from description (allow digits and hyphens, eg. "c2-hunting")
|
||||||
|
dm = re.search(r"Domain:\s*([A-Za-z]+)", desc)
|
||||||
|
if dm: domain = dm.group(1).lower()
|
||||||
|
vm = re.search(r"Variant:\s*([A-Za-z0-9][A-Za-z0-9-]*)", desc)
|
||||||
|
if vm:
|
||||||
|
variant = vm.group(1).lower()
|
||||||
|
elif suffix:
|
||||||
|
variant = suffix # fallback to filename suffix
|
||||||
|
return {
|
||||||
|
"name": name, "persona": persona, "variant": variant,
|
||||||
|
"mode": mode or "?", "domain": domain,
|
||||||
|
"description": desc,
|
||||||
|
}
|
||||||
|
|
||||||
seen = {}
|
seen = {}
|
||||||
def scan(base: Path, status: str):
|
def scan(base: Path, status: str):
|
||||||
if not base.exists(): return
|
if not base.exists(): return
|
||||||
for p in sorted(base.glob("*.md")):
|
for p in sorted(base.glob("*.md")):
|
||||||
if p.name in ("INDEX.md", "README.md"): continue
|
if p.name in ("INDEX.md", "README.md"): continue
|
||||||
n, d, m = read_agent(p)
|
rec = read_agent(p)
|
||||||
|
n = rec["name"]
|
||||||
if n in seen:
|
if n in seen:
|
||||||
seen[n]["status"] = "both"
|
seen[n]["status"] = "both"
|
||||||
else:
|
else:
|
||||||
seen[n] = {"name": n, "mode": m or "?", "description": d, "status": status}
|
rec["status"] = status
|
||||||
|
seen[n] = rec
|
||||||
|
|
||||||
scan(active, "active")
|
scan(active, "active")
|
||||||
scan(parked, "parked")
|
scan(parked, "parked")
|
||||||
@@ -356,21 +468,33 @@ parked_n = sum(1 for i in items if i["status"] in ("parked", "both"))
|
|||||||
prim = sum(1 for i in items if i["mode"] == "primary")
|
prim = sum(1 for i in items if i["mode"] == "primary")
|
||||||
sub = sum(1 for i in items if i["mode"] == "subagent")
|
sub = sum(1 for i in items if i["mode"] == "subagent")
|
||||||
|
|
||||||
|
# domain & variant breakdowns
|
||||||
|
from collections import Counter
|
||||||
|
dom_c = Counter(i["domain"] for i in items if i["domain"])
|
||||||
|
var_c = Counter(i["variant"] for i in items if i["variant"])
|
||||||
|
top_doms = ", ".join(f"{k}:{v}" for k,v in dom_c.most_common(8))
|
||||||
|
top_vars = ", ".join(f"{k}:{v}" for k,v in var_c.most_common(8))
|
||||||
|
|
||||||
lines = [
|
lines = [
|
||||||
"# Opencode Agents — Index",
|
"# Opencode Agents — Index",
|
||||||
"",
|
"",
|
||||||
f"**{len(items)} unique agents** — active: {active_n}, parked: {parked_n}.",
|
f"**{len(items)} unique agents** — active: {active_n}, parked: {parked_n}.",
|
||||||
f"Modes — primary: {prim}, subagent: {sub}.",
|
f"Modes — primary: {prim}, subagent: {sub}.",
|
||||||
|
f"Top domains — {top_doms}.",
|
||||||
|
f"Top variants — {top_vars}.",
|
||||||
"",
|
"",
|
||||||
f"Active: `{active}` | Parked: `{parked}`",
|
f"Active: `{active}` | Parked: `{parked}`",
|
||||||
"",
|
"",
|
||||||
"| # | Status | Mode | Name | Description |",
|
"| # | Status | Mode | Persona | Variant | Domain | Name | Description |",
|
||||||
"|---|--------|------|------|-------------|",
|
"|---|--------|------|---------|---------|--------|------|-------------|",
|
||||||
]
|
]
|
||||||
for i, it in enumerate(items, 1):
|
for i, it in enumerate(items, 1):
|
||||||
d = it["description"].replace("\n", " ").replace("|", "\\|")
|
d = it["description"].replace("\n", " ").replace("|", "\\|")
|
||||||
if len(d) > 200: d = d[:197] + "..."
|
if len(d) > 160: d = d[:157] + "..."
|
||||||
lines.append(f"| {i} | {it['status']} | {it['mode']} | `{it['name']}` | {d} |")
|
lines.append(
|
||||||
|
f"| {i} | {it['status']} | {it['mode']} | {it['persona']} | "
|
||||||
|
f"{it['variant'] or '-'} | {it['domain'] or '-'} | `{it['name']}` | {d} |"
|
||||||
|
)
|
||||||
out_md.write_text("\n".join(lines) + "\n")
|
out_md.write_text("\n".join(lines) + "\n")
|
||||||
print(f"reindexed: {len(items)} agents (active={active_n}, parked={parked_n}, primary={prim}, subagent={sub})")
|
print(f"reindexed: {len(items)} agents (active={active_n}, parked={parked_n}, primary={prim}, subagent={sub})")
|
||||||
PY
|
PY
|
||||||
@@ -382,18 +506,23 @@ opc-agents — opencode agent manager (file-based: <name>.md)
|
|||||||
|
|
||||||
status counts of active vs parked (+ mode breakdown)
|
status counts of active vs parked (+ mode breakdown)
|
||||||
list {active|parked|all} list agent names
|
list {active|parked|all} list agent names
|
||||||
categories prefix-based category counts (PARKED)
|
categories prefix-based base-persona counts (PARKED)
|
||||||
|
variants suffix-based variant counts (PARKED) — eg. salva, iran
|
||||||
enable <name> enable single agent (copy parked → active)
|
enable <name> enable single agent (copy parked → active)
|
||||||
disable <name> disable single agent (remove from active; keep parked)
|
disable <name> disable single agent (remove from active; keep parked)
|
||||||
disable-all [-y|--yes] [--keep-primary]
|
disable-all [-y|--yes] [--keep-primary]
|
||||||
disable every active agent (asks for confirmation)
|
disable every active agent (asks for confirmation)
|
||||||
enable-category <prefix> fzf multi-pick within a prefix, then enable
|
enable-category <prefix> fzf multi-pick within a base-persona prefix, then enable
|
||||||
disable-category <prefix> fzf multi-pick of ACTIVE agents with prefix, then disable
|
disable-category <prefix> fzf multi-pick of ACTIVE agents with prefix, then disable
|
||||||
|
enable-variant <suffix> bulk enable all *-<suffix>.md from PARKED (eg. salva)
|
||||||
|
disable-variant <suffix> bulk disable all *-<suffix>.md from ACTIVE
|
||||||
|
enable-domain <domain> bulk enable agents whose `Domain: <x>` matches (live scan)
|
||||||
|
disable-domain <domain> bulk disable from ACTIVE matching domain (live scan)
|
||||||
pick fzf: choose category → multi-select → enable
|
pick fzf: choose category → multi-select → enable
|
||||||
disable-pick fzf: choose ACTIVE category → multi-select → disable
|
disable-pick fzf: choose ACTIVE category → multi-select → disable
|
||||||
search [query] fzf fuzzy search across name+description (enable)
|
search [query] fzf fuzzy search (name+mode+domain+variant+description)
|
||||||
disable-search [query] fzf fuzzy search ACTIVE agents only (disable)
|
disable-search [query] fzf fuzzy search ACTIVE agents only (disable)
|
||||||
reindex rebuild INDEX.json / INDEX.md
|
reindex rebuild INDEX.json / INDEX.md (extracts persona/variant/domain)
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
- Each agent is a single <name>.md file (frontmatter + body).
|
- Each agent is a single <name>.md file (frontmatter + body).
|
||||||
@@ -414,11 +543,16 @@ main() {
|
|||||||
status) cmd_status "$@" ;;
|
status) cmd_status "$@" ;;
|
||||||
list) cmd_list "$@" ;;
|
list) cmd_list "$@" ;;
|
||||||
categories|cats) cmd_categories "$@" ;;
|
categories|cats) cmd_categories "$@" ;;
|
||||||
|
variants|vars) cmd_variants "$@" ;;
|
||||||
enable) cmd_enable "$@" ;;
|
enable) cmd_enable "$@" ;;
|
||||||
disable) cmd_disable "$@" ;;
|
disable) cmd_disable "$@" ;;
|
||||||
disable-all) cmd_disable_all "$@" ;;
|
disable-all) cmd_disable_all "$@" ;;
|
||||||
enable-category|enable-cat) cmd_enable_category "$@" ;;
|
enable-category|enable-cat) cmd_enable_category "$@" ;;
|
||||||
disable-category|disable-cat) cmd_disable_category "$@" ;;
|
disable-category|disable-cat) cmd_disable_category "$@" ;;
|
||||||
|
enable-variant|enable-var) cmd_enable_variant "$@" ;;
|
||||||
|
disable-variant|disable-var) cmd_disable_variant "$@" ;;
|
||||||
|
enable-domain) cmd_enable_domain "$@" ;;
|
||||||
|
disable-domain) cmd_disable_domain "$@" ;;
|
||||||
pick) cmd_pick "$@" ;;
|
pick) cmd_pick "$@" ;;
|
||||||
disable-pick) cmd_disable_pick "$@" ;;
|
disable-pick) cmd_disable_pick "$@" ;;
|
||||||
search) cmd_search "$@" ;;
|
search) cmd_search "$@" ;;
|
||||||
|
|||||||
Reference in New Issue
Block a user