Compare commits

..

1 Commits

Author SHA1 Message Date
shokollm
505d68642c fix: add explicit PR creation instructions to dev agent message
Add explicit curl command for creating PRs using Gitea API.
Previously the agent was guessing 'tea issue create' instead of
using the correct API endpoint.

Fixes #223
2026-04-07 13:08:11 +00:00
5 changed files with 29 additions and 160 deletions

View File

@@ -1,18 +0,0 @@
repos:
- repo: https://github.com/shellcheck-py/shellcheck-py
rev: v0.9.0.6
hooks:
- id: shellcheck
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.8
hooks:
- id: ruff
args: [--fix]
- id: ruff-format
- repo: https://github.com/commitizen-tools/commitizen
rev: v3.2.0
hooks:
- id: commitizen
stages: [commit-msg]

View File

@@ -16,38 +16,6 @@
- Test changes before submitting
- See [VERSIONING.md](VERSIONING.md) for backport compatibility rules
## Pre-commit Hooks
This repository uses [pre-commit](https://pre-commit.com/) for linting and commit message enforcement.
### Setup
```bash
pip install pre-commit
pre-commit install
```
### Hooks
- **shellcheck** — Lints bash scripts
- **ruff** — Lints and formats Python
- **commitizen** — Enforces [Conventional Commits](https://www.conventionalcommits.org/) format
### Commit Message Format
Use Conventional Commits format:
```
type(scope): message
# Examples
fix(session): handle missing session gracefully
feat(pm): add queue daemon for task delegation
docs: update contributing guide
```
Types: `fix`, `feat`, `docs`, `refactor`, `chore`, `test`
## Branches
### Primary Branches

View File

@@ -1,40 +1,6 @@
#!/bin/bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/kugetsu-config.sh"
log() {
local level="${1:-}"
local component="${2:-}"
local message="${3:-}"
local timestamp
timestamp=$(date -Iseconds)
case "$level" in
info|warn|error|debug) ;;
*)
echo "Error: log level must be info|warn|error|debug" >&2
return 1
;;
esac
if [ -z "$message" ]; then
message="$component"
component="${level}"
level="info"
fi
local masked
masked=$(mask_sensitive_vars "$message")
echo "[$timestamp] $level $component $masked"
}
log_debug() { log "debug" "$1" "${2:-}"; }
log_info() { log "info" "$1" "${2:-}"; }
log_warn() { log "warn" "$1" "${2:-}"; }
log_error() { log "error" "$1" "${2:-}"; }
cmd_logs() {
local count="${1:-10}"

View File

@@ -41,31 +41,6 @@ check_task_completion() {
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)
local pid=$(python3 -c "import json; print(json.load(open('$item')).get('pid', ''))" 2>/dev/null)
local notified_at=$(python3 -c "import json; print(json.load(open('$item')).get('notified_at', ''))" 2>/dev/null)
local timed_out=false
if [ -n "$notified_at" ]; then
local notified_epoch=$(date -d "$notified_at" +%s 2>/dev/null || echo "0")
local now_epoch=$(date +%s)
local hours_elapsed=$(( (now_epoch - notified_epoch) / 3600 ))
if [ "$hours_elapsed" -ge "${TASK_TIMEOUT_HOURS:-1}" ]; then
timed_out=true
log_warn "queue-daemon" "Task $queue_id ($issue_ref) timed out after ${hours_elapsed}h"
fi
fi
if [ "$timed_out" = true ]; then
if [ -n "$pid" ] && [ "$pid" != "None" ]; then
kill "$pid" 2>/dev/null || true
fi
if [ -n "$session_id" ]; then
opencode session stop "$session_id" 2>/dev/null || true
fi
update_queue_item_state "$queue_id" "error"
log_error "queue-daemon" "Task $queue_id ($issue_ref) marked error — timeout after ${hours_elapsed}h"
release_lock "$issue_ref"
return
fi
if [ -n "$pid" ] && [ "$pid" != "None" ]; then
if ! kill -0 "$pid" 2>/dev/null; then

View File

@@ -270,35 +270,7 @@ build_dev_agent_message() {
local number=$(echo "$issue_ref" | grep -oE '#[0-9]+$' | tr -d '#')
local worktree_path=$(issue_ref_to_worktree_path "$issue_ref")
if [ -n "$user_message" ]; then
cat <<EOF
You are continuing work on $issue_ref. A PR likely already exists.
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"
You may need to:
- Make code changes and push to the same branch
- 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"}'
- Or do both
MERGING: If instructed to merge, you MUST confirm approval first before merging:
- Check for PR approval via: curl -s "https://$instance/api/v1/repos/$owner/$repo/pulls/$number/reviews" -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"
- Only merge if you see approval OR the instruction explicitly says to merge (e.g., "merge the PR", "please merge", "go ahead and merge")
- To merge: tea pr merge --repo $owner/$repo $number --style merge
- If no approval yet, reply asking for review/approval first
Delegator's message:
$user_message
Work directory: $worktree_path (already on the fix branch)
EOF
else
cat <<EOF
You are assigned to work on $issue_ref.
local base_message="You are assigned to work on $issue_ref.
Workflow:
1. Read the issue at $instance/$owner/$repo/issues/$number AND all comments on that issue
@@ -313,20 +285,34 @@ Workflow:
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"}'
9. Create a PR when the implementation is complete
Tools for PR interaction:
- 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"}'
- List PR 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"
- Merge PR (only with approval): 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, ask reviewer to approve first before merging
### Creating PRs
When creating a PR, use the Gitea API directly with curl:
Work directory: $worktree_path
EOF
```bash
curl -X POST "https://$instance/api/v1/repos/$owner/$repo/pulls" \
-H "Authorization: Bearer \$GITEA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Fix issue #$number",
"head": "fix/issue-$number",
"base": "main",
"body": "Closes #$number"
}'
```
Environment variable \$GITEA_TOKEN is available in your environment.
Work directory: $worktree_path"
if [ -n "$user_message" ]; then
echo "$base_message
Additional instructions from delegator:
$user_message"
else
echo "$base_message"
fi
}
@@ -409,11 +395,7 @@ cmd_start() {
cd "$worktree_path"
local sanitized_id=$(echo "$new_session_id" | sed 's/[^a-zA-Z0-9_-]/_/g')
mkdir -p "$worktree_path/.kugetsu"
if [ ! -f "$worktree_path/.gitignore" ] || ! grep -q "^.kugetsu/" "$worktree_path/.gitignore"; then
echo ".kugetsu/" >> "$worktree_path/.gitignore" 2>/dev/null || true
fi
local msg_file="$worktree_path/.kugetsu/msg.txt"
local msg_file="$worktree_path/.kugetsu-msg.txt"
printf '%s' "$dev_message" > "$msg_file"
nohup sh -c "GITEA_TOKEN='${GITEA_TOKEN:-}' opencode run '@$msg_file' --session '$new_session_id'" >> "$LOGS_DIR/dev-$sanitized_id.log" 2>&1 &
@@ -479,11 +461,7 @@ cmd_continue() {
cd "$worktree_path"
local sanitized_id=$(echo "$opencode_session_id" | sed 's/[^a-zA-Z0-9_-]/_/g')
mkdir -p "$worktree_path/.kugetsu"
if [ ! -f "$worktree_path/.gitignore" ] || ! grep -q "^.kugetsu/" "$worktree_path/.gitignore"; then
echo ".kugetsu/" >> "$worktree_path/.gitignore" 2>/dev/null || true
fi
local msg_file="$worktree_path/.kugetsu/msg.txt"
local msg_file="$worktree_path/.kugetsu-msg.txt"
printf '%s' "$message" > "$msg_file"
nohup sh -c "GITEA_TOKEN='${GITEA_TOKEN:-}' opencode run '@$msg_file' --session '$opencode_session_id'" >> "$LOGS_DIR/dev-$sanitized_id.log" 2>&1 &
}