diff --git a/television/cable/agents.toml b/television/cable/agents.toml new file mode 100644 index 0000000..99e1422 --- /dev/null +++ b/television/cable/agents.toml @@ -0,0 +1,72 @@ +[metadata] +name = "agents" +description = """ +AI coding agent CLIs found on PATH. Enter starts the agent's TUI in the current +directory. ctrl-a in fish opens this cable (_agents_bind). +""" +requirements = [] + +# Entries are "\t\t". Only agents +# whose binary resolves on PATH are listed; add a row to the table to support +# another one. The launch command may carry flags (claude, as in `ai`). +[source] +command = ''' +while IFS='|' read -r bin cmd desc; do + command -v "$bin" >/dev/null 2>&1 && + printf '%-13s %s\t%s\t%s\n' "$bin" "$desc" "$cmd" "$bin" +done <<'EOF' +omp|omp|oh-my-pi coding agent +claude|claude --dangerously-skip-permissions|Claude Code (Anthropic) +codex|codex|Codex CLI (OpenAI) +opencode|opencode|OpenCode (sst) +crush|crush|Crush (Charm) +pi|pi|pi coding agent +cursor-agent|cursor-agent|Cursor Agent CLI +copilot|copilot|GitHub Copilot CLI +gemini|gemini|Gemini CLI (Google) +agy|agy|Antigravity CLI (Google) +grok|grok|Grok CLI (xAI) +muse|muse|Muse Code (Meta) +ori|ori|Ori (OpenRouter) +hermes|hermes|Hermes Agent (Nous Research) +amp|amp|Amp (Sourcegraph) +droid|droid|Droid (Factory) +qwen|qwen|Qwen Code (Alibaba) +kimi|kimi|Kimi CLI (Moonshot) +goose|goose|goose (Block) +aider|aider|aider +auggie|auggie|Auggie (Augment Code) +kiro-cli|kiro-cli|Kiro CLI (AWS) +cn|cn|Continue CLI +fractal|fractal|fractal +EOF +''' +shell = "bash" +display = "{split:\\t:0}" +output = "{split:\\t:1}" + +[preview] +command = ''' +p=$(command -v '{split:\t:2}') +printf 'command %s\npath %s\n' '{split:\t:1}' "$p" +r=$(readlink -f "$p") +[ "$r" != "$p" ] && printf 'resolves %s\n' "$r" +# ~/.local/bin wrappers install the agent through mise on first run. +tool=$(grep -o 'mise x "[^"]*"' "$r" 2>/dev/null | cut -d'"' -f2) +[ -n "$tool" ] && printf 'mise %s\n' "$tool" +''' +shell = "bash" + +[keybindings] +enter = "actions:launch" + +# AGENTS_STATE (set by _agents_bind) tells the fish binding an agent ran, so it +# does not move the cursor back up as it does after a cancel. +[actions.launch] +description = "Start the agent's TUI" +command = ''' +[ -n "$AGENTS_STATE" ] && echo ran >"$AGENTS_STATE" +{split:\t:1} +''' +shell = "bash" +mode = "execute" diff --git a/television/cable/obsidian.toml b/television/cable/obsidian.toml new file mode 100644 index 0000000..a065dc5 --- /dev/null +++ b/television/cable/obsidian.toml @@ -0,0 +1,66 @@ +[metadata] +name = "obsidian" +description = """ +Obsidian vaults under ~/Documents/Obsidian, most recently modified first. +Enter opens the vault in Obsidian; vaults Obsidian has never opened are +registered in obsidian.json first. +""" +requirements = ["fd", "jq", "eza", "obsidian", "xdg-open", "mtime-sort"] + +# Entries are "\t": the name is what you fuzzy-match, the +# path is what the actions use. +[source] +command = ''' +v=$HOME/Documents/Obsidian +fd -H -t d -d 3 '^\.obsidian$' "$v" -x dirname | + awk -v r="$v/" '{ print substr($0, length(r) + 1) "\t" $0 }' | + mtime-sort +''' +shell = "bash" +display = "{split:\\t:0}" +output = "{split:\\t:1}" + +[preview] +command = "eza --tree --level 2 --color=always '{split:\\t:1}' 2>/dev/null || ls -la '{split:\\t:1}'" +shell = "bash" + +# ctrl-e (edit) is bound globally in config.toml. +[keybindings] +enter = "actions:open" + +# obsidian://open?path= only resolves vaults listed in obsidian.json, and +# Obsidian reads that file once at startup and rewrites it from memory. An +# unlisted vault is therefore added only while Obsidian is closed; while it +# runs, the vault switcher opens instead. +[actions.open] +description = "Open the vault in Obsidian" +command = ''' +d='{split:\t:1}' +cfg=${XDG_CONFIG_HOME:-$HOME/.config}/obsidian/obsidian.json +uri="obsidian://open?path=$(jq -rn --arg p "$d" '$p | @uri')" +if ! jq -e --arg p "$d" 'any(.vaults[]?; .path == $p)' "$cfg" >/dev/null 2>&1; then + # [o]: keep pgrep from matching this script's own command line. + if pgrep -f '[o]bsidian/app.asar' >/dev/null; then + msg="Vault not registered and Obsidian is running: use 'Open folder as vault' for $d" + echo "$msg" >&2 + notify-send Obsidian "$msg" 2>/dev/null + uri="obsidian://choose-vault" + else + mkdir -p "${cfg%/*}" + [ -s "$cfg" ] || echo '{}' >"$cfg" + tmp=$(mktemp "$cfg.XXXXXX") || exit 1 + jq --arg id "$(od -An -N8 -tx1 /dev/urandom | tr -d ' \n')" --arg p "$d" \ + --argjson ts "$(date +%s%3N)" '.vaults[$id] = {path: $p, ts: $ts}' \ + "$cfg" >"$tmp" && mv "$tmp" "$cfg" || rm -f "$tmp" + fi +fi +setsid -f xdg-open "$uri" >/dev/null 2>&1 +''' +shell = "bash" +mode = "execute" + +[actions.edit] +description = "Open the vault in nvim" +command = "cd '{split:\\t:1}' && nvim . /dev/tty" +shell = "bash" +mode = "execute"