Files
agent-skills/skills/work/SKILL.md
T
Miguel Palhas e627f53934 feat(land): merge on gitea, stop at the button on github
The never-merge rule only holds for GitHub. Gitea repos here are the
user's own, so land squash-merges once CI is green, threads are
resolved and the branch is current. A gitea PR with no reviewer ever
requested counts as approved, otherwise it waits forever.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 09:56:56 +01:00

5.7 KiB

name, description, user-invocable, args
name description user-invocable args
work Pick a task from GitHub, Gitea, or Linear, implement it in a worktree, open a PR, and iterate on reviews autonomously true
name description required
input A GitHub or Gitea issue number, a Linear issue ID, an ad-hoc task description, or omit to auto-pick the next unblocked task false

Work - Proper PR Flow

Autonomous workflow: tracking issue -> worktree -> implementation -> PR -> review iteration -> done. GitHub and Gitea are the primary tracker backends; Linear remains supported. Select one with tracker in .claude/tracker.json.

First: Read tracker-common/COMMON.md (sibling skill, same skills root) for shared setup instructions.

Workflow

1. Setup (from COMMON.md)

  • Load project config
  • Select task (from $ARGUMENTS)
  • Set up worktree
  • Gather context

2. Plan

  1. Analyze the issue requirements and the codebase context you gathered.
  2. Break the work into logical commits.
  3. If the issue is non-trivial, write a brief plan as a comment on the tracking issue (Linear comment, or Gitea POST $BASE/api/v1/repos/$REPO/issues/$N/comments).
  4. Identify risks or open questions. If they're blocking, ask the user. If not, note them and proceed with best judgment.

3. Implement

Follow the implementation guidelines from COMMON.md.

After implementation is complete:

  1. Run the buildCommand from the config through the gate — <skills-root>/tracker-common/scripts/gate.sh -- <buildCommand> (see "Local verification budget" in COMMON.md). All checks must pass before opening a PR. Exit 75 = the machine was busy and it never ran: open the PR and let CI be the check, saying so in the PR body. Exit 137 = memory cap, not a failing test.
  2. If tests fail, fix them. Do not ship broken code.
  3. During implementation, check only the module you touched. This is the one full run.

3.5 Self-review gate (before opening the PR)

Spawn the cavecrew-reviewer subagent on your own diff (Agent tool, subagent_type: caveman:cavecrew-reviewer; point it at git diff <defaultBranch>...HEAD). It returns one line per finding, severity-tagged, no praise. Fix anything real it surfaces, then re-check only the modules those fixes touched — don't run the whole suite a second time; CI covers the rest. This catches obvious issues before /land waits on human/bot review — cheaper than a review round-trip.

Advisory, not a hard gate: for a trivial diff (typo, one-liner, config bump) skip it. Don't loop on it — one pass, address the genuine findings, move on.

4. Open PR

  1. Push the branch: git push -u origin <branch>
  2. Open a PR. The exact commands depend on remoteHost from .claude/tracker.json (or legacy .claude/linear.json):
    • github (default): see GitHub variant below.
    • gitea: see Gitea variant below.
  3. PR title and body in both cases:
    • Title: concise, under 70 characters
    • Body format:
      ## Summary
      <bullets>
      
      ## Issue
      Closes <REF>
      
      ## Test plan
      <what was tested and how>
      
      where <REF> is the Linear issue ID (ERN-347) for tracker: linear, or #<N> for tracker: gitea / tracker: github (both auto-close the issue when the PR merges to the default branch). End the body with the metadata marker from pr-common/COMMON.md.
    • Request reviewers from prReviewers if configured.
  4. Move the tracking issue to "In Review":
    • linear: set the issue status to "In Review" (or equivalent).
    • gitea: no review state exists — leave the issue open (the PR's Closes #N closes it on merge); optionally add an in-review label if one already exists in the repo.
    • github: no review state exists — leave the issue open (the PR's Closes #N closes it on merge); optionally add an in-review label if one already exists in the repo.

5. Hand off to /land

The PR is open — now drive it to ready-to-merge. Invoke /land <N> (the land skill). It owns the whole review/CI iteration loop: waits for CI + reviews without idling, fixes failures, resolves every comment (including bot reviewers), pushes, re-arms, and once green + approved it updates the branch, then merges on gitea or hands the merge click to the user on GitHub.

Do not re-implement that loop here — /land is the single source of truth for it, and it reads the same remoteHost / tracker config. /land derives the tracking issue from the PR body's Closes <REF>, so no extra hand-off state is needed.

The success bar /land enforces (all must hold before it declares ready): CI green, all review threads resolved, approved with no pending review requests.


GitHub variant (open PR)

gh pr create --title "<title>" --body "<body>" --reviewer <r1>,<r2>

Then go to step 5 (/land <N>).

Gitea variant (open PR)

Requires $GITEA_TOKEN in the environment (source ~/.env.claude if needed) and remoteBaseUrl from .claude/tracker.json (or legacy .claude/linear.json). Set BASE=$remoteBaseUrl and REPO=<owner>/<repo> (from git remote get-url origin).

curl -sS -X POST \
  -H "Authorization: token $GITEA_TOKEN" \
  -H "Content-Type: application/json" \
  "$BASE/api/v1/repos/$REPO/pulls" \
  -d "$(jq -nc --arg title "<title>" --arg body "<body>" --arg head "<branch>" --arg base "<defaultBranch>" \
        '{title:$title, body:$body, head:$head, base:$base}')"

The response includes number and html_url. Save the number — it's the PR index /land uses.

To request reviewers (if prReviewers is set):

curl -sS -X POST \
  -H "Authorization: token $GITEA_TOKEN" \
  -H "Content-Type: application/json" \
  "$BASE/api/v1/repos/$REPO/pulls/$N/requested_reviewers" \
  -d '{"reviewers": ["alice","bob"]}'

Then go to step 5 (/land <N>).