Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 09:03:11 +08:00
commit 4aff69d9a9
61 changed files with 7343 additions and 0 deletions

241
hooks/progress-tracker-display.sh Executable file
View File

@@ -0,0 +1,241 @@
#!/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