From cwf
Automates GitHub issue creation, PRs, and merges from validated CWF session artifacts with explicit human control points. Subcommands: /ship issue|pr|merge|status
npx claudepluginhub corca-ai/claude-plugins --plugin cwfThis skill uses the workspace's default tool permissions.
Convert validated CWF session artifacts into issue → PR → merge execution with explicit human merge control.
Creates isolated Git worktrees for feature branches with prioritized directory selection, gitignore safety checks, auto project setup for Node/Python/Rust/Go, and baseline verification.
Executes implementation plans in current session by dispatching fresh subagents per independent task, with two-stage reviews: spec compliance then code quality.
Dispatches parallel agents to independently tackle 2+ tasks like separate test failures or subsystems without shared state or dependencies.
Convert validated CWF session artifacts into issue → PR → merge execution with explicit human merge control.
/ship Show usage
/ship issue [--base B] [--no-branch] Create issue + feature branch
/ship pr [--base B] [--issue N] [--draft] Create PR linked to issue
/ship merge [--squash|--merge|--rebase] Check & merge if ready
/ship status Show open issues, PRs, checks
No args or help → print the usage block above and stop.
main → master (override with --base)--squash (override with --merge or --rebase)Before any subcommand, verify:
command -v gh >/dev/null 2>&1 || { echo "gh CLI not found"; exit 1; }
gh auth status 2>&1 | grep -q "Logged in" || { echo "Not authenticated — run: gh auth login"; exit 1; }
If either fails, do not stop with a passive failure only. Ask the user:
Install/configure now (recommended):
gh is missing, run bash {SKILL_DIR}/../setup/scripts/install-tooling-deps.sh --install ghgh auth loginShow commands only:
Skip ship for now:
For every /ship invocation (issue, pr, merge, status, and help or no-args):
live.dir).{session_dir}/ship.md with these required sections:
## Execution Status## Ambiguity Resolution## Next Step## Ambiguity Resolution, always write these scalar lines:
mode: strict|defer-blocking|defer-reversible|explore-worktreesblocking_open_count: <integer>blocking_issue_refs: <comma-separated refs or none>issue_ref: <issue URL or none>pr_ref: <PR URL or none>merge_allowed: yes|nomode from live state (live.ambiguity_mode) and derive counts from {session_dir}/run-ambiguity-decisions.md if it exists.defer-blocking, merge_allowed must be no when blocking_open_count > 0.issue_ref and pr_ref must contain concrete GitHub URLs before ship-stage closure.bash {CWF_PLUGIN_DIR}/scripts/sync-ambiguity-debt.sh \
--base-dir . \
--session-dir "{session_dir}"
cwf:run, enforce the stage gate:bash {CWF_PLUGIN_DIR}/scripts/check-run-gate-artifacts.sh \
--session-dir "{session_dir}" \
--stage ship \
--strict \
--record-lessons
Create a GitHub issue for the current session and optionally a feature branch.
Detect session context:
.cwf/projects/ (most recent YYMMDD-NN-*)plan.md if it exists for purpose, scope, success criteriamaster-plan.md or similar) for session number{base}:
--base is provided, use itgit symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||'main, then master; if none exists, ask the user for base branch explicitlyCompose issue body:
{SKILL_DIR}/references/issue-template.md{BACKGROUND} — why this work is needed; extract from plan.md context/motivation section, or summarize from session history{PROBLEM} — specific problem being solved; from plan.md or ask the user{GOAL} — desired outcome; from plan.md objectives or ask the user{SCOPE} — files/areas from plan.md or summarize{BRANCH} — the feature branch name to be created{BASE} — the base branch{PLAN_LINK} — relative path to plan.md{RETRO_SUMMARY} — concise retro outcome summary from .cwf/projects/{session}/retro.md
Post-Retro Findings when present_No retro summary recorded yet._{RETRO_PERSIST_PROPOSALS} — actionable persistence proposals from retro/lessons
_No persistence proposal recorded yet._Create issue:
gh issue create \
--title "S{N}: {title}" \
--body "$(cat <<'EOF'
{composed_body}
EOF
)" \
--label "cwf-v3"
cwf-v3 label doesn't exist, create it first:
gh label create cwf-v3 --color 0E8A16 --description "CWF v3 migration"Create feature branch (unless --no-branch):
git checkout {base} && git pull origin {base}
git checkout -b feat/{short-name}
Report: Print issue URL and branch name.
Create a pull request from the current feature branch.
Pre-flight checks (stop with message if any fail):
{base} using the same rule as /ship issuegit log {base}..HEAD --oneline is non-emptygit status --porcelain is empty
Auto-detect linked issue:
--issue N provided, use thatgh issue list --label cwf-v3 --search "S{N}" --json number,titleBuild PR body from {SKILL_DIR}/references/pr-template.md:
{ISSUE_LINK} — Closes #{N} if issue found, otherwise omit{PURPOSE} — synthesize from git log {base}..HEAD --oneline and plan.md;
describe why this change exists, not what files changed{DECISIONS} — extract key decisions from:
.cwf/projects/{session}/lessons.md takeaways.cwf/projects/{session}/retro.md CDM section.cwf/projects/{session}/plan.md decision points| Decision | Rationale | Alternatives | (in user's language){VERIFICATION} — concrete, reproducible verification steps:
claude --plugin-dir ... -p "..."){HUMAN_JUDGMENT} — agent self-assessment of items needing human review:
live.ambiguity_mode and {session_dir}/run-ambiguity-decisions.md when presentdefer-blocking and blocking_open_count > 0, list all open blocking decision debts here (never write None)None (this enables autonomous merge — see /ship merge){SYSTEM_IMPACT} — behavioral changes visible to end users or dependent systems{FUTURE_IMPACT} — impact on future development (new patterns, constraints, tech debt){GIT_DIFF_STAT} — output of git diff {base}...HEAD --stat
wrapped in a ```text code fence{LESSONS} — extract from .cwf/projects/{session}/lessons.md if exists,
otherwise write _No lessons recorded for this session._{CDM} — extract from .cwf/projects/{session}/retro.md CDM section if exists,
otherwise write _No CDM recorded yet._{RETRO_SUMMARY} — concise retro outcome summary from .cwf/projects/{session}/retro.md
Post-Retro Findings when present_No retro summary recorded yet._{RETRO_PERSIST_PROPOSALS} — actionable persistence proposals from retro/lessons
_No persistence proposal recorded yet._{CONDITIONAL_ITEMS} — add checklist items based on changed file types:
*.sh changed → - [ ] Scripts are executable and pass shellcheckSKILL.md changed → - [ ] SKILL.md under 500 linesplugin.json changed → - [ ] Version bumped appropriatelyhooks.json changed → - [ ] Hook matchers are correct*.md changed → - [ ] Markdown lint passesPush and create PR:
git push -u origin $(git branch --show-current)
gh pr create \
--title "S{N}: {title}" \
--body "$(cat <<'EOF'
{composed_body}
EOF
)" \
--base {base}
--draft if the user specified itReport: Print PR URL.
Check PR status and merge if ready.
Find current PR:
gh pr view --json number,state,reviewDecision,statusCheckRollup,mergeable,headRefName
Assess readiness:
Core checks (always required):
state = OPENstatusCheckRollup)mergeable = MERGEABLEReview requirement (conditional):
## Human Judgment Required sectiongh api repos/{owner}/{repo}/branches/{base}/protection 2>&1{session_dir}/run-ambiguity-decisions.md and/or ship.md ambiguity block:
mode: defer-blocking and blocking_open_count > 0, merge is blockedDecision matrix:
| Human judgment | Branch protected | Review required |
|---|---|---|
defer-blocking with open blocking debt | Any | Stop — do not merge |
None or empty | No | Skip — autonomous merge |
None or empty | Yes | reviewDecision = APPROVED required |
| Items listed | Any | Report items, stop — do not merge |
If not ready, report which conditions are blocking and stop. Do not attempt to merge.
Merge:
gh pr merge {N} --squash --delete-branch
--merge or --rebase if the user specified an override--squashPost-merge cleanup:
git checkout {base} && git pull origin {base}
Report: Merge confirmation, deleted branch name.
Read-only overview of current GitHub state.
Open issues:
gh issue list --label cwf-v3 --state open --json number,title,assignees
Open PRs:
gh pr list --json number,title,state,headRefName,reviewDecision,statusCheckRollup
Current branch PR (if exists):
gh pr view --json number,title,state,reviewDecision,mergeable,statusCheckRollup
Session progress (optional):
master-plan.md exists, parse the session roadmapReport: Format as a readable summary table.
| Situation | Action |
|---|---|
gh not installed | Ask whether to install now via setup installer script; if declined/fails, print manual commands and stop |
| Not authenticated | Report, suggest gh auth login, stop |
| No commits ahead of base | Report "nothing to PR", stop |
| Issue already exists for session | Show existing issue, ask user before creating duplicate |
| PR already exists for branch | Show existing PR URL, stop |
| Merge conflicts | Report, suggest git rebase {base} instructions, stop |
Missing lessons.md or retro.md | Use placeholder text, do not fail |
Label cwf-v3 missing | Create it automatically |
| Dirty working tree on PR | Ask user: commit or abort |
When invoked with no args or help, print:
Ship — GitHub workflow automation for cwf sessions
Usage:
/ship Show this message
/ship issue [--base B] [--no-branch] Create issue + feature branch
/ship pr [--base B] [--issue N] [--draft] Create PR
/ship merge [--squash|--merge|--rebase] Merge approved PR
/ship status Show issues, PRs, checks
Defaults: base=auto-detected (origin/HEAD -> main -> master), merge=squash
gh as the primary interface; do not craft raw GitHub API payloads when gh already supports the operation.gh missing, unauthenticated, or invalid branch state).plan.md, lessons.md, retro.md)./ship must always persist {session_dir}/ship.md before returning.defer-blocking mode, unresolved ambiguity debt is merge-blocking until tracked follow-up references are recorded and blocking_open_count is zero.retro outcomes and persistence proposals must be visible in issue/PR body sections, not only hidden in collapsed details blocks.