diff --git a/skills/kugetsu/scripts/kugetsu-index.sh b/skills/kugetsu/scripts/kugetsu-index.sh index aa22364..41cc216 100755 --- a/skills/kugetsu/scripts/kugetsu-index.sh +++ b/skills/kugetsu/scripts/kugetsu-index.sh @@ -139,6 +139,77 @@ validate_issue_ref() { fi } +read_json_file() { + local file_path="$1" + if [ -f "$file_path" ]; then + cat "$file_path" + else + echo "{}" + fi +} + +write_json_file() { + local file_path="$1" + local json_content="$2" + local temp_file="$file_path.tmp.$$" + + printf '%s' "$json_content" > "$temp_file" + + if ! python3 -c "import json; json.load(open('$temp_file'))" 2>/dev/null; then + echo "Error: write_json_file would create malformed JSON: $file_path" >&2 + rm -f "$temp_file" + return 1 + fi + + mv "$temp_file" "$file_path" +} + +get_json_value() { + local file_path="$1" + local key="$2" + local default="${3:-}" + + if [ ! -f "$file_path" ]; then + echo "$default" + return + fi + + python3 -c "import json; print(json.load(open('$file_path')).get('$key', '$default'))" 2>/dev/null || echo "$default" +} + +set_json_value() { + local file_path="$1" + local key="$2" + local value="$3" + + if [ ! -f "$file_path" ]; then + printf '{"%s": "%s"}\n' "$key" "$value" > "$file_path" + return + fi + + python3 << PYEOF +import json +import sys + +file_path = "$file_path" +key = "$key" +value = "$value" + +try: + with open(file_path, 'r') as f: + data = json.load(f) +except: + data = {} + +data[key] = value + +with open(file_path, 'w') as f: + json.dump(data, f, indent=2) + +print(f"Set $key = $value in $file_path") +PYEOF +} + update_session_pr_url() { local issue_ref="$1" local pr_url="$2" diff --git a/skills/kugetsu/scripts/kugetsu-queue-daemon.sh b/skills/kugetsu/scripts/kugetsu-queue-daemon.sh index a4dab1b..b2d8b0d 100644 --- a/skills/kugetsu/scripts/kugetsu-queue-daemon.sh +++ b/skills/kugetsu/scripts/kugetsu-queue-daemon.sh @@ -34,6 +34,8 @@ release_lock() { check_task_completion() { local item="$1" local queue_id=$(basename "$item" .json) + + local item_data=$(read_json_file "$item") local state=$(python3 -c "import json; print(json.load(open('$item')).get('state', ''))" 2>/dev/null) [ "$state" = "notified" ] || return 0 diff --git a/skills/kugetsu/scripts/kugetsu-session.sh b/skills/kugetsu/scripts/kugetsu-session.sh index 492ffec..f9d6f19 100755 --- a/skills/kugetsu/scripts/kugetsu-session.sh +++ b/skills/kugetsu/scripts/kugetsu-session.sh @@ -239,23 +239,34 @@ create_session() { return 1 fi - local before_json=$(opencode session list --format=json 2>/dev/null) - local before_set=$(echo "$before_json" | python3 -c "import sys,json; sessions=json.load(sys.stdin); print('|'.join(s['id'] for s in sessions))" 2>/dev/null || echo "|") + local before_file="$KUGETSU_DIR/sessions/before$$.json" + local after_file="$KUGETSU_DIR/sessions/after$$.json" + + opencode session list --format=json > "$before_file" 2>/dev/null || printf '{}' > "$before_file" opencode run --fork --session "$base_session" "new session" >/dev/null 2>&1 sleep 1 - local after_json=$(opencode session list --format=json 2>/dev/null) - local after_sessions=$(echo "$after_json" | python3 -c "import sys,json; sessions=json.load(sys.stdin); [print(s['id']) for s in sessions]" 2>/dev/null || true) + opencode session list --format=json > "$after_file" 2>/dev/null || printf '{}' > "$after_file" - local new_session_id="" - while IFS= read -r sess; do - if [[ -n "$sess" ]] && [[ ! "$before_set" =~ \|${sess}\| ]]; then - new_session_id="$sess" - break - fi - done <<< "$after_sessions" + local new_session_id=$(python3 << PYEOF +import json + +with open("$before_file", 'r') as f: + before = json.load(f) +with open("$after_file", 'r') as f: + after = json.load(f) + +before_ids = set(s['id'] for s in before) +for s in after: + if s['id'] not in before_ids: + print(s['id']) + break +PYEOF +) + + rm -f "$before_file" "$after_file" echo "$new_session_id" } diff --git a/skills/kugetsu/scripts/kugetsu-worktree.sh b/skills/kugetsu/scripts/kugetsu-worktree.sh index bff440d..a08ccee 100755 --- a/skills/kugetsu/scripts/kugetsu-worktree.sh +++ b/skills/kugetsu/scripts/kugetsu-worktree.sh @@ -145,15 +145,17 @@ check_pr_status() { token="${GITEA_TOKEN:-}" fi - local response + local response_file="$KUGETSU_DIR/.pr_status_response_$$.json" if [ -n "$token" ]; then - response=$(curl -s -H "Authorization: token $token" "$api_url" 2>/dev/null || echo "{}") + curl -s -H "Authorization: token $token" "$api_url" > "$response_file" 2>/dev/null || printf '{}' > "$response_file" else - response=$(curl -s "$api_url" 2>/dev/null || echo "{}") + curl -s "$api_url" > "$response_file" 2>/dev/null || printf '{}' > "$response_file" fi - local state=$(echo "$response" | python3 -c "import json, sys; d=json.load(sys.stdin); print(d.get('state', 'unknown'))" 2>/dev/null || echo "unknown") - local merged=$(echo "$response" | python3 -c "import json, sys; d=json.load(sys.stdin); print('true' if d.get('merged', False) else 'false')" 2>/dev/null || echo "false") + local state=$(python3 -c "import json; print(json.load(open('$response_file')).get('state', 'unknown'))" 2>/dev/null || echo "unknown") + local merged=$(python3 -c "import json; print('true' if json.load(open('$response_file')).get('merged', False) else 'false')" 2>/dev/null || echo "false") + + rm -f "$response_file" if [ "$merged" = "true" ]; then echo "merged"