Files
Alex Mikhalev c6d425be63 feat(gitea-skill): Rewrite Gitea agent skill with verified API patterns
Rewrites SKILL.md with patterns verified against live Gitea 1.22.6:
- Milestones as project containers (project board API does not exist)
- Scoped workflow labels with mutual exclusivity
- Issue dependencies using IssueMeta format
- 1Password token retrieval via op read
- Default repo terraphim/agent-tasks with env var overrides

Adds setup-labels.sh for idempotent repo and label creation.
Includes research and design documents from disciplined development.
Adds pre-commit config adapted for infrastructure project.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 12:41:19 +01:00

133 lines
4.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# setup-labels.sh -- Idempotent setup of Gitea repo and workflow labels
# Creates the default agent-tasks repo (if missing) and 12 scoped labels.
#
# Usage:
# source ~/op_zesticai_non_prod.sh # load OP_SERVICE_ACCOUNT_TOKEN
# export GITEA_TOKEN=$(op read "op://TerraphimPlatform/git.terraphim.cloud-admin-token/credential")
# ./setup-labels.sh [OWNER] [REPO]
#
# Environment:
# GITEA_URL -- Gitea instance (default: https://git.terraphim.cloud)
# GITEA_TOKEN -- API token (required)
# GITEA_OWNER -- Org or user (default: terraphim)
# GITEA_REPO -- Repository (default: agent-tasks)
set -euo pipefail
GITEA_URL="${GITEA_URL:-https://git.terraphim.cloud}"
GITEA_OWNER="${1:-${GITEA_OWNER:-terraphim}}"
GITEA_REPO="${2:-${GITEA_REPO:-agent-tasks}}"
if [ -z "${GITEA_TOKEN:-}" ]; then
echo '{"error": "GITEA_TOKEN is not set"}' >&2
exit 1
fi
gitea_api() {
local method="$1" endpoint="$2" data="${3:-}"
local args=(-s -H "Authorization: token $GITEA_TOKEN" -H "Content-Type: application/json")
if [ -n "$data" ]; then
args+=(-X "$method" -d "$data")
else
args+=(-X "$method")
fi
curl "${args[@]}" "$GITEA_URL/api/v1$endpoint"
}
# --- Ensure repo exists (idempotent) ---
ensure_repo() {
local http_code
http_code=$(curl -s -o /dev/null -w '%{http_code}' \
-H "Authorization: token $GITEA_TOKEN" \
"$GITEA_URL/api/v1/repos/$GITEA_OWNER/$GITEA_REPO")
if [ "$http_code" = "200" ]; then
echo "{\"repo\": \"$GITEA_OWNER/$GITEA_REPO\", \"action\": \"exists\"}"
return 0
fi
# Try creating under org first, fall back to user repo
local result
result=$(gitea_api POST "/orgs/$GITEA_OWNER/repos" \
"{\"name\": \"$GITEA_REPO\", \"description\": \"AI agent task tracking\", \"auto_init\": true, \"private\": false}" 2>&1)
if echo "$result" | jq -e '.id' > /dev/null 2>&1; then
echo "{\"repo\": \"$GITEA_OWNER/$GITEA_REPO\", \"action\": \"created\"}"
return 0
fi
# Fall back to user repo
result=$(gitea_api POST "/user/repos" \
"{\"name\": \"$GITEA_REPO\", \"description\": \"AI agent task tracking\", \"auto_init\": true, \"private\": false}" 2>&1)
if echo "$result" | jq -e '.id' > /dev/null 2>&1; then
echo "{\"repo\": \"$GITEA_OWNER/$GITEA_REPO\", \"action\": \"created\"}"
return 0
fi
echo "{\"repo\": \"$GITEA_OWNER/$GITEA_REPO\", \"action\": \"error\", \"detail\": $result}" >&2
return 1
}
# --- Create label if it does not exist ---
ensure_label() {
local name="$1" color="$2" description="$3" exclusive="${4:-false}"
local existing
existing=$(gitea_api GET "/repos/$GITEA_OWNER/$GITEA_REPO/labels" \
| jq -r --arg n "$name" '.[] | select(.name == $n) | .id')
if [ -n "$existing" ]; then
echo "{\"name\": \"$name\", \"id\": $existing, \"action\": \"exists\"}"
return 0
fi
local payload
payload=$(jq -n \
--arg name "$name" \
--arg color "$color" \
--arg desc "$description" \
--argjson excl "$exclusive" \
'{name: $name, color: $color, description: $desc, exclusive: $excl}')
local result
result=$(gitea_api POST "/repos/$GITEA_OWNER/$GITEA_REPO/labels" "$payload")
local label_id
label_id=$(echo "$result" | jq -r '.id // empty')
if [ -n "$label_id" ]; then
echo "{\"name\": \"$name\", \"id\": $label_id, \"action\": \"created\"}"
else
echo "{\"name\": \"$name\", \"action\": \"error\", \"detail\": $result}" >&2
return 1
fi
}
# === Main ===
echo "--- Ensure repo $GITEA_OWNER/$GITEA_REPO ---"
ensure_repo
echo "--- Creating labels ---"
# Workflow labels (mutually exclusive within scope)
ensure_label "workflow:ready" "0e8a16" "Task is ready for an agent to pick up" true
ensure_label "workflow:in-progress" "fbca04" "Task is actively being worked on" true
ensure_label "workflow:blocked" "d93f0b" "Task is blocked by a dependency" true
ensure_label "workflow:done" "6f42c1" "Task is complete" true
# Priority labels (mutually exclusive within scope)
ensure_label "priority:critical" "b60205" "Must be done immediately" true
ensure_label "priority:high" "d93f0b" "Should be done this cycle" true
ensure_label "priority:medium" "fbca04" "Normal priority" true
ensure_label "priority:low" "0e8a16" "Nice to have" true
# Type labels (mutually exclusive within scope)
ensure_label "type:feature" "1d76db" "New functionality" true
ensure_label "type:bug" "d93f0b" "Defect fix" true
ensure_label "type:task" "5319e7" "General task" true
ensure_label "type:research" "006b75" "Investigation or spike" true
echo "--- Done ---"