Runcastle

PR Description Writer

MIT1 downloads

by runcastle

v1.0.0
Homepage ↗

A single Claude Code agent reads the diff and commit history of your branch against its base, then writes a complete, reviewer-ready PR_DESCRIPTION.md — summary, what changed, why, testing, risk, and a reviewer checklist — grounded entirely in the real diff.

Topology

Disclosures

Disclosures — declared side-effect surface

Everything below runs on your machine or inside the sandbox when you use this workflow. Mismatches between these declarations and the actual code block publishing.

Host hooks

Commands executed on YOUR host machine by Sandcastle lifecycle hooks.

None declared.

Sandbox hooks

Commands executed inside the sandbox container.

None declared.

Network access

None. The agent operates only on the local repository inside the sandbox.

Shell expansion

Prompt files contain !`command` blocks — the agent CLI executes these commands at prompt-load time. They are highlighted amber in the prompt files below.

Files

Diff vs the stock Sandcastle 0.12.0 template Dockerfile — green lines were added by the author, red lines were removed from stock.

+# Sandbox image for the PR Description Writer workflow.
+# Mirrors the stock Sandcastle template: Node 22, git (the prompt diffs branches),
+# and the Claude Code CLI, running as a non-root `agent` user.
FROM node:22-bookworm
-# System dependencies.
+# System dependencies. `git` powers the diff/log shell-expansion blocks.
RUN apt-get update && apt-get install -y --no-install-recommends \
git \
curl \
jq \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# Claude Code CLI (the agent runtime).
RUN npm install -g @anthropic-ai/claude-code
# Non-root agent user. `sandcastle docker build-image` aligns AGENT_UID/GID to
# the host user via --build-arg to avoid permission errors on bind mounts.
ARG AGENT_UID=1000
ARG AGENT_GID=1000
RUN groupadd --gid ${AGENT_GID} agent \
&& useradd --uid ${AGENT_UID} --gid ${AGENT_GID} --create-home --shell /bin/bash agent
USER agent
WORKDIR /workspace
Show full Dockerfile (highlighted)
# Sandbox image for the PR Description Writer workflow.
# Mirrors the stock Sandcastle template: Node 22, git (the prompt diffs branches),
# and the Claude Code CLI, running as a non-root `agent` user.
FROM node:22-bookworm

# System dependencies. `git` powers the diff/log shell-expansion blocks.
RUN apt-get update && apt-get install -y --no-install-recommends \
      git \
      curl \
      jq \
      ca-certificates \
 && rm -rf /var/lib/apt/lists/*

# Claude Code CLI (the agent runtime).
RUN npm install -g @anthropic-ai/claude-code

# Non-root agent user. `sandcastle docker build-image` aligns AGENT_UID/GID to
# the host user via --build-arg to avoid permission errors on bind mounts.
ARG AGENT_UID=1000
ARG AGENT_GID=1000
RUN groupadd --gid ${AGENT_GID} agent \
 && useradd --uid ${AGENT_UID} --gid ${AGENT_GID} --create-home --shell /bin/bash agent

USER agent
WORKDIR /workspace

README

PR Description Writer

Stop writing pull request descriptions from scratch. Point this workflow at your branch and it produces a complete, reviewer-ready PR_DESCRIPTION.md — grounded entirely in the real diff, not in vague guesses about what you "probably" changed.

What it does

A single Claude Code agent reads the commit history and the full diff between your branch and its base, then writes a structured description with six sections:

  • Summary — the ten-second version a reviewer reads first.
  • What changed — a tight, grouped list of the concrete changes.
  • Why — the motivation and context behind the change.
  • Testing — how it was or should be verified.
  • Risk & rollout — blast radius, migrations, and what to scrutinize.
  • Reviewer checklist — a checkbox list to run before merging.

Because it works from the actual diff, it won't invent changes that aren't there — and it will honestly flag anything in the diff that looks risky or incomplete.

How it works

main.ts runs one Sonnet agent for a single pass (maxIterations: 1). The prompt seeds the model with !`git log {{BASE_BRANCH}}..HEAD --oneline` and !`git diff {{BASE_BRANCH}}...HEAD` shell-expansion blocks — which is why the manifest discloses shell expansion. BASE_BRANCH is passed as a prompt argument and defaults to main; change it at the top of main.ts for release or develop branches. The topology is a single node: diff + log → PR description. Nothing leaves the sandbox — there is no network access.

Requirements

Set CLAUDE_CODE_OAUTH_TOKEN in .sandcastle/.env (run claude setup-token). Check out the branch you want documented and set BASE_BRANCH in .sandcastle/main.ts if it isn't main. Build the image once with npx @ai-hero/sandcastle docker build-image, then run npx tsx .sandcastle/main.ts. The finished description lands at PR_DESCRIPTION.md, ready to paste into your PR.