From 7fa669b4c38efdba34183ccc21395cc17c717527 Mon Sep 17 00:00:00 2001 From: shokollm <270575765+shokollm@users.noreply.github.com> Date: Sun, 5 Apr 2026 20:57:51 +0000 Subject: [PATCH] fix(kugetsu): queue daemon runs PM agent in correct worktree with proper token - Load GITEA_TOKEN from ~/.kugetsu/env/default.env at daemon startup - Use --fork --session --dir instead of --continue to run in correct directory - Create worktree if it doesn't exist for the issue - Track forked session ID (not parent pm_session) for completion detection - Forked session ends when task completes, parent pm_session continues Fixes #156 --- .../kugetsu/scripts/kugetsu-queue-daemon.sh | 55 +++++++++++++++++-- 1 file changed, 49 insertions(+), 6 deletions(-) mode change 100755 => 100644 skills/kugetsu/scripts/kugetsu-queue-daemon.sh diff --git a/skills/kugetsu/scripts/kugetsu-queue-daemon.sh b/skills/kugetsu/scripts/kugetsu-queue-daemon.sh old mode 100755 new mode 100644 index d1d1e9f..77fd413 --- a/skills/kugetsu/scripts/kugetsu-queue-daemon.sh +++ b/skills/kugetsu/scripts/kugetsu-queue-daemon.sh @@ -8,7 +8,12 @@ source "$SCRIPT_DIR/kugetsu-index.sh" source "$SCRIPT_DIR/kugetsu-worktree.sh" source "$SCRIPT_DIR/kugetsu-log.sh" -# Check if a notified task has completed (session ended or has new commits) +# Load GITEA_TOKEN from default.env +if [ -f "$HOME/.kugetsu/env/default.env" ]; then + source "$HOME/.kugetsu/env/default.env" +fi + +# Check if a notified task has completed (forked session ended or has new commits) check_task_completion() { local item="$1" local queue_id=$(basename "$item" .json) @@ -16,15 +21,16 @@ check_task_completion() { [ "$state" = "notified" ] || return 0 - local session_id=$(python3 -c "import json; print(json.load(open('$item')).get('session_id', ''))" 2>/dev/null) + # Use opencode_session_id (the forked session, not the parent pm_session) + local session_id=$(python3 -c "import json; print(json.load(open('$item')).get('opencode_session_id', ''))" 2>/dev/null) local issue_ref=$(python3 -c "import json; print(json.load(open('$item')).get('issue_ref', ''))" 2>/dev/null) # If no session tracked, skip [ -n "$session_id" ] || return 0 - # Check if session still exists in opencode + # Check if forked session still exists in opencode if ! opencode session list 2>/dev/null | grep -q "$session_id"; then - # Session ended — check if work was done + # Forked session ended — check if work was done local worktree_path=$(issue_ref_to_worktree_path "$issue_ref" "$HOME/.kugetsu-worktrees") local has_commits=false @@ -64,10 +70,47 @@ while true; do pm_session=$(get_pm_agent_session_id) if [ -n "$pm_session" ] && [ "$pm_session" != "null" ]; then + # Compute worktree path for this issue + worktree_path=$(issue_ref_to_worktree_path "$issue_ref" "$HOME/.kugetsu-worktrees") + + # Ensure worktree exists, create if needed + if [ ! -d "$worktree_path" ]; then + echo "Creating worktree for $issue_ref at $worktree_path..." + create_worktree "$issue_ref" "$HOME/.kugetsu-worktrees" + fi + + # Capture sessions before fork to identify the new forked session + sessions_before=$(opencode session list 2>/dev/null || echo "") + log_file="$LOGS_DIR/delegate-$(date +%s).log" - nohup env GITEA_TOKEN="$GITEA_TOKEN" sh -c "opencode run '$message' --continue --session '$pm_session' >> '$log_file' 2>&1" > /dev/null 2>&1 & + # Use --fork --dir to run in the correct worktree directory + # The forked session will end when the task completes, while parent pm_session continues + (cd "$worktree_path" && nohup bash -c "export GITEA_TOKEN=$GITEA_TOKEN; opencode run '$message' --fork --session '$pm_session' --dir '$worktree_path'" >> "$log_file" 2>&1) & pid=$! - update_queue_item_state "$queue_id" "notified" "$pm_session" "$pid" + + # Wait for fork to initialize and capture new session + sleep 3 + + # Find the forked session ID by comparing session lists + sessions_after=$(opencode session list 2>/dev/null || echo "") + forked_session="" + while IFS= read -r line; do + session=$(echo "$line" | awk '{print $1}' | tr -d '[:space:]') + if [ -n "$session" ] && ! echo "$sessions_before" | grep -q "$session"; then + forked_session="$session" + break + fi + done <<< "$sessions_after" + + # Store the forked session ID (not the parent pm_session) for completion detection + if [ -n "$forked_session" ]; then + update_queue_item_state "$queue_id" "notified" "$forked_session" "$pid" + echo "Task $queue_id notified with forked session $forked_session for $issue_ref" + else + # Fallback: still update with empty session so task isn't stuck + update_queue_item_state "$queue_id" "notified" "" "$pid" + echo "Task $queue_id notified but could not capture forked session for $issue_ref" + fi fi fi done