Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .agents/scripts/aidevops-update-check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ main() {
# Check for excessive concurrent interactive sessions (t1398.4)
local session_warning=""
if [[ -x "${script_dir}/session-count-helper.sh" ]]; then
session_warning="$("${script_dir}/session-count-helper.sh" check 2>/dev/null || true)"
session_warning="$("${script_dir}/session-count-helper.sh" check || true)"
fi
if [[ -n "$session_warning" ]]; then
echo "$session_warning"
Expand Down
2 changes: 1 addition & 1 deletion .agents/scripts/pre-edit-check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ else

# Session count warning (t1398.4) — non-blocking, informational only
if [[ -x "$SCRIPT_DIR/session-count-helper.sh" ]]; then
session_warning=$("$SCRIPT_DIR/session-count-helper.sh" check 2>/dev/null || true)
session_warning=$("$SCRIPT_DIR/session-count-helper.sh" check || true)
if [[ -n "$session_warning" ]]; then
echo -e "${YELLOW}${session_warning}${NC}"
fi
Expand Down
92 changes: 69 additions & 23 deletions .agents/scripts/session-count-helper.sh
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ count_interactive_sessions() {
# the first argument after the binary name.
# Headless: .opencode run ...
local opencode_pids=""
opencode_pids=$(pgrep -f '\.opencode' 2>/dev/null || true)
opencode_pids=$(pgrep -f '\.opencode' || true)

if [[ -n "$opencode_pids" ]]; then
local pid
Expand All @@ -92,7 +92,7 @@ count_interactive_sessions() {
# Linux: /proc/PID/cmdline has null-separated args
cmdline=$(tr '\0' ' ' <"/proc/${pid}/cmdline" 2>/dev/null || true)
else
# macOS fallback: ps -o args=
# macOS fallback: ps -o args= (2>/dev/null: PID may have exited)
cmdline=$(ps -o args= -p "$pid" 2>/dev/null || true)
fi

Expand All @@ -117,7 +117,7 @@ count_interactive_sessions() {
# --- Claude Code sessions ---
# Interactive claude: the claude binary WITHOUT "-p", "--print", or "run"
local claude_pids=""
claude_pids=$(pgrep -x claude 2>/dev/null || true)
claude_pids=$(pgrep -x claude || true)

if [[ -n "$claude_pids" ]]; then
local pid
Expand All @@ -127,6 +127,7 @@ count_interactive_sessions() {
if [[ -r "/proc/${pid}/cmdline" ]]; then
cmdline=$(tr '\0' ' ' <"/proc/${pid}/cmdline" 2>/dev/null || true)
else
# macOS fallback (2>/dev/null: PID may have exited)
cmdline=$(ps -o args= -p "$pid" 2>/dev/null || true)
fi

Expand All @@ -139,32 +140,48 @@ count_interactive_sessions() {
fi

# --- Cursor sessions ---
# Note: pgrep -c is not available on macOS; use pgrep | wc -l instead
local cursor_count=0
cursor_count=$(pgrep -c -f 'Cursor\.app' 2>/dev/null || true)
cursor_count=$(pgrep -f 'Cursor\.app' | wc -l || true)
count=$((count + cursor_count))

# --- Windsurf sessions ---
local windsurf_count=0
windsurf_count=$(pgrep -c -f 'Windsurf' 2>/dev/null || true)
windsurf_count=$(pgrep -f 'Windsurf' | wc -l || true)
count=$((count + windsurf_count))

# --- Aider sessions ---
local aider_count=0
aider_count=$(pgrep -c -f 'aider' 2>/dev/null || true)
aider_count=$(pgrep -f 'aider' | wc -l || true)
count=$((count + aider_count))

echo "$count"
return 0
}

# List detected interactive sessions with details.
# Output format: PID | APP | RSS_MB | UPTIME | DIR
# Output format: PID | APP | RSS_MB | UPTIME
list_sessions() {
local found=0

# Helper: print session details for a given PID and app name.
# Uses 2>/dev/null on ps calls because the PID may have exited
# between detection and inspection (race condition).
_print_session_detail() {
local pid="$1"
local app_name="$2"
local rss_mb etime
rss_mb=$(ps -o rss= -p "$pid" 2>/dev/null || echo "0")
rss_mb=$((${rss_mb:-0} / 1024))
etime=$(ps -o etime= -p "$pid" 2>/dev/null || echo "unknown")
etime=$(echo "$etime" | tr -d ' ')
echo " PID ${pid} | ${app_name} | ${rss_mb} MB | uptime: ${etime}"
return 0
}

# --- OpenCode sessions ---
local opencode_pids=""
opencode_pids=$(pgrep -f '\.opencode' 2>/dev/null || true)
opencode_pids=$(pgrep -f '\.opencode' || true)

if [[ -n "$opencode_pids" ]]; then
local pid
Expand All @@ -174,6 +191,7 @@ list_sessions() {
if [[ -r "/proc/${pid}/cmdline" ]]; then
cmdline=$(tr '\0' ' ' <"/proc/${pid}/cmdline" 2>/dev/null || true)
else
# macOS fallback (2>/dev/null: PID may have exited)
cmdline=$(ps -o args= -p "$pid" 2>/dev/null || true)
fi

Expand All @@ -188,20 +206,14 @@ list_sessions() {
continue
fi

local rss_mb etime
rss_mb=$(ps -o rss= -p "$pid" 2>/dev/null || echo "0")
rss_mb=$((${rss_mb:-0} / 1024))
etime=$(ps -o etime= -p "$pid" 2>/dev/null || echo "unknown")
etime=$(echo "$etime" | tr -d ' ')

echo " PID ${pid} | OpenCode | ${rss_mb} MB | uptime: ${etime}"
_print_session_detail "$pid" "OpenCode"
found=$((found + 1))
done <<<"$opencode_pids"
fi

# --- Claude Code sessions ---
local claude_pids=""
claude_pids=$(pgrep -x claude 2>/dev/null || true)
claude_pids=$(pgrep -x claude || true)

if [[ -n "$claude_pids" ]]; then
local pid
Expand All @@ -211,24 +223,58 @@ list_sessions() {
if [[ -r "/proc/${pid}/cmdline" ]]; then
cmdline=$(tr '\0' ' ' <"/proc/${pid}/cmdline" 2>/dev/null || true)
else
# macOS fallback (2>/dev/null: PID may have exited)
cmdline=$(ps -o args= -p "$pid" 2>/dev/null || true)
fi

if echo "$cmdline" | grep -qE 'claude (-p|--print|run) '; then
continue
fi

local rss_mb etime
rss_mb=$(ps -o rss= -p "$pid" 2>/dev/null || echo "0")
rss_mb=$((${rss_mb:-0} / 1024))
etime=$(ps -o etime= -p "$pid" 2>/dev/null || echo "unknown")
etime=$(echo "$etime" | tr -d ' ')

echo " PID ${pid} | Claude Code | ${rss_mb} MB | uptime: ${etime}"
_print_session_detail "$pid" "Claude Code"
found=$((found + 1))
done <<<"$claude_pids"
fi

# --- Cursor sessions ---
local cursor_pids=""
cursor_pids=$(pgrep -f 'Cursor\.app' || true)

if [[ -n "$cursor_pids" ]]; then
local pid
while IFS= read -r pid; do
[[ -z "$pid" ]] && continue
_print_session_detail "$pid" "Cursor"
found=$((found + 1))
done <<<"$cursor_pids"
fi

# --- Windsurf sessions ---
local windsurf_pids=""
windsurf_pids=$(pgrep -f 'Windsurf' || true)

if [[ -n "$windsurf_pids" ]]; then
local pid
while IFS= read -r pid; do
[[ -z "$pid" ]] && continue
_print_session_detail "$pid" "Windsurf"
found=$((found + 1))
done <<<"$windsurf_pids"
fi

# --- Aider sessions ---
local aider_pids=""
aider_pids=$(pgrep -f 'aider' || true)

if [[ -n "$aider_pids" ]]; then
local pid
while IFS= read -r pid; do
[[ -z "$pid" ]] && continue
_print_session_detail "$pid" "Aider"
found=$((found + 1))
done <<<"$aider_pids"
fi

if [[ "$found" -eq 0 ]]; then
echo " No interactive AI sessions detected"
fi
Expand Down