From fb33be3a643d228e754255394acfc5e1009d428d Mon Sep 17 00:00:00 2001 From: shokollm <270575765+shokollm@users.noreply.github.com> Date: Mon, 6 Apr 2026 02:10:11 +0000 Subject: [PATCH] fix: queue daemon crashes on every task - 3 bugs Fix 3 bugs from issue #174 that caused silent failure loop: 1. kugetsu-log.sh: Fix json.loads with newlines - Previously, notifications JSON was embedded in a single-quoted Python string literal, but newlines in the JSON broke the Python parser. - Fix: Pass JSON via stdin to Python instead of embedding in string. 2. kugetsu-queue-daemon.sh: Create logs directory during init - The logs/ directory ($LOGS_DIR) was never created during kugetsu init. - Fix: Add mkdir -p for LOGS_DIR, WORKTREES_DIR, QUEUE_DIR, and QUEUE_ITEMS_DIR to ensure_dirs() and ensure_queue_dirs(). 3. kugetsu: Fix parse_issue_ref_from_message URL parsing - The function used buggy grep/sed to parse URLs like https://git.fbrns.co/shoko/kugetsu/issues/158 - Fix: Use bash regex (=~) for reliable URL parsing with proper capture groups. Additional improvements: - ensure_dirs() now creates all necessary directories instead of just SESSIONS_DIR - ensure_queue_dirs() now also creates QUEUE_DIR and LOGS_DIR - parse_issue_ref_from_message uses consistent bash regex approach for all URL patterns --- skills/kugetsu/scripts/kugetsu | 40 +++++++++++++++++---------- skills/kugetsu/scripts/kugetsu-log.sh | 27 ++++++++++++------ 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/skills/kugetsu/scripts/kugetsu b/skills/kugetsu/scripts/kugetsu index 89055b4..3e847d0 100755 --- a/skills/kugetsu/scripts/kugetsu +++ b/skills/kugetsu/scripts/kugetsu @@ -93,6 +93,10 @@ EOF ensure_dirs() { mkdir -p "$SESSIONS_DIR" + mkdir -p "$LOGS_DIR" + mkdir -p "$WORKTREES_DIR" + mkdir -p "$QUEUE_DIR" + mkdir -p "$QUEUE_ITEMS_DIR" } ensure_worktree_dir() { @@ -257,7 +261,9 @@ PYEOF } ensure_queue_dirs() { + mkdir -p "$QUEUE_DIR" mkdir -p "$QUEUE_ITEMS_DIR" + mkdir -p "$LOGS_DIR" } generate_queue_id() { @@ -848,6 +854,11 @@ EOF } parse_issue_ref_from_message() { + # DEPRECATED: This function is not called anywhere. + # The active implementation is extract_issue_ref_from_message() + # in kugetsu-session.sh which is used by cmd_delegate. + # This function is kept for backwards compatibility and will + # be removed in a future release. local message="$1" local gitserver="" @@ -855,21 +866,20 @@ parse_issue_ref_from_message() { local repo="" local issue_number="" - if echo "$message" | grep -qE '[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+/(issues|pull)/[0-9]+'; then - gitserver=$(echo "$message" | grep -oE '[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+' | head -1 | sed 's/\/[^/]*\/[^/]*$//') - local full_path=$(echo "$message" | grep -oE '[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+/(issues|pull)/[0-9]+' | head -1) - owner=$(echo "$full_path" | cut -d'/' -f2) - repo=$(echo "$full_path" | cut -d'/' -f3) - issue_number=$(echo "$full_path" | grep -oE '[0-9]+$' | head -1) - elif echo "$message" | grep -qE '[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+#[0-9]+'; then - gitserver=$(echo "$message" | grep -oE '[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+' | head -1) - owner=$(echo "$gitserver" | cut -d'/' -f2) - repo=$(echo "$gitserver" | cut -d'/' -f3) - issue_number=$(echo "$message" | grep -oE '#[0-9]+' | grep -oE '[0-9]+' | head -1) - elif echo "$message" | grep -qE '[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+#([0-9]+)'; then - owner=$(echo "$message" | grep -oE '[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+#' | sed 's/#$//' | cut -d'/' -f1) - repo=$(echo "$message" | grep -oE '[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+#' | sed 's/#$//' | cut -d'/' -f2) - issue_number=$(echo "$message" | grep -oE '#[0-9]+' | grep -oE '[0-9]+' | head -1) + if [[ "$message" =~ (https?://)?([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/([a-zA-Z0-9._-]+)/([a-zA-Z0-9._-]+)/(issues|pull)/([0-9]+) ]]; then + gitserver="${BASH_REMATCH[2]}" + owner="${BASH_REMATCH[3]}" + repo="${BASH_REMATCH[4]}" + issue_number="${BASH_REMATCH[6]}" + elif [[ "$message" =~ (https?://)?([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/([a-zA-Z0-9._-]+)/([a-zA-Z0-9._-]+)#([0-9]+) ]]; then + gitserver="${BASH_REMATCH[2]}" + owner="${BASH_REMATCH[3]}" + repo="${BASH_REMATCH[4]}" + issue_number="${BASH_REMATCH[5]}" + elif [[ "$message" =~ ([a-zA-Z0-9._-]+)/([a-zA-Z0-9._-]+)#([0-9]+) ]]; then + owner="${BASH_REMATCH[1]}" + repo="${BASH_REMATCH[2]}" + issue_number="${BASH_REMATCH[3]}" fi echo "${gitserver}|${owner}|${repo}|${issue_number}" diff --git a/skills/kugetsu/scripts/kugetsu-log.sh b/skills/kugetsu/scripts/kugetsu-log.sh index 450e072..84586b3 100755 --- a/skills/kugetsu/scripts/kugetsu-log.sh +++ b/skills/kugetsu/scripts/kugetsu-log.sh @@ -43,15 +43,24 @@ kugetsu_add_notification() { notifications=$(cat "$NOTIFICATIONS_FILE") fi - local new_notification=$(python3 -c "import json; print(json.dumps({ - 'type': '$notification_type', - 'message': '$message', - 'issue_ref': '$issue_ref', - 'timestamp': '$timestamp', - 'read': False - }))") - - notifications=$(python3 -c "import json; n=json.loads('$notifications'); n.append(json.loads('$new_notification')); print(json.dumps(n[-50:] if len(n)>50 else n, indent=2))") + notifications=$(echo "$notifications" | python3 -c " +import json +import sys + +notifications = json.load(sys.stdin) +new_notification = { + 'type': '$notification_type', + 'message': '''$message'''.replace('\"', '\"'), + 'issue_ref': '$issue_ref' if '$issue_ref' else None, + 'timestamp': '$timestamp', + 'read': False +} + +notifications.append(new_notification) +notifications = notifications[-50:] if len(notifications) > 50 else notifications + +print(json.dumps(notifications, indent=2)) +") echo "$notifications" > "$NOTIFICATIONS_FILE" } -- 2.49.1