fix(@scripts/session-tools): 🐛 optimize session uuid filtering logic
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
fa872a3718
commit
a55457ee5e
1 changed files with 50 additions and 39 deletions
89
bin/rclaude
89
bin/rclaude
|
|
@ -176,51 +176,58 @@ list_search_on() {
|
|||
list_sessions_on "$1"
|
||||
}
|
||||
|
||||
# Grep the full content of every Claude session JSONL AND the per-session
|
||||
# metadata index (~/.claude/sessions/*.json — which holds display names set
|
||||
# via `claude -n <name>`) on <host> for <pat>, and emit matching rows in
|
||||
# list_sessions_on() format. Used as a fallback when the cheap pattern path
|
||||
# (first-message snippets + cwd) returns nothing.
|
||||
deep_search_on() {
|
||||
# Filter list_sessions_on output to the rows whose uuid is in <uuid_list>
|
||||
# (newline-separated). Centralizes the regex-build + lookup.
|
||||
_filter_sessions_to_uuids() {
|
||||
_host=$1; _uuids=$2
|
||||
[ -z "$_uuids" ] && return 0
|
||||
_re=$(printf '%s\n' "$_uuids" | sort -u | grep -v '^$' | tr '\n' '|' | sed 's/|$//')
|
||||
[ -z "$_re" ] && return 0
|
||||
CLAUDE_PROJECTS_LIMIT=5000 list_sessions_on "$_host" \
|
||||
| awk -F'\t' -v r="^($_re)$" '$3 ~ r'
|
||||
}
|
||||
|
||||
# Cheap match by session display name (the `claude -n <name>` label, stored in
|
||||
# ~/.claude/sessions/<pid>.json). Single ssh round-trip. Always included in
|
||||
# pattern searches because the file count is bounded (one per active pid).
|
||||
name_search_on() {
|
||||
_host=$1; _pat=$2
|
||||
_q=$(printf %s "$_pat" | sed "s/'/'\\\\''/g")
|
||||
# Two passes:
|
||||
# (a) grep every projects/*.jsonl for the pattern → recover uuid via filename
|
||||
# (b) scan sessions/*.json (per-pid metadata: display name set via `claude -n`)
|
||||
# via python, extract sessionId of any whose `name` contains the pattern
|
||||
_py_script='import json, os, sys, glob
|
||||
_py='import json, os, sys, glob
|
||||
pat = os.environ.get("RCLAUDE_PAT", "").lower()
|
||||
if not pat: sys.exit(0)
|
||||
for f in glob.glob(os.path.expanduser("~/.claude/sessions/*.json")):
|
||||
try:
|
||||
d = json.load(open(f))
|
||||
except Exception:
|
||||
continue
|
||||
try: d = json.load(open(f))
|
||||
except Exception: continue
|
||||
name = (d.get("name") or "").lower()
|
||||
sid = d.get("sessionId") or ""
|
||||
if pat in name and sid:
|
||||
print(sid)'
|
||||
sid = d.get("sessionId") or ""
|
||||
if pat in name and sid: print(sid)'
|
||||
if is_local "$_host"; then
|
||||
_uuids_a=$(grep -l -F -i -- "$_pat" "$HOME/.claude/projects/"*/*.jsonl 2>/dev/null \
|
||||
| awk -F/ '{print $NF}' | sed 's/\.jsonl$//')
|
||||
_uuids_b=$(RCLAUDE_PAT="$_pat" python3 -c "$_py_script" 2>/dev/null || true)
|
||||
_uuids=$(RCLAUDE_PAT="$_pat" python3 -c "$_py" 2>/dev/null || true)
|
||||
else
|
||||
_uuids_a=$(ssh -o BatchMode=yes -o ConnectTimeout=5 "$_host" \
|
||||
"grep -l -F -i -- '$_q' \$HOME/.claude/projects/*/*.jsonl 2>/dev/null \
|
||||
| awk -F/ '{print \$NF}' | sed 's/\\.jsonl\$//'" 2>/dev/null || true)
|
||||
_uuids_b=$(ssh -o BatchMode=yes -o ConnectTimeout=5 "$_host" \
|
||||
_uuids=$(ssh -o BatchMode=yes -o ConnectTimeout=5 "$_host" \
|
||||
"RCLAUDE_PAT='$_q' python3 -" 2>/dev/null <<PYEOF || true
|
||||
$_py_script
|
||||
$_py
|
||||
PYEOF
|
||||
)
|
||||
fi
|
||||
_uuids=$(printf '%s\n%s\n' "$_uuids_a" "$_uuids_b" | sort -u | grep -v '^$' || true)
|
||||
[ -z "$_uuids" ] && return 0
|
||||
_re=$(printf '%s\n' "$_uuids" | tr '\n' '|' | sed 's/|$//')
|
||||
[ -z "$_re" ] && return 0
|
||||
# Bump CLAUDE_PROJECTS_LIMIT for this lookup so older matches aren't lost.
|
||||
CLAUDE_PROJECTS_LIMIT=5000 list_sessions_on "$_host" \
|
||||
| awk -F'\t' -v r="^($_re)$" '$3 ~ r'
|
||||
_filter_sessions_to_uuids "$_host" "$_uuids"
|
||||
}
|
||||
|
||||
# Grep the full content of every Claude session JSONL on <host> for <pat>.
|
||||
# Expensive — only used as the final fallback when cheap searches return nothing.
|
||||
deep_search_on() {
|
||||
_host=$1; _pat=$2
|
||||
_q=$(printf %s "$_pat" | sed "s/'/'\\\\''/g")
|
||||
if is_local "$_host"; then
|
||||
_uuids=$(grep -l -F -i -- "$_pat" "$HOME/.claude/projects/"*/*.jsonl 2>/dev/null \
|
||||
| awk -F/ '{print $NF}' | sed 's/\.jsonl$//')
|
||||
else
|
||||
_uuids=$(ssh -o BatchMode=yes -o ConnectTimeout=5 "$_host" \
|
||||
"grep -l -F -i -- '$_q' \$HOME/.claude/projects/*/*.jsonl 2>/dev/null \
|
||||
| awk -F/ '{print \$NF}' | sed 's/\\.jsonl\$//'" 2>/dev/null || true)
|
||||
fi
|
||||
_filter_sessions_to_uuids "$_host" "$_uuids"
|
||||
}
|
||||
|
||||
# Get $HOME on <host> (cached per host in /tmp for the life of this shell).
|
||||
|
|
@ -510,8 +517,15 @@ cmd_resume() {
|
|||
_matches=${_tmux:-$_disk_slice}
|
||||
fi
|
||||
else
|
||||
_matches=$(scan_hosts | while IFS= read -r h; do list_search_on "$h"; done)
|
||||
_matches=$(printf '%s\n' "$_matches" | grep -F -i -- "$_pattern" || true)
|
||||
# Pattern search ordering (cheapest → expensive):
|
||||
# 1. session display names (~/.claude/sessions/*.json) — fast: one
|
||||
# bounded python scan per host, hits sessions named via `claude -n`
|
||||
# 2. first-user-message snippets + cwd — cheap row-grep
|
||||
# Fallback (only if both empty): full-transcript grep over every jsonl
|
||||
_name_rows=$(scan_hosts | while IFS= read -r h; do name_search_on "$h" "$_pattern"; done)
|
||||
_cheap_all=$(scan_hosts | while IFS= read -r h; do list_search_on "$h"; done)
|
||||
_cheap_rows=$(printf '%s\n' "$_cheap_all" | grep -F -i -- "$_pattern" || true)
|
||||
_matches=$(printf '%s\n%s\n' "$_name_rows" "$_cheap_rows" | grep -v '^$' || true)
|
||||
_tmux_part=$(printf '%s\n' "$_matches" | awk -F'\t' '$2=="tmux"')
|
||||
_disk_part=$(printf '%s\n' "$_matches" | awk -F'\t' '$2!="tmux"' | dedupe_sessions)
|
||||
if [ -n "$_tmux_part" ] && [ -n "$_disk_part" ]; then
|
||||
|
|
@ -519,11 +533,8 @@ cmd_resume() {
|
|||
else
|
||||
_matches=${_tmux_part:-$_disk_part}
|
||||
fi
|
||||
# Cheap path searches first-user-message snippets + cwd. If nothing
|
||||
# matched, fall back to greping the full transcript content of every
|
||||
# JSONL on each host. Slower but catches mid-conversation references.
|
||||
if [ -z "$_matches" ]; then
|
||||
printf 'rclaude: no first-message hits; searching full transcripts...\n' >&2
|
||||
printf 'rclaude: no name/snippet hits; searching full transcripts...\n' >&2
|
||||
_matches=$(scan_hosts | while IFS= read -r h; do deep_search_on "$h" "$_pattern"; done | dedupe_sessions)
|
||||
fi
|
||||
fi
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue