con un clic
issue-close
イシュー完了時に使用。PRマージ・worktree削除・ブランチ安全削除を一括実行
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Menú
イシュー完了時に使用。PRマージ・worktree削除・ブランチ安全削除を一括実行
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Basado en la clasificación ocupacional SOC
dev workflow 向けの最終チェック。PR 前に品質ゲート、docs 整合、設計書昇格、Issue 更新をまとめて確認する。
docs-only workflow 向けの最終チェック。docs 整合と Issue 状態を確認し、PR に進めるか判定する。
docs review の指摘に対応し、ドキュメントのみを修正する。コードやテストは変更しない。
docs-only の変更をレビューし、事実整合性・実装整合性・運用整合性の観点から判定する。
docs-only の更新を行う。コードやテストは変更せず、現行実装・CLI・運用方針との整合を確認しながら docs を修正する。
docs review の指摘が適切に修正されたかを確認する。新規指摘は行わない。
| description | イシュー完了時に使用。PRマージ・worktree削除・ブランチ安全削除を一括実行 |
| name | issue-close |
イシュー対応完了後のクリーンアップを実行します。 PR マージ、worktree 削除、ブランチ削除、Issue クローズを一括実行します。
| タイミング | このスキルを使用 |
|---|---|
| PRがApproveされマージ可能 | ✅ 使用 |
| PRレビュー待ち | ❌ 待機 |
| 作業途中 | ❌ 不要 |
ワークフロー内の位置: implement → review-code → i-dev-final-check → i-pr → close
常に注入される変数:
| 変数 | 型 | 説明 |
|---|---|---|
issue_id | str | 正規化済み Issue ID(GitHub 数値または local ID) |
issue_ref | str | 人間可読の Issue 参照(GitHub では #<issue_id>、local では bare ID) |
step_id | str | 現在のステップ ID |
provider 解決時に追加で注入される変数:
| 変数 | 型 | 説明 |
|---|---|---|
provider_type | str | github / local のいずれか。本 Skill の経路分岐に使用 |
default_branch | str | ベースブランチ名(main 等)。local 経路で merge / push の引数に使用 |
branch_name | str | フィーチャーブランチ名(feat/<id> 等) |
worktree_dir | str | worktree 絶対パス |
$ARGUMENTS = <issue_id>
コンテキスト変数 issue_id が存在すればそちらを使用。
なければ $ARGUMENTS の第1引数を issue_id として使用。
issue_ref はハーネス経由ではプロンプトに自動注入される(provider 別に整形済み)。手動実行時は issue_id から導出する: GitHub 数値 ID なら #<issue_id>、local-* 形式なら bare ID(# を付けない)。
/i-pr でPRが作成済みであること[provider_type] に応じて手順が分岐する。
[provider_type] が github(または未注入の legacy 環境)→ 既存の
Step 1〜6 を順に実行する(uv run kaji pr merge / worktree 削除 / branch 削除 /
git pull / uv run kaji issue close / 報告)。[provider_type] が local → 後述の provider=local の場合 セクションへ
ジャンプし、local 用の手順 (6 step) を実行する。
github 用の Step 1〜6 は実行しない(PR 概念が無いため)。Issue本文からWorktree情報を取得します:
uv run kaji issue view [issue_id] --json body -q '.body'
以下の情報を抽出:
> **Worktree**: \../[worktree_dirname]` → worktree パス(/issue-start` が記録した値)> **Branch**: \[prefix]/[issue_id]`` → ブランチ名git worktree list の最初の行が常に main worktree(bare repository のルート)を示す:
MAIN_REPO=$(git worktree list | head -1 | awk '{print $1}')
注意:
git rev-parse --show-toplevelは現在の worktree のルートを返すため、 worktree 内から実行すると main repo を取得できない。必ずgit worktree listを使うこと。
worktree 内にいる場合は main repo に移動:
cd "$MAIN_REPO"
uv run kaji pr merge [branch_name]
マージコミットを作成してブランチ履歴を保持する。ブランチ削除は worktree 削除後に Step 4.5 で行う。
結果を記録:
pr_merge_result= 「マージ済み」。この値は Step 6 で使用する。
git worktree remove "$MAIN_REPO/../[worktree_dirname]"
$MAIN_REPOは Step 2 で取得済み。
結果を記録:
worktree_result= 「削除済み」。この値は Step 6 で使用する。
worktree 削除後にローカル・リモートブランチを削除する。
git fetch [git_remote] で [git_remote]/[default_branch] を最新化してから、merge-base --is-ancestor でマージ済み判定を行い、安全に削除する。
ローカル削除とリモート削除は独立して実行し、片方の失敗がもう片方をブロックしない。
ブランチが既に存在しない場合はスキップする。
# 1. fetch して [git_remote]/[default_branch] を更新
git fetch [git_remote]
# 2. ローカルブランチ削除: 存在確認 → マージ済み判定 → 安全な -D
if git show-ref --verify --quiet refs/heads/[branch_name]; then
if git merge-base --is-ancestor [branch_name] [git_remote]/[default_branch]; then
git branch -D [branch_name]
else
echo "WARNING: branch not merged into [git_remote]/[default_branch], skipping local delete"
fi
fi
# 3. リモートブランチ削除(ローカル削除の成否に依存しない)
git ls-remote --exit-code --heads [git_remote] [branch_name] >/dev/null 2>&1
LS_EXIT=$?
if [ "$LS_EXIT" -eq 0 ]; then
if ! git push [git_remote] --delete [branch_name]; then
echo "ERROR: git push [git_remote] --delete failed"
exit 1
fi
elif [ "$LS_EXIT" -eq 2 ]; then
echo "INFO: remote branch already deleted"
else
echo "ERROR: git ls-remote failed (exit $LS_EXIT)"
exit 1
fi
# 4. stale remote-tracking ref を掃除
git fetch --prune [git_remote]
結果を記録:
local_branch_result= 「削除済み」/「未存在を確認」/「未マージのためスキップ」remote_branch_result= 「削除済み」/「未存在を確認」/「削除失敗(要手動対応)」これらの値は Step 6 で使用する。
git pull [git_remote] [default_branch]
結果を記録:
pull_result= 「最新化済み」。この値は Step 6 で使用する。
uv run kaji issue close [issue_id] --reason completed
結果を記録:
close_result= 「クローズ済み」/「クローズ失敗(要手動対応)」。この値は Step 6 で使用する。重要:
uv run kaji issue closeが失敗した場合は verdict を ABORT にすること。Issue が未クローズのまま残ることは許容しない。
Step 3〜5.5 の結果を使って、stdout への報告と Issue タイムラインへのコメント投稿の両方を行う。
各ステップで記録した結果変数を使い、コメント内容を動的に組み立てて投稿する:
uv run kaji issue comment [issue_id] --commit --body-file - <<'COMMENT_EOF'
## Issue クローズ完了
| 項目 | 状態 |
|------|------|
| PR | [pr_merge_result] |
| worktree | [worktree_result] |
| ローカルブランチ | [local_branch_result] |
| リモートブランチ | [remote_branch_result] |
| main | [pull_result] |
| Issue | [close_result] |
COMMENT_EOF
[pr_merge_result]等のプレースホルダーは、実際の実行結果に置き換えること。ハードコードしない。
以下の形式で報告してください:
## Issue クローズ完了
| 項目 | 状態 |
|------|------|
| Issue | [issue_ref] |
| PR | [pr_merge_result] |
| worktree | [worktree_result] |
| ローカルブランチ | [local_branch_result] |
| リモートブランチ | [remote_branch_result] |
| main | [pull_result] |
| Issue 状態 | [close_result] |
[provider_type] が local のとき、PR 概念が無いため
以下の local 用手順 (6 step) を実行する。
重要 (worktree 運用): bare repository + worktree パターンでは
[default_branch]は feature worktree とは別の worktree(通常 main repo 側) で checkout されている。そのため merge / close commit は base worktree 側 で実行し、feature worktree ([worktree_dir]) はその後で削除する。 feature worktree 内でgit switch [default_branch]を実行しても、別 worktree がそのブランチを保持しているため Git に拒否される。
cd [worktree_dir]
test -z "$(git status --porcelain)" || { echo "ABORT: uncommitted changes in [worktree_dir]"; exit 1; }
git rev-parse --abbrev-ref HEAD | grep -qE "^[a-z]+/local-[a-z0-9]+-[0-9]+(-[a-z0-9-]+)?$" || { echo "ABORT: not on feature branch"; exit 1; }
未コミット変更 / feature ブランチ外なら ABORT。
git worktree list --porcelain から [default_branch] を checkout している
worktree を抽出する。見つからなければ user が手動で base 側を準備する必要が
あるため ABORT。
# [default_branch] を checkout している worktree を取得
BASE_WT=$(git worktree list --porcelain | awk -v b="[default_branch]" '
/^worktree / { wt=$2 }
$0 == "branch refs/heads/" b { print wt; exit }
')
test -n "$BASE_WT" || { echo "ABORT: no worktree has [default_branch] checked out. Run 'git worktree add <path> [default_branch]' or 'git switch [default_branch]' in your main checkout first."; exit 1; }
cd "$BASE_WT"
# Step 2.1: 3 段ガードによる救済 commit 判定
#
# 標準動線(各 skill での `uv run kaji issue {comment,edit} --commit`)が機能していれば
# base worktree は clean。蓄積が残っている場合は LocalProvider 永続化由来の path
# のみ救済し、それ以外は ABORT する。
#
# 救済対象 (LocalProvider 命名規則):
# - .kaji/issues/<issue_id>-<slug>/issue.md
# - .kaji/issues/<issue_id>-<slug>/comments/<4桁seq>-<machine_id>.md
DIRTY=$(git status --porcelain)
if [ -n "$DIRTY" ]; then
# 条件 1: dirty path がすべて [issue_id] の永続化 whitelist に一致するか検査
ISSUE_DIR_RE='^\.kaji/issues/[issue_id]-[a-z0-9-]+/(issue\.md|comments/[0-9]{4}-[a-z0-9]{1,16}\.md)$'
UNRELATED=$(printf '%s\n' "$DIRTY" | awk -v re="$ISSUE_DIR_RE" '
{
# rename / copy ("R old -> new") は救済対象外として ABORT に倒す
if (match($0, /->/)) { print; next }
# 先頭 3 文字 (status + space) を除いた残りを path として扱う
path = substr($0, 4)
# quoted path (path に空白等あり) は対応外として ABORT
if (substr(path, 1, 1) == "\"") { print; next }
if (path !~ re) { print }
}
')
if [ -n "$UNRELATED" ]; then
echo "ABORT: dirty files outside LocalProvider persistence whitelist in base worktree $BASE_WT:"
printf '%s\n' "$UNRELATED"
echo " Allowed pattern: $ISSUE_DIR_RE"
exit 1
fi
# 条件 2: whitelist 命名規則の glob で限定 add + atomic commit
# - `comments/` ディレクトリ全体を add してはならない (note.txt 等を巻き込む)
# - `git commit --only` で他の staged change を HEAD に混入させない
git add \
".kaji/issues/[issue_id]-"*"/issue.md" \
".kaji/issues/[issue_id]-"*"/comments/"[0-9][0-9][0-9][0-9]-*.md \
2>/dev/null || true
git commit --only \
-m "chore(local): salvage uncommitted issue files for [issue_ref]" \
-- \
".kaji/issues/[issue_id]-"*"/issue.md" \
".kaji/issues/[issue_id]-"*"/comments/"[0-9][0-9][0-9][0-9]-*.md \
|| { echo "ABORT: salvage commit failed"; exit 1; }
# 条件 3: 救済後の残差を再検証 (rename/copy/rm 等の取りこぼしを検出)
test -z "$(git status --porcelain)" || {
echo "ABORT: residual dirty files after salvage commit in base worktree $BASE_WT:"
git status --porcelain
exit 1
}
fi
# remote 設定がある場合のみ fetch + ff-only merge。
# fetch 失敗 (network 断 / 認証エラー / suspended account 等) は WARNING で skip し、
# local-only で close を完結させる (Step 6 の push も同様に warning で続行する設計と整合)。
# `uv run kaji run` 非対話モードでは AskUserQuestion 経由のリカバリ不可のため、
# deterministic に local fallback すること。手動 push は remote 復旧後に実施。
if git remote get-url [git_remote] >/dev/null 2>&1; then
if git fetch [git_remote] [default_branch] 2>&1; then
git merge --ff-only "[git_remote]/[default_branch]" || { echo "ABORT: ff-only merge failed in base worktree"; exit 1; }
else
echo "WARNING: git fetch [git_remote] [default_branch] failed; proceeding with local-only close (manual push needed after remote recovery)"
fi
fi
ABORT 条件:
WARNING 継続条件:
git fetch 失敗 (remote 到達不可 / 認証失敗) → local merge は実行、push は Step 6 で warning skip標準動線で各 skill が uv run kaji issue {comment,edit} --commit を使っていれば、ここまで到達した時点で
base worktree は clean のはず。救済 commit は標準動線が機能しなかった場合の安全装置として残す。
git merge --no-ff --no-edit [branch_name] || { echo "ABORT: merge conflict, resolve manually in $BASE_WT then retry"; exit 1; }
衝突したら ABORT。Issue は open のまま、user が手動 resolve した後で再実行する。
uv run kaji issue close [issue_id] --reason completed
git add .kaji/issues/[issue_id]-*/issue.md
git commit -m "chore(issue): close [issue_ref]" || { echo "ABORT: commit failed"; exit 1; }
--reason completed は明示で書く(kaji 側の default も
completed だが、Skill markdown 上で明示することで読み手の予期外を減らす)。
Step 4 完了で Issue close は確定。以降の失敗は警告のみ。
base worktree に居る状態で feature worktree を削除する。cwd == 削除対象 を
回避するため、Step 2 の cd "$BASE_WT" は維持したまま実行する。
git worktree remove [worktree_dir] || echo "WARNING: worktree remove failed for [worktree_dir]; manual cleanup needed"
git branch -d [branch_name] || echo "WARNING: branch delete failed for [branch_name]; manual cleanup needed"
if git remote get-url [git_remote] >/dev/null 2>&1; then
git push [git_remote] [default_branch] || echo "WARNING: push failed; manual push needed"
fi
実行完了後、以下の形式で verdict を出力すること:
---VERDICT---
status: PASS
reason: |
クローズ完了
evidence: |
PR マージ・worktree 削除・main 最新化・Issue クローズ済み
suggestion: |
---END_VERDICT---
重要: verdict は stdout にそのまま出力 すること。Issue コメントや Issue 本文更新とは別に、最終的な verdict ブロックは stdout に残す。
| status | 条件 |
|---|---|
| PASS | クローズ完了 |
| ABORT | クローズ失敗(uv run kaji issue close 失敗を含む / local merge 衝突) |