cameronmolen/skills

create-pr

Open a pull request for the current changes, then babysit it until it merges.

Voir la source

Mode d’emploi

  1. Copiez la commande et examinez le paquet avant de l’installer dans votre environnement agent.
  2. Consultez le document original pour les outils, identifiants et environnements requis.
  3. Décrivez les entrées et le livrable souhaité ; comparez la sortie aux sources.
npx skills add https://github.com/cameronmolen/skills --skill create-pr

Avant de commencer

  • L’installation n’inclut ni abonnement au modèle, ni quota API, ni accès aux fichiers.
  • Étoiles et installations reflètent l’activité, pas un test indépendant de qualité ou de sécurité.
Document Skill original

Rendu depuis le dépôt source en conservant titres, exemples, code, tableaux, liens et images.

Work the steps in order.

Arguments: $ARGUMENTS — an ENG-xxx task ID when one is given.

1. Determine the branch

  • Read the current branch with git branch --show-current.
  • On a feature branch (anything but main, master, staging), stay on it.
  • On main/master/staging, read the changes with git diff --stat and git diff --cached --stat, then create and check out a kebab-case branch named for them (e.g. add-user-endpoint, fix-search-pagination).

Done when git branch --show-current reports a feature branch.

2. Check coding standards

Skip when git ls-files '*CODING_STANDARDS.md' comes back empty.

Dispatch one subagent on a cheap model (Sonnet, Luna, etc.) to make a quick pass over the change and fix what breaks the standards. Hand it:

  • the path to the CODING_STANDARDS.md file;
  • the change: git add -A, then git diff --cached $(git merge-base HEAD origin/<base>), with <base> the repo's default branch;
  • the brief: every standard applied to the changed lines, each violation fixed in place, edits confined to code the diff touches; return each fix (file, standard, change) and each violation left unfixed with why.

Read its report and its edits; revert any fix that changes behavior rather than conforming to a standard.

Done when the subagent has reported and each of its fixes is reviewed.

3. Commit

git status --porcelain for what is outstanding, git add -A to stage it, then commit with a message describing the change.

Done when git status --porcelain comes back empty.

4. Push

The remote branch can move without you: a teammate's push, or a restack force-pushed from another worktree. Sync with it before this push and every later one:

sh
echo "old=$(git rev-parse -q --verify origin/<branch>)"; git fetch origin   # keep the old SHA
git rev-list --left-right --count origin/<branch>...HEAD   # remote-only, then local-only
  • No origin/<branch> yet, or no remote-only commits: push.
  • Remote-only commits: reconcile onto the remote first. When git rev-list <old>..HEAD is empty, every local commit is already pushed, so git reset --hard origin/<branch>. Otherwise git rebase --onto origin/<branch> <old> replays only the commits made here since the last sync. A conflict, or no old SHA, goes to the user.
  • In an orchestrate-project stack (refs/stack-base/<branch> exists), also check that the layer below still holds your fork point: git merge-base --is-ancestor refs/stack-base/<branch> <base ref>, where <base ref> is origin/<base>, or the local <base> before it has ever been pushed. A failure means the layer below was rewritten: push nothing, tell the user, and wait for the orchestrator's restack message, which carries the exact commands.

The base branch may be checked out in another worktree. Read it by ref and leave its checkout to that worktree.

git push -u origin HEAD

Done when the push lands as a fast-forward of origin/<branch>.

5. Create the PR

Title

An ENG-xxx prefix when a task ID was given, then a brief title-case summary of what the change does: ENG-1000 Create Get User Endpoint, Fix Search Results Pagination.

Write the summary in plain language describing the user-facing symptom or outcome, not the internal mechanism, class/method name, or implementation detail — a non-engineer skimming the PR list should understand what changed and why it matters. Save the technical specifics for the description body.

Bad (internal/technical)Good (plain language)
Derive reconcile_facility_listings Presence Set From Partner ResponsePartner Sync Error Wrongly Removes Available Units
Extend ListingVariations::Delete with the Delete-audit SurfaceUpdate ListingVariation Delete Service to Record Delete History
Refactor OrgMembership Query to Fix N+1Host Dashboard Takes 10+ Seconds to Load for Organizations with Many Locations

Description

