Skip to content
cccskills
FreePublished on GitHub

pr

Create or update a pull request: a typed title (`fix:`, `feat:` … from `scripts/lib/pr-title.js`, which places the change in CHANGELOG.md), category labels chosen by judgment, a concise body from `.github/pull_request_template.md` that reads as the squash commit message, and one skill-owned "review notes" comment for the detail reviewers want but `git log` doesn't. Detects an existing open PR for the current branch and routes to update-mode (diff title/labels/body/comment, ask, then apply) instead of duplicating; aborts cleanly on merged/closed PRs. Scans branch + commits for related issues, falls back to `gh` issue search, surfaces architecture docs whose related-files were touched, and runs the four-pillar judgment passes (tech-debt scan, decision-shape detect, followup capture) so journal hygiene is part of shipping rather than a separate manual step. Required for all PRs in this repo; it supersedes any default PR-creation flow.

The English summary is being prepared. Showing the original description.

jellyrock/jellyrock46 stars(GitHub 46 + cccskills 0)

Run score Not tested

See how to install

Files included (2)

  • SKILL.md30.8 KB
  • forge.sh30.4 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Create or Update a Pull Request

This repo

  • Merge settings fallback (Step 3): squash only; squash_merge_commit_title=PR_TITLE, squash_merge_commit_message=PR_BODY: the title is the commit subject and the changelog line, the body the permanent commit message, so reviewer detail goes in the notes comment.
  • Title gate and types (Steps 5, 6, 9): read scripts/lib/pr-title.js (TITLE_TYPES: each type and the CHANGELOG.md section it lands in; CI checks against it, so read it rather than recall it). scripts/changelog-syncer.js places the change by the title's type. Changes to the product paths (the app a viewer runs: components/, source/, locale/, images/, settings/, manifest) take feat for a new capability or setting, fix behavior that was wrong, update behavior changed on purpose, perf same behavior faster, refactor a restructure meant to change nothing (still listed: a refactor can regress), remove, revert. A scope names the PR's one area in its usual name (fix(video):, chore(skills):) and shows in the changelog line as (video) …; CI rejects an empty scope (fix():). Tooling (scripts/, .github/, .claude/, tests/, docs/, dev dependencies) take chore, ci, build, test or docs: fix(skills): once put a /pr change in the users' Fixed section (#998). The changelog reads the PR's current title, so a wrong title can be fixed after merge by editing the PR and re-syncing, until the release is cut; after that the released section is fixed text. A race fixed inside a restructure is user-visible whether or not it was reproduced (ADR 0037); #1010's first title dropped one, and #996 merged with a title that predated a credits row added in review.
  • Title spelling: the post-merge journal-sync writes the title verbatim into docs/progress.md, and journal-sync-precheck.yml spell-checks it at PR time: a bare identifier fails it, so backtick it (backticks render as code in progress.md; GitHub shows them literally in the title, the accepted trade-off).
  • Own journal passes (Step 4):
    • Tech debt: spawn /tech-debt-scan as an Agent sub-agent, subagent_type: general-purpose, model: sonnet, never Read docs/architecture/tech-debt.md inline. Prompt: Read .claude/skills/tech-debt-scan/SKILL.md and follow the steps; scope the changed-files set to git diff <lower>..HEAD --name-only so only file areas that became relevant since the last /pr render are considered; surface candidate slugs + ask about new debt but do not apply edits; return the proposed diff for the parent to confirm. Surface its diffs one at a time, apply / skip / edit; apply with Edit only on accept.
    • Decision shape: node scripts/lint/decision-shape-nudge.cjs --range=<lower>..HEAD; walk each match with the user (does it close off alternatives?) before /log decision.
    • Followups follow AGENTS.md's Followup-discipline rule (/log followup, or /tech-debt-scan's Step 4 for a refactor slug); the rule decides, not preference.
  • Gather (Step 5): node scripts/lint/check-touched-related-files.cjs --base main lists the architecture docs whose related-files: were touched; name them in the notes' Docs and journals line.
  • Sections (Step 8): Overview (required) 1–5 sentences, the problem first: a reader should know from it alone whether this is the commit they want. Changes (required) one bullet per logical change, not per file, naming the symbols a reader would grep. Testing (when something was verified) 1–4 lines: what ran, where, the result (test:unit 4503/4503 on a Roku Ultra): the durable record of the proof (prove-dont-dismiss); the full matrix goes in the notes. Follow-ups (when something is deferred) each bullet points at its entry: a docs/architecture/tech-debt.md slug or a docs/progress.md followup; most PRs have none. pr-body-check.js fails an optional section that is present but empty.
  • PR checks (Step 9): node scripts/lint/pr-body-check.js --pr-title "<title>" --body-file <body-file> must exit 0; node scripts/lint/pr-body-check.js --list-refs --pr-title "<title>" < <body-file> (and over the notes) prints each reference's resolved type, state and title for the Step 9 read; a non-zero exit is a shorthand or missing reference, and a ? line is not a pass.
  • Labels (Step 7): also new-setting (adds a user-facing setting; with new-feature when the setting is how a new capability is reached) and accessibility (added beside the main label whenever a deliverable changes what screen-reader, audio-guide or caption users get, even in one clause; never a deliverable of its own). Nothing automated reads the category labels: CHANGELOG.md goes by title type, and journal-sync skips only on dependencies, documentation, docs-only, ci, automated, chore-only. Automation's labels, never touched: dependencies (Renovate), release-prep, merge-conflict, and the issue-triage labels. Rulings on real PRs (two blind agents, differences settled): #1033 failed library, recovery, "#" crash, "never narrates or toasts over": bug-fix, accessibility (the dialog-delay consolidation and RTA hooks are Changes bullets only); #1029 a song crash: bug-fix (the applyItemArtwork() merge was needed by the fix); #1024 a subtitle parser crash: bug-fix, accessibility; #991 "only the first 25 channels" + "loading programs near the focus": bug-fix, general-improvement; #847 reskin, engine rewrite fixing "three known defects", "first functional coverage": general-improvement, bug-fix, dev-improvement (the rewrite is how the defects were fixed, so no code-cleanup); #987 a fix: touching only bsconfig, scripts and tests: dev-improvement.
  • After (Step 11), create path only and not on a trivial change: say once that journal-sync.yml adds the PR to docs/progress.md's Recently shipped on merge and clears ## Currently running when its text overlaps the title; /done running is needed only to close it before merge.

