src/autoskillit/skills_extended/open-integration-pr/SKILL.md
Create an integration PR for the merge-prs. Reads pr_order_file JSON, generates a rich PR body with per-PR details, arch-lens diagrams, and carried-forward Closes #N references. Closes all collapsed PRs with a comment after creation. Use inside the merge-prs after all PRs have been merged into the integration branch.
npx skillsauth add talont-org/autoskillit open-integration-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.
Read pr_order_file JSON produced by analyze-prs, generate a rich PR description
(per-PR details, complexity tags, merge outcomes, optional audit verdict), generate 1–3
arch-lens diagrams, carry forward Closes #N/Fixes #N references from original PR
bodies so linked issues auto-close on merge, create the integration PR via
gh pr create --body-file, close each collapsed PR with a comment referencing the new
PR, and output pr_url=<url>.
/autoskillit:open-integration-pr {batch_branch} {base_branch} {pr_order_file} [audit_verdict] [conflict_report_paths] [domain_partitions_path]
batch_branch — integration branch name (e.g. pr-batch/pr-merge-20250228-143052)base_branch — PR target branch (e.g. main)pr_order_file — absolute path to JSON produced by analyze-prsaudit_verdict (optional) — GO, NO GO, or empty string when audit was skippedconflict_report_paths (optional) — comma-separated list of absolute paths to conflict resolution report files, produced by resolve-merge-conflicts. When provided and non-empty, embed a "Conflict Resolution Decisions" section in the PR body.domain_partitions_path (optional) — absolute path to a JSON file containing pre-computed domain partitions (produced by compute_domain_partitions run_python step). When provided and present, read from file instead of computing via python3.merge-prs after all PRs have been merged into the integration branchrun_skill as the final step before CI watchNEVER:
{{AUTOSKILLIT_TEMP}}/open-integration-pr/ (except the temp body file for gh pr create --body-file)gh is unavailable or not authenticated — output pr_url= (empty) and exit successfullyrun_in_background: true is prohibited)ALWAYS:
gh auth status before attempting any GitHub operationspr_url=<url> on the last output line (empty string when GitHub unavailable)Closes #N and Fixes #N lines found in original PR bodiesgh pr create --body-file (never inline body via --body)Parse four positional args: batch_branch, base_branch, pr_order_file,
audit_verdict (last one may be absent or empty string). Parse the optional fifth
positional argument conflict_report_paths (may be absent or empty string). Split on ,
to get a list of paths; filter out any empty strings. Store as conflict_report_path_list.
Parse the optional named argument domain_partitions_path (may be absent or empty string);
store as domain_partitions_path.
Read the JSON file. Extract: prs array (each: number, title, branch,
complexity, additions, deletions, overlap_with_pr_numbers, files_changed). Also read
base_branch from JSON as confirmation. Store the PR list as pr_list.
Fetch all PR bodies in a single GraphQL alias query (1 API call instead of N sequential REST calls). Chunk into batches of 20 to stay within GraphQL complexity limits.
# Build GraphQL alias query for all PRs
PR_NUMS=($(echo "$pr_list" | jq -r '.[].number'))
BODIES_JSON="{}"
BATCH_SIZE=20
for batch_start in $(seq 0 $BATCH_SIZE $((${#PR_NUMS[@]} - 1))); do
BATCH_NUMS=("${PR_NUMS[@]:$batch_start:$BATCH_SIZE}")
QUERY="query { "
for i in $(seq 0 $((${#BATCH_NUMS[@]} - 1))); do
NUM="${BATCH_NUMS[$i]}"
QUERY="${QUERY} pr${i}: repository(owner: \"${OWNER}\", name: \"${REPO}\") {
pullRequest(number: ${NUM}) { number body }
}"
done
QUERY="${QUERY} }"
BATCH=$(gh api graphql -f query="${QUERY}" 2>/dev/null || echo "{}")
BODIES_JSON=$(echo "${BODIES_JSON} ${BATCH}" | jq -s 'add // {}')
done
Extract every line matching (Closes|Fixes|Resolves)\s+#\d+ (case-insensitive) from
each PR body in BODIES_JSON. Deduplicate across all PRs. Store as closing_refs
(list of strings like Closes #42).
Skip gracefully if gh is unavailable — closing_refs remains empty.
git diff --name-only {base_branch}..{batch_branch}
git diff --diff-filter=A --name-only {base_branch}..{batch_branch}
git diff --diff-filter=M --name-only {base_branch}..{batch_branch}
Store as changed_files, new_files, modified_files.
conflict_report_path_list is empty: skip — set conflict_resolution_table = "".conflict_report_path_list:
## Per-File Resolution Decisions table (all lines from the | File | header
through the last table row).conflict_resolution_table.This step is skipped gracefully if any path is missing — log a warning and exclude that file.
Read pre-computed domain partitions from disk when available:
DOMAIN_PARTITIONS="{}"
if [ -n "${domain_partitions_path:-}" ] && [ -f "$domain_partitions_path" ]; then
DOMAIN_PARTITIONS="$(cat "$domain_partitions_path")"
fi
Store the parsed dict as domain_partitions (parse DOMAIN_PARTITIONS as JSON).
Skip entirely and set domain_partitions = {} if changed_files is empty or
domain_partitions_path is absent.
For each domain name D in domain_partitions where domain_partitions[D] is non-empty,
run the following in parallel (issue all Bash calls in a single message):
git diff {base_branch}..{batch_branch} -- {space-separated list of files in domain D}
Store results as domain_diffs: dict[str, str] mapping domain name → diff text.
If a domain's diff text exceeds 12 000 characters, truncate to the first 12 000 characters
and append \n... [truncated — diff exceeds 12 000 chars]. Domains with empty diffs are
removed from domain_diffs.
For each domain D in domain_partitions, find every PR in pr_list whose
files_changed list intersects with domain_partitions[D].
domain_pr_numbers = {
domain: [
pr["number"]
for pr in pr_list
if set(pr.get("files_changed", [])) & set(domain_partitions[domain])
]
for domain in domain_partitions
}
Store as domain_pr_numbers: dict[str, list[int]].
For each domain D in domain_diffs (domains that actually have diff content), run in
parallel (all Bash calls in a single message):
git log {base_branch}..{batch_branch} --oneline -- {space-separated files in domain D}
Store as domain_commits: dict[str, list[str]] (each entry is a list of "sha message" strings).
Empty results are stored as empty lists.
For each domain D in domain_diffs, spawn a Task subagent (model: sonnet) in a single
parallel message. Issue all Task calls in a single message to maximize parallelism.
Skip domains with no diff content (not in domain_diffs) — do not spawn subagents for them.
Each subagent receives a prompt with:
pr_list)The subagent is instructed to return ONLY a JSON object with this exact shape:
{
"domain": "Server/MCP Tools",
"summary": "3-4 sentence description of what changed and why it matters",
"key_changes": ["concise description of change 1", "concise description of change 2"],
"pr_numbers": [42, 47],
"commit_count": 5
}
Parse each subagent's output as JSON. If parsing fails for a domain, log a warning and
omit that domain from domain_summaries. Store the collected results as
domain_summaries: list[dict].
The 7 canonical domain names are: Server/MCP Tools, Pipeline/Execution, Recipe/Validation, CLI/Workspace, Skills, Tests, Core/Config/Infra.
Spawn a subagent (Task tool, model: sonnet) with changed_files and the same lens
menu as open-pr. Instruct it to return 1–3 lens names using the same development
lens guard.
For each selected lens, follow this exact sequence:
1. Write the PR context to a file using the Write tool:
{{AUTOSKILLIT_TEMP}}/open-integration-pr/pr_arch_lens_context_{YYYY-MM-DD_HHMMSS}.md# PR Context — Changed Files
This diagram is for a Pull Request. Focus the diagram on the areas of the codebase affected by these changes. Do not create a generic whole-project diagram.
## New files (use ★ prefix on these nodes):
{list of new_files from Step 4, or "None"}
## Modified files (use ● prefix on these nodes):
{list of modified_files from Step 4, or "None"}
## Instructions:
- Focus exploration and the diagram on the architectural areas these files belong to
- Use `★` prefix on nodes representing new files/components
- Use `●` prefix on nodes representing modified files/components
- Leave unchanged components unmarked (include them only if needed for context/connectivity)
- The diagram should help PR reviewers understand the architectural impact of these specific changes
2. Immediately call the Skill tool to load the arch-lens skill (e.g., /autoskillit:arch-lens-module-dependency).
The loaded skill will read the PR context file written in step 1 above.
If the Skill tool returns an error containing "disable-model-invocation" or "cannot be used",
do NOT write a diagram freehand. Discard this lens iteration silently. If ALL arch-lens
invocations fail this way, set validated_diagrams = [] (the Architecture Impact section is
omitted per Step 7 behavior).
3. Follow the loaded skill's instructions to explore the codebase and generate the diagram. Using ONLY classDef styles from the mermaid skill (no invented colors).
The arch-lens skills write their output to {{AUTOSKILLIT_TEMP}}/arch-lens-{lens-name}/ (relative to the current working directory). After each skill
runs, read the generated markdown file and extract the mermaid code block(s).
After extracting the mermaid block, inspect its content for ★ or ● characters:
★ or ● → add it to validated_diagrams.Write to {{AUTOSKILLIT_TEMP}}/open-integration-pr/pr_body_{timestamp}.md. (relative to the current working directory)
## Integration Summary
Collapsed {N} PRs into `{batch_branch}` targeting `{base_branch}`.
## Merged PRs
| # | Title | Complexity | Additions | Deletions | Overlaps |
|---|-------|-----------|-----------|-----------|---------|
| #{number} | {title} | {complexity} | +{additions} | -{deletions} | {overlap_with_pr_numbers or "—"} |
...
{If domain_summaries is non-empty:}
## Domain Analysis
{For each entry in domain_summaries (ordered by domain name):}
### {entry.domain}
{entry.summary}
**Key changes:**
{For each item in entry.key_changes:}
- {item}
**Contributing PRs:** {comma-separated #{N} for each N in entry.pr_numbers, or "—" if empty}
**Commits:** {entry.commit_count} commit(s)
{If audit_verdict is non-empty:}
## Audit
**Verdict:** {audit_verdict}
{If conflict_resolution_table is non-empty:}
## Conflict Resolution Decisions
The following files had merge conflicts that were automatically resolved during pipeline integration.
{conflict_resolution_table}
{If validated_diagrams non-empty:}
## Architecture Impact
{For each validated diagram:}
### {Lens Name} Diagram
```mermaid
{diagram content}
{For each item in closing_refs:} {Closes #N}
🤖 Generated with Claude Code via AutoSkillit
### Step 8: Check GitHub Availability
```bash
gh auth status 2>/dev/null
If exit code non-zero: output pr_url= and exit successfully.
gh pr create \
--base {base_branch} \
--head {batch_branch} \
--title "Integration: collapsed PRs #{numbers} into {base_branch}" \
--body-file {{AUTOSKILLIT_TEMP}}/open-integration-pr/pr_body_{timestamp}.md
{numbers} = comma-separated PR numbers (e.g., #42, #47, #51).
Capture the new PR URL as new_pr_url. Extract the PR number from the URL as
new_pr_number.
For each PR in pr_list:
gh pr close {number} --comment "Collapsed into integration PR #{new_pr_number} ({new_pr_url})"
sleep 1 # Rate-limit discipline: 1s between mutating calls
Continue even if individual close operations fail (log warning, do not exit).
pr_url = {new_pr_url}
development
Generate YAML recipes for .autoskillit/recipes/. Use when user says "make script skill", "generate script", "script a workflow", "write a script", "create a script", "new recipe", "write a pipeline", or when loaded by other skills for script formatting.
data-ai
Create Uncertainty Representation visualization planning spec showing error bar definitions, distribution-aware alternatives, and multi-seed variance protocols. Statistical lens answering "How is uncertainty honestly represented?"
data-ai
Create Temporal Dynamics visualization planning spec showing axis scaling (linear vs log), smoothing disclosure, epoch/step alignment, run aggregation (mean + variance bands), early-stopping markers, and wall-clock vs step-count x-axis. Temporal lens answering "Are training dynamics shown clearly and honestly?"
data-ai
Create Narrative Story Arc visualization planning spec showing visual consistency across the report (same color = same model everywhere), logical figure progression, redundant figure detection, and narrative dependency between figures. Narrative lens answering "Do the figures tell a coherent story across the report?"