plugins/lisa/skills/lisa-git-submit-pr/SKILL.md
This skill should be used when pushing changes and creating or updating a pull request. It verifies the branch state, pushes to remote, creates or updates a PR with a comprehensive description, optionally coordinates the resulting Pull Request into the configured GitHub ProjectV2, and enables auto-merge.
npx skillsauth add codyswanngt/lisa lisa-git-submit-prInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Push current branch and create or update a pull request. Optional hint: $ARGUMENTS
Recognized optional hints:
work_item_ref=<ref> — source tracker item for native development linkage. Examples: CodySwannGT/lisa#614, https://github.com/CodySwannGT/lisa/issues/614, ENG-123, PROJ-456.target_branch=<branch> or base=<branch> — intended PR base branch.tracker_provider=<github|linear|jira|none> — explicit provider when the ref shape is ambiguous.pr_url=<url> — live pull request URL, only needed when updating tracker backlinks from an existing PR context.auto_merge=<true|false> — whether the PR should merge automatically. Default true (existing behavior for every current caller). With auto_merge=false, skip step 5 entirely (never run gh pr merge --auto) and pass auto_merge=false through to the drive-pr-to-merge delegation in step 6 so the PR is driven to a clean, green, OPEN state and then left awaiting a human.!git status !git log --oneline -10
dev, staging, or main (cannot create PR from protected branches)-u flag and the following environment variable - GIT_SSH_COMMAND="ssh -o ServerAliveInterval=30 -o ServerAliveCountMax=5"work_item_ref can be inferred from $ARGUMENTS, the current branch name, an existing PR body, or the issue/ticket context passed by the caller.lisa-tracker-sync with the work item, milestone pr-ready, the live pr_url, and tracker_provider when known. This makes ticket -> PR linkage mandatory, not just a best-effort milestone comment.github.projects.v2 is enabled, invoke lisa-github-project-v2 with operation: ensure-item and content_node_id: <pull-request-node-id> so linked pull requests join the configured shared Project without replacing the PR as the durable review/merge surface.auto_merge=true, the default — with auto_merge=false skip this step entirely): Choose merge strategy by PR type:
dev → staging): use gh pr merge --auto --merge (never squash). Squashing flattens the constituent chore(release): X.Y.Z [skip ci] commits into one commit titled with the PR title, stripping the [skip ci] markers and breaking the release workflow's promotion-detection regex — the destination branch then double-bumps its version. --merge keeps each chore(release) commit (and its [skip ci] marker) intact under a clean merge commit subject the workflow can recognize.dev): use gh pr merge --auto --merge.drive-pr-to-merge skill — invoke it with the PR number and merge_method=merge (and verify_commit=<pushed head sha> for the ancestry check). When the caller passed auto_merge=false, also pass auto_merge=false so the delegated loop drives the PR to green-and-open (awaiting-human) instead of merged — never merging it, even on repos that disallow auto-merge. That skill is the single source of truth for clearing every blocker: auto-merge with direct-merge fallback, BEHIND re-sync, conflict resolution, failing-check fixes, human + bot (CodeRabbit) review-comment handling with GraphQL thread resolution, stale CHANGES_REQUESTED dismissal, and post-merge ancestry verification. It runs inline and uses plain gh/git so Claude and Codex behave identically. Do not re-implement the loop here.Add provider-appropriate linkage to the PR title and/or body without changing the status lifecycle:
work_item_ref is a GitHub issue URL, org/repo#<n>, or #<n>, add a dedicated issue reference line to the PR body.Refs #<n>, so the merge cannot close the issue before the post-merge deploy, remote verification, health check, and terminal done label.closingIssuesReferences, while Refs yields only a CrossReferencedEvent. Measured on this repository — a Refs-only PR reports closingIssuesReferences: 0; a Closes PR reports 1. So the ticket-side backlink cannot be delegated to GitHub: the managed [lisa-pr-link] comment written by node scripts/lisa-work-item.mjs backlink — the one producer, which lisa-github-sync and the other vendor sync skills call rather than reimplement — is the required backlink under this rule, not a fallback for when native linkage happens to be absent. Two-way linkage (lisa-implement step 7a) depends on that comment, and so does the Work-Item Traceability check wherever the project declares workItem.verify: "full" — there, a PR carrying a correct Refs line still fails the check without it. Post it either way: under the default trailer level the check does not read the tracker, but the two-way linkage a human follows is still worth having, and a project can raise its level at any time.Refs CodySwannGT/lisa#614.lisa-implement.Linear: ENG-123 or Refs ENG-123, so Linear's GitHub integration can attach the PR without completing the Issue.Closes/Fixes/Resolves ENG-123) in the PR title, body, or commit message unless the target branch is the terminal/production branch — the repository default branch or the configured production branch from .lisa.config.json deploy.branches.production (resolved via config-resolution). Unlike GitHub, whose Closes auto-close is scoped to the default branch, Linear's integration completes a linked Issue on merge to any branch, so a magic word on a non-terminal env merge (for example into dev or staging) auto-closes the Issue prematurely and front-runs the env-keyed status:* label ladder. This is the leaf-only-lifecycle "Terminal native closure" invariant (native closure only at the production terminal done) — cite it, do not restate.lisa-linear-sync is the mandatory backstop, not an optional cleanup.lisa-implement.JIRA: PROJ-456, so the GitHub-JIRA integration can attach the PR.When updating an existing PR, preserve any existing linkage line unless the new work_item_ref is more specific. Do not duplicate equivalent references.
After creating or updating the PR, always make the reverse link durable on the source work item when work_item_ref is available:
Resolve the live PR URL with gh pr view <pr-number> --json url --jq .url.
Run the backlink command. It is the executable form of this requirement — it writes the managed [lisa-pr-link] comment on the work item, or updates the one already there, for every tracker Lisa supports:
node scripts/lisa-work-item.mjs backlink --ref <work_item_ref> --pr-url <url>
It is idempotent, so run it on every push rather than deciding whether it is needed. It refuses loudly for a tracker it cannot write, and never silently no-ops. Do not hand-post the comment, and do not describe the posting procedure anywhere: the same file that writes it is the file that checks it, which is what keeps producer and consumer from drifting.
Invoke lisa-tracker-sync with the original work item ref, milestone pr-ready, pr_url=<url>, and tracker_provider=<provider> when known. That is the progress-note and status side; it is not what satisfies the traceability check.
When the PR later merges, invoke lisa-tracker-sync again with milestone pr-merged, the same pr_url, and the merge SHA when available.
Why step 2 exists — do not "simplify" it away as redundant with the Refs line. Under the non-closing rule above, GitHub never creates a native development link at all: that surface is the closing-reference mechanism, so no non-closing form can populate it. A PR carrying a perfectly correct Refs line still fails the required Work-Item Traceability check without the comment. The managed comment is the ticket-side half of the link, not a fallback for when native linkage happens to be absent.
Do not report PR submission as fully synced while the PR body references the ticket but the ticket has neither a verified native PR link nor the managed backlink comment.
After PR creation or update, resolve the live Pull Request node id:
gh pr view <pr-number> --json id,url --jq '{ id, url }'
When github.projects.v2 is enabled, delegate membership to lisa-github-project-v2:
operation: ensure-item
content_node_id: <pull-request-node-id>
Branch on the shared utility outcome exactly as GitHub Issue writers do:
outcome: disabled — no Project configured; continue normally.outcome: added or outcome: reused — PR membership is now present; continue normally.outcome: warning with required: false — preserve the exact Project error, keep the underlying PR creation/update as the durable success, and continue the normal auto-merge/watch flow.outcome: blocked with required: true — surface the exact Project failure and treat the submit flow as blocked even if the PR already exists, so operators can fix Project access/config before reporting full success.Never inline separate gh api graphql ProjectV2 mutations here. All Pull Request membership coordination goes through lisa-github-project-v2 so linked-PR flows and Issue writers stay in parity.
Include in the PR description:
--force push without explicit user requestExecute the workflow now.
development
Prepare a machine — a fresh laptop or a throwaway container — to run coding agents, before any repository exists. Detects which of Lisa's supported agents (Claude Code, Codex, Cursor, OpenCode, Antigravity, Copilot) are already installed, asks which credential manager the machine uses (Bitwarden, 1Password, Doppler, Vault, AWS, or none), and installs only what is missing, each by its vendor's own preferred method. Idempotent, headless by default, and emits a Dockerfile for a spin-up/spin-down environment. Run it on a new machine, in a container, or before cloning anything.
tools
Provision and verify a remote execution environment for a host project — Codex Cloud today, other remote surfaces as they are added. Generates a repository-owned setup script that installs the declared toolchain, materializes secrets through lisa-secrets-access, and runs the project's own hook. Provisions by API where one exists, by driving the vendor console where one does not, and by emitting exact config otherwise — then proves the result with the same read-back regardless of which tier did the work. Use before dispatching any work with executionEnv.
tools
Bring a developer's machine in line with the toolchain the project declares. Reports every tool in remoteEnv.tools that is missing, outdated, or unpinned for this platform, and installs the missing ones into ~/.local/bin from the same pinned, checksummed entries the remote surfaces use — but only when asked. Same manifest, same pins, same installers as lisa-setup-remote-env; what differs is consent and that the pin is a floor rather than an equality. Run it on a fresh checkout, after a manifest change, or when a tool fails at the moment of use.
tools
Route one unit of work to a remote execution surface. Reads the executionEnv parameter (local by default, codex-cloud or claude-web today), verifies the environment is provisioned and bound to this repository, submits a thin skill invocation, records the task identifier to .lisa/remote-dispatch.json, and exits without polling. Routing only — the remote runs the identical skill from the identical repository. Composable and inline: other skills invoke it via the Skill tool rather than users calling it directly.