| name | pr |
| description | Create a PR from a committed and pushed branch after task-defined checks pass. Ready PRs continue to fixup in the primary conversation. |
PR
Planner Entry
Create the PR directly in the primary conversation after commit, task-defined
checks, and push. Ready PR monitoring and remediation continue through
/pr-fixup in the same conversation.
Host detection: This skill works on GitHub, GitLab, and Azure Repos. Detect the host before publication by inspecting git remote get-url origin:
- URL contains
dev.azure.com, visualstudio.com, or ssh.dev.azure.com → use the Azure Repos flow below.
- URL contains
github.com (or any host you have configured for GitHub) → use the GitHub flow below.
- URL contains
gitlab (e.g. gitlab.com, gitlab.acme.corp) → use the GitLab flow at the bottom of this file.
- For self-managed hosts, the user's repository configuration determines the host.
GitHub tool selection: The GitHub flow uses gh CLI by default. If gh is unavailable or fails, use any available GitHub tools in the environment (e.g. MCP GitHub tools).
GitLab tool selection: The GitLab flow prefers glab CLI when available; otherwise it shells curl against the REST v4 API using $GITLAB_TOKEN (which the agent runtime injects from the user's secrets store).
Azure Repos tool selection: The Azure flow prefers az repos pr create with the Azure DevOps extension. Auth can come from an existing az login session or AZURE_DEVOPS_EXT_PAT.
Available skills
/commit — Creates the artifact after task-defined checks pass.
/pr-fixup — Wait for CI checks and CodeRabbit, Greptile, Claude, OpenCode, and cubic review feedback, fix any failures or valid comments, and push.
Options
--draft — create the PR as draft and skip the fixup step. Use when the work is not ready for review.
- Default (no flag) — create as ready-for-review and continue with
/pr-fixup in the same conversation.
Publishing-state precedence: explicit user state (--draft or an explicit
ready-for-review request) wins. If the github:yeet plugin is explicitly
selected, follow its draft default only when the user did not request either
state; otherwise /pr defaults to ready-for-review. Always report the result.
Steps
Track these steps with an internal todo/checklist and mark them complete as you go.
Do not create, update, or delete Kandev subtasks for this workflow unless the user
explicitly requests task tracking.
-
Uncommitted changes: If there are dirty or staged changes, stop: commit
and the affected task checks are required first.
-
Branch: If on main or master, stop and ask the user for a feature
branch. Otherwise use the current feature branch as-is.
-
Remote state: Confirm the branch has an upstream and the remote contains
the local HEAD. If not, run /push before creating the PR.
CI artifact bootstrap: If the diff introduces a CI-consumed registry tag
or artifact that a workflow on this branch must publish first, follow that
publisher's documented bootstrap path before rerunning consumer checks.
Request explicit user approval before a workflow_dispatch or other action
writes a shared registry, and verify the target tag/digest exists.
-
Screenshots — capture and validate before publication. For a UI-visible
change, capture fresh screenshots for every affected viewport before creating
the PR. When the changed surface is structurally absent on another viewport,
record that rationale instead of capturing an unrelated screen.
Use synthetic or redacted data, validate the assets, and compress PNGs using
the recipe in step 7. If capture is impossible, report the concrete blocker
and stop before PR publication. For non-UI changes, record that screenshots
are not required and continue.
-
Create the PR. Before creating, check open PRs for the current branch and
inspect task-linked PR metadata. Reuse an existing PR; create a duplicate only
when the user explicitly requests separate PRs. Use --draft if requested,
otherwise create as ready-for-review.
PR title must follow Conventional Commits format (see /commit for full rules). CI validates via pr-title.yml — the PR title becomes the squash-merge commit used for release notes.
PR body must be built from .github/pull_request_template.md; fail fast if it is missing. Read the whole template before writing the body. Treat HTML comments as authoring instructions for the agent, not as output:
- Fill the template's required sections from the actual diff, commits, and verification performed.
- Remove optional sections that add no value for this change.
- Preserve static required sections such as checklists exactly as the template provides them; do not pre-fill unchecked boxes.
- For docs-only PRs, keep code-centric checklist items unchanged when they do not apply, and list the docs-safe validation commands actually run.
Azure Repos flow
When git remote get-url origin points at Azure Repos, use the same preflight
(steps 1-4). For step 5, create an Azure Repos pull request instead of a GitHub
PR. Skip the GitHub fixup handoff and the GitHub-only embedding portion of step
7, but do not skip screenshot capture. For a UI-visible change, capture and
validate the required assets as described in step 4. Attach them to the Azure
PR when supported; otherwise return the fresh asset paths to the planner as an
explicit attachment handoff. If capture is impossible or no viable attachment
handoff exists, return that blocker instead of treating the PR as complete.
Prefer the Azure CLI when it is on PATH:
SOURCE_BRANCH="$(git branch --show-current)"
TARGET_BRANCH="${TARGET_BRANCH:-}"
DRAFT_FLAG=""
[ "${DRAFT:-false}" = "true" ] && DRAFT_FLAG="--draft"
az repos pr create \
${TARGET_BRANCH:+--target-branch "$TARGET_BRANCH"} \
--source-branch "$SOURCE_BRANCH" \
--title "type: description" \
--description "$(cat <<'EOF'
<filled PR template>
EOF
)" \
${DRAFT_FLAG:+$DRAFT_FLAG}
Notes:
- Azure DevOps CLI auto-detects organization / project / repository from the current repo in most cases, so you usually do not need to pass
--organization, --project, or --repository explicitly.
- If auto-detect fails (common with unusual remotes or older CLI setups), derive them from the remote and retry with explicit flags.
- Complete the screenshot capture and attachment/handoff requirements above,
then return the PR URL and stop.
GitLab flow (Merge Requests)
When git remote get-url origin points at a GitLab host, use the same preflight
(steps 1-4) and create a Merge Request for step 5. Skip the GitHub fixup
handoff and the GitHub-only orphan-ref embedding portion of step 7, but do not
skip screenshot capture. For a UI-visible change, capture and validate the
required assets, including the synthetic/redaction gate, then attach them to
the MR when supported or return fresh asset paths as an explicit attachment
handoff. If capture is impossible or no viable attachment handoff exists,
return that blocker instead of treating the MR as complete.
MR title still follows Conventional Commits — the squash-merge commit message is built from it the same way.
MR description uses the same template as the PR body above (Summary, Validation, etc.).
Prefer the glab CLI when it is on the agent's PATH:
Don't hardcode --target-branch: many projects ship from master, develop, or a custom default. Omit the flag so glab resolves the project's default branch via the API, or pass an explicit value only if the user / spec already specified one.
glab mr create [--draft] \
--title "type: description" \
--description "$(cat <<'EOF'
<filled template>
EOF
)" \
--remove-source-branch \
--yes
If glab is unavailable but $GITLAB_TOKEN is set, fall back to the REST API. Derive the host from the git remote — $CI_SERVER_URL is only set inside GitLab runners and silently falling back to gitlab.com from a developer's machine would target the wrong instance. Construct the JSON body with jq so multi-line descriptions and embedded quotes can't break the payload.
REMOTE_URL="$(git remote get-url origin)"
case "$REMOTE_URL" in
ssh://*) URL="${REMOTE_URL#ssh://}"; FORM=ssh ;;
http://*|https://*) URL="${REMOTE_URL#*://}"; FORM=http ;;
*) URL="$REMOTE_URL"; FORM=scp ;;
esac
URL="${URL#*@}"
case "$FORM" in
scp)
HOST_ONLY="${URL%%:*}"
HOST="https://${HOST_ONLY}"
PROJECT_PATH="${URL#*:}"
;;
ssh)
HOST_PORT="${URL%%/*}"
HOST="https://${HOST_PORT%%:*}"
PROJECT_PATH="${URL#*/}"
;;
http)
HOST_PORT="${URL%%/*}"
HOST="https://${HOST_PORT}"
PROJECT_PATH="${URL#*/}"
;;
PROJECT=
SOURCE_BRANCH=
PROJECT_ENC=
TARGET_BRANCH=
PAYLOAD=
curl --fail -X POST \
-H \
-H \
--data \
To address review comments on a GitLab MR, use the discussions API rather than individual review comments — discussions are GitLab's threading primitive. List with GET /projects/:id/merge_requests/:iid/discussions, reply with POST /projects/:id/merge_requests/:iid/discussions/:discussion_id/notes, and resolve a thread with PUT /projects/:id/merge_requests/:iid/discussions/:discussion_id?resolved=true. The glab equivalent for replies is glab mr note create --reply <discussion_id> — bare glab mr note opens a new thread instead of replying to an existing one.