mirror of
https://github.com/theniceboy/.config.git
synced 2026-05-11 17:36:05 +08:00
codex agent tracker
This commit is contained in:
parent
20eddd1600
commit
b08d63e4a5
96 changed files with 3057 additions and 3055 deletions
106
tmux/scripts/layout_builder.sh
Executable file
106
tmux/scripts/layout_builder.sh
Executable file
|
|
@ -0,0 +1,106 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
if [ $# -ne 1 ]; then
|
||||
tmux display-message "layout command requires direction"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dir="$1"
|
||||
|
||||
run_tmux() {
|
||||
local output
|
||||
if ! output=$(tmux "$@" 2>&1); then
|
||||
tmux display-message "layout-${dir}: tmux $* failed: ${output}"
|
||||
exit 1
|
||||
fi
|
||||
printf '%s' "$output"
|
||||
}
|
||||
|
||||
pane_count=0
|
||||
while IFS='|' read -r pid ptop pleft ppath; do
|
||||
case $pane_count in
|
||||
0)
|
||||
id1=$pid
|
||||
top1=$ptop
|
||||
left1=$pleft
|
||||
path1=$ppath
|
||||
;;
|
||||
1)
|
||||
id2=$pid
|
||||
top2=$ptop
|
||||
left2=$pleft
|
||||
path2=$ppath
|
||||
;;
|
||||
esac
|
||||
pane_count=$((pane_count + 1))
|
||||
done < <(tmux list-panes -F "#{pane_id}|#{pane_top}|#{pane_left}|#{pane_current_path}")
|
||||
|
||||
if [ "$pane_count" -ne 2 ]; then
|
||||
tmux display-message "layout-${dir} expects exactly 2 panes"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$top1" -le "$top2" ]; then
|
||||
top_id=$id1
|
||||
top_path=$path1
|
||||
bottom_id=$id2
|
||||
bottom_path=$path2
|
||||
else
|
||||
top_id=$id2
|
||||
top_path=$path2
|
||||
bottom_id=$id1
|
||||
bottom_path=$path1
|
||||
fi
|
||||
|
||||
if [ "$left1" -le "$left2" ]; then
|
||||
left_id=$id1
|
||||
left_path=$path1
|
||||
right_id=$id2
|
||||
right_path=$path2
|
||||
else
|
||||
left_id=$id2
|
||||
left_path=$path2
|
||||
right_id=$id1
|
||||
right_path=$path1
|
||||
fi
|
||||
|
||||
ensure_horizontal() {
|
||||
if [ "$top1" -ne "$top2" ]; then
|
||||
tmux display-message "layout-${dir} expects horizontal panes"
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
case "$dir" in
|
||||
right)
|
||||
new_id=$(run_tmux split-window -P -F '#{pane_id}' -h -c "$top_path" -t "$top_id")
|
||||
run_tmux join-pane -v -s "$bottom_id" -t "$top_id"
|
||||
run_tmux select-pane -t "$new_id"
|
||||
;;
|
||||
left)
|
||||
new_id=$(run_tmux split-window -P -F '#{pane_id}' -h -b -c "$top_path" -t "$top_id")
|
||||
run_tmux join-pane -v -s "$bottom_id" -t "$top_id"
|
||||
run_tmux select-pane -t "$new_id"
|
||||
;;
|
||||
up)
|
||||
ensure_horizontal
|
||||
run_tmux break-pane -d -s "$right_id"
|
||||
run_tmux select-pane -t "$left_id"
|
||||
new_id=$(run_tmux split-window -P -F '#{pane_id}' -v -b -c "$left_path" -t "$left_id")
|
||||
run_tmux join-pane -h -s "$right_id" -t "$left_id"
|
||||
run_tmux select-pane -t "$new_id"
|
||||
;;
|
||||
down)
|
||||
ensure_horizontal
|
||||
run_tmux break-pane -d -s "$right_id"
|
||||
run_tmux select-pane -t "$left_id"
|
||||
new_id=$(run_tmux split-window -P -F '#{pane_id}' -v -c "$left_path" -t "$left_id")
|
||||
run_tmux join-pane -h -s "$right_id" -t "$left_id"
|
||||
run_tmux select-pane -t "$new_id"
|
||||
;;
|
||||
*)
|
||||
tmux display-message "Unknown layout direction: ${dir}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
9
tmux/scripts/move_session.sh
Executable file
9
tmux/scripts/move_session.sh
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
#!/bin/bash
|
||||
|
||||
direction="$1"
|
||||
|
||||
if [ -z "$direction" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
python3 "$HOME/.config/tmux/scripts/session_manager.py" move "$direction"
|
||||
11
tmux/scripts/new_session.sh
Executable file
11
tmux/scripts/new_session.sh
Executable file
|
|
@ -0,0 +1,11 @@
|
|||
#!/bin/bash
|
||||
|
||||
session_id=$(tmux new-session -d -P -F '#{session_id}' 2>/dev/null)
|
||||
|
||||
if [ -z "$session_id" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
python3 "$HOME/.config/tmux/scripts/session_manager.py" ensure
|
||||
|
||||
tmux switch-client -t "$session_id"
|
||||
9
tmux/scripts/rename_session_prompt.sh
Executable file
9
tmux/scripts/rename_session_prompt.sh
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
#!/bin/bash
|
||||
|
||||
label="$1"
|
||||
|
||||
if [ -z "$label" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
python3 "$HOME/.config/tmux/scripts/session_manager.py" rename "$label"
|
||||
3
tmux/scripts/session_created.sh
Executable file
3
tmux/scripts/session_created.sh
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash
|
||||
|
||||
python3 "$HOME/.config/tmux/scripts/session_manager.py" created
|
||||
146
tmux/scripts/session_manager.py
Executable file
146
tmux/scripts/session_manager.py
Executable file
|
|
@ -0,0 +1,146 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from typing import List, Dict
|
||||
|
||||
|
||||
def run_tmux(args: List[str], check: bool = True, capture: bool = False) -> str:
|
||||
kwargs = {
|
||||
"check": check,
|
||||
}
|
||||
if capture:
|
||||
kwargs["stdout"] = subprocess.PIPE
|
||||
kwargs["text"] = True
|
||||
result = subprocess.run(["tmux", *args], **kwargs)
|
||||
if capture:
|
||||
return result.stdout.rstrip("\n")
|
||||
return ""
|
||||
|
||||
|
||||
def list_sessions() -> List[Dict[str, object]]:
|
||||
output = run_tmux([
|
||||
"list-sessions",
|
||||
"-F",
|
||||
"#{session_id}\t#{session_name}\t#{session_created}"
|
||||
], capture=True)
|
||||
if not output:
|
||||
return []
|
||||
|
||||
sessions = []
|
||||
for line in output.splitlines():
|
||||
session_id, name, created_str = line.split("\t")
|
||||
created = int(created_str)
|
||||
match = re.match(r"^(\d+)-(.*)$", name)
|
||||
if match:
|
||||
index = int(match.group(1))
|
||||
label = match.group(2)
|
||||
else:
|
||||
index = None
|
||||
label = name
|
||||
sessions.append({
|
||||
"id": session_id,
|
||||
"name": name,
|
||||
"created": created,
|
||||
"index": index,
|
||||
"label": label,
|
||||
})
|
||||
|
||||
def sort_key(entry: Dict[str, object]):
|
||||
index = entry["index"]
|
||||
return (0, index) if index is not None else (1, entry["created"])
|
||||
|
||||
sessions.sort(key=sort_key)
|
||||
return sessions
|
||||
|
||||
|
||||
def sanitize_label(label: str) -> str:
|
||||
stripped = label.strip()
|
||||
return stripped or "session"
|
||||
|
||||
|
||||
def apply_order(ordered_sessions: List[Dict[str, object]]) -> None:
|
||||
for position, session in enumerate(ordered_sessions, start=1):
|
||||
label = sanitize_label(str(session["label"]))
|
||||
new_name = f"{position}-{label}"
|
||||
run_tmux(["rename-session", "-t", session["id"], new_name])
|
||||
|
||||
|
||||
def current_session_id() -> str:
|
||||
return run_tmux(["display-message", "-p", "#{session_id}"], capture=True)
|
||||
|
||||
|
||||
def command_switch(index_str: str) -> None:
|
||||
try:
|
||||
index = int(index_str)
|
||||
except ValueError:
|
||||
return
|
||||
if index < 1:
|
||||
return
|
||||
sessions = list_sessions()
|
||||
if index > len(sessions):
|
||||
return
|
||||
run_tmux(["switch-client", "-t", sessions[index - 1]["id"]], check=False)
|
||||
|
||||
|
||||
def command_rename(label: str) -> None:
|
||||
label = sanitize_label(label)
|
||||
current_id = current_session_id()
|
||||
sessions = list_sessions()
|
||||
for session in sessions:
|
||||
if session["id"] == current_id:
|
||||
session["label"] = label
|
||||
break
|
||||
else:
|
||||
return
|
||||
apply_order(sessions)
|
||||
# run_tmux(["display-message", f"Renamed tmux session to {label}"] , check=False)
|
||||
|
||||
|
||||
def command_move(direction: str) -> None:
|
||||
direction = direction.lower()
|
||||
sessions = list_sessions()
|
||||
current_id = current_session_id()
|
||||
indices = {session["id"]: idx for idx, session in enumerate(sessions)}
|
||||
if current_id not in indices:
|
||||
return
|
||||
pos = indices[current_id]
|
||||
if direction == "left" and pos > 0:
|
||||
sessions[pos - 1], sessions[pos] = sessions[pos], sessions[pos - 1]
|
||||
elif direction == "right" and pos < len(sessions) - 1:
|
||||
sessions[pos], sessions[pos + 1] = sessions[pos + 1], sessions[pos]
|
||||
else:
|
||||
return
|
||||
apply_order(sessions)
|
||||
|
||||
|
||||
def command_ensure() -> None:
|
||||
sessions = list_sessions()
|
||||
if sessions:
|
||||
apply_order(sessions)
|
||||
|
||||
|
||||
def command_created() -> None:
|
||||
# Called after a session is created; ensure numbering stays contiguous.
|
||||
command_ensure()
|
||||
|
||||
|
||||
def main(argv: List[str]) -> None:
|
||||
if len(argv) < 2:
|
||||
return
|
||||
command = argv[1]
|
||||
if command == "switch" and len(argv) >= 3:
|
||||
command_switch(argv[2])
|
||||
elif command == "rename" and len(argv) >= 3:
|
||||
command_rename(argv[2])
|
||||
elif command == "move" and len(argv) >= 3:
|
||||
command_move(argv[2])
|
||||
elif command == "ensure":
|
||||
command_ensure()
|
||||
elif command == "created":
|
||||
command_created()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv)
|
||||
9
tmux/scripts/switch_session_by_index.sh
Executable file
9
tmux/scripts/switch_session_by_index.sh
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
#!/bin/bash
|
||||
|
||||
index="$1"
|
||||
|
||||
if [[ -z "$index" || ! "$index" =~ ^[0-9]+$ ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
python3 "$HOME/.config/tmux/scripts/session_manager.py" switch "$index"
|
||||
34
tmux/scripts/toggle_orientation.sh
Executable file
34
tmux/scripts/toggle_orientation.sh
Executable file
|
|
@ -0,0 +1,34 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
info=$(tmux list-panes -F '#{pane_id}|#{pane_top}|#{pane_left}')
|
||||
|
||||
pane_ids=()
|
||||
pane_tops=()
|
||||
pane_lefts=()
|
||||
while IFS='|' read -r pid top left; do
|
||||
[ -z "$pid" ] && continue
|
||||
pane_ids+=("$pid")
|
||||
pane_tops+=("$top")
|
||||
pane_lefts+=("$left")
|
||||
done <<EOF
|
||||
$info
|
||||
EOF
|
||||
|
||||
if [ "${#pane_ids[@]}" -ne 2 ]; then
|
||||
tmux display-message "toggle-orientation: needs exactly 2 panes"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
top_a=${pane_tops[0]}
|
||||
top_b=${pane_tops[1]}
|
||||
left_a=${pane_lefts[0]}
|
||||
left_b=${pane_lefts[1]}
|
||||
|
||||
if [ "$top_a" = "$top_b" ] && [ "$left_a" != "$left_b" ]; then
|
||||
tmux select-layout even-vertical
|
||||
elif [ "$left_a" = "$left_b" ] && [ "$top_a" != "$top_b" ]; then
|
||||
tmux select-layout even-horizontal
|
||||
else
|
||||
tmux select-layout tiled
|
||||
fi
|
||||
Loading…
Add table
Add a link
Reference in a new issue