@wbern/claude-instructions 1.11.0 → 1.13.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/bin/cli.js +53 -24
- package/downloads/with-beads/worktree-add.md +77 -10
- package/downloads/without-beads/worktree-add.md +77 -10
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -119,7 +119,6 @@ init_esm_shims();
|
|
|
119
119
|
import {
|
|
120
120
|
select,
|
|
121
121
|
text,
|
|
122
|
-
multiselect,
|
|
123
122
|
groupMultiselect,
|
|
124
123
|
isCancel,
|
|
125
124
|
intro,
|
|
@@ -469,16 +468,39 @@ async function checkExistingFiles(outputPath, variant, scope, options) {
|
|
|
469
468
|
if (!destinationPath) {
|
|
470
469
|
return [];
|
|
471
470
|
}
|
|
472
|
-
const
|
|
471
|
+
const allFiles = await fs.readdir(sourcePath);
|
|
472
|
+
const files = options?.commands ? allFiles.filter((f) => options.commands.includes(f)) : allFiles;
|
|
473
473
|
const existingFiles = [];
|
|
474
474
|
const prefix = options?.commandPrefix || "";
|
|
475
|
+
let metadata = null;
|
|
476
|
+
let allowedToolsSet = null;
|
|
477
|
+
if (options?.allowedTools && options.allowedTools.length > 0) {
|
|
478
|
+
metadata = await loadCommandsMetadata(variant || VARIANTS.WITH_BEADS);
|
|
479
|
+
allowedToolsSet = new Set(options.allowedTools);
|
|
480
|
+
}
|
|
475
481
|
for (const file of files) {
|
|
476
482
|
const destFileName = prefix + file;
|
|
477
483
|
const destFilePath = path2.join(destinationPath, destFileName);
|
|
478
484
|
const sourceFilePath = path2.join(sourcePath, file);
|
|
479
485
|
if (await fs.pathExists(destFilePath)) {
|
|
480
486
|
const existingContent = await fs.readFile(destFilePath, "utf-8");
|
|
481
|
-
|
|
487
|
+
let newContent = await fs.readFile(sourceFilePath, "utf-8");
|
|
488
|
+
if (metadata && allowedToolsSet) {
|
|
489
|
+
const commandMetadata = metadata[file];
|
|
490
|
+
const requestedTools = commandMetadata?.["_requested-tools"] || [];
|
|
491
|
+
const toolsForCommand = requestedTools.filter(
|
|
492
|
+
(tool) => allowedToolsSet.has(tool)
|
|
493
|
+
);
|
|
494
|
+
if (toolsForCommand.length > 0) {
|
|
495
|
+
const allowedToolsYaml = `allowed-tools: ${toolsForCommand.join(", ")}`;
|
|
496
|
+
newContent = newContent.replace(
|
|
497
|
+
/^---\n/,
|
|
498
|
+
`---
|
|
499
|
+
${allowedToolsYaml}
|
|
500
|
+
`
|
|
501
|
+
);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
482
504
|
existingFiles.push({
|
|
483
505
|
filename: destFileName,
|
|
484
506
|
existingContent,
|
|
@@ -618,38 +640,42 @@ async function generateToDirectory(outputPath, variant, scope, options) {
|
|
|
618
640
|
const allFiles = await fs.readdir(sourcePath);
|
|
619
641
|
let files = options?.commands ? allFiles.filter((f) => options.commands.includes(f)) : allFiles;
|
|
620
642
|
if (options?.skipFiles) {
|
|
621
|
-
|
|
643
|
+
const prefix2 = options?.commandPrefix || "";
|
|
644
|
+
files = files.filter((f) => !options.skipFiles.includes(prefix2 + f));
|
|
622
645
|
}
|
|
623
|
-
|
|
646
|
+
const prefix = options?.commandPrefix || "";
|
|
647
|
+
if (options?.commands || options?.skipFiles || options?.commandPrefix) {
|
|
624
648
|
await fs.ensureDir(destinationPath);
|
|
625
649
|
for (const file of files) {
|
|
626
650
|
await fs.copy(
|
|
627
651
|
path2.join(sourcePath, file),
|
|
628
|
-
path2.join(destinationPath, file)
|
|
652
|
+
path2.join(destinationPath, prefix + file)
|
|
629
653
|
);
|
|
630
654
|
}
|
|
631
655
|
} else {
|
|
632
656
|
await fs.copy(sourcePath, destinationPath, {});
|
|
633
657
|
}
|
|
634
658
|
if (options?.allowedTools && options.allowedTools.length > 0) {
|
|
659
|
+
const metadata = await loadCommandsMetadata(variant || VARIANTS.WITH_BEADS);
|
|
660
|
+
const allowedToolsSet = new Set(options.allowedTools);
|
|
635
661
|
for (const file of files) {
|
|
636
|
-
const
|
|
637
|
-
const
|
|
638
|
-
const
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
662
|
+
const commandMetadata = metadata[file];
|
|
663
|
+
const requestedTools = commandMetadata?.["_requested-tools"] || [];
|
|
664
|
+
const toolsForCommand = requestedTools.filter(
|
|
665
|
+
(tool) => allowedToolsSet.has(tool)
|
|
666
|
+
);
|
|
667
|
+
if (toolsForCommand.length > 0) {
|
|
668
|
+
const filePath = path2.join(destinationPath, prefix + file);
|
|
669
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
670
|
+
const allowedToolsYaml = `allowed-tools: ${toolsForCommand.join(", ")}`;
|
|
671
|
+
const modifiedContent = content.replace(
|
|
672
|
+
/^---\n/,
|
|
673
|
+
`---
|
|
642
674
|
${allowedToolsYaml}
|
|
643
675
|
`
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
}
|
|
648
|
-
if (options?.commandPrefix) {
|
|
649
|
-
for (const file of files) {
|
|
650
|
-
const oldPath = path2.join(destinationPath, file);
|
|
651
|
-
const newPath = path2.join(destinationPath, options.commandPrefix + file);
|
|
652
|
-
await fs.rename(oldPath, newPath);
|
|
676
|
+
);
|
|
677
|
+
await fs.writeFile(filePath, modifiedContent);
|
|
678
|
+
}
|
|
653
679
|
}
|
|
654
680
|
}
|
|
655
681
|
let templateInjected = false;
|
|
@@ -904,9 +930,11 @@ async function main(args) {
|
|
|
904
930
|
variant
|
|
905
931
|
);
|
|
906
932
|
if (requestedToolsOptions.length > 0) {
|
|
907
|
-
selectedAllowedTools = await
|
|
933
|
+
selectedAllowedTools = await groupMultiselect({
|
|
908
934
|
message: "Select allowed tools for commands (optional)",
|
|
909
|
-
options:
|
|
935
|
+
options: {
|
|
936
|
+
"All tools": requestedToolsOptions
|
|
937
|
+
},
|
|
910
938
|
required: false
|
|
911
939
|
});
|
|
912
940
|
if (isCancel(selectedAllowedTools)) {
|
|
@@ -916,7 +944,8 @@ async function main(args) {
|
|
|
916
944
|
}
|
|
917
945
|
const existingFiles = cachedExistingFiles ?? await checkExistingFiles(void 0, variant, scope, {
|
|
918
946
|
commandPrefix,
|
|
919
|
-
commands: selectedCommands
|
|
947
|
+
commands: selectedCommands,
|
|
948
|
+
allowedTools: selectedAllowedTools
|
|
920
949
|
});
|
|
921
950
|
const skipFiles = [];
|
|
922
951
|
if (!args?.overwrite && !args?.skipOnConflict) {
|
|
@@ -26,6 +26,25 @@ Uncommitted changes: `git status --short`
|
|
|
26
26
|
|
|
27
27
|
<execution_steps>
|
|
28
28
|
<step_0>
|
|
29
|
+
<description>Ask user for setup mode</description>
|
|
30
|
+
<prompt>
|
|
31
|
+
<message>How would you like to set up the worktree?</message>
|
|
32
|
+
<options>
|
|
33
|
+
<option value="quick">
|
|
34
|
+
<label>Quick</label>
|
|
35
|
+
<description>Just create the worktree (skip deps, settings, IDE)</description>
|
|
36
|
+
</option>
|
|
37
|
+
<option value="full">
|
|
38
|
+
<label>Full setup</label>
|
|
39
|
+
<description>Install dependencies, copy settings, open in IDE</description>
|
|
40
|
+
</option>
|
|
41
|
+
</options>
|
|
42
|
+
</prompt>
|
|
43
|
+
<set_variable>$SETUP_MODE = user selection ("quick" or "full")</set_variable>
|
|
44
|
+
<purpose>Allow quick worktree creation when user just needs the branch</purpose>
|
|
45
|
+
</step_0>
|
|
46
|
+
|
|
47
|
+
<step_0b>
|
|
29
48
|
<description>Detect git hosting provider and available tools (only needed if argument is an issue URL)</description>
|
|
30
49
|
<condition>Only run this step if first argument looks like a git hosting URL</condition>
|
|
31
50
|
<detect_provider>
|
|
@@ -49,10 +68,11 @@ Uncommitted changes: `git status --short`
|
|
|
49
68
|
</select_tool>
|
|
50
69
|
|
|
51
70
|
<purpose>Detect git hosting provider and select appropriate tool for issue lookup</purpose>
|
|
52
|
-
</
|
|
71
|
+
</step_0b>
|
|
53
72
|
|
|
54
73
|
<step_1>
|
|
55
74
|
<description>Detect current IDE environment</description>
|
|
75
|
+
<condition>Only if $SETUP_MODE is "full"</condition>
|
|
56
76
|
<detection_methods>
|
|
57
77
|
<method_1>
|
|
58
78
|
<tool>mcp__ide__getDiagnostics</tool>
|
|
@@ -136,11 +156,29 @@ Uncommitted changes: `git status --short`
|
|
|
136
156
|
</step_2_5>
|
|
137
157
|
|
|
138
158
|
<step_3>
|
|
139
|
-
<description>
|
|
140
|
-
<condition>If output is not empty (has uncommitted changes)</condition>
|
|
141
|
-
<
|
|
142
|
-
|
|
143
|
-
|
|
159
|
+
<description>Handle uncommitted changes if any exist</description>
|
|
160
|
+
<condition>If git status --short output is not empty (has uncommitted changes)</condition>
|
|
161
|
+
<prompt>
|
|
162
|
+
<message>You have uncommitted changes. Move them to the new branch?</message>
|
|
163
|
+
<options>
|
|
164
|
+
<option value="yes">
|
|
165
|
+
<label>Yes</label>
|
|
166
|
+
<description>Stash changes and apply them in the new worktree</description>
|
|
167
|
+
</option>
|
|
168
|
+
<option value="no">
|
|
169
|
+
<label>No</label>
|
|
170
|
+
<description>Leave changes in current branch</description>
|
|
171
|
+
</option>
|
|
172
|
+
</options>
|
|
173
|
+
</prompt>
|
|
174
|
+
<if_yes>
|
|
175
|
+
<command>git add -A && git stash push -m "Worktree switch: Moving changes to ${branch_name}"</command>
|
|
176
|
+
<set_variable>$STASH_CREATED = true</set_variable>
|
|
177
|
+
</if_yes>
|
|
178
|
+
<if_no>
|
|
179
|
+
<set_variable>$STASH_CREATED = false</set_variable>
|
|
180
|
+
</if_no>
|
|
181
|
+
<purpose>Let user decide whether to move work in progress to new branch</purpose>
|
|
144
182
|
</step_3>
|
|
145
183
|
|
|
146
184
|
<step_4>
|
|
@@ -184,8 +222,32 @@ Uncommitted changes: `git status --short`
|
|
|
184
222
|
</option_b_existing_branch>
|
|
185
223
|
</step_7>
|
|
186
224
|
|
|
225
|
+
<step_7b>
|
|
226
|
+
<description>Set up remote tracking for new branch</description>
|
|
227
|
+
<condition>Only if new branch was created (option_a from step_7)</condition>
|
|
228
|
+
<working_directory>${parent_path}/${branch_name}</working_directory>
|
|
229
|
+
<command>cd ${parent_path}/${branch_name} && git push -u origin ${branch_name}</command>
|
|
230
|
+
<purpose>Establish remote tracking so git status shows ahead/behind and git push/pull work without specifying remote</purpose>
|
|
231
|
+
<note>This creates the remote branch and sets upstream tracking in one step</note>
|
|
232
|
+
</step_7b>
|
|
233
|
+
|
|
234
|
+
<step_7c>
|
|
235
|
+
<description>Quick mode completion</description>
|
|
236
|
+
<condition>Only if $SETUP_MODE is "quick"</condition>
|
|
237
|
+
<message>Worktree created at: ${parent_path}/${branch_name}</message>
|
|
238
|
+
<suggested_next_steps>
|
|
239
|
+
<intro>You can now:</intro>
|
|
240
|
+
<suggestion priority="1">Open in VS Code: `code ${parent_path}/${branch_name}`</suggestion>
|
|
241
|
+
<suggestion priority="2">Open in Cursor: `cursor ${parent_path}/${branch_name}`</suggestion>
|
|
242
|
+
<suggestion priority="3">Navigate to it: `cd ${parent_path}/${branch_name}`</suggestion>
|
|
243
|
+
<suggestion priority="4">Install dependencies: `cd ${parent_path}/${branch_name} && pnpm install`</suggestion>
|
|
244
|
+
</suggested_next_steps>
|
|
245
|
+
<action>STOP here - do not continue to remaining steps</action>
|
|
246
|
+
</step_7c>
|
|
247
|
+
|
|
187
248
|
<step_8>
|
|
188
249
|
<description>Copy Claude settings to new worktree</description>
|
|
250
|
+
<condition>Only if $SETUP_MODE is "full"</condition>
|
|
189
251
|
<source>.claude/settings.local.json</source>
|
|
190
252
|
<destination>${parent_path}/${branch_name}/.claude/settings.local.json</destination>
|
|
191
253
|
<command>cp -r .claude/settings.local.json ${parent_path}/${branch_name}/.claude/settings.local.json</command>
|
|
@@ -194,6 +256,7 @@ Uncommitted changes: `git status --short`
|
|
|
194
256
|
|
|
195
257
|
<step_9>
|
|
196
258
|
<description>Copy .env.local files to new worktree</description>
|
|
259
|
+
<condition>Only if $SETUP_MODE is "full"</condition>
|
|
197
260
|
<search_command>find . -name ".env.local" -type f</search_command>
|
|
198
261
|
<copy_logic>For each .env.local file found, copy to corresponding location in new worktree</copy_logic>
|
|
199
262
|
<common_locations>
|
|
@@ -201,14 +264,14 @@ Uncommitted changes: `git status --short`
|
|
|
201
264
|
- packages/*/.env.local
|
|
202
265
|
- (any other .env.local files found)
|
|
203
266
|
</common_locations>
|
|
204
|
-
<copy_command>find . -name ".env.local" -type f -exec sh -c 'mkdir -p "$(dirname "${parent_path}/${branch_name}/$1")" && cp "$1" "${parent_path}/${branch_name}/$1"'
|
|
267
|
+
<copy_command>find . -name ".env.local" -type f -exec sh -c 'mkdir -p "$(dirname "${parent_path}/${branch_name}/$1")" && cp "$1" "${parent_path}/${branch_name}/$1"'_ {} \;</copy_command>
|
|
205
268
|
<purpose>Preserve local environment configurations for development</purpose>
|
|
206
269
|
<note>Only copies files that exist; ignores missing ones</note>
|
|
207
270
|
</step_9>
|
|
208
271
|
|
|
209
272
|
<step_10>
|
|
210
273
|
<description>Create IDE-specific configuration (conditional)</description>
|
|
211
|
-
<condition>Only if supports_tasks is true (VS Code variants)</condition>
|
|
274
|
+
<condition>Only if $SETUP_MODE is "full" AND supports_tasks is true (VS Code variants)</condition>
|
|
212
275
|
<vs_code_tasks>
|
|
213
276
|
<create_directory>mkdir -p ${parent_path}/${branch_name}/.vscode</create_directory>
|
|
214
277
|
<create_file_command>cat > ${parent_path}/${branch_name}/.vscode/tasks.json << 'EOF'
|
|
@@ -240,6 +303,7 @@ EOF</create_file_command>
|
|
|
240
303
|
|
|
241
304
|
<step_11>
|
|
242
305
|
<description>Install dependencies in new worktree</description>
|
|
306
|
+
<condition>Only if $SETUP_MODE is "full"</condition>
|
|
243
307
|
<working_directory>${parent_path}/${branch_name}</working_directory>
|
|
244
308
|
<command>cd ${parent_path}/${branch_name} && pnpm install</command>
|
|
245
309
|
<purpose>Ensure all node_modules are installed for the new worktree</purpose>
|
|
@@ -247,7 +311,7 @@ EOF</create_file_command>
|
|
|
247
311
|
|
|
248
312
|
<step_12>
|
|
249
313
|
<description>Apply stashed changes to new worktree (if stash was created)</description>
|
|
250
|
-
<condition>Only if
|
|
314
|
+
<condition>Only if $SETUP_MODE is "full" AND $STASH_CREATED is true</condition>
|
|
251
315
|
<working_directory>${parent_path}/${branch_name}</working_directory>
|
|
252
316
|
<command>cd ${parent_path}/${branch_name} && git stash pop</command>
|
|
253
317
|
<purpose>Restore uncommitted work-in-progress to the new worktree branch</purpose>
|
|
@@ -256,6 +320,7 @@ EOF</create_file_command>
|
|
|
256
320
|
|
|
257
321
|
<step_13>
|
|
258
322
|
<description>Open detected IDE in new worktree</description>
|
|
323
|
+
<condition>Only if $SETUP_MODE is "full"</condition>
|
|
259
324
|
<command>${ide_command} ${parent_path}/${branch_name}</command>
|
|
260
325
|
<ide_specific_behavior>
|
|
261
326
|
<vs_code_variants>Opens folder in VS Code/Insiders/Cursor with tasks.json auto-starting Claude</vs_code_variants>
|
|
@@ -269,7 +334,8 @@ EOF</create_file_command>
|
|
|
269
334
|
|
|
270
335
|
<important_notes>
|
|
271
336
|
|
|
272
|
-
-
|
|
337
|
+
- Offers Quick or Full setup mode - Quick just creates the worktree, Full does everything
|
|
338
|
+
- Automatically detects and uses your current IDE (VS Code, VS Code Insiders, Cursor, Zed, etc.) in Full mode
|
|
273
339
|
- Creates VS Code-specific tasks.json only for VS Code variants (auto-starts Claude on folder open)
|
|
274
340
|
- Branch names with slashes (feat/, fix/, etc.) are fully supported
|
|
275
341
|
- The worktree directory path will match the full branch name including slashes
|
|
@@ -279,6 +345,7 @@ EOF</create_file_command>
|
|
|
279
345
|
- Uncommitted changes are automatically stashed and moved to the new worktree
|
|
280
346
|
- Your work-in-progress seamlessly transfers to the new branch
|
|
281
347
|
- IDE detection fallback: checks available editors and uses priority order
|
|
348
|
+
- New branches are automatically pushed with `-u` to set up remote tracking
|
|
282
349
|
|
|
283
350
|
Limitations:
|
|
284
351
|
|
|
@@ -24,6 +24,25 @@ Uncommitted changes: `git status --short`
|
|
|
24
24
|
|
|
25
25
|
<execution_steps>
|
|
26
26
|
<step_0>
|
|
27
|
+
<description>Ask user for setup mode</description>
|
|
28
|
+
<prompt>
|
|
29
|
+
<message>How would you like to set up the worktree?</message>
|
|
30
|
+
<options>
|
|
31
|
+
<option value="quick">
|
|
32
|
+
<label>Quick</label>
|
|
33
|
+
<description>Just create the worktree (skip deps, settings, IDE)</description>
|
|
34
|
+
</option>
|
|
35
|
+
<option value="full">
|
|
36
|
+
<label>Full setup</label>
|
|
37
|
+
<description>Install dependencies, copy settings, open in IDE</description>
|
|
38
|
+
</option>
|
|
39
|
+
</options>
|
|
40
|
+
</prompt>
|
|
41
|
+
<set_variable>$SETUP_MODE = user selection ("quick" or "full")</set_variable>
|
|
42
|
+
<purpose>Allow quick worktree creation when user just needs the branch</purpose>
|
|
43
|
+
</step_0>
|
|
44
|
+
|
|
45
|
+
<step_0b>
|
|
27
46
|
<description>Detect git hosting provider and available tools (only needed if argument is an issue URL)</description>
|
|
28
47
|
<condition>Only run this step if first argument looks like a git hosting URL</condition>
|
|
29
48
|
<detect_provider>
|
|
@@ -47,10 +66,11 @@ Uncommitted changes: `git status --short`
|
|
|
47
66
|
</select_tool>
|
|
48
67
|
|
|
49
68
|
<purpose>Detect git hosting provider and select appropriate tool for issue lookup</purpose>
|
|
50
|
-
</
|
|
69
|
+
</step_0b>
|
|
51
70
|
|
|
52
71
|
<step_1>
|
|
53
72
|
<description>Detect current IDE environment</description>
|
|
73
|
+
<condition>Only if $SETUP_MODE is "full"</condition>
|
|
54
74
|
<detection_methods>
|
|
55
75
|
<method_1>
|
|
56
76
|
<tool>mcp__ide__getDiagnostics</tool>
|
|
@@ -134,11 +154,29 @@ Uncommitted changes: `git status --short`
|
|
|
134
154
|
</step_2_5>
|
|
135
155
|
|
|
136
156
|
<step_3>
|
|
137
|
-
<description>
|
|
138
|
-
<condition>If output is not empty (has uncommitted changes)</condition>
|
|
139
|
-
<
|
|
140
|
-
|
|
141
|
-
|
|
157
|
+
<description>Handle uncommitted changes if any exist</description>
|
|
158
|
+
<condition>If git status --short output is not empty (has uncommitted changes)</condition>
|
|
159
|
+
<prompt>
|
|
160
|
+
<message>You have uncommitted changes. Move them to the new branch?</message>
|
|
161
|
+
<options>
|
|
162
|
+
<option value="yes">
|
|
163
|
+
<label>Yes</label>
|
|
164
|
+
<description>Stash changes and apply them in the new worktree</description>
|
|
165
|
+
</option>
|
|
166
|
+
<option value="no">
|
|
167
|
+
<label>No</label>
|
|
168
|
+
<description>Leave changes in current branch</description>
|
|
169
|
+
</option>
|
|
170
|
+
</options>
|
|
171
|
+
</prompt>
|
|
172
|
+
<if_yes>
|
|
173
|
+
<command>git add -A && git stash push -m "Worktree switch: Moving changes to ${branch_name}"</command>
|
|
174
|
+
<set_variable>$STASH_CREATED = true</set_variable>
|
|
175
|
+
</if_yes>
|
|
176
|
+
<if_no>
|
|
177
|
+
<set_variable>$STASH_CREATED = false</set_variable>
|
|
178
|
+
</if_no>
|
|
179
|
+
<purpose>Let user decide whether to move work in progress to new branch</purpose>
|
|
142
180
|
</step_3>
|
|
143
181
|
|
|
144
182
|
<step_4>
|
|
@@ -182,8 +220,32 @@ Uncommitted changes: `git status --short`
|
|
|
182
220
|
</option_b_existing_branch>
|
|
183
221
|
</step_7>
|
|
184
222
|
|
|
223
|
+
<step_7b>
|
|
224
|
+
<description>Set up remote tracking for new branch</description>
|
|
225
|
+
<condition>Only if new branch was created (option_a from step_7)</condition>
|
|
226
|
+
<working_directory>${parent_path}/${branch_name}</working_directory>
|
|
227
|
+
<command>cd ${parent_path}/${branch_name} && git push -u origin ${branch_name}</command>
|
|
228
|
+
<purpose>Establish remote tracking so git status shows ahead/behind and git push/pull work without specifying remote</purpose>
|
|
229
|
+
<note>This creates the remote branch and sets upstream tracking in one step</note>
|
|
230
|
+
</step_7b>
|
|
231
|
+
|
|
232
|
+
<step_7c>
|
|
233
|
+
<description>Quick mode completion</description>
|
|
234
|
+
<condition>Only if $SETUP_MODE is "quick"</condition>
|
|
235
|
+
<message>Worktree created at: ${parent_path}/${branch_name}</message>
|
|
236
|
+
<suggested_next_steps>
|
|
237
|
+
<intro>You can now:</intro>
|
|
238
|
+
<suggestion priority="1">Open in VS Code: `code ${parent_path}/${branch_name}`</suggestion>
|
|
239
|
+
<suggestion priority="2">Open in Cursor: `cursor ${parent_path}/${branch_name}`</suggestion>
|
|
240
|
+
<suggestion priority="3">Navigate to it: `cd ${parent_path}/${branch_name}`</suggestion>
|
|
241
|
+
<suggestion priority="4">Install dependencies: `cd ${parent_path}/${branch_name} && pnpm install`</suggestion>
|
|
242
|
+
</suggested_next_steps>
|
|
243
|
+
<action>STOP here - do not continue to remaining steps</action>
|
|
244
|
+
</step_7c>
|
|
245
|
+
|
|
185
246
|
<step_8>
|
|
186
247
|
<description>Copy Claude settings to new worktree</description>
|
|
248
|
+
<condition>Only if $SETUP_MODE is "full"</condition>
|
|
187
249
|
<source>.claude/settings.local.json</source>
|
|
188
250
|
<destination>${parent_path}/${branch_name}/.claude/settings.local.json</destination>
|
|
189
251
|
<command>cp -r .claude/settings.local.json ${parent_path}/${branch_name}/.claude/settings.local.json</command>
|
|
@@ -192,6 +254,7 @@ Uncommitted changes: `git status --short`
|
|
|
192
254
|
|
|
193
255
|
<step_9>
|
|
194
256
|
<description>Copy .env.local files to new worktree</description>
|
|
257
|
+
<condition>Only if $SETUP_MODE is "full"</condition>
|
|
195
258
|
<search_command>find . -name ".env.local" -type f</search_command>
|
|
196
259
|
<copy_logic>For each .env.local file found, copy to corresponding location in new worktree</copy_logic>
|
|
197
260
|
<common_locations>
|
|
@@ -199,14 +262,14 @@ Uncommitted changes: `git status --short`
|
|
|
199
262
|
- packages/*/.env.local
|
|
200
263
|
- (any other .env.local files found)
|
|
201
264
|
</common_locations>
|
|
202
|
-
<copy_command>find . -name ".env.local" -type f -exec sh -c 'mkdir -p "$(dirname "${parent_path}/${branch_name}/$1")" && cp "$1" "${parent_path}/${branch_name}/$1"'
|
|
265
|
+
<copy_command>find . -name ".env.local" -type f -exec sh -c 'mkdir -p "$(dirname "${parent_path}/${branch_name}/$1")" && cp "$1" "${parent_path}/${branch_name}/$1"'_ {} \;</copy_command>
|
|
203
266
|
<purpose>Preserve local environment configurations for development</purpose>
|
|
204
267
|
<note>Only copies files that exist; ignores missing ones</note>
|
|
205
268
|
</step_9>
|
|
206
269
|
|
|
207
270
|
<step_10>
|
|
208
271
|
<description>Create IDE-specific configuration (conditional)</description>
|
|
209
|
-
<condition>Only if supports_tasks is true (VS Code variants)</condition>
|
|
272
|
+
<condition>Only if $SETUP_MODE is "full" AND supports_tasks is true (VS Code variants)</condition>
|
|
210
273
|
<vs_code_tasks>
|
|
211
274
|
<create_directory>mkdir -p ${parent_path}/${branch_name}/.vscode</create_directory>
|
|
212
275
|
<create_file_command>cat > ${parent_path}/${branch_name}/.vscode/tasks.json << 'EOF'
|
|
@@ -238,6 +301,7 @@ EOF</create_file_command>
|
|
|
238
301
|
|
|
239
302
|
<step_11>
|
|
240
303
|
<description>Install dependencies in new worktree</description>
|
|
304
|
+
<condition>Only if $SETUP_MODE is "full"</condition>
|
|
241
305
|
<working_directory>${parent_path}/${branch_name}</working_directory>
|
|
242
306
|
<command>cd ${parent_path}/${branch_name} && pnpm install</command>
|
|
243
307
|
<purpose>Ensure all node_modules are installed for the new worktree</purpose>
|
|
@@ -245,7 +309,7 @@ EOF</create_file_command>
|
|
|
245
309
|
|
|
246
310
|
<step_12>
|
|
247
311
|
<description>Apply stashed changes to new worktree (if stash was created)</description>
|
|
248
|
-
<condition>Only if
|
|
312
|
+
<condition>Only if $SETUP_MODE is "full" AND $STASH_CREATED is true</condition>
|
|
249
313
|
<working_directory>${parent_path}/${branch_name}</working_directory>
|
|
250
314
|
<command>cd ${parent_path}/${branch_name} && git stash pop</command>
|
|
251
315
|
<purpose>Restore uncommitted work-in-progress to the new worktree branch</purpose>
|
|
@@ -254,6 +318,7 @@ EOF</create_file_command>
|
|
|
254
318
|
|
|
255
319
|
<step_13>
|
|
256
320
|
<description>Open detected IDE in new worktree</description>
|
|
321
|
+
<condition>Only if $SETUP_MODE is "full"</condition>
|
|
257
322
|
<command>${ide_command} ${parent_path}/${branch_name}</command>
|
|
258
323
|
<ide_specific_behavior>
|
|
259
324
|
<vs_code_variants>Opens folder in VS Code/Insiders/Cursor with tasks.json auto-starting Claude</vs_code_variants>
|
|
@@ -267,7 +332,8 @@ EOF</create_file_command>
|
|
|
267
332
|
|
|
268
333
|
<important_notes>
|
|
269
334
|
|
|
270
|
-
-
|
|
335
|
+
- Offers Quick or Full setup mode - Quick just creates the worktree, Full does everything
|
|
336
|
+
- Automatically detects and uses your current IDE (VS Code, VS Code Insiders, Cursor, Zed, etc.) in Full mode
|
|
271
337
|
- Creates VS Code-specific tasks.json only for VS Code variants (auto-starts Claude on folder open)
|
|
272
338
|
- Branch names with slashes (feat/, fix/, etc.) are fully supported
|
|
273
339
|
- The worktree directory path will match the full branch name including slashes
|
|
@@ -277,6 +343,7 @@ EOF</create_file_command>
|
|
|
277
343
|
- Uncommitted changes are automatically stashed and moved to the new worktree
|
|
278
344
|
- Your work-in-progress seamlessly transfers to the new branch
|
|
279
345
|
- IDE detection fallback: checks available editors and uses priority order
|
|
346
|
+
- New branches are automatically pushed with `-u` to set up remote tracking
|
|
280
347
|
|
|
281
348
|
Limitations:
|
|
282
349
|
|