@iloom/cli 0.6.1 → 0.7.1
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/LICENSE +1 -1
- package/README.md +35 -18
- package/dist/{BranchNamingService-B5PVRR7F.js → BranchNamingService-FLPUUFOB.js} +2 -2
- package/dist/ClaudeContextManager-KE5TBZVZ.js +14 -0
- package/dist/ClaudeService-CRSETT3A.js +13 -0
- package/dist/{GitHubService-S2OGUTDR.js → GitHubService-O7U4UQ7N.js} +3 -3
- package/dist/{LoomLauncher-5LFM4LXB.js → LoomLauncher-NL65LSKP.js} +6 -6
- package/dist/{MetadataManager-DFI73J3G.js → MetadataManager-XJ2YB762.js} +2 -2
- package/dist/PRManager-2ABCWXHW.js +16 -0
- package/dist/{ProjectCapabilityDetector-S5FLNCFI.js → ProjectCapabilityDetector-IA56AUE6.js} +3 -3
- package/dist/{PromptTemplateManager-C3DK6XZL.js → PromptTemplateManager-7L3HJQQU.js} +2 -2
- package/dist/README.md +35 -18
- package/dist/{SettingsManager-35F5RUJH.js → SettingsManager-YU4VYPTW.js} +2 -2
- package/dist/agents/iloom-framework-detector.md +78 -9
- package/dist/agents/iloom-issue-analyze-and-plan.md +42 -17
- package/dist/agents/iloom-issue-analyzer.md +14 -14
- package/dist/agents/iloom-issue-complexity-evaluator.md +38 -15
- package/dist/agents/iloom-issue-enhancer.md +15 -15
- package/dist/agents/iloom-issue-implementer.md +44 -15
- package/dist/agents/iloom-issue-planner.md +121 -17
- package/dist/agents/iloom-issue-reviewer.md +15 -15
- package/dist/{build-FJVYP7EV.js → build-HQ5HGA3T.js} +9 -9
- package/dist/{chunk-VU3QMIP2.js → chunk-453NC377.js} +91 -15
- package/dist/chunk-453NC377.js.map +1 -0
- package/dist/{chunk-UQIXZ3BA.js → chunk-5V74K5ZA.js} +2 -2
- package/dist/{chunk-7WANFUIK.js → chunk-6TL3BYH6.js} +2 -2
- package/dist/{chunk-ZPSTA5PR.js → chunk-7GLZVDPQ.js} +2 -2
- package/dist/{chunk-64O2UIWO.js → chunk-AFRICMSW.js} +4 -4
- package/dist/{chunk-5TXLVEXT.js → chunk-C3AKFAIR.js} +2 -2
- package/dist/{chunk-K7SEEHKO.js → chunk-CNSTXBJ3.js} +7 -419
- package/dist/chunk-CNSTXBJ3.js.map +1 -0
- package/dist/{chunk-2A7WQKBE.js → chunk-DAOS6EC3.js} +96 -6
- package/dist/chunk-DAOS6EC3.js.map +1 -0
- package/dist/{chunk-TRQ76ISK.js → chunk-ELJKYFSH.js} +9 -9
- package/dist/{chunk-VDA5JMB4.js → chunk-EPPPDVHD.js} +21 -8
- package/dist/chunk-EPPPDVHD.js.map +1 -0
- package/dist/{chunk-LVBRMTE6.js → chunk-FEAJR6PN.js} +6 -6
- package/dist/{chunk-6YSFTPKW.js → chunk-FM4KBPVA.js} +18 -13
- package/dist/chunk-FM4KBPVA.js.map +1 -0
- package/dist/{chunk-AEIMYF4P.js → chunk-FP7G7DG3.js} +6 -2
- package/dist/chunk-FP7G7DG3.js.map +1 -0
- package/dist/{chunk-LT3SGBR7.js → chunk-GCPAZSGV.js} +36 -2
- package/dist/{chunk-LT3SGBR7.js.map → chunk-GCPAZSGV.js.map} +1 -1
- package/dist/chunk-GJMEKEI5.js +517 -0
- package/dist/chunk-GJMEKEI5.js.map +1 -0
- package/dist/{chunk-7Q66W4OH.js → chunk-HBJITKSZ.js} +37 -1
- package/dist/chunk-HBJITKSZ.js.map +1 -0
- package/dist/{chunk-7HIRPCKU.js → chunk-HVQNVRAF.js} +2 -2
- package/dist/{chunk-6U6VI4SZ.js → chunk-KVS4XGBQ.js} +4 -4
- package/dist/{chunk-SN3Z6EZO.js → chunk-N7FVXZNI.js} +2 -2
- package/dist/{chunk-I75JMBNB.js → chunk-QQFBMCAH.js} +54 -43
- package/dist/chunk-QQFBMCAH.js.map +1 -0
- package/dist/{chunk-AXX3QIKK.js → chunk-RD7I2Q2F.js} +2 -2
- package/dist/chunk-TIYJEEVO.js +79 -0
- package/dist/chunk-TIYJEEVO.js.map +1 -0
- package/dist/{chunk-EK3XCAAS.js → chunk-UDRZY65Y.js} +2 -2
- package/dist/{chunk-3PT7RKL5.js → chunk-USJSNHGG.js} +2 -2
- package/dist/{chunk-CFUWQHCJ.js → chunk-VWGKGNJP.js} +114 -35
- package/dist/chunk-VWGKGNJP.js.map +1 -0
- package/dist/{chunk-F6WVM437.js → chunk-WFQ5CLTR.js} +6 -3
- package/dist/chunk-WFQ5CLTR.js.map +1 -0
- package/dist/{chunk-BXCPJJYM.js → chunk-XPKN3QWY.js} +24 -6
- package/dist/chunk-XPKN3QWY.js.map +1 -0
- package/dist/chunk-YQNSZKKT.js +822 -0
- package/dist/chunk-YQNSZKKT.js.map +1 -0
- package/dist/{chunk-GEXP5IOF.js → chunk-ZA575VLF.js} +21 -8
- package/dist/chunk-ZA575VLF.js.map +1 -0
- package/dist/{claude-H33OQMXO.js → claude-6H36IBHO.js} +4 -2
- package/dist/{cleanup-BRUAINKE.js → cleanup-77U5ATYI.js} +20 -16
- package/dist/cleanup-77U5ATYI.js.map +1 -0
- package/dist/cli.js +361 -954
- package/dist/cli.js.map +1 -1
- package/dist/commit-ONRXU67O.js +237 -0
- package/dist/commit-ONRXU67O.js.map +1 -0
- package/dist/{compile-ULNO5F7Q.js → compile-CT7IR7O2.js} +9 -9
- package/dist/{contribute-Q6GX6AXK.js → contribute-GXKOIA42.js} +5 -5
- package/dist/{dev-server-4RCDJ5MU.js → dev-server-UKAPBGUR.js} +22 -74
- package/dist/dev-server-UKAPBGUR.js.map +1 -0
- package/dist/{feedback-O4Q55SVS.js → feedback-K3A4QUSG.js} +10 -10
- package/dist/{git-FVMGBHC2.js → git-ENLT2VNI.js} +6 -4
- package/dist/hooks/iloom-hook.js +30 -2
- package/dist/{ignite-VHV65WEZ.js → ignite-YUAOJ5PP.js} +20 -20
- package/dist/ignite-YUAOJ5PP.js.map +1 -0
- package/dist/index.d.ts +71 -27
- package/dist/index.js +196 -266
- package/dist/index.js.map +1 -1
- package/dist/init-XQQMFDM6.js +21 -0
- package/dist/{lint-5JMCWE4Y.js → lint-HAVU4U34.js} +9 -9
- package/dist/mcp/issue-management-server.js +359 -13
- package/dist/mcp/issue-management-server.js.map +1 -1
- package/dist/mcp/recap-server.js +13 -4
- package/dist/mcp/recap-server.js.map +1 -1
- package/dist/{open-WHVUYGPY.js → open-QI63XQ4F.js} +25 -76
- package/dist/open-QI63XQ4F.js.map +1 -0
- package/dist/{projects-SA76I4TZ.js → projects-TWY4RT2Z.js} +11 -4
- package/dist/projects-TWY4RT2Z.js.map +1 -0
- package/dist/prompts/init-prompt.txt +119 -51
- package/dist/prompts/issue-prompt.txt +132 -63
- package/dist/prompts/pr-prompt.txt +3 -3
- package/dist/prompts/regular-prompt.txt +16 -18
- package/dist/prompts/session-summary-prompt.txt +13 -13
- package/dist/{rebase-Y4AS6LQW.js → rebase-QYCRF7JG.js} +53 -8
- package/dist/rebase-QYCRF7JG.js.map +1 -0
- package/dist/{recap-VOOUXOGP.js → recap-ZKGHZCX6.js} +6 -6
- package/dist/{run-NCRK5NPR.js → run-YDVYORT2.js} +25 -76
- package/dist/run-YDVYORT2.js.map +1 -0
- package/dist/schema/settings.schema.json +14 -3
- package/dist/{shell-SBLXVOVJ.js → shell-2NNSIU34.js} +6 -6
- package/dist/{summary-CVFAMDOJ.js → summary-G6L3VAKK.js} +11 -10
- package/dist/{summary-CVFAMDOJ.js.map → summary-G6L3VAKK.js.map} +1 -1
- package/dist/{test-3KIVXI6J.js → test-75WAA6DU.js} +9 -9
- package/dist/{test-git-ZB6AGGRW.js → test-git-E2BLXR6M.js} +4 -4
- package/dist/{test-prefix-FBGXKMPA.js → test-prefix-A7JGGYAA.js} +4 -4
- package/dist/{test-webserver-YVQD42W6.js → test-webserver-NRMGT2HB.js} +29 -8
- package/dist/test-webserver-NRMGT2HB.js.map +1 -0
- package/package.json +3 -1
- package/dist/ClaudeContextManager-6J2EB4QU.js +0 -14
- package/dist/ClaudeService-O2PB22GX.js +0 -13
- package/dist/PRManager-GB3FOJ2W.js +0 -14
- package/dist/chunk-2A7WQKBE.js.map +0 -1
- package/dist/chunk-6YSFTPKW.js.map +0 -1
- package/dist/chunk-7Q66W4OH.js.map +0 -1
- package/dist/chunk-AEIMYF4P.js.map +0 -1
- package/dist/chunk-BXCPJJYM.js.map +0 -1
- package/dist/chunk-CFUWQHCJ.js.map +0 -1
- package/dist/chunk-F6WVM437.js.map +0 -1
- package/dist/chunk-GEXP5IOF.js.map +0 -1
- package/dist/chunk-I75JMBNB.js.map +0 -1
- package/dist/chunk-K7SEEHKO.js.map +0 -1
- package/dist/chunk-VDA5JMB4.js.map +0 -1
- package/dist/chunk-VU3QMIP2.js.map +0 -1
- package/dist/chunk-W6WVRHJ6.js +0 -251
- package/dist/chunk-W6WVRHJ6.js.map +0 -1
- package/dist/cleanup-BRUAINKE.js.map +0 -1
- package/dist/dev-server-4RCDJ5MU.js.map +0 -1
- package/dist/ignite-VHV65WEZ.js.map +0 -1
- package/dist/init-UTYRHNJJ.js +0 -21
- package/dist/open-WHVUYGPY.js.map +0 -1
- package/dist/projects-SA76I4TZ.js.map +0 -1
- package/dist/rebase-Y4AS6LQW.js.map +0 -1
- package/dist/run-NCRK5NPR.js.map +0 -1
- package/dist/test-webserver-YVQD42W6.js.map +0 -1
- /package/dist/{BranchNamingService-B5PVRR7F.js.map → BranchNamingService-FLPUUFOB.js.map} +0 -0
- /package/dist/{ClaudeContextManager-6J2EB4QU.js.map → ClaudeContextManager-KE5TBZVZ.js.map} +0 -0
- /package/dist/{ClaudeService-O2PB22GX.js.map → ClaudeService-CRSETT3A.js.map} +0 -0
- /package/dist/{GitHubService-S2OGUTDR.js.map → GitHubService-O7U4UQ7N.js.map} +0 -0
- /package/dist/{LoomLauncher-5LFM4LXB.js.map → LoomLauncher-NL65LSKP.js.map} +0 -0
- /package/dist/{MetadataManager-DFI73J3G.js.map → MetadataManager-XJ2YB762.js.map} +0 -0
- /package/dist/{PRManager-GB3FOJ2W.js.map → PRManager-2ABCWXHW.js.map} +0 -0
- /package/dist/{ProjectCapabilityDetector-S5FLNCFI.js.map → ProjectCapabilityDetector-IA56AUE6.js.map} +0 -0
- /package/dist/{PromptTemplateManager-C3DK6XZL.js.map → PromptTemplateManager-7L3HJQQU.js.map} +0 -0
- /package/dist/{SettingsManager-35F5RUJH.js.map → SettingsManager-YU4VYPTW.js.map} +0 -0
- /package/dist/{build-FJVYP7EV.js.map → build-HQ5HGA3T.js.map} +0 -0
- /package/dist/{chunk-UQIXZ3BA.js.map → chunk-5V74K5ZA.js.map} +0 -0
- /package/dist/{chunk-7WANFUIK.js.map → chunk-6TL3BYH6.js.map} +0 -0
- /package/dist/{chunk-ZPSTA5PR.js.map → chunk-7GLZVDPQ.js.map} +0 -0
- /package/dist/{chunk-64O2UIWO.js.map → chunk-AFRICMSW.js.map} +0 -0
- /package/dist/{chunk-5TXLVEXT.js.map → chunk-C3AKFAIR.js.map} +0 -0
- /package/dist/{chunk-TRQ76ISK.js.map → chunk-ELJKYFSH.js.map} +0 -0
- /package/dist/{chunk-LVBRMTE6.js.map → chunk-FEAJR6PN.js.map} +0 -0
- /package/dist/{chunk-7HIRPCKU.js.map → chunk-HVQNVRAF.js.map} +0 -0
- /package/dist/{chunk-6U6VI4SZ.js.map → chunk-KVS4XGBQ.js.map} +0 -0
- /package/dist/{chunk-SN3Z6EZO.js.map → chunk-N7FVXZNI.js.map} +0 -0
- /package/dist/{chunk-AXX3QIKK.js.map → chunk-RD7I2Q2F.js.map} +0 -0
- /package/dist/{chunk-EK3XCAAS.js.map → chunk-UDRZY65Y.js.map} +0 -0
- /package/dist/{chunk-3PT7RKL5.js.map → chunk-USJSNHGG.js.map} +0 -0
- /package/dist/{claude-H33OQMXO.js.map → claude-6H36IBHO.js.map} +0 -0
- /package/dist/{compile-ULNO5F7Q.js.map → compile-CT7IR7O2.js.map} +0 -0
- /package/dist/{contribute-Q6GX6AXK.js.map → contribute-GXKOIA42.js.map} +0 -0
- /package/dist/{feedback-O4Q55SVS.js.map → feedback-K3A4QUSG.js.map} +0 -0
- /package/dist/{git-FVMGBHC2.js.map → git-ENLT2VNI.js.map} +0 -0
- /package/dist/{init-UTYRHNJJ.js.map → init-XQQMFDM6.js.map} +0 -0
- /package/dist/{lint-5JMCWE4Y.js.map → lint-HAVU4U34.js.map} +0 -0
- /package/dist/{recap-VOOUXOGP.js.map → recap-ZKGHZCX6.js.map} +0 -0
- /package/dist/{shell-SBLXVOVJ.js.map → shell-2NNSIU34.js.map} +0 -0
- /package/dist/{test-3KIVXI6J.js.map → test-75WAA6DU.js.map} +0 -0
- /package/dist/{test-git-ZB6AGGRW.js.map → test-git-E2BLXR6M.js.map} +0 -0
- /package/dist/{test-prefix-FBGXKMPA.js.map → test-prefix-A7JGGYAA.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
SessionSummaryService
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-CNSTXBJ3.js";
|
|
5
5
|
import "./chunk-NXMDEL3F.js";
|
|
6
6
|
import {
|
|
7
7
|
CLIIsolationManager,
|
|
@@ -9,30 +9,28 @@ import {
|
|
|
9
9
|
EnvironmentManager,
|
|
10
10
|
LoomManager,
|
|
11
11
|
ResourceCleanup
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-QQFBMCAH.js";
|
|
13
|
+
import {
|
|
14
|
+
BuildRunner,
|
|
15
|
+
MergeManager
|
|
16
|
+
} from "./chunk-DAOS6EC3.js";
|
|
13
17
|
import {
|
|
14
18
|
IssueTrackerFactory,
|
|
15
19
|
generateIssueManagementMcpConfig
|
|
16
|
-
} from "./chunk-
|
|
17
|
-
import "./chunk-7Q66W4OH.js";
|
|
20
|
+
} from "./chunk-FM4KBPVA.js";
|
|
18
21
|
import {
|
|
19
22
|
ProcessManager
|
|
20
|
-
} from "./chunk-
|
|
21
|
-
import {
|
|
22
|
-
detectPackageManager,
|
|
23
|
-
installDependencies,
|
|
24
|
-
runScript
|
|
25
|
-
} from "./chunk-AXX3QIKK.js";
|
|
23
|
+
} from "./chunk-453NC377.js";
|
|
26
24
|
import {
|
|
27
25
|
IdentifierParser
|
|
28
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-5V74K5ZA.js";
|
|
29
27
|
import {
|
|
30
28
|
createNeonProviderFromSettings
|
|
31
29
|
} from "./chunk-7LSSNB7Y.js";
|
|
32
30
|
import {
|
|
33
31
|
InitCommand,
|
|
34
32
|
ShellCompletion
|
|
35
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-FEAJR6PN.js";
|
|
36
34
|
import {
|
|
37
35
|
FirstRunManager
|
|
38
36
|
} from "./chunk-Q7POFB5Q.js";
|
|
@@ -40,29 +38,35 @@ import "./chunk-F2PWIRV4.js";
|
|
|
40
38
|
import {
|
|
41
39
|
IssueEnhancementService,
|
|
42
40
|
capitalizeFirstLetter
|
|
43
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-HVQNVRAF.js";
|
|
44
42
|
import {
|
|
45
43
|
ProjectCapabilityDetector
|
|
46
|
-
} from "./chunk-
|
|
47
|
-
import {
|
|
48
|
-
getPackageConfig,
|
|
49
|
-
hasScript
|
|
50
|
-
} from "./chunk-BXCPJJYM.js";
|
|
44
|
+
} from "./chunk-7GLZVDPQ.js";
|
|
51
45
|
import {
|
|
52
46
|
AgentManager
|
|
53
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-N7FVXZNI.js";
|
|
54
48
|
import {
|
|
55
|
-
|
|
56
|
-
|
|
49
|
+
CommitManager,
|
|
50
|
+
UserAbortedCommitError,
|
|
51
|
+
ValidationRunner
|
|
52
|
+
} from "./chunk-YQNSZKKT.js";
|
|
53
|
+
import {
|
|
54
|
+
installDependencies
|
|
55
|
+
} from "./chunk-RD7I2Q2F.js";
|
|
57
56
|
import {
|
|
58
57
|
GitWorktreeManager
|
|
59
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-UDRZY65Y.js";
|
|
59
|
+
import "./chunk-XPKN3QWY.js";
|
|
60
60
|
import {
|
|
61
61
|
PRManager
|
|
62
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-EPPPDVHD.js";
|
|
63
63
|
import {
|
|
64
64
|
openBrowser
|
|
65
65
|
} from "./chunk-YETJNRQM.js";
|
|
66
|
+
import {
|
|
67
|
+
IssueManagementProviderFactory
|
|
68
|
+
} from "./chunk-GJMEKEI5.js";
|
|
69
|
+
import "./chunk-HBJITKSZ.js";
|
|
66
70
|
import {
|
|
67
71
|
getConfiguredRepoFromSettings,
|
|
68
72
|
hasMultipleRemotes
|
|
@@ -74,16 +78,17 @@ import {
|
|
|
74
78
|
} from "./chunk-O7VL5N6S.js";
|
|
75
79
|
import {
|
|
76
80
|
ClaudeContextManager
|
|
77
|
-
} from "./chunk-
|
|
78
|
-
import "./chunk-
|
|
79
|
-
import "./chunk-
|
|
81
|
+
} from "./chunk-6TL3BYH6.js";
|
|
82
|
+
import "./chunk-KVS4XGBQ.js";
|
|
83
|
+
import "./chunk-TIYJEEVO.js";
|
|
80
84
|
import {
|
|
81
85
|
extractSettingsOverrides
|
|
82
86
|
} from "./chunk-GYCR2LOU.js";
|
|
83
87
|
import {
|
|
84
88
|
DefaultBranchNamingService
|
|
85
|
-
} from "./chunk-
|
|
89
|
+
} from "./chunk-C3AKFAIR.js";
|
|
86
90
|
import {
|
|
91
|
+
GitCommandError,
|
|
87
92
|
executeGitCommand,
|
|
88
93
|
extractIssueNumber,
|
|
89
94
|
findMainWorktreePathWithSettings,
|
|
@@ -91,30 +96,29 @@ import {
|
|
|
91
96
|
getMergeTargetBranch,
|
|
92
97
|
getRepoRoot,
|
|
93
98
|
isPlaceholderCommit,
|
|
99
|
+
isValidGitRepo,
|
|
94
100
|
pushBranchToRemote,
|
|
95
101
|
removePlaceholderCommitFromHead,
|
|
96
102
|
removePlaceholderCommitFromHistory
|
|
97
|
-
} from "./chunk-
|
|
103
|
+
} from "./chunk-ZA575VLF.js";
|
|
98
104
|
import {
|
|
99
105
|
SettingsManager
|
|
100
|
-
} from "./chunk-
|
|
106
|
+
} from "./chunk-WFQ5CLTR.js";
|
|
101
107
|
import {
|
|
102
108
|
MetadataManager
|
|
103
|
-
} from "./chunk-
|
|
109
|
+
} from "./chunk-VWGKGNJP.js";
|
|
104
110
|
import {
|
|
105
111
|
GitHubService
|
|
106
|
-
} from "./chunk-
|
|
107
|
-
import "./chunk-
|
|
112
|
+
} from "./chunk-USJSNHGG.js";
|
|
113
|
+
import "./chunk-GCPAZSGV.js";
|
|
108
114
|
import {
|
|
109
|
-
promptCommitAction,
|
|
110
115
|
promptConfirmation,
|
|
111
116
|
waitForKeypress
|
|
112
117
|
} from "./chunk-ZX3GTM7O.js";
|
|
113
118
|
import "./chunk-433MOLAU.js";
|
|
114
119
|
import {
|
|
115
|
-
detectClaudeCli,
|
|
116
120
|
launchClaude
|
|
117
|
-
} from "./chunk-
|
|
121
|
+
} from "./chunk-FP7G7DG3.js";
|
|
118
122
|
import {
|
|
119
123
|
getLogger,
|
|
120
124
|
withLogger
|
|
@@ -687,7 +691,8 @@ var EnhanceCommand = class {
|
|
|
687
691
|
"mcp__issue_management__get_issue",
|
|
688
692
|
"mcp__issue_management__get_comment",
|
|
689
693
|
"mcp__issue_management__create_comment",
|
|
690
|
-
"mcp__issue_management__update_comment"
|
|
694
|
+
"mcp__issue_management__update_comment",
|
|
695
|
+
"mcp__issue_management__create_issue"
|
|
691
696
|
];
|
|
692
697
|
disallowedTools = ["Bash(gh api:*)"];
|
|
693
698
|
getLogger().debug("Configured tool filtering for issue workflow", { allowedTools, disallowedTools });
|
|
@@ -815,860 +820,6 @@ IMPORTANT: When you create your analysis comment, tag @${author} in the "Questio
|
|
|
815
820
|
}
|
|
816
821
|
};
|
|
817
822
|
|
|
818
|
-
// src/lib/ValidationRunner.ts
|
|
819
|
-
var ValidationRunner = class {
|
|
820
|
-
constructor() {
|
|
821
|
-
}
|
|
822
|
-
/**
|
|
823
|
-
* Run all validations in sequence: typecheck → lint → test
|
|
824
|
-
* Fails fast on first error
|
|
825
|
-
*/
|
|
826
|
-
async runValidations(worktreePath, options = {}) {
|
|
827
|
-
const startTime = Date.now();
|
|
828
|
-
const steps = [];
|
|
829
|
-
if (!options.skipTypecheck) {
|
|
830
|
-
const typecheckResult = await this.runTypecheck(
|
|
831
|
-
worktreePath,
|
|
832
|
-
options.dryRun ?? false
|
|
833
|
-
);
|
|
834
|
-
steps.push(typecheckResult);
|
|
835
|
-
if (!typecheckResult.passed && !typecheckResult.skipped) {
|
|
836
|
-
return {
|
|
837
|
-
success: false,
|
|
838
|
-
steps,
|
|
839
|
-
totalDuration: Date.now() - startTime
|
|
840
|
-
};
|
|
841
|
-
}
|
|
842
|
-
}
|
|
843
|
-
if (!options.skipLint) {
|
|
844
|
-
const lintResult = await this.runLint(worktreePath, options.dryRun ?? false);
|
|
845
|
-
steps.push(lintResult);
|
|
846
|
-
if (!lintResult.passed && !lintResult.skipped) {
|
|
847
|
-
return { success: false, steps, totalDuration: Date.now() - startTime };
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
|
-
if (!options.skipTests) {
|
|
851
|
-
const testResult = await this.runTests(
|
|
852
|
-
worktreePath,
|
|
853
|
-
options.dryRun ?? false
|
|
854
|
-
);
|
|
855
|
-
steps.push(testResult);
|
|
856
|
-
if (!testResult.passed && !testResult.skipped) {
|
|
857
|
-
return { success: false, steps, totalDuration: Date.now() - startTime };
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
return { success: true, steps, totalDuration: Date.now() - startTime };
|
|
861
|
-
}
|
|
862
|
-
/**
|
|
863
|
-
* Run typecheck validation
|
|
864
|
-
* Prefers 'compile' script over 'typecheck' if both exist
|
|
865
|
-
*/
|
|
866
|
-
async runTypecheck(worktreePath, dryRun) {
|
|
867
|
-
const stepStartTime = Date.now();
|
|
868
|
-
let scriptToRun = null;
|
|
869
|
-
try {
|
|
870
|
-
const pkgJson = await getPackageConfig(worktreePath);
|
|
871
|
-
const hasCompileScript = hasScript(pkgJson, "compile");
|
|
872
|
-
const hasTypecheckScript = hasScript(pkgJson, "typecheck");
|
|
873
|
-
if (hasCompileScript) {
|
|
874
|
-
scriptToRun = "compile";
|
|
875
|
-
} else if (hasTypecheckScript) {
|
|
876
|
-
scriptToRun = "typecheck";
|
|
877
|
-
}
|
|
878
|
-
if (!scriptToRun) {
|
|
879
|
-
getLogger().debug("Skipping typecheck - no compile or typecheck script found");
|
|
880
|
-
return {
|
|
881
|
-
step: "typecheck",
|
|
882
|
-
passed: true,
|
|
883
|
-
skipped: true,
|
|
884
|
-
duration: Date.now() - stepStartTime
|
|
885
|
-
};
|
|
886
|
-
}
|
|
887
|
-
} catch (error) {
|
|
888
|
-
if (error instanceof Error && error.message.includes("package.json not found")) {
|
|
889
|
-
getLogger().debug("Skipping typecheck - no package.json found (non-Node.js project)");
|
|
890
|
-
return {
|
|
891
|
-
step: "typecheck",
|
|
892
|
-
passed: true,
|
|
893
|
-
skipped: true,
|
|
894
|
-
duration: Date.now() - stepStartTime
|
|
895
|
-
};
|
|
896
|
-
}
|
|
897
|
-
throw error;
|
|
898
|
-
}
|
|
899
|
-
const packageManager = await detectPackageManager(worktreePath);
|
|
900
|
-
if (dryRun) {
|
|
901
|
-
const command = packageManager === "npm" ? `npm run ${scriptToRun}` : `${packageManager} ${scriptToRun}`;
|
|
902
|
-
getLogger().info(`[DRY RUN] Would run: ${command}`);
|
|
903
|
-
return {
|
|
904
|
-
step: scriptToRun,
|
|
905
|
-
passed: true,
|
|
906
|
-
skipped: false,
|
|
907
|
-
duration: Date.now() - stepStartTime
|
|
908
|
-
};
|
|
909
|
-
}
|
|
910
|
-
getLogger().info(`Running ${scriptToRun}...`);
|
|
911
|
-
try {
|
|
912
|
-
await runScript(scriptToRun, worktreePath, [], { quiet: true });
|
|
913
|
-
getLogger().success(`${scriptToRun.charAt(0).toUpperCase() + scriptToRun.slice(1)} passed`);
|
|
914
|
-
return {
|
|
915
|
-
step: scriptToRun,
|
|
916
|
-
passed: true,
|
|
917
|
-
skipped: false,
|
|
918
|
-
duration: Date.now() - stepStartTime
|
|
919
|
-
};
|
|
920
|
-
} catch {
|
|
921
|
-
const fixed = await this.attemptClaudeFix(
|
|
922
|
-
scriptToRun,
|
|
923
|
-
worktreePath,
|
|
924
|
-
packageManager
|
|
925
|
-
);
|
|
926
|
-
if (fixed) {
|
|
927
|
-
return {
|
|
928
|
-
step: scriptToRun,
|
|
929
|
-
passed: true,
|
|
930
|
-
skipped: false,
|
|
931
|
-
duration: Date.now() - stepStartTime
|
|
932
|
-
};
|
|
933
|
-
}
|
|
934
|
-
const runCommand = packageManager === "npm" ? `npm run ${scriptToRun}` : `${packageManager} ${scriptToRun}`;
|
|
935
|
-
const stepLabel = scriptToRun.charAt(0).toUpperCase() + scriptToRun.slice(1);
|
|
936
|
-
throw new Error(
|
|
937
|
-
`Error: ${stepLabel} failed.
|
|
938
|
-
Fix type errors before merging.
|
|
939
|
-
|
|
940
|
-
Run '${runCommand}' to see detailed errors.`
|
|
941
|
-
);
|
|
942
|
-
}
|
|
943
|
-
}
|
|
944
|
-
/**
|
|
945
|
-
* Run lint validation
|
|
946
|
-
*/
|
|
947
|
-
async runLint(worktreePath, dryRun) {
|
|
948
|
-
const stepStartTime = Date.now();
|
|
949
|
-
try {
|
|
950
|
-
const pkgJson = await getPackageConfig(worktreePath);
|
|
951
|
-
const hasLintScript = hasScript(pkgJson, "lint");
|
|
952
|
-
if (!hasLintScript) {
|
|
953
|
-
getLogger().debug("Skipping lint - no lint script found");
|
|
954
|
-
return {
|
|
955
|
-
step: "lint",
|
|
956
|
-
passed: true,
|
|
957
|
-
skipped: true,
|
|
958
|
-
duration: Date.now() - stepStartTime
|
|
959
|
-
};
|
|
960
|
-
}
|
|
961
|
-
} catch (error) {
|
|
962
|
-
if (error instanceof Error && error.message.includes("package.json not found")) {
|
|
963
|
-
getLogger().debug("Skipping lint - no package.json found (non-Node.js project)");
|
|
964
|
-
return {
|
|
965
|
-
step: "lint",
|
|
966
|
-
passed: true,
|
|
967
|
-
skipped: true,
|
|
968
|
-
duration: Date.now() - stepStartTime
|
|
969
|
-
};
|
|
970
|
-
}
|
|
971
|
-
throw error;
|
|
972
|
-
}
|
|
973
|
-
const packageManager = await detectPackageManager(worktreePath);
|
|
974
|
-
if (dryRun) {
|
|
975
|
-
const command = packageManager === "npm" ? "npm run lint" : `${packageManager} lint`;
|
|
976
|
-
getLogger().info(`[DRY RUN] Would run: ${command}`);
|
|
977
|
-
return {
|
|
978
|
-
step: "lint",
|
|
979
|
-
passed: true,
|
|
980
|
-
skipped: false,
|
|
981
|
-
duration: Date.now() - stepStartTime
|
|
982
|
-
};
|
|
983
|
-
}
|
|
984
|
-
getLogger().info("Running lint...");
|
|
985
|
-
try {
|
|
986
|
-
await runScript("lint", worktreePath, [], { quiet: true });
|
|
987
|
-
getLogger().success("Linting passed");
|
|
988
|
-
return {
|
|
989
|
-
step: "lint",
|
|
990
|
-
passed: true,
|
|
991
|
-
skipped: false,
|
|
992
|
-
duration: Date.now() - stepStartTime
|
|
993
|
-
};
|
|
994
|
-
} catch {
|
|
995
|
-
const fixed = await this.attemptClaudeFix(
|
|
996
|
-
"lint",
|
|
997
|
-
worktreePath,
|
|
998
|
-
packageManager
|
|
999
|
-
);
|
|
1000
|
-
if (fixed) {
|
|
1001
|
-
return {
|
|
1002
|
-
step: "lint",
|
|
1003
|
-
passed: true,
|
|
1004
|
-
skipped: false,
|
|
1005
|
-
duration: Date.now() - stepStartTime
|
|
1006
|
-
};
|
|
1007
|
-
}
|
|
1008
|
-
const runCommand = packageManager === "npm" ? "npm run lint" : `${packageManager} lint`;
|
|
1009
|
-
throw new Error(
|
|
1010
|
-
`Error: Linting failed.
|
|
1011
|
-
Fix linting errors before merging.
|
|
1012
|
-
|
|
1013
|
-
Run '${runCommand}' to see detailed errors.`
|
|
1014
|
-
);
|
|
1015
|
-
}
|
|
1016
|
-
}
|
|
1017
|
-
/**
|
|
1018
|
-
* Run test validation
|
|
1019
|
-
*/
|
|
1020
|
-
async runTests(worktreePath, dryRun) {
|
|
1021
|
-
const stepStartTime = Date.now();
|
|
1022
|
-
try {
|
|
1023
|
-
const pkgJson = await getPackageConfig(worktreePath);
|
|
1024
|
-
const hasTestScript = hasScript(pkgJson, "test");
|
|
1025
|
-
if (!hasTestScript) {
|
|
1026
|
-
getLogger().debug("Skipping tests - no test script found");
|
|
1027
|
-
return {
|
|
1028
|
-
step: "test",
|
|
1029
|
-
passed: true,
|
|
1030
|
-
skipped: true,
|
|
1031
|
-
duration: Date.now() - stepStartTime
|
|
1032
|
-
};
|
|
1033
|
-
}
|
|
1034
|
-
} catch (error) {
|
|
1035
|
-
if (error instanceof Error && error.message.includes("package.json not found")) {
|
|
1036
|
-
getLogger().debug("Skipping tests - no package.json found (non-Node.js project)");
|
|
1037
|
-
return {
|
|
1038
|
-
step: "test",
|
|
1039
|
-
passed: true,
|
|
1040
|
-
skipped: true,
|
|
1041
|
-
duration: Date.now() - stepStartTime
|
|
1042
|
-
};
|
|
1043
|
-
}
|
|
1044
|
-
throw error;
|
|
1045
|
-
}
|
|
1046
|
-
const packageManager = await detectPackageManager(worktreePath);
|
|
1047
|
-
if (dryRun) {
|
|
1048
|
-
const command = packageManager === "npm" ? "npm run test" : `${packageManager} test`;
|
|
1049
|
-
getLogger().info(`[DRY RUN] Would run: ${command}`);
|
|
1050
|
-
return {
|
|
1051
|
-
step: "test",
|
|
1052
|
-
passed: true,
|
|
1053
|
-
skipped: false,
|
|
1054
|
-
duration: Date.now() - stepStartTime
|
|
1055
|
-
};
|
|
1056
|
-
}
|
|
1057
|
-
getLogger().info("Running tests...");
|
|
1058
|
-
try {
|
|
1059
|
-
await runScript("test", worktreePath, [], { quiet: true });
|
|
1060
|
-
getLogger().success("Tests passed");
|
|
1061
|
-
return {
|
|
1062
|
-
step: "test",
|
|
1063
|
-
passed: true,
|
|
1064
|
-
skipped: false,
|
|
1065
|
-
duration: Date.now() - stepStartTime
|
|
1066
|
-
};
|
|
1067
|
-
} catch {
|
|
1068
|
-
const fixed = await this.attemptClaudeFix(
|
|
1069
|
-
"test",
|
|
1070
|
-
worktreePath,
|
|
1071
|
-
packageManager
|
|
1072
|
-
);
|
|
1073
|
-
if (fixed) {
|
|
1074
|
-
return {
|
|
1075
|
-
step: "test",
|
|
1076
|
-
passed: true,
|
|
1077
|
-
skipped: false,
|
|
1078
|
-
duration: Date.now() - stepStartTime
|
|
1079
|
-
};
|
|
1080
|
-
}
|
|
1081
|
-
const runCommand = packageManager === "npm" ? "npm run test" : `${packageManager} test`;
|
|
1082
|
-
throw new Error(
|
|
1083
|
-
`Error: Tests failed.
|
|
1084
|
-
Fix test failures before merging.
|
|
1085
|
-
|
|
1086
|
-
Run '${runCommand}' to see detailed errors.`
|
|
1087
|
-
);
|
|
1088
|
-
}
|
|
1089
|
-
}
|
|
1090
|
-
/**
|
|
1091
|
-
* Attempt to fix validation errors using Claude
|
|
1092
|
-
* Pattern based on MergeManager.attemptClaudeConflictResolution
|
|
1093
|
-
*
|
|
1094
|
-
* @param validationType - Type of validation that failed ('compile' | 'typecheck' | 'lint' | 'test')
|
|
1095
|
-
* @param worktreePath - Path to the worktree
|
|
1096
|
-
* @param packageManager - Detected package manager
|
|
1097
|
-
* @returns true if Claude fixed the issue, false otherwise
|
|
1098
|
-
*/
|
|
1099
|
-
async attemptClaudeFix(validationType, worktreePath, packageManager) {
|
|
1100
|
-
const isClaudeAvailable = await detectClaudeCli();
|
|
1101
|
-
if (!isClaudeAvailable) {
|
|
1102
|
-
getLogger().debug("Claude CLI not available, skipping auto-fix");
|
|
1103
|
-
return false;
|
|
1104
|
-
}
|
|
1105
|
-
const validationCommand = this.getValidationCommand(validationType, packageManager);
|
|
1106
|
-
const prompt = this.getClaudePrompt(validationType, validationCommand);
|
|
1107
|
-
const validationTypeCapitalized = validationType.charAt(0).toUpperCase() + validationType.slice(1);
|
|
1108
|
-
getLogger().info(`Launching Claude to help fix ${validationTypeCapitalized} errors...`);
|
|
1109
|
-
try {
|
|
1110
|
-
await launchClaude(prompt, {
|
|
1111
|
-
addDir: worktreePath,
|
|
1112
|
-
headless: false,
|
|
1113
|
-
// Interactive mode
|
|
1114
|
-
permissionMode: "acceptEdits",
|
|
1115
|
-
// Auto-accept edits
|
|
1116
|
-
model: "sonnet"
|
|
1117
|
-
// Use Sonnet model
|
|
1118
|
-
});
|
|
1119
|
-
getLogger().info(`Re-running ${validationTypeCapitalized} after Claude's fixes...`);
|
|
1120
|
-
try {
|
|
1121
|
-
await runScript(validationType, worktreePath, [], { quiet: true });
|
|
1122
|
-
getLogger().success(`${validationTypeCapitalized} passed after Claude auto-fix`);
|
|
1123
|
-
return true;
|
|
1124
|
-
} catch {
|
|
1125
|
-
getLogger().warn(`${validationTypeCapitalized} still failing after Claude's help`);
|
|
1126
|
-
return false;
|
|
1127
|
-
}
|
|
1128
|
-
} catch (error) {
|
|
1129
|
-
getLogger().warn("Claude auto-fix failed", {
|
|
1130
|
-
error: error instanceof Error ? error.message : String(error)
|
|
1131
|
-
});
|
|
1132
|
-
return false;
|
|
1133
|
-
}
|
|
1134
|
-
}
|
|
1135
|
-
/**
|
|
1136
|
-
* Get validation command string for prompts
|
|
1137
|
-
* Uses il commands for multi-language project support
|
|
1138
|
-
*/
|
|
1139
|
-
getValidationCommand(validationType, _packageManager) {
|
|
1140
|
-
return `il ${validationType}`;
|
|
1141
|
-
}
|
|
1142
|
-
/**
|
|
1143
|
-
* Get Claude prompt for specific validation type
|
|
1144
|
-
* Matches bash script prompts exactly
|
|
1145
|
-
*/
|
|
1146
|
-
getClaudePrompt(validationType, validationCommand) {
|
|
1147
|
-
switch (validationType) {
|
|
1148
|
-
case "compile":
|
|
1149
|
-
case "typecheck":
|
|
1150
|
-
return `There are TypeScript errors in this codebase. Please analyze the ${validationType} output, identify all type errors, and fix them. Run '${validationCommand}' to see the errors, then make the necessary code changes to resolve all type issues. When you are done, tell the user to quit using /exit to continue the validation process.`;
|
|
1151
|
-
case "lint":
|
|
1152
|
-
return `There are ESLint errors in this codebase. Please analyze the linting output, identify all linting issues, and fix them. Run '${validationCommand}' to see the errors, then make the necessary code changes to resolve all linting issues. Focus on code quality, consistency, and following the project's linting rules. When you are done, tell the user to quit using /exit to continue the validation process.`;
|
|
1153
|
-
case "test":
|
|
1154
|
-
return `There are unit test failures in this codebase. Please analyze the test output to understand what's failing, then fix the issues. This might involve updating test code, fixing bugs in the source code, or updating tests to match new behavior. Run '${validationCommand}' to see the detailed test failures, then make the necessary changes to get all tests passing. When you are done, tell the user to quit using /exit to continue the validation process.`;
|
|
1155
|
-
}
|
|
1156
|
-
}
|
|
1157
|
-
};
|
|
1158
|
-
|
|
1159
|
-
// src/utils/vscode.ts
|
|
1160
|
-
import { execa } from "execa";
|
|
1161
|
-
function isRunningInVSCode() {
|
|
1162
|
-
return process.env.TERM_PROGRAM === "vscode";
|
|
1163
|
-
}
|
|
1164
|
-
function isRunningInCursor() {
|
|
1165
|
-
return !!process.env.CURSOR_TRACE_ID;
|
|
1166
|
-
}
|
|
1167
|
-
function isRunningInAntigravity() {
|
|
1168
|
-
return !!process.env.ANTIGRAVITY_CLI_ALIAS;
|
|
1169
|
-
}
|
|
1170
|
-
async function isVSCodeAvailable() {
|
|
1171
|
-
try {
|
|
1172
|
-
await execa("command", ["-v", "code"], {
|
|
1173
|
-
shell: true,
|
|
1174
|
-
timeout: 5e3
|
|
1175
|
-
});
|
|
1176
|
-
return true;
|
|
1177
|
-
} catch (error) {
|
|
1178
|
-
logger.debug("VSCode CLI not available", { error });
|
|
1179
|
-
return false;
|
|
1180
|
-
}
|
|
1181
|
-
}
|
|
1182
|
-
async function isCursorAvailable() {
|
|
1183
|
-
try {
|
|
1184
|
-
await execa("command", ["-v", "cursor"], {
|
|
1185
|
-
shell: true,
|
|
1186
|
-
timeout: 5e3
|
|
1187
|
-
});
|
|
1188
|
-
return true;
|
|
1189
|
-
} catch (error) {
|
|
1190
|
-
logger.debug("Cursor CLI not available", { error });
|
|
1191
|
-
return false;
|
|
1192
|
-
}
|
|
1193
|
-
}
|
|
1194
|
-
async function isAntigravityAvailable() {
|
|
1195
|
-
try {
|
|
1196
|
-
await execa("command", ["-v", "agy"], {
|
|
1197
|
-
shell: true,
|
|
1198
|
-
timeout: 5e3
|
|
1199
|
-
});
|
|
1200
|
-
return true;
|
|
1201
|
-
} catch (error) {
|
|
1202
|
-
logger.debug("Antigravity CLI not available", { error });
|
|
1203
|
-
return false;
|
|
1204
|
-
}
|
|
1205
|
-
}
|
|
1206
|
-
|
|
1207
|
-
// src/types/index.ts
|
|
1208
|
-
var UserAbortedCommitError = class extends Error {
|
|
1209
|
-
constructor(message = "User aborted the commit") {
|
|
1210
|
-
super(message);
|
|
1211
|
-
this.name = "UserAbortedCommitError";
|
|
1212
|
-
}
|
|
1213
|
-
};
|
|
1214
|
-
|
|
1215
|
-
// src/lib/CommitManager.ts
|
|
1216
|
-
import { writeFile, readFile as readFile2, unlink } from "fs/promises";
|
|
1217
|
-
import { join } from "path";
|
|
1218
|
-
import { execa as execa2 } from "execa";
|
|
1219
|
-
var CommitManager = class {
|
|
1220
|
-
constructor() {
|
|
1221
|
-
}
|
|
1222
|
-
/**
|
|
1223
|
-
* Detect uncommitted changes in a worktree
|
|
1224
|
-
* Parses git status --porcelain output into structured GitStatus
|
|
1225
|
-
*/
|
|
1226
|
-
async detectUncommittedChanges(worktreePath) {
|
|
1227
|
-
const porcelainOutput = await executeGitCommand(["status", "--porcelain"], {
|
|
1228
|
-
cwd: worktreePath
|
|
1229
|
-
});
|
|
1230
|
-
const { stagedFiles, unstagedFiles } = this.parseGitStatus(porcelainOutput);
|
|
1231
|
-
const currentBranch = await executeGitCommand(["branch", "--show-current"], {
|
|
1232
|
-
cwd: worktreePath
|
|
1233
|
-
});
|
|
1234
|
-
return {
|
|
1235
|
-
hasUncommittedChanges: stagedFiles.length > 0 || unstagedFiles.length > 0,
|
|
1236
|
-
unstagedFiles,
|
|
1237
|
-
stagedFiles,
|
|
1238
|
-
currentBranch: currentBranch.trim(),
|
|
1239
|
-
// Defer these to future enhancement
|
|
1240
|
-
isAheadOfRemote: false,
|
|
1241
|
-
isBehindRemote: false
|
|
1242
|
-
};
|
|
1243
|
-
}
|
|
1244
|
-
/**
|
|
1245
|
-
* Stage all changes and commit with Claude-generated or simple message
|
|
1246
|
-
* Tries Claude first, falls back to simple message if Claude unavailable or fails
|
|
1247
|
-
*/
|
|
1248
|
-
async commitChanges(worktreePath, options) {
|
|
1249
|
-
if (options.dryRun) {
|
|
1250
|
-
getLogger().info("[DRY RUN] Would run: git add -A");
|
|
1251
|
-
getLogger().info("[DRY RUN] Would generate commit message with Claude (if available)");
|
|
1252
|
-
const fallbackMessage = this.generateFallbackMessage(options);
|
|
1253
|
-
const verifyFlag = options.skipVerify ? " --no-verify" : "";
|
|
1254
|
-
getLogger().info(`[DRY RUN] Would commit with message${verifyFlag}: ${fallbackMessage}`);
|
|
1255
|
-
return;
|
|
1256
|
-
}
|
|
1257
|
-
await executeGitCommand(["add", "-A"], { cwd: worktreePath });
|
|
1258
|
-
let message = null;
|
|
1259
|
-
if (!options.message) {
|
|
1260
|
-
try {
|
|
1261
|
-
message = await this.generateClaudeCommitMessage(worktreePath, options.issueNumber);
|
|
1262
|
-
} catch (error) {
|
|
1263
|
-
getLogger().debug("Claude commit message generation failed, using fallback", { error });
|
|
1264
|
-
}
|
|
1265
|
-
}
|
|
1266
|
-
message ??= this.generateFallbackMessage(options);
|
|
1267
|
-
if (options.skipVerify) {
|
|
1268
|
-
getLogger().warn("Skipping pre-commit hooks (--no-verify configured in settings)");
|
|
1269
|
-
}
|
|
1270
|
-
try {
|
|
1271
|
-
if (options.noReview || options.message) {
|
|
1272
|
-
const commitArgs = ["commit", "-m", message];
|
|
1273
|
-
if (options.skipVerify) {
|
|
1274
|
-
commitArgs.push("--no-verify");
|
|
1275
|
-
}
|
|
1276
|
-
await executeGitCommand(commitArgs, { cwd: worktreePath });
|
|
1277
|
-
} else {
|
|
1278
|
-
const action = await promptCommitAction(message);
|
|
1279
|
-
if (action === "abort") {
|
|
1280
|
-
throw new UserAbortedCommitError();
|
|
1281
|
-
}
|
|
1282
|
-
if (action === "accept") {
|
|
1283
|
-
const commitArgs = ["commit", "-m", message];
|
|
1284
|
-
if (options.skipVerify) {
|
|
1285
|
-
commitArgs.push("--no-verify");
|
|
1286
|
-
}
|
|
1287
|
-
await executeGitCommand(commitArgs, { cwd: worktreePath });
|
|
1288
|
-
} else {
|
|
1289
|
-
getLogger().info("Opening editor for commit message review...");
|
|
1290
|
-
if (isRunningInAntigravity() && await isAntigravityAvailable()) {
|
|
1291
|
-
await this.commitWithExternalEditor(worktreePath, message, options, "agy", "Antigravity");
|
|
1292
|
-
} else if (isRunningInCursor() && await isCursorAvailable()) {
|
|
1293
|
-
await this.commitWithExternalEditor(worktreePath, message, options, "cursor", "Cursor");
|
|
1294
|
-
} else if (isRunningInVSCode() && await isVSCodeAvailable()) {
|
|
1295
|
-
await this.commitWithExternalEditor(worktreePath, message, options, "code", "VSCode");
|
|
1296
|
-
} else {
|
|
1297
|
-
const commitArgs = ["commit", "-e", "-m", message];
|
|
1298
|
-
if (options.skipVerify) {
|
|
1299
|
-
commitArgs.push("--no-verify");
|
|
1300
|
-
}
|
|
1301
|
-
await executeGitCommand(commitArgs, {
|
|
1302
|
-
cwd: worktreePath,
|
|
1303
|
-
stdio: "inherit",
|
|
1304
|
-
timeout: 3e5
|
|
1305
|
-
// 5 minutes for interactive editing
|
|
1306
|
-
});
|
|
1307
|
-
}
|
|
1308
|
-
}
|
|
1309
|
-
}
|
|
1310
|
-
} catch (error) {
|
|
1311
|
-
if (error instanceof UserAbortedCommitError) {
|
|
1312
|
-
throw error;
|
|
1313
|
-
}
|
|
1314
|
-
if (error instanceof Error && error.message.includes("nothing to commit")) {
|
|
1315
|
-
getLogger().info("No changes to commit");
|
|
1316
|
-
return;
|
|
1317
|
-
}
|
|
1318
|
-
throw error;
|
|
1319
|
-
}
|
|
1320
|
-
}
|
|
1321
|
-
/**
|
|
1322
|
-
* Commit with external editor CLI (VSCode, Cursor, Antigravity, etc.)
|
|
1323
|
-
* Handles file creation, editing, and commit to ensure the file opens
|
|
1324
|
-
* in the current editor window (preserves IPC context)
|
|
1325
|
-
*/
|
|
1326
|
-
async commitWithExternalEditor(worktreePath, message, options, cliCommand, editorName) {
|
|
1327
|
-
const commitMsgPath = join(worktreePath, ".COMMIT_EDITMSG");
|
|
1328
|
-
const initialContent = `${message}
|
|
1329
|
-
|
|
1330
|
-
# Please enter the commit message for your changes. Lines starting
|
|
1331
|
-
# with '#' will be ignored, and an empty message aborts the commit.
|
|
1332
|
-
#
|
|
1333
|
-
# Save and close the file to complete the commit.
|
|
1334
|
-
`;
|
|
1335
|
-
await writeFile(commitMsgPath, initialContent, "utf-8");
|
|
1336
|
-
try {
|
|
1337
|
-
getLogger().debug(`Opening commit message in ${editorName}: ${commitMsgPath}`);
|
|
1338
|
-
await execa2(cliCommand, ["--wait", commitMsgPath], {
|
|
1339
|
-
cwd: worktreePath,
|
|
1340
|
-
stdio: "inherit"
|
|
1341
|
-
});
|
|
1342
|
-
const editedContent = await readFile2(commitMsgPath, "utf-8");
|
|
1343
|
-
const finalMessage = editedContent.split("\n").filter((line) => !line.startsWith("#")).join("\n").trim();
|
|
1344
|
-
if (!finalMessage) {
|
|
1345
|
-
throw new UserAbortedCommitError();
|
|
1346
|
-
}
|
|
1347
|
-
const commitArgs = ["commit", "-F", commitMsgPath];
|
|
1348
|
-
if (options.skipVerify) {
|
|
1349
|
-
commitArgs.push("--no-verify");
|
|
1350
|
-
}
|
|
1351
|
-
await writeFile(commitMsgPath, finalMessage, "utf-8");
|
|
1352
|
-
await executeGitCommand(commitArgs, { cwd: worktreePath });
|
|
1353
|
-
} finally {
|
|
1354
|
-
try {
|
|
1355
|
-
await unlink(commitMsgPath);
|
|
1356
|
-
} catch {
|
|
1357
|
-
}
|
|
1358
|
-
}
|
|
1359
|
-
}
|
|
1360
|
-
/**
|
|
1361
|
-
* Generate simple fallback commit message when Claude unavailable
|
|
1362
|
-
* Used as fallback for Claude-powered commit messages
|
|
1363
|
-
*/
|
|
1364
|
-
generateFallbackMessage(options) {
|
|
1365
|
-
if (options.message) {
|
|
1366
|
-
return options.message;
|
|
1367
|
-
}
|
|
1368
|
-
if (options.issueNumber) {
|
|
1369
|
-
return `WIP: Auto-commit for issue #${options.issueNumber}
|
|
1370
|
-
|
|
1371
|
-
Fixes #${options.issueNumber}`;
|
|
1372
|
-
} else {
|
|
1373
|
-
return "WIP: Auto-commit uncommitted changes";
|
|
1374
|
-
}
|
|
1375
|
-
}
|
|
1376
|
-
/**
|
|
1377
|
-
* Parse git status --porcelain output
|
|
1378
|
-
* Format: "XY filename" where X=index, Y=worktree
|
|
1379
|
-
* Examples:
|
|
1380
|
-
* "M file.ts" - staged modification
|
|
1381
|
-
* " M file.ts" - unstaged modification
|
|
1382
|
-
* "MM file.ts" - both staged and unstaged
|
|
1383
|
-
* "?? file.ts" - untracked
|
|
1384
|
-
*/
|
|
1385
|
-
parseGitStatus(porcelainOutput) {
|
|
1386
|
-
const stagedFiles = [];
|
|
1387
|
-
const unstagedFiles = [];
|
|
1388
|
-
if (!porcelainOutput.trim()) {
|
|
1389
|
-
return { stagedFiles, unstagedFiles };
|
|
1390
|
-
}
|
|
1391
|
-
const lines = porcelainOutput.split("\n").filter((line) => line.trim());
|
|
1392
|
-
for (const line of lines) {
|
|
1393
|
-
if (line.length < 3) continue;
|
|
1394
|
-
const indexStatus = line[0];
|
|
1395
|
-
const worktreeStatus = line[1];
|
|
1396
|
-
const filename = line.substring(3);
|
|
1397
|
-
if (indexStatus !== " " && indexStatus !== "?") {
|
|
1398
|
-
stagedFiles.push(filename);
|
|
1399
|
-
}
|
|
1400
|
-
if (worktreeStatus !== " " || line.startsWith("??")) {
|
|
1401
|
-
unstagedFiles.push(filename);
|
|
1402
|
-
}
|
|
1403
|
-
}
|
|
1404
|
-
return { stagedFiles, unstagedFiles };
|
|
1405
|
-
}
|
|
1406
|
-
/**
|
|
1407
|
-
* Generate commit message using Claude Code
|
|
1408
|
-
* Claude examines the git repository directly via --add-dir option
|
|
1409
|
-
* Returns null if Claude unavailable or fails validation
|
|
1410
|
-
*/
|
|
1411
|
-
async generateClaudeCommitMessage(worktreePath, issueNumber) {
|
|
1412
|
-
const startTime = Date.now();
|
|
1413
|
-
getLogger().info("Starting Claude commit message generation...", {
|
|
1414
|
-
worktreePath: worktreePath.split("/").pop(),
|
|
1415
|
-
// Just show the folder name for privacy
|
|
1416
|
-
issueNumber
|
|
1417
|
-
});
|
|
1418
|
-
getLogger().debug("Checking Claude CLI availability...");
|
|
1419
|
-
const isClaudeAvailable = await detectClaudeCli();
|
|
1420
|
-
if (!isClaudeAvailable) {
|
|
1421
|
-
getLogger().info("Claude CLI not available, skipping Claude commit message generation");
|
|
1422
|
-
return null;
|
|
1423
|
-
}
|
|
1424
|
-
getLogger().debug("Claude CLI is available");
|
|
1425
|
-
getLogger().debug("Building commit message prompt...");
|
|
1426
|
-
const prompt = this.buildCommitMessagePrompt(issueNumber);
|
|
1427
|
-
getLogger().debug("Prompt built", { promptLength: prompt.length });
|
|
1428
|
-
getLogger().debug("Claude prompt content:", {
|
|
1429
|
-
prompt,
|
|
1430
|
-
truncatedPreview: prompt.substring(0, 500) + (prompt.length > 500 ? "...[truncated]" : "")
|
|
1431
|
-
});
|
|
1432
|
-
try {
|
|
1433
|
-
getLogger().info("Calling Claude CLI for commit message generation...");
|
|
1434
|
-
const claudeStartTime = Date.now();
|
|
1435
|
-
const claudeOptions = {
|
|
1436
|
-
headless: true,
|
|
1437
|
-
addDir: worktreePath,
|
|
1438
|
-
model: "claude-haiku-4-5-20251001",
|
|
1439
|
-
// Fast, cost-effective model
|
|
1440
|
-
timeout: 12e4,
|
|
1441
|
-
// 120 second timeout
|
|
1442
|
-
appendSystemPrompt: "Output only the requested content. Never include preamble, analysis, or meta-commentary. Your response is used verbatim."
|
|
1443
|
-
};
|
|
1444
|
-
getLogger().debug("Claude CLI call parameters:", {
|
|
1445
|
-
options: claudeOptions,
|
|
1446
|
-
worktreePathForAnalysis: worktreePath,
|
|
1447
|
-
addDirContents: "Will include entire worktree directory for analysis"
|
|
1448
|
-
});
|
|
1449
|
-
const result = await launchClaude(prompt, claudeOptions);
|
|
1450
|
-
const claudeDuration = Date.now() - claudeStartTime;
|
|
1451
|
-
getLogger().debug("Claude API call completed", { duration: `${claudeDuration}ms` });
|
|
1452
|
-
if (typeof result !== "string") {
|
|
1453
|
-
getLogger().warn("Claude returned non-string result", { resultType: typeof result });
|
|
1454
|
-
return null;
|
|
1455
|
-
}
|
|
1456
|
-
getLogger().debug("Raw Claude output received", {
|
|
1457
|
-
outputLength: result.length,
|
|
1458
|
-
preview: result.substring(0, 200) + (result.length > 200 ? "..." : "")
|
|
1459
|
-
});
|
|
1460
|
-
getLogger().debug("Sanitizing Claude output...");
|
|
1461
|
-
const sanitized = this.sanitizeClaudeOutput(result);
|
|
1462
|
-
getLogger().debug("Output sanitized", {
|
|
1463
|
-
originalLength: result.length,
|
|
1464
|
-
sanitizedLength: sanitized.length,
|
|
1465
|
-
sanitized: sanitized.substring(0, 200) + (sanitized.length > 200 ? "..." : "")
|
|
1466
|
-
});
|
|
1467
|
-
if (!sanitized) {
|
|
1468
|
-
getLogger().warn("Claude returned empty message after sanitization");
|
|
1469
|
-
return null;
|
|
1470
|
-
}
|
|
1471
|
-
let finalMessage = sanitized;
|
|
1472
|
-
if (issueNumber) {
|
|
1473
|
-
if (!finalMessage.includes(`Fixes #${issueNumber}`)) {
|
|
1474
|
-
finalMessage = `${finalMessage}
|
|
1475
|
-
|
|
1476
|
-
Fixes #${issueNumber}`;
|
|
1477
|
-
getLogger().debug(`Added "Fixes #${issueNumber}" trailer to commit message`);
|
|
1478
|
-
} else {
|
|
1479
|
-
getLogger().debug(`"Fixes #${issueNumber}" already present in commit message`);
|
|
1480
|
-
}
|
|
1481
|
-
}
|
|
1482
|
-
const totalDuration = Date.now() - startTime;
|
|
1483
|
-
getLogger().info("Claude commit message generated successfully", {
|
|
1484
|
-
message: finalMessage,
|
|
1485
|
-
totalDuration: `${totalDuration}ms`,
|
|
1486
|
-
claudeApiDuration: `${claudeDuration}ms`
|
|
1487
|
-
});
|
|
1488
|
-
return finalMessage;
|
|
1489
|
-
} catch (error) {
|
|
1490
|
-
const totalDuration = Date.now() - startTime;
|
|
1491
|
-
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
1492
|
-
if (errorMessage.includes("timed out") || errorMessage.includes("timeout")) {
|
|
1493
|
-
getLogger().warn("Claude commit message generation timed out after 45 seconds", {
|
|
1494
|
-
totalDuration: `${totalDuration}ms`,
|
|
1495
|
-
worktreePath: worktreePath.split("/").pop()
|
|
1496
|
-
});
|
|
1497
|
-
} else {
|
|
1498
|
-
getLogger().warn("Failed to generate commit message with Claude", {
|
|
1499
|
-
error: errorMessage,
|
|
1500
|
-
totalDuration: `${totalDuration}ms`,
|
|
1501
|
-
worktreePath: worktreePath.split("/").pop()
|
|
1502
|
-
});
|
|
1503
|
-
}
|
|
1504
|
-
return null;
|
|
1505
|
-
}
|
|
1506
|
-
}
|
|
1507
|
-
/**
|
|
1508
|
-
* Build structured XML prompt for commit message generation
|
|
1509
|
-
* Uses XML format for clear task definition and output expectations
|
|
1510
|
-
*/
|
|
1511
|
-
buildCommitMessagePrompt(issueNumber) {
|
|
1512
|
-
const issueContext = issueNumber ? `
|
|
1513
|
-
<IssueContext>
|
|
1514
|
-
This commit is associated with GitHub issue #${issueNumber}.
|
|
1515
|
-
If the changes appear to resolve the issue, include "Fixes #${issueNumber}" at the end of the first line of commit message.
|
|
1516
|
-
</IssueContext>` : "";
|
|
1517
|
-
return `<Task>
|
|
1518
|
-
You are a software engineer writing a commit message for this repository.
|
|
1519
|
-
Examine the staged changes in the git repository and generate a concise, meaningful commit message.
|
|
1520
|
-
</Task>
|
|
1521
|
-
|
|
1522
|
-
<Requirements>
|
|
1523
|
-
<Format>The first line must be a brief summary of the changes made as a full sentence. If it references an issue, include "Fixes #N" at the end of this line.
|
|
1524
|
-
|
|
1525
|
-
Add 2 newlines, then add a bullet-point form description of the changes made, each change on a new line.</Format>
|
|
1526
|
-
<Mood>Use imperative mood (e.g., "Add feature" not "Added feature")</Mood>
|
|
1527
|
-
<Focus>Be specific about what was changed and why</Focus>
|
|
1528
|
-
<Conciseness>Keep message under 72 characters for subject line when possible</Conciseness>
|
|
1529
|
-
<NoMeta>CRITICAL: Do NOT include ANY explanatory text, analysis, or meta-commentary. Output ONLY the raw commit message.</NoMeta>
|
|
1530
|
-
<Examples>
|
|
1531
|
-
Good: "Add user authentication with JWT tokens. Fixes #42
|
|
1532
|
-
|
|
1533
|
-
- Implement login and registration endpoints
|
|
1534
|
-
- Secure routes with JWT middleware
|
|
1535
|
-
- Update user model to store hashed passwords"
|
|
1536
|
-
Good: "Fix navigation bug in sidebar menu."
|
|
1537
|
-
Bad: "Based on the changes, I'll create: Add user authentication"
|
|
1538
|
-
Bad: "Looking at the files, this commit should be: Fix navigation bug"
|
|
1539
|
-
</Examples>
|
|
1540
|
-
${issueContext}
|
|
1541
|
-
</Requirements>
|
|
1542
|
-
|
|
1543
|
-
<Output>
|
|
1544
|
-
IMPORTANT: Your entire response will be used directly as the git commit message.
|
|
1545
|
-
Do not include any explanatory text before or after the commit message.
|
|
1546
|
-
Start your response immediately with the commit message text.
|
|
1547
|
-
</Output>`;
|
|
1548
|
-
}
|
|
1549
|
-
/**
|
|
1550
|
-
* Sanitize Claude output to remove meta-commentary and clean formatting
|
|
1551
|
-
* Handles cases where Claude includes explanatory text despite instructions
|
|
1552
|
-
*/
|
|
1553
|
-
sanitizeClaudeOutput(rawOutput) {
|
|
1554
|
-
let cleaned = rawOutput.trim();
|
|
1555
|
-
const metaPatterns = [
|
|
1556
|
-
/^.*?based on.*?changes.*?:/i,
|
|
1557
|
-
/^.*?looking at.*?files.*?:/i,
|
|
1558
|
-
/^.*?examining.*?:/i,
|
|
1559
|
-
/^.*?analyzing.*?:/i,
|
|
1560
|
-
/^.*?i'll.*?generate.*?:/i,
|
|
1561
|
-
/^.*?let me.*?:/i,
|
|
1562
|
-
/^.*?the commit message.*?should be.*?:/i,
|
|
1563
|
-
/^.*?here.*?is.*?commit.*?message.*?:/i
|
|
1564
|
-
];
|
|
1565
|
-
for (const pattern of metaPatterns) {
|
|
1566
|
-
cleaned = cleaned.replace(pattern, "").trim();
|
|
1567
|
-
}
|
|
1568
|
-
if (cleaned.includes(":")) {
|
|
1569
|
-
const colonIndex = cleaned.indexOf(":");
|
|
1570
|
-
const beforeColon = cleaned.substring(0, colonIndex).trim().toLowerCase();
|
|
1571
|
-
const metaIndicators = [
|
|
1572
|
-
"here is the commit message",
|
|
1573
|
-
"commit message",
|
|
1574
|
-
"here is",
|
|
1575
|
-
"the message should be",
|
|
1576
|
-
"i suggest",
|
|
1577
|
-
"my suggestion"
|
|
1578
|
-
];
|
|
1579
|
-
const isMetaCommentary = metaIndicators.some((indicator) => beforeColon.includes(indicator));
|
|
1580
|
-
if (isMetaCommentary) {
|
|
1581
|
-
const afterColon = cleaned.substring(colonIndex + 1).trim();
|
|
1582
|
-
if (afterColon && afterColon.length > 10) {
|
|
1583
|
-
cleaned = afterColon;
|
|
1584
|
-
}
|
|
1585
|
-
}
|
|
1586
|
-
}
|
|
1587
|
-
if (cleaned.startsWith('"') && cleaned.endsWith('"') || cleaned.startsWith("'") && cleaned.endsWith("'")) {
|
|
1588
|
-
cleaned = cleaned.slice(1, -1).trim();
|
|
1589
|
-
}
|
|
1590
|
-
return cleaned;
|
|
1591
|
-
}
|
|
1592
|
-
};
|
|
1593
|
-
|
|
1594
|
-
// src/lib/BuildRunner.ts
|
|
1595
|
-
var BuildRunner = class {
|
|
1596
|
-
constructor(capabilityDetector) {
|
|
1597
|
-
this.capabilityDetector = capabilityDetector ?? new ProjectCapabilityDetector();
|
|
1598
|
-
}
|
|
1599
|
-
/**
|
|
1600
|
-
* Run build verification in the specified directory
|
|
1601
|
-
* @param buildPath - Path where build should run (typically main worktree path)
|
|
1602
|
-
* @param options - Build options
|
|
1603
|
-
*/
|
|
1604
|
-
async runBuild(buildPath, options = {}) {
|
|
1605
|
-
const startTime = Date.now();
|
|
1606
|
-
try {
|
|
1607
|
-
const pkgJson = await getPackageConfig(buildPath);
|
|
1608
|
-
const hasBuildScript = hasScript(pkgJson, "build");
|
|
1609
|
-
if (!hasBuildScript) {
|
|
1610
|
-
getLogger().debug("Skipping build - no build script found");
|
|
1611
|
-
return {
|
|
1612
|
-
success: true,
|
|
1613
|
-
skipped: true,
|
|
1614
|
-
reason: "No build script found in package configuration",
|
|
1615
|
-
duration: Date.now() - startTime
|
|
1616
|
-
};
|
|
1617
|
-
}
|
|
1618
|
-
} catch (error) {
|
|
1619
|
-
if (error instanceof Error && error.message.includes("package.json not found")) {
|
|
1620
|
-
getLogger().debug("Skipping build - no package configuration found");
|
|
1621
|
-
return {
|
|
1622
|
-
success: true,
|
|
1623
|
-
skipped: true,
|
|
1624
|
-
reason: "No package configuration found in project",
|
|
1625
|
-
duration: Date.now() - startTime
|
|
1626
|
-
};
|
|
1627
|
-
}
|
|
1628
|
-
throw error;
|
|
1629
|
-
}
|
|
1630
|
-
const capabilities = await this.capabilityDetector.detectCapabilities(buildPath);
|
|
1631
|
-
const isCLIProject = capabilities.capabilities.includes("cli");
|
|
1632
|
-
if (!isCLIProject) {
|
|
1633
|
-
getLogger().debug("Skipping build - not a CLI project (no bin field)");
|
|
1634
|
-
return {
|
|
1635
|
-
success: true,
|
|
1636
|
-
skipped: true,
|
|
1637
|
-
reason: "Project is not a CLI project (no bin field in package.json)",
|
|
1638
|
-
duration: Date.now() - startTime
|
|
1639
|
-
};
|
|
1640
|
-
}
|
|
1641
|
-
const packageManager = await detectPackageManager(buildPath);
|
|
1642
|
-
if (options.dryRun) {
|
|
1643
|
-
const command = packageManager === "npm" ? "npm run build" : `${packageManager} build`;
|
|
1644
|
-
getLogger().info(`[DRY RUN] Would run: ${command}`);
|
|
1645
|
-
return {
|
|
1646
|
-
success: true,
|
|
1647
|
-
skipped: false,
|
|
1648
|
-
duration: Date.now() - startTime
|
|
1649
|
-
};
|
|
1650
|
-
}
|
|
1651
|
-
getLogger().info("Running build...");
|
|
1652
|
-
try {
|
|
1653
|
-
await runScript("build", buildPath, [], { quiet: true });
|
|
1654
|
-
getLogger().success("Build completed successfully");
|
|
1655
|
-
return {
|
|
1656
|
-
success: true,
|
|
1657
|
-
skipped: false,
|
|
1658
|
-
duration: Date.now() - startTime
|
|
1659
|
-
};
|
|
1660
|
-
} catch {
|
|
1661
|
-
const runCommand = packageManager === "npm" ? "npm run build" : `${packageManager} build`;
|
|
1662
|
-
throw new Error(
|
|
1663
|
-
`Error: Build failed.
|
|
1664
|
-
Fix build errors before proceeding.
|
|
1665
|
-
|
|
1666
|
-
Run '${runCommand}' to see detailed errors.`
|
|
1667
|
-
);
|
|
1668
|
-
}
|
|
1669
|
-
}
|
|
1670
|
-
};
|
|
1671
|
-
|
|
1672
823
|
// src/commands/finish.ts
|
|
1673
824
|
import path3 from "path";
|
|
1674
825
|
var FinishCommand = class {
|
|
@@ -1709,7 +860,7 @@ var FinishCommand = class {
|
|
|
1709
860
|
const neonProvider = createNeonProviderFromSettings(settings);
|
|
1710
861
|
const databaseManager = new DatabaseManager(neonProvider, environmentManager, databaseUrlEnvVarName);
|
|
1711
862
|
const cliIsolationManager = new CLIIsolationManager();
|
|
1712
|
-
const { DefaultBranchNamingService: DefaultBranchNamingService2 } = await import("./BranchNamingService-
|
|
863
|
+
const { DefaultBranchNamingService: DefaultBranchNamingService2 } = await import("./BranchNamingService-FLPUUFOB.js");
|
|
1713
864
|
this.loomManager ??= new LoomManager(
|
|
1714
865
|
this.gitWorktreeManager,
|
|
1715
866
|
this.issueTracker,
|
|
@@ -1768,6 +919,7 @@ var FinishCommand = class {
|
|
|
1768
919
|
*/
|
|
1769
920
|
async execute(input) {
|
|
1770
921
|
var _a, _b, _c, _d;
|
|
922
|
+
process.env.ILOOM = "1";
|
|
1771
923
|
const isJsonMode = input.options.json === true;
|
|
1772
924
|
const result = {
|
|
1773
925
|
success: false,
|
|
@@ -2049,7 +1201,7 @@ var FinishCommand = class {
|
|
|
2049
1201
|
* This is the workflow: rebase → validate → commit → merge → cleanup
|
|
2050
1202
|
*/
|
|
2051
1203
|
async executeIssueWorkflow(parsed, options, worktree, result) {
|
|
2052
|
-
var _a, _b, _c;
|
|
1204
|
+
var _a, _b, _c, _d;
|
|
2053
1205
|
getLogger().info("Rebasing branch on main...");
|
|
2054
1206
|
const mergeOptions = {
|
|
2055
1207
|
dryRun: options.dryRun ?? false,
|
|
@@ -2094,9 +1246,12 @@ var FinishCommand = class {
|
|
|
2094
1246
|
getLogger().info("Validation passed, auto-committing uncommitted changes...");
|
|
2095
1247
|
const settings2 = await this.settingsManager.loadSettings(worktree.path);
|
|
2096
1248
|
const skipVerify = ((_b = (_a = settings2.workflows) == null ? void 0 : _a.issue) == null ? void 0 : _b.noVerify) ?? false;
|
|
1249
|
+
const providerType = ((_c = settings2.issueManagement) == null ? void 0 : _c.provider) ?? "github";
|
|
1250
|
+
const issuePrefix = IssueManagementProviderFactory.create(providerType).issuePrefix;
|
|
2097
1251
|
const commitOptions = {
|
|
2098
1252
|
dryRun: options.dryRun ?? false,
|
|
2099
|
-
skipVerify
|
|
1253
|
+
skipVerify,
|
|
1254
|
+
issuePrefix
|
|
2100
1255
|
};
|
|
2101
1256
|
if (parsed.type === "issue" && parsed.number) {
|
|
2102
1257
|
commitOptions.issueNumber = parsed.number;
|
|
@@ -2142,9 +1297,9 @@ var FinishCommand = class {
|
|
|
2142
1297
|
`The 'github-draft-pr' merge mode requires a GitHub-compatible issue tracker. Your provider (${this.issueTracker.providerName}) does not support pull requests.`
|
|
2143
1298
|
);
|
|
2144
1299
|
}
|
|
2145
|
-
const { MetadataManager:
|
|
2146
|
-
const
|
|
2147
|
-
const metadata = await
|
|
1300
|
+
const { MetadataManager: MetadataManager3 } = await import("./MetadataManager-XJ2YB762.js");
|
|
1301
|
+
const metadataManager2 = new MetadataManager3();
|
|
1302
|
+
const metadata = await metadataManager2.readMetadata(worktree.path);
|
|
2148
1303
|
getLogger().debug(`Draft PR mode: worktree=${worktree.path}, draftPrNumber=${(metadata == null ? void 0 : metadata.draftPrNumber) ?? "none"}`);
|
|
2149
1304
|
if (!(metadata == null ? void 0 : metadata.draftPrNumber)) {
|
|
2150
1305
|
getLogger().warn("No draft PR found in metadata, creating new PR...");
|
|
@@ -2209,7 +1364,7 @@ var FinishCommand = class {
|
|
|
2209
1364
|
} else {
|
|
2210
1365
|
getLogger().info(`[DRY RUN] Would mark PR #${metadata.draftPrNumber} as ready for review`);
|
|
2211
1366
|
}
|
|
2212
|
-
const prUrl = (
|
|
1367
|
+
const prUrl = (_d = metadata.prUrls) == null ? void 0 : _d[String(metadata.draftPrNumber)];
|
|
2213
1368
|
if (prUrl) {
|
|
2214
1369
|
result.prUrl = prUrl;
|
|
2215
1370
|
}
|
|
@@ -2243,7 +1398,17 @@ var FinishCommand = class {
|
|
|
2243
1398
|
getLogger().debug("Skipping build verification (--skip-build flag provided)");
|
|
2244
1399
|
}
|
|
2245
1400
|
await this.generateSessionSummaryIfConfigured(parsed, worktree, options);
|
|
2246
|
-
|
|
1401
|
+
const { MetadataManager: MetadataManager2 } = await import("./MetadataManager-XJ2YB762.js");
|
|
1402
|
+
const metadataManager = new MetadataManager2();
|
|
1403
|
+
if (!options.dryRun) {
|
|
1404
|
+
await metadataManager.archiveMetadata(worktree.path);
|
|
1405
|
+
}
|
|
1406
|
+
if (options.cleanup === false) {
|
|
1407
|
+
getLogger().info("Worktree kept active (--no-cleanup flag)");
|
|
1408
|
+
getLogger().info(`To cleanup later: il cleanup ${parsed.originalInput}`);
|
|
1409
|
+
} else {
|
|
1410
|
+
await this.performPostMergeCleanup(parsed, options, worktree, result);
|
|
1411
|
+
}
|
|
2247
1412
|
}
|
|
2248
1413
|
/**
|
|
2249
1414
|
* Execute workflow for Pull Requests
|
|
@@ -2252,7 +1417,7 @@ var FinishCommand = class {
|
|
|
2252
1417
|
* - CLOSED/MERGED: Skip to cleanup
|
|
2253
1418
|
*/
|
|
2254
1419
|
async executePRWorkflow(parsed, options, worktree, pr, result) {
|
|
2255
|
-
var _a, _b;
|
|
1420
|
+
var _a, _b, _c;
|
|
2256
1421
|
if (pr.state === "closed" || pr.state === "merged") {
|
|
2257
1422
|
getLogger().info(`PR #${parsed.number} is ${pr.state.toUpperCase()} - skipping to cleanup`);
|
|
2258
1423
|
const gitStatus = await this.commitManager.detectUncommittedChanges(worktree.path);
|
|
@@ -2262,6 +1427,11 @@ var FinishCommand = class {
|
|
|
2262
1427
|
"Cannot cleanup PR with uncommitted changes. Commit or stash changes, then run again with --force to cleanup anyway."
|
|
2263
1428
|
);
|
|
2264
1429
|
}
|
|
1430
|
+
const { MetadataManager: MetadataManager2 } = await import("./MetadataManager-XJ2YB762.js");
|
|
1431
|
+
const metadataManager = new MetadataManager2();
|
|
1432
|
+
if (!options.dryRun) {
|
|
1433
|
+
await metadataManager.archiveMetadata(worktree.path);
|
|
1434
|
+
}
|
|
2265
1435
|
await this.performPRCleanup(parsed, options, worktree, pr.state, result);
|
|
2266
1436
|
getLogger().success(`PR #${parsed.number} cleanup completed`);
|
|
2267
1437
|
result.operations.push({
|
|
@@ -2284,10 +1454,13 @@ var FinishCommand = class {
|
|
|
2284
1454
|
getLogger().info("Committing uncommitted changes...");
|
|
2285
1455
|
const settings = await this.settingsManager.loadSettings(worktree.path);
|
|
2286
1456
|
const skipVerify = ((_b = (_a = settings.workflows) == null ? void 0 : _a.pr) == null ? void 0 : _b.noVerify) ?? false;
|
|
1457
|
+
const providerType = ((_c = settings.issueManagement) == null ? void 0 : _c.provider) ?? "github";
|
|
1458
|
+
const issuePrefix = IssueManagementProviderFactory.create(providerType).issuePrefix;
|
|
2287
1459
|
try {
|
|
2288
1460
|
await this.commitManager.commitChanges(worktree.path, {
|
|
2289
1461
|
dryRun: false,
|
|
2290
|
-
skipVerify
|
|
1462
|
+
skipVerify,
|
|
1463
|
+
issuePrefix
|
|
2291
1464
|
// Do NOT pass issueNumber for PRs - no "Fixes #" trailer needed
|
|
2292
1465
|
});
|
|
2293
1466
|
getLogger().success("Changes committed");
|
|
@@ -2386,6 +1559,11 @@ var FinishCommand = class {
|
|
|
2386
1559
|
}
|
|
2387
1560
|
finishResult.prUrl = prResult.url;
|
|
2388
1561
|
await this.generateSessionSummaryIfConfigured(parsed, worktree, options, prResult.number);
|
|
1562
|
+
const { MetadataManager: MetadataManager2 } = await import("./MetadataManager-XJ2YB762.js");
|
|
1563
|
+
const metadataManager = new MetadataManager2();
|
|
1564
|
+
if (!options.dryRun) {
|
|
1565
|
+
await metadataManager.archiveMetadata(worktree.path);
|
|
1566
|
+
}
|
|
2389
1567
|
await this.handlePRCleanupPrompt(parsed, options, worktree, finishResult);
|
|
2390
1568
|
}
|
|
2391
1569
|
}
|
|
@@ -2740,7 +1918,7 @@ var FinishCommand = class {
|
|
|
2740
1918
|
// src/utils/package-info.ts
|
|
2741
1919
|
import { readFileSync } from "fs";
|
|
2742
1920
|
import { fileURLToPath } from "url";
|
|
2743
|
-
import { dirname, join
|
|
1921
|
+
import { dirname, join } from "path";
|
|
2744
1922
|
function getPackageInfo(scriptPath) {
|
|
2745
1923
|
try {
|
|
2746
1924
|
let basePath;
|
|
@@ -2751,7 +1929,7 @@ function getPackageInfo(scriptPath) {
|
|
|
2751
1929
|
basePath = __filename2;
|
|
2752
1930
|
}
|
|
2753
1931
|
const __dirname = dirname(basePath);
|
|
2754
|
-
const packageJsonPath =
|
|
1932
|
+
const packageJsonPath = join(__dirname, "..", "package.json");
|
|
2755
1933
|
const packageJsonContent = readFileSync(packageJsonPath, "utf8");
|
|
2756
1934
|
const packageJson2 = JSON.parse(packageJsonContent);
|
|
2757
1935
|
return packageJson2;
|
|
@@ -2830,12 +2008,40 @@ function formatLoomForJson(worktree, mainWorktreePath, metadata) {
|
|
|
2830
2008
|
colorHex: (metadata == null ? void 0 : metadata.colorHex) ?? null,
|
|
2831
2009
|
projectPath: (metadata == null ? void 0 : metadata.projectPath) ?? null,
|
|
2832
2010
|
issueUrls: (metadata == null ? void 0 : metadata.issueUrls) ?? {},
|
|
2833
|
-
prUrls: (metadata == null ? void 0 : metadata.prUrls) ?? {}
|
|
2011
|
+
prUrls: (metadata == null ? void 0 : metadata.prUrls) ?? {},
|
|
2012
|
+
capabilities: (metadata == null ? void 0 : metadata.capabilities) ?? []
|
|
2834
2013
|
};
|
|
2835
2014
|
}
|
|
2836
2015
|
function formatLoomsForJson(worktrees, mainWorktreePath, metadata) {
|
|
2837
2016
|
return worktrees.map((wt) => formatLoomForJson(wt, mainWorktreePath, metadata == null ? void 0 : metadata.get(wt.path)));
|
|
2838
2017
|
}
|
|
2018
|
+
function formatFinishedLoomForJson(metadata) {
|
|
2019
|
+
const loomType = metadata.issueType ?? "branch";
|
|
2020
|
+
return {
|
|
2021
|
+
name: metadata.branchName ?? metadata.worktreePath ?? "unknown",
|
|
2022
|
+
worktreePath: null,
|
|
2023
|
+
// Finished looms no longer have a worktree
|
|
2024
|
+
branch: metadata.branchName,
|
|
2025
|
+
type: loomType,
|
|
2026
|
+
issue_numbers: metadata.issue_numbers,
|
|
2027
|
+
pr_numbers: metadata.pr_numbers,
|
|
2028
|
+
isMainWorktree: false,
|
|
2029
|
+
// Finished looms are never the main worktree
|
|
2030
|
+
description: metadata.description ?? null,
|
|
2031
|
+
created_at: metadata.created_at ?? null,
|
|
2032
|
+
issueTracker: metadata.issueTracker ?? null,
|
|
2033
|
+
colorHex: metadata.colorHex ?? null,
|
|
2034
|
+
projectPath: metadata.projectPath ?? null,
|
|
2035
|
+
issueUrls: metadata.issueUrls ?? {},
|
|
2036
|
+
prUrls: metadata.prUrls ?? {},
|
|
2037
|
+
capabilities: metadata.capabilities ?? [],
|
|
2038
|
+
status: metadata.status ?? "finished",
|
|
2039
|
+
finishedAt: metadata.finishedAt ?? null
|
|
2040
|
+
};
|
|
2041
|
+
}
|
|
2042
|
+
|
|
2043
|
+
// src/cli.ts
|
|
2044
|
+
import fs3 from "fs-extra";
|
|
2839
2045
|
|
|
2840
2046
|
// src/lib/VersionMigrationManager.ts
|
|
2841
2047
|
import fs2 from "fs-extra";
|
|
@@ -2867,6 +2073,26 @@ var migrations = [
|
|
|
2867
2073
|
const newContent = content + separator + "\n# Added by iloom CLI\n" + pattern + "\n";
|
|
2868
2074
|
await fs.writeFile(globalIgnorePath, newContent, "utf-8");
|
|
2869
2075
|
}
|
|
2076
|
+
},
|
|
2077
|
+
{
|
|
2078
|
+
version: "0.7.1",
|
|
2079
|
+
description: "Add global gitignore for .iloom/package.iloom.local.json",
|
|
2080
|
+
migrate: async () => {
|
|
2081
|
+
const globalIgnorePath = path4.join(os.homedir(), ".config", "git", "ignore");
|
|
2082
|
+
const pattern = "**/.iloom/package.iloom.local.json";
|
|
2083
|
+
await fs.ensureDir(path4.dirname(globalIgnorePath));
|
|
2084
|
+
let content = "";
|
|
2085
|
+
try {
|
|
2086
|
+
content = await fs.readFile(globalIgnorePath, "utf-8");
|
|
2087
|
+
} catch {
|
|
2088
|
+
}
|
|
2089
|
+
if (content.includes(pattern)) {
|
|
2090
|
+
return;
|
|
2091
|
+
}
|
|
2092
|
+
const separator = content.endsWith("\n") || content === "" ? "" : "\n";
|
|
2093
|
+
const newContent = content + separator + "\n# Added by iloom CLI\n" + pattern + "\n";
|
|
2094
|
+
await fs.writeFile(globalIgnorePath, newContent, "utf-8");
|
|
2095
|
+
}
|
|
2870
2096
|
}
|
|
2871
2097
|
];
|
|
2872
2098
|
|
|
@@ -3162,14 +2388,14 @@ async function autoLaunchInitForMultipleRemotes() {
|
|
|
3162
2388
|
await waitForKeypress2("Press any key to start configuration...");
|
|
3163
2389
|
logger.info("");
|
|
3164
2390
|
try {
|
|
3165
|
-
const { InitCommand: InitCommand2 } = await import("./init-
|
|
2391
|
+
const { InitCommand: InitCommand2 } = await import("./init-XQQMFDM6.js");
|
|
3166
2392
|
const initCommand = new InitCommand2();
|
|
3167
2393
|
const customInitialMessage = "Help me configure which git remote iloom should use for GitHub operations. I have multiple remotes and need to select the correct one.";
|
|
3168
2394
|
await initCommand.execute(customInitialMessage);
|
|
3169
2395
|
logger.info("");
|
|
3170
2396
|
logger.info("Configuration complete! Continuing with your original command...");
|
|
3171
2397
|
logger.info("");
|
|
3172
|
-
const { SettingsManager: SettingsManager2 } = await import("./SettingsManager-
|
|
2398
|
+
const { SettingsManager: SettingsManager2 } = await import("./SettingsManager-YU4VYPTW.js");
|
|
3173
2399
|
const settingsManager = new SettingsManager2();
|
|
3174
2400
|
const settings = await settingsManager.loadSettings();
|
|
3175
2401
|
const { hasMultipleRemotes: hasMultipleRemotes2 } = await import("./remote-IJAMOEAP.js");
|
|
@@ -3263,7 +2489,7 @@ program.command("add-issue").alias("a").description("Create and enhance GitHub i
|
|
|
3263
2489
|
});
|
|
3264
2490
|
program.command("feedback").alias("f").description("Submit feedback/bug report to iloom-cli repository").argument("<description>", "Feedback title (>30 chars, >2 spaces; or any non-empty text when --body provided)").option("--body <text>", "Body text for feedback (added after diagnostics)").action(async (description, options) => {
|
|
3265
2491
|
try {
|
|
3266
|
-
const { FeedbackCommand } = await import("./feedback-
|
|
2492
|
+
const { FeedbackCommand } = await import("./feedback-K3A4QUSG.js");
|
|
3267
2493
|
const command = new FeedbackCommand();
|
|
3268
2494
|
const feedbackOptions = {};
|
|
3269
2495
|
if (options.body !== void 0) {
|
|
@@ -3313,7 +2539,7 @@ program.command("enhance").description("Apply enhancement agent to existing GitH
|
|
|
3313
2539
|
await executeAction();
|
|
3314
2540
|
}
|
|
3315
2541
|
});
|
|
3316
|
-
program.command("finish").alias("dn").description("Merge work and cleanup workspace").argument("[identifier]", "Issue number, PR number, or branch name (auto-detected if omitted)").option("-f, --force", "Skip confirmation prompts").option("-n, --dry-run", "Preview actions without executing").option("--pr <number>", "Treat input as PR number", parseFloat).option("--skip-build", "Skip post-merge build verification").option("--no-browser", "Skip opening PR in browser (github-pr mode only)").option("--cleanup", "Clean up worktree after
|
|
2542
|
+
program.command("finish").alias("dn").description("Merge work and cleanup workspace").argument("[identifier]", "Issue number, PR number, or branch name (auto-detected if omitted)").option("-f, --force", "Skip confirmation prompts").option("-n, --dry-run", "Preview actions without executing").option("--pr <number>", "Treat input as PR number", parseFloat).option("--skip-build", "Skip post-merge build verification").option("--no-browser", "Skip opening PR in browser (github-pr mode only)").option("--cleanup", "Clean up worktree after finishing (default in local mode)").option("--no-cleanup", "Keep worktree after finishing").option("--json", "Output result as JSON").action(async (identifier, options) => {
|
|
3317
2543
|
const executeAction = async () => {
|
|
3318
2544
|
try {
|
|
3319
2545
|
const settingsManager = new SettingsManager();
|
|
@@ -3344,9 +2570,45 @@ program.command("finish").alias("dn").description("Merge work and cleanup worksp
|
|
|
3344
2570
|
await executeAction();
|
|
3345
2571
|
}
|
|
3346
2572
|
});
|
|
2573
|
+
program.command("commit").alias("c").description("Commit all uncommitted files with issue reference").option("-m, --message <text>", "Custom commit message (skip Claude generation)").option("--fixes", 'Use "Fixes #N" trailer instead of "Refs #N" (closes issue)').option("--no-review", "Skip commit message review prompt").option("--json", "Output result as JSON (implies --no-review)").option("--wip-commit", "Quick WIP commit: skip validations and pre-commit hooks").action(async (options) => {
|
|
2574
|
+
const executeAction = async () => {
|
|
2575
|
+
try {
|
|
2576
|
+
const { CommitCommand } = await import("./commit-ONRXU67O.js");
|
|
2577
|
+
const command = new CommitCommand();
|
|
2578
|
+
const noReview = options.review === false || options.json === true;
|
|
2579
|
+
const result = await command.execute({
|
|
2580
|
+
message: options.message,
|
|
2581
|
+
fixes: options.fixes ?? false,
|
|
2582
|
+
noReview,
|
|
2583
|
+
json: options.json ?? false,
|
|
2584
|
+
wipCommit: options.wipCommit ?? false
|
|
2585
|
+
});
|
|
2586
|
+
if (options.json && result) {
|
|
2587
|
+
console.log(JSON.stringify(result, null, 2));
|
|
2588
|
+
}
|
|
2589
|
+
process.exit(0);
|
|
2590
|
+
} catch (error) {
|
|
2591
|
+
if (error instanceof UserAbortedCommitError) {
|
|
2592
|
+
process.exit(130);
|
|
2593
|
+
}
|
|
2594
|
+
if (options.json) {
|
|
2595
|
+
console.log(JSON.stringify({ success: false, error: error instanceof Error ? error.message : "Unknown error" }, null, 2));
|
|
2596
|
+
} else {
|
|
2597
|
+
logger.error(`Commit failed: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2598
|
+
}
|
|
2599
|
+
process.exit(1);
|
|
2600
|
+
}
|
|
2601
|
+
};
|
|
2602
|
+
if (options.json) {
|
|
2603
|
+
const jsonLogger = createStderrLogger();
|
|
2604
|
+
await withLogger(jsonLogger, executeAction);
|
|
2605
|
+
} else {
|
|
2606
|
+
await executeAction();
|
|
2607
|
+
}
|
|
2608
|
+
});
|
|
3347
2609
|
program.command("rebase").description("Rebase current branch on main with Claude-assisted conflict resolution").option("-f, --force", "Skip confirmation prompts").option("-n, --dry-run", "Preview actions without executing").action(async (options) => {
|
|
3348
2610
|
try {
|
|
3349
|
-
const { RebaseCommand } = await import("./rebase-
|
|
2611
|
+
const { RebaseCommand } = await import("./rebase-QYCRF7JG.js");
|
|
3350
2612
|
const command = new RebaseCommand();
|
|
3351
2613
|
await command.execute(options);
|
|
3352
2614
|
} catch (error) {
|
|
@@ -3358,7 +2620,7 @@ program.command("spin").alias("ignite").description("Launch Claude with auto-det
|
|
|
3358
2620
|
new Option("--one-shot <mode>", "One-shot automation mode").choices(["default", "noReview", "bypassPermissions"]).default("default")
|
|
3359
2621
|
).action(async (options) => {
|
|
3360
2622
|
try {
|
|
3361
|
-
const { IgniteCommand } = await import("./ignite-
|
|
2623
|
+
const { IgniteCommand } = await import("./ignite-YUAOJ5PP.js");
|
|
3362
2624
|
const command = new IgniteCommand();
|
|
3363
2625
|
await command.execute(options.oneShot ?? "default");
|
|
3364
2626
|
} catch (error) {
|
|
@@ -3369,7 +2631,7 @@ program.command("spin").alias("ignite").description("Launch Claude with auto-det
|
|
|
3369
2631
|
program.command("open").description("Open workspace in browser or run CLI tool").argument("[identifier]", "Issue number, PR number, or branch name (auto-detected if omitted)").allowUnknownOption().action(async (identifier, _options, command) => {
|
|
3370
2632
|
try {
|
|
3371
2633
|
const args = (command == null ? void 0 : command.args) ? command.args.slice(identifier ? 1 : 0) : [];
|
|
3372
|
-
const { OpenCommand } = await import("./open-
|
|
2634
|
+
const { OpenCommand } = await import("./open-QI63XQ4F.js");
|
|
3373
2635
|
const cmd = new OpenCommand();
|
|
3374
2636
|
const input = identifier ? { identifier, args } : { args };
|
|
3375
2637
|
await cmd.execute(input);
|
|
@@ -3381,7 +2643,7 @@ program.command("open").description("Open workspace in browser or run CLI tool")
|
|
|
3381
2643
|
program.command("run").description("Run CLI tool or open workspace in browser").argument("[identifier]", "Issue number, PR number, or branch name (auto-detected if omitted)").allowUnknownOption().action(async (identifier, _options, command) => {
|
|
3382
2644
|
try {
|
|
3383
2645
|
const args = (command == null ? void 0 : command.args) ? command.args.slice(identifier ? 1 : 0) : [];
|
|
3384
|
-
const { RunCommand } = await import("./run-
|
|
2646
|
+
const { RunCommand } = await import("./run-YDVYORT2.js");
|
|
3385
2647
|
const cmd = new RunCommand();
|
|
3386
2648
|
const input = identifier ? { identifier, args } : { args };
|
|
3387
2649
|
await cmd.execute(input);
|
|
@@ -3392,7 +2654,7 @@ program.command("run").description("Run CLI tool or open workspace in browser").
|
|
|
3392
2654
|
});
|
|
3393
2655
|
program.command("dev-server").alias("dev").description("Start dev server for workspace (foreground)").argument("[identifier]", "Issue number, PR number, or branch name (auto-detected if omitted)").option("--json", "Output as JSON").action(async (identifier, options) => {
|
|
3394
2656
|
try {
|
|
3395
|
-
const { DevServerCommand } = await import("./dev-server-
|
|
2657
|
+
const { DevServerCommand } = await import("./dev-server-UKAPBGUR.js");
|
|
3396
2658
|
const cmd = new DevServerCommand();
|
|
3397
2659
|
await cmd.execute({ identifier, json: options == null ? void 0 : options.json });
|
|
3398
2660
|
} catch (error) {
|
|
@@ -3402,7 +2664,7 @@ program.command("dev-server").alias("dev").description("Start dev server for wor
|
|
|
3402
2664
|
});
|
|
3403
2665
|
program.command("shell").alias("terminal").description("Open interactive shell with workspace environment").argument("[identifier]", "Issue number, PR number, or branch name (auto-detected if omitted)").action(async (identifier) => {
|
|
3404
2666
|
try {
|
|
3405
|
-
const { ShellCommand } = await import("./shell-
|
|
2667
|
+
const { ShellCommand } = await import("./shell-2NNSIU34.js");
|
|
3406
2668
|
const cmd = new ShellCommand();
|
|
3407
2669
|
await cmd.execute({ identifier });
|
|
3408
2670
|
} catch (error) {
|
|
@@ -3412,7 +2674,7 @@ program.command("shell").alias("terminal").description("Open interactive shell w
|
|
|
3412
2674
|
});
|
|
3413
2675
|
program.command("build").description("Run the build script").argument("[identifier]", "Issue number, PR number, or branch name (auto-detected if omitted)").action(async (identifier) => {
|
|
3414
2676
|
try {
|
|
3415
|
-
const { BuildCommand } = await import("./build-
|
|
2677
|
+
const { BuildCommand } = await import("./build-HQ5HGA3T.js");
|
|
3416
2678
|
const cmd = new BuildCommand();
|
|
3417
2679
|
await cmd.execute(identifier ? { identifier } : {});
|
|
3418
2680
|
} catch (error) {
|
|
@@ -3422,7 +2684,7 @@ program.command("build").description("Run the build script").argument("[identifi
|
|
|
3422
2684
|
});
|
|
3423
2685
|
program.command("lint").description("Run the lint script").argument("[identifier]", "Issue number, PR number, or branch name (auto-detected if omitted)").action(async (identifier) => {
|
|
3424
2686
|
try {
|
|
3425
|
-
const { LintCommand } = await import("./lint-
|
|
2687
|
+
const { LintCommand } = await import("./lint-HAVU4U34.js");
|
|
3426
2688
|
const cmd = new LintCommand();
|
|
3427
2689
|
await cmd.execute(identifier ? { identifier } : {});
|
|
3428
2690
|
} catch (error) {
|
|
@@ -3432,7 +2694,7 @@ program.command("lint").description("Run the lint script").argument("[identifier
|
|
|
3432
2694
|
});
|
|
3433
2695
|
program.command("test").description("Run the test script").argument("[identifier]", "Issue number, PR number, or branch name (auto-detected if omitted)").action(async (identifier) => {
|
|
3434
2696
|
try {
|
|
3435
|
-
const { TestCommand } = await import("./test-
|
|
2697
|
+
const { TestCommand } = await import("./test-75WAA6DU.js");
|
|
3436
2698
|
const cmd = new TestCommand();
|
|
3437
2699
|
await cmd.execute(identifier ? { identifier } : {});
|
|
3438
2700
|
} catch (error) {
|
|
@@ -3442,7 +2704,7 @@ program.command("test").description("Run the test script").argument("[identifier
|
|
|
3442
2704
|
});
|
|
3443
2705
|
program.command("compile").alias("typecheck").description("Run the compile or typecheck script (prefers compile if both exist)").argument("[identifier]", "Issue number, PR number, or branch name (auto-detected if omitted)").action(async (identifier) => {
|
|
3444
2706
|
try {
|
|
3445
|
-
const { CompileCommand } = await import("./compile-
|
|
2707
|
+
const { CompileCommand } = await import("./compile-CT7IR7O2.js");
|
|
3446
2708
|
const cmd = new CompileCommand();
|
|
3447
2709
|
await cmd.execute(identifier ? { identifier } : {});
|
|
3448
2710
|
} catch (error) {
|
|
@@ -3450,10 +2712,10 @@ program.command("compile").alias("typecheck").description("Run the compile or ty
|
|
|
3450
2712
|
process.exit(1);
|
|
3451
2713
|
}
|
|
3452
2714
|
});
|
|
3453
|
-
program.command("cleanup").alias("remove").alias("clean").description("Remove workspaces").argument("[identifier]", "Branch name or issue number to cleanup (auto-detected)").option("-l, --list", "List all worktrees").option("-a, --all", "Remove all worktrees (interactive confirmation)").option("-i, --issue <number>", "Cleanup by issue number", parseInt).option("-f, --force", "Skip confirmations and force removal").option("--dry-run", "Show what would be done without doing it").option("--json", "Output result as JSON").action(async (identifier, options) => {
|
|
2715
|
+
program.command("cleanup").alias("remove").alias("clean").description("Remove workspaces").argument("[identifier]", "Branch name or issue number to cleanup (auto-detected)").option("-l, --list", "List all worktrees").option("-a, --all", "Remove all worktrees (interactive confirmation)").option("-i, --issue <number>", "Cleanup by issue number", parseInt).option("-f, --force", "Skip confirmations and force removal").option("--dry-run", "Show what would be done without doing it").option("--json", "Output result as JSON").option("--defer <ms>", "Wait specified milliseconds before cleanup", parseInt).action(async (identifier, options) => {
|
|
3454
2716
|
const executeAction = async () => {
|
|
3455
2717
|
try {
|
|
3456
|
-
const { CleanupCommand } = await import("./cleanup-
|
|
2718
|
+
const { CleanupCommand } = await import("./cleanup-77U5ATYI.js");
|
|
3457
2719
|
const command = new CleanupCommand();
|
|
3458
2720
|
const input = {
|
|
3459
2721
|
options: options ?? {}
|
|
@@ -3482,15 +2744,78 @@ program.command("cleanup").alias("remove").alias("clean").description("Remove wo
|
|
|
3482
2744
|
await executeAction();
|
|
3483
2745
|
}
|
|
3484
2746
|
});
|
|
3485
|
-
program.command("list").description("Show active workspaces").option("--json", "Output as JSON").action(async (options) => {
|
|
2747
|
+
program.command("list").description("Show active workspaces").option("--json", "Output as JSON").option("--finished", "Show only finished looms (sorted by finish time, latest first)").option("--all", "Show both active and finished looms").option("--global", "Show looms from all projects (default: current project only)").action(async (options) => {
|
|
3486
2748
|
try {
|
|
3487
2749
|
const manager = new GitWorktreeManager();
|
|
3488
2750
|
const metadataManager = new MetadataManager();
|
|
3489
|
-
|
|
2751
|
+
let currentProjectPath = null;
|
|
2752
|
+
if (!options.global) {
|
|
2753
|
+
try {
|
|
2754
|
+
currentProjectPath = await findMainWorktreePathWithSettings();
|
|
2755
|
+
} catch (error) {
|
|
2756
|
+
if (error instanceof GitCommandError && (error.exitCode === 128 || /fatal: not a git repository/i.test(error.stderr))) {
|
|
2757
|
+
currentProjectPath = null;
|
|
2758
|
+
} else if (error instanceof Error && error.message.includes("Invalid settings")) {
|
|
2759
|
+
currentProjectPath = null;
|
|
2760
|
+
} else {
|
|
2761
|
+
throw error;
|
|
2762
|
+
}
|
|
2763
|
+
}
|
|
2764
|
+
}
|
|
2765
|
+
const showActive = !options.finished;
|
|
2766
|
+
const showFinished = Boolean(options.finished) || Boolean(options.all);
|
|
2767
|
+
let worktrees = [];
|
|
3490
2768
|
const metadata = /* @__PURE__ */ new Map();
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
2769
|
+
let globalActiveLooms = [];
|
|
2770
|
+
if (showActive) {
|
|
2771
|
+
if (options.global) {
|
|
2772
|
+
const allMetadata = await metadataManager.listAllMetadata();
|
|
2773
|
+
for (const loom of allMetadata) {
|
|
2774
|
+
if (!loom.worktreePath) {
|
|
2775
|
+
continue;
|
|
2776
|
+
}
|
|
2777
|
+
const pathExists = await fs3.pathExists(loom.worktreePath);
|
|
2778
|
+
if (!pathExists) {
|
|
2779
|
+
continue;
|
|
2780
|
+
}
|
|
2781
|
+
const isValid = await isValidGitRepo(loom.worktreePath);
|
|
2782
|
+
if (!isValid) {
|
|
2783
|
+
continue;
|
|
2784
|
+
}
|
|
2785
|
+
globalActiveLooms.push(loom);
|
|
2786
|
+
metadata.set(loom.worktreePath, loom);
|
|
2787
|
+
}
|
|
2788
|
+
} else {
|
|
2789
|
+
try {
|
|
2790
|
+
worktrees = await manager.listWorktrees({ porcelain: true });
|
|
2791
|
+
for (const worktree of worktrees) {
|
|
2792
|
+
const loomMetadata = await metadataManager.readMetadata(worktree.path);
|
|
2793
|
+
metadata.set(worktree.path, loomMetadata);
|
|
2794
|
+
}
|
|
2795
|
+
} catch (error) {
|
|
2796
|
+
if (error instanceof GitCommandError && (error.exitCode === 128 || /fatal: not a git repository/i.test(error.stderr))) {
|
|
2797
|
+
worktrees = [];
|
|
2798
|
+
} else {
|
|
2799
|
+
throw error;
|
|
2800
|
+
}
|
|
2801
|
+
}
|
|
2802
|
+
}
|
|
2803
|
+
}
|
|
2804
|
+
let finishedLooms = [];
|
|
2805
|
+
if (showFinished) {
|
|
2806
|
+
finishedLooms = await metadataManager.listFinishedMetadata();
|
|
2807
|
+
}
|
|
2808
|
+
let filteredWorktrees = worktrees;
|
|
2809
|
+
let filteredGlobalActiveLooms = globalActiveLooms;
|
|
2810
|
+
let filteredFinishedLooms = finishedLooms;
|
|
2811
|
+
if (currentProjectPath) {
|
|
2812
|
+
filteredWorktrees = worktrees.filter((wt) => {
|
|
2813
|
+
const loomMetadata = metadata.get(wt.path);
|
|
2814
|
+
return (loomMetadata == null ? void 0 : loomMetadata.projectPath) == null || (loomMetadata == null ? void 0 : loomMetadata.projectPath) === currentProjectPath;
|
|
2815
|
+
});
|
|
2816
|
+
filteredFinishedLooms = finishedLooms.filter(
|
|
2817
|
+
(loom) => loom.projectPath == null || loom.projectPath === currentProjectPath
|
|
2818
|
+
);
|
|
3494
2819
|
}
|
|
3495
2820
|
if (options.json) {
|
|
3496
2821
|
let mainWorktreePath;
|
|
@@ -3498,26 +2823,108 @@ program.command("list").description("Show active workspaces").option("--json", "
|
|
|
3498
2823
|
mainWorktreePath = await findMainWorktreePathWithSettings();
|
|
3499
2824
|
} catch {
|
|
3500
2825
|
}
|
|
3501
|
-
|
|
2826
|
+
let activeJson = [];
|
|
2827
|
+
if (showActive) {
|
|
2828
|
+
if (options.global) {
|
|
2829
|
+
activeJson = globalActiveLooms.map((loom) => ({
|
|
2830
|
+
name: loom.branchName ?? loom.worktreePath ?? "unknown",
|
|
2831
|
+
worktreePath: loom.worktreePath,
|
|
2832
|
+
branch: loom.branchName,
|
|
2833
|
+
type: loom.issueType ?? "branch",
|
|
2834
|
+
issue_numbers: loom.issue_numbers,
|
|
2835
|
+
pr_numbers: loom.pr_numbers,
|
|
2836
|
+
isMainWorktree: false,
|
|
2837
|
+
// Global looms from other projects are never the main worktree
|
|
2838
|
+
description: loom.description ?? null,
|
|
2839
|
+
created_at: loom.created_at ?? null,
|
|
2840
|
+
issueTracker: loom.issueTracker ?? null,
|
|
2841
|
+
colorHex: loom.colorHex ?? null,
|
|
2842
|
+
projectPath: loom.projectPath ?? null,
|
|
2843
|
+
issueUrls: loom.issueUrls ?? {},
|
|
2844
|
+
prUrls: loom.prUrls ?? {},
|
|
2845
|
+
status: "active",
|
|
2846
|
+
finishedAt: null
|
|
2847
|
+
}));
|
|
2848
|
+
} else {
|
|
2849
|
+
activeJson = formatLoomsForJson(worktrees, mainWorktreePath, metadata).map((loom) => ({
|
|
2850
|
+
...loom,
|
|
2851
|
+
status: "active",
|
|
2852
|
+
finishedAt: null
|
|
2853
|
+
}));
|
|
2854
|
+
}
|
|
2855
|
+
}
|
|
2856
|
+
if (currentProjectPath && !options.global) {
|
|
2857
|
+
activeJson = activeJson.filter(
|
|
2858
|
+
(loom) => loom.projectPath == null || loom.projectPath === currentProjectPath
|
|
2859
|
+
);
|
|
2860
|
+
}
|
|
2861
|
+
let finishedJson = finishedLooms.map(formatFinishedLoomForJson);
|
|
2862
|
+
if (currentProjectPath) {
|
|
2863
|
+
finishedJson = finishedJson.filter(
|
|
2864
|
+
(loom) => loom.projectPath == null || loom.projectPath === currentProjectPath
|
|
2865
|
+
);
|
|
2866
|
+
}
|
|
2867
|
+
const allLooms = [...activeJson, ...finishedJson];
|
|
2868
|
+
console.log(JSON.stringify(allLooms, null, 2));
|
|
3502
2869
|
return;
|
|
3503
2870
|
}
|
|
3504
|
-
|
|
3505
|
-
|
|
2871
|
+
const hasActive = options.global ? filteredGlobalActiveLooms.length > 0 : filteredWorktrees.length > 0;
|
|
2872
|
+
const hasFinished = filteredFinishedLooms.length > 0;
|
|
2873
|
+
if (!hasActive && !hasFinished) {
|
|
2874
|
+
if (options.finished) {
|
|
2875
|
+
logger.info("No finished looms found");
|
|
2876
|
+
} else if (options.all) {
|
|
2877
|
+
logger.info("No looms found");
|
|
2878
|
+
} else {
|
|
2879
|
+
logger.info("No worktrees found");
|
|
2880
|
+
}
|
|
3506
2881
|
return;
|
|
3507
2882
|
}
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
2883
|
+
if (showActive && hasActive) {
|
|
2884
|
+
logger.info("Active workspaces:");
|
|
2885
|
+
if (options.global) {
|
|
2886
|
+
for (const loom of filteredGlobalActiveLooms) {
|
|
2887
|
+
logger.info(` ${loom.branchName ?? "unknown"}`);
|
|
2888
|
+
if (loom.description) {
|
|
2889
|
+
logger.info(` Description: ${loom.description}`);
|
|
2890
|
+
}
|
|
2891
|
+
if (loom.worktreePath) {
|
|
2892
|
+
logger.info(` Path: ${loom.worktreePath}`);
|
|
2893
|
+
}
|
|
2894
|
+
if (loom.projectPath) {
|
|
2895
|
+
logger.info(` Project: ${loom.projectPath}`);
|
|
2896
|
+
}
|
|
2897
|
+
}
|
|
2898
|
+
} else {
|
|
2899
|
+
for (const worktree of filteredWorktrees) {
|
|
2900
|
+
const formatted = manager.formatWorktree(worktree);
|
|
2901
|
+
const loomMetadata = metadata.get(worktree.path);
|
|
2902
|
+
logger.info(` ${formatted.title}`);
|
|
2903
|
+
if (loomMetadata == null ? void 0 : loomMetadata.description) {
|
|
2904
|
+
logger.info(` Description: ${loomMetadata.description}`);
|
|
2905
|
+
}
|
|
2906
|
+
logger.info(` Path: ${formatted.path}`);
|
|
2907
|
+
logger.info(` Commit: ${formatted.commit}`);
|
|
2908
|
+
}
|
|
2909
|
+
}
|
|
2910
|
+
}
|
|
2911
|
+
if (showFinished && hasFinished) {
|
|
2912
|
+
if (showActive && hasActive) {
|
|
2913
|
+
logger.info("");
|
|
2914
|
+
}
|
|
2915
|
+
logger.info("Finished looms:");
|
|
2916
|
+
for (const loom of filteredFinishedLooms) {
|
|
2917
|
+
logger.info(` ${loom.branchName ?? "unknown"}`);
|
|
2918
|
+
if (loom.description) {
|
|
2919
|
+
logger.info(` Description: ${loom.description}`);
|
|
2920
|
+
}
|
|
2921
|
+
if (loom.finishedAt) {
|
|
2922
|
+
logger.info(` Finished: ${new Date(loom.finishedAt).toLocaleString()}`);
|
|
2923
|
+
}
|
|
3515
2924
|
}
|
|
3516
|
-
logger.info(` Path: ${formatted.path}`);
|
|
3517
|
-
logger.info(` Commit: ${formatted.commit}`);
|
|
3518
2925
|
}
|
|
3519
2926
|
} catch (error) {
|
|
3520
|
-
if (error instanceof
|
|
2927
|
+
if (error instanceof GitCommandError && (error.exitCode === 128 || /fatal: not a git repository/i.test(error.stderr))) {
|
|
3521
2928
|
if (options.json) {
|
|
3522
2929
|
console.log("[]");
|
|
3523
2930
|
} else {
|
|
@@ -3531,7 +2938,7 @@ program.command("list").description("Show active workspaces").option("--json", "
|
|
|
3531
2938
|
});
|
|
3532
2939
|
program.command("projects").description("List configured iloom projects").option("--json", "Output as JSON (default behavior)").action(async (options) => {
|
|
3533
2940
|
try {
|
|
3534
|
-
const { ProjectsCommand } = await import("./projects-
|
|
2941
|
+
const { ProjectsCommand } = await import("./projects-TWY4RT2Z.js");
|
|
3535
2942
|
const command = new ProjectsCommand();
|
|
3536
2943
|
const result = await command.execute(options);
|
|
3537
2944
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -3542,7 +2949,7 @@ program.command("projects").description("List configured iloom projects").option
|
|
|
3542
2949
|
});
|
|
3543
2950
|
program.command("init").alias("config").description("Initialize iloom configuration").argument("[prompt]", 'Custom initial message to send to Claude (defaults to "Help me configure iloom settings.")').action(async (prompt) => {
|
|
3544
2951
|
try {
|
|
3545
|
-
const { InitCommand: InitCommand2 } = await import("./init-
|
|
2952
|
+
const { InitCommand: InitCommand2 } = await import("./init-XQQMFDM6.js");
|
|
3546
2953
|
const command = new InitCommand2();
|
|
3547
2954
|
const trimmedPrompt = prompt == null ? void 0 : prompt.trim();
|
|
3548
2955
|
const customPrompt = trimmedPrompt && trimmedPrompt.length > 0 ? trimmedPrompt : void 0;
|
|
@@ -3554,7 +2961,7 @@ program.command("init").alias("config").description("Initialize iloom configurat
|
|
|
3554
2961
|
});
|
|
3555
2962
|
program.command("contribute").description("Set up local development environment for contributing to a GitHub project").argument("[repository]", "GitHub repository (owner/repo, github.com/owner/repo, or full URL). Defaults to iloom-ai/iloom-cli").action(async (repository) => {
|
|
3556
2963
|
try {
|
|
3557
|
-
const { ContributeCommand } = await import("./contribute-
|
|
2964
|
+
const { ContributeCommand } = await import("./contribute-GXKOIA42.js");
|
|
3558
2965
|
const command = new ContributeCommand();
|
|
3559
2966
|
await command.execute(repository);
|
|
3560
2967
|
} catch (error) {
|
|
@@ -3574,8 +2981,8 @@ program.command("update").description("Update iloom-cli to the latest version").
|
|
|
3574
2981
|
});
|
|
3575
2982
|
program.command("test-github").description("Test GitHub integration (Issue #3)").argument("<identifier>", "Issue number or PR number").option("--no-claude", "Skip Claude for branch name generation").action(async (identifier, options) => {
|
|
3576
2983
|
try {
|
|
3577
|
-
const { GitHubService: GitHubService2 } = await import("./GitHubService-
|
|
3578
|
-
const { DefaultBranchNamingService: DefaultBranchNamingService2 } = await import("./BranchNamingService-
|
|
2984
|
+
const { GitHubService: GitHubService2 } = await import("./GitHubService-O7U4UQ7N.js");
|
|
2985
|
+
const { DefaultBranchNamingService: DefaultBranchNamingService2 } = await import("./BranchNamingService-FLPUUFOB.js");
|
|
3579
2986
|
logger.info("Testing GitHub Integration\n");
|
|
3580
2987
|
const service = new GitHubService2();
|
|
3581
2988
|
const branchNaming = new DefaultBranchNamingService2({ useClaude: options.claude !== false });
|
|
@@ -3633,14 +3040,14 @@ program.command("test-github").description("Test GitHub integration (Issue #3)")
|
|
|
3633
3040
|
});
|
|
3634
3041
|
program.command("test-claude").description("Test Claude integration (Issue #10)").option("--detect", "Test Claude CLI detection").option("--version", "Get Claude CLI version").option("--branch <title>", "Test branch name generation with given title").option("--issue <number>", "Issue number for branch generation", "123").option("--launch <prompt>", "Launch Claude with a prompt (headless)").option("--interactive", "Launch Claude interactively (requires --launch)").option("--template <name>", "Test template loading").action(async (options) => {
|
|
3635
3042
|
try {
|
|
3636
|
-
const { detectClaudeCli
|
|
3637
|
-
const { PromptTemplateManager } = await import("./PromptTemplateManager-
|
|
3638
|
-
const { ClaudeService } = await import("./ClaudeService-
|
|
3639
|
-
const { ClaudeContextManager: ClaudeContextManager2 } = await import("./ClaudeContextManager-
|
|
3043
|
+
const { detectClaudeCli, getClaudeVersion, generateBranchName, launchClaude: launchClaude2 } = await import("./claude-6H36IBHO.js");
|
|
3044
|
+
const { PromptTemplateManager } = await import("./PromptTemplateManager-7L3HJQQU.js");
|
|
3045
|
+
const { ClaudeService } = await import("./ClaudeService-CRSETT3A.js");
|
|
3046
|
+
const { ClaudeContextManager: ClaudeContextManager2 } = await import("./ClaudeContextManager-KE5TBZVZ.js");
|
|
3640
3047
|
logger.info("Testing Claude Integration\n");
|
|
3641
3048
|
if (options.detect) {
|
|
3642
3049
|
logger.info("Detecting Claude CLI...");
|
|
3643
|
-
const isAvailable = await
|
|
3050
|
+
const isAvailable = await detectClaudeCli();
|
|
3644
3051
|
if (isAvailable) {
|
|
3645
3052
|
logger.success(" Claude CLI is available");
|
|
3646
3053
|
} else {
|
|
@@ -3696,7 +3103,7 @@ program.command("test-claude").description("Test Claude integration (Issue #10)"
|
|
|
3696
3103
|
if (!options.detect && !options.version && !options.branch && !options.launch && !options.template) {
|
|
3697
3104
|
logger.info("Running full Claude integration test suite...\n");
|
|
3698
3105
|
logger.info("1. Testing Claude CLI detection...");
|
|
3699
|
-
const isAvailable = await
|
|
3106
|
+
const isAvailable = await detectClaudeCli();
|
|
3700
3107
|
if (isAvailable) {
|
|
3701
3108
|
logger.success(" Claude CLI is available");
|
|
3702
3109
|
} else {
|
|
@@ -3771,7 +3178,7 @@ program.command("test-claude").description("Test Claude integration (Issue #10)"
|
|
|
3771
3178
|
});
|
|
3772
3179
|
program.command("test-webserver").description("Test if a web server is running on a workspace port").argument("<issue-number>", "Issue number (port will be calculated as 3000 + issue number)", parseInt).option("--kill", "Kill the web server if detected").action(async (issueNumber, options) => {
|
|
3773
3180
|
try {
|
|
3774
|
-
const { TestWebserverCommand } = await import("./test-webserver-
|
|
3181
|
+
const { TestWebserverCommand } = await import("./test-webserver-NRMGT2HB.js");
|
|
3775
3182
|
const command = new TestWebserverCommand();
|
|
3776
3183
|
await command.execute({ issueNumber, options });
|
|
3777
3184
|
} catch (error) {
|
|
@@ -3784,7 +3191,7 @@ program.command("test-webserver").description("Test if a web server is running o
|
|
|
3784
3191
|
});
|
|
3785
3192
|
program.command("test-git").description("Test Git integration - findMainWorktreePath() function (reads .iloom/settings.json)").action(async () => {
|
|
3786
3193
|
try {
|
|
3787
|
-
const { TestGitCommand } = await import("./test-git-
|
|
3194
|
+
const { TestGitCommand } = await import("./test-git-E2BLXR6M.js");
|
|
3788
3195
|
const command = new TestGitCommand();
|
|
3789
3196
|
await command.execute();
|
|
3790
3197
|
} catch (error) {
|
|
@@ -3810,7 +3217,7 @@ program.command("test-tabs").description("Test iTerm2 dual tab functionality - o
|
|
|
3810
3217
|
});
|
|
3811
3218
|
program.command("test-prefix").description("Test worktree prefix configuration - preview worktree paths (reads .iloom/settings.json)").action(async () => {
|
|
3812
3219
|
try {
|
|
3813
|
-
const { TestPrefixCommand } = await import("./test-prefix-
|
|
3220
|
+
const { TestPrefixCommand } = await import("./test-prefix-A7JGGYAA.js");
|
|
3814
3221
|
const command = new TestPrefixCommand();
|
|
3815
3222
|
await command.execute();
|
|
3816
3223
|
} catch (error) {
|
|
@@ -3824,7 +3231,7 @@ program.command("test-prefix").description("Test worktree prefix configuration -
|
|
|
3824
3231
|
program.command("summary").description("Generate Claude session summary for a loom").argument("[identifier]", "Issue number, PR number (pr/123), or branch name (auto-detected if omitted)").option("--with-comment", "Post summary as a comment to the issue/PR").option("--json", "Output result as JSON").action(async (identifier, options) => {
|
|
3825
3232
|
const executeAction = async () => {
|
|
3826
3233
|
try {
|
|
3827
|
-
const { SummaryCommand } = await import("./summary-
|
|
3234
|
+
const { SummaryCommand } = await import("./summary-G6L3VAKK.js");
|
|
3828
3235
|
const command = new SummaryCommand();
|
|
3829
3236
|
const result = await command.execute({ identifier, options });
|
|
3830
3237
|
if (options.json && result) {
|
|
@@ -3853,7 +3260,7 @@ program.command("summary").description("Generate Claude session summary for a lo
|
|
|
3853
3260
|
program.command("recap").description("Get recap for a loom (defaults to current directory)").argument("[identifier]", "Issue number, PR number (pr/123), or branch name (auto-detected if omitted)").option("--json", "Output as JSON with filePath for file watching").action(async (identifier, options) => {
|
|
3854
3261
|
const executeAction = async () => {
|
|
3855
3262
|
try {
|
|
3856
|
-
const { RecapCommand } = await import("./recap-
|
|
3263
|
+
const { RecapCommand } = await import("./recap-ZKGHZCX6.js");
|
|
3857
3264
|
const command = new RecapCommand();
|
|
3858
3265
|
const result = await command.execute({ identifier, json: options.json });
|
|
3859
3266
|
if (options.json && result) {
|
|
@@ -3882,7 +3289,7 @@ program.command("recap").description("Get recap for a loom (defaults to current
|
|
|
3882
3289
|
program.command("test-neon").description("Test Neon integration and debug configuration").action(async () => {
|
|
3883
3290
|
var _a;
|
|
3884
3291
|
try {
|
|
3885
|
-
const { SettingsManager: SettingsManager2 } = await import("./SettingsManager-
|
|
3292
|
+
const { SettingsManager: SettingsManager2 } = await import("./SettingsManager-YU4VYPTW.js");
|
|
3886
3293
|
const { createNeonProviderFromSettings: createNeonProviderFromSettings2 } = await import("./neon-helpers-3KBC4A3Y.js");
|
|
3887
3294
|
logger.info("Testing Neon Integration\n");
|
|
3888
3295
|
logger.info("1. Settings Configuration:");
|