`md
<!-- Summary -->

## Demo

TODO: Add screenshots and/or videos for frontend-facing changes.

**Related Notion ticket:** <!-- Link to Notion ticket -->

<details>
<summary>Design decisions and acceptance criteria</summary>

<!-- Include full breakdown of architectural and design decisions and acceptance criteria here -->
</details>

<details>
<summary>Terraform plan</summary>

<!-- Root module path -->

<!-- terraform plan output -->

</details>

Summary

When writing the summary, pick the smallest view that makes the key point clear.

  • Show logic or an algorithm as pseudocode:
text
  on(save)
    if content is unchanged
      return cached result
    write new content
    return fresh result
  • Show runtime control flow as a call tree:
text
  submitForm
    createSession
      persistPrompt
      launchAgent
    navigateToSession
  • Show UI structure as a component tree, including state and module boundaries that matter:
tsx
  <SessionPage>(apps / example / src / routes / session.tsx);
  useSessionEvents() < SessionToolbar > <RunSkillButton>(packages / ui);
  • Show file responsibility or a broad refactor as a shallow file tree:
text
  src/
  ├── commands/       # parses user actions
  ├── sessions/       # owns session state
  └── transport/      # sends API requests
  • Show component interaction, control flow, or data flow with Mermaid:
mermaid
  sequenceDiagram
      participant User
      participant UI
      participant Daemon
      User->>UI: choose command
      UI->>Daemon: send expanded prompt
      Daemon-->>UI: stream result
  • Use diff when the point is what changes and the surrounding shape already exists. Match the diff shape to the topic.

For a component change:

diff
<SessionPage>
  useSessionEvents()
  <SessionToolbar>
+    <RunSkillButton />
  <SessionTimeline>
+    <SkillResultCard />

For a file-layout change:

diff
src/
├── commands/
+│   └── show-me.ts       # expands the slash command
├── sessions/
-└── transport.ts
+└── transport/
+    ├── client.ts
+    └── stream.ts

For a call-tree or call-stack change:

diff
submitForm
  createSession
    persistPrompt
+    expandSkillMention
    launchAgent
-  navigateToSession
+  navigateToSession
+    subscribeToEvents

For a state or control-flow change:

diff
on(save)
-  write content
+  if content is unchanged
+    return cached result
+  write new content
+  invalidate cache
  • Show the whole block when most of it is new, when omitted context would hide ownership or order, or when the user needs a copyable target shape:
ts
function expandSkill(command: string): string {
  const skillName = command.slice(1)
  return `use the ${skillName} skill`
}

Guidance

  • Place each visual next to the short text it supports. Keep only the calls, files, props, states, and boundaries needed to answer the user's current question or the options to resolve the current discussion point.
  • You may use one of these, you may use several, it is unlikely you will use all of them. Use your judgment and don't overwhelm the user.

Other Description Sections

  • ## Demo belongs to frontend-facing changes only; backend, infra, docs, and test-only PRs drop the section. Screenshots and videos you recorded while verifying the change become the demo: replace the TODO line with one ![<what it shows>](<path>) per file, each path also passed to --attach (see Command). With nothing recorded, leave the TODO line in place for the author's screenshots.
  • **Related Notion ticket:** takes the ticket URL, found from the URL given, the ENG-xxx ID, the branch name, commit messages, or task context. N/A goes in only once all of those come up empty. Hold onto the page ID — step 6 and BABYSITTING.md's On merge write back to it.
  • The collapsible section carries the design decisions reviewers need (product, architecture, data model, API, UI, testing, migration, compatibility) and the acceptance criteria that shaped the work — this is where the technical specifics belong. Trivial PRs — copy changes, one-line fixes, dependency bumps, mechanical cleanup — drop the section.
  • The Terraform plan section belongs to PRs that change Terraform (.tf, .tfvars, .terraform.lock.hcl) only; every other PR drops it. Run the plan the way the repo does — a Makefile target, script, or README instructions — falling back to terraform init -lockfile=readonly then terraform plan -no-color -lock=false in each root module the diff affects, including root modules that call a changed module. Paste from Terraform will perform the following actions through the Plan: line (or the No changes. line), one path line and fenced block per root module. When the plans together run past 60,000 characters (GitHub caps a PR body at 65,536), cut each to its # <resource> will be ... lines and its Plan: line. Redact any secret that shows in plain text. When the plan can't run (missing credentials, init fails), put TODO: Add terraform plan output. in the section and tell the user why.

Command

gh pr create --title "<title>" --body "<description>" --attach <path> --attach <path>

One --attach per demo file; drop the flag when there are none. gh uploads each file and rewrites the body reference with the matching path to point at the uploaded asset. When some uploads fail, gh still creates the PR, prints its URL, and exits non-zero: take the URL, report the files that failed, and carry on.

When the PR already exists, gh pr view --json url,state,number,headRefName,baseRefName names the target instead; attach demo files recorded since with gh pr edit <PR> --attach <path>, which appends them to the existing body.

Link the PR to this thread with link_pull_request as soon as you hold its URL, so T3 Code shows its status beside the thread.

Done when you hold a linked PR URL, every placeholder comment in the body has resolved to real content or N/A, and every recorded demo file shows in the body as an uploaded asset.

6. Append the PR to the Notion ticket

Skip when step 5 turned up no ticket.

PR(s) is a free-text property on the Project Tasks data source (collection://9bde6985-9747-4684-b969-c8ecec481b63). It is append-only: Notion's update replaces the whole value, so every write carries the entries already there.

  1. Fetch the ticket and read PR(s) and Status from the <properties> block. When PR(s) reads back <omitted /> or truncated, ask the user for its current contents — writing from an unconfirmed value loses whatever it held.
  2. Build the PR(s) value. Blank field: the new URL alone. Existing entries: those entries verbatim and in order, then , and the new URL. New URL already present: the ticket is already linked, so skip the PR(s) write, but still check Status below. Any non-URL text carries over verbatim.
   https://github.com/neiybor/rails-api/pull/11070, https://github.com/neiybor/rails-api/pull/11067
  1. Decide on Status. Status values on this data source: Blocked, Inbound, Ready, In progress, In review, In verification, Abandoned, Done. Move it to In review only when the current value is Blocked, Inbound, Ready, or In progress — those are the states linking a PR should advance out of. Leave In review, In verification, Abandoned, and Done untouched; each is either already past this point or a state a human parked it in on purpose, and this step never moves a ticket backward.
  2. Write with the Notion update-page tool: the page ID, command: "update_properties", properties carrying "PR(s)" (when it changed) and "Status": "In review" (when step 3 called for it). Skip the call entirely when neither changed.

Done when a re-fetch shows PR(s) holding every pre-existing entry plus the new URL and Status reflecting step 3's decision; report both alongside the ticket URL. A failed write is reported with the values you meant to write, and step 7 continues.

7. Babysit the PR

Read BABYSITTING.md now and run it.

Done when the PR is closed, or merged and On merge is done.

Guardrails

  • Commit and push through the hooks; --no-verify stays out of every command.
  • A failing step stops the run and reports the error rather than retrying blindly. Step 6 is the exception: report and carry on to step 7.

Tâches connexes