一键导入
draft-pr
Open a pull request in the browser with prefilled title, description, and labels
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Open a pull request in the browser with prefilled title, description, and labels
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Assess a pending NIST 800-53 control with OSCAL enrichment, CIS reverse lookup, and Linux hardening prioritization. Guides authors through understanding, automatability analysis, rule mapping, and validation.
Resolve XCCDF variable selections for a set of rules. Looks up which variables each rule depends on, reads their .var files, and guides the author to select a value key for each variable. Returns a list of var_name=key selections ready to add to a control file's rules list.
Create a new product in ComplianceAsCode project
Create a template for checks and remediations
Create Automatus test scenarios to test the given rule.
Search for existing rules that match a given requirement text. Identify rules that implement a specific control.
| name | draft-pr |
| description | Open a pull request in the browser with prefilled title, description, and labels |
Analyze the current branch, generate a PR title/description/labels, push to the user's fork, and open the GitHub PR creation page in the browser with everything prefilled.
This skill uses mcp__content-agent__* tools when available (preferred — deterministic, structured results). When the MCP server is not configured, fall back to filesystem-based alternatives noted as Fallback in each step. See .claude/skills/shared/mcp_fallbacks.md for detailed fallback procedures. The skill must complete successfully either way.
Derive upstream repo identifier:
UPSTREAM_REPO=$(git remote get-url origin | sed -n 's|.*[:/]\([^/]*/[^/]*\)\.git$|\1|p; s|.*[:/]\([^/]*/[^/]*\)$|\1|p')
Get current branch and branching point:
git branch --show-current
git merge-base HEAD master
Abort if not on a feature branch:
master, or if merge-base equals HEAD (no diverging commits), inform the user:
"No diverging commits found. Please switch to your feature branch first."Collect commit history (all commits since branching point):
MERGE_BASE=$(git merge-base HEAD master)
git log --no-merges --format="%H %s%n%b---" ${MERGE_BASE}..HEAD
Collect diff information:
MERGE_BASE=$(git merge-base HEAD master)
git diff --stat ${MERGE_BASE}..HEAD
git diff ${MERGE_BASE}..HEAD
git diff --name-only ${MERGE_BASE}..HEAD
Determine which categories apply based on changed files and diff content:
rule.yml added)rule.yml changed)shared/templates/).profile files)controls/)tests/)Look for product indicators:
rule.yml files (cce@rhel8, cce@rhel9, cce@rhel10, etc.)products/<product>/)For significant changed files, use MCP functions to get structured metadata:
mcp__content-agent__get_rule_details with the rule ID to get title, description, rationale, template, severity, references, and platform infomcp__content-agent__get_profile_details with product and profile ID to get profile structure and rule selectionsmcp__content-agent__get_control_details to understand control framework structuremcp__content-agent__get_template_schema to get template parameter infoFallback: Read the files directly — rule.yml, .profile, control YAML, and template files in shared/templates/<name>/.
tests/ subdirectoriesScan commit messages for patterns like Fixes #N, Resolves #N, Closes #N, or bare #N references.
Generate a PR title following project conventions:
Read the PR template for reference:
cat .github/pull_request_template.md
Draft all three sections following the template format exactly:
Auto-generate from analysis:
<rule_id> that . The rule has <severity> severity and targets . It uses the <template> template / includes custom OVAL and <Bash/Ansible/both> remediation."<rule_id> to ."<template_name> to ."Attempt to infer from:
rationale field in rule.ymlIf rationale cannot be fully inferred, include what was found and mark gaps for user input.
Include issue reference if detected in commit messages, otherwise leave a placeholder.
Auto-generate:
./build_product --datastream-only <product>./tests/automatus.py rule --libvirt qemu:///session <product_vm_name> --datastream build/ssg-<product>-ds.xml <rule_id>
Note: Adjust qemu:///session to qemu:///system and <product_vm_name> to the actual VM name based on reviewer's local setup.Write the body to $TMPDIR/pr_body.md. Do NOT write PR_DESCRIPTION.md to the repo root.
Fetch available labels from the repository:
gh label list -R ${UPSTREAM_REPO} --limit 200 --json name --jq '.[].name'
If gh label list fails (e.g., auth issue), skip label inference and tell the user why. Continue to Phase 4 without labels.
Match available labels against the PR content using these heuristics:
rule.yml files were added, look for a "new rule" or similar label.profile files changed, look for a "profiles" labelcontrols/ files changed, look for a "controls" labelshared/templates/ files changed, look for a "templates" labelOnly select labels that actually exist in the fetched label list. Be conservative — pick labels that clearly apply rather than guessing.
Fetch open milestones that look like version numbers:
gh api repos/${UPSTREAM_REPO}/milestones --jq '[.[] | select(.title | test("^[0-9]+\\."))] | sort_by(.title) | reverse'
Apply selection logic:
Store the resolved milestone title (or none) for use in Phase 4.
Verify the fork remote exists:
git remote get-url fork
If this fails, tell the user: "No fork remote found. Add it with: git remote add fork <your-fork-url>" and stop.
Push the branch:
BRANCH=$(git branch --show-current)
git push fork "${BRANCH}"
If the push fails with a non-fast-forward error (e.g., branch was rebased), retry with --force-with-lease:
git push --force-with-lease fork "${BRANCH}"
--force-with-lease is safe — it refuses to overwrite remote commits that you haven't seen locally, preventing accidental data loss while still allowing rebased branches to be pushed.
Construct and run the gh pr create --web command with all prefilled metadata:
BRANCH=$(git branch --show-current)
FORK_OWNER=$(git remote get-url fork | sed -n 's|.*[:/]\([^/]*\)/[^/]*\(\.git\)\{0,1\}$|\1|p')
gh pr create --web \
--repo ${UPSTREAM_REPO} \
--head "${FORK_OWNER}:${BRANCH}" \
--base master \
--title "<generated title>" \
--body-file "$TMPDIR/pr_body.md" \
--label "<label1>" --label "<label2>" \
--milestone "<resolved milestone title>"
Determine FORK_OWNER by parsing the fork remote URL (extract the GitHub username from the URL).
--label flags.--milestone flag.--web combined with other flags fails, fall back to:
--web).xdg-open <pr_url>.Remove the temporary body file:
rm -f "$TMPDIR/pr_body.md"
Tell the user:
gh and git push commands with dangerouslyDisableSandbox: true — gh credentials may be stored in the system keyring, which the sandbox blocks, causing silent 401 auth failures.--no-merges when reading commit log to skip merge commits.github/pull_request_template.mdfork, upstream is origin — determine the upstream repo from git remote get-url originfork remote URL — never hardcode a GitHub username