fix(@scripts/session-tools): 🐛 locate sessions by uuid instead of slug

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Natalie 2026-05-17 07:48:00 -07:00
parent b1e7f46f25
commit 167beadec6

View file

@ -283,23 +283,26 @@ dedupe_sessions() {
' | sort -t"$(printf '\t')" -k6,6nr
}
# Mirror a session JSONL from <src_host>'s ~/.claude/projects/<src_slug>/<uuid>.jsonl
# Mirror a session JSONL from <src_host>'s ~/.claude/projects/*/<uuid>.jsonl
# to <dst_host>'s ~/.claude/projects/<dst_slug>/<uuid>.jsonl, rewriting every
# `"cwd":"<src_cwd...>"` occurrence to point at <dst_cwd...>.
# `"cwd":"<src_cwd...>"` occurrence to point at <dst_cwd...>. The source
# project-slug is NOT computed from <src_cwd> — claude stores sessions under
# the slug of the cwd-at-session-start, which can differ from any later cwd
# the session recorded — so we search for the file by uuid instead.
migrate_session() {
_src=$1; _dst=$2; _uuid=$3; _src_cwd=$4; _dst_cwd=$5
_src_slug=$(claude_slug "$_src_cwd")
_dst_slug=$(claude_slug "$_dst_cwd")
_src_path="\$HOME/.claude/projects/${_src_slug}/${_uuid}.jsonl"
_dst_path="\$HOME/.claude/projects/${_dst_slug}/${_uuid}.jsonl"
if is_local "$_src"; then
_src_data=$(cat "$HOME/.claude/projects/${_src_slug}/${_uuid}.jsonl" 2>/dev/null || true)
_src_path=$(ls "$HOME/.claude/projects/"*/"${_uuid}.jsonl" 2>/dev/null | head -1)
[ -n "$_src_path" ] && _src_data=$(cat "$_src_path" 2>/dev/null) || _src_data=""
else
_src_data=$(ssh -o BatchMode=yes -o ConnectTimeout=5 "$_src" "cat $_src_path" 2>/dev/null || true)
_src_data=$(ssh -o BatchMode=yes -o ConnectTimeout=5 "$_src" \
"cat \$(ls \$HOME/.claude/projects/*/${_uuid}.jsonl 2>/dev/null | head -1) 2>/dev/null" || true)
fi
if [ -z "$_src_data" ]; then
echo "rclaude: source session not found on $_src ($_src_path)" >&2
echo "rclaude: source session $_uuid not found anywhere under $_src:~/.claude/projects/" >&2
return 1
fi
@ -707,19 +710,22 @@ cmd_resume() {
_keys="123456789abcdefghijklmnopqrstuvwxyz"
# Append a trailing name column (host+uuid → display name from
# ~/.claude/sessions/*.json). Empty for tmux rows and for sessions
# with no `claude -n` label.
_name_map=$(build_name_map)
_matches=$(printf '%s\n' "$_matches" | awk -F'\t' -v OFS='\t' -v map="$_name_map" '
# with no `claude -n` label. Map is passed via tempfile because
# awk -v can't hold a multi-line value.
_name_map_f=$(mktemp /tmp/rclaude-namemap.XXXXXX 2>/dev/null || echo /tmp/rclaude-namemap.$$)
build_name_map > "$_name_map_f"
_matches=$(printf '%s\n' "$_matches" | awk -F'\t' -v OFS='\t' -v mapf="$_name_map_f" '
BEGIN {
n = split(map, lines, "\n")
for (i=1; i<=n; i++) {
split(lines[i], f, "\t")
while ((getline line < mapf) > 0) {
split(line, f, "\t")
if (f[1] && f[2]) names[f[1] SUBSEP f[2]] = f[3]
}
close(mapf)
}
{ nm = ($2=="tmux") ? "" : (($1 SUBSEP $3) in names ? names[$1 SUBSEP $3] : "")
print $0, nm }
')
rm -f "$_name_map_f"
if [ "$_count" -gt 35 ]; then
_orig_count=$_count
_matches=$(printf '%s\n' "$_matches" | head -n 35)
@ -739,9 +745,10 @@ cmd_resume() {
_Cp5=$(printf '\033[1;31m'); _Cp4=$(printf '\033[33m')
_Cblk=$(printf '\033[31m'); _Cwait=$(printf '\033[33m')
_Cinp=$(printf '\033[36m'); _Cdone=$(printf '\033[32m')
_Cname=$(printf '\033[1;35m') # display name: bold magenta
else
_R=; _Chost=; _Ctmux=; _Cdim=; _Ckey=
_Cp5=; _Cp4=; _Cblk=; _Cwait=; _Cinp=; _Cdone=
_Cp5=; _Cp4=; _Cblk=; _Cwait=; _Cinp=; _Cdone=; _Cname=
fi
# Kind column dropped — it carried no signal when all rows were the
# same kind. Kind is now encoded by row shape: tmux has a ▶ marker,
@ -778,13 +785,19 @@ cmd_resume() {
return ""
}
function fit(s, n) { return length(s) > n ? substr(s, 1, n-1) "…" : s }
# The trailing column (NF) is the optional display name set via
# `claude -n`. Wrap it in c_name when present.
function name_tag() {
if ($NF == "" || $2 == "tmux") return ""
return " " c_name "" $NF "" r
}
function display() {
if ($2 == "tmux")
return c_tmux "▶ " r $3
if ($2 == "triage")
return prio_c($4) "P" $4 r " " stat_c($5) sprintf("%-15s", $5) r " " $6 " " c_dim "[" substr($3,1,8) "]" r
return prio_c($4) "P" $4 r " " stat_c($5) sprintf("%-15s", $5) r " " $6 " " c_dim "[" substr($3,1,8) "]" r name_tag()
if ($2 == "session")
return $4 " " c_dim "[" substr($3,1,8) "]" r
return $4 " " c_dim "[" substr($3,1,8) "]" r name_tag()
return $3
}
{
@ -797,6 +810,7 @@ cmd_resume() {
-v r="$_R" -v c_host="$_Chost" -v c_tmux="$_Ctmux" -v c_dim="$_Cdim" \
-v c_p5="$_Cp5" -v c_p4="$_Cp4" \
-v c_blk="$_Cblk" -v c_wait="$_Cwait" -v c_inp="$_Cinp" -v c_done="$_Cdone" \
-v c_name="$_Cname" \
"$_fmt_row"'{printf "\n"}' >&2
exit 1
fi
@ -813,6 +827,7 @@ cmd_resume() {
-v r="$_R" -v c_host="$_Chost" -v c_tmux="$_Ctmux" -v c_dim="$_Cdim" \
-v c_p5="$_Cp5" -v c_p4="$_Cp4" \
-v c_blk="$_Cblk" -v c_wait="$_Cwait" -v c_inp="$_Cinp" -v c_done="$_Cdone" \
-v c_name="$_Cname" \
"$_fmt_row")
printf ' %s[%s]%s %s\n' "$_Ckey" "$_k" "$_R" "$_row_text" >&2
_prev_kind=$_kind_now