main
1# Pi coding agent helpers
2has pi || return
3
4# Path to the session helper script (sourced from same directory as this file)
5_PI_SESSION_HELPER="${0:A:h}/_pi-session-helper"
6
7# pir-fork: fuzzy-pick a pi session and fork it into a new session
8#
9# By default shows sessions from the current project directory, all time.
10# --all / -a show sessions from all projects
11# --week / -w last 7 days only
12# --month / -m last 30 days only
13# --days N last N days
14#
15# Inside fzf:
16# ctrl-a show all projects
17# ctrl-p show current project only
18# alt-w show last 7 days (week)
19# alt-m show last 30 days (month)
20# alt-t show all time (total)
21function pir-fork() {
22 local show_all=false
23 local days=""
24 local filter_cwd="$(pwd)"
25
26 while [[ $# -gt 0 ]]; do
27 case "$1" in
28 --all|-a) show_all=true; shift ;;
29 --week|-w) days=7; shift ;;
30 --month|-m) days=30; shift ;;
31 --days) days="$2"; shift 2 ;;
32 *) shift ;;
33 esac
34 done
35
36 [[ -d "${HOME}/.pi/agent/sessions/" ]] || { echo "No sessions found" >&2; return 1; }
37
38 # Build initial list command
39 local list_base="${_PI_SESSION_HELPER} list"
40 local list_cmd="$list_base"
41 [[ "$show_all" == "true" ]] && list_cmd+=" --all" || list_cmd+=" --cwd ${(q)filter_cwd}"
42 [[ -n "$days" ]] && list_cmd+=" --days $days"
43
44 local entries
45 entries=$(eval "$list_cmd")
46
47 if [[ -z "$entries" ]]; then
48 if [[ "$show_all" == "false" ]]; then
49 echo "No sessions found for $(pwd). Try: pir-fork --all" >&2
50 else
51 echo "No sessions found" >&2
52 fi
53 return 1
54 fi
55
56 # Precompute reload commands for fzf bindings
57 # Scope toggles (preserve no time filter — user can combine with ctrl-1/2/3)
58 local rld_all="${list_base} --all"
59 local rld_project="${list_base} --cwd ${(q)filter_cwd}"
60 local rld_all_7d="${rld_all} --days 7"
61 local rld_all_30d="${rld_all} --days 30"
62 local rld_proj_7d="${rld_project} --days 7"
63 local rld_proj_30d="${rld_project} --days 30"
64
65 # Initial state for header
66 local scope_label
67 [[ "$show_all" == "true" ]] && scope_label="all projects" || scope_label="${filter_cwd/$HOME/\~}"
68 local time_label
69 [[ -n "$days" ]] && time_label="last ${days}d" || time_label="all time"
70
71 local selected
72 selected=$(printf "%s\n" "$entries" \
73 | fzf --delimiter='\t' \
74 --with-nth=1..3 \
75 --preview="${_PI_SESSION_HELPER} preview {4}" \
76 --preview-window=right:50%:wrap \
77 --header="scope: ${scope_label} │ time: ${time_label}
78ctrl-a/p: scope │ alt-w/m/t: week/month/all │ ctrl-j: fork" \
79 --prompt="fork> " \
80 --bind="ctrl-j:accept" \
81 --bind="ctrl-a:reload(${rld_all})+change-header(scope: all projects │ time: all
82ctrl-a/p: scope │ alt-w/m/t: week/month/all │ ctrl-j: fork)" \
83 --bind="ctrl-p:reload(${rld_project})+change-header(scope: ${scope_label} │ time: all
84ctrl-a/p: scope │ alt-w/m/t: week/month/all │ ctrl-j: fork)" \
85 --bind="alt-w:reload(${rld_proj_7d})+change-header(scope: ${scope_label} │ time: last 7d
86ctrl-a/p: scope │ alt-w/m/t: week/month/all │ ctrl-j: fork)" \
87 --bind="alt-m:reload(${rld_proj_30d})+change-header(scope: ${scope_label} │ time: last 30d
88ctrl-a/p: scope │ alt-w/m/t: week/month/all │ ctrl-j: fork)" \
89 --bind="alt-t:reload(${rld_project})+change-header(scope: ${scope_label} │ time: all
90ctrl-a/p: scope │ alt-w/m/t: week/month/all │ ctrl-j: fork)"
91 )
92
93 [[ -z "$selected" ]] && return 0
94
95 local uuid
96 uuid=$(printf "%s" "$selected" | awk -F'\t' '{print $NF}')
97
98 echo "Forking session ${uuid}..."
99 pi --fork "$uuid"
100}