refactor: extract lib/agent-session.sh — reusable tmux + Claude agent runtime (#158)
Move generic agent infrastructure from dev/dev-agent.sh into lib/agent-session.sh:
- log, status, notify, notify_ctx, read_phase, wait_for_claude_ready,
inject_into_session, kill_tmux_session extracted verbatim
- create_agent_session(session_name, workdir) — new: tmux session creation
- inject_formula(session_name, formula_text, context) — new: prompt injection
- monitor_phase_loop(phase_file, idle_timeout, callback_fn) — new: phase loop
with session health check, crash recovery, and idle timeout detection
dev-agent.sh: sources the library, implements _on_phase_change() callback,
calls monitor_phase_loop(); idle-timeout and crash-recovery-failed cleanup
handled via _MONITOR_LOOP_EXIT signal variable. Behavior unchanged.
2026-03-18 14:36:36 +00:00
|
|
|
|
#!/usr/bin/env bash
|
2026-03-18 16:21:07 +01:00
|
|
|
|
# agent-session.sh — Shared tmux + Claude interactive session helpers
|
refactor: extract lib/agent-session.sh — reusable tmux + Claude agent runtime (#158)
Move generic agent infrastructure from dev/dev-agent.sh into lib/agent-session.sh:
- log, status, notify, notify_ctx, read_phase, wait_for_claude_ready,
inject_into_session, kill_tmux_session extracted verbatim
- create_agent_session(session_name, workdir) — new: tmux session creation
- inject_formula(session_name, formula_text, context) — new: prompt injection
- monitor_phase_loop(phase_file, idle_timeout, callback_fn) — new: phase loop
with session health check, crash recovery, and idle timeout detection
dev-agent.sh: sources the library, implements _on_phase_change() callback,
calls monitor_phase_loop(); idle-timeout and crash-recovery-failed cleanup
handled via _MONITOR_LOOP_EXIT signal variable. Behavior unchanged.
2026-03-18 14:36:36 +00:00
|
|
|
|
#
|
2026-03-18 16:21:07 +01:00
|
|
|
|
# Source this into agent orchestrator scripts for reusable session management.
|
refactor: extract lib/agent-session.sh — reusable tmux + Claude agent runtime (#158)
Move generic agent infrastructure from dev/dev-agent.sh into lib/agent-session.sh:
- log, status, notify, notify_ctx, read_phase, wait_for_claude_ready,
inject_into_session, kill_tmux_session extracted verbatim
- create_agent_session(session_name, workdir) — new: tmux session creation
- inject_formula(session_name, formula_text, context) — new: prompt injection
- monitor_phase_loop(phase_file, idle_timeout, callback_fn) — new: phase loop
with session health check, crash recovery, and idle timeout detection
dev-agent.sh: sources the library, implements _on_phase_change() callback,
calls monitor_phase_loop(); idle-timeout and crash-recovery-failed cleanup
handled via _MONITOR_LOOP_EXIT signal variable. Behavior unchanged.
2026-03-18 14:36:36 +00:00
|
|
|
|
#
|
2026-03-18 16:21:07 +01:00
|
|
|
|
# Functions:
|
|
|
|
|
|
# agent_wait_for_claude_ready SESSION_NAME [TIMEOUT_SECS]
|
|
|
|
|
|
# agent_inject_into_session SESSION_NAME TEXT
|
|
|
|
|
|
# agent_kill_session SESSION_NAME
|
refactor: extract lib/agent-session.sh — reusable tmux + Claude agent runtime (#158)
Move generic agent infrastructure from dev/dev-agent.sh into lib/agent-session.sh:
- log, status, notify, notify_ctx, read_phase, wait_for_claude_ready,
inject_into_session, kill_tmux_session extracted verbatim
- create_agent_session(session_name, workdir) — new: tmux session creation
- inject_formula(session_name, formula_text, context) — new: prompt injection
- monitor_phase_loop(phase_file, idle_timeout, callback_fn) — new: phase loop
with session health check, crash recovery, and idle timeout detection
dev-agent.sh: sources the library, implements _on_phase_change() callback,
calls monitor_phase_loop(); idle-timeout and crash-recovery-failed cleanup
handled via _MONITOR_LOOP_EXIT signal variable. Behavior unchanged.
2026-03-18 14:36:36 +00:00
|
|
|
|
|
2026-03-18 16:21:07 +01:00
|
|
|
|
# Wait for the Claude ❯ ready prompt in a tmux pane.
|
|
|
|
|
|
# Returns 0 if ready within TIMEOUT_SECS (default 120), 1 otherwise.
|
|
|
|
|
|
agent_wait_for_claude_ready() {
|
|
|
|
|
|
local session="$1"
|
|
|
|
|
|
local timeout="${2:-120}"
|
refactor: extract lib/agent-session.sh — reusable tmux + Claude agent runtime (#158)
Move generic agent infrastructure from dev/dev-agent.sh into lib/agent-session.sh:
- log, status, notify, notify_ctx, read_phase, wait_for_claude_ready,
inject_into_session, kill_tmux_session extracted verbatim
- create_agent_session(session_name, workdir) — new: tmux session creation
- inject_formula(session_name, formula_text, context) — new: prompt injection
- monitor_phase_loop(phase_file, idle_timeout, callback_fn) — new: phase loop
with session health check, crash recovery, and idle timeout detection
dev-agent.sh: sources the library, implements _on_phase_change() callback,
calls monitor_phase_loop(); idle-timeout and crash-recovery-failed cleanup
handled via _MONITOR_LOOP_EXIT signal variable. Behavior unchanged.
2026-03-18 14:36:36 +00:00
|
|
|
|
local elapsed=0
|
|
|
|
|
|
while [ "$elapsed" -lt "$timeout" ]; do
|
2026-03-18 16:21:07 +01:00
|
|
|
|
if tmux capture-pane -t "$session" -p 2>/dev/null | grep -q '❯'; then
|
refactor: extract lib/agent-session.sh — reusable tmux + Claude agent runtime (#158)
Move generic agent infrastructure from dev/dev-agent.sh into lib/agent-session.sh:
- log, status, notify, notify_ctx, read_phase, wait_for_claude_ready,
inject_into_session, kill_tmux_session extracted verbatim
- create_agent_session(session_name, workdir) — new: tmux session creation
- inject_formula(session_name, formula_text, context) — new: prompt injection
- monitor_phase_loop(phase_file, idle_timeout, callback_fn) — new: phase loop
with session health check, crash recovery, and idle timeout detection
dev-agent.sh: sources the library, implements _on_phase_change() callback,
calls monitor_phase_loop(); idle-timeout and crash-recovery-failed cleanup
handled via _MONITOR_LOOP_EXIT signal variable. Behavior unchanged.
2026-03-18 14:36:36 +00:00
|
|
|
|
return 0
|
|
|
|
|
|
fi
|
|
|
|
|
|
sleep 2
|
|
|
|
|
|
elapsed=$((elapsed + 2))
|
|
|
|
|
|
done
|
|
|
|
|
|
return 1
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-18 16:21:07 +01:00
|
|
|
|
# Paste TEXT into SESSION (waits for Claude to be ready first), then press Enter.
|
|
|
|
|
|
agent_inject_into_session() {
|
|
|
|
|
|
local session="$1"
|
|
|
|
|
|
local text="$2"
|
refactor: extract lib/agent-session.sh — reusable tmux + Claude agent runtime (#158)
Move generic agent infrastructure from dev/dev-agent.sh into lib/agent-session.sh:
- log, status, notify, notify_ctx, read_phase, wait_for_claude_ready,
inject_into_session, kill_tmux_session extracted verbatim
- create_agent_session(session_name, workdir) — new: tmux session creation
- inject_formula(session_name, formula_text, context) — new: prompt injection
- monitor_phase_loop(phase_file, idle_timeout, callback_fn) — new: phase loop
with session health check, crash recovery, and idle timeout detection
dev-agent.sh: sources the library, implements _on_phase_change() callback,
calls monitor_phase_loop(); idle-timeout and crash-recovery-failed cleanup
handled via _MONITOR_LOOP_EXIT signal variable. Behavior unchanged.
2026-03-18 14:36:36 +00:00
|
|
|
|
local tmpfile
|
2026-03-18 16:21:07 +01:00
|
|
|
|
agent_wait_for_claude_ready "$session" 120 || true
|
|
|
|
|
|
tmpfile=$(mktemp /tmp/agent-inject-XXXXXX)
|
refactor: extract lib/agent-session.sh — reusable tmux + Claude agent runtime (#158)
Move generic agent infrastructure from dev/dev-agent.sh into lib/agent-session.sh:
- log, status, notify, notify_ctx, read_phase, wait_for_claude_ready,
inject_into_session, kill_tmux_session extracted verbatim
- create_agent_session(session_name, workdir) — new: tmux session creation
- inject_formula(session_name, formula_text, context) — new: prompt injection
- monitor_phase_loop(phase_file, idle_timeout, callback_fn) — new: phase loop
with session health check, crash recovery, and idle timeout detection
dev-agent.sh: sources the library, implements _on_phase_change() callback,
calls monitor_phase_loop(); idle-timeout and crash-recovery-failed cleanup
handled via _MONITOR_LOOP_EXIT signal variable. Behavior unchanged.
2026-03-18 14:36:36 +00:00
|
|
|
|
printf '%s' "$text" > "$tmpfile"
|
2026-03-18 16:21:07 +01:00
|
|
|
|
tmux load-buffer -b "agent-inject-$$" "$tmpfile"
|
|
|
|
|
|
tmux paste-buffer -t "$session" -b "agent-inject-$$"
|
refactor: extract lib/agent-session.sh — reusable tmux + Claude agent runtime (#158)
Move generic agent infrastructure from dev/dev-agent.sh into lib/agent-session.sh:
- log, status, notify, notify_ctx, read_phase, wait_for_claude_ready,
inject_into_session, kill_tmux_session extracted verbatim
- create_agent_session(session_name, workdir) — new: tmux session creation
- inject_formula(session_name, formula_text, context) — new: prompt injection
- monitor_phase_loop(phase_file, idle_timeout, callback_fn) — new: phase loop
with session health check, crash recovery, and idle timeout detection
dev-agent.sh: sources the library, implements _on_phase_change() callback,
calls monitor_phase_loop(); idle-timeout and crash-recovery-failed cleanup
handled via _MONITOR_LOOP_EXIT signal variable. Behavior unchanged.
2026-03-18 14:36:36 +00:00
|
|
|
|
sleep 0.5
|
2026-03-18 16:21:07 +01:00
|
|
|
|
tmux send-keys -t "$session" "" Enter
|
|
|
|
|
|
tmux delete-buffer -b "agent-inject-$$" 2>/dev/null || true
|
refactor: extract lib/agent-session.sh — reusable tmux + Claude agent runtime (#158)
Move generic agent infrastructure from dev/dev-agent.sh into lib/agent-session.sh:
- log, status, notify, notify_ctx, read_phase, wait_for_claude_ready,
inject_into_session, kill_tmux_session extracted verbatim
- create_agent_session(session_name, workdir) — new: tmux session creation
- inject_formula(session_name, formula_text, context) — new: prompt injection
- monitor_phase_loop(phase_file, idle_timeout, callback_fn) — new: phase loop
with session health check, crash recovery, and idle timeout detection
dev-agent.sh: sources the library, implements _on_phase_change() callback,
calls monitor_phase_loop(); idle-timeout and crash-recovery-failed cleanup
handled via _MONITOR_LOOP_EXIT signal variable. Behavior unchanged.
2026-03-18 14:36:36 +00:00
|
|
|
|
rm -f "$tmpfile"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-18 16:21:07 +01:00
|
|
|
|
# Kill a tmux session gracefully (no-op if not found).
|
|
|
|
|
|
agent_kill_session() {
|
|
|
|
|
|
tmux kill-session -t "$1" 2>/dev/null || true
|
refactor: extract lib/agent-session.sh — reusable tmux + Claude agent runtime (#158)
Move generic agent infrastructure from dev/dev-agent.sh into lib/agent-session.sh:
- log, status, notify, notify_ctx, read_phase, wait_for_claude_ready,
inject_into_session, kill_tmux_session extracted verbatim
- create_agent_session(session_name, workdir) — new: tmux session creation
- inject_formula(session_name, formula_text, context) — new: prompt injection
- monitor_phase_loop(phase_file, idle_timeout, callback_fn) — new: phase loop
with session health check, crash recovery, and idle timeout detection
dev-agent.sh: sources the library, implements _on_phase_change() callback,
calls monitor_phase_loop(); idle-timeout and crash-recovery-failed cleanup
handled via _MONITOR_LOOP_EXIT signal variable. Behavior unchanged.
2026-03-18 14:36:36 +00:00
|
|
|
|
}
|