242 lines
9.9 KiB
Bash
Executable File
242 lines
9.9 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Orchestra Progress Tracker - Enhanced Display
|
|
# Version: 2.0.0
|
|
# Shows rich formatted progress in chat after TodoWrite updates
|
|
|
|
set +e
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="${PROJECT_ROOT:-$(cd "$SCRIPT_DIR/.." && pwd)}"
|
|
PROGRESS_FILE="$PROJECT_ROOT/.orchestra/cache/progress.json"
|
|
|
|
# Source utility library
|
|
if [ -f "$SCRIPT_DIR/lib/progress-utils.sh" ]; then
|
|
source "$SCRIPT_DIR/lib/progress-utils.sh"
|
|
else
|
|
echo "Warning: progress-utils.sh not found, using basic display" >&2
|
|
fi
|
|
|
|
# Check if progress file exists
|
|
if [ ! -f "$PROGRESS_FILE" ]; then
|
|
# No progress to display
|
|
exit 0
|
|
fi
|
|
|
|
# Check if jq is available
|
|
if ! command -v jq &> /dev/null; then
|
|
echo "Warning: jq not found, cannot display progress" >&2
|
|
exit 0
|
|
fi
|
|
|
|
# Get metadata
|
|
get_metadata() {
|
|
local field="$1"
|
|
jq -r ".metadata.$field // 0" "$PROGRESS_FILE" 2>/dev/null || echo "0"
|
|
}
|
|
|
|
# Display compact progress view
|
|
display_compact() {
|
|
local total=$(get_metadata "totalTasks")
|
|
local completed=$(get_metadata "completedTasks")
|
|
local in_progress=$(get_metadata "inProgressTasks")
|
|
local pending=$(get_metadata "pendingTasks")
|
|
local completion_rate=$(get_metadata "completionRate")
|
|
local active_agents_count=$(jq -r '.metadata.activeAgents | length' "$PROGRESS_FILE" 2>/dev/null || echo "0")
|
|
|
|
# Skip display if no tasks
|
|
if [ "$total" -eq 0 ]; then
|
|
return 0
|
|
fi
|
|
|
|
echo ""
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo -e "🎯 ${COLOR_BOLD}PROGRESS${COLOR_RESET} | ${active_agents_count} agent(s) | ${completion_rate}% complete"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo ""
|
|
|
|
# Display active (in-progress) tasks with agent info
|
|
if [ "$in_progress" -gt 0 ]; then
|
|
jq -r '.todos[] | select(.status == "in_progress") | @json' "$PROGRESS_FILE" 2>/dev/null | while IFS= read -r task_json; do
|
|
local agent=$(echo "$task_json" | jq -r '.agent // "Unknown"')
|
|
local content=$(echo "$task_json" | jq -r '.content')
|
|
local active_form=$(echo "$task_json" | jq -r '.activeForm')
|
|
local start_time=$(echo "$task_json" | jq -r '.startTime // 0')
|
|
local current_step=$(echo "$task_json" | jq -r '.currentStep // null')
|
|
local total_steps=$(echo "$task_json" | jq -r '.totalSteps // null')
|
|
|
|
# Calculate elapsed time
|
|
local current_time=$(get_timestamp_ms)
|
|
local elapsed=$((current_time - start_time))
|
|
local duration=$(format_duration "$elapsed")
|
|
|
|
# Get agent emoji
|
|
local emoji=$(get_agent_emoji "$agent")
|
|
|
|
# Calculate progress percentage
|
|
local progress_pct=0
|
|
if [ "$current_step" != "null" ] && [ "$total_steps" != "null" ] && [ "$total_steps" -gt 0 ]; then
|
|
progress_pct=$((current_step * 100 / total_steps))
|
|
else
|
|
# Default to 50% if no step info
|
|
progress_pct=50
|
|
fi
|
|
|
|
# Format progress bar
|
|
local progress_bar=$(format_progress_bar "$progress_pct")
|
|
|
|
# Truncate content if too long
|
|
local display_content="$content"
|
|
if [ ${#display_content} -gt 50 ]; then
|
|
display_content="${display_content:0:47}..."
|
|
fi
|
|
|
|
# Display task line
|
|
echo -e "${COLOR_YELLOW}${emoji} ${agent}${COLOR_RESET} ${progress_bar} ${progress_pct}% ${display_content} (${duration})"
|
|
done
|
|
echo ""
|
|
fi
|
|
|
|
# Display summary line
|
|
echo -e "${COLOR_GREEN}$SYMBOL_COMPLETED ${completed}${COLOR_RESET} ${COLOR_YELLOW}$SYMBOL_IN_PROGRESS ${in_progress}${COLOR_RESET} ${COLOR_GRAY}$SYMBOL_PENDING ${pending}${COLOR_RESET}"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo ""
|
|
}
|
|
|
|
# Display detailed progress view (verbose mode)
|
|
display_detailed() {
|
|
local total=$(get_metadata "totalTasks")
|
|
local completed=$(get_metadata "completedTasks")
|
|
local in_progress=$(get_metadata "inProgressTasks")
|
|
local pending=$(get_metadata "pendingTasks")
|
|
local completion_rate=$(get_metadata "completionRate")
|
|
local session_start=$(get_metadata "sessionStartTime")
|
|
|
|
# Skip display if no tasks
|
|
if [ "$total" -eq 0 ]; then
|
|
echo "No tasks tracked yet."
|
|
return 0
|
|
fi
|
|
|
|
# Calculate session duration
|
|
local current_time=$(get_timestamp_ms)
|
|
local session_duration=$((current_time - session_start))
|
|
local session_duration_str=$(format_duration "$session_duration")
|
|
|
|
echo ""
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo -e "${COLOR_BOLD}🎯 ORCHESTRA PROGRESS TRACKER${COLOR_RESET}"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo ""
|
|
echo "Session: $session_duration_str | Overall: $(format_progress_bar "$completion_rate" 20) $completion_rate% ($completed/$total tasks)"
|
|
echo ""
|
|
|
|
# Active agents section
|
|
local active_agents=$(jq -r '.metadata.activeAgents[]' "$PROGRESS_FILE" 2>/dev/null)
|
|
if [ -n "$active_agents" ]; then
|
|
local agent_count=$(echo "$active_agents" | wc -l | tr -d ' ')
|
|
echo -e "${COLOR_BOLD}👥 Active Agents ($agent_count)${COLOR_RESET}"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo ""
|
|
|
|
# Display each active agent's tasks
|
|
echo "$active_agents" | while IFS= read -r agent; do
|
|
local emoji=$(get_agent_emoji "$agent")
|
|
|
|
# Get in-progress tasks for this agent
|
|
jq -r --arg agent "$agent" '.todos[] | select(.status == "in_progress" and .agent == $agent) | @json' "$PROGRESS_FILE" 2>/dev/null | while IFS= read -r task_json; do
|
|
local content=$(echo "$task_json" | jq -r '.content')
|
|
local start_time=$(echo "$task_json" | jq -r '.startTime // 0')
|
|
local current_step=$(echo "$task_json" | jq -r '.currentStep // null')
|
|
local total_steps=$(echo "$task_json" | jq -r '.totalSteps // null')
|
|
local tags=$(echo "$task_json" | jq -r '.tags // [] | join(", ")')
|
|
|
|
# Calculate elapsed time
|
|
local current_time=$(get_timestamp_ms)
|
|
local elapsed=$((current_time - start_time))
|
|
local duration=$(format_duration "$elapsed")
|
|
|
|
# Calculate progress
|
|
local progress_pct=0
|
|
local step_info=""
|
|
if [ "$current_step" != "null" ] && [ "$total_steps" != "null" ] && [ "$total_steps" -gt 0 ]; then
|
|
progress_pct=$((current_step * 100 / total_steps))
|
|
step_info=" (Step $current_step/$total_steps)"
|
|
fi
|
|
|
|
local progress_bar=$(format_progress_bar "$progress_pct")
|
|
|
|
echo -e "${COLOR_YELLOW}${emoji} ${agent}${COLOR_RESET}"
|
|
echo " Task: $content"
|
|
echo " Progress: ${progress_bar} ${progress_pct}%${step_info}"
|
|
echo " Duration: ${duration}"
|
|
if [ -n "$tags" ]; then
|
|
echo " Tags: $tags"
|
|
fi
|
|
echo ""
|
|
done
|
|
done
|
|
fi
|
|
|
|
# Task summary section
|
|
echo -e "${COLOR_BOLD}📋 Task Summary${COLOR_RESET}"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo ""
|
|
|
|
# Completed tasks
|
|
if [ "$completed" -gt 0 ]; then
|
|
echo -e "${COLOR_GREEN}$SYMBOL_COMPLETED Completed ($completed tasks)${COLOR_RESET}"
|
|
jq -r '.todos[] | select(.status == "completed") | " - " + .content' "$PROGRESS_FILE" 2>/dev/null | head -5
|
|
if [ "$completed" -gt 5 ]; then
|
|
echo " ... and $((completed - 5)) more"
|
|
fi
|
|
echo ""
|
|
fi
|
|
|
|
# In-progress tasks
|
|
if [ "$in_progress" -gt 0 ]; then
|
|
echo -e "${COLOR_YELLOW}$SYMBOL_IN_PROGRESS In Progress ($in_progress tasks)${COLOR_RESET}"
|
|
jq -r '.todos[] | select(.status == "in_progress") | " - " + .content' "$PROGRESS_FILE" 2>/dev/null
|
|
echo ""
|
|
fi
|
|
|
|
# Pending tasks
|
|
if [ "$pending" -gt 0 ]; then
|
|
echo -e "${COLOR_GRAY}$SYMBOL_PENDING Pending ($pending tasks)${COLOR_RESET}"
|
|
jq -r '.todos[] | select(.status == "pending") | " - " + .content' "$PROGRESS_FILE" 2>/dev/null | head -5
|
|
if [ "$pending" -gt 5 ]; then
|
|
echo " ... and $((pending - 5)) more"
|
|
fi
|
|
echo ""
|
|
fi
|
|
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo ""
|
|
}
|
|
|
|
# Main execution
|
|
main() {
|
|
# Check for verbose flag
|
|
local verbose=false
|
|
if [ "$1" = "--verbose" ] || [ "$1" = "-v" ]; then
|
|
verbose=true
|
|
fi
|
|
|
|
# Check ORCHESTRA_PROGRESS_VERBOSE environment variable
|
|
if [ "${ORCHESTRA_PROGRESS_VERBOSE:-0}" = "1" ]; then
|
|
verbose=true
|
|
fi
|
|
|
|
# Display appropriate view
|
|
if [ "$verbose" = true ]; then
|
|
display_detailed
|
|
else
|
|
display_compact
|
|
fi
|
|
}
|
|
|
|
# Run main function
|
|
main "$@"
|
|
|
|
exit 0
|