Compare commits

..

1 Commits

Author SHA1 Message Date
shokollm
1fbb96bd8d refactor(session): make cmd_continue idempotent with ensure_* functions
- Add ensure_worktree() - creates worktree if missing, returns status
- Add ensure_session() - creates session if missing, handles inconsistent states
- Add fork_agent() - extracted agent forking logic
- Refactor cmd_continue() to use ensure_* functions (idempotent)
- Make cmd_start() a thin wrapper calling cmd_continue()
- Simplify daemon to always call cmd_continue (no existence check)

This makes cmd_continue truly idempotent - it will:
- Continue existing session if it exists
- Create session and worktree if they don't exist
- Clean and recreate if state is inconsistent

Closes #168
2026-04-07 14:30:00 +00:00
2 changed files with 22 additions and 31 deletions

1
.gitignore vendored
View File

@@ -4,4 +4,3 @@ results/
*/results/ */results/
*.pyc *.pyc
.kugetsu/

View File

@@ -272,39 +272,29 @@ build_dev_agent_message() {
if [ -n "$user_message" ]; then if [ -n "$user_message" ]; then
cat <<EOF cat <<EOF
You are assigned to work on $issue_ref. You are continuing work on $issue_ref. A PR likely already exists.
IMPORTANT: Follow the workflow below as your guideline, but prioritize the delegator's message. IMPORTANT - Review workflow:
1. First, check if PR exists: curl -s "https://$instance/api/v1/repos/$owner/$repo/pulls?state=open" -H "Authorization: Bearer \$GITEA_TOKEN" | grep -i "$number"
2. Get PR comments: curl -s "https://$instance/api/v1/repos/$owner/$repo/issues/$number/comments" -H "Authorization: Bearer \$GITEA_TOKEN"
3. Get PR reviews: curl -s "https://$instance/api/v1/repos/$owner/$repo/pulls/$number/reviews" -H "Authorization: Bearer \$GITEA_TOKEN"
Workflow: You may need to:
1. Read the issue at $instance/$owner/$repo/issues/$number AND all comments on that issue - Make code changes and push to the same branch
2. Check if a PR already exists for this issue - Reply to PR comments using: curl -X POST "https://$instance/api/v1/repos/$owner/$repo/issues/$number/comments" -H "Authorization: Bearer \$GITEA_TOKEN" -H "Content-Type: application/json" -d '{"body":"Your reply here"}'
- If PR exists and is open, review it and learn from it - Or do both
- If PR makes sense to continue, work on it instead
- If PR is not worth continuing, create a new branch/PR but explain in PR description why you're creating a new one instead of continuing the existing PR
3. Read README.md (if exists) to understand the general concept of this repository
4. Read CONTRIBUTING.md (if exists) to understand how to contribute
- If CONTRIBUTING.md doesn't exist, follow steps 5-9 as your guideline
5. Explore the repository to understand the codebase
6. If anything is unclear, post a comment on the issue asking for clarification before implementing
7. Implement the solution
8. Create a branch named fix/issue-$number and implement the fix
9. Create a PR when the implementation is complete using: tea pr create --repo $owner/$repo --title "Your PR title" --body "PR description"
- Make sure you are logged in with: tea login add --name gitea --token \$GITEA_TOKEN --url https://$instance
- If tea is not available, use: curl -X POST "https://$instance/api/v1/repos/$owner/$repo/pulls" -H "Authorization: Bearer \$GITEA_TOKEN" -H "Content-Type: application/json" -d '{"title":"PR Title","head":"branch-name","base":"main","body":"PR description"}'
Tools for PR interaction: MERGING: If instructed to merge, you MUST confirm approval first before merging:
- Post issue/PR comment: curl -X POST "https://$instance/api/v1/repos/$owner/$repo/issues/$number/comments" -H "Authorization: Bearer \$GITEA_TOKEN" -H "Content-Type: application/json" -d '{"body":"Your comment"}' - Check for PR approval via: curl -s "https://$instance/api/v1/repos/$owner/$repo/pulls/$number/reviews" -H "Authorization: Bearer \$GITEA_TOKEN"
- List PR comments: curl -s "https://$instance/api/v1/repos/$owner/$repo/issues/$number/comments" -H "Authorization: Bearer \$GITEA_TOKEN" - Check for "lgtm" or "approved" in comments: curl -s "https://$instance/api/v1/repos/$owner/$repo/issues/$number/comments" -H "Authorization: Bearer \$GITEA_TOKEN"
- List PR reviews: curl -s "https://$instance/api/v1/repos/$owner/$repo/pulls/$number/reviews" -H "Authorization: Bearer \$GITEA_TOKEN" - Only merge if you see approval OR the instruction explicitly says to merge (e.g., "merge the PR", "please merge", "go ahead and merge")
- Merge PR (only with approval): tea pr merge --repo $owner/$repo $number --style merge - To merge: tea pr merge --repo $owner/$repo $number --style merge
- MERGING requires approval first! Check for: approval in reviews, OR "lgtm"/"approved" in comments - If no approval yet, reply asking for review/approval first
- If no approval, ask reviewer to approve first before merging
Delegator's message: Delegator's message:
$user_message $user_message
Work directory: $worktree_path Work directory: $worktree_path (already on the fix branch)
EOF EOF
else else
cat <<EOF cat <<EOF
@@ -396,6 +386,12 @@ ensure_session() {
return 0 return 0
fi fi
if $worktree_exists && ! $session_exists; then
log "warn" "ensure_session" "Worktree exists but session is missing. Removing worktree to recreate both..."
remove_worktree_for_issue "$issue_ref"
worktree_exists=false
fi
if ! $worktree_exists && $session_exists; then if ! $worktree_exists && $session_exists; then
log "warn" "ensure_session" "Session exists but worktree is missing. Removing stale session..." log "warn" "ensure_session" "Session exists but worktree is missing. Removing stale session..."
rm -f "$session_path" rm -f "$session_path"
@@ -485,8 +481,6 @@ cmd_continue() {
if [ -z "$message" ]; then if [ -z "$message" ]; then
message=$(build_dev_agent_message "$issue_ref" "") message=$(build_dev_agent_message "$issue_ref" "")
else
message=$(build_dev_agent_message "$issue_ref" "$message")
fi fi
local worktree_status=$(ensure_worktree "$issue_ref") local worktree_status=$(ensure_worktree "$issue_ref")
@@ -501,8 +495,6 @@ cmd_continue() {
exit 1 exit 1
fi fi
kugetsu_context_dump "$issue_ref" "$message" "$(issue_ref_to_branch_name "$issue_ref")"
local session_file=$(issue_ref_to_filename "$issue_ref") local session_file=$(issue_ref_to_filename "$issue_ref")
local session_path="$SESSIONS_DIR/$session_file" local session_path="$SESSIONS_DIR/$session_file"
local opencode_session_id=$(python3 -c "import json; print(json.load(open('$session_path')).get('opencode_session_id', ''))" 2>/dev/null || echo "") local opencode_session_id=$(python3 -c "import json; print(json.load(open('$session_path')).get('opencode_session_id', ''))" 2>/dev/null || echo "")