20cdf74b58
Placing -g after -- made ripgrep treat the filters as literal positional paths instead of options, so the .obsidian/.git/*.md exclusions were silently inert (confirmed: matched inside a .pdf).
60 lines
1.9 KiB
Bash
Executable File
60 lines
1.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Full-text search strictly confined to a configured vault.
|
|
#
|
|
# Usage: vault_search.sh <query> [vault-name] [subfolder]
|
|
# - query: search term (plain text, treated as a fixed string, not a
|
|
# shell-interpreted pattern)
|
|
# - vault-name: optional if only one vault is configured
|
|
# - subfolder: optional, relative subfolder to narrow the search; rejected
|
|
# if it tries to escape the vault (e.g. contains '..' or is
|
|
# an absolute path)
|
|
#
|
|
# The vault path always comes from
|
|
# ~/.agent-skills/obsidian-vault-kb/config.json — never from a raw argument —
|
|
# so this script can't be used to search outside the configured vault(s).
|
|
|
|
set -euo pipefail
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
# shellcheck source=_lib.sh
|
|
source "$SCRIPT_DIR/_lib.sh"
|
|
|
|
QUERY="${1:?Usage: vault_search.sh <query> [vault-name] [subfolder]}"
|
|
VAULT_NAME="${2:-}"
|
|
SUBFOLDER="${3:-}"
|
|
|
|
VAULT_RAW="$(resolve_vault_path "$VAULT_NAME")"
|
|
VAULT="$(canonicalize_and_check_dir "$VAULT_RAW")"
|
|
|
|
SEARCH_ROOT="$VAULT"
|
|
if [ -n "$SUBFOLDER" ]; then
|
|
case "$SUBFOLDER" in
|
|
/*|*..*)
|
|
echo "Error: subfolder must be a relative path within the vault (no '..' or absolute paths)." >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
CANDIDATE="$VAULT/$SUBFOLDER"
|
|
SEARCH_ROOT="$(realpath -e "$CANDIDATE" 2>/dev/null)" || {
|
|
echo "Error: subfolder '$SUBFOLDER' does not exist in the vault." >&2
|
|
exit 1
|
|
}
|
|
# Ensure the resolved path is still inside the vault after symlink resolution.
|
|
case "$SEARCH_ROOT" in
|
|
"$VAULT"/*|"$VAULT") ;;
|
|
*)
|
|
echo "Error: subfolder resolves outside the vault, refusing." >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
echo "== Search root: $SEARCH_ROOT =="
|
|
echo
|
|
|
|
if command -v rg >/dev/null 2>&1; then
|
|
rg -i -n --fixed-strings -g '!.obsidian' -g '!.git' -g '*.md' \
|
|
-- "$QUERY" "$SEARCH_ROOT" || echo "(no matches)"
|
|
else
|
|
grep -ril -- "$QUERY" "$SEARCH_ROOT" --include='*.md' 2>/dev/null || echo "(no matches)"
|
|
fi
|