You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There's no skill that composes a merge-commit message and executes a PR merge through the platform's API. Users run gh pr merge directly with hand-typed flags, missing the project's title-rendering machinery (describe-change.sh), label-based scope/type inference, and consistent merge-log voice.
Context
The project already has the building blocks:
describe-change.sh renders titles from declarative templates and emits a merge_commit_title field (to be renamed merge_title).
create-pr / create-gh-pr / create-bitbucket-pr establishes the orchestrator-and-delegate pattern that splits decisions from per-platform execution.
summarize-change produces release-notes-voice ## What sections that feed the PR body, which in turn should feed the merge-commit body.
The existing merge_commit: preferences section was created when only title_format was needed. With action-of-merging concerns coming in, that name is misleading — rebase strategy produces no merge commit at all. Renaming to merge: and reserving the namespace for future settings is the cleanest forward path.
Solution
A three-skill family mirroring the create-pr pattern:
merge-pr — user-invocable orchestrator. Owns all decisions: PR resolution, body composition, scope/type/strategy resolution, approval gate.
merge-bb-pr — internal Bitbucket delegate. Stub for this iteration, parallel to how create-ticket handles Jira.
Configuration:
Rename merge_commit: → merge: in both preferences files (.agents/preferences.yaml, ~/.agents/preferences.yaml), describe-change.sh, its tests, commit-format.md, and packages/agents/README.md.
Rename JSON output key merge_commit_title → merge_title in describe-change.sh.
This iteration hard-codes defaults (strategy=squash, delete_branch=true); resolver functions are shaped to accept future preference-file lookup as a one-line additive change. The merge: section is reserved for these keys; they are documented as reserved-but-unhonored.
CLI surface (merge-pr):
Flag
Effect
Default
--pr {n}
Merge PR {n} instead of the current branch's PR
current branch's PR
--scope {s}
Override scope inference
inferred
--type {t}
Override type inference
inferred
--strategy {squash|merge|rebase}
Override merge strategy
squash
--delete-branch {yes|no}
Override branch deletion
yes
Process (orchestrator):
Resolve session context (get-session-context) and PR number (--pr or current-branch lookup).
Run pre-merge checks: branch in sync with remote; PR exists and open; not draft; mergeable (no conflicts, required checks pass, required reviews approved). Refuse with a specific reason on any failure.
Resolve scope/type: CLI override → reverse-lookup of PR labels via .meta/label-map.json → commit-message majority across default_branch...HEAD → mark ambiguous.
Resolve strategy and delete_branch from CLI override or hard-coded default.
Render merge-commit title via describe-change.sh (merge_title field).
Compose merge-commit body: extract ## What section content (heading dropped) from the live PR body via gh pr view --json body. If missing or thin, compose fresh from commits + diff in release-notes voice.
Approval gate: render proposed merge commit (title + body), strategy, branch-deletion choice. If scope/type are ambiguous, ask the user to fill them in now. Prompt 👍🏼👎🏼 before invoking the API.
Delegate to merge-gh-pr (or stub merge-bb-pr).
Save merge artifact in the ticket directory recording PR URL, merged-at timestamp, commit SHA, strategy, title, body, branch-deletion outcome.
Report results. Local state untouched.
Out of scope (intentionally):
Auto-merge (gh pr merge --auto).
--admin bypass of branch protections.
Local cleanup (checkout main, pull, delete local branch).
Bitbucket execution (stub only — full implementation is a follow-up).
merge-pr accepts --pr, --scope, --type, --strategy, --delete-branch overrides; defaults to current-branch PR with strategy=squash and delete_branch=yes.
Pre-merge checks refuse the merge with a specific reason when: branch out of sync, PR missing, PR closed/merged, PR draft, conflicts present, failing required checks, missing required reviews.
Merge-commit title is rendered via describe-change.sh's merge_title field.
Merge-commit body is extracted from the ## What section of the live PR description; falls back to fresh release-notes-voice composition when missing or thin.
Scope/type inference order is: CLI override → PR label reverse-lookup → commit majority → user prompt at approval gate.
Approval gate is always shown before the API call; no bypass flag.
On success, merge-pr saves a merge artifact in the ticket directory recording PR URL, commit SHA, strategy, title, body, and branch-deletion outcome.
merge-bb-pr SKILL.md exists with the delegate interface declared and a notice that Bitbucket merge is not yet implemented.
merge_commit: section is renamed to merge: in .agents/preferences.yaml, ~/.agents/preferences.yaml, describe-change.sh, describe_change_test.sh, commit-format.md, and packages/agents/README.md. References to merge_commit_title and merge_commit: are removed wherever they occur.
JSON output key in describe-change.sh is renamed from merge_commit_title to merge_title.
Skill body documents that merge.strategy and merge.delete_branch keys are reserved for future use and not yet honored.
New and modified behavior in this change is covered by tests (script test for describe-change.sh rename + parser changes; resolver functions for scope/type/strategy/delete_branch; pre-merge check logic).
User-facing surface changes (new skills, renamed config key, renamed JSON output key) are reflected in skill content and packages/agents/README.md; obsolete references are removed.
Problem
There's no skill that composes a merge-commit message and executes a PR merge through the platform's API. Users run
gh pr mergedirectly with hand-typed flags, missing the project's title-rendering machinery (describe-change.sh), label-based scope/type inference, and consistent merge-log voice.Context
The project already has the building blocks:
describe-change.shrenders titles from declarative templates and emits amerge_commit_titlefield (to be renamedmerge_title).create-pr/create-gh-pr/create-bitbucket-prestablishes the orchestrator-and-delegate pattern that splits decisions from per-platform execution.summarize-changeproduces release-notes-voice## Whatsections that feed the PR body, which in turn should feed the merge-commit body..meta/label-map.jsondefines forward scope/type → label mappings, easily reverse-lookable for inference.The existing
merge_commit:preferences section was created when onlytitle_formatwas needed. With action-of-merging concerns coming in, that name is misleading —rebasestrategy produces no merge commit at all. Renaming tomerge:and reserving the namespace for future settings is the cleanest forward path.Solution
A three-skill family mirroring the
create-prpattern:merge-pr— user-invocable orchestrator. Owns all decisions: PR resolution, body composition, scope/type/strategy resolution, approval gate.merge-gh-pr— internal GitHub delegate. Ownsgh pr view,gh pr merge, label fetching, PR-state validation.merge-bb-pr— internal Bitbucket delegate. Stub for this iteration, parallel to howcreate-tickethandles Jira.Configuration:
merge_commit:→merge:in both preferences files (.agents/preferences.yaml,~/.agents/preferences.yaml),describe-change.sh, its tests,commit-format.md, andpackages/agents/README.md.merge_commit_title→merge_titleindescribe-change.sh.strategy=squash,delete_branch=true); resolver functions are shaped to accept future preference-file lookup as a one-line additive change. Themerge:section is reserved for these keys; they are documented as reserved-but-unhonored.CLI surface (
merge-pr):--pr {n}{n}instead of the current branch's PR--scope {s}--type {t}--strategy {squash|merge|rebase}squash--delete-branch {yes|no}yesProcess (orchestrator):
get-session-context) and PR number (--pror current-branch lookup)..meta/label-map.json→ commit-message majority acrossdefault_branch...HEAD→ mark ambiguous.delete_branchfrom CLI override or hard-coded default.describe-change.sh(merge_titlefield).## Whatsection content (heading dropped) from the live PR body viagh pr view --json body. If missing or thin, compose fresh from commits + diff in release-notes voice.merge-gh-pr(or stubmerge-bb-pr).Out of scope (intentionally):
gh pr merge --auto).--adminbypass of branch protections.merge.strategy/merge.delete_branch(resolver shape supports it; lookup deferred).Acceptance criteria
merge-pr(user-invocable),merge-gh-pr(internal delegate),merge-bb-pr(internal delegate, stub).merge-praccepts--pr,--scope,--type,--strategy,--delete-branchoverrides; defaults to current-branch PR withstrategy=squashanddelete_branch=yes.describe-change.sh'smerge_titlefield.## Whatsection of the live PR description; falls back to fresh release-notes-voice composition when missing or thin.merge-prsaves a merge artifact in the ticket directory recording PR URL, commit SHA, strategy, title, body, and branch-deletion outcome.merge-bb-prSKILL.md exists with the delegate interface declared and a notice that Bitbucket merge is not yet implemented.merge_commit:section is renamed tomerge:in.agents/preferences.yaml,~/.agents/preferences.yaml,describe-change.sh,describe_change_test.sh,commit-format.md, andpackages/agents/README.md. References tomerge_commit_titleandmerge_commit:are removed wherever they occur.describe-change.shis renamed frommerge_commit_titletomerge_title.merge.strategyandmerge.delete_branchkeys are reserved for future use and not yet honored.describe-change.shrename + parser changes; resolver functions for scope/type/strategy/delete_branch; pre-merge check logic).packages/agents/README.md; obsolete references are removed.