@iloom/cli 0.9.2 → 0.10.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 +160 -41
- package/dist/{BranchNamingService-K6XNWQ6C.js → BranchNamingService-25KSZAEM.js} +2 -2
- package/dist/ClaudeContextManager-66GR4BGM.js +14 -0
- package/dist/ClaudeService-7KM5NA5Z.js +13 -0
- package/dist/{GitHubService-TGWJN4V4.js → GitHubService-MEHKHUQP.js} +4 -4
- package/dist/IssueTrackerFactory-NG53YX5S.js +14 -0
- package/dist/{LoomLauncher-73NXL2CL.js → LoomLauncher-TDLZSYG2.js} +9 -9
- package/dist/{MetadataManager-W3C54UYT.js → MetadataManager-5QZSTKNN.js} +2 -2
- package/dist/{ProjectCapabilityDetector-N5L7T4IY.js → ProjectCapabilityDetector-5KSYUTBJ.js} +3 -3
- package/dist/{PromptTemplateManager-36YLQRHP.js → PromptTemplateManager-YOE2SIPG.js} +2 -2
- package/dist/README.md +160 -41
- package/dist/{SettingsManager-AW3JTJHD.js → SettingsManager-FNKCOZMQ.js} +4 -2
- package/dist/agents/iloom-artifact-reviewer.md +11 -0
- package/dist/agents/iloom-code-reviewer.md +14 -0
- package/dist/agents/iloom-issue-analyze-and-plan.md +55 -12
- package/dist/agents/iloom-issue-analyzer.md +49 -6
- package/dist/agents/iloom-issue-complexity-evaluator.md +47 -6
- package/dist/agents/iloom-issue-enhancer.md +86 -7
- package/dist/agents/iloom-issue-implementer.md +48 -7
- package/dist/agents/iloom-issue-planner.md +115 -62
- package/dist/{build-THZI572G.js → build-VHGEMXBA.js} +9 -9
- package/dist/chunk-4232AHNQ.js +35 -0
- package/dist/chunk-4232AHNQ.js.map +1 -0
- package/dist/chunk-4E7LCFUG.js +24 -0
- package/dist/chunk-4E7LCFUG.js.map +1 -0
- package/dist/{chunk-AR5QKYNE.js → chunk-4FGEGQW4.js} +4 -4
- package/dist/{chunk-R4YWBGY6.js → chunk-5FJWO4IT.js} +67 -22
- package/dist/chunk-5FJWO4IT.js.map +1 -0
- package/dist/{chunk-VPTAX5TR.js → chunk-5RPBYK5Q.js} +35 -30
- package/dist/chunk-5RPBYK5Q.js.map +1 -0
- package/dist/{chunk-YKFCCV6S.js → chunk-63QWFWH3.js} +7 -7
- package/dist/chunk-63QWFWH3.js.map +1 -0
- package/dist/{chunk-RI2YL6TK.js → chunk-7VHJNVLF.js} +80 -23
- package/dist/chunk-7VHJNVLF.js.map +1 -0
- package/dist/{chunk-B7U6OKUR.js → chunk-C6HNNJIV.js} +11 -3
- package/dist/chunk-C6HNNJIV.js.map +1 -0
- package/dist/{chunk-A7NJF73J.js → chunk-CVCTIDDK.js} +4 -4
- package/dist/{chunk-Z2TWEXR7.js → chunk-E6KOWMKA.js} +6 -6
- package/dist/chunk-E6KOWMKA.js.map +1 -0
- package/dist/{chunk-3I4ONZRT.js → chunk-EVPZFV3K.js} +10 -10
- package/dist/chunk-EVPZFV3K.js.map +1 -0
- package/dist/{chunk-IZIYLYPK.js → chunk-G5V75JD5.js} +2 -2
- package/dist/chunk-GRISNU6G.js +651 -0
- package/dist/chunk-GRISNU6G.js.map +1 -0
- package/dist/chunk-HEXKPKCK.js +1396 -0
- package/dist/chunk-HEXKPKCK.js.map +1 -0
- package/dist/{chunk-TC7APDKU.js → chunk-I5T677EA.js} +2 -2
- package/dist/{chunk-KBEIQP4G.js → chunk-KB64WNBZ.js} +43 -3
- package/dist/chunk-KB64WNBZ.js.map +1 -0
- package/dist/{chunk-NWMORW3U.js → chunk-KIK2ZFAL.js} +2 -2
- package/dist/{chunk-CWRI4JC3.js → chunk-KKV5WH5M.js} +30 -31
- package/dist/chunk-KKV5WH5M.js.map +1 -0
- package/dist/{chunk-DGG2VY7B.js → chunk-KVHIAWVT.js} +9 -9
- package/dist/chunk-KVHIAWVT.js.map +1 -0
- package/dist/{chunk-OFDN5NKS.js → chunk-KXDRI47U.js} +69 -12
- package/dist/chunk-KXDRI47U.js.map +1 -0
- package/dist/{chunk-NUACL52E.js → chunk-LLHXQS3C.js} +2 -2
- package/dist/chunk-LUKXJSRI.js +73 -0
- package/dist/chunk-LUKXJSRI.js.map +1 -0
- package/dist/{chunk-TL72BGP6.js → chunk-MORRVYPT.js} +2 -2
- package/dist/chunk-OTGH2HRS.js +1427 -0
- package/dist/chunk-OTGH2HRS.js.map +1 -0
- package/dist/{chunk-7ZEHSSUP.js → chunk-P4O6EH46.js} +4 -4
- package/dist/{chunk-KAYXR544.js → chunk-QVLPWNE3.js} +2 -2
- package/dist/chunk-QZWEJVWV.js +207 -0
- package/dist/chunk-QZWEJVWV.js.map +1 -0
- package/dist/chunk-RJ3VBUFK.js +781 -0
- package/dist/chunk-RJ3VBUFK.js.map +1 -0
- package/dist/chunk-RSYT7MVI.js +202 -0
- package/dist/chunk-RSYT7MVI.js.map +1 -0
- package/dist/{chunk-6IIL5M2L.js → chunk-S7PZA6IV.js} +10 -8
- package/dist/{chunk-6IIL5M2L.js.map → chunk-S7PZA6IV.js.map} +1 -1
- package/dist/chunk-SKSYYBCU.js +229 -0
- package/dist/chunk-SKSYYBCU.js.map +1 -0
- package/dist/{chunk-ULSWCPQG.js → chunk-SWSJWA2S.js} +476 -5
- package/dist/chunk-SWSJWA2S.js.map +1 -0
- package/dist/{chunk-KXGQYLFZ.js → chunk-UKBAJ2QQ.js} +61 -7
- package/dist/chunk-UKBAJ2QQ.js.map +1 -0
- package/dist/{chunk-FO5GGFOV.js → chunk-UR5DGNUO.js} +71 -9
- package/dist/chunk-UR5DGNUO.js.map +1 -0
- package/dist/{chunk-QN47QVBX.js → chunk-UUEW5KWB.js} +1 -1
- package/dist/chunk-UUEW5KWB.js.map +1 -0
- package/dist/{chunk-4CO6KG5S.js → chunk-VG45TUYK.js} +53 -7
- package/dist/{chunk-4CO6KG5S.js.map → chunk-VG45TUYK.js.map} +1 -1
- package/dist/{chunk-4LKGCFGG.js → chunk-WWKOVDWC.js} +2 -2
- package/dist/{chunk-KJTVU3HZ.js → chunk-WXIM2WS7.js} +8 -8
- package/dist/chunk-WXIM2WS7.js.map +1 -0
- package/dist/{chunk-VOGGLPG5.js → chunk-YQ57ORTV.js} +14 -1
- package/dist/chunk-YQ57ORTV.js.map +1 -0
- package/dist/{chunk-SOSQILHO.js → chunk-ZNMPGMHY.js} +44 -797
- package/dist/chunk-ZNMPGMHY.js.map +1 -0
- package/dist/{claude-TP2QO3BU.js → claude-7GGEWVEM.js} +2 -2
- package/dist/{cleanup-PJRIFFU4.js → cleanup-6PVAC4NI.js} +85 -34
- package/dist/cleanup-6PVAC4NI.js.map +1 -0
- package/dist/cli.js +630 -801
- package/dist/cli.js.map +1 -1
- package/dist/{commit-IVP3M4HG.js → commit-FZR5XDQG.js} +26 -23
- package/dist/commit-FZR5XDQG.js.map +1 -0
- package/dist/{compile-R2J65HBQ.js → compile-7ALJHZ4N.js} +9 -9
- package/dist/{contribute-VDZXHK5Y.js → contribute-5GKLK3BQ.js} +14 -6
- package/dist/contribute-5GKLK3BQ.js.map +1 -0
- package/dist/{dev-server-7F622OEO.js → dev-server-7SMIB7OF.js} +29 -15
- package/dist/dev-server-7SMIB7OF.js.map +1 -0
- package/dist/{feedback-E7VET7CL.js → feedback-G2GJFN2F.js} +18 -16
- package/dist/{feedback-E7VET7CL.js.map → feedback-G2GJFN2F.js.map} +1 -1
- package/dist/{git-2QDQ2X2S.js → git-GTLKAZRJ.js} +4 -4
- package/dist/hooks/iloom-hook.js +15 -0
- package/dist/ignite-H2O5Y5A2.js +34 -0
- package/dist/ignite-H2O5Y5A2.js.map +1 -0
- package/dist/index.d.ts +482 -58
- package/dist/index.js +1340 -44
- package/dist/index.js.map +1 -1
- package/dist/{init-676DHF6R.js → init-32YOKXRL.js} +57 -21
- package/dist/init-32YOKXRL.js.map +1 -0
- package/dist/{issues-PJSOLOBJ.js → issues-4UUAQ5K6.js} +61 -20
- package/dist/issues-4UUAQ5K6.js.map +1 -0
- package/dist/{lint-CJM7BAIM.js → lint-AAN2NZWG.js} +9 -9
- package/dist/mcp/harness-server.js +140 -0
- package/dist/mcp/harness-server.js.map +1 -0
- package/dist/mcp/issue-management-server.js +2599 -262
- package/dist/mcp/issue-management-server.js.map +1 -1
- package/dist/mcp/recap-server.js +144 -21
- package/dist/mcp/recap-server.js.map +1 -1
- package/dist/{neon-helpers-VVFFTLXE.js → neon-helpers-CQN2PB4S.js} +3 -3
- package/dist/neon-helpers-CQN2PB4S.js.map +1 -0
- package/dist/{open-544H7JF5.js → open-FXWW3VI4.js} +15 -15
- package/dist/open-FXWW3VI4.js.map +1 -0
- package/dist/{plan-Q7ELXDLC.js → plan-RQ5FPIGF.js} +358 -40
- package/dist/plan-RQ5FPIGF.js.map +1 -0
- package/dist/{projects-LH362JZQ.js → projects-2UOXFLNZ.js} +4 -4
- package/dist/prompts/CLAUDE.md +62 -0
- package/dist/prompts/init-prompt.txt +430 -34
- package/dist/prompts/issue-prompt.txt +473 -54
- package/dist/prompts/plan-prompt.txt +140 -19
- package/dist/prompts/pr-prompt.txt +44 -1
- package/dist/prompts/regular-prompt.txt +42 -1
- package/dist/prompts/session-summary-prompt.txt +14 -0
- package/dist/prompts/swarm-orchestrator-prompt.txt +464 -0
- package/dist/{rebase-YND35CIE.js → rebase-6NVLX5V7.js} +21 -12
- package/dist/rebase-6NVLX5V7.js.map +1 -0
- package/dist/{recap-3W7COH7D.js → recap-OMBOKJST.js} +47 -19
- package/dist/recap-OMBOKJST.js.map +1 -0
- package/dist/{run-QUXJKDQQ.js → run-BBXLRIZB.js} +15 -15
- package/dist/run-BBXLRIZB.js.map +1 -0
- package/dist/schema/package-iloom.schema.json +58 -0
- package/dist/schema/settings.schema.json +149 -15
- package/dist/{shell-QGECBLST.js → shell-RF7LTND5.js} +14 -7
- package/dist/shell-RF7LTND5.js.map +1 -0
- package/dist/{summary-G2T4452H.js → summary-WTQZ7XG2.js} +27 -25
- package/dist/summary-WTQZ7XG2.js.map +1 -0
- package/dist/{test-EA5NQFDC.js → test-SGO6I5Z7.js} +9 -9
- package/dist/{test-git-M7LSLEFL.js → test-git-XM4TM65W.js} +4 -4
- package/dist/test-jira-LDTOYFSD.js +96 -0
- package/dist/test-jira-LDTOYFSD.js.map +1 -0
- package/dist/{test-prefix-64NAAUON.js → test-prefix-GBO37XCN.js} +4 -4
- package/dist/{test-webserver-OK6Z5FJM.js → test-webserver-NZ3JTVLL.js} +6 -6
- package/dist/{vscode-AR5NNXXI.js → vscode-6XUGHJKL.js} +7 -7
- package/package.json +5 -1
- package/dist/ClaudeContextManager-HR5JQKAI.js +0 -14
- package/dist/ClaudeService-TK7FMC2X.js +0 -13
- package/dist/chunk-3I4ONZRT.js.map +0 -1
- package/dist/chunk-B7U6OKUR.js.map +0 -1
- package/dist/chunk-CWRI4JC3.js.map +0 -1
- package/dist/chunk-DGG2VY7B.js.map +0 -1
- package/dist/chunk-FJDRTVJX.js +0 -520
- package/dist/chunk-FJDRTVJX.js.map +0 -1
- package/dist/chunk-FO5GGFOV.js.map +0 -1
- package/dist/chunk-KBEIQP4G.js.map +0 -1
- package/dist/chunk-KJTVU3HZ.js.map +0 -1
- package/dist/chunk-KXGQYLFZ.js.map +0 -1
- package/dist/chunk-OFDN5NKS.js.map +0 -1
- package/dist/chunk-QN47QVBX.js.map +0 -1
- package/dist/chunk-R4YWBGY6.js.map +0 -1
- package/dist/chunk-RI2YL6TK.js.map +0 -1
- package/dist/chunk-SOSQILHO.js.map +0 -1
- package/dist/chunk-ULSWCPQG.js.map +0 -1
- package/dist/chunk-VOGGLPG5.js.map +0 -1
- package/dist/chunk-VPTAX5TR.js.map +0 -1
- package/dist/chunk-W6DP5RVR.js +0 -101
- package/dist/chunk-W6DP5RVR.js.map +0 -1
- package/dist/chunk-WHI5KEOX.js +0 -121
- package/dist/chunk-WHI5KEOX.js.map +0 -1
- package/dist/chunk-YKFCCV6S.js.map +0 -1
- package/dist/chunk-Z2TWEXR7.js.map +0 -1
- package/dist/cleanup-PJRIFFU4.js.map +0 -1
- package/dist/commit-IVP3M4HG.js.map +0 -1
- package/dist/contribute-VDZXHK5Y.js.map +0 -1
- package/dist/dev-server-7F622OEO.js.map +0 -1
- package/dist/ignite-IW35CDBD.js +0 -784
- package/dist/ignite-IW35CDBD.js.map +0 -1
- package/dist/init-676DHF6R.js.map +0 -1
- package/dist/issues-PJSOLOBJ.js.map +0 -1
- package/dist/open-544H7JF5.js.map +0 -1
- package/dist/plan-Q7ELXDLC.js.map +0 -1
- package/dist/rebase-YND35CIE.js.map +0 -1
- package/dist/recap-3W7COH7D.js.map +0 -1
- package/dist/run-QUXJKDQQ.js.map +0 -1
- package/dist/shell-QGECBLST.js.map +0 -1
- package/dist/summary-G2T4452H.js.map +0 -1
- /package/dist/{BranchNamingService-K6XNWQ6C.js.map → BranchNamingService-25KSZAEM.js.map} +0 -0
- /package/dist/{ClaudeContextManager-HR5JQKAI.js.map → ClaudeContextManager-66GR4BGM.js.map} +0 -0
- /package/dist/{ClaudeService-TK7FMC2X.js.map → ClaudeService-7KM5NA5Z.js.map} +0 -0
- /package/dist/{GitHubService-TGWJN4V4.js.map → GitHubService-MEHKHUQP.js.map} +0 -0
- /package/dist/{MetadataManager-W3C54UYT.js.map → IssueTrackerFactory-NG53YX5S.js.map} +0 -0
- /package/dist/{LoomLauncher-73NXL2CL.js.map → LoomLauncher-TDLZSYG2.js.map} +0 -0
- /package/dist/{ProjectCapabilityDetector-N5L7T4IY.js.map → MetadataManager-5QZSTKNN.js.map} +0 -0
- /package/dist/{PromptTemplateManager-36YLQRHP.js.map → ProjectCapabilityDetector-5KSYUTBJ.js.map} +0 -0
- /package/dist/{SettingsManager-AW3JTJHD.js.map → PromptTemplateManager-YOE2SIPG.js.map} +0 -0
- /package/dist/{claude-TP2QO3BU.js.map → SettingsManager-FNKCOZMQ.js.map} +0 -0
- /package/dist/{build-THZI572G.js.map → build-VHGEMXBA.js.map} +0 -0
- /package/dist/{chunk-AR5QKYNE.js.map → chunk-4FGEGQW4.js.map} +0 -0
- /package/dist/{chunk-A7NJF73J.js.map → chunk-CVCTIDDK.js.map} +0 -0
- /package/dist/{chunk-IZIYLYPK.js.map → chunk-G5V75JD5.js.map} +0 -0
- /package/dist/{chunk-TC7APDKU.js.map → chunk-I5T677EA.js.map} +0 -0
- /package/dist/{chunk-NWMORW3U.js.map → chunk-KIK2ZFAL.js.map} +0 -0
- /package/dist/{chunk-NUACL52E.js.map → chunk-LLHXQS3C.js.map} +0 -0
- /package/dist/{chunk-TL72BGP6.js.map → chunk-MORRVYPT.js.map} +0 -0
- /package/dist/{chunk-7ZEHSSUP.js.map → chunk-P4O6EH46.js.map} +0 -0
- /package/dist/{chunk-KAYXR544.js.map → chunk-QVLPWNE3.js.map} +0 -0
- /package/dist/{chunk-4LKGCFGG.js.map → chunk-WWKOVDWC.js.map} +0 -0
- /package/dist/{git-2QDQ2X2S.js.map → claude-7GGEWVEM.js.map} +0 -0
- /package/dist/{compile-R2J65HBQ.js.map → compile-7ALJHZ4N.js.map} +0 -0
- /package/dist/{neon-helpers-VVFFTLXE.js.map → git-GTLKAZRJ.js.map} +0 -0
- /package/dist/{lint-CJM7BAIM.js.map → lint-AAN2NZWG.js.map} +0 -0
- /package/dist/{projects-LH362JZQ.js.map → projects-2UOXFLNZ.js.map} +0 -0
- /package/dist/{test-EA5NQFDC.js.map → test-SGO6I5Z7.js.map} +0 -0
- /package/dist/{test-git-M7LSLEFL.js.map → test-git-XM4TM65W.js.map} +0 -0
- /package/dist/{test-prefix-64NAAUON.js.map → test-prefix-GBO37XCN.js.map} +0 -0
- /package/dist/{test-webserver-OK6Z5FJM.js.map → test-webserver-NZ3JTVLL.js.map} +0 -0
- /package/dist/{vscode-AR5NNXXI.js.map → vscode-6XUGHJKL.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -1,72 +1,83 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
SessionSummaryService
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-EVPZFV3K.js";
|
|
5
5
|
import "./chunk-NXMDEL3F.js";
|
|
6
|
+
import {
|
|
7
|
+
ResourceCleanup
|
|
8
|
+
} from "./chunk-RJ3VBUFK.js";
|
|
9
|
+
import "./chunk-LUKXJSRI.js";
|
|
10
|
+
import {
|
|
11
|
+
StartCommand,
|
|
12
|
+
launchFirstRunSetup,
|
|
13
|
+
needsFirstRunSetup
|
|
14
|
+
} from "./chunk-GRISNU6G.js";
|
|
6
15
|
import {
|
|
7
16
|
CLIIsolationManager,
|
|
8
17
|
DatabaseManager,
|
|
9
18
|
EnvironmentManager,
|
|
10
|
-
LoomManager
|
|
11
|
-
|
|
12
|
-
} from "./chunk-SOSQILHO.js";
|
|
19
|
+
LoomManager
|
|
20
|
+
} from "./chunk-ZNMPGMHY.js";
|
|
13
21
|
import {
|
|
14
22
|
PRManager
|
|
15
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-KVHIAWVT.js";
|
|
16
24
|
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
25
|
+
CommitManager,
|
|
26
|
+
UserAbortedCommitError,
|
|
27
|
+
ValidationRunner
|
|
28
|
+
} from "./chunk-5RPBYK5Q.js";
|
|
20
29
|
import {
|
|
21
30
|
BuildRunner,
|
|
22
31
|
MergeManager
|
|
23
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-5FJWO4IT.js";
|
|
24
33
|
import {
|
|
25
|
-
|
|
26
|
-
} from "./chunk-
|
|
34
|
+
assembleChildrenData
|
|
35
|
+
} from "./chunk-QZWEJVWV.js";
|
|
36
|
+
import {
|
|
37
|
+
IssueManagementProviderFactory
|
|
38
|
+
} from "./chunk-SWSJWA2S.js";
|
|
39
|
+
import "./chunk-4232AHNQ.js";
|
|
27
40
|
import {
|
|
28
41
|
ProcessManager
|
|
29
|
-
} from "./chunk-
|
|
30
|
-
import "./chunk-
|
|
42
|
+
} from "./chunk-G5V75JD5.js";
|
|
43
|
+
import "./chunk-LLHXQS3C.js";
|
|
31
44
|
import {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
45
|
+
installDependencies
|
|
46
|
+
} from "./chunk-WWKOVDWC.js";
|
|
47
|
+
import {
|
|
48
|
+
IdentifierParser
|
|
49
|
+
} from "./chunk-63QWFWH3.js";
|
|
35
50
|
import {
|
|
36
51
|
createNeonProviderFromSettings
|
|
37
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-P4O6EH46.js";
|
|
38
53
|
import {
|
|
39
54
|
ShellCompletion
|
|
40
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-KIK2ZFAL.js";
|
|
56
|
+
import {
|
|
57
|
+
TelemetryManager,
|
|
58
|
+
TelemetryService
|
|
59
|
+
} from "./chunk-RSYT7MVI.js";
|
|
60
|
+
import {
|
|
61
|
+
GitWorktreeManager
|
|
62
|
+
} from "./chunk-I5T677EA.js";
|
|
41
63
|
import "./chunk-Q7POFB5Q.js";
|
|
42
64
|
import {
|
|
43
|
-
IssueEnhancementService
|
|
65
|
+
IssueEnhancementService
|
|
66
|
+
} from "./chunk-KKV5WH5M.js";
|
|
67
|
+
import {
|
|
44
68
|
capitalizeFirstLetter
|
|
45
|
-
} from "./chunk-
|
|
46
|
-
import "./chunk-
|
|
69
|
+
} from "./chunk-4E7LCFUG.js";
|
|
70
|
+
import "./chunk-SKSYYBCU.js";
|
|
47
71
|
import {
|
|
48
72
|
openBrowser
|
|
49
73
|
} from "./chunk-YETJNRQM.js";
|
|
50
74
|
import {
|
|
51
|
-
|
|
52
|
-
} from "./chunk-
|
|
53
|
-
import
|
|
54
|
-
CommitManager,
|
|
55
|
-
UserAbortedCommitError,
|
|
56
|
-
ValidationRunner
|
|
57
|
-
} from "./chunk-VPTAX5TR.js";
|
|
58
|
-
import {
|
|
59
|
-
IssueManagementProviderFactory
|
|
60
|
-
} from "./chunk-ULSWCPQG.js";
|
|
61
|
-
import {
|
|
62
|
-
getLinearChildIssues
|
|
63
|
-
} from "./chunk-FJDRTVJX.js";
|
|
64
|
-
import {
|
|
65
|
-
installDependencies
|
|
66
|
-
} from "./chunk-4LKGCFGG.js";
|
|
75
|
+
ProjectCapabilityDetector
|
|
76
|
+
} from "./chunk-MORRVYPT.js";
|
|
77
|
+
import "./chunk-YQ57ORTV.js";
|
|
67
78
|
import {
|
|
68
|
-
|
|
69
|
-
} from "./chunk-
|
|
79
|
+
AgentManager
|
|
80
|
+
} from "./chunk-C6HNNJIV.js";
|
|
70
81
|
import {
|
|
71
82
|
getConfiguredRepoFromSettings,
|
|
72
83
|
hasMultipleRemotes
|
|
@@ -78,19 +89,12 @@ import {
|
|
|
78
89
|
} from "./chunk-O7VL5N6S.js";
|
|
79
90
|
import {
|
|
80
91
|
ClaudeContextManager
|
|
81
|
-
} from "./chunk-
|
|
82
|
-
import "./chunk-
|
|
83
|
-
import "./chunk-
|
|
84
|
-
import
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
import {
|
|
88
|
-
DefaultBranchNamingService
|
|
89
|
-
} from "./chunk-KAYXR544.js";
|
|
90
|
-
import {
|
|
91
|
-
ProjectCapabilityDetector
|
|
92
|
-
} from "./chunk-TL72BGP6.js";
|
|
93
|
-
import "./chunk-VOGGLPG5.js";
|
|
92
|
+
} from "./chunk-E6KOWMKA.js";
|
|
93
|
+
import "./chunk-S7PZA6IV.js";
|
|
94
|
+
import "./chunk-UR5DGNUO.js";
|
|
95
|
+
import "./chunk-UUEW5KWB.js";
|
|
96
|
+
import "./chunk-GYCR2LOU.js";
|
|
97
|
+
import "./chunk-QVLPWNE3.js";
|
|
94
98
|
import {
|
|
95
99
|
GitCommandError,
|
|
96
100
|
executeGitCommand,
|
|
@@ -103,29 +107,30 @@ import {
|
|
|
103
107
|
pushBranchToRemote,
|
|
104
108
|
removePlaceholderCommitFromHead,
|
|
105
109
|
removePlaceholderCommitFromHistory
|
|
106
|
-
} from "./chunk-
|
|
110
|
+
} from "./chunk-4FGEGQW4.js";
|
|
107
111
|
import {
|
|
108
112
|
SettingsManager
|
|
109
|
-
} from "./chunk-
|
|
113
|
+
} from "./chunk-7VHJNVLF.js";
|
|
110
114
|
import {
|
|
111
115
|
MetadataManager
|
|
112
|
-
} from "./chunk-
|
|
116
|
+
} from "./chunk-KB64WNBZ.js";
|
|
117
|
+
import {
|
|
118
|
+
IssueTrackerFactory
|
|
119
|
+
} from "./chunk-UKBAJ2QQ.js";
|
|
120
|
+
import "./chunk-HEXKPKCK.js";
|
|
113
121
|
import {
|
|
114
122
|
GitHubService
|
|
115
|
-
} from "./chunk-
|
|
123
|
+
} from "./chunk-KXDRI47U.js";
|
|
124
|
+
import "./chunk-VG45TUYK.js";
|
|
116
125
|
import {
|
|
117
|
-
|
|
118
|
-
|
|
126
|
+
getLogger,
|
|
127
|
+
withLogger
|
|
128
|
+
} from "./chunk-6MLEBAYZ.js";
|
|
119
129
|
import {
|
|
120
130
|
promptConfirmation,
|
|
121
131
|
waitForKeypress
|
|
122
132
|
} from "./chunk-7JDMYTFZ.js";
|
|
123
133
|
import "./chunk-433MOLAU.js";
|
|
124
|
-
import "./chunk-FO5GGFOV.js";
|
|
125
|
-
import {
|
|
126
|
-
getLogger,
|
|
127
|
-
withLogger
|
|
128
|
-
} from "./chunk-6MLEBAYZ.js";
|
|
129
134
|
import {
|
|
130
135
|
createStderrLogger,
|
|
131
136
|
loadEnvIntoProcess,
|
|
@@ -135,423 +140,6 @@ import {
|
|
|
135
140
|
// src/cli.ts
|
|
136
141
|
import { program, Option } from "commander";
|
|
137
142
|
|
|
138
|
-
// src/commands/start.ts
|
|
139
|
-
import path from "path";
|
|
140
|
-
var StartCommand = class {
|
|
141
|
-
constructor(issueTracker, loomManager, _agentManager, settingsManager) {
|
|
142
|
-
this.loomManager = null;
|
|
143
|
-
this.githubService = null;
|
|
144
|
-
this.issueTracker = issueTracker;
|
|
145
|
-
this.settingsManager = settingsManager ?? new SettingsManager();
|
|
146
|
-
this.providedLoomManager = loomManager;
|
|
147
|
-
const envResult = loadEnvIntoProcess();
|
|
148
|
-
if (envResult.error) {
|
|
149
|
-
getLogger().debug(`Environment loading warning: ${envResult.error.message}`);
|
|
150
|
-
}
|
|
151
|
-
if (envResult.parsed) {
|
|
152
|
-
getLogger().debug(`Loaded ${Object.keys(envResult.parsed).length} environment variables`);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
/**
|
|
156
|
-
* Get or create a GitHubService instance for PR operations
|
|
157
|
-
* Used when the configured issue tracker doesn't support PRs (e.g., Linear)
|
|
158
|
-
*/
|
|
159
|
-
getGitHubService() {
|
|
160
|
-
this.githubService ??= new GitHubService();
|
|
161
|
-
return this.githubService;
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Initialize LoomManager with the main worktree path
|
|
165
|
-
* Uses lazy initialization to ensure we have the correct path
|
|
166
|
-
*/
|
|
167
|
-
async initializeLoomManager() {
|
|
168
|
-
var _a, _b;
|
|
169
|
-
if (this.loomManager) {
|
|
170
|
-
return this.loomManager;
|
|
171
|
-
}
|
|
172
|
-
if (this.providedLoomManager) {
|
|
173
|
-
this.loomManager = this.providedLoomManager;
|
|
174
|
-
return this.loomManager;
|
|
175
|
-
}
|
|
176
|
-
const mainWorktreePath = await findMainWorktreePathWithSettings();
|
|
177
|
-
const settings = await this.settingsManager.loadSettings();
|
|
178
|
-
const environmentManager = new EnvironmentManager();
|
|
179
|
-
const neonProvider = createNeonProviderFromSettings(settings);
|
|
180
|
-
const databaseUrlEnvVarName = ((_b = (_a = settings.capabilities) == null ? void 0 : _a.database) == null ? void 0 : _b.databaseUrlEnvVarName) ?? "DATABASE_URL";
|
|
181
|
-
const databaseManager = new DatabaseManager(neonProvider, environmentManager, databaseUrlEnvVarName);
|
|
182
|
-
const branchNaming = new DefaultBranchNamingService({ useClaude: true });
|
|
183
|
-
this.loomManager = new LoomManager(
|
|
184
|
-
new GitWorktreeManager(mainWorktreePath),
|
|
185
|
-
this.issueTracker,
|
|
186
|
-
branchNaming,
|
|
187
|
-
// Add branch naming service
|
|
188
|
-
environmentManager,
|
|
189
|
-
// Reuse same instance
|
|
190
|
-
new ClaudeContextManager(),
|
|
191
|
-
new ProjectCapabilityDetector(),
|
|
192
|
-
new CLIIsolationManager(),
|
|
193
|
-
this.settingsManager,
|
|
194
|
-
// Use same instance with CLI overrides
|
|
195
|
-
databaseManager
|
|
196
|
-
// Add database manager
|
|
197
|
-
);
|
|
198
|
-
return this.loomManager;
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* Main entry point for the start command
|
|
202
|
-
*/
|
|
203
|
-
async execute(input) {
|
|
204
|
-
var _a, _b, _c, _d, _e;
|
|
205
|
-
const isJsonMode = input.options.json === true;
|
|
206
|
-
try {
|
|
207
|
-
const initialSettings = await this.settingsManager.loadSettings();
|
|
208
|
-
if (!isJsonMode && (process.env.FORCE_FIRST_TIME_SETUP === "true" || await needsFirstRunSetup())) {
|
|
209
|
-
await launchFirstRunSetup();
|
|
210
|
-
const newSettings = await this.settingsManager.loadSettings();
|
|
211
|
-
const newProvider = ((_a = newSettings.issueManagement) == null ? void 0 : _a.provider) ?? "github";
|
|
212
|
-
if (newProvider !== this.issueTracker.providerName) {
|
|
213
|
-
getLogger().debug(`Reinitializing issue tracker: provider changed to "${newProvider}"`);
|
|
214
|
-
this.issueTracker = IssueTrackerFactory.create(newSettings);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
let repo;
|
|
218
|
-
if (this.issueTracker.providerName === "github" && await hasMultipleRemotes()) {
|
|
219
|
-
repo = await getConfiguredRepoFromSettings(initialSettings);
|
|
220
|
-
getLogger().info(`Using GitHub repository: ${repo}`);
|
|
221
|
-
}
|
|
222
|
-
const loomManager = await this.initializeLoomManager();
|
|
223
|
-
let parentLoom = await this.detectParentLoom(loomManager);
|
|
224
|
-
const parsed = await this.parseInput(input.identifier, repo);
|
|
225
|
-
await this.validateInput(parsed, repo);
|
|
226
|
-
if (parentLoom) {
|
|
227
|
-
const { isInteractiveEnvironment, promptConfirmation: promptConfirmation2 } = await import("./prompt-ONNPSNKM.js");
|
|
228
|
-
const parentDisplay = parentLoom.type === "issue" ? `issue #${parentLoom.identifier}` : parentLoom.type === "pr" ? `PR #${parentLoom.identifier}` : `branch ${parentLoom.identifier}`;
|
|
229
|
-
if (input.options.childLoom === true) {
|
|
230
|
-
getLogger().info(`Creating as child loom of ${parentDisplay} (--child-loom flag)`);
|
|
231
|
-
} else if (input.options.childLoom === false) {
|
|
232
|
-
parentLoom = null;
|
|
233
|
-
getLogger().info("Creating as independent loom (--no-child-loom flag)");
|
|
234
|
-
} else {
|
|
235
|
-
if (isJsonMode) {
|
|
236
|
-
throw new Error("JSON mode requires explicit --child-loom or --no-child-loom flag when running from inside a loom");
|
|
237
|
-
}
|
|
238
|
-
let createAsChild = true;
|
|
239
|
-
if (isInteractiveEnvironment()) {
|
|
240
|
-
createAsChild = await promptConfirmation2(
|
|
241
|
-
`You are not in your main worktree. Create as a child loom of ${parentDisplay}?`,
|
|
242
|
-
true
|
|
243
|
-
// Default yes
|
|
244
|
-
);
|
|
245
|
-
} else {
|
|
246
|
-
getLogger().error(`Non-interactive environment detected, use either --child-loom or --no-child-loom to specify behavior`);
|
|
247
|
-
process.exit(1);
|
|
248
|
-
}
|
|
249
|
-
if (!createAsChild) {
|
|
250
|
-
parentLoom = null;
|
|
251
|
-
getLogger().info("Creating as independent loom");
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
} else if (input.options.childLoom === true) {
|
|
255
|
-
getLogger().debug("--child-loom flag provided but not running from inside an existing loom (ignored)");
|
|
256
|
-
}
|
|
257
|
-
if (parsed.type === "description") {
|
|
258
|
-
getLogger().info("Creating GitHub issue from description...");
|
|
259
|
-
const title = capitalizeFirstLetter(parsed.originalInput);
|
|
260
|
-
const body = input.options.body ? capitalizeFirstLetter(input.options.body) : "";
|
|
261
|
-
const result = await this.issueTracker.createIssue(
|
|
262
|
-
title,
|
|
263
|
-
// Use capitalized description as title
|
|
264
|
-
body
|
|
265
|
-
// Use capitalized body or empty
|
|
266
|
-
);
|
|
267
|
-
getLogger().success(`Created issue #${result.number}: ${result.url}`);
|
|
268
|
-
parsed.type = "issue";
|
|
269
|
-
parsed.number = result.number;
|
|
270
|
-
}
|
|
271
|
-
if (input.options.oneShot === "bypassPermissions" && input.options.claude !== false && !isJsonMode) {
|
|
272
|
-
const { promptConfirmation: promptConfirmation2 } = await import("./prompt-ONNPSNKM.js");
|
|
273
|
-
const confirmed = await promptConfirmation2(
|
|
274
|
-
"WARNING: bypassPermissions mode will allow Claude to execute all tool calls without confirmation. This can be dangerous. Do you want to proceed?"
|
|
275
|
-
);
|
|
276
|
-
if (!confirmed) {
|
|
277
|
-
getLogger().info("Operation cancelled by user");
|
|
278
|
-
process.exit(0);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
const cliOverrides = extractSettingsOverrides();
|
|
282
|
-
const settings = await this.settingsManager.loadSettings(void 0, cliOverrides);
|
|
283
|
-
const workflowType = parsed.type === "branch" ? "regular" : parsed.type;
|
|
284
|
-
const workflowConfig = (_b = settings.workflows) == null ? void 0 : _b[workflowType];
|
|
285
|
-
const { extractRawSetArguments, getExecutablePath } = await import("./cli-overrides-XFZWY7CM.js");
|
|
286
|
-
const setArguments = extractRawSetArguments();
|
|
287
|
-
const executablePath = getExecutablePath();
|
|
288
|
-
getLogger().info(`Validated input: ${this.formatParsedInput(parsed)}`);
|
|
289
|
-
const identifier = parsed.type === "branch" ? parsed.branchName ?? "" : parsed.number ?? 0;
|
|
290
|
-
const enableClaude = input.options.claude ?? (workflowConfig == null ? void 0 : workflowConfig.startAiAgent) ?? true;
|
|
291
|
-
const enableCode = input.options.code ?? (workflowConfig == null ? void 0 : workflowConfig.startIde) ?? true;
|
|
292
|
-
const enableDevServer = input.options.devServer ?? (workflowConfig == null ? void 0 : workflowConfig.startDevServer) ?? true;
|
|
293
|
-
const enableTerminal = input.options.terminal ?? (workflowConfig == null ? void 0 : workflowConfig.startTerminal) ?? false;
|
|
294
|
-
getLogger().debug("Final workflow config values:", {
|
|
295
|
-
enableClaude,
|
|
296
|
-
enableCode,
|
|
297
|
-
enableDevServer,
|
|
298
|
-
enableTerminal
|
|
299
|
-
});
|
|
300
|
-
const loom = await loomManager.createIloom({
|
|
301
|
-
type: parsed.type,
|
|
302
|
-
identifier,
|
|
303
|
-
originalInput: parsed.originalInput,
|
|
304
|
-
...parentLoom && { parentLoom },
|
|
305
|
-
options: {
|
|
306
|
-
enableClaude,
|
|
307
|
-
enableCode,
|
|
308
|
-
enableDevServer,
|
|
309
|
-
enableTerminal,
|
|
310
|
-
...input.options.oneShot && { oneShot: input.options.oneShot },
|
|
311
|
-
...setArguments.length > 0 && { setArguments },
|
|
312
|
-
...executablePath && { executablePath }
|
|
313
|
-
}
|
|
314
|
-
});
|
|
315
|
-
getLogger().success(`Created loom: ${loom.id} at ${loom.path}`);
|
|
316
|
-
getLogger().info(` Branch: ${loom.branch}`);
|
|
317
|
-
if ((_c = loom.capabilities) == null ? void 0 : _c.includes("web")) {
|
|
318
|
-
getLogger().info(` Port: ${loom.port}`);
|
|
319
|
-
}
|
|
320
|
-
if ((_d = loom.issueData) == null ? void 0 : _d.title) {
|
|
321
|
-
getLogger().info(` Title: ${loom.issueData.title}`);
|
|
322
|
-
}
|
|
323
|
-
if (isJsonMode) {
|
|
324
|
-
return {
|
|
325
|
-
id: loom.id,
|
|
326
|
-
path: loom.path,
|
|
327
|
-
branch: loom.branch,
|
|
328
|
-
type: parsed.type,
|
|
329
|
-
identifier: loom.identifier,
|
|
330
|
-
...loom.port !== void 0 && { port: loom.port },
|
|
331
|
-
...((_e = loom.issueData) == null ? void 0 : _e.title) && { title: loom.issueData.title },
|
|
332
|
-
...loom.capabilities && { capabilities: loom.capabilities }
|
|
333
|
-
};
|
|
334
|
-
}
|
|
335
|
-
} catch (error) {
|
|
336
|
-
if (error instanceof Error) {
|
|
337
|
-
getLogger().error(`${error.message}`);
|
|
338
|
-
} else {
|
|
339
|
-
getLogger().error("An unknown error occurred");
|
|
340
|
-
}
|
|
341
|
-
throw error;
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
/**
|
|
345
|
-
* Parse input to determine type and extract relevant data
|
|
346
|
-
*/
|
|
347
|
-
async parseInput(identifier, repo) {
|
|
348
|
-
const hasLeadingSpace = identifier.startsWith(" ");
|
|
349
|
-
const trimmedIdentifier = identifier.trim();
|
|
350
|
-
if (!trimmedIdentifier) {
|
|
351
|
-
throw new Error("Missing required argument: identifier");
|
|
352
|
-
}
|
|
353
|
-
const spaceCount = (trimmedIdentifier.match(/ /g) ?? []).length;
|
|
354
|
-
if (trimmedIdentifier.length > 15 && spaceCount >= 1) {
|
|
355
|
-
return {
|
|
356
|
-
type: "description",
|
|
357
|
-
originalInput: hasLeadingSpace ? " " + trimmedIdentifier : trimmedIdentifier
|
|
358
|
-
};
|
|
359
|
-
}
|
|
360
|
-
const prPattern = /^pr[/-](\d+)$/i;
|
|
361
|
-
const prMatch = trimmedIdentifier.match(prPattern);
|
|
362
|
-
if (prMatch == null ? void 0 : prMatch[1]) {
|
|
363
|
-
return {
|
|
364
|
-
type: "pr",
|
|
365
|
-
number: parseInt(prMatch[1], 10),
|
|
366
|
-
originalInput: trimmedIdentifier
|
|
367
|
-
};
|
|
368
|
-
}
|
|
369
|
-
const identifierMatch = matchIssueIdentifier(trimmedIdentifier);
|
|
370
|
-
if (identifierMatch.type === "linear" && identifierMatch.identifier) {
|
|
371
|
-
const detection = await this.issueTracker.detectInputType(
|
|
372
|
-
trimmedIdentifier,
|
|
373
|
-
repo
|
|
374
|
-
);
|
|
375
|
-
if (detection.type === "issue" && detection.identifier) {
|
|
376
|
-
return {
|
|
377
|
-
type: "issue",
|
|
378
|
-
number: detection.identifier,
|
|
379
|
-
// Keep as string for Linear
|
|
380
|
-
originalInput: trimmedIdentifier
|
|
381
|
-
};
|
|
382
|
-
}
|
|
383
|
-
throw new Error(
|
|
384
|
-
`Could not find Linear issue ${identifierMatch.identifier}`
|
|
385
|
-
);
|
|
386
|
-
}
|
|
387
|
-
if (identifierMatch.type === "numeric" && identifierMatch.identifier) {
|
|
388
|
-
const number = parseInt(identifierMatch.identifier, 10);
|
|
389
|
-
if (this.issueTracker.supportsPullRequests) {
|
|
390
|
-
const detection = await this.issueTracker.detectInputType(
|
|
391
|
-
trimmedIdentifier,
|
|
392
|
-
repo
|
|
393
|
-
);
|
|
394
|
-
if (detection.type === "pr") {
|
|
395
|
-
return {
|
|
396
|
-
type: "pr",
|
|
397
|
-
number: detection.identifier ? parseInt(detection.identifier, 10) : number,
|
|
398
|
-
originalInput: trimmedIdentifier
|
|
399
|
-
};
|
|
400
|
-
} else if (detection.type === "issue") {
|
|
401
|
-
return {
|
|
402
|
-
type: "issue",
|
|
403
|
-
number: detection.identifier ? parseInt(detection.identifier, 10) : number,
|
|
404
|
-
originalInput: trimmedIdentifier
|
|
405
|
-
};
|
|
406
|
-
} else {
|
|
407
|
-
throw new Error(`Could not find issue or PR #${number}`);
|
|
408
|
-
}
|
|
409
|
-
} else {
|
|
410
|
-
const githubService = this.getGitHubService();
|
|
411
|
-
const detection = await githubService.detectInputType(trimmedIdentifier, repo);
|
|
412
|
-
if (detection.type === "pr") {
|
|
413
|
-
return {
|
|
414
|
-
type: "pr",
|
|
415
|
-
number: detection.identifier ? parseInt(detection.identifier, 10) : number,
|
|
416
|
-
originalInput: trimmedIdentifier
|
|
417
|
-
};
|
|
418
|
-
} else {
|
|
419
|
-
return {
|
|
420
|
-
type: "issue",
|
|
421
|
-
number,
|
|
422
|
-
originalInput: trimmedIdentifier
|
|
423
|
-
};
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
return {
|
|
428
|
-
type: "branch",
|
|
429
|
-
branchName: trimmedIdentifier,
|
|
430
|
-
originalInput: trimmedIdentifier
|
|
431
|
-
};
|
|
432
|
-
}
|
|
433
|
-
/**
|
|
434
|
-
* Validate the parsed input based on its type
|
|
435
|
-
*/
|
|
436
|
-
async validateInput(parsed, repo) {
|
|
437
|
-
switch (parsed.type) {
|
|
438
|
-
case "pr": {
|
|
439
|
-
if (!parsed.number) {
|
|
440
|
-
throw new Error("Invalid PR number");
|
|
441
|
-
}
|
|
442
|
-
if (this.issueTracker.supportsPullRequests && this.issueTracker.fetchPR && this.issueTracker.validatePRState) {
|
|
443
|
-
const pr = await this.issueTracker.fetchPR(parsed.number, repo);
|
|
444
|
-
await this.issueTracker.validatePRState(pr);
|
|
445
|
-
} else {
|
|
446
|
-
const githubService = this.getGitHubService();
|
|
447
|
-
const pr = await githubService.fetchPR(parsed.number, repo);
|
|
448
|
-
await githubService.validatePRState(pr);
|
|
449
|
-
}
|
|
450
|
-
getLogger().debug(`Validated PR #${parsed.number}`);
|
|
451
|
-
break;
|
|
452
|
-
}
|
|
453
|
-
case "issue": {
|
|
454
|
-
if (!parsed.number) {
|
|
455
|
-
throw new Error("Invalid issue number");
|
|
456
|
-
}
|
|
457
|
-
const issue = await this.issueTracker.fetchIssue(parsed.number, repo);
|
|
458
|
-
await this.issueTracker.validateIssueState(issue);
|
|
459
|
-
getLogger().debug(`Validated issue #${parsed.number}`);
|
|
460
|
-
break;
|
|
461
|
-
}
|
|
462
|
-
case "branch": {
|
|
463
|
-
if (!parsed.branchName) {
|
|
464
|
-
throw new Error("Invalid branch name");
|
|
465
|
-
}
|
|
466
|
-
if (!this.isValidBranchName(parsed.branchName)) {
|
|
467
|
-
throw new Error(
|
|
468
|
-
"Invalid branch name. Use only letters, numbers, hyphens, underscores, and slashes"
|
|
469
|
-
);
|
|
470
|
-
}
|
|
471
|
-
getLogger().debug(`Validated branch name: ${parsed.branchName}`);
|
|
472
|
-
break;
|
|
473
|
-
}
|
|
474
|
-
case "description": {
|
|
475
|
-
getLogger().debug("Detected description input", {
|
|
476
|
-
length: parsed.originalInput.length
|
|
477
|
-
});
|
|
478
|
-
break;
|
|
479
|
-
}
|
|
480
|
-
default: {
|
|
481
|
-
const unknownType = parsed;
|
|
482
|
-
throw new Error(`Unknown input type: ${unknownType.type}`);
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
/**
|
|
487
|
-
* Validate branch name format
|
|
488
|
-
*/
|
|
489
|
-
isValidBranchName(branch) {
|
|
490
|
-
return /^[a-zA-Z0-9/_-]+$/.test(branch);
|
|
491
|
-
}
|
|
492
|
-
/**
|
|
493
|
-
* Format parsed input for display
|
|
494
|
-
*/
|
|
495
|
-
formatParsedInput(parsed) {
|
|
496
|
-
switch (parsed.type) {
|
|
497
|
-
case "pr":
|
|
498
|
-
return `PR #${parsed.number}`;
|
|
499
|
-
case "issue":
|
|
500
|
-
return `Issue #${parsed.number}`;
|
|
501
|
-
case "branch":
|
|
502
|
-
return `Branch '${parsed.branchName}'`;
|
|
503
|
-
case "description":
|
|
504
|
-
return `Description: ${parsed.originalInput.slice(0, 50)}...`;
|
|
505
|
-
default:
|
|
506
|
-
return "Unknown input";
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
/**
|
|
510
|
-
* Detect if running from inside an existing loom worktree
|
|
511
|
-
* Returns parent loom info if detected, null otherwise
|
|
512
|
-
*/
|
|
513
|
-
async detectParentLoom(loomManager) {
|
|
514
|
-
try {
|
|
515
|
-
const cwd = process.cwd();
|
|
516
|
-
const looms = await loomManager.listLooms();
|
|
517
|
-
if (!looms) {
|
|
518
|
-
return null;
|
|
519
|
-
}
|
|
520
|
-
const mainWorktreePath = await findMainWorktreePathWithSettings();
|
|
521
|
-
const parentLoom = looms.find((loom) => {
|
|
522
|
-
if (loom.path === mainWorktreePath) {
|
|
523
|
-
return false;
|
|
524
|
-
}
|
|
525
|
-
return cwd === loom.path || cwd.startsWith(loom.path + path.sep);
|
|
526
|
-
});
|
|
527
|
-
if (!parentLoom) {
|
|
528
|
-
return null;
|
|
529
|
-
}
|
|
530
|
-
getLogger().debug(`Detected parent loom: ${parentLoom.type} ${parentLoom.identifier} at ${parentLoom.path}`);
|
|
531
|
-
const result = {
|
|
532
|
-
type: parentLoom.type,
|
|
533
|
-
identifier: parentLoom.identifier,
|
|
534
|
-
branchName: parentLoom.branch,
|
|
535
|
-
worktreePath: parentLoom.path
|
|
536
|
-
};
|
|
537
|
-
if (parentLoom.databaseBranch) {
|
|
538
|
-
result.databaseBranch = parentLoom.databaseBranch;
|
|
539
|
-
}
|
|
540
|
-
if (!result.databaseBranch) {
|
|
541
|
-
const databaseBranch = await loomManager.getDatabaseBranchForLoom(parentLoom.path);
|
|
542
|
-
if (databaseBranch) {
|
|
543
|
-
result.databaseBranch = databaseBranch;
|
|
544
|
-
getLogger().debug(`Detected parent database branch: ${databaseBranch}`);
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
return result;
|
|
548
|
-
} catch (error) {
|
|
549
|
-
getLogger().debug(`Failed to detect parent loom: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
550
|
-
return null;
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
};
|
|
554
|
-
|
|
555
143
|
// src/commands/add-issue.ts
|
|
556
144
|
var AddIssueCommand = class {
|
|
557
145
|
constructor(enhancementService, settingsManager) {
|
|
@@ -588,7 +176,10 @@ var AddIssueCommand = class {
|
|
|
588
176
|
}
|
|
589
177
|
throw new Error("Description is required and must be more than 30 characters with at least 3 words");
|
|
590
178
|
}
|
|
591
|
-
const
|
|
179
|
+
const enhancementInput = body ? `${description}
|
|
180
|
+
|
|
181
|
+
${body}` : description;
|
|
182
|
+
const issueBody = await this.enhancementService.enhanceDescription(enhancementInput);
|
|
592
183
|
const result = await this.enhancementService.createEnhancedIssue(
|
|
593
184
|
description,
|
|
594
185
|
issueBody,
|
|
@@ -718,7 +309,7 @@ var EnhanceCommand = class {
|
|
|
718
309
|
};
|
|
719
310
|
|
|
720
311
|
// src/commands/finish.ts
|
|
721
|
-
import
|
|
312
|
+
import path from "path";
|
|
722
313
|
var FinishCommand = class {
|
|
723
314
|
constructor(issueTracker, gitWorktreeManager, validationRunner, commitManager, mergeManager, identifierParser, resourceCleanup, buildRunner, settingsManager, loomManager) {
|
|
724
315
|
const envResult = loadEnvIntoProcess();
|
|
@@ -747,21 +338,21 @@ var FinishCommand = class {
|
|
|
747
338
|
* Lazy initialization of ResourceCleanup with properly configured DatabaseManager
|
|
748
339
|
*/
|
|
749
340
|
async ensureResourceCleanup() {
|
|
750
|
-
var
|
|
341
|
+
var _a2, _b;
|
|
751
342
|
if (this.resourceCleanup && this.loomManager) {
|
|
752
343
|
return;
|
|
753
344
|
}
|
|
754
345
|
const settings = await this.settingsManager.loadSettings();
|
|
755
|
-
const databaseUrlEnvVarName = ((_b = (
|
|
346
|
+
const databaseUrlEnvVarName = ((_b = (_a2 = settings.capabilities) == null ? void 0 : _a2.database) == null ? void 0 : _b.databaseUrlEnvVarName) ?? "DATABASE_URL";
|
|
756
347
|
const environmentManager = new EnvironmentManager();
|
|
757
348
|
const neonProvider = createNeonProviderFromSettings(settings);
|
|
758
349
|
const databaseManager = new DatabaseManager(neonProvider, environmentManager, databaseUrlEnvVarName);
|
|
759
350
|
const cliIsolationManager = new CLIIsolationManager();
|
|
760
|
-
const { DefaultBranchNamingService
|
|
351
|
+
const { DefaultBranchNamingService } = await import("./BranchNamingService-25KSZAEM.js");
|
|
761
352
|
this.loomManager ??= new LoomManager(
|
|
762
353
|
this.gitWorktreeManager,
|
|
763
354
|
this.issueTracker,
|
|
764
|
-
new
|
|
355
|
+
new DefaultBranchNamingService({ useClaude: true }),
|
|
765
356
|
environmentManager,
|
|
766
357
|
new ClaudeContextManager(),
|
|
767
358
|
new ProjectCapabilityDetector(),
|
|
@@ -815,9 +406,9 @@ var FinishCommand = class {
|
|
|
815
406
|
* Main entry point for finish command
|
|
816
407
|
*/
|
|
817
408
|
async execute(input) {
|
|
818
|
-
var
|
|
409
|
+
var _a2, _b, _c, _d, _e;
|
|
819
410
|
process.env.ILOOM = "1";
|
|
820
|
-
const isJsonMode = input.options.json === true;
|
|
411
|
+
const isJsonMode = input.options.json === true || input.options.jsonStream === true;
|
|
821
412
|
const result = {
|
|
822
413
|
success: false,
|
|
823
414
|
type: "issue",
|
|
@@ -827,7 +418,7 @@ var FinishCommand = class {
|
|
|
827
418
|
};
|
|
828
419
|
if (isJsonMode) {
|
|
829
420
|
const settings2 = await this.settingsManager.loadSettings();
|
|
830
|
-
if ((((
|
|
421
|
+
if ((((_a2 = settings2.mergeBehavior) == null ? void 0 : _a2.mode) === "github-pr" || ((_b = settings2.mergeBehavior) == null ? void 0 : _b.mode) === "github-draft-pr") && input.options.cleanup === void 0) {
|
|
831
422
|
throw new Error('JSON mode with "github-pr"/"github-draft-pr" workflow requires --cleanup or --no-cleanup flag. Use: il finish --json --cleanup <identifier>');
|
|
832
423
|
}
|
|
833
424
|
}
|
|
@@ -848,6 +439,14 @@ var FinishCommand = class {
|
|
|
848
439
|
if (!worktree) {
|
|
849
440
|
throw new Error("No worktree found");
|
|
850
441
|
}
|
|
442
|
+
let preFinishCreatedAt;
|
|
443
|
+
try {
|
|
444
|
+
const metadataManager = new MetadataManager();
|
|
445
|
+
const metadata = await metadataManager.readMetadata(worktree.path);
|
|
446
|
+
preFinishCreatedAt = (metadata == null ? void 0 : metadata.created_at) ?? void 0;
|
|
447
|
+
} catch (error) {
|
|
448
|
+
getLogger().debug(`Failed to read metadata for telemetry: ${error instanceof Error ? error.message : String(error)}`);
|
|
449
|
+
}
|
|
851
450
|
if (parsed.type === "pr") {
|
|
852
451
|
if (!parsed.number) {
|
|
853
452
|
throw new Error("Invalid PR number");
|
|
@@ -861,6 +460,15 @@ var FinishCommand = class {
|
|
|
861
460
|
await this.executeIssueWorkflow(parsed, input.options, worktree, result);
|
|
862
461
|
}
|
|
863
462
|
result.success = true;
|
|
463
|
+
try {
|
|
464
|
+
const durationMinutes = preFinishCreatedAt ? Math.round((Date.now() - new Date(preFinishCreatedAt).getTime()) / 6e4) : 0;
|
|
465
|
+
TelemetryService.getInstance().track("loom.finished", {
|
|
466
|
+
merge_behavior: ((_e = settings.mergeBehavior) == null ? void 0 : _e.mode) ?? "local",
|
|
467
|
+
duration_minutes: isNaN(durationMinutes) ? 0 : durationMinutes
|
|
468
|
+
});
|
|
469
|
+
} catch (error) {
|
|
470
|
+
getLogger().debug(`Failed to track loom.finished telemetry: ${error instanceof Error ? error.message : String(error)}`);
|
|
471
|
+
}
|
|
864
472
|
if (isJsonMode) {
|
|
865
473
|
return result;
|
|
866
474
|
}
|
|
@@ -888,6 +496,7 @@ var FinishCommand = class {
|
|
|
888
496
|
* (No GitHub API calls - uses IdentifierParser)
|
|
889
497
|
*/
|
|
890
498
|
async parseExplicitInput(identifier) {
|
|
499
|
+
var _a2;
|
|
891
500
|
const prPattern = /^(?:pr|PR)[/-](\d+)$/;
|
|
892
501
|
const prMatch = identifier.match(prPattern);
|
|
893
502
|
if (prMatch == null ? void 0 : prMatch[1]) {
|
|
@@ -913,6 +522,18 @@ var FinishCommand = class {
|
|
|
913
522
|
if (parsed.branchName !== void 0) {
|
|
914
523
|
result.branchName = parsed.branchName;
|
|
915
524
|
}
|
|
525
|
+
if (result.type === "issue" && result.number !== void 0) {
|
|
526
|
+
const worktree = await this.gitWorktreeManager.findWorktreeForIssue(result.number);
|
|
527
|
+
if (worktree) {
|
|
528
|
+
const { MetadataManager: MetadataManager2 } = await import("./MetadataManager-5QZSTKNN.js");
|
|
529
|
+
const metadataManager = new MetadataManager2();
|
|
530
|
+
const metadata = await metadataManager.readMetadata(worktree.path);
|
|
531
|
+
const canonicalKey = (metadata == null ? void 0 : metadata.issueKey) ?? ((_a2 = metadata == null ? void 0 : metadata.issue_numbers) == null ? void 0 : _a2[0]);
|
|
532
|
+
if (canonicalKey) {
|
|
533
|
+
result.number = canonicalKey;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
916
537
|
return result;
|
|
917
538
|
}
|
|
918
539
|
/**
|
|
@@ -920,7 +541,8 @@ var FinishCommand = class {
|
|
|
920
541
|
* Ports logic from merge-current-issue.sh lines 30-52
|
|
921
542
|
*/
|
|
922
543
|
async autoDetectFromCurrentDirectory() {
|
|
923
|
-
|
|
544
|
+
var _a2, _b;
|
|
545
|
+
const currentDir = path.basename(process.cwd());
|
|
924
546
|
const prPattern = /_pr_(\d+)$/;
|
|
925
547
|
const prMatch = currentDir.match(prPattern);
|
|
926
548
|
if (prMatch == null ? void 0 : prMatch[1]) {
|
|
@@ -933,14 +555,18 @@ var FinishCommand = class {
|
|
|
933
555
|
autoDetected: true
|
|
934
556
|
};
|
|
935
557
|
}
|
|
558
|
+
const { MetadataManager: MetadataManager2 } = await import("./MetadataManager-5QZSTKNN.js");
|
|
559
|
+
const metadataManager = new MetadataManager2();
|
|
560
|
+
const metadata = await metadataManager.readMetadata(process.cwd());
|
|
936
561
|
const issueNumber = extractIssueNumber(currentDir);
|
|
937
562
|
if (issueNumber !== null) {
|
|
563
|
+
const originalIssueKey = (metadata == null ? void 0 : metadata.issueKey) ?? ((_a2 = metadata == null ? void 0 : metadata.issue_numbers) == null ? void 0 : _a2[0]) ?? issueNumber;
|
|
938
564
|
getLogger().debug(
|
|
939
|
-
`Auto-detected issue #${
|
|
565
|
+
`Auto-detected issue #${originalIssueKey} from directory: ${currentDir}`
|
|
940
566
|
);
|
|
941
567
|
return {
|
|
942
568
|
type: "issue",
|
|
943
|
-
number:
|
|
569
|
+
number: originalIssueKey,
|
|
944
570
|
originalInput: currentDir,
|
|
945
571
|
autoDetected: true
|
|
946
572
|
};
|
|
@@ -954,12 +580,13 @@ var FinishCommand = class {
|
|
|
954
580
|
}
|
|
955
581
|
const branchIssueNumber = extractIssueNumber(currentBranch);
|
|
956
582
|
if (branchIssueNumber !== null) {
|
|
583
|
+
const originalIssueKey = (metadata == null ? void 0 : metadata.issueKey) ?? ((_b = metadata == null ? void 0 : metadata.issue_numbers) == null ? void 0 : _b[0]) ?? branchIssueNumber;
|
|
957
584
|
getLogger().debug(
|
|
958
|
-
`Auto-detected issue #${
|
|
585
|
+
`Auto-detected issue #${originalIssueKey} from branch: ${currentBranch}`
|
|
959
586
|
);
|
|
960
587
|
return {
|
|
961
588
|
type: "issue",
|
|
962
|
-
number:
|
|
589
|
+
number: originalIssueKey,
|
|
963
590
|
originalInput: currentBranch,
|
|
964
591
|
autoDetected: true
|
|
965
592
|
};
|
|
@@ -1098,85 +725,104 @@ var FinishCommand = class {
|
|
|
1098
725
|
* This is the workflow: rebase → validate → commit → merge → cleanup
|
|
1099
726
|
*/
|
|
1100
727
|
async executeIssueWorkflow(parsed, options, worktree, result) {
|
|
1101
|
-
var
|
|
1102
|
-
getLogger().info("Rebasing branch on main...");
|
|
728
|
+
var _a2, _b, _c, _d, _e, _f;
|
|
1103
729
|
const mergeOptions = {
|
|
1104
730
|
dryRun: options.dryRun ?? false,
|
|
1105
|
-
force: options.force ?? false
|
|
731
|
+
force: options.force ?? false,
|
|
732
|
+
jsonStream: options.jsonStream ?? false
|
|
1106
733
|
};
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
result.operations.push({
|
|
1110
|
-
type: "rebase",
|
|
1111
|
-
message: "Branch rebased on main",
|
|
1112
|
-
success: true
|
|
1113
|
-
});
|
|
1114
|
-
if (!options.dryRun) {
|
|
1115
|
-
getLogger().info("Running pre-merge validations...");
|
|
1116
|
-
await this.validationRunner.runValidations(worktree.path, {
|
|
1117
|
-
dryRun: options.dryRun ?? false
|
|
1118
|
-
});
|
|
1119
|
-
getLogger().success("All validations passed");
|
|
1120
|
-
result.operations.push({
|
|
1121
|
-
type: "validation",
|
|
1122
|
-
message: "Pre-merge validations passed",
|
|
1123
|
-
success: true
|
|
1124
|
-
});
|
|
734
|
+
if (options.skipToPr) {
|
|
735
|
+
getLogger().info("Skipping rebase/validation/commit (--skip-to-pr flag)");
|
|
1125
736
|
} else {
|
|
1126
|
-
getLogger().info("
|
|
737
|
+
getLogger().info("Rebasing branch on main...");
|
|
738
|
+
await this.mergeManager.rebaseOnMain(worktree.path, mergeOptions);
|
|
739
|
+
getLogger().success("Branch rebased successfully");
|
|
1127
740
|
result.operations.push({
|
|
1128
|
-
type: "
|
|
1129
|
-
message: "
|
|
741
|
+
type: "rebase",
|
|
742
|
+
message: "Branch rebased on main",
|
|
1130
743
|
success: true
|
|
1131
744
|
});
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
745
|
+
if (!options.dryRun) {
|
|
746
|
+
getLogger().info("Installing dependencies...");
|
|
747
|
+
try {
|
|
748
|
+
await installDependencies(worktree.path, true, true);
|
|
749
|
+
} catch (error) {
|
|
750
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
751
|
+
getLogger().warn(`Dependency installation failed: ${message}`);
|
|
752
|
+
getLogger().warn("Please run your package manager install command manually");
|
|
753
|
+
}
|
|
754
|
+
} else {
|
|
755
|
+
getLogger().info("[DRY RUN] Would install dependencies");
|
|
756
|
+
}
|
|
757
|
+
if (!options.dryRun) {
|
|
758
|
+
getLogger().info("Running pre-merge validations...");
|
|
759
|
+
await this.validationRunner.runValidations(worktree.path, {
|
|
760
|
+
dryRun: options.dryRun ?? false,
|
|
761
|
+
jsonStream: options.jsonStream ?? false
|
|
762
|
+
});
|
|
763
|
+
getLogger().success("All validations passed");
|
|
1137
764
|
result.operations.push({
|
|
1138
|
-
type: "
|
|
1139
|
-
message: "
|
|
765
|
+
type: "validation",
|
|
766
|
+
message: "Pre-merge validations passed",
|
|
1140
767
|
success: true
|
|
1141
768
|
});
|
|
1142
769
|
} else {
|
|
1143
|
-
getLogger().info("
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
if (parsed.type === "issue" && parsed.number) {
|
|
1155
|
-
commitOptions.issueNumber = parsed.number;
|
|
1156
|
-
}
|
|
1157
|
-
try {
|
|
1158
|
-
await this.commitManager.commitChanges(worktree.path, commitOptions);
|
|
1159
|
-
getLogger().success("Changes committed successfully");
|
|
770
|
+
getLogger().info("[DRY RUN] Would run pre-merge validations");
|
|
771
|
+
result.operations.push({
|
|
772
|
+
type: "validation",
|
|
773
|
+
message: "Would run pre-merge validations (dry-run)",
|
|
774
|
+
success: true
|
|
775
|
+
});
|
|
776
|
+
}
|
|
777
|
+
const gitStatus = await this.commitManager.detectUncommittedChanges(worktree.path);
|
|
778
|
+
if (gitStatus.hasUncommittedChanges) {
|
|
779
|
+
if (options.dryRun) {
|
|
780
|
+
getLogger().info("[DRY RUN] Would auto-commit uncommitted changes (validation passed)");
|
|
1160
781
|
result.operations.push({
|
|
1161
782
|
type: "commit",
|
|
1162
|
-
message: "
|
|
783
|
+
message: "Would auto-commit uncommitted changes (dry-run)",
|
|
1163
784
|
success: true
|
|
1164
785
|
});
|
|
1165
|
-
}
|
|
1166
|
-
|
|
1167
|
-
|
|
786
|
+
} else {
|
|
787
|
+
getLogger().info("Validation passed, auto-committing uncommitted changes...");
|
|
788
|
+
const settings2 = await this.settingsManager.loadSettings(worktree.path);
|
|
789
|
+
const skipVerify = ((_b = (_a2 = settings2.workflows) == null ? void 0 : _a2.issue) == null ? void 0 : _b.noVerify) ?? false;
|
|
790
|
+
const providerType = ((_c = settings2.issueManagement) == null ? void 0 : _c.provider) ?? "github";
|
|
791
|
+
const issuePrefix = IssueManagementProviderFactory.create(providerType, settings2).issuePrefix;
|
|
792
|
+
const commitOptions = {
|
|
793
|
+
dryRun: options.dryRun ?? false,
|
|
794
|
+
skipVerify,
|
|
795
|
+
issuePrefix,
|
|
796
|
+
timeout: (_d = settings2.git) == null ? void 0 : _d.commitTimeout,
|
|
797
|
+
noReview: options.review !== true || options.json === true
|
|
798
|
+
};
|
|
799
|
+
if (parsed.type === "issue" && parsed.number) {
|
|
800
|
+
commitOptions.issueNumber = parsed.number;
|
|
801
|
+
}
|
|
802
|
+
try {
|
|
803
|
+
await this.commitManager.commitChanges(worktree.path, commitOptions);
|
|
804
|
+
getLogger().success("Changes committed successfully");
|
|
1168
805
|
result.operations.push({
|
|
1169
806
|
type: "commit",
|
|
1170
|
-
message: "
|
|
1171
|
-
success:
|
|
807
|
+
message: "Changes committed successfully",
|
|
808
|
+
success: true
|
|
1172
809
|
});
|
|
810
|
+
} catch (error) {
|
|
811
|
+
if (error instanceof UserAbortedCommitError) {
|
|
812
|
+
getLogger().info("Commit aborted by user");
|
|
813
|
+
result.operations.push({
|
|
814
|
+
type: "commit",
|
|
815
|
+
message: "Commit aborted by user",
|
|
816
|
+
success: false
|
|
817
|
+
});
|
|
818
|
+
throw error;
|
|
819
|
+
}
|
|
1173
820
|
throw error;
|
|
1174
821
|
}
|
|
1175
|
-
throw error;
|
|
1176
822
|
}
|
|
823
|
+
} else {
|
|
824
|
+
getLogger().debug("No uncommitted changes found");
|
|
1177
825
|
}
|
|
1178
|
-
} else {
|
|
1179
|
-
getLogger().debug("No uncommitted changes found");
|
|
1180
826
|
}
|
|
1181
827
|
const settings = await this.settingsManager.loadSettings(worktree.path);
|
|
1182
828
|
const mergeBehavior = settings.mergeBehavior ?? { mode: "local" };
|
|
@@ -1185,7 +831,7 @@ var FinishCommand = class {
|
|
|
1185
831
|
return;
|
|
1186
832
|
}
|
|
1187
833
|
if (mergeBehavior.mode === "github-draft-pr") {
|
|
1188
|
-
const { MetadataManager: MetadataManager3 } = await import("./MetadataManager-
|
|
834
|
+
const { MetadataManager: MetadataManager3 } = await import("./MetadataManager-5QZSTKNN.js");
|
|
1189
835
|
const metadataManager2 = new MetadataManager3();
|
|
1190
836
|
const metadata = await metadataManager2.readMetadata(worktree.path);
|
|
1191
837
|
getLogger().debug(`Draft PR mode: worktree=${worktree.path}, draftPrNumber=${(metadata == null ? void 0 : metadata.draftPrNumber) ?? "none"}`);
|
|
@@ -1247,6 +893,10 @@ var FinishCommand = class {
|
|
|
1247
893
|
if (prUrl) {
|
|
1248
894
|
result.prUrl = prUrl;
|
|
1249
895
|
}
|
|
896
|
+
const shouldOpenBrowser = !options.dryRun && !options.noBrowser && !options.json && ((_f = settings.mergeBehavior) == null ? void 0 : _f.openBrowserOnFinish) !== false;
|
|
897
|
+
if (shouldOpenBrowser && prUrl) {
|
|
898
|
+
await prManager.openPRInBrowser(prUrl);
|
|
899
|
+
}
|
|
1250
900
|
result.operations.push({
|
|
1251
901
|
type: "pr-ready",
|
|
1252
902
|
message: `PR #${metadata.draftPrNumber} marked as ready for review`,
|
|
@@ -1277,7 +927,7 @@ var FinishCommand = class {
|
|
|
1277
927
|
getLogger().debug("Skipping build verification (--skip-build flag provided)");
|
|
1278
928
|
}
|
|
1279
929
|
await this.generateSessionSummaryIfConfigured(parsed, worktree, options);
|
|
1280
|
-
const { MetadataManager: MetadataManager2 } = await import("./MetadataManager-
|
|
930
|
+
const { MetadataManager: MetadataManager2 } = await import("./MetadataManager-5QZSTKNN.js");
|
|
1281
931
|
const metadataManager = new MetadataManager2();
|
|
1282
932
|
if (!options.dryRun) {
|
|
1283
933
|
await metadataManager.archiveMetadata(worktree.path);
|
|
@@ -1296,7 +946,7 @@ var FinishCommand = class {
|
|
|
1296
946
|
* - CLOSED/MERGED: Skip to cleanup
|
|
1297
947
|
*/
|
|
1298
948
|
async executePRWorkflow(parsed, options, worktree, pr, result) {
|
|
1299
|
-
var
|
|
949
|
+
var _a2, _b, _c, _d;
|
|
1300
950
|
if (pr.state === "closed" || pr.state === "merged") {
|
|
1301
951
|
getLogger().info(`PR #${parsed.number} is ${pr.state.toUpperCase()} - skipping to cleanup`);
|
|
1302
952
|
const gitStatus = await this.commitManager.detectUncommittedChanges(worktree.path);
|
|
@@ -1306,7 +956,7 @@ var FinishCommand = class {
|
|
|
1306
956
|
"Cannot cleanup PR with uncommitted changes. Commit or stash changes, then run again with --force to cleanup anyway."
|
|
1307
957
|
);
|
|
1308
958
|
}
|
|
1309
|
-
const { MetadataManager: MetadataManager2 } = await import("./MetadataManager-
|
|
959
|
+
const { MetadataManager: MetadataManager2 } = await import("./MetadataManager-5QZSTKNN.js");
|
|
1310
960
|
const metadataManager = new MetadataManager2();
|
|
1311
961
|
if (!options.dryRun) {
|
|
1312
962
|
await metadataManager.archiveMetadata(worktree.path);
|
|
@@ -1332,15 +982,16 @@ var FinishCommand = class {
|
|
|
1332
982
|
} else {
|
|
1333
983
|
getLogger().info("Committing uncommitted changes...");
|
|
1334
984
|
const settings = await this.settingsManager.loadSettings(worktree.path);
|
|
1335
|
-
const skipVerify = ((_b = (
|
|
985
|
+
const skipVerify = ((_b = (_a2 = settings.workflows) == null ? void 0 : _a2.pr) == null ? void 0 : _b.noVerify) ?? false;
|
|
1336
986
|
const providerType = ((_c = settings.issueManagement) == null ? void 0 : _c.provider) ?? "github";
|
|
1337
|
-
const issuePrefix = IssueManagementProviderFactory.create(providerType).issuePrefix;
|
|
987
|
+
const issuePrefix = IssueManagementProviderFactory.create(providerType, settings).issuePrefix;
|
|
1338
988
|
try {
|
|
1339
989
|
await this.commitManager.commitChanges(worktree.path, {
|
|
1340
990
|
dryRun: false,
|
|
1341
991
|
skipVerify,
|
|
1342
992
|
issuePrefix,
|
|
1343
|
-
timeout: (_d = settings.git) == null ? void 0 : _d.commitTimeout
|
|
993
|
+
timeout: (_d = settings.git) == null ? void 0 : _d.commitTimeout,
|
|
994
|
+
noReview: options.review !== true || options.json === true
|
|
1344
995
|
// Do NOT pass issueNumber for PRs - no "Fixes #" trailer needed
|
|
1345
996
|
});
|
|
1346
997
|
getLogger().success("Changes committed");
|
|
@@ -1385,6 +1036,7 @@ var FinishCommand = class {
|
|
|
1385
1036
|
* Validates → Commits → Pushes → Creates PR → Prompts for cleanup
|
|
1386
1037
|
*/
|
|
1387
1038
|
async executeGitHubPRWorkflow(parsed, options, worktree, settings, finishResult) {
|
|
1039
|
+
var _a2;
|
|
1388
1040
|
if (options.dryRun) {
|
|
1389
1041
|
getLogger().info("[DRY RUN] Would push branch to origin");
|
|
1390
1042
|
} else {
|
|
@@ -1413,7 +1065,7 @@ var FinishCommand = class {
|
|
|
1413
1065
|
success: true
|
|
1414
1066
|
});
|
|
1415
1067
|
} else {
|
|
1416
|
-
const openInBrowser = options.noBrowser !==
|
|
1068
|
+
const openInBrowser = !options.noBrowser && !options.json && ((_a2 = settings.mergeBehavior) == null ? void 0 : _a2.openBrowserOnFinish) !== false;
|
|
1417
1069
|
const prResult = await prManager.createOrOpenPR(
|
|
1418
1070
|
worktree.branch,
|
|
1419
1071
|
prTitle,
|
|
@@ -1436,10 +1088,23 @@ var FinishCommand = class {
|
|
|
1436
1088
|
message: `Pull request created`,
|
|
1437
1089
|
success: true
|
|
1438
1090
|
});
|
|
1091
|
+
if (parsed.type === "issue" && parsed.number) {
|
|
1092
|
+
try {
|
|
1093
|
+
if (this.issueTracker.moveIssueToReadyForReview) {
|
|
1094
|
+
await this.issueTracker.moveIssueToReadyForReview(parsed.number);
|
|
1095
|
+
getLogger().info("Issue moved to Ready for Review");
|
|
1096
|
+
}
|
|
1097
|
+
} catch (error) {
|
|
1098
|
+
getLogger().warn(
|
|
1099
|
+
`Failed to move issue to Ready for Review: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
1100
|
+
error
|
|
1101
|
+
);
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1439
1104
|
}
|
|
1440
1105
|
finishResult.prUrl = prResult.url;
|
|
1441
1106
|
await this.generateSessionSummaryIfConfigured(parsed, worktree, options, prResult.number);
|
|
1442
|
-
const { MetadataManager: MetadataManager2 } = await import("./MetadataManager-
|
|
1107
|
+
const { MetadataManager: MetadataManager2 } = await import("./MetadataManager-5QZSTKNN.js");
|
|
1443
1108
|
const metadataManager = new MetadataManager2();
|
|
1444
1109
|
if (!options.dryRun) {
|
|
1445
1110
|
await metadataManager.archiveMetadata(worktree.path);
|
|
@@ -1493,7 +1158,8 @@ var FinishCommand = class {
|
|
|
1493
1158
|
// Don't delete branch - PR still needs it
|
|
1494
1159
|
keepDatabase: false,
|
|
1495
1160
|
// Clean up database
|
|
1496
|
-
force: options.force ?? false
|
|
1161
|
+
force: options.force ?? false,
|
|
1162
|
+
worktree: { path: worktree.path, branch: worktree.branch }
|
|
1497
1163
|
};
|
|
1498
1164
|
try {
|
|
1499
1165
|
getLogger().info("Starting worktree cleanup...");
|
|
@@ -1576,7 +1242,8 @@ var FinishCommand = class {
|
|
|
1576
1242
|
// For CLOSED PRs, we rely on checkMergeSafety to verify no unpushed commits
|
|
1577
1243
|
// rather than checkRemoteBranch, since the remote branch may still exist
|
|
1578
1244
|
// but local may have additional commits
|
|
1579
|
-
checkRemoteBranch: false
|
|
1245
|
+
checkRemoteBranch: false,
|
|
1246
|
+
worktree: { path: worktree.path, branch: worktree.branch }
|
|
1580
1247
|
};
|
|
1581
1248
|
try {
|
|
1582
1249
|
await this.ensureResourceCleanup();
|
|
@@ -1707,7 +1374,8 @@ var FinishCommand = class {
|
|
|
1707
1374
|
// Delete branch after successful merge
|
|
1708
1375
|
keepDatabase: false,
|
|
1709
1376
|
// Clean up database after merge
|
|
1710
|
-
force: options.force ?? false
|
|
1377
|
+
force: options.force ?? false,
|
|
1378
|
+
worktree: { path: worktree.path, branch: worktree.branch }
|
|
1711
1379
|
};
|
|
1712
1380
|
try {
|
|
1713
1381
|
getLogger().info("Starting post-merge cleanup...");
|
|
@@ -1780,8 +1448,8 @@ var FinishCommand = class {
|
|
|
1780
1448
|
* Check if current working directory is within the target worktree
|
|
1781
1449
|
*/
|
|
1782
1450
|
isRunningFromWithinWorktree(worktreePath) {
|
|
1783
|
-
const normalizedCwd =
|
|
1784
|
-
const normalizedWorktree =
|
|
1451
|
+
const normalizedCwd = path.normalize(process.cwd());
|
|
1452
|
+
const normalizedWorktree = path.normalize(worktreePath);
|
|
1785
1453
|
return normalizedCwd.startsWith(normalizedWorktree);
|
|
1786
1454
|
}
|
|
1787
1455
|
/**
|
|
@@ -1822,9 +1490,17 @@ function getPackageInfo(scriptPath) {
|
|
|
1822
1490
|
|
|
1823
1491
|
// src/cli.ts
|
|
1824
1492
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1825
|
-
import { realpathSync } from "fs";
|
|
1493
|
+
import { realpathSync as realpathSync2 } from "fs";
|
|
1826
1494
|
|
|
1827
1495
|
// src/utils/loom-formatter.ts
|
|
1496
|
+
import { realpathSync } from "fs";
|
|
1497
|
+
function resolvePathSafe(p) {
|
|
1498
|
+
try {
|
|
1499
|
+
return realpathSync(p);
|
|
1500
|
+
} catch {
|
|
1501
|
+
return p;
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1828
1504
|
function determineLoomType(worktree) {
|
|
1829
1505
|
const prPathPattern = /_pr_\d+$/;
|
|
1830
1506
|
if (prPathPattern.test(worktree.path)) {
|
|
@@ -1836,12 +1512,12 @@ function determineLoomType(worktree) {
|
|
|
1836
1512
|
}
|
|
1837
1513
|
return "branch";
|
|
1838
1514
|
}
|
|
1839
|
-
function extractPRNumbers(
|
|
1840
|
-
if (!
|
|
1515
|
+
function extractPRNumbers(path4) {
|
|
1516
|
+
if (!path4) {
|
|
1841
1517
|
return [];
|
|
1842
1518
|
}
|
|
1843
1519
|
const prPathPattern = /_pr_(\d+)$/;
|
|
1844
|
-
const match =
|
|
1520
|
+
const match = path4.match(prPathPattern);
|
|
1845
1521
|
if (match == null ? void 0 : match[1]) {
|
|
1846
1522
|
return [match[1]];
|
|
1847
1523
|
}
|
|
@@ -1857,7 +1533,37 @@ function extractIssueNumbers(branch) {
|
|
|
1857
1533
|
}
|
|
1858
1534
|
return [issueNumber];
|
|
1859
1535
|
}
|
|
1860
|
-
function
|
|
1536
|
+
function enrichSwarmIssues(childIssues, allMetadata, finishedMetadata, projectPath) {
|
|
1537
|
+
const resolvedProjectPath = projectPath ? resolvePathSafe(projectPath) : null;
|
|
1538
|
+
const scopedActive = resolvedProjectPath ? allMetadata.filter((m) => m.projectPath && resolvePathSafe(m.projectPath) === resolvedProjectPath) : allMetadata;
|
|
1539
|
+
const scopedFinished = resolvedProjectPath && finishedMetadata ? finishedMetadata.filter((m) => m.projectPath && resolvePathSafe(m.projectPath) === resolvedProjectPath) : finishedMetadata;
|
|
1540
|
+
const issueNumberToMetadata = /* @__PURE__ */ new Map();
|
|
1541
|
+
for (const meta of scopedActive) {
|
|
1542
|
+
for (const issueNum of meta.issue_numbers) {
|
|
1543
|
+
issueNumberToMetadata.set(issueNum, meta);
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
const finishedIssueNumberToMetadata = /* @__PURE__ */ new Map();
|
|
1547
|
+
if (scopedFinished) {
|
|
1548
|
+
for (const meta of scopedFinished) {
|
|
1549
|
+
for (const issueNum of meta.issue_numbers) {
|
|
1550
|
+
finishedIssueNumberToMetadata.set(issueNum, meta);
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
return childIssues.map((child) => {
|
|
1555
|
+
const lookupNumber = child.number.startsWith("#") ? child.number.slice(1) : child.number;
|
|
1556
|
+
const childMeta = issueNumberToMetadata.get(lookupNumber) ?? finishedIssueNumberToMetadata.get(lookupNumber);
|
|
1557
|
+
return {
|
|
1558
|
+
number: child.number,
|
|
1559
|
+
title: child.title,
|
|
1560
|
+
url: child.url,
|
|
1561
|
+
state: (childMeta == null ? void 0 : childMeta.state) ?? null,
|
|
1562
|
+
worktreePath: (childMeta == null ? void 0 : childMeta.worktreePath) ?? null
|
|
1563
|
+
};
|
|
1564
|
+
});
|
|
1565
|
+
}
|
|
1566
|
+
function formatLoomForJson(worktree, mainWorktreePath, metadata, allMetadata, finishedMetadata) {
|
|
1861
1567
|
const loomType = (metadata == null ? void 0 : metadata.issueType) ?? determineLoomType(worktree);
|
|
1862
1568
|
let issueNumbers;
|
|
1863
1569
|
let prNumbers;
|
|
@@ -1874,6 +1580,9 @@ function formatLoomForJson(worktree, mainWorktreePath, metadata) {
|
|
|
1874
1580
|
}
|
|
1875
1581
|
}
|
|
1876
1582
|
const isMainWorktree = mainWorktreePath ? worktree.path === mainWorktreePath : false;
|
|
1583
|
+
const isEpic = loomType === "epic";
|
|
1584
|
+
const swarmIssues = isEpic && (metadata == null ? void 0 : metadata.childIssues) && metadata.childIssues.length > 0 ? enrichSwarmIssues(metadata.childIssues, allMetadata ?? [], finishedMetadata, metadata == null ? void 0 : metadata.projectPath) : isEpic ? [] : void 0;
|
|
1585
|
+
const dependencyMap = isEpic ? (metadata == null ? void 0 : metadata.dependencyMap) && Object.keys(metadata.dependencyMap).length > 0 ? metadata.dependencyMap : {} : void 0;
|
|
1877
1586
|
return {
|
|
1878
1587
|
name: worktree.branch || worktree.path,
|
|
1879
1588
|
worktreePath: worktree.bare ? null : worktree.path,
|
|
@@ -1890,15 +1599,22 @@ function formatLoomForJson(worktree, mainWorktreePath, metadata) {
|
|
|
1890
1599
|
issueUrls: (metadata == null ? void 0 : metadata.issueUrls) ?? {},
|
|
1891
1600
|
prUrls: (metadata == null ? void 0 : metadata.prUrls) ?? {},
|
|
1892
1601
|
capabilities: (metadata == null ? void 0 : metadata.capabilities) ?? [],
|
|
1602
|
+
state: (metadata == null ? void 0 : metadata.state) ?? null,
|
|
1893
1603
|
isChildLoom: (metadata == null ? void 0 : metadata.parentLoom) != null,
|
|
1894
|
-
parentLoom: (metadata == null ? void 0 : metadata.parentLoom) ?? null
|
|
1604
|
+
parentLoom: (metadata == null ? void 0 : metadata.parentLoom) ?? null,
|
|
1605
|
+
...swarmIssues !== void 0 && { swarmIssues },
|
|
1606
|
+
...dependencyMap !== void 0 && { dependencyMap }
|
|
1895
1607
|
};
|
|
1896
1608
|
}
|
|
1897
|
-
function formatLoomsForJson(worktrees, mainWorktreePath, metadata) {
|
|
1898
|
-
|
|
1609
|
+
function formatLoomsForJson(worktrees, mainWorktreePath, metadata, allMetadata, finishedMetadata) {
|
|
1610
|
+
const resolvedAllMetadata = allMetadata ?? (metadata ? Array.from(metadata.values()).filter((m) => m != null) : []);
|
|
1611
|
+
return worktrees.map((wt) => formatLoomForJson(wt, mainWorktreePath, metadata == null ? void 0 : metadata.get(wt.path), resolvedAllMetadata, finishedMetadata));
|
|
1899
1612
|
}
|
|
1900
|
-
function formatFinishedLoomForJson(metadata) {
|
|
1613
|
+
function formatFinishedLoomForJson(metadata, allMetadata, finishedMetadata) {
|
|
1901
1614
|
const loomType = metadata.issueType ?? "branch";
|
|
1615
|
+
const isEpic = loomType === "epic";
|
|
1616
|
+
const swarmIssues = isEpic && metadata.childIssues && metadata.childIssues.length > 0 ? enrichSwarmIssues(metadata.childIssues, allMetadata ?? [], finishedMetadata, metadata.projectPath) : isEpic ? [] : void 0;
|
|
1617
|
+
const dependencyMap = isEpic ? metadata.dependencyMap && Object.keys(metadata.dependencyMap).length > 0 ? metadata.dependencyMap : {} : void 0;
|
|
1902
1618
|
return {
|
|
1903
1619
|
name: metadata.branchName ?? metadata.worktreePath ?? "unknown",
|
|
1904
1620
|
worktreePath: null,
|
|
@@ -1919,126 +1635,26 @@ function formatFinishedLoomForJson(metadata) {
|
|
|
1919
1635
|
capabilities: metadata.capabilities ?? [],
|
|
1920
1636
|
status: metadata.status ?? "finished",
|
|
1921
1637
|
finishedAt: metadata.finishedAt ?? null,
|
|
1638
|
+
state: metadata.state ?? null,
|
|
1922
1639
|
isChildLoom: metadata.parentLoom != null,
|
|
1923
|
-
parentLoom: metadata.parentLoom ?? null
|
|
1640
|
+
parentLoom: metadata.parentLoom ?? null,
|
|
1641
|
+
...swarmIssues !== void 0 && { swarmIssues },
|
|
1642
|
+
...dependencyMap !== void 0 && { dependencyMap }
|
|
1924
1643
|
};
|
|
1925
1644
|
}
|
|
1926
1645
|
|
|
1927
|
-
// src/utils/list-children.ts
|
|
1928
|
-
async function fetchChildIssues(parentIssueNumber, settings, repo) {
|
|
1929
|
-
const providerName = IssueTrackerFactory.getProviderName(settings);
|
|
1930
|
-
logger.debug("Fetching child issues", { parentIssueNumber, provider: providerName, repo });
|
|
1931
|
-
const results = await Promise.allSettled([
|
|
1932
|
-
(async () => {
|
|
1933
|
-
var _a, _b;
|
|
1934
|
-
if (providerName === "github") {
|
|
1935
|
-
const issueNum = parseInt(parentIssueNumber, 10);
|
|
1936
|
-
if (isNaN(issueNum)) {
|
|
1937
|
-
logger.warn(`Invalid GitHub issue number: ${parentIssueNumber}`);
|
|
1938
|
-
return [];
|
|
1939
|
-
}
|
|
1940
|
-
return getSubIssues(issueNum, repo);
|
|
1941
|
-
} else if (providerName === "linear") {
|
|
1942
|
-
const apiToken = (_b = (_a = settings.issueManagement) == null ? void 0 : _a.linear) == null ? void 0 : _b.apiToken;
|
|
1943
|
-
return getLinearChildIssues(parentIssueNumber, apiToken ? { apiToken } : void 0);
|
|
1944
|
-
} else {
|
|
1945
|
-
logger.warn(`Unsupported issue tracker provider: ${providerName}`);
|
|
1946
|
-
return [];
|
|
1947
|
-
}
|
|
1948
|
-
})()
|
|
1949
|
-
]);
|
|
1950
|
-
const result = results[0];
|
|
1951
|
-
if (result.status === "fulfilled") {
|
|
1952
|
-
return result.value;
|
|
1953
|
-
} else {
|
|
1954
|
-
logger.warn(`Failed to fetch child issues for ${parentIssueNumber}`, { error: result.reason });
|
|
1955
|
-
return [];
|
|
1956
|
-
}
|
|
1957
|
-
}
|
|
1958
|
-
async function findChildLooms(parentBranchName, metadataManager) {
|
|
1959
|
-
logger.debug("Finding child looms", { parentBranchName });
|
|
1960
|
-
const allMetadata = await metadataManager.listAllMetadata();
|
|
1961
|
-
const childLooms = allMetadata.filter((metadata) => {
|
|
1962
|
-
if (!metadata.parentLoom) {
|
|
1963
|
-
return false;
|
|
1964
|
-
}
|
|
1965
|
-
return metadata.parentLoom.branchName === parentBranchName;
|
|
1966
|
-
});
|
|
1967
|
-
logger.debug(`Found ${childLooms.length} child looms for parent: ${parentBranchName}`);
|
|
1968
|
-
return childLooms;
|
|
1969
|
-
}
|
|
1970
|
-
function matchChildrenData(childIssues, childLooms) {
|
|
1971
|
-
const issueToLoomMap = /* @__PURE__ */ new Map();
|
|
1972
|
-
for (const loom of childLooms) {
|
|
1973
|
-
for (const issueNum of loom.issue_numbers) {
|
|
1974
|
-
issueToLoomMap.set(issueNum, loom);
|
|
1975
|
-
}
|
|
1976
|
-
}
|
|
1977
|
-
const childIssueIds = new Set(childIssues.map((issue) => issue.id));
|
|
1978
|
-
const matchedIssues = childIssues.map((issue) => {
|
|
1979
|
-
const matchingLoom = issueToLoomMap.get(issue.id);
|
|
1980
|
-
return {
|
|
1981
|
-
id: issue.id,
|
|
1982
|
-
title: issue.title,
|
|
1983
|
-
url: issue.url,
|
|
1984
|
-
state: issue.state,
|
|
1985
|
-
hasActiveLoom: matchingLoom != null,
|
|
1986
|
-
loomBranch: (matchingLoom == null ? void 0 : matchingLoom.branchName) ?? null
|
|
1987
|
-
};
|
|
1988
|
-
});
|
|
1989
|
-
const matchedLooms = childLooms.map((loom) => {
|
|
1990
|
-
const hasMatchingIssue = loom.issue_numbers.some((issueNum) => childIssueIds.has(issueNum));
|
|
1991
|
-
return {
|
|
1992
|
-
branch: loom.branchName ?? "",
|
|
1993
|
-
issueNumbers: loom.issue_numbers,
|
|
1994
|
-
hasMatchingIssue
|
|
1995
|
-
};
|
|
1996
|
-
});
|
|
1997
|
-
const summary = {
|
|
1998
|
-
totalIssues: matchedIssues.length,
|
|
1999
|
-
issuesWithLooms: matchedIssues.filter((issue) => issue.hasActiveLoom).length,
|
|
2000
|
-
totalLooms: matchedLooms.length,
|
|
2001
|
-
orphanLooms: matchedLooms.filter((loom) => !loom.hasMatchingIssue).length
|
|
2002
|
-
};
|
|
2003
|
-
return {
|
|
2004
|
-
issues: matchedIssues,
|
|
2005
|
-
looms: matchedLooms,
|
|
2006
|
-
summary
|
|
2007
|
-
};
|
|
2008
|
-
}
|
|
2009
|
-
async function assembleChildrenData(parentLoom, metadataManager, settings, repo) {
|
|
2010
|
-
if (!parentLoom.issue_numbers || parentLoom.issue_numbers.length === 0) {
|
|
2011
|
-
logger.debug("No issue_numbers on loom, skipping children fetch", {
|
|
2012
|
-
branch: parentLoom.branchName
|
|
2013
|
-
});
|
|
2014
|
-
return null;
|
|
2015
|
-
}
|
|
2016
|
-
if (!parentLoom.branchName) {
|
|
2017
|
-
logger.debug("No branchName on loom, skipping children fetch");
|
|
2018
|
-
return null;
|
|
2019
|
-
}
|
|
2020
|
-
const parentIssueNumber = parentLoom.issue_numbers[0];
|
|
2021
|
-
if (parentIssueNumber === void 0) {
|
|
2022
|
-
return null;
|
|
2023
|
-
}
|
|
2024
|
-
const [childIssues, childLooms] = await Promise.all([
|
|
2025
|
-
fetchChildIssues(parentIssueNumber, settings, repo),
|
|
2026
|
-
findChildLooms(parentLoom.branchName, metadataManager)
|
|
2027
|
-
]);
|
|
2028
|
-
return matchChildrenData(childIssues, childLooms);
|
|
2029
|
-
}
|
|
2030
|
-
|
|
2031
1646
|
// src/cli.ts
|
|
1647
|
+
import chalk from "chalk";
|
|
2032
1648
|
import fs3 from "fs-extra";
|
|
2033
1649
|
|
|
2034
1650
|
// src/lib/VersionMigrationManager.ts
|
|
2035
1651
|
import fs2 from "fs-extra";
|
|
2036
|
-
import
|
|
1652
|
+
import path3 from "path";
|
|
2037
1653
|
import os2 from "os";
|
|
2038
1654
|
|
|
2039
1655
|
// src/migrations/index.ts
|
|
2040
1656
|
import fs from "fs-extra";
|
|
2041
|
-
import
|
|
1657
|
+
import path2 from "path";
|
|
2042
1658
|
import os from "os";
|
|
2043
1659
|
var migrations = [
|
|
2044
1660
|
// v0.6.0 is the baseline - no migrations needed
|
|
@@ -2046,9 +1662,9 @@ var migrations = [
|
|
|
2046
1662
|
version: "0.6.1",
|
|
2047
1663
|
description: "Add global gitignore for .iloom/settings.local.json",
|
|
2048
1664
|
migrate: async () => {
|
|
2049
|
-
const globalIgnorePath =
|
|
1665
|
+
const globalIgnorePath = path2.join(os.homedir(), ".config", "git", "ignore");
|
|
2050
1666
|
const pattern = "**/.iloom/settings.local.json";
|
|
2051
|
-
await fs.ensureDir(
|
|
1667
|
+
await fs.ensureDir(path2.dirname(globalIgnorePath));
|
|
2052
1668
|
let content = "";
|
|
2053
1669
|
try {
|
|
2054
1670
|
content = await fs.readFile(globalIgnorePath, "utf-8");
|
|
@@ -2066,9 +1682,9 @@ var migrations = [
|
|
|
2066
1682
|
version: "0.7.1",
|
|
2067
1683
|
description: "Add global gitignore for .iloom/package.iloom.local.json",
|
|
2068
1684
|
migrate: async () => {
|
|
2069
|
-
const globalIgnorePath =
|
|
1685
|
+
const globalIgnorePath = path2.join(os.homedir(), ".config", "git", "ignore");
|
|
2070
1686
|
const pattern = "**/.iloom/package.iloom.local.json";
|
|
2071
|
-
await fs.ensureDir(
|
|
1687
|
+
await fs.ensureDir(path2.dirname(globalIgnorePath));
|
|
2072
1688
|
let content = "";
|
|
2073
1689
|
try {
|
|
2074
1690
|
content = await fs.readFile(globalIgnorePath, "utf-8");
|
|
@@ -2081,6 +1697,28 @@ var migrations = [
|
|
|
2081
1697
|
const newContent = content + separator + "\n# Added by iloom CLI\n" + pattern + "\n";
|
|
2082
1698
|
await fs.writeFile(globalIgnorePath, newContent, "utf-8");
|
|
2083
1699
|
}
|
|
1700
|
+
},
|
|
1701
|
+
{
|
|
1702
|
+
version: "0.9.3",
|
|
1703
|
+
description: "Add global gitignore for swarm mode agent and skill files",
|
|
1704
|
+
migrate: async () => {
|
|
1705
|
+
const globalIgnorePath = path2.join(os.homedir(), ".config", "git", "ignore");
|
|
1706
|
+
const agentPattern = "**/.claude/agents/iloom-*";
|
|
1707
|
+
const skillPattern = "**/.claude/skills/iloom-*";
|
|
1708
|
+
const mcpConfigPathPattern = "**/.claude/iloom-swarm-mcp-config-path";
|
|
1709
|
+
await fs.ensureDir(path2.dirname(globalIgnorePath));
|
|
1710
|
+
let content = "";
|
|
1711
|
+
try {
|
|
1712
|
+
content = await fs.readFile(globalIgnorePath, "utf-8");
|
|
1713
|
+
} catch {
|
|
1714
|
+
}
|
|
1715
|
+
if (content.includes(agentPattern)) {
|
|
1716
|
+
return;
|
|
1717
|
+
}
|
|
1718
|
+
const separator = content.endsWith("\n") || content === "" ? "" : "\n";
|
|
1719
|
+
const newContent = content + separator + "\n# Added by iloom CLI\n" + agentPattern + "\n" + skillPattern + "\n" + mcpConfigPathPattern + "\n";
|
|
1720
|
+
await fs.writeFile(globalIgnorePath, newContent, "utf-8");
|
|
1721
|
+
}
|
|
2084
1722
|
}
|
|
2085
1723
|
];
|
|
2086
1724
|
|
|
@@ -2092,7 +1730,7 @@ var VersionMigrationManager = class {
|
|
|
2092
1730
|
}
|
|
2093
1731
|
// Return path to migration state file
|
|
2094
1732
|
getMigrationStatePath() {
|
|
2095
|
-
return
|
|
1733
|
+
return path3.join(os2.homedir(), ".config", "iloom-ai", "migration-state.json");
|
|
2096
1734
|
}
|
|
2097
1735
|
// Get effective version, respecting ILOOM_VERSION_OVERRIDE env var
|
|
2098
1736
|
// packageVersion is the version from package.json passed by caller
|
|
@@ -2132,7 +1770,7 @@ var VersionMigrationManager = class {
|
|
|
2132
1770
|
async saveMigrationState(version, newFailures = []) {
|
|
2133
1771
|
const statePath = this.getMigrationStatePath();
|
|
2134
1772
|
try {
|
|
2135
|
-
await fs2.ensureDir(
|
|
1773
|
+
await fs2.ensureDir(path3.dirname(statePath));
|
|
2136
1774
|
const existingState = await this.loadFullMigrationState();
|
|
2137
1775
|
const existingFailures = existingState.failedMigrations ?? [];
|
|
2138
1776
|
const allFailures = [...existingFailures];
|
|
@@ -2213,6 +1851,35 @@ var VersionMigrationManager = class {
|
|
|
2213
1851
|
// src/cli.ts
|
|
2214
1852
|
var __filename = fileURLToPath2(import.meta.url);
|
|
2215
1853
|
var packageJson = getPackageInfo(__filename);
|
|
1854
|
+
function handleTelemetryLifecycle(currentVersion, jsonMode) {
|
|
1855
|
+
const service = TelemetryService.getInstance();
|
|
1856
|
+
const telemetryManager = service.getManager();
|
|
1857
|
+
if (!telemetryManager.hasBeenDisclosed()) {
|
|
1858
|
+
if (!jsonMode) {
|
|
1859
|
+
logger.info("");
|
|
1860
|
+
logger.info("iloom collects anonymous usage data to improve the product.");
|
|
1861
|
+
logger.info("No personal information, repo names, or code is collected.");
|
|
1862
|
+
logger.info('Run "il telemetry off" to disable CLI telemetry at any time.');
|
|
1863
|
+
logger.info("If you also use the iloom VS Code extension, its telemetry is managed separately in VS Code settings.");
|
|
1864
|
+
logger.info("");
|
|
1865
|
+
}
|
|
1866
|
+
telemetryManager.markDisclosed();
|
|
1867
|
+
service.track("cli.installed", {
|
|
1868
|
+
version: currentVersion,
|
|
1869
|
+
os: process.platform,
|
|
1870
|
+
node_version: process.version
|
|
1871
|
+
});
|
|
1872
|
+
}
|
|
1873
|
+
const lastVersion = telemetryManager.getLastVersion();
|
|
1874
|
+
if (lastVersion && lastVersion !== currentVersion) {
|
|
1875
|
+
service.track("cli.upgraded", {
|
|
1876
|
+
version: currentVersion,
|
|
1877
|
+
previous_version: lastVersion,
|
|
1878
|
+
os: process.platform
|
|
1879
|
+
});
|
|
1880
|
+
}
|
|
1881
|
+
telemetryManager.setLastVersion(currentVersion);
|
|
1882
|
+
}
|
|
2216
1883
|
function parseIssueIdentifier(value) {
|
|
2217
1884
|
const parsed = parseInt(value, 10);
|
|
2218
1885
|
return !isNaN(parsed) && String(parsed) === value ? parsed : value;
|
|
@@ -2248,6 +1915,12 @@ program.name("iloom").description(packageJson.description).version(packageJson.v
|
|
|
2248
1915
|
} catch (error) {
|
|
2249
1916
|
logger.warn(`Version migration failed: ${error instanceof Error ? error.message : "Unknown"}`);
|
|
2250
1917
|
}
|
|
1918
|
+
try {
|
|
1919
|
+
const jsonMode = actionCommand.opts().json === true;
|
|
1920
|
+
handleTelemetryLifecycle(packageJson.version, jsonMode);
|
|
1921
|
+
} catch (error) {
|
|
1922
|
+
logger.debug(`Telemetry: ${error instanceof Error ? error.message : String(error)}`);
|
|
1923
|
+
}
|
|
2251
1924
|
await validateSettingsForCommand(actionCommand);
|
|
2252
1925
|
await validateGhCliForCommand(actionCommand);
|
|
2253
1926
|
await validateIdeForStartCommand(actionCommand);
|
|
@@ -2262,9 +1935,9 @@ program.name("iloom").description(packageJson.description).version(packageJson.v
|
|
|
2262
1935
|
}
|
|
2263
1936
|
});
|
|
2264
1937
|
async function validateSettingsForCommand(command) {
|
|
2265
|
-
var
|
|
1938
|
+
var _a2, _b;
|
|
2266
1939
|
const commandName = command.name();
|
|
2267
|
-
const bypassCommands = ["help", "init", "update", "contribute"];
|
|
1940
|
+
const bypassCommands = ["help", "init", "update", "contribute", "telemetry"];
|
|
2268
1941
|
if (bypassCommands.includes(commandName)) {
|
|
2269
1942
|
return;
|
|
2270
1943
|
}
|
|
@@ -2273,7 +1946,7 @@ async function validateSettingsForCommand(command) {
|
|
|
2273
1946
|
const settingsManager = new SettingsManager();
|
|
2274
1947
|
const settings = await settingsManager.loadSettings();
|
|
2275
1948
|
const multipleRemotes = await hasMultipleRemotes();
|
|
2276
|
-
if (multipleRemotes && !((_b = (
|
|
1949
|
+
if (multipleRemotes && !((_b = (_a2 = settings.issueManagement) == null ? void 0 : _a2.github) == null ? void 0 : _b.remote)) {
|
|
2277
1950
|
await autoLaunchInitForMultipleRemotes();
|
|
2278
1951
|
return;
|
|
2279
1952
|
}
|
|
@@ -2288,7 +1961,7 @@ async function validateSettingsForCommand(command) {
|
|
|
2288
1961
|
}
|
|
2289
1962
|
}
|
|
2290
1963
|
async function validateGhCliForCommand(command) {
|
|
2291
|
-
var
|
|
1964
|
+
var _a2, _b;
|
|
2292
1965
|
const commandName = command.name();
|
|
2293
1966
|
const alwaysRequireGh = ["feedback", "contribute"];
|
|
2294
1967
|
const conditionallyRequireGh = ["start", "finish", "enhance", "add-issue", "ignite", "spin"];
|
|
@@ -2303,7 +1976,7 @@ async function validateGhCliForCommand(command) {
|
|
|
2303
1976
|
const settingsManager = new SettingsManager();
|
|
2304
1977
|
const settings = await settingsManager.loadSettings();
|
|
2305
1978
|
const provider = IssueTrackerFactory.getProviderName(settings);
|
|
2306
|
-
const mergeBehaviorMode = (
|
|
1979
|
+
const mergeBehaviorMode = (_a2 = settings.mergeBehavior) == null ? void 0 : _a2.mode;
|
|
2307
1980
|
needsGhCli = provider === "github" || mergeBehaviorMode === "github-pr" || mergeBehaviorMode === "github-draft-pr";
|
|
2308
1981
|
} catch {
|
|
2309
1982
|
needsGhCli = true;
|
|
@@ -2341,7 +2014,7 @@ async function validateGhCliForCommand(command) {
|
|
|
2341
2014
|
}
|
|
2342
2015
|
}
|
|
2343
2016
|
async function validateIdeForStartCommand(command) {
|
|
2344
|
-
var
|
|
2017
|
+
var _a2, _b;
|
|
2345
2018
|
const commandName = command.name();
|
|
2346
2019
|
if (commandName !== "start") {
|
|
2347
2020
|
return;
|
|
@@ -2357,7 +2030,7 @@ async function validateIdeForStartCommand(command) {
|
|
|
2357
2030
|
} catch {
|
|
2358
2031
|
return;
|
|
2359
2032
|
}
|
|
2360
|
-
const workflowConfig = (
|
|
2033
|
+
const workflowConfig = (_a2 = settings.workflows) == null ? void 0 : _a2.issue;
|
|
2361
2034
|
if ((workflowConfig == null ? void 0 : workflowConfig.startIde) === false && codeOption !== true) {
|
|
2362
2035
|
return;
|
|
2363
2036
|
}
|
|
@@ -2376,7 +2049,7 @@ async function validateIdeForStartCommand(command) {
|
|
|
2376
2049
|
}
|
|
2377
2050
|
}
|
|
2378
2051
|
async function autoLaunchInitForMultipleRemotes() {
|
|
2379
|
-
var
|
|
2052
|
+
var _a2, _b;
|
|
2380
2053
|
logger.info("Multiple git remotes detected, but no GitHub remote is configured.");
|
|
2381
2054
|
logger.info("");
|
|
2382
2055
|
logger.info("iloom will now launch an interactive configuration session with Claude");
|
|
@@ -2386,19 +2059,19 @@ async function autoLaunchInitForMultipleRemotes() {
|
|
|
2386
2059
|
await waitForKeypress2("Press any key to start configuration...");
|
|
2387
2060
|
logger.info("");
|
|
2388
2061
|
try {
|
|
2389
|
-
const { InitCommand } = await import("./init-
|
|
2062
|
+
const { InitCommand } = await import("./init-32YOKXRL.js");
|
|
2390
2063
|
const initCommand = new InitCommand();
|
|
2391
2064
|
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.";
|
|
2392
2065
|
await initCommand.execute(customInitialMessage);
|
|
2393
2066
|
logger.info("");
|
|
2394
2067
|
logger.info("Configuration complete! Continuing with your original command...");
|
|
2395
2068
|
logger.info("");
|
|
2396
|
-
const { SettingsManager: SettingsManager2 } = await import("./SettingsManager-
|
|
2069
|
+
const { SettingsManager: SettingsManager2 } = await import("./SettingsManager-FNKCOZMQ.js");
|
|
2397
2070
|
const settingsManager = new SettingsManager2();
|
|
2398
2071
|
const settings = await settingsManager.loadSettings();
|
|
2399
2072
|
const { hasMultipleRemotes: hasMultipleRemotes2 } = await import("./remote-IJAMOEAP.js");
|
|
2400
2073
|
const multipleRemotes = await hasMultipleRemotes2();
|
|
2401
|
-
if (multipleRemotes && !((_b = (
|
|
2074
|
+
if (multipleRemotes && !((_b = (_a2 = settings.issueManagement) == null ? void 0 : _a2.github) == null ? void 0 : _b.remote)) {
|
|
2402
2075
|
logger.error("Configuration incomplete: GitHub remote is still not configured.");
|
|
2403
2076
|
logger.info('Please run "iloom init" again and configure the GitHub remote setting.');
|
|
2404
2077
|
process.exit(1);
|
|
@@ -2412,7 +2085,7 @@ async function autoLaunchInitForMultipleRemotes() {
|
|
|
2412
2085
|
}
|
|
2413
2086
|
var shellCompletion = new ShellCompletion();
|
|
2414
2087
|
shellCompletion.init();
|
|
2415
|
-
program.command("start").alias("new").alias("create").alias("up").description("Create isolated workspace for an issue/PR").argument("[identifier]", "Issue number, PR number, or branch name (optional - will prompt if not provided)").option("--claude", "Enable Claude integration (default: true)").option("--no-claude", "Disable Claude integration").option("--code", "Enable VSCode (default: true)").option("--no-code", "Disable VSCode").option("--dev-server", "Enable dev server in terminal (default: true)").option("--no-dev-server", "Disable dev server").option("--terminal", "Enable terminal without dev server (default: false)").option("--no-terminal", "Disable terminal").option("--child-loom", "Force create as child loom (skip prompt)").option("--no-child-loom", "Force create as independent loom (skip prompt)").option("--body <text>", "Body text for issue (skips AI enhancement)").option("--json", "Output result as JSON").addOption(
|
|
2088
|
+
program.command("start").alias("new").alias("create").alias("up").description("Create isolated workspace for an issue/PR").argument("[identifier]", "Issue number, PR number, or branch name (optional - will prompt if not provided)").option("--claude", "Enable Claude integration (default: true)").option("--no-claude", "Disable Claude integration").option("--code", "Enable VSCode (default: true)").option("--no-code", "Disable VSCode").option("--dev-server", "Enable dev server in terminal (default: true)").option("--no-dev-server", "Disable dev server").option("--terminal", "Enable terminal without dev server (default: false)").option("--no-terminal", "Disable terminal").option("--child-loom", "Force create as child loom (skip prompt)").option("--no-child-loom", "Force create as independent loom (skip prompt)").option("--epic", "Create as epic loom with child issues (skip prompt; ignored if no children)").option("--no-epic", "Skip epic loom creation even if issue has children (ignored if no children)").option("--body <text>", "Body text for issue (skips AI enhancement)").option("--json", "Output result as JSON").addOption(
|
|
2416
2089
|
new Option("--one-shot <mode>", "One-shot automation mode").choices(["default", "noReview", "bypassPermissions"]).default("default")
|
|
2417
2090
|
).option("--yolo", "Enable autonomous mode (shorthand for --one-shot=bypassPermissions)").action(async (identifier, options) => {
|
|
2418
2091
|
if (options.yolo) {
|
|
@@ -2490,7 +2163,7 @@ program.command("add-issue").alias("a").description("Create and enhance GitHub i
|
|
|
2490
2163
|
});
|
|
2491
2164
|
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) => {
|
|
2492
2165
|
try {
|
|
2493
|
-
const { FeedbackCommand } = await import("./feedback-
|
|
2166
|
+
const { FeedbackCommand } = await import("./feedback-G2GJFN2F.js");
|
|
2494
2167
|
const command = new FeedbackCommand();
|
|
2495
2168
|
const feedbackOptions = {};
|
|
2496
2169
|
if (options.body !== void 0) {
|
|
@@ -2541,7 +2214,15 @@ program.command("enhance").description("Apply enhancement agent to existing GitH
|
|
|
2541
2214
|
await executeAction();
|
|
2542
2215
|
}
|
|
2543
2216
|
});
|
|
2544
|
-
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
|
|
2217
|
+
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 and github-draft-pr modes)").option("--cleanup", "Clean up worktree after finishing (default in local mode)").option("--no-cleanup", "Keep worktree after finishing").option("--review", "Review commit message before committing (default: auto-commit without review)").option("--json", "Output result as JSON").option("--json-stream", "Stream JSONL output; runs Claude headless for conflict resolution").action(async (identifier, options) => {
|
|
2218
|
+
if (options.browser === false) {
|
|
2219
|
+
options.noBrowser = true;
|
|
2220
|
+
}
|
|
2221
|
+
if (options.json && options.jsonStream) {
|
|
2222
|
+
logger.error("--json and --json-stream are mutually exclusive");
|
|
2223
|
+
process.exit(1);
|
|
2224
|
+
}
|
|
2225
|
+
const isAnyJsonMode = options.json ?? options.jsonStream;
|
|
2545
2226
|
const executeAction = async () => {
|
|
2546
2227
|
try {
|
|
2547
2228
|
const settingsManager = new SettingsManager();
|
|
@@ -2549,13 +2230,14 @@ program.command("finish").alias("dn").description("Merge work and cleanup worksp
|
|
|
2549
2230
|
const issueTracker = IssueTrackerFactory.create(settings);
|
|
2550
2231
|
const command = new FinishCommand(issueTracker);
|
|
2551
2232
|
const result = await command.execute({ identifier, options });
|
|
2552
|
-
if (
|
|
2553
|
-
console.log(JSON.stringify(result, null, 2));
|
|
2233
|
+
if (isAnyJsonMode && result) {
|
|
2234
|
+
console.log(options.jsonStream ? JSON.stringify(result) : JSON.stringify(result, null, 2));
|
|
2554
2235
|
}
|
|
2555
2236
|
process.exit(0);
|
|
2556
2237
|
} catch (error) {
|
|
2557
|
-
if (
|
|
2558
|
-
|
|
2238
|
+
if (isAnyJsonMode) {
|
|
2239
|
+
const errorJson = { success: false, error: error instanceof Error ? error.message : "Unknown error" };
|
|
2240
|
+
console.log(options.jsonStream ? JSON.stringify(errorJson) : JSON.stringify(errorJson, null, 2));
|
|
2559
2241
|
} else {
|
|
2560
2242
|
logger.error(`Failed to finish workspace: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2561
2243
|
}
|
|
@@ -2565,69 +2247,97 @@ program.command("finish").alias("dn").description("Merge work and cleanup worksp
|
|
|
2565
2247
|
process.exit(1);
|
|
2566
2248
|
}
|
|
2567
2249
|
};
|
|
2568
|
-
if (
|
|
2250
|
+
if (isAnyJsonMode) {
|
|
2569
2251
|
const jsonLogger = createStderrLogger();
|
|
2570
2252
|
await withLogger(jsonLogger, executeAction);
|
|
2571
2253
|
} else {
|
|
2572
2254
|
await executeAction();
|
|
2573
2255
|
}
|
|
2574
2256
|
});
|
|
2575
|
-
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) => {
|
|
2257
|
+
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("--json-stream", "Stream JSONL output; runs Claude headless for validation fixes").option("--wip-commit", "Quick WIP commit: skip validations and pre-commit hooks").action(async (options) => {
|
|
2258
|
+
if (options.json && options.jsonStream) {
|
|
2259
|
+
logger.error("--json and --json-stream are mutually exclusive");
|
|
2260
|
+
process.exit(1);
|
|
2261
|
+
}
|
|
2262
|
+
const isAnyJsonMode = options.json ?? options.jsonStream;
|
|
2576
2263
|
const executeAction = async () => {
|
|
2577
2264
|
try {
|
|
2578
|
-
const { CommitCommand } = await import("./commit-
|
|
2265
|
+
const { CommitCommand } = await import("./commit-FZR5XDQG.js");
|
|
2579
2266
|
const command = new CommitCommand();
|
|
2580
|
-
const noReview = options.review === false || options.json === true;
|
|
2267
|
+
const noReview = options.review === false || options.json === true || options.jsonStream === true;
|
|
2581
2268
|
const result = await command.execute({
|
|
2582
2269
|
message: options.message,
|
|
2583
2270
|
fixes: options.fixes ?? false,
|
|
2584
2271
|
noReview,
|
|
2585
2272
|
json: options.json ?? false,
|
|
2273
|
+
jsonStream: options.jsonStream ?? false,
|
|
2586
2274
|
wipCommit: options.wipCommit ?? false
|
|
2587
2275
|
});
|
|
2588
|
-
if (
|
|
2589
|
-
console.log(JSON.stringify(result, null, 2));
|
|
2276
|
+
if (isAnyJsonMode && result) {
|
|
2277
|
+
console.log(options.jsonStream ? JSON.stringify(result) : JSON.stringify(result, null, 2));
|
|
2590
2278
|
}
|
|
2591
2279
|
process.exit(0);
|
|
2592
2280
|
} catch (error) {
|
|
2593
2281
|
if (error instanceof UserAbortedCommitError) {
|
|
2594
2282
|
process.exit(130);
|
|
2595
2283
|
}
|
|
2596
|
-
if (
|
|
2597
|
-
|
|
2284
|
+
if (isAnyJsonMode) {
|
|
2285
|
+
const errorJson = { success: false, error: error instanceof Error ? error.message : "Unknown error" };
|
|
2286
|
+
console.log(options.jsonStream ? JSON.stringify(errorJson) : JSON.stringify(errorJson, null, 2));
|
|
2598
2287
|
} else {
|
|
2599
2288
|
logger.error(`Commit failed: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2600
2289
|
}
|
|
2601
2290
|
process.exit(1);
|
|
2602
2291
|
}
|
|
2603
2292
|
};
|
|
2604
|
-
if (
|
|
2293
|
+
if (isAnyJsonMode) {
|
|
2605
2294
|
const jsonLogger = createStderrLogger();
|
|
2606
2295
|
await withLogger(jsonLogger, executeAction);
|
|
2607
2296
|
} else {
|
|
2608
2297
|
await executeAction();
|
|
2609
2298
|
}
|
|
2610
2299
|
});
|
|
2611
|
-
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) => {
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2300
|
+
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").option("--json-stream", "Stream JSONL output; runs Claude headless for conflict resolution").action(async (options) => {
|
|
2301
|
+
const executeAction = async () => {
|
|
2302
|
+
try {
|
|
2303
|
+
const { RebaseCommand } = await import("./rebase-6NVLX5V7.js");
|
|
2304
|
+
const command = new RebaseCommand();
|
|
2305
|
+
const result = await command.execute(options);
|
|
2306
|
+
if (options.jsonStream && result) {
|
|
2307
|
+
console.log(JSON.stringify(result));
|
|
2308
|
+
}
|
|
2309
|
+
process.exit(0);
|
|
2310
|
+
} catch (error) {
|
|
2311
|
+
if (options.jsonStream) {
|
|
2312
|
+
console.log(JSON.stringify({
|
|
2313
|
+
success: false,
|
|
2314
|
+
conflictsDetected: false,
|
|
2315
|
+
claudeLaunched: false,
|
|
2316
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
2317
|
+
}));
|
|
2318
|
+
} else {
|
|
2319
|
+
logger.error(`Failed to rebase: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2320
|
+
}
|
|
2321
|
+
process.exit(1);
|
|
2322
|
+
}
|
|
2323
|
+
};
|
|
2324
|
+
if (options.jsonStream) {
|
|
2325
|
+
const jsonLogger = createStderrLogger();
|
|
2326
|
+
await withLogger(jsonLogger, executeAction);
|
|
2327
|
+
} else {
|
|
2328
|
+
await executeAction();
|
|
2619
2329
|
}
|
|
2620
2330
|
});
|
|
2621
2331
|
program.command("spin").alias("ignite").description("Launch Claude with auto-detected workspace context").addOption(
|
|
2622
2332
|
new Option("--one-shot <mode>", "One-shot automation mode").choices(["default", "noReview", "bypassPermissions"])
|
|
2623
2333
|
).option("--yolo", "Enable autonomous mode (shorthand for --one-shot=bypassPermissions)").option("-p, --print", "Enable print/headless mode for CI/CD (uses bypassPermissions)").addOption(
|
|
2624
2334
|
new Option("--output-format <format>", "Output format for Claude CLI (requires --print)").choices(["json", "stream-json", "text"])
|
|
2625
|
-
).option("--verbose", "Enable verbose output (requires --print)").option("--json", "Output final result as JSON object (requires --print)").option("--json-stream", "Stream JSONL output to stdout in real-time (requires --print)").action(async (options) => {
|
|
2335
|
+
).option("--verbose", "Enable verbose output (requires --print)").option("--json", "Output final result as JSON object (requires --print)").option("--json-stream", "Stream JSONL output to stdout in real-time (requires --print)").option("--set <key=value>", "Override settings (repeatable, e.g., --set workflows.issue.permissionMode=bypassPermissions)").option("--skip-cleanup", "Skip automatic cleanup of child worktrees after they complete in swarm mode").action(async (options) => {
|
|
2626
2336
|
if (options.yolo) {
|
|
2627
2337
|
options.oneShot = "bypassPermissions";
|
|
2628
2338
|
}
|
|
2629
2339
|
try {
|
|
2630
|
-
const { IgniteCommand } = await import("./ignite-
|
|
2340
|
+
const { IgniteCommand } = await import("./ignite-H2O5Y5A2.js");
|
|
2631
2341
|
const command = new IgniteCommand();
|
|
2632
2342
|
if (options.json && options.jsonStream) {
|
|
2633
2343
|
logger.error("--json and --json-stream are mutually exclusive");
|
|
@@ -2646,7 +2356,7 @@ program.command("spin").alias("ignite").description("Launch Claude with auto-det
|
|
|
2646
2356
|
...options.json && { json: true },
|
|
2647
2357
|
...options.jsonStream && { jsonStream: true }
|
|
2648
2358
|
} : void 0;
|
|
2649
|
-
await command.execute(options.oneShot, printOptions);
|
|
2359
|
+
await command.execute(options.oneShot, printOptions, options.skipCleanup);
|
|
2650
2360
|
} catch (error) {
|
|
2651
2361
|
logger.error(`Failed to spin up loom: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2652
2362
|
process.exit(1);
|
|
@@ -2655,7 +2365,7 @@ program.command("spin").alias("ignite").description("Launch Claude with auto-det
|
|
|
2655
2365
|
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) => {
|
|
2656
2366
|
try {
|
|
2657
2367
|
const args = (command == null ? void 0 : command.args) ? command.args.slice(identifier ? 1 : 0) : [];
|
|
2658
|
-
const { OpenCommand } = await import("./open-
|
|
2368
|
+
const { OpenCommand } = await import("./open-FXWW3VI4.js");
|
|
2659
2369
|
const cmd = new OpenCommand();
|
|
2660
2370
|
const input = identifier ? { identifier, args } : { args };
|
|
2661
2371
|
await cmd.execute(input);
|
|
@@ -2667,7 +2377,7 @@ program.command("open").description("Open workspace in browser or run CLI tool")
|
|
|
2667
2377
|
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) => {
|
|
2668
2378
|
try {
|
|
2669
2379
|
const args = (command == null ? void 0 : command.args) ? command.args.slice(identifier ? 1 : 0) : [];
|
|
2670
|
-
const { RunCommand } = await import("./run-
|
|
2380
|
+
const { RunCommand } = await import("./run-BBXLRIZB.js");
|
|
2671
2381
|
const cmd = new RunCommand();
|
|
2672
2382
|
const input = identifier ? { identifier, args } : { args };
|
|
2673
2383
|
await cmd.execute(input);
|
|
@@ -2678,7 +2388,7 @@ program.command("run").description("Run CLI tool or open workspace in browser").
|
|
|
2678
2388
|
});
|
|
2679
2389
|
program.command("vscode").description("Install iloom VS Code extension and open workspace in VS Code").argument("[identifier]", "Issue number, PR number, or branch name (auto-detected if omitted)").option("--no-wait", "Skip keypress prompt and open immediately").action(async (identifier, options) => {
|
|
2680
2390
|
try {
|
|
2681
|
-
const { VSCodeCommand } = await import("./vscode-
|
|
2391
|
+
const { VSCodeCommand } = await import("./vscode-6XUGHJKL.js");
|
|
2682
2392
|
const cmd = new VSCodeCommand();
|
|
2683
2393
|
await cmd.execute({ identifier, wait: options == null ? void 0 : options.wait });
|
|
2684
2394
|
} catch (error) {
|
|
@@ -2687,7 +2397,7 @@ program.command("vscode").description("Install iloom VS Code extension and open
|
|
|
2687
2397
|
});
|
|
2688
2398
|
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) => {
|
|
2689
2399
|
try {
|
|
2690
|
-
const { DevServerCommand } = await import("./dev-server-
|
|
2400
|
+
const { DevServerCommand } = await import("./dev-server-7SMIB7OF.js");
|
|
2691
2401
|
const cmd = new DevServerCommand();
|
|
2692
2402
|
await cmd.execute({ identifier, json: options == null ? void 0 : options.json });
|
|
2693
2403
|
} catch (error) {
|
|
@@ -2697,7 +2407,7 @@ program.command("dev-server").alias("dev").description("Start dev server for wor
|
|
|
2697
2407
|
});
|
|
2698
2408
|
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) => {
|
|
2699
2409
|
try {
|
|
2700
|
-
const { ShellCommand } = await import("./shell-
|
|
2410
|
+
const { ShellCommand } = await import("./shell-RF7LTND5.js");
|
|
2701
2411
|
const cmd = new ShellCommand();
|
|
2702
2412
|
await cmd.execute({ identifier });
|
|
2703
2413
|
} catch (error) {
|
|
@@ -2707,7 +2417,7 @@ program.command("shell").alias("terminal").description("Open interactive shell w
|
|
|
2707
2417
|
});
|
|
2708
2418
|
program.command("build").description("Run the build script").argument("[identifier]", "Issue number, PR number, or branch name (auto-detected if omitted)").action(async (identifier) => {
|
|
2709
2419
|
try {
|
|
2710
|
-
const { BuildCommand } = await import("./build-
|
|
2420
|
+
const { BuildCommand } = await import("./build-VHGEMXBA.js");
|
|
2711
2421
|
const cmd = new BuildCommand();
|
|
2712
2422
|
await cmd.execute(identifier ? { identifier } : {});
|
|
2713
2423
|
} catch (error) {
|
|
@@ -2717,7 +2427,7 @@ program.command("build").description("Run the build script").argument("[identifi
|
|
|
2717
2427
|
});
|
|
2718
2428
|
program.command("lint").description("Run the lint script").argument("[identifier]", "Issue number, PR number, or branch name (auto-detected if omitted)").action(async (identifier) => {
|
|
2719
2429
|
try {
|
|
2720
|
-
const { LintCommand } = await import("./lint-
|
|
2430
|
+
const { LintCommand } = await import("./lint-AAN2NZWG.js");
|
|
2721
2431
|
const cmd = new LintCommand();
|
|
2722
2432
|
await cmd.execute(identifier ? { identifier } : {});
|
|
2723
2433
|
} catch (error) {
|
|
@@ -2727,7 +2437,7 @@ program.command("lint").description("Run the lint script").argument("[identifier
|
|
|
2727
2437
|
});
|
|
2728
2438
|
program.command("test").description("Run the test script").argument("[identifier]", "Issue number, PR number, or branch name (auto-detected if omitted)").action(async (identifier) => {
|
|
2729
2439
|
try {
|
|
2730
|
-
const { TestCommand } = await import("./test-
|
|
2440
|
+
const { TestCommand } = await import("./test-SGO6I5Z7.js");
|
|
2731
2441
|
const cmd = new TestCommand();
|
|
2732
2442
|
await cmd.execute(identifier ? { identifier } : {});
|
|
2733
2443
|
} catch (error) {
|
|
@@ -2737,7 +2447,7 @@ program.command("test").description("Run the test script").argument("[identifier
|
|
|
2737
2447
|
});
|
|
2738
2448
|
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) => {
|
|
2739
2449
|
try {
|
|
2740
|
-
const { CompileCommand } = await import("./compile-
|
|
2450
|
+
const { CompileCommand } = await import("./compile-7ALJHZ4N.js");
|
|
2741
2451
|
const cmd = new CompileCommand();
|
|
2742
2452
|
await cmd.execute(identifier ? { identifier } : {});
|
|
2743
2453
|
} catch (error) {
|
|
@@ -2745,10 +2455,10 @@ program.command("compile").alias("typecheck").description("Run the compile or ty
|
|
|
2745
2455
|
process.exit(1);
|
|
2746
2456
|
}
|
|
2747
2457
|
});
|
|
2748
|
-
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) => {
|
|
2458
|
+
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("--archive", "Archive metadata instead of deleting (preserves loom in il list --finished)").option("--defer <ms>", "Wait specified milliseconds before cleanup", parseInt).action(async (identifier, options) => {
|
|
2749
2459
|
const executeAction = async () => {
|
|
2750
2460
|
try {
|
|
2751
|
-
const { CleanupCommand } = await import("./cleanup-
|
|
2461
|
+
const { CleanupCommand } = await import("./cleanup-6PVAC4NI.js");
|
|
2752
2462
|
const command = new CleanupCommand();
|
|
2753
2463
|
const input = {
|
|
2754
2464
|
options: options ?? {}
|
|
@@ -2777,6 +2487,22 @@ program.command("cleanup").alias("remove").alias("clean").description("Remove wo
|
|
|
2777
2487
|
await executeAction();
|
|
2778
2488
|
}
|
|
2779
2489
|
});
|
|
2490
|
+
function colorizeState(state) {
|
|
2491
|
+
switch (state) {
|
|
2492
|
+
case "pending":
|
|
2493
|
+
return chalk.gray(state);
|
|
2494
|
+
case "in_progress":
|
|
2495
|
+
return chalk.yellow(state);
|
|
2496
|
+
case "code_review":
|
|
2497
|
+
return chalk.blue(state);
|
|
2498
|
+
case "done":
|
|
2499
|
+
return chalk.green(state);
|
|
2500
|
+
case "failed":
|
|
2501
|
+
return chalk.red(state);
|
|
2502
|
+
default:
|
|
2503
|
+
return chalk.gray(state);
|
|
2504
|
+
}
|
|
2505
|
+
}
|
|
2780
2506
|
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)").option("--children", "Fetch and display child issues and child looms for each parent loom").action(async (options) => {
|
|
2781
2507
|
try {
|
|
2782
2508
|
const manager = new GitWorktreeManager();
|
|
@@ -2834,10 +2560,7 @@ program.command("list").description("Show active workspaces").option("--json", "
|
|
|
2834
2560
|
}
|
|
2835
2561
|
}
|
|
2836
2562
|
}
|
|
2837
|
-
|
|
2838
|
-
if (showFinished) {
|
|
2839
|
-
finishedLooms = await metadataManager.listFinishedMetadata();
|
|
2840
|
-
}
|
|
2563
|
+
const finishedLooms = await metadataManager.listFinishedMetadata();
|
|
2841
2564
|
let filteredWorktrees = worktrees;
|
|
2842
2565
|
let filteredGlobalActiveLooms = globalActiveLooms;
|
|
2843
2566
|
let filteredFinishedLooms = finishedLooms;
|
|
@@ -2856,32 +2579,41 @@ program.command("list").description("Show active workspaces").option("--json", "
|
|
|
2856
2579
|
mainWorktreePath = await findMainWorktreePathWithSettings();
|
|
2857
2580
|
} catch {
|
|
2858
2581
|
}
|
|
2582
|
+
const allActiveMetadata = options.global ? globalActiveLooms : Array.from(metadata.values()).filter((m) => m != null);
|
|
2859
2583
|
let activeJson = [];
|
|
2860
2584
|
if (showActive) {
|
|
2861
2585
|
if (options.global) {
|
|
2862
|
-
activeJson = globalActiveLooms.map((loom) =>
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2586
|
+
activeJson = globalActiveLooms.map((loom) => {
|
|
2587
|
+
const isEpic = (loom.issueType ?? "branch") === "epic";
|
|
2588
|
+
const swarmIssues = isEpic && loom.childIssues && loom.childIssues.length > 0 ? enrichSwarmIssues(loom.childIssues, globalActiveLooms, finishedLooms, loom.projectPath) : isEpic ? [] : void 0;
|
|
2589
|
+
const depMap = isEpic ? loom.dependencyMap && Object.keys(loom.dependencyMap).length > 0 ? loom.dependencyMap : {} : void 0;
|
|
2590
|
+
return {
|
|
2591
|
+
name: loom.branchName ?? loom.worktreePath ?? "unknown",
|
|
2592
|
+
worktreePath: loom.worktreePath,
|
|
2593
|
+
branch: loom.branchName,
|
|
2594
|
+
type: loom.issueType ?? "branch",
|
|
2595
|
+
issue_numbers: loom.issue_numbers,
|
|
2596
|
+
pr_numbers: loom.pr_numbers,
|
|
2597
|
+
isMainWorktree: false,
|
|
2598
|
+
// Global looms from other projects are never the main worktree
|
|
2599
|
+
description: loom.description ?? null,
|
|
2600
|
+
created_at: loom.created_at ?? null,
|
|
2601
|
+
issueTracker: loom.issueTracker ?? null,
|
|
2602
|
+
colorHex: loom.colorHex ?? null,
|
|
2603
|
+
projectPath: loom.projectPath ?? null,
|
|
2604
|
+
issueUrls: loom.issueUrls ?? {},
|
|
2605
|
+
prUrls: loom.prUrls ?? {},
|
|
2606
|
+
status: "active",
|
|
2607
|
+
finishedAt: null,
|
|
2608
|
+
state: loom.state ?? null,
|
|
2609
|
+
isChildLoom: loom.parentLoom != null,
|
|
2610
|
+
parentLoom: loom.parentLoom ?? null,
|
|
2611
|
+
...swarmIssues !== void 0 && { swarmIssues },
|
|
2612
|
+
...depMap !== void 0 && { dependencyMap: depMap }
|
|
2613
|
+
};
|
|
2614
|
+
});
|
|
2883
2615
|
} else {
|
|
2884
|
-
activeJson = formatLoomsForJson(worktrees, mainWorktreePath, metadata).map((loom) => ({
|
|
2616
|
+
activeJson = formatLoomsForJson(worktrees, mainWorktreePath, metadata, allActiveMetadata, finishedLooms).map((loom) => ({
|
|
2885
2617
|
...loom,
|
|
2886
2618
|
status: "active",
|
|
2887
2619
|
finishedAt: null
|
|
@@ -2893,7 +2625,7 @@ program.command("list").description("Show active workspaces").option("--json", "
|
|
|
2893
2625
|
(loom) => loom.projectPath == null || loom.projectPath === currentProjectPath
|
|
2894
2626
|
);
|
|
2895
2627
|
}
|
|
2896
|
-
let finishedJson = finishedLooms.map(formatFinishedLoomForJson);
|
|
2628
|
+
let finishedJson = showFinished ? finishedLooms.map((loom) => formatFinishedLoomForJson(loom, allActiveMetadata, finishedLooms)) : [];
|
|
2897
2629
|
if (currentProjectPath) {
|
|
2898
2630
|
finishedJson = finishedJson.filter(
|
|
2899
2631
|
(loom) => loom.projectPath == null || loom.projectPath === currentProjectPath
|
|
@@ -2902,6 +2634,7 @@ program.command("list").description("Show active workspaces").option("--json", "
|
|
|
2902
2634
|
if (options.children) {
|
|
2903
2635
|
const settingsManager = new SettingsManager();
|
|
2904
2636
|
const settings = await settingsManager.loadSettings();
|
|
2637
|
+
const issueTracker = IssueTrackerFactory.create(settings);
|
|
2905
2638
|
const activeChildrenResults = await Promise.allSettled(
|
|
2906
2639
|
activeJson.map(async (loom) => {
|
|
2907
2640
|
const index = activeJson.indexOf(loom);
|
|
@@ -2909,7 +2642,7 @@ program.command("list").description("Show active workspaces").option("--json", "
|
|
|
2909
2642
|
if (!loomMetadata) {
|
|
2910
2643
|
return { index, children: null };
|
|
2911
2644
|
}
|
|
2912
|
-
const children = await assembleChildrenData(loomMetadata, metadataManager,
|
|
2645
|
+
const children = await assembleChildrenData(loomMetadata, metadataManager, issueTracker);
|
|
2913
2646
|
return { index, children };
|
|
2914
2647
|
})
|
|
2915
2648
|
);
|
|
@@ -2927,7 +2660,7 @@ program.command("list").description("Show active workspaces").option("--json", "
|
|
|
2927
2660
|
if (!loomMetadata) {
|
|
2928
2661
|
return { index, children: null };
|
|
2929
2662
|
}
|
|
2930
|
-
const children = await assembleChildrenData(loomMetadata, metadataManager,
|
|
2663
|
+
const children = await assembleChildrenData(loomMetadata, metadataManager, issueTracker);
|
|
2931
2664
|
return { index, children };
|
|
2932
2665
|
})
|
|
2933
2666
|
);
|
|
@@ -2956,10 +2689,11 @@ program.command("list").description("Show active workspaces").option("--json", "
|
|
|
2956
2689
|
}
|
|
2957
2690
|
return;
|
|
2958
2691
|
}
|
|
2959
|
-
let
|
|
2692
|
+
let textIssueTracker = null;
|
|
2960
2693
|
if (options.children) {
|
|
2961
2694
|
const settingsManager = new SettingsManager();
|
|
2962
|
-
textSettings = await settingsManager.loadSettings();
|
|
2695
|
+
const textSettings = await settingsManager.loadSettings();
|
|
2696
|
+
textIssueTracker = IssueTrackerFactory.create(textSettings);
|
|
2963
2697
|
}
|
|
2964
2698
|
if (showActive && hasActive) {
|
|
2965
2699
|
logger.info("Active workspaces:");
|
|
@@ -2973,14 +2707,17 @@ program.command("list").description("Show active workspaces").option("--json", "
|
|
|
2973
2707
|
if (loom.description) {
|
|
2974
2708
|
logger.info(` Description: ${loom.description}`);
|
|
2975
2709
|
}
|
|
2710
|
+
if (loom.state) {
|
|
2711
|
+
logger.info(` State: ${colorizeState(loom.state)}`);
|
|
2712
|
+
}
|
|
2976
2713
|
if (loom.worktreePath) {
|
|
2977
2714
|
logger.info(` Path: ${loom.worktreePath}`);
|
|
2978
2715
|
}
|
|
2979
2716
|
if (loom.projectPath) {
|
|
2980
2717
|
logger.info(` Project: ${loom.projectPath}`);
|
|
2981
2718
|
}
|
|
2982
|
-
if (options.children &&
|
|
2983
|
-
const childrenData = await assembleChildrenData(loom, metadataManager,
|
|
2719
|
+
if (options.children && textIssueTracker) {
|
|
2720
|
+
const childrenData = await assembleChildrenData(loom, metadataManager, textIssueTracker);
|
|
2984
2721
|
if (childrenData && (childrenData.summary.totalIssues > 0 || childrenData.summary.totalLooms > 0)) {
|
|
2985
2722
|
logger.info(` Child Issues: ${childrenData.summary.totalIssues} (${childrenData.summary.issuesWithLooms} with active looms)`);
|
|
2986
2723
|
for (const issue of childrenData.issues) {
|
|
@@ -3003,10 +2740,13 @@ program.command("list").description("Show active workspaces").option("--json", "
|
|
|
3003
2740
|
if (loomMetadata == null ? void 0 : loomMetadata.description) {
|
|
3004
2741
|
logger.info(` Description: ${loomMetadata.description}`);
|
|
3005
2742
|
}
|
|
2743
|
+
if (loomMetadata == null ? void 0 : loomMetadata.state) {
|
|
2744
|
+
logger.info(` State: ${colorizeState(loomMetadata.state)}`);
|
|
2745
|
+
}
|
|
3006
2746
|
logger.info(` Path: ${formatted.path}`);
|
|
3007
2747
|
logger.info(` Commit: ${formatted.commit}`);
|
|
3008
|
-
if (options.children &&
|
|
3009
|
-
const childrenData = await assembleChildrenData(loomMetadata, metadataManager,
|
|
2748
|
+
if (options.children && textIssueTracker && loomMetadata) {
|
|
2749
|
+
const childrenData = await assembleChildrenData(loomMetadata, metadataManager, textIssueTracker);
|
|
3010
2750
|
if (childrenData && (childrenData.summary.totalIssues > 0 || childrenData.summary.totalLooms > 0)) {
|
|
3011
2751
|
logger.info(` Child Issues: ${childrenData.summary.totalIssues} (${childrenData.summary.issuesWithLooms} with active looms)`);
|
|
3012
2752
|
for (const issue of childrenData.issues) {
|
|
@@ -3033,11 +2773,14 @@ program.command("list").description("Show active workspaces").option("--json", "
|
|
|
3033
2773
|
if (loom.description) {
|
|
3034
2774
|
logger.info(` Description: ${loom.description}`);
|
|
3035
2775
|
}
|
|
2776
|
+
if (loom.state) {
|
|
2777
|
+
logger.info(` State: ${colorizeState(loom.state)}`);
|
|
2778
|
+
}
|
|
3036
2779
|
if (loom.finishedAt) {
|
|
3037
2780
|
logger.info(` Finished: ${new Date(loom.finishedAt).toLocaleString()}`);
|
|
3038
2781
|
}
|
|
3039
|
-
if (options.children &&
|
|
3040
|
-
const childrenData = await assembleChildrenData(loom, metadataManager,
|
|
2782
|
+
if (options.children && textIssueTracker) {
|
|
2783
|
+
const childrenData = await assembleChildrenData(loom, metadataManager, textIssueTracker);
|
|
3041
2784
|
if (childrenData && (childrenData.summary.totalIssues > 0 || childrenData.summary.totalLooms > 0)) {
|
|
3042
2785
|
logger.info(` Child Issues: ${childrenData.summary.totalIssues} (${childrenData.summary.issuesWithLooms} with active looms)`);
|
|
3043
2786
|
for (const issue of childrenData.issues) {
|
|
@@ -3064,7 +2807,7 @@ program.command("list").description("Show active workspaces").option("--json", "
|
|
|
3064
2807
|
});
|
|
3065
2808
|
program.command("projects").description("List configured iloom projects").option("--json", "Output as JSON (default behavior)").action(async (options) => {
|
|
3066
2809
|
try {
|
|
3067
|
-
const { ProjectsCommand } = await import("./projects-
|
|
2810
|
+
const { ProjectsCommand } = await import("./projects-2UOXFLNZ.js");
|
|
3068
2811
|
const command = new ProjectsCommand();
|
|
3069
2812
|
const result = await command.execute(options);
|
|
3070
2813
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -3073,15 +2816,17 @@ program.command("projects").description("List configured iloom projects").option
|
|
|
3073
2816
|
process.exit(1);
|
|
3074
2817
|
}
|
|
3075
2818
|
});
|
|
3076
|
-
program.command("issues").description("List project issues from configured issue tracker").argument("[project-path]", "Path to project root (auto-detected if omitted)").option("--json", "Output as JSON (default behavior)").option("--limit <n>", "Max issues to return", "100").action(async (projectPath, options) => {
|
|
2819
|
+
program.command("issues").description("List project issues from configured issue tracker").argument("[project-path]", "Path to project root (auto-detected if omitted)").option("--json", "Output as JSON (default behavior)").option("--limit <n>", "Max issues to return", "100").option("--sprint <name>", 'Jira only: filter by sprint name (e.g., "Sprint 17") or "current" for active sprint').option("--mine", "Show only issues and PRs assigned to me").action(async (projectPath, options) => {
|
|
3077
2820
|
try {
|
|
3078
|
-
const { IssuesCommand } = await import("./issues-
|
|
2821
|
+
const { IssuesCommand } = await import("./issues-4UUAQ5K6.js");
|
|
3079
2822
|
const command = new IssuesCommand();
|
|
3080
2823
|
const parsedLimit = parseInt((options == null ? void 0 : options.limit) ?? "100", 10);
|
|
3081
2824
|
const limit = Number.isNaN(parsedLimit) || parsedLimit <= 0 ? 100 : parsedLimit;
|
|
3082
2825
|
const result = await command.execute({
|
|
3083
2826
|
...projectPath ? { projectPath } : {},
|
|
3084
|
-
limit
|
|
2827
|
+
limit,
|
|
2828
|
+
sprint: options == null ? void 0 : options.sprint,
|
|
2829
|
+
mine: options == null ? void 0 : options.mine
|
|
3085
2830
|
});
|
|
3086
2831
|
console.log(JSON.stringify(result, null, 2));
|
|
3087
2832
|
} catch (error) {
|
|
@@ -3089,13 +2834,13 @@ program.command("issues").description("List project issues from configured issue
|
|
|
3089
2834
|
process.exit(1);
|
|
3090
2835
|
}
|
|
3091
2836
|
});
|
|
3092
|
-
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) => {
|
|
2837
|
+
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.")').addOption(new Option("--accept-defaults").hideHelp()).action(async (prompt, options) => {
|
|
3093
2838
|
try {
|
|
3094
|
-
const { InitCommand } = await import("./init-
|
|
2839
|
+
const { InitCommand } = await import("./init-32YOKXRL.js");
|
|
3095
2840
|
const command = new InitCommand();
|
|
3096
2841
|
const trimmedPrompt = prompt == null ? void 0 : prompt.trim();
|
|
3097
2842
|
const customPrompt = trimmedPrompt && trimmedPrompt.length > 0 ? trimmedPrompt : void 0;
|
|
3098
|
-
await command.execute(customPrompt);
|
|
2843
|
+
await command.execute(customPrompt, options == null ? void 0 : options.acceptDefaults);
|
|
3099
2844
|
} catch (error) {
|
|
3100
2845
|
logger.error(`Failed to initialize: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
3101
2846
|
process.exit(1);
|
|
@@ -3103,9 +2848,9 @@ program.command("init").alias("config").description("Initialize iloom configurat
|
|
|
3103
2848
|
});
|
|
3104
2849
|
program.command("plan").description("Launch interactive planning session with Architect persona").argument("[prompt]", "Initial planning prompt or topic").option("--model <model>", "Model to use (default: opus)").option("--yolo", "Enable autonomous mode - Claude proceeds without user interaction").option("--planner <provider>", "AI provider for planning: claude, gemini, codex (default: claude)").option("--reviewer <provider>", "AI provider for review: claude, gemini, codex, none (default: none)").option("-p, --print", "Enable print/headless mode for CI/CD (uses bypassPermissions)").addOption(
|
|
3105
2850
|
new Option("--output-format <format>", "Output format for Claude CLI (requires --print)").choices(["json", "stream-json", "text"])
|
|
3106
|
-
).option("--verbose", "Enable verbose output (requires --print)").option("--json", "Output final result as JSON object (requires --print)").option("--json-stream", "Stream JSONL output to stdout in real-time (requires --print)").action(async (prompt, options) => {
|
|
2851
|
+
).option("--verbose", "Enable verbose output (requires --print)").option("--json", "Output final result as JSON object (requires --print)").option("--json-stream", "Stream JSONL output to stdout in real-time (requires --print)").option("--auto-swarm", "Enable auto-swarm: plan, start epic, and spin automatically").action(async (prompt, options) => {
|
|
3107
2852
|
try {
|
|
3108
|
-
const { PlanCommand } = await import("./plan-
|
|
2853
|
+
const { PlanCommand } = await import("./plan-RQ5FPIGF.js");
|
|
3109
2854
|
const command = new PlanCommand();
|
|
3110
2855
|
if ((options == null ? void 0 : options.json) && (options == null ? void 0 : options.jsonStream)) {
|
|
3111
2856
|
logger.error("--json and --json-stream are mutually exclusive");
|
|
@@ -3124,7 +2869,7 @@ program.command("plan").description("Launch interactive planning session with Ar
|
|
|
3124
2869
|
...(options == null ? void 0 : options.json) && { json: true },
|
|
3125
2870
|
...(options == null ? void 0 : options.jsonStream) && { jsonStream: true }
|
|
3126
2871
|
} : void 0;
|
|
3127
|
-
await command.execute(prompt, options == null ? void 0 : options.model, options == null ? void 0 : options.yolo, options == null ? void 0 : options.planner, options == null ? void 0 : options.reviewer, printOptions);
|
|
2872
|
+
await command.execute(prompt, options == null ? void 0 : options.model, options == null ? void 0 : options.yolo, options == null ? void 0 : options.planner, options == null ? void 0 : options.reviewer, printOptions, options == null ? void 0 : options.autoSwarm);
|
|
3128
2873
|
} catch (error) {
|
|
3129
2874
|
logger.error(`Planning session failed: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
3130
2875
|
process.exit(1);
|
|
@@ -3132,7 +2877,7 @@ program.command("plan").description("Launch interactive planning session with Ar
|
|
|
3132
2877
|
});
|
|
3133
2878
|
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) => {
|
|
3134
2879
|
try {
|
|
3135
|
-
const { ContributeCommand } = await import("./contribute-
|
|
2880
|
+
const { ContributeCommand } = await import("./contribute-5GKLK3BQ.js");
|
|
3136
2881
|
const command = new ContributeCommand();
|
|
3137
2882
|
await command.execute(repository);
|
|
3138
2883
|
} catch (error) {
|
|
@@ -3152,11 +2897,11 @@ program.command("update").description("Update iloom-cli to the latest version").
|
|
|
3152
2897
|
});
|
|
3153
2898
|
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) => {
|
|
3154
2899
|
try {
|
|
3155
|
-
const { GitHubService: GitHubService2 } = await import("./GitHubService-
|
|
3156
|
-
const { DefaultBranchNamingService
|
|
2900
|
+
const { GitHubService: GitHubService2 } = await import("./GitHubService-MEHKHUQP.js");
|
|
2901
|
+
const { DefaultBranchNamingService } = await import("./BranchNamingService-25KSZAEM.js");
|
|
3157
2902
|
logger.info("Testing GitHub Integration\n");
|
|
3158
2903
|
const service = new GitHubService2();
|
|
3159
|
-
const branchNaming = new
|
|
2904
|
+
const branchNaming = new DefaultBranchNamingService({ useClaude: options.claude !== false });
|
|
3160
2905
|
logger.info("Detecting input type...");
|
|
3161
2906
|
const detection = await service.detectInputType(identifier);
|
|
3162
2907
|
logger.info(` Type: ${detection.type}`);
|
|
@@ -3211,10 +2956,10 @@ program.command("test-github").description("Test GitHub integration (Issue #3)")
|
|
|
3211
2956
|
});
|
|
3212
2957
|
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) => {
|
|
3213
2958
|
try {
|
|
3214
|
-
const { detectClaudeCli, getClaudeVersion, generateBranchName, launchClaude } = await import("./claude-
|
|
3215
|
-
const { PromptTemplateManager } = await import("./PromptTemplateManager-
|
|
3216
|
-
const { ClaudeService } = await import("./ClaudeService-
|
|
3217
|
-
const { ClaudeContextManager: ClaudeContextManager2 } = await import("./ClaudeContextManager-
|
|
2959
|
+
const { detectClaudeCli, getClaudeVersion, generateBranchName, launchClaude } = await import("./claude-7GGEWVEM.js");
|
|
2960
|
+
const { PromptTemplateManager } = await import("./PromptTemplateManager-YOE2SIPG.js");
|
|
2961
|
+
const { ClaudeService } = await import("./ClaudeService-7KM5NA5Z.js");
|
|
2962
|
+
const { ClaudeContextManager: ClaudeContextManager2 } = await import("./ClaudeContextManager-66GR4BGM.js");
|
|
3218
2963
|
logger.info("Testing Claude Integration\n");
|
|
3219
2964
|
if (options.detect) {
|
|
3220
2965
|
logger.info("Detecting Claude CLI...");
|
|
@@ -3349,7 +3094,7 @@ program.command("test-claude").description("Test Claude integration (Issue #10)"
|
|
|
3349
3094
|
});
|
|
3350
3095
|
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) => {
|
|
3351
3096
|
try {
|
|
3352
|
-
const { TestWebserverCommand } = await import("./test-webserver-
|
|
3097
|
+
const { TestWebserverCommand } = await import("./test-webserver-NZ3JTVLL.js");
|
|
3353
3098
|
const command = new TestWebserverCommand();
|
|
3354
3099
|
await command.execute({ issueNumber, options });
|
|
3355
3100
|
} catch (error) {
|
|
@@ -3362,7 +3107,7 @@ program.command("test-webserver").description("Test if a web server is running o
|
|
|
3362
3107
|
});
|
|
3363
3108
|
program.command("test-git").description("Test Git integration - findMainWorktreePath() function (reads .iloom/settings.json)").action(async () => {
|
|
3364
3109
|
try {
|
|
3365
|
-
const { TestGitCommand } = await import("./test-git-
|
|
3110
|
+
const { TestGitCommand } = await import("./test-git-XM4TM65W.js");
|
|
3366
3111
|
const command = new TestGitCommand();
|
|
3367
3112
|
await command.execute();
|
|
3368
3113
|
} catch (error) {
|
|
@@ -3388,7 +3133,7 @@ program.command("test-tabs").description("Test iTerm2 dual tab functionality - o
|
|
|
3388
3133
|
});
|
|
3389
3134
|
program.command("test-prefix").description("Test worktree prefix configuration - preview worktree paths (reads .iloom/settings.json)").action(async () => {
|
|
3390
3135
|
try {
|
|
3391
|
-
const { TestPrefixCommand } = await import("./test-prefix-
|
|
3136
|
+
const { TestPrefixCommand } = await import("./test-prefix-GBO37XCN.js");
|
|
3392
3137
|
const command = new TestPrefixCommand();
|
|
3393
3138
|
await command.execute();
|
|
3394
3139
|
} catch (error) {
|
|
@@ -3402,7 +3147,7 @@ program.command("test-prefix").description("Test worktree prefix configuration -
|
|
|
3402
3147
|
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) => {
|
|
3403
3148
|
const executeAction = async () => {
|
|
3404
3149
|
try {
|
|
3405
|
-
const { SummaryCommand } = await import("./summary-
|
|
3150
|
+
const { SummaryCommand } = await import("./summary-WTQZ7XG2.js");
|
|
3406
3151
|
const command = new SummaryCommand();
|
|
3407
3152
|
const result = await command.execute({ identifier, options });
|
|
3408
3153
|
if (options.json && result) {
|
|
@@ -3431,7 +3176,7 @@ program.command("summary").description("Generate Claude session summary for a lo
|
|
|
3431
3176
|
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) => {
|
|
3432
3177
|
const executeAction = async () => {
|
|
3433
3178
|
try {
|
|
3434
|
-
const { RecapCommand } = await import("./recap-
|
|
3179
|
+
const { RecapCommand } = await import("./recap-OMBOKJST.js");
|
|
3435
3180
|
const command = new RecapCommand();
|
|
3436
3181
|
const result = await command.execute({ identifier, json: options.json });
|
|
3437
3182
|
if (options.json && result) {
|
|
@@ -3457,16 +3202,62 @@ program.command("recap").description("Get recap for a loom (defaults to current
|
|
|
3457
3202
|
await executeAction();
|
|
3458
3203
|
}
|
|
3459
3204
|
});
|
|
3205
|
+
var testJiraCommand = program.command("test-jira").description("Test Jira integration methods against a real Jira instance");
|
|
3206
|
+
testJiraCommand.command("child-issue").description("Create a test child issue under a parent").argument("<parentKey>", "Parent issue key (e.g., PROJ-123)").action(async (parentKey) => {
|
|
3207
|
+
try {
|
|
3208
|
+
const { TestJiraCommand } = await import("./test-jira-LDTOYFSD.js");
|
|
3209
|
+
await new TestJiraCommand().createChildIssue(parentKey);
|
|
3210
|
+
} catch (error) {
|
|
3211
|
+
logger.error(`Failed: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
3212
|
+
process.exit(1);
|
|
3213
|
+
}
|
|
3214
|
+
});
|
|
3215
|
+
testJiraCommand.command("create-dep").description('Create a "Blocks" dependency between two issues').argument("<blockingKey>", "Issue key that blocks (e.g., PROJ-100)").argument("<blockedKey>", "Issue key being blocked (e.g., PROJ-200)").action(async (blockingKey, blockedKey) => {
|
|
3216
|
+
try {
|
|
3217
|
+
const { TestJiraCommand } = await import("./test-jira-LDTOYFSD.js");
|
|
3218
|
+
await new TestJiraCommand().createDependency(blockingKey, blockedKey);
|
|
3219
|
+
} catch (error) {
|
|
3220
|
+
logger.error(`Failed: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
3221
|
+
process.exit(1);
|
|
3222
|
+
}
|
|
3223
|
+
});
|
|
3224
|
+
testJiraCommand.command("get-deps").description("Fetch and print dependencies for an issue").argument("<issueKey>", "Issue key (e.g., PROJ-123)").action(async (issueKey) => {
|
|
3225
|
+
try {
|
|
3226
|
+
const { TestJiraCommand } = await import("./test-jira-LDTOYFSD.js");
|
|
3227
|
+
await new TestJiraCommand().getDependencies(issueKey);
|
|
3228
|
+
} catch (error) {
|
|
3229
|
+
logger.error(`Failed: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
3230
|
+
process.exit(1);
|
|
3231
|
+
}
|
|
3232
|
+
});
|
|
3233
|
+
testJiraCommand.command("remove-dep").description('Remove a "Blocks" dependency between two issues').argument("<blockingKey>", "Issue key that blocks (e.g., PROJ-100)").argument("<blockedKey>", "Issue key being blocked (e.g., PROJ-200)").action(async (blockingKey, blockedKey) => {
|
|
3234
|
+
try {
|
|
3235
|
+
const { TestJiraCommand } = await import("./test-jira-LDTOYFSD.js");
|
|
3236
|
+
await new TestJiraCommand().removeDependency(blockingKey, blockedKey);
|
|
3237
|
+
} catch (error) {
|
|
3238
|
+
logger.error(`Failed: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
3239
|
+
process.exit(1);
|
|
3240
|
+
}
|
|
3241
|
+
});
|
|
3242
|
+
testJiraCommand.command("get-children").description("List child issues of a parent").argument("<issueKey>", "Parent issue key (e.g., PROJ-123)").action(async (issueKey) => {
|
|
3243
|
+
try {
|
|
3244
|
+
const { TestJiraCommand } = await import("./test-jira-LDTOYFSD.js");
|
|
3245
|
+
await new TestJiraCommand().getChildIssues(issueKey);
|
|
3246
|
+
} catch (error) {
|
|
3247
|
+
logger.error(`Failed: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
3248
|
+
process.exit(1);
|
|
3249
|
+
}
|
|
3250
|
+
});
|
|
3460
3251
|
program.command("test-neon").description("Test Neon integration and debug configuration").action(async () => {
|
|
3461
|
-
var
|
|
3252
|
+
var _a2;
|
|
3462
3253
|
try {
|
|
3463
|
-
const { SettingsManager: SettingsManager2 } = await import("./SettingsManager-
|
|
3464
|
-
const { createNeonProviderFromSettings: createNeonProviderFromSettings2 } = await import("./neon-helpers-
|
|
3254
|
+
const { SettingsManager: SettingsManager2 } = await import("./SettingsManager-FNKCOZMQ.js");
|
|
3255
|
+
const { createNeonProviderFromSettings: createNeonProviderFromSettings2 } = await import("./neon-helpers-CQN2PB4S.js");
|
|
3465
3256
|
logger.info("Testing Neon Integration\n");
|
|
3466
3257
|
logger.info("1. Settings Configuration:");
|
|
3467
3258
|
const settingsManager = new SettingsManager2();
|
|
3468
3259
|
const settings = await settingsManager.loadSettings();
|
|
3469
|
-
const neonConfig = (
|
|
3260
|
+
const neonConfig = (_a2 = settings.databaseProviders) == null ? void 0 : _a2.neon;
|
|
3470
3261
|
logger.info(` projectId: ${(neonConfig == null ? void 0 : neonConfig.projectId) ?? "(not configured)"}`);
|
|
3471
3262
|
logger.info(` parentBranch: ${(neonConfig == null ? void 0 : neonConfig.parentBranch) ?? "(not configured)"}`);
|
|
3472
3263
|
logger.info("\n2. Creating NeonProvider...");
|
|
@@ -3525,6 +3316,23 @@ program.command("test-neon").description("Test Neon integration and debug config
|
|
|
3525
3316
|
process.exit(1);
|
|
3526
3317
|
}
|
|
3527
3318
|
});
|
|
3319
|
+
var telemetryCmd = program.command("telemetry").description("Manage anonymous usage telemetry");
|
|
3320
|
+
telemetryCmd.command("off").description("Disable anonymous usage telemetry").action(async () => {
|
|
3321
|
+
const manager = new TelemetryManager();
|
|
3322
|
+
manager.disable();
|
|
3323
|
+
logger.info("Telemetry disabled. No usage data will be collected.");
|
|
3324
|
+
});
|
|
3325
|
+
telemetryCmd.command("on").description("Enable anonymous usage telemetry").action(async () => {
|
|
3326
|
+
const manager = new TelemetryManager();
|
|
3327
|
+
manager.enable();
|
|
3328
|
+
logger.info("Telemetry enabled. Anonymous usage data will be collected to improve iloom.");
|
|
3329
|
+
});
|
|
3330
|
+
telemetryCmd.command("status").description("Show current telemetry status").action(async () => {
|
|
3331
|
+
const manager = new TelemetryManager();
|
|
3332
|
+
const status = manager.getStatus();
|
|
3333
|
+
logger.info(`Telemetry: ${status.enabled ? "enabled" : "disabled"}`);
|
|
3334
|
+
logger.info(`Anonymous ID: ${status.distinctId}`);
|
|
3335
|
+
});
|
|
3528
3336
|
program.command("help").description("Display help information").argument("[command]", "Show help for specific command").action(async (command) => {
|
|
3529
3337
|
if (command) {
|
|
3530
3338
|
const subCommand = program.commands.find((cmd) => cmd.name() === command);
|
|
@@ -3541,24 +3349,45 @@ program.command("help").description("Display help information").argument("[comma
|
|
|
3541
3349
|
});
|
|
3542
3350
|
var isRunDirectly = process.argv[1] && (() => {
|
|
3543
3351
|
try {
|
|
3544
|
-
const scriptPath =
|
|
3352
|
+
const scriptPath = realpathSync2(process.argv[1]);
|
|
3545
3353
|
const modulePath = fileURLToPath2(import.meta.url);
|
|
3546
3354
|
return scriptPath === modulePath;
|
|
3547
3355
|
} catch {
|
|
3548
3356
|
return true;
|
|
3549
3357
|
}
|
|
3550
3358
|
})();
|
|
3359
|
+
var _a;
|
|
3551
3360
|
if (isRunDirectly) {
|
|
3552
3361
|
try {
|
|
3553
3362
|
await program.parseAsync();
|
|
3363
|
+
try {
|
|
3364
|
+
await TelemetryService.getInstance().shutdown();
|
|
3365
|
+
} catch (shutdownError) {
|
|
3366
|
+
logger.debug(`Telemetry shutdown: ${shutdownError instanceof Error ? shutdownError.message : String(shutdownError)}`);
|
|
3367
|
+
}
|
|
3554
3368
|
} catch (error) {
|
|
3369
|
+
try {
|
|
3370
|
+
const commandName = ((_a = program.args) == null ? void 0 : _a[0]) ?? "unknown";
|
|
3371
|
+
TelemetryService.getInstance().track("error.occurred", {
|
|
3372
|
+
error_type: error instanceof Error ? error.constructor.name : "Unknown",
|
|
3373
|
+
command: commandName,
|
|
3374
|
+
phase: "execution"
|
|
3375
|
+
});
|
|
3376
|
+
await TelemetryService.getInstance().shutdown();
|
|
3377
|
+
} catch (telemetryError) {
|
|
3378
|
+
logger.debug(`Telemetry error tracking: ${telemetryError instanceof Error ? telemetryError.message : String(telemetryError)}`);
|
|
3379
|
+
}
|
|
3555
3380
|
if (error instanceof Error) {
|
|
3556
3381
|
logger.error(`Error: ${error.message}`);
|
|
3557
3382
|
process.exit(1);
|
|
3383
|
+
} else {
|
|
3384
|
+
logger.error(`Error: ${String(error)}`);
|
|
3385
|
+
process.exit(1);
|
|
3558
3386
|
}
|
|
3559
3387
|
}
|
|
3560
3388
|
}
|
|
3561
3389
|
export {
|
|
3390
|
+
handleTelemetryLifecycle,
|
|
3562
3391
|
validateGhCliForCommand,
|
|
3563
3392
|
validateIdeForStartCommand
|
|
3564
3393
|
};
|