@wbern/claude-instructions 1.10.0 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -221,7 +221,7 @@ flowchart TB
221
221
 
222
222
  ### Worktree Management
223
223
 
224
- - `/worktree-add` - Add a new git worktree from branch name or GitHub issue URL, copy settings, install deps, and open in current IDE
224
+ - `/worktree-add` - Add a new git worktree from branch name or issue URL, copy settings, install deps, and open in current IDE
225
225
  - `/worktree-cleanup` - Clean up merged worktrees by verifying PR/issue status, consolidating settings, and removing stale worktrees
226
226
 
227
227
  ### Utilities
package/bin/cli.js CHANGED
@@ -548,19 +548,31 @@ function extractLabelFromTool(tool) {
548
548
  const match = tool.match(/^Bash\(([^:]+):/);
549
549
  return match ? match[1] : tool;
550
550
  }
551
+ function formatCommandsHint(commands) {
552
+ if (commands.length <= 2) {
553
+ return commands.map((c) => `/${c}`).join(", ");
554
+ }
555
+ const first = commands.slice(0, 2).map((c) => `/${c}`);
556
+ const remaining = commands.length - 2;
557
+ return `${first.join(", ")}, and ${remaining} ${remaining === 1 ? "other" : "others"}`;
558
+ }
551
559
  async function getRequestedToolsOptions(variant) {
552
560
  const metadata = await loadCommandsMetadata(variant);
553
- const allTools = /* @__PURE__ */ new Set();
554
- for (const data of Object.values(metadata)) {
561
+ const toolToCommands = /* @__PURE__ */ new Map();
562
+ for (const [filename, data] of Object.entries(metadata)) {
555
563
  if (data["_requested-tools"]) {
564
+ const commandName = filename.replace(/\.md$/, "");
556
565
  for (const tool of data["_requested-tools"]) {
557
- allTools.add(tool);
566
+ const commands = toolToCommands.get(tool) || [];
567
+ commands.push(commandName);
568
+ toolToCommands.set(tool, commands);
558
569
  }
559
570
  }
560
571
  }
561
- return Array.from(allTools).map((tool) => ({
572
+ return Array.from(toolToCommands.entries()).map(([tool, commands]) => ({
562
573
  value: tool,
563
- label: extractLabelFromTool(tool)
574
+ label: extractLabelFromTool(tool),
575
+ hint: formatCommandsHint(commands)
564
576
  }));
565
577
  }
566
578
  function getDestinationPath(outputPath, scope) {
@@ -894,7 +906,8 @@ async function main(args) {
894
906
  if (requestedToolsOptions.length > 0) {
895
907
  selectedAllowedTools = await multiselect({
896
908
  message: "Select allowed tools for commands (optional)",
897
- options: requestedToolsOptions
909
+ options: requestedToolsOptions,
910
+ required: false
898
911
  });
899
912
  if (isCancel(selectedAllowedTools)) {
900
913
  return;
@@ -907,21 +920,58 @@ async function main(args) {
907
920
  });
908
921
  const skipFiles = [];
909
922
  if (!args?.overwrite && !args?.skipOnConflict) {
923
+ const conflictingFiles = existingFiles.filter((f) => !f.isIdentical);
924
+ const hasMultipleConflicts = conflictingFiles.length > 1;
925
+ let overwriteAllSelected = false;
926
+ let skipAllSelected = false;
910
927
  for (const file of existingFiles) {
911
928
  if (file.isIdentical) {
912
929
  log.info(`${file.filename} is identical, skipping`);
913
930
  skipFiles.push(file.filename);
914
931
  continue;
915
932
  }
933
+ if (overwriteAllSelected) {
934
+ continue;
935
+ }
936
+ if (skipAllSelected) {
937
+ skipFiles.push(file.filename);
938
+ continue;
939
+ }
916
940
  const stats = getDiffStats(file.existingContent, file.newContent);
917
941
  const diff = formatCompactDiff(file.existingContent, file.newContent);
918
942
  note(diff, `Diff: ${file.filename}`);
919
943
  log.info(`+${stats.added} -${stats.removed}`);
920
- const shouldOverwrite = await confirm({
921
- message: `Overwrite ${file.filename}?`
922
- });
923
- if (!shouldOverwrite) {
924
- skipFiles.push(file.filename);
944
+ if (hasMultipleConflicts) {
945
+ const choice = await select({
946
+ message: `Overwrite ${file.filename}?`,
947
+ options: [
948
+ { value: "yes", label: "Yes" },
949
+ { value: "no", label: "No" },
950
+ { value: "overwrite_all", label: "Overwrite all" },
951
+ { value: "skip_all", label: "Skip all" }
952
+ ]
953
+ });
954
+ if (isCancel(choice)) {
955
+ return;
956
+ }
957
+ if (choice === "no") {
958
+ skipFiles.push(file.filename);
959
+ } else if (choice === "overwrite_all") {
960
+ overwriteAllSelected = true;
961
+ } else if (choice === "skip_all") {
962
+ skipAllSelected = true;
963
+ skipFiles.push(file.filename);
964
+ }
965
+ } else {
966
+ const shouldOverwrite = await confirm({
967
+ message: `Overwrite ${file.filename}?`
968
+ });
969
+ if (isCancel(shouldOverwrite)) {
970
+ return;
971
+ }
972
+ if (!shouldOverwrite) {
973
+ skipFiles.push(file.filename);
974
+ }
925
975
  }
926
976
  }
927
977
  } else if (args?.skipOnConflict) {
@@ -125,7 +125,7 @@
125
125
  "order": 1
126
126
  },
127
127
  "worktree-add.md": {
128
- "description": "Add a new git worktree from branch name or GitHub issue URL, copy settings, install deps, and open in current IDE",
128
+ "description": "Add a new git worktree from branch name or issue URL, copy settings, install deps, and open in current IDE",
129
129
  "hint": "Add worktree",
130
130
  "category": "Worktree Management",
131
131
  "order": 1
@@ -1,6 +1,6 @@
1
1
  ---
2
- description: Add a new git worktree from branch name or GitHub issue URL, copy settings, install deps, and open in current IDE
3
- argument-hint: <branch-name-or-github-issue-url> [optional-base-branch]
2
+ description: Add a new git worktree from branch name or issue URL, copy settings, install deps, and open in current IDE
3
+ argument-hint: <branch-name-or-issue-url> [optional-base-branch]
4
4
  ---
5
5
 
6
6
  # Git Worktree Setup
@@ -18,31 +18,37 @@ Beads is available for task tracking. Use `mcp__beads__*` tools to manage issues
18
18
  Create a new git worktree for branch: $ARGUMENTS
19
19
 
20
20
  <current_state>
21
- Current branch: !git branch --show-current`
22
- Current worktrees: !git worktree list`
23
- Remote branches: !git branch -r`
24
- Uncommitted changes: !git status --short`
21
+ Current branch: `git branch --show-current`
22
+ Current worktrees: `git worktree list`
23
+ Remote branches: `git branch -r`
24
+ Uncommitted changes: `git status --short`
25
25
  </current_state>
26
26
 
27
27
  <execution_steps>
28
28
  <step_0>
29
- <description>Validate MCP dependencies</description>
30
- <check_github_mcp>
31
- <requirement>GitHub MCP server must be configured</requirement>
32
- <fallback>If unavailable, use `gh` CLI commands</fallback>
33
- <validation>
34
- - Try listing available MCP resources
35
- - If GitHub MCP not found, switch to CLI fallback
36
- - Inform user about MCP configuration if needed
37
- </validation>
38
- </check_github_mcp>
39
- <error_handling>
40
- If MCP validation fails:
41
- - Show clear error message
42
- - Provide setup instructions
43
- - Fallback to CLI if possible
44
- </error_handling>
45
- <purpose>Ensure required MCP dependencies are available before proceeding</purpose>
29
+ <description>Detect git hosting provider and available tools (only needed if argument is an issue URL)</description>
30
+ <condition>Only run this step if first argument looks like a git hosting URL</condition>
31
+ <detect_provider>
32
+ <check_remote_url>git remote get-url origin</check_remote_url>
33
+ <identify_host>
34
+ - github.com GitHub
35
+ - gitlab.com GitLab
36
+ - bitbucket.org Bitbucket
37
+ - Other → Ask user
38
+ </identify_host>
39
+ </detect_provider>
40
+ <check_available_tools>
41
+ <list_mcp_servers>Check which git-hosting MCP servers are available (github, gitlab, etc.)</list_mcp_servers>
42
+ <check_cli>Check if gh/glab CLI is available as fallback</check_cli>
43
+ </check_available_tools>
44
+ <select_tool>
45
+ <if_single_mcp>If only one relevant MCP available, confirm with user</if_single_mcp>
46
+ <if_multiple>Let user choose which tool to use</if_multiple>
47
+ <if_told_earlier>If user specified tool earlier in conversation, use that without asking again</if_told_earlier>
48
+ <store_as>$GIT_HOST_TOOL (e.g., "github_mcp", "gitlab_mcp", "gh_cli")</store_as>
49
+ </select_tool>
50
+
51
+ <purpose>Detect git hosting provider and select appropriate tool for issue lookup</purpose>
46
52
  </step_0>
47
53
 
48
54
  <step_1>
@@ -70,30 +76,41 @@ Uncommitted changes: !git status --short`
70
76
  </step_1>
71
77
 
72
78
  <step_2>
73
- <description>Parse the arguments</description>
79
+ <description>Determine default branch and parse arguments</description>
80
+ <find_default_branch>
81
+ <command>git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'</command>
82
+ <fallback>git remote show origin | grep 'HEAD branch' | cut -d: -f2 | tr -d ' '</fallback>
83
+ <store_as>$DEFAULT_BRANCH (typically "main" or "master")</store_as>
84
+ </find_default_branch>
74
85
  <input>The user-provided arguments</input>
75
- <expected_format>branch-name-or-github-url [optional-base-branch]</expected_format>
86
+ <expected_format>branch-name-or-issue-url [optional-base-branch]</expected_format>
76
87
  <example>fix/issue-123-main-content-area-visually-clipped main</example>
77
- <example_github_url><https://github.com/owner/project/issues/123> main</example_github_url>
78
- <default_base_branch>main (if not specified)</default_base_branch>
79
- </step_1>
88
+ <example_issue_url>https://github.com/owner/project/issues/123 main</example_issue_url>
89
+ <base_branch>Use provided base branch, or $DEFAULT_BRANCH if not specified</base_branch>
90
+ </step_2>
80
91
 
81
92
  <step_2_5>
82
- <description>Handle GitHub issue URLs</description>
83
- <condition>If first argument matches GitHub issue URL pattern</condition>
84
- <url_detection>Check if argument contains "github.com" and "/issues/"</url_detection>
93
+ <description>Handle issue URLs from git hosting provider</description>
94
+ <condition>If first argument matches issue URL pattern (detected in step_0)</condition>
95
+ <url_detection>
96
+ <github>Check if argument contains "github.com" and "/issues/"</github>
97
+ <gitlab>Check if argument contains "gitlab.com" and "/-/issues/"</gitlab>
98
+ <bitbucket>Check if argument contains "bitbucket.org" and "/issues/"</bitbucket>
99
+ </url_detection>
85
100
  <url_parsing>
86
- <pattern>https://github.com/{owner}/{repo}/issues/{issue_number}</pattern>
101
+ <github_pattern><https://github.com/{owner}/{repo}/issues/{issue_number}></github_pattern>
102
+ <gitlab_pattern><https://gitlab.com/{owner}/{repo}/-/issues/{issue_number}></gitlab_pattern>
103
+ <bitbucket_pattern><https://bitbucket.org/{owner}/{repo}/issues/{issue_number}></bitbucket_pattern>
87
104
  <extract>owner, repo, issue_number from URL</extract>
88
105
  </url_parsing>
89
106
  <fetch_issue_details>
90
- <tool>mcp__github__issue_read</tool>
91
- <method>get</method>
107
+ <tool>Use $GIT_HOST_TOOL from step_0</tool>
108
+ <method>get issue details</method>
92
109
  <parameters>owner, repo, issue_number</parameters>
93
110
  </fetch_issue_details>
94
111
  <generate_branch_name>
95
112
  <determine_type>Analyze issue title/labels to determine type (feat/fix/refactor/chore)</determine_type>
96
- <format>{type}/{repo}-{issue_number}-{kebab-case-title}</format>
113
+ <format>{type}/issue-{issue_number}-{kebab-case-title}</format>
97
114
  <kebab_case>Convert title to lowercase, replace spaces/special chars with hyphens</kebab_case>
98
115
  <sanitization>
99
116
  <rule>Always use lowercase for branch names</rule>
@@ -116,12 +133,12 @@ Uncommitted changes: !git status --short`
116
133
  <title>"Fix duplicate items in list view"</title>
117
134
  <generated>fix/issue-456-duplicate-items-in-list-view</generated>
118
135
  </examples>
119
- </step_1_5>
136
+ </step_2_5>
120
137
 
121
138
  <step_3>
122
139
  <description>Add all files and stash uncommitted changes if any exist</description>
123
140
  <condition>If output is not empty (has uncommitted changes)</condition>
124
- <command>git add -A && git stash push -m "Worktree switch: Moving changes to ${branch_name}"</chained_command>
141
+ <command>git add -A && git stash push -m "Worktree switch: Moving changes to ${branch_name}"</command>
125
142
  <purpose>Preserve work in progress before switching worktrees</purpose>
126
143
  <note>Remember stash was created for later restoration</note>
127
144
  </step_3>
@@ -140,20 +157,20 @@ Uncommitted changes: !git status --short`
140
157
  <step_5>
141
158
  <description>Fetch latest changes from remote</description>
142
159
  <command>git fetch origin</command>
143
- <purpose>Ensure we have the latest remote branches and main branch state</purpose>
144
- <note>This ensures new worktrees are created from the most recent main branch</note>
145
- </step_6>
160
+ <purpose>Ensure we have the latest remote branches and default branch state</purpose>
161
+ <note>This ensures new worktrees are created from the most recent default branch</note>
162
+ </step_5>
146
163
 
147
- <step_7>
164
+ <step_6>
148
165
  <description>Check if branch exists on remote</description>
149
166
  <command>git branch -r | grep "origin/${branch_name}"</command>
150
167
  <decision>
151
168
  <if_exists>Branch exists on remote - will checkout existing branch</if_exists>
152
169
  <if_not_exists>Branch does not exist - will create new branch from base</if_not_exists>
153
170
  </decision>
154
- </step_5>
171
+ </step_6>
155
172
 
156
- <step_6>
173
+ <step_7>
157
174
  <description>Create the worktree</description>
158
175
  <option_a_new_branch>
159
176
  <condition>Remote branch does NOT exist</condition>
@@ -247,7 +264,7 @@ EOF</create_file_command>
247
264
  </ide_specific_behavior>
248
265
  <purpose>Launch development environment for the new worktree using detected IDE</purpose>
249
266
  <confirmation_message>Opening worktree in ${ide_name}</confirmation_message>
250
- </step_11>
267
+ </step_13>
251
268
  </execution_steps>
252
269
 
253
270
  <important_notes>
@@ -262,4 +279,11 @@ EOF</create_file_command>
262
279
  - Uncommitted changes are automatically stashed and moved to the new worktree
263
280
  - Your work-in-progress seamlessly transfers to the new branch
264
281
  - IDE detection fallback: checks available editors and uses priority order
282
+
283
+ Limitations:
284
+
285
+ - Assumes remote is named "origin" (most common convention)
286
+ - Supports macOS and Linux only (no Windows support)
287
+ - Requires MCP server or CLI for git hosting provider when using issue URLs (GitHub, GitLab, etc.)
288
+ - Dependency install command is pnpm (modify for npm/yarn if needed)
265
289
  </important_notes>
@@ -20,54 +20,71 @@ Clean up merged worktrees by finding the oldest merged branch, consolidating set
20
20
  Additional info: $ARGUMENTS
21
21
 
22
22
  <current_state>
23
- Current branch: !git branch --show-current`
24
- Current worktrees: !git worktree list`
23
+ Current branch: `git branch --show-current`
24
+ Current worktrees: `git worktree list`
25
25
  </current_state>
26
26
 
27
27
  <execution_steps>
28
28
  <step_0>
29
- <description>Validate MCP dependencies</description>
30
- <check_github_mcp>
31
- <requirement>GitHub MCP server must be configured</requirement>
32
- <fallback>If unavailable, use `gh` CLI commands</fallback>
33
- <validation>
34
- - Try listing available MCP resources
35
- - If GitHub MCP not found, switch to CLI fallback
36
- - Inform user about MCP configuration if needed
37
- </validation>
38
- </check_github_mcp>
39
- <error_handling>
40
- If MCP validation fails:
41
- - Show clear error message
42
- - Provide setup instructions
43
- - Fallback to CLI if possible
44
- </error_handling>
45
- <purpose>Ensure required MCP dependencies are available before proceeding</purpose>
29
+ <description>Detect git hosting provider and available tools</description>
30
+ <detect_provider>
31
+ <check_remote_url>git remote get-url origin</check_remote_url>
32
+ <identify_host>
33
+ - github.com → GitHub
34
+ - gitlab.com GitLab
35
+ - bitbucket.org Bitbucket
36
+ - Other Ask user
37
+ </identify_host>
38
+ </detect_provider>
39
+ <check_available_tools>
40
+ <list_mcp_servers>Check which git-hosting MCP servers are available (github, gitlab, etc.)</list_mcp_servers>
41
+ <check_cli>Check if gh/glab CLI is available as fallback</check_cli>
42
+ </check_available_tools>
43
+ <select_tool>
44
+ <if_single_mcp>If only one relevant MCP available, confirm with user</if_single_mcp>
45
+ <if_multiple>Let user choose which tool to use</if_multiple>
46
+ <if_told_earlier>If user specified tool earlier in conversation, use that without asking again</if_told_earlier>
47
+ <store_as>$GIT_HOST_TOOL (e.g., "github_mcp", "gitlab_mcp", "gh_cli")</store_as>
48
+ </select_tool>
49
+
50
+ <purpose>Detect git hosting provider and select appropriate tool for PR verification</purpose>
46
51
  </step_0>
47
52
 
48
53
  <step_1>
49
- <description>Verify we're in main branch</description>
50
- <check_command>git branch --show-current</check_command>
51
- <required_branch>main</required_branch>
52
- <error_if_not_main>Exit with error message: "This command must be run from the main branch"</error_if_not_main>
53
- <purpose>Ensure we're consolidating to the main worktree</purpose>
54
+ <description>Determine default branch and verify we're on it</description>
55
+ <find_default_branch>
56
+ <command>git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'</command>
57
+ <fallback>git remote show origin | grep 'HEAD branch' | cut -d: -f2 | tr -d ' '</fallback>
58
+ <store_as>$DEFAULT_BRANCH (typically "main" or "master")</store_as>
59
+ </find_default_branch>
60
+ <check_current_branch>git branch --show-current</check_current_branch>
61
+ <verify>Current branch must equal $DEFAULT_BRANCH</verify>
62
+ <error_if_not_default>Exit with error: "This command must be run from the default branch ($DEFAULT_BRANCH)"</error_if_not_default>
63
+ <purpose>Ensure we're consolidating to the default branch worktree</purpose>
54
64
  </step_1>
55
65
 
56
66
  <step_2>
57
67
  <description>Get list of all worktrees</description>
58
68
  <command>git worktree list --porcelain</command>
59
69
  <parse_output>Extract worktree paths and branch names</parse_output>
60
- <exclude_main>Filter out the main worktree from cleanup candidates</exclude_main>
70
+ <exclude_default>Filter out the default branch worktree from cleanup candidates</exclude_default>
61
71
  <purpose>Identify all worktrees that could potentially be cleaned up</purpose>
62
72
  </step_2>
63
73
 
64
74
  <step_3>
65
75
  <description>Find oldest worktree by directory age</description>
66
76
  <get_worktree_ages>
67
- <command_macos>git worktree list | grep -v "main" | awk '{print $1}' | while read path; do /usr/bin/stat -f "%Sm|%N" -t "%Y-%m-%d %H:%M:%S" "$path" 2>/dev/null; done | sort</command_macos>
68
- <command_linux>git worktree list | grep -v "main" | awk '{print $1}' | xargs stat -c "%y|%n" | sort</command_linux>
77
+ <detect_platform>uname -s (returns "Darwin" for macOS, "Linux" for Linux)</detect_platform>
78
+ <command_macos>git worktree list | grep -v "\[$DEFAULT_BRANCH\]" | awk '{print $1}' > /tmp/worktrees-$$.txt && while IFS= read -r path; do echo "$(/usr/bin/stat -f '%Sm' -t '%Y-%m-%d %H:%M' "$path" 2>/dev/null)|$path"; done < /tmp/worktrees-$$.txt | sort; rm -f /tmp/worktrees-$$.txt</command_macos>
79
+ <command_linux>git worktree list | grep -v "\[$DEFAULT_BRANCH\]" | awk '{print $1}' > /tmp/worktrees-$$.txt && while IFS= read -r path; do echo "$(stat -c '%y' "$path" 2>/dev/null | cut -d. -f1)|$path"; done < /tmp/worktrees-$$.txt | sort; rm -f /tmp/worktrees-$$.txt</command_linux>
69
80
  <purpose>List all worktrees sorted by directory modification time (oldest first)</purpose>
70
- <note>Use full path /usr/bin/stat on macOS, regular stat on Linux.</note>
81
+ <critical_notes>
82
+ - Replace $DEFAULT_BRANCH with value from step_1 (e.g., "main" or "master")
83
+ - grep "\[branch\]" matches branch name in brackets, not paths containing the word
84
+ - Temp file approach avoids subshell parsing issues with piped while-loops
85
+ - /usr/bin/stat on macOS avoids homebrew stat conflicts
86
+ </critical_notes>
87
+ <expected_output_format>YYYY-MM-DD HH:MM|/full/path/to/worktree (oldest first)</expected_output_format>
71
88
  </get_worktree_ages>
72
89
  <filter_recent>
73
90
  <exclude_new>For worktrees created within the last 24 hours, let user know that this worktree might not be worth cleaning</exclude_new>
@@ -78,28 +95,27 @@ Current worktrees: !git worktree list`
78
95
  <important_note>DO NOT use "git branch --merged" to check merge status - it's unreliable</important_note>
79
96
  <proceed_to_pr_check>Move directly to step 4 to verify PR merge status instead</proceed_to_pr_check>
80
97
  </select_oldest>
81
- <purpose>Identify oldest worktree candidate - actual merge verification happens via GitHub PR in next step</purpose>
98
+ <purpose>Identify oldest worktree candidate - actual merge verification happens via PR/MR in next step</purpose>
82
99
  </step_3>
83
100
 
84
101
  <step_4>
85
- <description>Verify GitHub PR merge status (primary merge verification)</description>
102
+ <description>Verify PR/MR merge status (primary merge verification)</description>
86
103
  <determine_repo>
87
104
  <check_remote>git remote get-url origin</check_remote>
88
- <parse_repo>Extract owner/repo from GitHub URL</parse_repo>
89
- <fallback>Use project repository from git remote (owner/repo format)</fallback>
105
+ <parse_repo>Extract owner/repo from remote URL</parse_repo>
90
106
  </determine_repo>
91
107
  <search_pr>
92
- <tool>mcp__github__search_pull_requests</tool>
93
- <query>repo:owner/repo head:{branch_name} base:main</query>
94
- <purpose>Find PR for this branch targeting main</purpose>
108
+ <tool>Use $GIT_HOST_TOOL from step_0 (e.g., mcp__github__search_pull_requests, mcp__gitlab__*, or gh CLI)</tool>
109
+ <query>Find PRs/MRs where head={branch_name} and base=$DEFAULT_BRANCH</query>
110
+ <purpose>Find PR/MR for this branch targeting default branch</purpose>
95
111
  <important>This is the PRIMARY way to verify if a branch was merged - NOT git commands</important>
96
112
  </search_pr>
97
113
  <verify_pr_merged>
98
114
  <if_pr_found>
99
- <get_pr_details>Use mcp__github__pull_request_read to get full PR info</get_pr_details>
100
- <confirm_merged>Verify PR state is "closed" AND merged_at is not null AND base is "main"</confirm_merged>
101
- <extract_issue_number>Look for issue references in PR title/body (e.g., #14533, owner/repo#14533)</extract_issue_number>
102
- <if_merged>Proceed with cleanup - this branch was definitively merged to main</if_merged>
115
+ <get_pr_details>Use $GIT_HOST_TOOL to get full PR/MR info</get_pr_details>
116
+ <confirm_merged>Verify PR/MR state is "closed"/"merged" AND merged_at is not null AND base is "$DEFAULT_BRANCH"</confirm_merged>
117
+ <extract_issue_number>Look for issue references in PR title/body (e.g., #123, owner/repo#123)</extract_issue_number>
118
+ <if_merged>Proceed with cleanup - this branch was definitively merged to default branch</if_merged>
103
119
  <if_not_merged>
104
120
  <skip_worktree>This worktree is NOT merged - continue to next oldest worktree</skip_worktree>
105
121
  <repeat_from_step_3>Go back and find the next oldest worktree to check</repeat_from_step_3>
@@ -110,15 +126,14 @@ Current worktrees: !git worktree list`
110
126
  <continue_to_next>Continue checking next oldest worktree</continue_to_next>
111
127
  </if_no_pr>
112
128
  </verify_pr_merged>
113
- <purpose>Use GitHub PR status as the authoritative source for merge verification instead of unreliable git commands</purpose>
129
+ <purpose>Use PR/MR status as the authoritative source for merge verification instead of unreliable git commands</purpose>
114
130
  </step_4>
115
131
 
116
132
  <step_4_5>
117
- <description>Check and close related GitHub issue</description>
133
+ <description>Check and close related issue</description>
118
134
  <if_issue_found>
119
135
  <get_issue_details>
120
- <tool>mcp__github__issue_read</tool>
121
- <method>get</method>
136
+ <tool>Use $GIT_HOST_TOOL to read issue details</tool>
122
137
  <extract_repo>From issue reference (main-repo vs cross-repo)</extract_repo>
123
138
  </get_issue_details>
124
139
  <check_issue_state>
@@ -126,14 +141,13 @@ Current worktrees: !git worktree list`
126
141
  <ask_close>Ask user: "Related issue #{number} is still open. Should I close it? (y/N)"</ask_close>
127
142
  <if_yes_close>
128
143
  <add_closing_comment>
129
- <tool>mcp__github__add_issue_comment</tool>
130
- <body_template>Closing this issue as branch {branch_name} was merged to main on {merge_date} via PR #{pr_number}.</body_template>
131
- <get_merge_date>Extract merge date from PR details</get_merge_date>
132
- <get_pr_number>Use PR number from search results</get_pr_number>
144
+ <tool>Use $GIT_HOST_TOOL to add comment</tool>
145
+ <body_template>Closing this issue as branch {branch_name} was merged to {default_branch} on {merge_date} via PR/MR #{pr_number}.</body_template>
146
+ <get_merge_date>Extract merge date from PR/MR details</get_merge_date>
147
+ <get_pr_number>Use PR/MR number from search results</get_pr_number>
133
148
  </add_closing_comment>
134
149
  <close_issue>
135
- <tool>mcp__github__issue_write</tool>
136
- <method>update</method>
150
+ <tool>Use $GIT_HOST_TOOL to close issue</tool>
137
151
  <state>closed</state>
138
152
  <state_reason>completed</state_reason>
139
153
  </close_issue>
@@ -215,17 +229,22 @@ Current worktrees: !git worktree list`
215
229
 
216
230
  <important_notes>
217
231
 
218
- - Uses GitHub PR merge status as the ONLY reliable way to verify if a branch was merged
232
+ - Uses PR/MR merge status as the ONLY reliable way to verify if a branch was merged
219
233
  - DOES NOT use "git branch --merged" command as it's unreliable for merge verification
220
- - Only processes branches with PRs that were definitively merged to main
221
- - Skips worktrees without merged PRs and continues to next oldest candidate
222
- - Checks and optionally closes related GitHub issues
234
+ - Only processes branches with PRs/MRs that were definitively merged to default branch
235
+ - Skips worktrees without merged PRs/MRs and continues to next oldest candidate
236
+ - Checks and optionally closes related issues
223
237
  - Prioritizes oldest worktrees by directory age first for systematic cleanup
224
238
  - Warns about very recent worktrees (created within 24 hours) to avoid cleaning active work
225
239
  - Preserves useful development settings before deletion
226
240
  - Requires explicit confirmation before any destructive actions
227
241
  - Handles locked worktrees automatically
228
242
  - Processes one worktree at a time to maintain control
229
- - Must be run from main branch for safety
230
- - Works with standard GitHub repository URLs (owner/repo format)
243
+ - Must be run from default branch for safety
244
+
245
+ Limitations:
246
+
247
+ - Assumes remote is named "origin" (most common convention)
248
+ - Supports macOS and Linux only (no Windows support)
249
+ - Requires MCP server or CLI for git hosting provider (GitHub, GitLab, etc.)
231
250
  </important_notes>
@@ -125,7 +125,7 @@
125
125
  "order": 1
126
126
  },
127
127
  "worktree-add.md": {
128
- "description": "Add a new git worktree from branch name or GitHub issue URL, copy settings, install deps, and open in current IDE",
128
+ "description": "Add a new git worktree from branch name or issue URL, copy settings, install deps, and open in current IDE",
129
129
  "hint": "Add worktree",
130
130
  "category": "Worktree Management",
131
131
  "order": 1
@@ -1,6 +1,6 @@
1
1
  ---
2
- description: Add a new git worktree from branch name or GitHub issue URL, copy settings, install deps, and open in current IDE
3
- argument-hint: <branch-name-or-github-issue-url> [optional-base-branch]
2
+ description: Add a new git worktree from branch name or issue URL, copy settings, install deps, and open in current IDE
3
+ argument-hint: <branch-name-or-issue-url> [optional-base-branch]
4
4
  ---
5
5
 
6
6
  # Git Worktree Setup
@@ -16,31 +16,37 @@ argument-hint: <branch-name-or-github-issue-url> [optional-base-branch]
16
16
  Create a new git worktree for branch: $ARGUMENTS
17
17
 
18
18
  <current_state>
19
- Current branch: !git branch --show-current`
20
- Current worktrees: !git worktree list`
21
- Remote branches: !git branch -r`
22
- Uncommitted changes: !git status --short`
19
+ Current branch: `git branch --show-current`
20
+ Current worktrees: `git worktree list`
21
+ Remote branches: `git branch -r`
22
+ Uncommitted changes: `git status --short`
23
23
  </current_state>
24
24
 
25
25
  <execution_steps>
26
26
  <step_0>
27
- <description>Validate MCP dependencies</description>
28
- <check_github_mcp>
29
- <requirement>GitHub MCP server must be configured</requirement>
30
- <fallback>If unavailable, use `gh` CLI commands</fallback>
31
- <validation>
32
- - Try listing available MCP resources
33
- - If GitHub MCP not found, switch to CLI fallback
34
- - Inform user about MCP configuration if needed
35
- </validation>
36
- </check_github_mcp>
37
- <error_handling>
38
- If MCP validation fails:
39
- - Show clear error message
40
- - Provide setup instructions
41
- - Fallback to CLI if possible
42
- </error_handling>
43
- <purpose>Ensure required MCP dependencies are available before proceeding</purpose>
27
+ <description>Detect git hosting provider and available tools (only needed if argument is an issue URL)</description>
28
+ <condition>Only run this step if first argument looks like a git hosting URL</condition>
29
+ <detect_provider>
30
+ <check_remote_url>git remote get-url origin</check_remote_url>
31
+ <identify_host>
32
+ - github.com GitHub
33
+ - gitlab.com GitLab
34
+ - bitbucket.org Bitbucket
35
+ - Other → Ask user
36
+ </identify_host>
37
+ </detect_provider>
38
+ <check_available_tools>
39
+ <list_mcp_servers>Check which git-hosting MCP servers are available (github, gitlab, etc.)</list_mcp_servers>
40
+ <check_cli>Check if gh/glab CLI is available as fallback</check_cli>
41
+ </check_available_tools>
42
+ <select_tool>
43
+ <if_single_mcp>If only one relevant MCP available, confirm with user</if_single_mcp>
44
+ <if_multiple>Let user choose which tool to use</if_multiple>
45
+ <if_told_earlier>If user specified tool earlier in conversation, use that without asking again</if_told_earlier>
46
+ <store_as>$GIT_HOST_TOOL (e.g., "github_mcp", "gitlab_mcp", "gh_cli")</store_as>
47
+ </select_tool>
48
+
49
+ <purpose>Detect git hosting provider and select appropriate tool for issue lookup</purpose>
44
50
  </step_0>
45
51
 
46
52
  <step_1>
@@ -68,30 +74,41 @@ Uncommitted changes: !git status --short`
68
74
  </step_1>
69
75
 
70
76
  <step_2>
71
- <description>Parse the arguments</description>
77
+ <description>Determine default branch and parse arguments</description>
78
+ <find_default_branch>
79
+ <command>git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'</command>
80
+ <fallback>git remote show origin | grep 'HEAD branch' | cut -d: -f2 | tr -d ' '</fallback>
81
+ <store_as>$DEFAULT_BRANCH (typically "main" or "master")</store_as>
82
+ </find_default_branch>
72
83
  <input>The user-provided arguments</input>
73
- <expected_format>branch-name-or-github-url [optional-base-branch]</expected_format>
84
+ <expected_format>branch-name-or-issue-url [optional-base-branch]</expected_format>
74
85
  <example>fix/issue-123-main-content-area-visually-clipped main</example>
75
- <example_github_url><https://github.com/owner/project/issues/123> main</example_github_url>
76
- <default_base_branch>main (if not specified)</default_base_branch>
77
- </step_1>
86
+ <example_issue_url>https://github.com/owner/project/issues/123 main</example_issue_url>
87
+ <base_branch>Use provided base branch, or $DEFAULT_BRANCH if not specified</base_branch>
88
+ </step_2>
78
89
 
79
90
  <step_2_5>
80
- <description>Handle GitHub issue URLs</description>
81
- <condition>If first argument matches GitHub issue URL pattern</condition>
82
- <url_detection>Check if argument contains "github.com" and "/issues/"</url_detection>
91
+ <description>Handle issue URLs from git hosting provider</description>
92
+ <condition>If first argument matches issue URL pattern (detected in step_0)</condition>
93
+ <url_detection>
94
+ <github>Check if argument contains "github.com" and "/issues/"</github>
95
+ <gitlab>Check if argument contains "gitlab.com" and "/-/issues/"</gitlab>
96
+ <bitbucket>Check if argument contains "bitbucket.org" and "/issues/"</bitbucket>
97
+ </url_detection>
83
98
  <url_parsing>
84
- <pattern>https://github.com/{owner}/{repo}/issues/{issue_number}</pattern>
99
+ <github_pattern><https://github.com/{owner}/{repo}/issues/{issue_number}></github_pattern>
100
+ <gitlab_pattern><https://gitlab.com/{owner}/{repo}/-/issues/{issue_number}></gitlab_pattern>
101
+ <bitbucket_pattern><https://bitbucket.org/{owner}/{repo}/issues/{issue_number}></bitbucket_pattern>
85
102
  <extract>owner, repo, issue_number from URL</extract>
86
103
  </url_parsing>
87
104
  <fetch_issue_details>
88
- <tool>mcp__github__issue_read</tool>
89
- <method>get</method>
105
+ <tool>Use $GIT_HOST_TOOL from step_0</tool>
106
+ <method>get issue details</method>
90
107
  <parameters>owner, repo, issue_number</parameters>
91
108
  </fetch_issue_details>
92
109
  <generate_branch_name>
93
110
  <determine_type>Analyze issue title/labels to determine type (feat/fix/refactor/chore)</determine_type>
94
- <format>{type}/{repo}-{issue_number}-{kebab-case-title}</format>
111
+ <format>{type}/issue-{issue_number}-{kebab-case-title}</format>
95
112
  <kebab_case>Convert title to lowercase, replace spaces/special chars with hyphens</kebab_case>
96
113
  <sanitization>
97
114
  <rule>Always use lowercase for branch names</rule>
@@ -114,12 +131,12 @@ Uncommitted changes: !git status --short`
114
131
  <title>"Fix duplicate items in list view"</title>
115
132
  <generated>fix/issue-456-duplicate-items-in-list-view</generated>
116
133
  </examples>
117
- </step_1_5>
134
+ </step_2_5>
118
135
 
119
136
  <step_3>
120
137
  <description>Add all files and stash uncommitted changes if any exist</description>
121
138
  <condition>If output is not empty (has uncommitted changes)</condition>
122
- <command>git add -A && git stash push -m "Worktree switch: Moving changes to ${branch_name}"</chained_command>
139
+ <command>git add -A && git stash push -m "Worktree switch: Moving changes to ${branch_name}"</command>
123
140
  <purpose>Preserve work in progress before switching worktrees</purpose>
124
141
  <note>Remember stash was created for later restoration</note>
125
142
  </step_3>
@@ -138,20 +155,20 @@ Uncommitted changes: !git status --short`
138
155
  <step_5>
139
156
  <description>Fetch latest changes from remote</description>
140
157
  <command>git fetch origin</command>
141
- <purpose>Ensure we have the latest remote branches and main branch state</purpose>
142
- <note>This ensures new worktrees are created from the most recent main branch</note>
143
- </step_6>
158
+ <purpose>Ensure we have the latest remote branches and default branch state</purpose>
159
+ <note>This ensures new worktrees are created from the most recent default branch</note>
160
+ </step_5>
144
161
 
145
- <step_7>
162
+ <step_6>
146
163
  <description>Check if branch exists on remote</description>
147
164
  <command>git branch -r | grep "origin/${branch_name}"</command>
148
165
  <decision>
149
166
  <if_exists>Branch exists on remote - will checkout existing branch</if_exists>
150
167
  <if_not_exists>Branch does not exist - will create new branch from base</if_not_exists>
151
168
  </decision>
152
- </step_5>
169
+ </step_6>
153
170
 
154
- <step_6>
171
+ <step_7>
155
172
  <description>Create the worktree</description>
156
173
  <option_a_new_branch>
157
174
  <condition>Remote branch does NOT exist</condition>
@@ -245,7 +262,7 @@ EOF</create_file_command>
245
262
  </ide_specific_behavior>
246
263
  <purpose>Launch development environment for the new worktree using detected IDE</purpose>
247
264
  <confirmation_message>Opening worktree in ${ide_name}</confirmation_message>
248
- </step_11>
265
+ </step_13>
249
266
  </execution_steps>
250
267
 
251
268
  <important_notes>
@@ -260,4 +277,11 @@ EOF</create_file_command>
260
277
  - Uncommitted changes are automatically stashed and moved to the new worktree
261
278
  - Your work-in-progress seamlessly transfers to the new branch
262
279
  - IDE detection fallback: checks available editors and uses priority order
280
+
281
+ Limitations:
282
+
283
+ - Assumes remote is named "origin" (most common convention)
284
+ - Supports macOS and Linux only (no Windows support)
285
+ - Requires MCP server or CLI for git hosting provider when using issue URLs (GitHub, GitLab, etc.)
286
+ - Dependency install command is pnpm (modify for npm/yarn if needed)
263
287
  </important_notes>
@@ -18,54 +18,71 @@ Clean up merged worktrees by finding the oldest merged branch, consolidating set
18
18
  Additional info: $ARGUMENTS
19
19
 
20
20
  <current_state>
21
- Current branch: !git branch --show-current`
22
- Current worktrees: !git worktree list`
21
+ Current branch: `git branch --show-current`
22
+ Current worktrees: `git worktree list`
23
23
  </current_state>
24
24
 
25
25
  <execution_steps>
26
26
  <step_0>
27
- <description>Validate MCP dependencies</description>
28
- <check_github_mcp>
29
- <requirement>GitHub MCP server must be configured</requirement>
30
- <fallback>If unavailable, use `gh` CLI commands</fallback>
31
- <validation>
32
- - Try listing available MCP resources
33
- - If GitHub MCP not found, switch to CLI fallback
34
- - Inform user about MCP configuration if needed
35
- </validation>
36
- </check_github_mcp>
37
- <error_handling>
38
- If MCP validation fails:
39
- - Show clear error message
40
- - Provide setup instructions
41
- - Fallback to CLI if possible
42
- </error_handling>
43
- <purpose>Ensure required MCP dependencies are available before proceeding</purpose>
27
+ <description>Detect git hosting provider and available tools</description>
28
+ <detect_provider>
29
+ <check_remote_url>git remote get-url origin</check_remote_url>
30
+ <identify_host>
31
+ - github.com → GitHub
32
+ - gitlab.com GitLab
33
+ - bitbucket.org Bitbucket
34
+ - Other Ask user
35
+ </identify_host>
36
+ </detect_provider>
37
+ <check_available_tools>
38
+ <list_mcp_servers>Check which git-hosting MCP servers are available (github, gitlab, etc.)</list_mcp_servers>
39
+ <check_cli>Check if gh/glab CLI is available as fallback</check_cli>
40
+ </check_available_tools>
41
+ <select_tool>
42
+ <if_single_mcp>If only one relevant MCP available, confirm with user</if_single_mcp>
43
+ <if_multiple>Let user choose which tool to use</if_multiple>
44
+ <if_told_earlier>If user specified tool earlier in conversation, use that without asking again</if_told_earlier>
45
+ <store_as>$GIT_HOST_TOOL (e.g., "github_mcp", "gitlab_mcp", "gh_cli")</store_as>
46
+ </select_tool>
47
+
48
+ <purpose>Detect git hosting provider and select appropriate tool for PR verification</purpose>
44
49
  </step_0>
45
50
 
46
51
  <step_1>
47
- <description>Verify we're in main branch</description>
48
- <check_command>git branch --show-current</check_command>
49
- <required_branch>main</required_branch>
50
- <error_if_not_main>Exit with error message: "This command must be run from the main branch"</error_if_not_main>
51
- <purpose>Ensure we're consolidating to the main worktree</purpose>
52
+ <description>Determine default branch and verify we're on it</description>
53
+ <find_default_branch>
54
+ <command>git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'</command>
55
+ <fallback>git remote show origin | grep 'HEAD branch' | cut -d: -f2 | tr -d ' '</fallback>
56
+ <store_as>$DEFAULT_BRANCH (typically "main" or "master")</store_as>
57
+ </find_default_branch>
58
+ <check_current_branch>git branch --show-current</check_current_branch>
59
+ <verify>Current branch must equal $DEFAULT_BRANCH</verify>
60
+ <error_if_not_default>Exit with error: "This command must be run from the default branch ($DEFAULT_BRANCH)"</error_if_not_default>
61
+ <purpose>Ensure we're consolidating to the default branch worktree</purpose>
52
62
  </step_1>
53
63
 
54
64
  <step_2>
55
65
  <description>Get list of all worktrees</description>
56
66
  <command>git worktree list --porcelain</command>
57
67
  <parse_output>Extract worktree paths and branch names</parse_output>
58
- <exclude_main>Filter out the main worktree from cleanup candidates</exclude_main>
68
+ <exclude_default>Filter out the default branch worktree from cleanup candidates</exclude_default>
59
69
  <purpose>Identify all worktrees that could potentially be cleaned up</purpose>
60
70
  </step_2>
61
71
 
62
72
  <step_3>
63
73
  <description>Find oldest worktree by directory age</description>
64
74
  <get_worktree_ages>
65
- <command_macos>git worktree list | grep -v "main" | awk '{print $1}' | while read path; do /usr/bin/stat -f "%Sm|%N" -t "%Y-%m-%d %H:%M:%S" "$path" 2>/dev/null; done | sort</command_macos>
66
- <command_linux>git worktree list | grep -v "main" | awk '{print $1}' | xargs stat -c "%y|%n" | sort</command_linux>
75
+ <detect_platform>uname -s (returns "Darwin" for macOS, "Linux" for Linux)</detect_platform>
76
+ <command_macos>git worktree list | grep -v "\[$DEFAULT_BRANCH\]" | awk '{print $1}' > /tmp/worktrees-$$.txt && while IFS= read -r path; do echo "$(/usr/bin/stat -f '%Sm' -t '%Y-%m-%d %H:%M' "$path" 2>/dev/null)|$path"; done < /tmp/worktrees-$$.txt | sort; rm -f /tmp/worktrees-$$.txt</command_macos>
77
+ <command_linux>git worktree list | grep -v "\[$DEFAULT_BRANCH\]" | awk '{print $1}' > /tmp/worktrees-$$.txt && while IFS= read -r path; do echo "$(stat -c '%y' "$path" 2>/dev/null | cut -d. -f1)|$path"; done < /tmp/worktrees-$$.txt | sort; rm -f /tmp/worktrees-$$.txt</command_linux>
67
78
  <purpose>List all worktrees sorted by directory modification time (oldest first)</purpose>
68
- <note>Use full path /usr/bin/stat on macOS, regular stat on Linux.</note>
79
+ <critical_notes>
80
+ - Replace $DEFAULT_BRANCH with value from step_1 (e.g., "main" or "master")
81
+ - grep "\[branch\]" matches branch name in brackets, not paths containing the word
82
+ - Temp file approach avoids subshell parsing issues with piped while-loops
83
+ - /usr/bin/stat on macOS avoids homebrew stat conflicts
84
+ </critical_notes>
85
+ <expected_output_format>YYYY-MM-DD HH:MM|/full/path/to/worktree (oldest first)</expected_output_format>
69
86
  </get_worktree_ages>
70
87
  <filter_recent>
71
88
  <exclude_new>For worktrees created within the last 24 hours, let user know that this worktree might not be worth cleaning</exclude_new>
@@ -76,28 +93,27 @@ Current worktrees: !git worktree list`
76
93
  <important_note>DO NOT use "git branch --merged" to check merge status - it's unreliable</important_note>
77
94
  <proceed_to_pr_check>Move directly to step 4 to verify PR merge status instead</proceed_to_pr_check>
78
95
  </select_oldest>
79
- <purpose>Identify oldest worktree candidate - actual merge verification happens via GitHub PR in next step</purpose>
96
+ <purpose>Identify oldest worktree candidate - actual merge verification happens via PR/MR in next step</purpose>
80
97
  </step_3>
81
98
 
82
99
  <step_4>
83
- <description>Verify GitHub PR merge status (primary merge verification)</description>
100
+ <description>Verify PR/MR merge status (primary merge verification)</description>
84
101
  <determine_repo>
85
102
  <check_remote>git remote get-url origin</check_remote>
86
- <parse_repo>Extract owner/repo from GitHub URL</parse_repo>
87
- <fallback>Use project repository from git remote (owner/repo format)</fallback>
103
+ <parse_repo>Extract owner/repo from remote URL</parse_repo>
88
104
  </determine_repo>
89
105
  <search_pr>
90
- <tool>mcp__github__search_pull_requests</tool>
91
- <query>repo:owner/repo head:{branch_name} base:main</query>
92
- <purpose>Find PR for this branch targeting main</purpose>
106
+ <tool>Use $GIT_HOST_TOOL from step_0 (e.g., mcp__github__search_pull_requests, mcp__gitlab__*, or gh CLI)</tool>
107
+ <query>Find PRs/MRs where head={branch_name} and base=$DEFAULT_BRANCH</query>
108
+ <purpose>Find PR/MR for this branch targeting default branch</purpose>
93
109
  <important>This is the PRIMARY way to verify if a branch was merged - NOT git commands</important>
94
110
  </search_pr>
95
111
  <verify_pr_merged>
96
112
  <if_pr_found>
97
- <get_pr_details>Use mcp__github__pull_request_read to get full PR info</get_pr_details>
98
- <confirm_merged>Verify PR state is "closed" AND merged_at is not null AND base is "main"</confirm_merged>
99
- <extract_issue_number>Look for issue references in PR title/body (e.g., #14533, owner/repo#14533)</extract_issue_number>
100
- <if_merged>Proceed with cleanup - this branch was definitively merged to main</if_merged>
113
+ <get_pr_details>Use $GIT_HOST_TOOL to get full PR/MR info</get_pr_details>
114
+ <confirm_merged>Verify PR/MR state is "closed"/"merged" AND merged_at is not null AND base is "$DEFAULT_BRANCH"</confirm_merged>
115
+ <extract_issue_number>Look for issue references in PR title/body (e.g., #123, owner/repo#123)</extract_issue_number>
116
+ <if_merged>Proceed with cleanup - this branch was definitively merged to default branch</if_merged>
101
117
  <if_not_merged>
102
118
  <skip_worktree>This worktree is NOT merged - continue to next oldest worktree</skip_worktree>
103
119
  <repeat_from_step_3>Go back and find the next oldest worktree to check</repeat_from_step_3>
@@ -108,15 +124,14 @@ Current worktrees: !git worktree list`
108
124
  <continue_to_next>Continue checking next oldest worktree</continue_to_next>
109
125
  </if_no_pr>
110
126
  </verify_pr_merged>
111
- <purpose>Use GitHub PR status as the authoritative source for merge verification instead of unreliable git commands</purpose>
127
+ <purpose>Use PR/MR status as the authoritative source for merge verification instead of unreliable git commands</purpose>
112
128
  </step_4>
113
129
 
114
130
  <step_4_5>
115
- <description>Check and close related GitHub issue</description>
131
+ <description>Check and close related issue</description>
116
132
  <if_issue_found>
117
133
  <get_issue_details>
118
- <tool>mcp__github__issue_read</tool>
119
- <method>get</method>
134
+ <tool>Use $GIT_HOST_TOOL to read issue details</tool>
120
135
  <extract_repo>From issue reference (main-repo vs cross-repo)</extract_repo>
121
136
  </get_issue_details>
122
137
  <check_issue_state>
@@ -124,14 +139,13 @@ Current worktrees: !git worktree list`
124
139
  <ask_close>Ask user: "Related issue #{number} is still open. Should I close it? (y/N)"</ask_close>
125
140
  <if_yes_close>
126
141
  <add_closing_comment>
127
- <tool>mcp__github__add_issue_comment</tool>
128
- <body_template>Closing this issue as branch {branch_name} was merged to main on {merge_date} via PR #{pr_number}.</body_template>
129
- <get_merge_date>Extract merge date from PR details</get_merge_date>
130
- <get_pr_number>Use PR number from search results</get_pr_number>
142
+ <tool>Use $GIT_HOST_TOOL to add comment</tool>
143
+ <body_template>Closing this issue as branch {branch_name} was merged to {default_branch} on {merge_date} via PR/MR #{pr_number}.</body_template>
144
+ <get_merge_date>Extract merge date from PR/MR details</get_merge_date>
145
+ <get_pr_number>Use PR/MR number from search results</get_pr_number>
131
146
  </add_closing_comment>
132
147
  <close_issue>
133
- <tool>mcp__github__issue_write</tool>
134
- <method>update</method>
148
+ <tool>Use $GIT_HOST_TOOL to close issue</tool>
135
149
  <state>closed</state>
136
150
  <state_reason>completed</state_reason>
137
151
  </close_issue>
@@ -213,17 +227,22 @@ Current worktrees: !git worktree list`
213
227
 
214
228
  <important_notes>
215
229
 
216
- - Uses GitHub PR merge status as the ONLY reliable way to verify if a branch was merged
230
+ - Uses PR/MR merge status as the ONLY reliable way to verify if a branch was merged
217
231
  - DOES NOT use "git branch --merged" command as it's unreliable for merge verification
218
- - Only processes branches with PRs that were definitively merged to main
219
- - Skips worktrees without merged PRs and continues to next oldest candidate
220
- - Checks and optionally closes related GitHub issues
232
+ - Only processes branches with PRs/MRs that were definitively merged to default branch
233
+ - Skips worktrees without merged PRs/MRs and continues to next oldest candidate
234
+ - Checks and optionally closes related issues
221
235
  - Prioritizes oldest worktrees by directory age first for systematic cleanup
222
236
  - Warns about very recent worktrees (created within 24 hours) to avoid cleaning active work
223
237
  - Preserves useful development settings before deletion
224
238
  - Requires explicit confirmation before any destructive actions
225
239
  - Handles locked worktrees automatically
226
240
  - Processes one worktree at a time to maintain control
227
- - Must be run from main branch for safety
228
- - Works with standard GitHub repository URLs (owner/repo format)
241
+ - Must be run from default branch for safety
242
+
243
+ Limitations:
244
+
245
+ - Assumes remote is named "origin" (most common convention)
246
+ - Supports macOS and Linux only (no Windows support)
247
+ - Requires MCP server or CLI for git hosting provider (GitHub, GitLab, etc.)
229
248
  </important_notes>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wbern/claude-instructions",
3
- "version": "1.10.0",
3
+ "version": "1.11.0",
4
4
  "description": "TDD workflow commands for Claude Code CLI",
5
5
  "type": "module",
6
6
  "bin": "./bin/cli.js",