Files
command-center/agent/managed-skills/gitea-api-pr-operations/SKILL.md
T

4.7 KiB

name, description
name description
gitea-api-pr-operations "Open, list, merge, and diagnose issues/PRs on the Dankclaw Gitea API (192.168.0.143:3000, repo dank/command-center) with the token stored in ~/.config/secrets/gitea — incl. the required merge payload, where review comments actually live on 1.27.3, and how to recover the session id for the mandatory body footer."

Gitea API PR operations (Dankclaw dank/command-center)

Where

  • Token: ~/.config/secrets/gitea (http://user:TOKEN@192.168.0.143 single line). Extract WITHOUT echoing: tok=$(sed -nE 's#^http://[^:/@]+:([^@]+)@192\.168\.0\.143.*#\1#p' ~/.config/secrets/gitea | head -1)
  • Build a 600-perm temp curl config and use curl -K: cfg=$(mktemp) && chmod 600 "$cfg" && printf 'header = "Authorization: token %s"\n' "$tok" > "$cfg" Delete $cfg after use. NEVER pass -H "Authorization: token $tok" (the literal header lands in transcript + logs). NEVER echo the token.
  • Base URL: http://192.168.0.143:3000/api/v1/repos/dank/command-center.

Recipes (all verified live 2026-10-18)

  • Open PR (token only needed for private repos; this one reads publicly but POST needs auth): POST /pulls JSON {title, head, base:"main", body}.
  • PATCH PR title/body: PATCH /pulls/<n> with JSON body {title} and/or {body}. Returns 201 with the full PR. Use jq -n --arg to build JSON; for multi-line bodies write the text to a temp file and --arg b "$(cat b.txt)". (jq CLI: a bare --- argument after the program is parsed as a flag → error; fold footers into the --arg string instead.)
  • List open PRs: GET /pulls?state=open → jq -r '.[] | "#\(.number) \(.head.ref) \(.title)"'.
  • Read PR: GET /pulls/<n> (no token; public repo) → jq -c '{state,merged,mergeable,head:.head.ref}'. mergeable:false is often Gitea's not-yet-checked state, not a conflict — prove a real conflict locally with git merge-tree --write-tree HEAD origin/main before believing it.
  • MERGE: POST /pulls/<n>/merge with -H 'Content-Type: application/json' and body {"Do":"merge"} — this build REQUIRES the Do field: {} or {"DoNotMerge":false,...} → 422; {"Do":"merge"} → 200 + {"state":"closed","merged":true,"merge_commit_sha":"..."}. Verify with a plain GET /pulls/ afterwards (merge endpoint's own stdout may not parse). Merge is the --no-ff merge commit on main; then git -C ~/.omp fetch && git merge --ff-only origin/main propagates the live deployment.
  • Issues: same shape at /issues (POST {title, body}), /issues/<n>/comments (POST {body}, PATCH .../comments/<id>) — both work with the temp-cfg auth.

Review comments: the API lies on 1.27.3 (learned 2026-10-18)

  • GET /pulls/<n>/comments (inline review comments) → 404 not found on every route (token or not, ?pull_request_id= or not) even when a review with comments exists.
  • GET /pulls/<n>/reviews works (shows state, comments_count) but bodies are empty.
  • The comments are readable from the PR HTML: curl -sS http://192.168.0.143:3000/dank/command-center/pulls/<n> -o /tmp/pr.html then extract <div class="content comment-content"> blocks (python: re.finditer(r'comment-content', src) → widen ±800 chars, strip tags). Duplicates appear (suggested-change UI shows text twice); dedupe mentally.
  • Per-conversation resolve API also 404s — flag resolutions in an issue comment instead.

Every issue/PR body ends with --- line then cwd: <wd> · session: <id>. Keep it inside the --arg string (not a --- CLI arg).

cwd is THIS session's own working directory (note a build worktree separately if they differ). When /status is unreachable (headless/subagent context), recover the session id from the session store instead of inventing one: ls -t ~/.omp/agent/sessions/<cwd-slug>/ | head -2 → <timestamp>_<uuid> (the same uuid as <uuid>.jsonl); the slug is the cwd with / replaced by -. Subagent files live under the parent session's directory, so the newest entry there is the parent id.

Gotchas

  • Content-Type: POSTs with -d @file.json MUST carry -H 'Content-Type: application/json' on the command line. -H entries put in the curl config file are ignored for this (header ordering quirk).
  • xdg-open <pr-url> lands the PR in Frank's Firefox the moment it is opened — law, not courtesy.
  • jq: cannot index "not found" with "user" = endpoint 404'd into an error object; check -w '%{http_code}' before blaming jq.
  • The token in .git/config's remote URL is the same secret; the credential file (~/.config/secrets/gitea) is the one git actually consults (global credential.helper) and the one to reuse for API calls.