- Fix shellcheck SC2155 (separate variable assignment from declaration) - Replace ! bool && bool pattern with [ "$bool" = true ] && [ "$bool2" = true ] - Add retry logic for git clone with configurable attempts - Add retry logic for opencode session fork - Add NETWORK_RETRY_ATTEMPTS and NETWORK_RETRY_DELAY_SECONDS config vars - Add retry_with_backoff helper function in kugetsu-config.sh - Replace subshell cd with git -C for safer directory handling
114 lines
3.4 KiB
Bash
Executable File
114 lines
3.4 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
KUGETSU_DIR="${KUGETSU_DIR:-$HOME/.kugetsu}"
|
|
SESSIONS_DIR="$KUGETSU_DIR/sessions"
|
|
WORKTREES_DIR="$KUGETSU_DIR/worktrees"
|
|
REPOS_CONFIG="$KUGETSU_DIR/repos.json"
|
|
INDEX_FILE="$KUGETSU_DIR/index.json"
|
|
NOTIFICATIONS_FILE="$KUGETSU_DIR/notifications.json"
|
|
LOGS_DIR="$KUGETSU_DIR/logs"
|
|
ENV_DIR="${ENV_DIR:-$KUGETSU_DIR/env}"
|
|
VERBOSITY_DIR="$KUGETSU_DIR/verbosity"
|
|
|
|
MAX_CONCURRENT_AGENTS="${MAX_CONCURRENT_AGENTS:-3}"
|
|
KUGETSU_VERBOSITY="${KUGETSU_VERBOSITY:-default}"
|
|
CONTEXT_DIR="${CONTEXT_DIR:-$KUGETSU_DIR/context}"
|
|
ENABLE_CONTEXT_DUMP="${ENABLE_CONTEXT_DUMP:-true}"
|
|
WORKTREE_CHECK_PR_STATUS="${WORKTREE_CHECK_PR_STATUS:-true}"
|
|
|
|
QUEUE_DIR="${QUEUE_DIR:-$KUGETSU_DIR/queue}"
|
|
QUEUE_ITEMS_DIR="${QUEUE_ITEMS_DIR:-$QUEUE_DIR/items}"
|
|
QUEUE_DAEMON_PID_FILE="${QUEUE_DAEMON_PID_FILE:-$QUEUE_DIR/daemon.pid}"
|
|
QUEUE_DAEMON_LOCK_FILE="${QUEUE_DAEMON_LOCK_FILE:-$QUEUE_DIR/daemon.lock}"
|
|
QUEUE_DAEMON_LOG_FILE="${QUEUE_DAEMON_LOG_FILE:-$QUEUE_DIR/daemon.log}"
|
|
QUEUE_DAEMON_INTERVAL_MINUTES="${QUEUE_DAEMON_INTERVAL_MINUTES:-5}"
|
|
QUEUE_CLEANUP_AGE_DAYS="${QUEUE_CLEANUP_AGE_DAYS:-7}"
|
|
TASK_TIMEOUT_HOURS="${TASK_TIMEOUT_HOURS:-1}"
|
|
|
|
NETWORK_RETRY_ATTEMPTS="${NETWORK_RETRY_ATTEMPTS:-3}"
|
|
NETWORK_RETRY_DELAY_SECONDS="${NETWORK_RETRY_DELAY_SECONDS:-5}"
|
|
|
|
# Load user config overrides (~/.kugetsu/config)
|
|
if [ -f "$KUGETSU_DIR/config" ]; then
|
|
source "$KUGETSU_DIR/config"
|
|
fi
|
|
|
|
mask_sensitive_vars() {
|
|
local line="${1:-}"
|
|
for var in GITEA_TOKEN GITHUB_TOKEN GITLAB_TOKEN API_KEY PASSWORD TOKEN SECRET; do
|
|
if [[ "$line" =~ $var ]]; then
|
|
line=$(echo "$line" | sed -E "s/=.*/=***MASKED***/")
|
|
fi
|
|
done
|
|
echo "$line"
|
|
}
|
|
|
|
strip_ansi_codes() {
|
|
local line="${1:-}"
|
|
echo "$line" | sed 's/\x1b\[[0-9;]*m//g' | sed 's/\x1b\[[0-9;]*[a-zA-Z]//g'
|
|
}
|
|
|
|
load_agent_env() {
|
|
local agent_type="${1:-base}"
|
|
local env_file="$ENV_DIR/${agent_type}.env"
|
|
|
|
if [ -f "$env_file" ]; then
|
|
set -a
|
|
source "$env_file"
|
|
set +a
|
|
elif [ -f "$ENV_DIR/default.env" ]; then
|
|
set -a
|
|
source "$ENV_DIR/default.env"
|
|
set +a
|
|
elif [ -f "$ENV_DIR/pm-agent.env" ]; then
|
|
set -a
|
|
source "$ENV_DIR/pm-agent.env"
|
|
set +a
|
|
fi
|
|
}
|
|
|
|
set_debug_mode() {
|
|
local filtered_args=()
|
|
local debug_mode=false
|
|
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--debug)
|
|
debug_mode=true
|
|
;;
|
|
*)
|
|
filtered_args+=("$arg")
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [ "$debug_mode" = true ]; then
|
|
export KUGETSU_VERBOSITY="debug"
|
|
echo "[DEBUG] Debug mode enabled" >&2
|
|
fi
|
|
|
|
echo "${filtered_args[@]}"
|
|
}
|
|
|
|
retry_with_backoff() {
|
|
local max_attempts="${1:-$NETWORK_RETRY_ATTEMPTS}"
|
|
local delay_seconds="${2:-$NETWORK_RETRY_DELAY_SECONDS}"
|
|
local command="$3"
|
|
local remaining_attempts=$max_attempts
|
|
|
|
while [ $remaining_attempts -gt 0 ]; do
|
|
if eval "$command"; then
|
|
return 0
|
|
fi
|
|
remaining_attempts=$((remaining_attempts - 1))
|
|
if [ $remaining_attempts -gt 0 ]; then
|
|
log "warn" "retry_with_backoff" "Command failed, $remaining_attempts retries remaining. Waiting ${delay_seconds}s..."
|
|
sleep "$delay_seconds"
|
|
delay_seconds=$((delay_seconds * 2))
|
|
fi
|
|
done
|
|
log "error" "retry_with_backoff" "Command failed after $max_attempts attempts"
|
|
return 1
|
|
}
|