worktree-launcher 1.4.0 → 1.4.2
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/dist/index.js +81 -53
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -627,7 +627,10 @@ async function interactiveCommand() {
|
|
|
627
627
|
const repoName = path8.basename(mainRepoPath);
|
|
628
628
|
screen = blessed.screen({
|
|
629
629
|
smartCSR: true,
|
|
630
|
-
|
|
630
|
+
fullUnicode: true,
|
|
631
|
+
title: `wt - ${repoName}`,
|
|
632
|
+
terminal: "xterm-256color",
|
|
633
|
+
warnings: false
|
|
631
634
|
});
|
|
632
635
|
headerBox = blessed.box({
|
|
633
636
|
parent: screen,
|
|
@@ -637,9 +640,8 @@ async function interactiveCommand() {
|
|
|
637
640
|
height: 1,
|
|
638
641
|
content: ` ${repoName} (${currentBranch})`,
|
|
639
642
|
style: {
|
|
640
|
-
fg: "
|
|
641
|
-
bg: "
|
|
642
|
-
bold: true
|
|
643
|
+
fg: "black",
|
|
644
|
+
bg: "cyan"
|
|
643
645
|
}
|
|
644
646
|
});
|
|
645
647
|
worktreeList = blessed.list({
|
|
@@ -653,16 +655,16 @@ async function interactiveCommand() {
|
|
|
653
655
|
mouse: true,
|
|
654
656
|
style: {
|
|
655
657
|
selected: {
|
|
656
|
-
bg: "
|
|
657
|
-
fg: "
|
|
658
|
+
bg: "cyan",
|
|
659
|
+
fg: "black"
|
|
658
660
|
},
|
|
659
661
|
item: {
|
|
660
|
-
fg: "
|
|
662
|
+
fg: "default"
|
|
661
663
|
}
|
|
662
664
|
},
|
|
663
665
|
scrollbar: {
|
|
664
666
|
ch: " ",
|
|
665
|
-
style: { bg: "
|
|
667
|
+
style: { bg: "cyan" }
|
|
666
668
|
}
|
|
667
669
|
});
|
|
668
670
|
statusBar = blessed.box({
|
|
@@ -673,8 +675,7 @@ async function interactiveCommand() {
|
|
|
673
675
|
height: 1,
|
|
674
676
|
content: "",
|
|
675
677
|
style: {
|
|
676
|
-
fg: "
|
|
677
|
-
bg: "black"
|
|
678
|
+
fg: "green"
|
|
678
679
|
}
|
|
679
680
|
});
|
|
680
681
|
helpBar = blessed.box({
|
|
@@ -686,7 +687,7 @@ async function interactiveCommand() {
|
|
|
686
687
|
content: " [n]ew [d]elete [c]laude [x]codex [Enter]cd [q]uit",
|
|
687
688
|
style: {
|
|
688
689
|
fg: "black",
|
|
689
|
-
bg: "
|
|
690
|
+
bg: "cyan"
|
|
690
691
|
}
|
|
691
692
|
});
|
|
692
693
|
await refreshWorktrees();
|
|
@@ -695,8 +696,7 @@ async function interactiveCommand() {
|
|
|
695
696
|
showPath();
|
|
696
697
|
});
|
|
697
698
|
screen.key(["q", "C-c"], () => {
|
|
698
|
-
|
|
699
|
-
process.exit(0);
|
|
699
|
+
cleanExit();
|
|
700
700
|
});
|
|
701
701
|
screen.key(["n"], () => {
|
|
702
702
|
startCreationWizard();
|
|
@@ -713,11 +713,9 @@ async function interactiveCommand() {
|
|
|
713
713
|
screen.key(["enter"], () => {
|
|
714
714
|
const wt = worktrees[selectedIndex];
|
|
715
715
|
if (wt) {
|
|
716
|
-
|
|
717
|
-
console.log(`
|
|
716
|
+
cleanExit(`
|
|
718
717
|
cd "${wt.path}"
|
|
719
718
|
`);
|
|
720
|
-
process.exit(0);
|
|
721
719
|
}
|
|
722
720
|
});
|
|
723
721
|
screen.key(["r"], async () => {
|
|
@@ -753,6 +751,17 @@ function setStatus(msg) {
|
|
|
753
751
|
statusBar.setContent(` ${msg}`);
|
|
754
752
|
screen.render();
|
|
755
753
|
}
|
|
754
|
+
function cleanExit(message) {
|
|
755
|
+
screen.program.clear();
|
|
756
|
+
screen.program.disableMouse();
|
|
757
|
+
screen.program.showCursor();
|
|
758
|
+
screen.program.normalBuffer();
|
|
759
|
+
screen.destroy();
|
|
760
|
+
if (message) {
|
|
761
|
+
console.log(message);
|
|
762
|
+
}
|
|
763
|
+
process.exit(0);
|
|
764
|
+
}
|
|
756
765
|
function startCreationWizard() {
|
|
757
766
|
const state = {
|
|
758
767
|
branchName: "",
|
|
@@ -772,9 +781,8 @@ function askBranchName(state) {
|
|
|
772
781
|
height: 12,
|
|
773
782
|
border: { type: "line" },
|
|
774
783
|
style: {
|
|
775
|
-
fg: "
|
|
776
|
-
|
|
777
|
-
border: { fg: "blue" }
|
|
784
|
+
fg: "default",
|
|
785
|
+
border: { fg: "cyan" }
|
|
778
786
|
},
|
|
779
787
|
label: " New Worktree "
|
|
780
788
|
});
|
|
@@ -790,14 +798,14 @@ function askBranchName(state) {
|
|
|
790
798
|
top: 2,
|
|
791
799
|
left: 2,
|
|
792
800
|
content: `Current branch: ${currentBranch}`,
|
|
793
|
-
style: { fg: "
|
|
801
|
+
style: { fg: "default" }
|
|
794
802
|
});
|
|
795
803
|
blessed.text({
|
|
796
804
|
parent: form,
|
|
797
805
|
top: 4,
|
|
798
806
|
left: 2,
|
|
799
807
|
content: "Branch name:",
|
|
800
|
-
style: { fg: "
|
|
808
|
+
style: { fg: "default" }
|
|
801
809
|
});
|
|
802
810
|
const input = blessed.textbox({
|
|
803
811
|
parent: form,
|
|
@@ -806,8 +814,8 @@ function askBranchName(state) {
|
|
|
806
814
|
width: 54,
|
|
807
815
|
height: 1,
|
|
808
816
|
style: {
|
|
809
|
-
fg: "
|
|
810
|
-
bg: "
|
|
817
|
+
fg: "black",
|
|
818
|
+
bg: "white"
|
|
811
819
|
},
|
|
812
820
|
inputOnFocus: true
|
|
813
821
|
});
|
|
@@ -816,23 +824,27 @@ function askBranchName(state) {
|
|
|
816
824
|
top: 7,
|
|
817
825
|
left: 2,
|
|
818
826
|
content: "[Enter] next [Esc] cancel",
|
|
819
|
-
style: { fg: "
|
|
827
|
+
style: { fg: "cyan" }
|
|
820
828
|
});
|
|
821
829
|
input.focus();
|
|
822
830
|
screen.render();
|
|
823
|
-
input.on("submit", (
|
|
831
|
+
input.on("submit", () => {
|
|
832
|
+
const value = input.getValue();
|
|
824
833
|
if (!value || !value.trim()) {
|
|
825
834
|
form.destroy();
|
|
826
835
|
screen.render();
|
|
836
|
+
worktreeList.focus();
|
|
827
837
|
return;
|
|
828
838
|
}
|
|
829
839
|
try {
|
|
830
840
|
validateBranchName(value.trim());
|
|
831
841
|
state.branchName = value.trim();
|
|
832
842
|
form.destroy();
|
|
843
|
+
screen.render();
|
|
833
844
|
askBaseBranch(state);
|
|
834
845
|
} catch (e) {
|
|
835
846
|
setStatus(`Error: ${e.message}`);
|
|
847
|
+
input.clearValue();
|
|
836
848
|
input.focus();
|
|
837
849
|
screen.render();
|
|
838
850
|
}
|
|
@@ -840,6 +852,7 @@ function askBranchName(state) {
|
|
|
840
852
|
input.on("cancel", () => {
|
|
841
853
|
form.destroy();
|
|
842
854
|
screen.render();
|
|
855
|
+
worktreeList.focus();
|
|
843
856
|
});
|
|
844
857
|
input.readInput();
|
|
845
858
|
}
|
|
@@ -852,9 +865,8 @@ function askBaseBranch(state) {
|
|
|
852
865
|
height: 10,
|
|
853
866
|
border: { type: "line" },
|
|
854
867
|
style: {
|
|
855
|
-
fg: "
|
|
856
|
-
|
|
857
|
-
border: { fg: "blue" }
|
|
868
|
+
fg: "default",
|
|
869
|
+
border: { fg: "cyan" }
|
|
858
870
|
},
|
|
859
871
|
label: " Base Branch "
|
|
860
872
|
});
|
|
@@ -863,7 +875,7 @@ function askBaseBranch(state) {
|
|
|
863
875
|
top: 1,
|
|
864
876
|
left: 2,
|
|
865
877
|
content: "Create worktree from:",
|
|
866
|
-
style: { fg: "
|
|
878
|
+
style: { fg: "default" }
|
|
867
879
|
});
|
|
868
880
|
const list = blessed.list({
|
|
869
881
|
parent: form,
|
|
@@ -874,8 +886,8 @@ function askBaseBranch(state) {
|
|
|
874
886
|
keys: true,
|
|
875
887
|
vi: true,
|
|
876
888
|
style: {
|
|
877
|
-
selected: { bg: "
|
|
878
|
-
item: { fg: "
|
|
889
|
+
selected: { bg: "cyan", fg: "black" },
|
|
890
|
+
item: { fg: "default" }
|
|
879
891
|
},
|
|
880
892
|
items: [
|
|
881
893
|
` Current branch (${currentBranch})`,
|
|
@@ -887,18 +899,20 @@ function askBaseBranch(state) {
|
|
|
887
899
|
top: 7,
|
|
888
900
|
left: 2,
|
|
889
901
|
content: "[Enter] select [Esc] cancel",
|
|
890
|
-
style: { fg: "
|
|
902
|
+
style: { fg: "cyan" }
|
|
891
903
|
});
|
|
892
904
|
list.focus();
|
|
893
905
|
screen.render();
|
|
894
906
|
list.on("select", (_item, index) => {
|
|
895
907
|
state.baseBranch = index === 0 ? "current" : "default";
|
|
896
908
|
form.destroy();
|
|
909
|
+
screen.render();
|
|
897
910
|
askCopyEnv(state);
|
|
898
911
|
});
|
|
899
912
|
list.key(["escape"], () => {
|
|
900
913
|
form.destroy();
|
|
901
914
|
screen.render();
|
|
915
|
+
worktreeList.focus();
|
|
902
916
|
});
|
|
903
917
|
}
|
|
904
918
|
function askCopyEnv(state) {
|
|
@@ -910,9 +924,8 @@ function askCopyEnv(state) {
|
|
|
910
924
|
height: 8,
|
|
911
925
|
border: { type: "line" },
|
|
912
926
|
style: {
|
|
913
|
-
fg: "
|
|
914
|
-
|
|
915
|
-
border: { fg: "blue" }
|
|
927
|
+
fg: "default",
|
|
928
|
+
border: { fg: "cyan" }
|
|
916
929
|
},
|
|
917
930
|
label: " Environment Files "
|
|
918
931
|
});
|
|
@@ -921,7 +934,7 @@ function askCopyEnv(state) {
|
|
|
921
934
|
top: 1,
|
|
922
935
|
left: 2,
|
|
923
936
|
content: "Copy .env files to worktree?",
|
|
924
|
-
style: { fg: "
|
|
937
|
+
style: { fg: "default" }
|
|
925
938
|
});
|
|
926
939
|
const list = blessed.list({
|
|
927
940
|
parent: form,
|
|
@@ -932,8 +945,8 @@ function askCopyEnv(state) {
|
|
|
932
945
|
keys: true,
|
|
933
946
|
vi: true,
|
|
934
947
|
style: {
|
|
935
|
-
selected: { bg: "
|
|
936
|
-
item: { fg: "
|
|
948
|
+
selected: { bg: "cyan", fg: "black" },
|
|
949
|
+
item: { fg: "default" }
|
|
937
950
|
},
|
|
938
951
|
items: [" Yes (recommended)", " No"]
|
|
939
952
|
});
|
|
@@ -942,11 +955,13 @@ function askCopyEnv(state) {
|
|
|
942
955
|
list.on("select", (_item, index) => {
|
|
943
956
|
state.copyEnv = index === 0;
|
|
944
957
|
form.destroy();
|
|
958
|
+
screen.render();
|
|
945
959
|
askPushToRemote(state);
|
|
946
960
|
});
|
|
947
961
|
list.key(["escape"], () => {
|
|
948
962
|
form.destroy();
|
|
949
963
|
screen.render();
|
|
964
|
+
worktreeList.focus();
|
|
950
965
|
});
|
|
951
966
|
}
|
|
952
967
|
function askPushToRemote(state) {
|
|
@@ -958,9 +973,8 @@ function askPushToRemote(state) {
|
|
|
958
973
|
height: 8,
|
|
959
974
|
border: { type: "line" },
|
|
960
975
|
style: {
|
|
961
|
-
fg: "
|
|
962
|
-
|
|
963
|
-
border: { fg: "blue" }
|
|
976
|
+
fg: "default",
|
|
977
|
+
border: { fg: "cyan" }
|
|
964
978
|
},
|
|
965
979
|
label: " Push to Remote "
|
|
966
980
|
});
|
|
@@ -969,7 +983,7 @@ function askPushToRemote(state) {
|
|
|
969
983
|
top: 1,
|
|
970
984
|
left: 2,
|
|
971
985
|
content: "Push branch to GitHub immediately?",
|
|
972
|
-
style: { fg: "
|
|
986
|
+
style: { fg: "default" }
|
|
973
987
|
});
|
|
974
988
|
const list = blessed.list({
|
|
975
989
|
parent: form,
|
|
@@ -980,8 +994,8 @@ function askPushToRemote(state) {
|
|
|
980
994
|
keys: true,
|
|
981
995
|
vi: true,
|
|
982
996
|
style: {
|
|
983
|
-
selected: { bg: "
|
|
984
|
-
item: { fg: "
|
|
997
|
+
selected: { bg: "cyan", fg: "black" },
|
|
998
|
+
item: { fg: "default" }
|
|
985
999
|
},
|
|
986
1000
|
items: [" No (push later)", " Yes (visible on GitHub now)"]
|
|
987
1001
|
});
|
|
@@ -990,11 +1004,13 @@ function askPushToRemote(state) {
|
|
|
990
1004
|
list.on("select", (_item, index) => {
|
|
991
1005
|
state.pushToRemote = index === 1;
|
|
992
1006
|
form.destroy();
|
|
1007
|
+
screen.render();
|
|
993
1008
|
askAITool(state);
|
|
994
1009
|
});
|
|
995
1010
|
list.key(["escape"], () => {
|
|
996
1011
|
form.destroy();
|
|
997
1012
|
screen.render();
|
|
1013
|
+
worktreeList.focus();
|
|
998
1014
|
});
|
|
999
1015
|
}
|
|
1000
1016
|
function askAITool(state) {
|
|
@@ -1006,9 +1022,8 @@ function askAITool(state) {
|
|
|
1006
1022
|
height: 10,
|
|
1007
1023
|
border: { type: "line" },
|
|
1008
1024
|
style: {
|
|
1009
|
-
fg: "
|
|
1010
|
-
|
|
1011
|
-
border: { fg: "blue" }
|
|
1025
|
+
fg: "default",
|
|
1026
|
+
border: { fg: "cyan" }
|
|
1012
1027
|
},
|
|
1013
1028
|
label: " Launch AI Tool "
|
|
1014
1029
|
});
|
|
@@ -1017,7 +1032,7 @@ function askAITool(state) {
|
|
|
1017
1032
|
top: 1,
|
|
1018
1033
|
left: 2,
|
|
1019
1034
|
content: "Which AI assistant to launch?",
|
|
1020
|
-
style: { fg: "
|
|
1035
|
+
style: { fg: "default" }
|
|
1021
1036
|
});
|
|
1022
1037
|
const list = blessed.list({
|
|
1023
1038
|
parent: form,
|
|
@@ -1028,8 +1043,8 @@ function askAITool(state) {
|
|
|
1028
1043
|
keys: true,
|
|
1029
1044
|
vi: true,
|
|
1030
1045
|
style: {
|
|
1031
|
-
selected: { bg: "
|
|
1032
|
-
item: { fg: "
|
|
1046
|
+
selected: { bg: "cyan", fg: "black" },
|
|
1047
|
+
item: { fg: "default" }
|
|
1033
1048
|
},
|
|
1034
1049
|
items: [" Claude Code", " Codex", " Skip (just create worktree)"]
|
|
1035
1050
|
});
|
|
@@ -1038,11 +1053,13 @@ function askAITool(state) {
|
|
|
1038
1053
|
list.on("select", (_item, index) => {
|
|
1039
1054
|
state.aiTool = index === 0 ? "claude" : index === 1 ? "codex" : "skip";
|
|
1040
1055
|
form.destroy();
|
|
1056
|
+
screen.render();
|
|
1041
1057
|
executeCreation(state);
|
|
1042
1058
|
});
|
|
1043
1059
|
list.key(["escape"], () => {
|
|
1044
1060
|
form.destroy();
|
|
1045
1061
|
screen.render();
|
|
1062
|
+
worktreeList.focus();
|
|
1046
1063
|
});
|
|
1047
1064
|
}
|
|
1048
1065
|
async function executeCreation(state) {
|
|
@@ -1064,6 +1081,7 @@ async function executeCreation(state) {
|
|
|
1064
1081
|
}
|
|
1065
1082
|
await refreshWorktrees();
|
|
1066
1083
|
setStatus(`Created ${branchName}`);
|
|
1084
|
+
worktreeList.focus();
|
|
1067
1085
|
if (aiTool !== "skip") {
|
|
1068
1086
|
await launchInWorktree(worktreePath, aiTool);
|
|
1069
1087
|
}
|
|
@@ -1079,12 +1097,15 @@ async function executeCreation(state) {
|
|
|
1079
1097
|
}
|
|
1080
1098
|
await refreshWorktrees();
|
|
1081
1099
|
setStatus(`Created ${branchName}`);
|
|
1100
|
+
worktreeList.focus();
|
|
1082
1101
|
if (aiTool !== "skip") {
|
|
1083
1102
|
await launchInWorktree(worktreePath, aiTool);
|
|
1084
1103
|
}
|
|
1085
1104
|
}
|
|
1086
1105
|
} catch (e) {
|
|
1087
1106
|
setStatus(`Error: ${e.message}`);
|
|
1107
|
+
worktreeList.focus();
|
|
1108
|
+
screen.render();
|
|
1088
1109
|
}
|
|
1089
1110
|
}
|
|
1090
1111
|
async function launchInWorktree(worktreePath, tool) {
|
|
@@ -1094,6 +1115,10 @@ async function launchInWorktree(worktreePath, tool) {
|
|
|
1094
1115
|
return;
|
|
1095
1116
|
}
|
|
1096
1117
|
setStatus(`Launching ${tool}...`);
|
|
1118
|
+
screen.program.clear();
|
|
1119
|
+
screen.program.disableMouse();
|
|
1120
|
+
screen.program.showCursor();
|
|
1121
|
+
screen.program.normalBuffer();
|
|
1097
1122
|
screen.destroy();
|
|
1098
1123
|
launchAITool({ cwd: worktreePath, tool });
|
|
1099
1124
|
console.log(`
|
|
@@ -1117,8 +1142,7 @@ async function deleteSelected() {
|
|
|
1117
1142
|
height: 5,
|
|
1118
1143
|
border: { type: "line" },
|
|
1119
1144
|
style: {
|
|
1120
|
-
fg: "
|
|
1121
|
-
bg: "black",
|
|
1145
|
+
fg: "default",
|
|
1122
1146
|
border: { fg: "red" }
|
|
1123
1147
|
}
|
|
1124
1148
|
});
|
|
@@ -1153,6 +1177,10 @@ async function launchAI(tool) {
|
|
|
1153
1177
|
return;
|
|
1154
1178
|
}
|
|
1155
1179
|
setStatus(`Launching ${tool}...`);
|
|
1180
|
+
screen.program.clear();
|
|
1181
|
+
screen.program.disableMouse();
|
|
1182
|
+
screen.program.showCursor();
|
|
1183
|
+
screen.program.normalBuffer();
|
|
1156
1184
|
screen.destroy();
|
|
1157
1185
|
launchAITool({ cwd: wt.path, tool });
|
|
1158
1186
|
console.log(`
|
|
@@ -1163,7 +1191,7 @@ ${tool} launched in: ${path8.basename(wt.path)}
|
|
|
1163
1191
|
|
|
1164
1192
|
// src/index.ts
|
|
1165
1193
|
var program = new Command();
|
|
1166
|
-
program.name("wt").description("CLI tool to streamline git worktrees with AI coding assistants").version("1.4.
|
|
1194
|
+
program.name("wt").description("CLI tool to streamline git worktrees with AI coding assistants").version("1.4.2").action(async () => {
|
|
1167
1195
|
await interactiveCommand();
|
|
1168
1196
|
});
|
|
1169
1197
|
program.command("new <branch-name>").description("Create a new worktree and launch AI assistant").option("-i, --install", "Run package manager install after creating worktree").option("-s, --skip-launch", "Create worktree without launching AI assistant").option("-p, --push", "Push branch to remote (visible on GitHub)").action(async (branchName, options) => {
|