Compare commits

..

2 Commits

Author SHA1 Message Date
shokollm
fb33be3a64 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
     #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
2026-04-06 02:14:27 +00:00
shokollm
85a4239383 fix: init script captures wrong session IDs when old sessions exist
The init script used 'tail -1' to find newly created sessions, which
fails when old sessions exist because it picks an existing session
instead of the newly created one.

The fix captures session IDs before and after creating new sessions,
then diffs to identify newly created sessions.

Fixes #172
2026-04-06 01:08:09 +00:00
3 changed files with 67 additions and 26 deletions

View File

@@ -93,6 +93,10 @@ EOF
ensure_dirs() { ensure_dirs() {
mkdir -p "$SESSIONS_DIR" mkdir -p "$SESSIONS_DIR"
mkdir -p "$LOGS_DIR"
mkdir -p "$WORKTREES_DIR"
mkdir -p "$QUEUE_DIR"
mkdir -p "$QUEUE_ITEMS_DIR"
} }
ensure_worktree_dir() { ensure_worktree_dir() {
@@ -257,7 +261,9 @@ PYEOF
} }
ensure_queue_dirs() { ensure_queue_dirs() {
mkdir -p "$QUEUE_DIR"
mkdir -p "$QUEUE_ITEMS_DIR" mkdir -p "$QUEUE_ITEMS_DIR"
mkdir -p "$LOGS_DIR"
} }
generate_queue_id() { generate_queue_id() {
@@ -848,6 +854,11 @@ EOF
} }
parse_issue_ref_from_message() { 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 message="$1"
local gitserver="" local gitserver=""
@@ -855,21 +866,20 @@ parse_issue_ref_from_message() {
local repo="" local repo=""
local issue_number="" 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 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=$(echo "$message" | grep -oE '[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+' | head -1 | sed 's/\/[^/]*\/[^/]*$//') gitserver="${BASH_REMATCH[2]}"
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="${BASH_REMATCH[3]}"
owner=$(echo "$full_path" | cut -d'/' -f2) repo="${BASH_REMATCH[4]}"
repo=$(echo "$full_path" | cut -d'/' -f3) issue_number="${BASH_REMATCH[6]}"
issue_number=$(echo "$full_path" | grep -oE '[0-9]+$' | head -1) elif [[ "$message" =~ (https?://)?([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/([a-zA-Z0-9._-]+)/([a-zA-Z0-9._-]+)#([0-9]+) ]]; then
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="${BASH_REMATCH[2]}"
gitserver=$(echo "$message" | grep -oE '[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+' | head -1) owner="${BASH_REMATCH[3]}"
owner=$(echo "$gitserver" | cut -d'/' -f2) repo="${BASH_REMATCH[4]}"
repo=$(echo "$gitserver" | cut -d'/' -f3) issue_number="${BASH_REMATCH[5]}"
issue_number=$(echo "$message" | grep -oE '#[0-9]+' | grep -oE '[0-9]+' | head -1) elif [[ "$message" =~ ([a-zA-Z0-9._-]+)/([a-zA-Z0-9._-]+)#([0-9]+) ]]; then
elif echo "$message" | grep -qE '[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+#([0-9]+)'; then owner="${BASH_REMATCH[1]}"
owner=$(echo "$message" | grep -oE '[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+#' | sed 's/#$//' | cut -d'/' -f1) repo="${BASH_REMATCH[2]}"
repo=$(echo "$message" | grep -oE '[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+#' | sed 's/#$//' | cut -d'/' -f2) issue_number="${BASH_REMATCH[3]}"
issue_number=$(echo "$message" | grep -oE '#[0-9]+' | grep -oE '[0-9]+' | head -1)
fi fi
echo "${gitserver}|${owner}|${repo}|${issue_number}" echo "${gitserver}|${owner}|${repo}|${issue_number}"

View File

@@ -43,15 +43,24 @@ kugetsu_add_notification() {
notifications=$(cat "$NOTIFICATIONS_FILE") notifications=$(cat "$NOTIFICATIONS_FILE")
fi fi
local new_notification=$(python3 -c "import json; print(json.dumps({ notifications=$(echo "$notifications" | python3 -c "
'type': '$notification_type', import json
'message': '$message', import sys
'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 = 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" echo "$notifications" > "$NOTIFICATIONS_FILE"
} }

View File

@@ -81,9 +81,20 @@ EOF
echo "Press Ctrl+C to cancel or wait for session to be created" echo "Press Ctrl+C to cancel or wait for session to be created"
sleep 2 sleep 2
local before_sessions=$(opencode session list 2>/dev/null | grep -E '^ses_' | awk '{print $1}' || true)
opencode opencode
local session_ids=$(opencode session list 2>/dev/null | grep -E '^ses_' | awk '{print $1}' | tail -1) local after_sessions=$(opencode session list 2>/dev/null | grep -E '^ses_' | awk '{print $1}' || true)
local session_ids=""
while IFS= read -r line; do
local sid=$(echo "$line" | awk '{print $1}')
if [ -n "$sid" ] && ! echo "$before_sessions" | grep -q "^${sid}$"; then
session_ids="$sid"
break
fi
done <<< "$after_sessions"
if [ -z "$session_ids" ]; then if [ -z "$session_ids" ]; then
echo "Error: Could not find newly created session" >&2 echo "Error: Could not find newly created session" >&2
exit 1 exit 1
@@ -95,9 +106,20 @@ EOF
echo "Base session created: $session_ids" echo "Base session created: $session_ids"
echo "Starting PM agent..." echo "Starting PM agent..."
before_sessions="$after_sessions"
opencode opencode
local pm_session_ids=$(opencode session list 2>/dev/null | grep -E '^ses_' | grep -v "$session_ids" | tail -1) after_sessions=$(opencode session list 2>/dev/null | grep -E '^ses_' | awk '{print $1}' || true)
local pm_session_ids=""
while IFS= read -r line; do
local sid=$(echo "$line" | awk '{print $1}')
if [ -n "$sid" ] && ! echo "$before_sessions" | grep -q "^${sid}$"; then
pm_session_ids="$sid"
break
fi
done <<< "$after_sessions"
if [ -z "$pm_session_ids" ]; then if [ -z "$pm_session_ids" ]; then
echo "Warning: Could not find separate PM agent session" >&2 echo "Warning: Could not find separate PM agent session" >&2
pm_session_ids="$session_ids" pm_session_ids="$session_ids"