Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
75 lines
3.2 KiB
Bash
Executable File
75 lines
3.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Minimal Gitea issue API wrapper for the agent loop (Claude side, Linux).
|
|
# Token is read from a 0600 file and never echoed. Usage: gitea.sh <command> [args]
|
|
set -euo pipefail
|
|
set +x
|
|
|
|
GITEA_URL="${GITEA_URL:-https://git.copse.top}"
|
|
GITEA_REPO="${GITEA_REPO:-root/Jyotisha}"
|
|
TOKEN_FILE="${JYOTISHA_AGENT_TOKEN_FILE:-$HOME/.config/jyotisha-agent/gitea-token}"
|
|
API="$GITEA_URL/api/v1/repos/$GITEA_REPO"
|
|
|
|
_token() {
|
|
[[ -r "$TOKEN_FILE" ]] || { echo "gitea.sh: token file missing: $TOKEN_FILE" >&2; exit 2; }
|
|
tr -d '[:space:]' < "$TOKEN_FILE"
|
|
}
|
|
|
|
# _call METHOD PATH [JSON_BODY] — prints the response body; fails on HTTP >= 400
|
|
# without echoing request headers.
|
|
_call() {
|
|
local method="$1" path="$2" body="${3:-}" out code
|
|
out="$(mktemp)"
|
|
if [[ -n "$body" ]]; then
|
|
code="$(curl -sS -o "$out" -w '%{http_code}' -X "$method" \
|
|
-H "Authorization: token $(_token)" -H 'Content-Type: application/json' \
|
|
--data-binary "$body" "$API$path")"
|
|
else
|
|
code="$(curl -sS -o "$out" -w '%{http_code}' -X "$method" \
|
|
-H "Authorization: token $(_token)" "$API$path")"
|
|
fi
|
|
if [[ "$code" -ge 400 ]]; then
|
|
echo "gitea.sh: $method $path -> HTTP $code: $(head -c 300 "$out")" >&2
|
|
rm -f "$out"
|
|
return 1
|
|
fi
|
|
cat "$out"
|
|
rm -f "$out"
|
|
}
|
|
|
|
cmd="${1:-}"; shift || true
|
|
case "$cmd" in
|
|
whoami)
|
|
curl -sS -H "Authorization: token $(_token)" "$GITEA_URL/api/v1/user" | jq -r .login ;;
|
|
label-id) # label-id NAME
|
|
_call GET "/labels?limit=100" | jq -r --arg n "$1" '.[] | select(.name == $n) | .id' ;;
|
|
ensure-label) # ensure-label NAME COLOR DESCRIPTION
|
|
if [[ -z "$("$0" label-id "$1")" ]]; then
|
|
_call POST "/labels" "$(jq -nc --arg n "$1" --arg c "$2" --arg d "$3" '{name:$n,color:$c,description:$d}')" | jq -r '"created \(.name)"'
|
|
else
|
|
echo "exists $1"
|
|
fi ;;
|
|
issues) # issues LABEL — open issues carrying LABEL, oldest first, as JSON array
|
|
_call GET "/issues?state=open&type=issues&limit=50&labels=$(jq -rn --arg l "$1" '$l|@uri')" \
|
|
| jq -c 'sort_by(.created_at)' ;;
|
|
issue) # issue N
|
|
_call GET "/issues/$1" ;;
|
|
labels) # labels N — label names on issue N, one per line
|
|
_call GET "/issues/$1/labels" | jq -r '.[].name' ;;
|
|
add-label) # add-label N NAME
|
|
_call POST "/issues/$1/labels" "$(jq -nc --arg n "$2" '{labels:[$n]}')" >/dev/null ;;
|
|
remove-label) # remove-label N NAME (no-op when absent)
|
|
id="$("$0" label-id "$2")"
|
|
[[ -n "$id" ]] && _call DELETE "/issues/$1/labels/$id" >/dev/null || true ;;
|
|
comments) # comments N — JSON array
|
|
_call GET "/issues/$1/comments" ;;
|
|
comment) # comment N FILE — post FILE's content as a comment
|
|
_call POST "/issues/$1/comments" "$(jq -Rsc '{body:.}' < "$2")" >/dev/null ;;
|
|
create-issue) # create-issue TITLE FILE — prints the new issue number
|
|
_call POST "/issues" "$(jq -Rsc --arg t "$1" '{title:$t, body:.}' < "$2")" | jq -r .number ;;
|
|
close) # close N
|
|
_call PATCH "/issues/$1" '{"state":"closed"}' >/dev/null ;;
|
|
*)
|
|
echo "usage: gitea.sh whoami|label-id|ensure-label|issues|issue|labels|add-label|remove-label|comments|comment|create-issue|close" >&2
|
|
exit 64 ;;
|
|
esac
|