Contract

Goal. Be the single, mandatory path for opening or updating a pull request in this repo. The skill reads what a squash merge keeps (the repo's merge settings, read live), titles the PR for the place its title ends up, renders the body from the repo's PR template for whoever reads it (the permanent commit message, or a reviewer only), labels each deliverable, and runs the journal passes (decision and followup, plus any this repo adds) before anything is posted, so journal hygiene lands in the same change set rather than as separate manual chores. It is create-or-update aware: an existing open PR for the branch routes to update-mode (diff the current title, labels, body and notes against a fresh render, confirm, back up, then apply), and merged or closed PRs abort cleanly instead of opening a duplicate. It ships at the Sonnet tier because the work is template-fill and structured signal-gathering with bounded judgment; a pass that walks a large ledger runs as its own sub-agent with an explicit model. Supersede any default PR-creation flow with this skill; never open or edit a pull request outside it, through forge.sh or the forge directly.

Inputs. No arguments: the skill operates on the current branch and its commits. It expects a non-default, non-detached branch with a clean working tree; the pre-flight pushes the branch and any unpushed commits. It reads the repo's PR template, its squash-merge settings, the branch's commit log and diff against the default branch, an existing PR's title, labels, body and notes comment (when one is open) including the render marker, and this skill's ## This repo for the repo's title rules, labels, own journal passes, PR checks and required sections.

Outputs. A created or updated pull request with: a title that passes the repo's title gate, names every user-visible change and backticks code identifiers; one label per kind of deliverable; a body that is the filled template, written for the reader the merge settings give it; when the body becomes the commit message, one notes comment for reviewer-only detail; and a hidden render marker (a full sha and an ISO-8601 UTC timestamp) that lets the next run narrow the journal passes to "since last render". Also: drafted journal entries surfaced per candidate for the user to accept into /log; on the update path, a backup of the prior body and notes inside the git directory; and the PR URL printed. No journal entry is written without a per-candidate accept, and nothing on the PR is overwritten without confirmation.

Success criteria.

  • The pre-flight gates hold: not on the default branch, not detached, clean tree, branch and commits pushed. Hard failures stop and report; an obvious push is not gated behind a verbal question.
  • Existing-PR routing is correct: an open PR takes the update path (diff, confirm, back up, apply); a merged or closed one aborts with the right recovery instruction; none takes the create path.
  • What reaches git log is read from the repo's settings, not assumed: the body is written as a commit message only when the merge keeps it, and the title gets the most care where the merge keeps it.
  • The journal passes run against the resolved lower-bound commit (the prior render marker on update, the default branch on create), so the user isn't re-asked about candidates already handled, and each candidate is confirm/skip per item.
  • The title passes the repo's title gate, backticks code identifiers and names every user-visible change; on the update path it is re-derived from the whole PR.
  • Labels come from the deliverables the title and the body's summary name, each shown to the user beside the phrase that earned it; tooling-only work is dev-improvement, documentation goes only on a PR that changes nothing but docs, and labels this skill does not manage are never removed.
  • The body passes the repo's own PR checks before it is posted, every issue reference points where its sentence means, and in a public repo nothing private is posted.
  • forge.sh pr create, pr edit and pr comment permission prompts are left intact: they are the user's gate on what gets posted, not friction to allowlist away.

Failure modes to avoid.

  • Writing for the wrong reader. A body written as a reviewer's note when the merge makes it the permanent commit message, or a commit-message body on a repo whose merge discards it. Read the settings first.
  • Polluting the skill's context with a ledger walk. A pass that reads a large ledger runs as a sub-agent with an explicit model; reading the ledger inline is the context pollution the sub-agent exists to prevent, and narrating a sub-agent while the transcript shows an inline read is a false report.
  • Auto-applying journal entries. The passes produce drafts only; invoke /log (or apply a ledger edit) only on an explicit per-candidate accept.
  • Overwriting a PR without confirmation or backup. On the update path, always diff, confirm and back up the prior body and notes before forge.sh pr edit; if an edit fails, the backup is the recovery path: surface it, don't claim success.
  • Opening a duplicate on a merged or closed PR. Abort with the recovery instruction; never silently create a second PR.
  • A title that names only part of the PR. Where the title becomes the commit subject or a changelog line it cannot be fixed after merge; re-derive it from every user-visible change, on the update path too. The likeliest omission is a behavioral fix delivered inside a refactor.
  • A type picked by habit. Where the title's type places the change (a changelog section, a release note), choose it from what the PR delivers: a tooling-only change given a user-facing type lands in the users' notes, and a product change given a housekeeping type drops out of them.
  • Labeling a PR's ingredients instead of its purposes. A helper the fix needed, or the tests and docs that prove or explain it, earn no label of their own; a label with no title or summary phrase to point to is dropped.
  • Detail stuffed into a commit-message body. Measurement tables, device or host matrices and reviewer asides belong in the notes comment, with a one-line summary of the evidence left in the body.
  • Dropping a code reference to pass a check. When a title or spelling check rejects an identifier, backtick it; rephrasing the reference away is the wrong fix.
  • Silencing forge.sh, or reaching past it. 2>/dev/null turns the forge's exact error into a guess; each verb's fields are fixed, so a field it lacks is a change to forge.sh, never a direct forge call.
  • Creating a label to fit the PR. A new label for each PR fragments the repo's label set; a missing label is replaced by the closest existing one first, and forge.sh label create is proposed only as the last option, never run silently.
  • Suppressing the create, edit or comment permission prompts by allowlisting them: they are intentional user gates.

When not to use.

  • There is no branch to ship (on the default branch, or nothing committed): there's nothing to open a PR for.
  • You need to bypass the journal passes for a trivial change: that is still in scope (skip the passes with one confirmation), not a reason to call forge.sh pr create directly.

Implementation

This skill's ## This repo holds the repo's own parts: the title gate and its types, the product paths that separate product work from tooling, labels beyond the shared table and the labels automation owns, any journal pass of its own, the PR checks to run before posting, guidance for each template section, what to say after posting, and the merge-settings fallback line. Where a step needs one of them, it says so.

Step 1: Pre-flight (abort if any fails)

Run in parallel:

  • git rev-parse --abbrev-ref HEAD: must not be the default branch (bash .claude/skills/pr/forge.sh repo default-branch, called {{default}} below) and must not be HEAD (detached: ask the user to check out a branch).
  • git status --porcelain: must be empty.
  • git rev-parse --abbrev-ref --symbolic-full-name @{u}: with no upstream, run git push -u origin HEAD.
  • git rev-list --count @{u}..HEAD: when it is not zero, run git push.

A failed hard check (default branch, detached, dirty tree) stops with which one and why. Pushing a feature branch to open its PR is obvious: don't ask first.

Step 2: Detect an existing PR (route create vs update)

bash .claude/skills/pr/forge.sh pr view for the current branch: JSON with number, url, state, author, title, labels, body and headRefOid. Never add 2>/dev/null: forge.sh passes the forge's own message on whole.

  • MERGED: abort. PR #{{N}} is already merged at {{url}}. Switch to {{default}} and pull before opening a follow-up PR.
  • CLOSED: abort. PR #{{N}} at {{url}} was closed without merging. Reopen it with bash .claude/skills/pr/forge.sh pr reopen {{N}}, or start a new branch.
  • OPEN: the update path. Keep {{N}}, {{url}}, {{author}}, {{title}}, {{labels}}, {{body}}.
  • No PR (forge.sh pr view exits 4; any other non-zero exit is an error: show its message and stop): the create path; {{lower}} is {{default}}.

On the update path:

  1. Author note. bash .claude/skills/pr/forge.sh user login; when it differs from {{author}}, print one line: Note: PR #{{N}} was opened by {{author}}. Edits will appear under your account. If the call fails, skip the note.
  2. Find the notes comment. bash .claude/skills/pr/forge.sh pr comments {{N}} | jq -c '.comments[] | select(.body | startswith("<!-- /pr notes -->")) | {url, author: .author.login, body}'; keep the last match authored by you as {{notes}}. Its numeric id is the #issuecomment-{{id}} suffix of its url (the id field is a GraphQL node id the REST call cannot use).
  3. Resolve {{lower}}, the lower bound for the journal passes:
    1. The last <!-- /pr render: sha=([0-9a-f]{40}) ts=(\S+) --> in {{notes}}, else in {{body}}; use its sha when git merge-base --is-ancestor {{sha}} HEAD exits 0.
    2. Else the PR's first commit, bash .claude/skills/pr/forge.sh pr commits {{N}} | jq -r '.commits[0].oid', when it is an ancestor of HEAD.
    3. Else {{default}}, and print: Note: the last render's commit is not in this branch (rebase or force-push?); the journal passes cover the whole branch.

Step 3: Read what the merge keeps

bash .claude/skills/pr/forge.sh repo merge-settings: JSON with squash_merge_commit_title and squash_merge_commit_message. These come back only with enough rights on the repo; when they are null or empty, use the merge-settings line in this skill's ## This repo, and when that is missing too, ask in chat which of the readings below holds. The result decides two things:

  • The title. PR_TITLE: the title becomes the commit subject on {{default}}. COMMIT_OR_PR_TITLE: it does on a multi-commit PR, but a single-commit PR keeps the commit's own subject, so on a one-commit branch the care goes into that subject (the title is still gated). Those are the only two values the API defines.
  • The body. PR_BODY: the body is the permanent commit message, so it is written for someone reading git log a year from now, and reviewer-only detail goes in the notes comment (Step 8), which also carries the render marker. COMMIT_MESSAGES or BLANK (the API's other two values): the body never reaches git log, so it is written for a reviewer, holds the detail itself, and ends with the render marker; no notes comment.

Step 4: Journal passes (before drafting the body)

Each pass surfaces journal entries the user should write, one-line confirm/skip per candidate; drafts only, applied through /log on accept. One confirmation skips the whole step on a trivial change (a typo, a dependency bump, docs only). Every pass covers {{lower}}..HEAD, so candidates handled on an earlier render are not raised again.

  • Decision: commits that close off alternatives or carry a non-obvious rationale (architectural, hard to reverse, cross-component). On accept, /log decision, which applies its own significance gate.
  • Followup: anything the branch defers, half-does or leaves for later, including what you are about to write as a follow-up in the body. On accept, /log followup, and the body cites the entry by its fid or title, never by its position in a list.
  • This repo's own passes, from this skill's ## This repo, only for capture types or ledgers this repo keeps. A pass that reads a large ledger runs as a sub-agent with an explicit model, never as an inline read.

Step 5: Gather context (in parallel)

  • git log {{default}}..HEAD --pretty=format:"%h %s%n%b%n---": the full commit history on the branch.
  • git diff {{default}}...HEAD --stat and --name-only: what changed.
  • The PR template (.github/pull_request_template.md, or the path this skill's ## This repo gives): read it, hints included.
  • Anything this skill's ## This repo lists for this step (a title-type definition, a related-docs check).

Step 6: Title

type: Imperative summary or type(scope): Imperative summary, under 70 characters, passed with --title; the types and the gate that checks them are in this skill's ## This repo. Synthesize it from all the commits, not the latest. Pick the type by what the PR does to the product (this skill's ## This repo names the product paths): a change to the product takes a product type; a change only to the tooling around it takes a tooling type, even when it fixes something; a PR with both is typed by its product change. Scope is optional; never write an empty one.

Name every user-visible change. List the changes a user of the product would notice, then check the title names each; when they don't fit, name the outcome that covers them all rather than the biggest alone. A refactor that changes behavior is not a refactor here: if you can say "X used to sometimes fail, now it doesn't", it is user-visible, and a commit subject that joins a fix to a restructure with "and" needs each half checked. On the update path, re-derive the title from the whole PR; a PR that grew in review is when a title goes stale.

Backtick every code identifier (a component, file or function name). When a check rejects it, keep the backticks; never rephrase the reference away.

Step 7: Labels

Labels are for finding PRs in the forge's list: a label is right when someone filtering by it would want this PR. Pick them after the body is final:

  1. Find the deliverables. Read the title and the body's summary section. A deliverable is something they present as what the PR does; something presented only as how or why another deliverable works is part of that one. A change that appears only in the list of changes (a refactor the fix needed, the tests or docs that prove or explain a deliverable) earns no label.
  2. Label each deliverable with the one best label below, or one this skill's ## This repo adds. A PR with different kinds of deliverable gets several labels.
  3. Tooling is not the product. new-feature, general-improvement, bug-fix and code-cleanup describe the product (the paths in this skill's ## This repo). A deliverable that changes only tooling is dev-improvement, whether it fixes, adds or tidies something; a PR that changes only tooling is dev-improvement alone.
  4. Name the evidence. Show the user each label beside the title or summary phrase that earned it, before create or edit, so it can be overruled in one reply. A label with no phrase to point to is dropped.
LabelThe deliverable…
new-featureadds a capability the product's users can use
general-improvementmakes behavior that was working better on purpose: UX, speed, wording, robustness
bug-fixmakes the product do what it should have done already
code-cleanuprestructures or tidies product code as a goal of the PR, meant to change nothing a user sees
dev-improvementchanges only tooling (rule 3)
documentationthe PR changes only docs; never on a PR that also changes code

Check each chosen label exists (bash .claude/skills/pr/forge.sh label list: every label with its description). For a missing one, in this order: use the existing label whose name and description fit the same deliverable, shown beside the label it replaces; else leave it off and say so; and only when the user wants it and nothing existing fits, show the bash .claude/skills/pr/forge.sh label create {{name}} --description "{{text}}" command for them to run or approve. Never create a label silently. Leave alone the labels automation owns (this skill's ## This repo lists them) and any label not in the table.

Step 8: Build the body (and the notes comment)

Start from the template. Fill each section the way its hint comment asks (a section the hint marks required is never left empty; an optional one is left out or marked None as that hint says), then remove the hint comments. Keep the headings you use exactly as the template spells them. This skill's ## This repo has the repo's guidance per section. Fill checkboxes from what the diff and Step 4 actually produced, never from intent.

  • Links are absolute URLs to the default branch (get each from bash .claude/skills/pr/forge.sh repo file-url {{path}}, which knows the repo's forge): a repo-relative link is emitted as written and 404s from the PR page. Link the default branch, not the PR branch (deleted on merge); a file the PR adds is named in backticks instead.
  • A bare #N is always this repo's issue N, whatever repo the sentence names. Write another repo's issue or PR as owner/repo#N or a full URL. They usually arrive by copying a commit message: rewrite them on the way in.
  • Related issues. First the branch name (a number in it) and the commit messages ((?i)(fix|fixes|close|closes|resolve|resolves|ref|refs|see)\s*#(\d+)), each confirmed with bash .claude/skills/pr/forge.sh issue view {{N}} | jq -c '{number, title, state}'. Only when that finds nothing: 2–4 keywords from the title, bash .claude/skills/pr/forge.sh issue list --state open --search "{{keywords}}" --limit 10, read as candidates, not answers. Render Fixes #N when the PR closes it, Ref #N when only related; when several candidates are plausible and you can't judge between them, list them and ask.

When the body is the commit message (Step 3): keep it to what a git log reader needs (the problem and the change, the symbols a reader would grep for, a one-line summary of the evidence), and put the rest in one notes comment:

<!-- /pr notes -->
## Review notes

**Docs and journals:** {{what this PR updated — docs, decision records, journal entries — or "none", from Step 5's list of changed files, not intent.}}

{{Verification detail: matrices, measurements, before/after output, the reasoning behind a non-obvious call. Omit a part with nothing to say. Absolute URLs only.}}

<!-- /pr render: sha={{full-40-char-HEAD-sha}} ts={{ISO-8601-UTC}} -->

<!-- /pr notes --> stays the first line: it is how the update path finds the comment. The render marker goes in this notes comment only, never in the body, which becomes the commit message and would carry it into git log. When the body is not the commit message (Step 3), the body holds the detail and ends with the render marker line, and there is no notes comment. Either way, fill the marker from git rev-parse HEAD and date -u +%Y-%m-%dT%H:%M:%SZ, never by hand.

Step 9: Check before posting

  1. This repo's PR checks, from this skill's ## This repo (a title gate, a body linter), on the rendered title, body and notes: each must pass; fix what it reports and run it again.
  2. Issue references. Read every bare #N in the body and notes against the sentence it sits in, with bash .claude/skills/pr/forge.sh issue view {{N}} | jq -c '{title, state}' (an issue or a PR): a title that doesn't match the sentence means it belongs to another repo and becomes owner/repo#N. A reference you could not resolve is not a pass: check it by hand.
  3. Public repo. When this repo's public posture is public, sweep the title, body, notes and the branch diff for a home path, a person's email, a secret or another repository's name: git diff {{default}}...HEAD | grep -nEi '/home/|/Users/|@[a-z0-9.-]+\.[a-z]{2,}|BEGIN [A-Z ]*PRIVATE KEY' for the diff, and a read for the text you wrote. Read each hit; remove what is private, and stop to ask about anything in the diff itself.
  4. The render marker's place. When the body is the commit message (Step 3), grep -c '/pr render' {{body-file}} must print 0; otherwise move the marker into the notes comment and run it again.

Step 10: Create or update

Create path:

bash .claude/skills/pr/forge.sh pr create --base {{default}} --title "{{title}}" --label "{{label}}" [--label "{{label}}" …] --body-file {{body-file}}
bash .claude/skills/pr/forge.sh pr comment {{N}} --body-file {{notes-file}}    # only when Step 3 calls for a notes comment

Default to non-draft; use --draft only when the work is incomplete and you want CI early, and say so.

Update path:

  1. Render the title, labels, body and notes the same way; the body describes the whole PR ({{default}}..HEAD), not the delta since the last render.
  2. Compare each with what the PR has now. When everything is unchanged (the marker's timestamp ignored), print PR #{{N}} already up to date at {{url}} and stop: no backup, no edit. Otherwise show a diff for each part that changed (title, labels added and removed, the body section by section, the notes), and say which body sections a person likely edited by hand.
  3. Confirm in chat: apply, skip (print {{url}} and stop) or edit (take the user's changes, then ask again).
  4. Back up the prior body, then the prior notes if any, to "$(git rev-parse --git-dir)/pr-backup-{{N}}-{{date -u +%Y%m%dT%H%M%SZ}}.md": inside the git directory it can never be committed. Outside auto mode Claude Code asks before any write there (a sensitive path), and a headless run refuses it: that approval is the last gate before the edit, so never skip the backup or move it elsewhere to avoid it.
  5. Apply only the parts that changed: bash .claude/skills/pr/forge.sh pr edit {{N}} [--title "{{title}}"] [--add-label "{{a}},{{b}}"] [--remove-label "{{c}}"] [--body-file {{body-file}}] (remove only a label from Step 7's table, or this repo's additions, that no longer applies); edit the notes comment by id with bash .claude/skills/pr/forge.sh comment edit {{id}} --body-file {{notes-file}}, or create it with forge.sh pr comment when there was none. If an edit fails, give the backup path and stop; the body is restored with bash .claude/skills/pr/forge.sh pr edit {{N}} --body-file {{backup}} after trimming the notes off its end.

Step 11: After

Print the PR URL; don't summarize the body. Apply the accepted journal drafts through /log. Then anything this skill's ## This repo asks for after posting.

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Session-start briefing: where did I leave off, what is in flight, what needs attention. One tested script reads git, the journal (followups, running work, cadences) and tracked projects and prints every fixed-threshold check that fires; JellyRock's own aggregator adds open PRs, high-engagement bugs, recent bug reports, current-branch CI, pending handoffs, open upstream-watch issues (Jellyfin releases and release candidates, Roku OS), recent ADRs, tech debt and architecture-doc staleness. Ends with one Suggested next move that hands off to /log, /done, /issue-triage, /runtime-triage, /ci-triage or /server-upgrade. Mandated by AGENTS.md's catchup-discipline rule: run at the start of any genuine new session, after a multi-day gap, or whenever you ask what the state of the world is.

The English summary is being prepared. Showing the original description.

jellyrock/jellyrock46Updated Oct 26, 2026

Diagnose a failed CI workflow run and fix it the /snag way. A tested read-only script fetches the run, reports every failed job and step with the log region around its errors (not the post-job cleanup), and classifies each against this repo's gates.tsv, printing the banner a gate carries when its obvious fix is the wrong one. Then: re-run only what is transient, reproduce locally, find the root cause, and show one decision screen; the chosen fix is built test-first and committed on a fix branch, never pushed. Use when a CI run failed on a pull request or on the default branch.

The English summary is being prepared. Showing the original description.

jellyrock/jellyrock46Updated Oct 26, 2026

DEPRECATED, replaced by the `enrich` phase built into /crash-report. The old flow filed crash issues first and enriched them one by one afterward. The new flow (stage, then enrich, then file) pulls the dashboard backtrace before filing, so issues are born complete and architectural-class crashes go to their epic instead of becoming standalone issues. Do not invoke it for new work: run /crash-report and paste the backtraces during its enrich step. It stays only as a redirect; the `enrich-issue` script subcommand still exists as a legacy escape hatch for a crash issue filed before the change.

The English summary is being prepared. Showing the original description.

jellyrock/jellyrock46Updated Oct 26, 2026

Process a Roku weekly crash-report CSV (or a zip holding one or more CSVs) into tracked GitHub issues and architectural-epic evidence, enriching before filing (stage, then enrich, then file). STAGE parses and filters the CSV, groups by pkg-path signature, builds each cited app version in a temporary git worktree, maps the transpiled `.brs` line back to the source `.bs` line, runs the GitHub dedup search, and writes a local worksheet where every crash starts pending; a mechanism hint (task-launch, network, other) orders which to pull first but never authorizes a file. ENRICH folds in the per-crash backtraces you paste from Roku's dashboard (a 7-day window, one click per crash, no bulk export), extracts each `&hNN` exception code, and routes every crash to a disposition (nothing files or aggregates without a backtrace): `file` (a scoped bug becomes a new per-signature [crash] issue, born enriched), `aggregate` (a known architectural class: `&h29` big-library too-many-task-threads, `&h23` render-thread execution timeouts, the `&hec` init `m.global.constants` race; upserted as one flat record comment per `file·function·line·version` onto the class epic, never a standalone issue), or `watch` (accepted noise, a spike comment only). FILE performs the GitHub writes (create, comment or reopen for scoped bugs; the epic record upsert for architectural classes) and writes a run-summary handoff. Dedup-aware and idempotent. Use when a fresh Roku crash CSV arrives (weekly). A deep dive on one crash goes to `/issue-triage <N>` after filing.

The English summary is being prepared. Showing the original description.

jellyrock/jellyrock46Updated Oct 26, 2026

Draft a GitHub issue body for the JellyRock repo from a Reddit/Discord post or free-form bug report and submit it via forge.sh. Reads the YAML form templates under .github/ISSUE_TEMPLATE/ to know which fields are required, fills them by extracting from the input, asks for any missing required fields, validates the body matches the chosen template's schema, then runs forge.sh issue create with the auto-labels the template defines. Use when you have a user report (paste from anywhere) and want to formalize it into a properly-structured GitHub issue.

The English summary is being prepared. Showing the original description.

jellyrock/jellyrock46Updated Oct 26, 2026

Walk a major dependency-version bump (a Renovate major PR, possibly a grouped one carrying several deps, or a package you name) through JellyRock's major-bump SOP so the judgment steps run the same way every time. Resolves each package and its from and to versions, fetches the upstream changelog/migration guide for that range, classifies the breaking changes, greps the codebase for the call sites those breaks actually hit, runs the mechanical gate that fits the dependency's type (a runtime BrightScript lib: validate, build, lint:bs, then test:unit and test:rta on a device; JS or Node tooling: test:scripts, then run the affected script; GitHub Actions: the PR's own CI plus a trace of the conditional paths CI doesn't exercise), and returns a go/no-go with any required migration surfaced (and applied on request). Majors never automerge (the org Renovate config), so this is the human-review path. Use when a Renovate major PR appears, or before bumping a dependency's major version by hand. Not for patch or minor bumps (those automerge after a soak) or for Jellyfin server releases (use /server-upgrade).

The English summary is being prepared. Showing the original description.

jellyrock/jellyrock46Updated Oct 26, 2026

See all skills by jellyrock

Report a problem with this skill