@iloom/cli 0.3.4 → 0.4.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/README.md +13 -3
- package/dist/{BranchNamingService-A77VI6AI.js → BranchNamingService-GCCWB3LK.js} +4 -3
- package/dist/ClaudeContextManager-DK77227F.js +16 -0
- package/dist/ClaudeService-W3SA7HVG.js +15 -0
- package/dist/GitHubService-RPM27GWD.js +12 -0
- package/dist/{LoomLauncher-ZV3ZZIBA.js → LoomLauncher-S3YGJRJQ.js} +43 -27
- package/dist/LoomLauncher-S3YGJRJQ.js.map +1 -0
- package/dist/PromptTemplateManager-2TDZAUC6.js +9 -0
- package/dist/README.md +13 -3
- package/dist/{SettingsManager-I2LRCW2A.js → SettingsManager-FJFU6JJD.js} +7 -3
- package/dist/SettingsMigrationManager-EH3J2TCN.js +10 -0
- package/dist/{chunk-5Q3NDNNV.js → chunk-2W2FBL5G.js} +153 -6
- package/dist/chunk-2W2FBL5G.js.map +1 -0
- package/dist/{chunk-OXAM2WVC.js → chunk-55TB3FSG.js} +21 -1
- package/dist/chunk-55TB3FSG.js.map +1 -0
- package/dist/chunk-6UIGZD2N.js +20 -0
- package/dist/chunk-6UIGZD2N.js.map +1 -0
- package/dist/{chunk-RIEO2WML.js → chunk-74VMN2KC.js} +26 -2
- package/dist/chunk-74VMN2KC.js.map +1 -0
- package/dist/{chunk-2MAIX45J.js → chunk-BIIQHEXJ.js} +104 -43
- package/dist/chunk-BIIQHEXJ.js.map +1 -0
- package/dist/{chunk-UAN4A3YU.js → chunk-G6CIIJLT.js} +11 -11
- package/dist/{chunk-DLHA5VQ3.js → chunk-HD5SUKI2.js} +36 -179
- package/dist/chunk-HD5SUKI2.js.map +1 -0
- package/dist/{chunk-2IJEMXOB.js → chunk-IARWMDAX.js} +427 -428
- package/dist/chunk-IARWMDAX.js.map +1 -0
- package/dist/chunk-IJ7IGJT3.js +192 -0
- package/dist/chunk-IJ7IGJT3.js.map +1 -0
- package/dist/{chunk-2CXREBLZ.js → chunk-JC5HXN75.js} +8 -6
- package/dist/chunk-JC5HXN75.js.map +1 -0
- package/dist/{chunk-3RUPPQRG.js → chunk-KO2FOMHL.js} +43 -2
- package/dist/{chunk-3RUPPQRG.js.map → chunk-KO2FOMHL.js.map} +1 -1
- package/dist/{chunk-4XIDC3NF.js → chunk-MD6HA5IK.js} +2 -2
- package/dist/{chunk-OC4H6HJD.js → chunk-O7WHXLCB.js} +2 -2
- package/dist/{chunk-M7JJCX53.js → chunk-OEGECBFS.js} +20 -20
- package/dist/chunk-OEGECBFS.js.map +1 -0
- package/dist/{chunk-MKWYLDFK.js → chunk-OF7BNW4D.js} +43 -3
- package/dist/chunk-OF7BNW4D.js.map +1 -0
- package/dist/{chunk-PGPI5LR4.js → chunk-POI7KLBH.js} +7 -21
- package/dist/chunk-POI7KLBH.js.map +1 -0
- package/dist/{chunk-PA6Q6AWM.js → chunk-PSFVTBM7.js} +2 -2
- package/dist/chunk-QHA67Q7A.js +281 -0
- package/dist/chunk-QHA67Q7A.js.map +1 -0
- package/dist/{chunk-SUOXY5WJ.js → chunk-QIUJPPJQ.js} +5 -5
- package/dist/chunk-QIUJPPJQ.js.map +1 -0
- package/dist/{chunk-ZM3CFL5L.js → chunk-QRBOPFAA.js} +3 -3
- package/dist/{chunk-OYF4VIFI.js → chunk-RUC7OULH.js} +147 -22
- package/dist/chunk-RUC7OULH.js.map +1 -0
- package/dist/{chunk-CE26YH2U.js → chunk-SJ2GZ6RF.js} +48 -50
- package/dist/chunk-SJ2GZ6RF.js.map +1 -0
- package/dist/{chunk-SSCQCCJ7.js → chunk-THF25ICZ.js} +2 -2
- package/dist/chunk-TMZAVPGF.js +667 -0
- package/dist/chunk-TMZAVPGF.js.map +1 -0
- package/dist/{chunk-5VK4NRSF.js → chunk-UNXRACJ7.js} +35 -36
- package/dist/chunk-UNXRACJ7.js.map +1 -0
- package/dist/{chunk-AKUJXDNW.js → chunk-UPUAQYAW.js} +3 -3
- package/dist/{chunk-GEHQXLEI.js → chunk-UYVWLISQ.js} +18 -35
- package/dist/chunk-UYVWLISQ.js.map +1 -0
- package/dist/{chunk-OSCLCMDG.js → chunk-UYWAESOT.js} +3 -3
- package/dist/{chunk-RW54ZMBM.js → chunk-VAYGNQTE.js} +2 -2
- package/dist/{chunk-ZT3YZB4K.js → chunk-VBFDVGAE.js} +12 -12
- package/dist/chunk-VBFDVGAE.js.map +1 -0
- package/dist/{chunk-IFB4Z76W.js → chunk-VTXCGKV5.js} +13 -12
- package/dist/chunk-VTXCGKV5.js.map +1 -0
- package/dist/{chunk-CDZERT7Z.js → chunk-VWNS6DH5.js} +48 -4
- package/dist/chunk-VWNS6DH5.js.map +1 -0
- package/dist/{chunk-CFFQ2Z7A.js → chunk-WUQQNE63.js} +2 -2
- package/dist/{chunk-UJL4HI2R.js → chunk-Z5NXYJIG.js} +20 -2
- package/dist/chunk-Z5NXYJIG.js.map +1 -0
- package/dist/{claude-W52VKI6L.js → claude-ACVXNB6N.js} +8 -5
- package/dist/{cleanup-H4VXU3C3.js → cleanup-KDLVTT7M.js} +133 -122
- package/dist/cleanup-KDLVTT7M.js.map +1 -0
- package/dist/cli.js +953 -430
- package/dist/cli.js.map +1 -1
- package/dist/{color-F7RU6B6Z.js → color-ZPIIUADB.js} +3 -3
- package/dist/{contribute-Y7IQV5QY.js → contribute-HY372S6F.js} +8 -6
- package/dist/{contribute-Y7IQV5QY.js.map → contribute-HY372S6F.js.map} +1 -1
- package/dist/dev-server-JCJGQ3PV.js +298 -0
- package/dist/dev-server-JCJGQ3PV.js.map +1 -0
- package/dist/{feedback-XTUCKJNT.js → feedback-7PVBQNLJ.js} +13 -12
- package/dist/{feedback-XTUCKJNT.js.map → feedback-7PVBQNLJ.js.map} +1 -1
- package/dist/{git-IYA53VIC.js → git-4BVOOOOV.js} +16 -4
- package/dist/hooks/iloom-hook.js +258 -0
- package/dist/{ignite-T74RYXCA.js → ignite-3B264M7K.js} +245 -39
- package/dist/ignite-3B264M7K.js.map +1 -0
- package/dist/index.d.ts +461 -124
- package/dist/index.js +743 -210
- package/dist/index.js.map +1 -1
- package/dist/init-LBA6NUK2.js +21 -0
- package/dist/{installation-detector-VARGFFRZ.js → installation-detector-6R6YOFVZ.js} +3 -3
- package/dist/mcp/issue-management-server.js +2 -1
- package/dist/mcp/issue-management-server.js.map +1 -1
- package/dist/neon-helpers-L5CXQ5CT.js +11 -0
- package/dist/{open-UMXANW5S.js → open-OGCV32Z4.js} +15 -13
- package/dist/{open-UMXANW5S.js.map → open-OGCV32Z4.js.map} +1 -1
- package/dist/projects-P55273AB.js +73 -0
- package/dist/projects-P55273AB.js.map +1 -0
- package/dist/{prompt-QALMYTVC.js → prompt-A7GGRHSY.js} +3 -3
- package/dist/prompts/init-prompt.txt +49 -0
- package/dist/prompts/issue-prompt.txt +110 -8
- package/dist/prompts/regular-prompt.txt +90 -0
- package/dist/prompts/session-summary-prompt.txt +82 -0
- package/dist/{rebase-VJ2VKR6R.js → rebase-4T5FQHNH.js} +11 -9
- package/dist/{rebase-VJ2VKR6R.js.map → rebase-4T5FQHNH.js.map} +1 -1
- package/dist/{remote-VUNCQZ6J.js → remote-73TZ2ADI.js} +3 -3
- package/dist/{run-MJYY4PUT.js → run-HNOP6WE2.js} +15 -13
- package/dist/{run-MJYY4PUT.js.map → run-HNOP6WE2.js.map} +1 -1
- package/dist/schema/settings.schema.json +49 -0
- package/dist/shell-DE3HKJSM.js +240 -0
- package/dist/shell-DE3HKJSM.js.map +1 -0
- package/dist/summary-GDT7DTRI.js +244 -0
- package/dist/summary-GDT7DTRI.js.map +1 -0
- package/dist/{test-git-IT5EWQ5C.js → test-git-YMAE57UP.js} +6 -4
- package/dist/{test-git-IT5EWQ5C.js.map → test-git-YMAE57UP.js.map} +1 -1
- package/dist/{test-prefix-NPWDPUUH.js → test-prefix-YCKL6CMT.js} +6 -4
- package/dist/{test-prefix-NPWDPUUH.js.map → test-prefix-YCKL6CMT.js.map} +1 -1
- package/dist/{test-tabs-PRMRSHKI.js → test-tabs-3SCJWRKT.js} +4 -4
- package/dist/{test-webserver-DAHONWCS.js → test-webserver-VPNLAFZ3.js} +2 -2
- package/dist/{update-4TDDUR5K.js → update-LETF5ASC.js} +4 -4
- package/dist/{update-notifier-QEX3CJHA.js → update-notifier-H55ZK7NU.js} +3 -3
- package/package.json +6 -6
- package/dist/ClaudeContextManager-BN7RE5ZQ.js +0 -15
- package/dist/ClaudeService-DLYLJUPA.js +0 -14
- package/dist/GitHubService-FZHHBOFG.js +0 -11
- package/dist/LoomLauncher-ZV3ZZIBA.js.map +0 -1
- package/dist/PromptTemplateManager-6HH3PVXV.js +0 -9
- package/dist/SettingsMigrationManager-TJ7UWZG5.js +0 -10
- package/dist/chunk-2CXREBLZ.js.map +0 -1
- package/dist/chunk-2IJEMXOB.js.map +0 -1
- package/dist/chunk-2MAIX45J.js.map +0 -1
- package/dist/chunk-5Q3NDNNV.js.map +0 -1
- package/dist/chunk-5VK4NRSF.js.map +0 -1
- package/dist/chunk-CDZERT7Z.js.map +0 -1
- package/dist/chunk-CE26YH2U.js.map +0 -1
- package/dist/chunk-DLHA5VQ3.js.map +0 -1
- package/dist/chunk-GEHQXLEI.js.map +0 -1
- package/dist/chunk-IFB4Z76W.js.map +0 -1
- package/dist/chunk-M7JJCX53.js.map +0 -1
- package/dist/chunk-MKWYLDFK.js.map +0 -1
- package/dist/chunk-OXAM2WVC.js.map +0 -1
- package/dist/chunk-OYF4VIFI.js.map +0 -1
- package/dist/chunk-PGPI5LR4.js.map +0 -1
- package/dist/chunk-RIEO2WML.js.map +0 -1
- package/dist/chunk-SUOXY5WJ.js.map +0 -1
- package/dist/chunk-UJL4HI2R.js.map +0 -1
- package/dist/chunk-ZT3YZB4K.js.map +0 -1
- package/dist/cleanup-H4VXU3C3.js.map +0 -1
- package/dist/ignite-T74RYXCA.js.map +0 -1
- package/dist/init-4FHTAM3F.js +0 -19
- package/dist/logger-MKYH4UDV.js +0 -12
- package/dist/neon-helpers-77PBPGJ5.js +0 -10
- package/dist/update-notifier-QEX3CJHA.js.map +0 -1
- /package/dist/{BranchNamingService-A77VI6AI.js.map → BranchNamingService-GCCWB3LK.js.map} +0 -0
- /package/dist/{ClaudeContextManager-BN7RE5ZQ.js.map → ClaudeContextManager-DK77227F.js.map} +0 -0
- /package/dist/{ClaudeService-DLYLJUPA.js.map → ClaudeService-W3SA7HVG.js.map} +0 -0
- /package/dist/{GitHubService-FZHHBOFG.js.map → GitHubService-RPM27GWD.js.map} +0 -0
- /package/dist/{PromptTemplateManager-6HH3PVXV.js.map → PromptTemplateManager-2TDZAUC6.js.map} +0 -0
- /package/dist/{SettingsManager-I2LRCW2A.js.map → SettingsManager-FJFU6JJD.js.map} +0 -0
- /package/dist/{SettingsMigrationManager-TJ7UWZG5.js.map → SettingsMigrationManager-EH3J2TCN.js.map} +0 -0
- /package/dist/{chunk-UAN4A3YU.js.map → chunk-G6CIIJLT.js.map} +0 -0
- /package/dist/{chunk-4XIDC3NF.js.map → chunk-MD6HA5IK.js.map} +0 -0
- /package/dist/{chunk-OC4H6HJD.js.map → chunk-O7WHXLCB.js.map} +0 -0
- /package/dist/{chunk-PA6Q6AWM.js.map → chunk-PSFVTBM7.js.map} +0 -0
- /package/dist/{chunk-ZM3CFL5L.js.map → chunk-QRBOPFAA.js.map} +0 -0
- /package/dist/{chunk-SSCQCCJ7.js.map → chunk-THF25ICZ.js.map} +0 -0
- /package/dist/{chunk-AKUJXDNW.js.map → chunk-UPUAQYAW.js.map} +0 -0
- /package/dist/{chunk-OSCLCMDG.js.map → chunk-UYWAESOT.js.map} +0 -0
- /package/dist/{chunk-RW54ZMBM.js.map → chunk-VAYGNQTE.js.map} +0 -0
- /package/dist/{chunk-CFFQ2Z7A.js.map → chunk-WUQQNE63.js.map} +0 -0
- /package/dist/{claude-W52VKI6L.js.map → claude-ACVXNB6N.js.map} +0 -0
- /package/dist/{color-F7RU6B6Z.js.map → color-ZPIIUADB.js.map} +0 -0
- /package/dist/{git-IYA53VIC.js.map → git-4BVOOOOV.js.map} +0 -0
- /package/dist/{init-4FHTAM3F.js.map → init-LBA6NUK2.js.map} +0 -0
- /package/dist/{installation-detector-VARGFFRZ.js.map → installation-detector-6R6YOFVZ.js.map} +0 -0
- /package/dist/{logger-MKYH4UDV.js.map → neon-helpers-L5CXQ5CT.js.map} +0 -0
- /package/dist/{neon-helpers-77PBPGJ5.js.map → prompt-A7GGRHSY.js.map} +0 -0
- /package/dist/{prompt-QALMYTVC.js.map → remote-73TZ2ADI.js.map} +0 -0
- /package/dist/{test-tabs-PRMRSHKI.js.map → test-tabs-3SCJWRKT.js.map} +0 -0
- /package/dist/{test-webserver-DAHONWCS.js.map → test-webserver-VPNLAFZ3.js.map} +0 -0
- /package/dist/{update-4TDDUR5K.js.map → update-LETF5ASC.js.map} +0 -0
- /package/dist/{remote-VUNCQZ6J.js.map → update-notifier-H55ZK7NU.js.map} +0 -0
package/README.md
CHANGED
|
@@ -51,7 +51,9 @@ iloom stops the "Context Window Tetris." It treats context as a first-class conc
|
|
|
51
51
|
* **Scale Understanding:** Because every loom holds its own isolated environment (Git worktree, DB branch, local server), you can switch between 5 complex features without losing your place or your AI's context.
|
|
52
52
|
|
|
53
53
|
* **Visible Reasoning:** The AI's decisions are documented publicly. Your team sees the plan, and "future you" knows exactly why a decision was made.
|
|
54
|
-
|
|
54
|
+
|
|
55
|
+
* **Automatic Session Summaries:** When you finish a loom, iloom captures key insights, decisions, and lessons learned from your Claude session and posts them to the issue. These summaries become institutional knowledge that informs future tasks.
|
|
56
|
+
|
|
55
57
|
|
|
56
58
|
_iloom is not just a tool for managing git worktrees - it's a control plane for maintaining alignment between you and your AI assistant._
|
|
57
59
|
|
|
@@ -73,8 +75,8 @@ iloom uses your existing Claude subscription to build a shared mental model of y
|
|
|
73
75
|
|
|
74
76
|
# ... You, the iloom agents and Claude build the feature together in the isolated environment ...
|
|
75
77
|
|
|
76
|
-
# 4. Finish & Merge # Validates code
|
|
77
|
-
il finish
|
|
78
|
+
# 4. Finish & Merge # Validates code, generates session summary, merges, and cleans up.
|
|
79
|
+
il finish
|
|
78
80
|
```
|
|
79
81
|
|
|
80
82
|
**The iloom Difference:** il start doesn't just create a branch. It launches a multi-agent workflow that surfaces assumptions and creates a structured plan in your issue tracker **before you even need to look at your IDE.**
|
|
@@ -138,8 +140,10 @@ Command Reference
|
|
|
138
140
|
| `il finish` | `dn` | Validate tests/lint, commit, handle conflicts, and merge/PR. |
|
|
139
141
|
| `il cleanup` | `remove` | Safely remove a loom and its database branch without merging. |
|
|
140
142
|
| `il list` | | Show active looms and paths. |
|
|
143
|
+
| `il projects` | | List configured projects (JSON output). |
|
|
141
144
|
| `il spin` | | Launch Claude inside the current loom with context auto-detected. |
|
|
142
145
|
| `il open` | `run` | Open loom in browser (web) or run your CLI tool. |
|
|
146
|
+
| `il dev-server` | `dev` | Start dev server in foreground for a workspace. |
|
|
143
147
|
| `il add-issue` | `a` | Create and AI-enhance a new issue without starting work yet. |
|
|
144
148
|
| `il init` | `config` | Interactive configuration wizard. |
|
|
145
149
|
| `il feedback` | `f` | Submit bug reports/feedback directly from the CLI. |
|
|
@@ -218,6 +222,12 @@ This example shows how to configure a project-wide default (e.g., GitHub remote)
|
|
|
218
222
|
"issue": {
|
|
219
223
|
"permissionMode": "acceptEdits" // Control Claude Code permissions
|
|
220
224
|
}
|
|
225
|
+
},
|
|
226
|
+
"spin": {
|
|
227
|
+
"model": "opus" // Claude model for spin orchestrator: opus (default), sonnet, or haiku
|
|
228
|
+
},
|
|
229
|
+
"summary": {
|
|
230
|
+
"model": "sonnet" // Claude model for session summaries: sonnet (default), opus, or haiku
|
|
221
231
|
}
|
|
222
232
|
}
|
|
223
233
|
```
|
|
@@ -3,11 +3,12 @@ import {
|
|
|
3
3
|
ClaudeBranchNameStrategy,
|
|
4
4
|
DefaultBranchNamingService,
|
|
5
5
|
SimpleBranchNameStrategy
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-QIUJPPJQ.js";
|
|
7
|
+
import "./chunk-6UIGZD2N.js";
|
|
8
|
+
import "./chunk-UYVWLISQ.js";
|
|
8
9
|
export {
|
|
9
10
|
ClaudeBranchNameStrategy,
|
|
10
11
|
DefaultBranchNamingService,
|
|
11
12
|
SimpleBranchNameStrategy
|
|
12
13
|
};
|
|
13
|
-
//# sourceMappingURL=BranchNamingService-
|
|
14
|
+
//# sourceMappingURL=BranchNamingService-GCCWB3LK.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
ClaudeContextManager
|
|
4
|
+
} from "./chunk-UPUAQYAW.js";
|
|
5
|
+
import "./chunk-POI7KLBH.js";
|
|
6
|
+
import "./chunk-VWNS6DH5.js";
|
|
7
|
+
import "./chunk-RUC7OULH.js";
|
|
8
|
+
import "./chunk-VAYGNQTE.js";
|
|
9
|
+
import "./chunk-Z5NXYJIG.js";
|
|
10
|
+
import "./chunk-6UIGZD2N.js";
|
|
11
|
+
import "./chunk-74VMN2KC.js";
|
|
12
|
+
import "./chunk-UYVWLISQ.js";
|
|
13
|
+
export {
|
|
14
|
+
ClaudeContextManager
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=ClaudeContextManager-DK77227F.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
ClaudeService
|
|
4
|
+
} from "./chunk-POI7KLBH.js";
|
|
5
|
+
import "./chunk-VWNS6DH5.js";
|
|
6
|
+
import "./chunk-RUC7OULH.js";
|
|
7
|
+
import "./chunk-VAYGNQTE.js";
|
|
8
|
+
import "./chunk-Z5NXYJIG.js";
|
|
9
|
+
import "./chunk-6UIGZD2N.js";
|
|
10
|
+
import "./chunk-74VMN2KC.js";
|
|
11
|
+
import "./chunk-UYVWLISQ.js";
|
|
12
|
+
export {
|
|
13
|
+
ClaudeService
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=ClaudeService-W3SA7HVG.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
GitHubService
|
|
4
|
+
} from "./chunk-OEGECBFS.js";
|
|
5
|
+
import "./chunk-KO2FOMHL.js";
|
|
6
|
+
import "./chunk-SJ2GZ6RF.js";
|
|
7
|
+
import "./chunk-6UIGZD2N.js";
|
|
8
|
+
import "./chunk-UYVWLISQ.js";
|
|
9
|
+
export {
|
|
10
|
+
GitHubService
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=GitHubService-RPM27GWD.js.map
|
|
@@ -1,29 +1,35 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
getDevServerLaunchCommand
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-QRBOPFAA.js";
|
|
5
|
+
import "./chunk-VBFDVGAE.js";
|
|
6
6
|
import {
|
|
7
7
|
ClaudeContextManager
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import
|
|
11
|
-
|
|
8
|
+
} from "./chunk-UPUAQYAW.js";
|
|
9
|
+
import "./chunk-POI7KLBH.js";
|
|
10
|
+
import {
|
|
11
|
+
getExecutablePath
|
|
12
|
+
} from "./chunk-GYCR2LOU.js";
|
|
13
|
+
import "./chunk-VWNS6DH5.js";
|
|
12
14
|
import {
|
|
13
15
|
generateColorFromBranchName,
|
|
14
16
|
hexToRgb
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
import "./chunk-
|
|
17
|
+
} from "./chunk-WUQQNE63.js";
|
|
18
|
+
import "./chunk-RUC7OULH.js";
|
|
17
19
|
import {
|
|
18
20
|
openMultipleTerminalWindows,
|
|
19
21
|
openTerminalWindow
|
|
20
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-VAYGNQTE.js";
|
|
21
23
|
import {
|
|
22
24
|
getDotenvFlowFiles
|
|
23
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-Z5NXYJIG.js";
|
|
26
|
+
import {
|
|
27
|
+
getLogger
|
|
28
|
+
} from "./chunk-6UIGZD2N.js";
|
|
29
|
+
import "./chunk-74VMN2KC.js";
|
|
24
30
|
import {
|
|
25
31
|
logger
|
|
26
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-UYVWLISQ.js";
|
|
27
33
|
|
|
28
34
|
// src/lib/LoomLauncher.ts
|
|
29
35
|
import { existsSync } from "fs";
|
|
@@ -102,10 +108,10 @@ var LoomLauncher = class {
|
|
|
102
108
|
*/
|
|
103
109
|
async launchLoom(options) {
|
|
104
110
|
const { enableClaude, enableCode, enableDevServer, enableTerminal } = options;
|
|
105
|
-
|
|
111
|
+
getLogger().debug(`Launching loom components: Claude=${enableClaude}, Code=${enableCode}, DevServer=${enableDevServer}, Terminal=${enableTerminal}`);
|
|
106
112
|
const launchPromises = [];
|
|
107
113
|
if (enableCode) {
|
|
108
|
-
|
|
114
|
+
getLogger().debug("Launching VSCode");
|
|
109
115
|
launchPromises.push(this.launchVSCode(options));
|
|
110
116
|
}
|
|
111
117
|
const terminalsToLaunch = [];
|
|
@@ -128,7 +134,7 @@ var LoomLauncher = class {
|
|
|
128
134
|
});
|
|
129
135
|
}
|
|
130
136
|
if (terminalsToLaunch.length > 1) {
|
|
131
|
-
|
|
137
|
+
getLogger().debug(`Launching ${terminalsToLaunch.length} terminals in single window`);
|
|
132
138
|
launchPromises.push(this.launchMultipleTerminals(terminalsToLaunch, options));
|
|
133
139
|
} else if (terminalsToLaunch.length === 1) {
|
|
134
140
|
const terminal = terminalsToLaunch[0];
|
|
@@ -136,7 +142,7 @@ var LoomLauncher = class {
|
|
|
136
142
|
throw new Error("Terminal configuration is undefined");
|
|
137
143
|
}
|
|
138
144
|
const terminalType = terminal.type;
|
|
139
|
-
|
|
145
|
+
getLogger().debug(`Launching single ${terminalType} terminal`);
|
|
140
146
|
if (terminalType === "claude") {
|
|
141
147
|
launchPromises.push(this.launchClaudeTerminal(options));
|
|
142
148
|
} else if (terminalType === "devServer") {
|
|
@@ -146,7 +152,7 @@ var LoomLauncher = class {
|
|
|
146
152
|
}
|
|
147
153
|
}
|
|
148
154
|
await Promise.all(launchPromises);
|
|
149
|
-
|
|
155
|
+
getLogger().success("loom launched successfully");
|
|
150
156
|
}
|
|
151
157
|
/**
|
|
152
158
|
* Launch IDE (VSCode or configured alternative)
|
|
@@ -155,7 +161,7 @@ var LoomLauncher = class {
|
|
|
155
161
|
var _a;
|
|
156
162
|
const ideConfig = await ((_a = this.settings) == null ? void 0 : _a.loadSettings().then((s) => s.ide));
|
|
157
163
|
await openIdeWindow(options.worktreePath, ideConfig);
|
|
158
|
-
|
|
164
|
+
getLogger().info("IDE opened");
|
|
159
165
|
}
|
|
160
166
|
/**
|
|
161
167
|
* Launch Claude terminal
|
|
@@ -172,7 +178,7 @@ var LoomLauncher = class {
|
|
|
172
178
|
...options.setArguments && { setArguments: options.setArguments },
|
|
173
179
|
...options.executablePath && { executablePath: options.executablePath }
|
|
174
180
|
});
|
|
175
|
-
|
|
181
|
+
getLogger().info("Claude terminal opened");
|
|
176
182
|
}
|
|
177
183
|
/**
|
|
178
184
|
* Launch dev server terminal
|
|
@@ -192,21 +198,26 @@ var LoomLauncher = class {
|
|
|
192
198
|
includePortExport: options.capabilities.includes("web"),
|
|
193
199
|
...options.port !== void 0 && { port: options.port }
|
|
194
200
|
});
|
|
195
|
-
|
|
201
|
+
getLogger().info("Dev server terminal opened");
|
|
196
202
|
}
|
|
197
203
|
/**
|
|
198
|
-
* Launch standalone terminal
|
|
204
|
+
* Launch standalone terminal running `il shell <identifier>`
|
|
199
205
|
*/
|
|
200
206
|
async launchStandaloneTerminal(options) {
|
|
207
|
+
const executable = options.executablePath ?? getExecutablePath();
|
|
208
|
+
const shellIdentifier = String(options.identifier);
|
|
209
|
+
const shellCommand = `${executable} shell ${shellIdentifier}`;
|
|
201
210
|
const backgroundColor = options.colorTerminal ?? true ? options.colorHex ? hexToRgb(options.colorHex) : generateColorFromBranchName(options.branchName).rgb : void 0;
|
|
202
211
|
await openTerminalWindow({
|
|
203
212
|
workspacePath: options.worktreePath,
|
|
213
|
+
command: shellCommand,
|
|
204
214
|
...backgroundColor && { backgroundColor },
|
|
205
|
-
|
|
215
|
+
// il shell handles env loading internally, so we don't need includeEnvSetup
|
|
216
|
+
includeEnvSetup: false,
|
|
206
217
|
includePortExport: options.capabilities.includes("web"),
|
|
207
218
|
...options.port !== void 0 && { port: options.port }
|
|
208
219
|
});
|
|
209
|
-
|
|
220
|
+
getLogger().info("Standalone terminal opened");
|
|
210
221
|
}
|
|
211
222
|
/**
|
|
212
223
|
* Build terminal options for Claude
|
|
@@ -257,17 +268,22 @@ var LoomLauncher = class {
|
|
|
257
268
|
};
|
|
258
269
|
}
|
|
259
270
|
/**
|
|
260
|
-
* Build terminal options for standalone terminal
|
|
271
|
+
* Build terminal options for standalone terminal
|
|
272
|
+
* Runs `il shell <identifier>` which handles env loading internally
|
|
261
273
|
*/
|
|
262
274
|
buildStandaloneTerminalOptions(options) {
|
|
263
|
-
const hasEnvFile = this.hasAnyEnvFiles(options.worktreePath);
|
|
264
275
|
const terminalTitle = `Terminal - ${this.formatIdentifier(options.workflowType, options.identifier)}`;
|
|
276
|
+
const executable = options.executablePath ?? getExecutablePath();
|
|
277
|
+
const shellIdentifier = String(options.identifier);
|
|
278
|
+
const shellCommand = `${executable} shell ${shellIdentifier}`;
|
|
265
279
|
const backgroundColor = options.colorTerminal ?? true ? options.colorHex ? hexToRgb(options.colorHex) : generateColorFromBranchName(options.branchName).rgb : void 0;
|
|
266
280
|
return {
|
|
267
281
|
workspacePath: options.worktreePath,
|
|
282
|
+
command: shellCommand,
|
|
268
283
|
...backgroundColor && { backgroundColor },
|
|
269
284
|
title: terminalTitle,
|
|
270
|
-
|
|
285
|
+
// il shell handles env loading internally, so we don't need includeEnvSetup
|
|
286
|
+
includeEnvSetup: false,
|
|
271
287
|
includePortExport: options.capabilities.includes("web"),
|
|
272
288
|
...options.port !== void 0 && { port: options.port }
|
|
273
289
|
};
|
|
@@ -279,7 +295,7 @@ var LoomLauncher = class {
|
|
|
279
295
|
const terminalOptions = terminals.map((t) => t.options);
|
|
280
296
|
await openMultipleTerminalWindows(terminalOptions);
|
|
281
297
|
const terminalTypes = terminals.map((t) => t.type).join(" + ");
|
|
282
|
-
|
|
298
|
+
getLogger().info(`Multiple terminals opened: ${terminalTypes}`);
|
|
283
299
|
}
|
|
284
300
|
/**
|
|
285
301
|
* Check if any dotenv-flow files exist in the workspace
|
|
@@ -305,4 +321,4 @@ var LoomLauncher = class {
|
|
|
305
321
|
export {
|
|
306
322
|
LoomLauncher
|
|
307
323
|
};
|
|
308
|
-
//# sourceMappingURL=LoomLauncher-
|
|
324
|
+
//# sourceMappingURL=LoomLauncher-S3YGJRJQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/LoomLauncher.ts","../src/utils/ide.ts"],"sourcesContent":["import { existsSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { openTerminalWindow, openMultipleTerminalWindows } from '../utils/terminal.js'\nimport type { TerminalWindowOptions } from '../utils/terminal.js'\nimport { openIdeWindow } from '../utils/ide.js'\nimport { getDevServerLaunchCommand } from '../utils/dev-server.js'\nimport { generateColorFromBranchName, hexToRgb } from '../utils/color.js'\nimport { getLogger } from '../utils/logger-context.js'\nimport { ClaudeContextManager } from './ClaudeContextManager.js'\nimport type { SettingsManager } from './SettingsManager.js'\nimport type { Capability } from '../types/loom.js'\nimport { getDotenvFlowFiles } from '../utils/env.js'\nimport { getExecutablePath } from '../utils/cli-overrides.js'\n\nexport interface LaunchLoomOptions {\n\tenableClaude: boolean\n\tenableCode: boolean\n\tenableDevServer: boolean\n\tenableTerminal: boolean\n\tworktreePath: string\n\tbranchName: string\n\tport?: number\n\tcapabilities: Capability[]\n\tworkflowType: 'issue' | 'pr' | 'regular'\n\tidentifier: string | number\n\ttitle?: string\n\toneShot?: import('../types/index.js').OneShotMode\n\tsetArguments?: string[] // Raw --set arguments to forward\n\texecutablePath?: string // Executable path to use for spin command\n\tsourceEnvOnStart?: boolean // defaults to false if undefined\n\tcolorTerminal?: boolean // defaults to true if undefined\n\tcolorHex?: string // Pre-calculated hex color from metadata, avoids recalculation\n}\n\n/**\n * LoomLauncher orchestrates opening loom components\n */\nexport class LoomLauncher {\n\tprivate claudeContext: ClaudeContextManager\n\tprivate settings?: SettingsManager\n\n\tconstructor(claudeContext?: ClaudeContextManager, settings?: SettingsManager) {\n\t\tthis.claudeContext = claudeContext ?? new ClaudeContextManager()\n\t\tif (settings !== undefined) {\n\t\t\tthis.settings = settings\n\t\t}\n\t}\n\n\t/**\n\t * Launch loom components based on individual flags\n\t */\n\tasync launchLoom(options: LaunchLoomOptions): Promise<void> {\n\t\tconst { enableClaude, enableCode, enableDevServer, enableTerminal } = options\n\n\t\tgetLogger().debug(`Launching loom components: Claude=${enableClaude}, Code=${enableCode}, DevServer=${enableDevServer}, Terminal=${enableTerminal}`)\n\n\t\tconst launchPromises: Promise<void>[] = []\n\n\t\t// Launch VSCode if enabled\n\t\tif (enableCode) {\n\t\t\tgetLogger().debug('Launching VSCode')\n\t\t\tlaunchPromises.push(this.launchVSCode(options))\n\t\t}\n\n\t\t// Build array of terminals to launch\n\t\tconst terminalsToLaunch: Array<{\n\t\t\ttype: 'claude' | 'devServer' | 'terminal'\n\t\t\toptions: TerminalWindowOptions\n\t\t}> = []\n\n\t\tif (enableDevServer) {\n\t\t\tterminalsToLaunch.push({\n\t\t\t\ttype: 'devServer',\n\t\t\t\toptions: await this.buildDevServerTerminalOptions(options),\n\t\t\t})\n\t\t}\n\n\t\tif (enableTerminal) {\n\t\t\tterminalsToLaunch.push({\n\t\t\t\ttype: 'terminal',\n\t\t\t\toptions: this.buildStandaloneTerminalOptions(options),\n\t\t\t})\n\t\t}\n\n\t\tif (enableClaude) {\n\t\t\tterminalsToLaunch.push({\n\t\t\t\ttype: 'claude',\n\t\t\t\toptions: await this.buildClaudeTerminalOptions(options),\n\t\t\t})\n\t\t}\n\n\t\t// Launch terminals based on count\n\t\tif (terminalsToLaunch.length > 1) {\n\t\t\t// Multiple terminals - launch as tabs in single window\n\t\t\tgetLogger().debug(`Launching ${terminalsToLaunch.length} terminals in single window`)\n\t\t\tlaunchPromises.push(this.launchMultipleTerminals(terminalsToLaunch, options))\n\t\t} else if (terminalsToLaunch.length === 1) {\n\t\t\t// Single terminal - launch standalone\n\t\t\tconst terminal = terminalsToLaunch[0]\n\t\t\tif (!terminal) {\n\t\t\t\tthrow new Error('Terminal configuration is undefined')\n\t\t\t}\n\t\t\tconst terminalType = terminal.type\n\t\t\tgetLogger().debug(`Launching single ${terminalType} terminal`)\n\n\t\t\tif (terminalType === 'claude') {\n\t\t\t\tlaunchPromises.push(this.launchClaudeTerminal(options))\n\t\t\t} else if (terminalType === 'devServer') {\n\t\t\t\tlaunchPromises.push(this.launchDevServerTerminal(options))\n\t\t\t} else {\n\t\t\t\tlaunchPromises.push(this.launchStandaloneTerminal(options))\n\t\t\t}\n\t\t}\n\n\t\t// Wait for all components to launch\n\t\tawait Promise.all(launchPromises)\n\n\t\tgetLogger().success('loom launched successfully')\n\t}\n\n\t/**\n\t * Launch IDE (VSCode or configured alternative)\n\t */\n\tprivate async launchVSCode(options: LaunchLoomOptions): Promise<void> {\n\t\tconst ideConfig = await this.settings?.loadSettings().then((s) => s.ide)\n\t\tawait openIdeWindow(options.worktreePath, ideConfig)\n\t\tgetLogger().info('IDE opened')\n\t}\n\n\t/**\n\t * Launch Claude terminal\n\t */\n\tprivate async launchClaudeTerminal(options: LaunchLoomOptions): Promise<void> {\n\t\tawait this.claudeContext.launchWithContext({\n\t\t\tworkspacePath: options.worktreePath,\n\t\t\ttype: options.workflowType,\n\t\t\tidentifier: options.identifier,\n\t\t\tbranchName: options.branchName,\n\t\t\t...(options.title && { title: options.title }),\n\t\t\t...(options.port !== undefined && { port: options.port }),\n\t\t\toneShot: options.oneShot ?? 'default',\n\t\t\t...(options.setArguments && { setArguments: options.setArguments }),\n\t\t\t...(options.executablePath && { executablePath: options.executablePath }),\n\t\t})\n\t\tgetLogger().info('Claude terminal opened')\n\t}\n\n\t/**\n\t * Launch dev server terminal\n\t */\n\tprivate async launchDevServerTerminal(options: LaunchLoomOptions): Promise<void> {\n\t\tconst devServerCommand = await getDevServerLaunchCommand(\n\t\t\toptions.worktreePath,\n\t\t\toptions.port,\n\t\t\toptions.capabilities\n\t\t)\n\n\t\t// Only generate color if terminal coloring is enabled (default: true)\n\t\tconst backgroundColor = (options.colorTerminal ?? true)\n\t\t\t? options.colorHex\n\t\t\t\t? hexToRgb(options.colorHex)\n\t\t\t\t: generateColorFromBranchName(options.branchName).rgb\n\t\t\t: undefined\n\n\t\tawait openTerminalWindow({\n\t\t\tworkspacePath: options.worktreePath,\n\t\t\tcommand: devServerCommand,\n\t\t\t...(backgroundColor && { backgroundColor }),\n\t\t\tincludeEnvSetup: (options.sourceEnvOnStart ?? false) && this.hasAnyEnvFiles(options.worktreePath),\n\t\t\tincludePortExport: options.capabilities.includes('web'),\n\t\t\t...(options.port !== undefined && { port: options.port }),\n\t\t})\n\t\tgetLogger().info('Dev server terminal opened')\n\t}\n\n\t/**\n\t * Launch standalone terminal running `il shell <identifier>`\n\t */\n\tprivate async launchStandaloneTerminal(options: LaunchLoomOptions): Promise<void> {\n\t\t// Build shell command with identifier\n\t\tconst executable = options.executablePath ?? getExecutablePath()\n\t\tconst shellIdentifier = String(options.identifier)\n\t\tconst shellCommand = `${executable} shell ${shellIdentifier}`\n\n\t\t// Only generate color if terminal coloring is enabled (default: true)\n\t\tconst backgroundColor = (options.colorTerminal ?? true)\n\t\t\t? options.colorHex\n\t\t\t\t? hexToRgb(options.colorHex)\n\t\t\t\t: generateColorFromBranchName(options.branchName).rgb\n\t\t\t: undefined\n\n\t\tawait openTerminalWindow({\n\t\t\tworkspacePath: options.worktreePath,\n\t\t\tcommand: shellCommand,\n\t\t\t...(backgroundColor && { backgroundColor }),\n\t\t\t// il shell handles env loading internally, so we don't need includeEnvSetup\n\t\t\tincludeEnvSetup: false,\n\t\t\tincludePortExport: options.capabilities.includes('web'),\n\t\t\t...(options.port !== undefined && { port: options.port }),\n\t\t})\n\t\tgetLogger().info('Standalone terminal opened')\n\t}\n\n\t/**\n\t * Build terminal options for Claude\n\t */\n\tprivate async buildClaudeTerminalOptions(\n\t\toptions: LaunchLoomOptions\n\t): Promise<TerminalWindowOptions> {\n\t\tconst hasEnvFile = this.hasAnyEnvFiles(options.worktreePath)\n\t\tconst claudeTitle = `Claude - ${this.formatIdentifier(options.workflowType, options.identifier)}`\n\n\t\tconst executable = options.executablePath ?? 'iloom'\n\t\tlet claudeCommand = `${executable} spin`\n\t\tif (options.oneShot !== undefined && options.oneShot !== 'default') {\n\t\t\tclaudeCommand += ` --one-shot=${options.oneShot}`\n\t\t}\n\t\tif (options.setArguments && options.setArguments.length > 0) {\n\t\t\tfor (const setArg of options.setArguments) {\n\t\t\t\tclaudeCommand += ` --set ${setArg}`\n\t\t\t}\n\t\t}\n\n\t\t// Only generate color if terminal coloring is enabled (default: true)\n\t\tconst backgroundColor = (options.colorTerminal ?? true)\n\t\t\t? options.colorHex\n\t\t\t\t? hexToRgb(options.colorHex)\n\t\t\t\t: generateColorFromBranchName(options.branchName).rgb\n\t\t\t: undefined\n\n\t\treturn {\n\t\t\tworkspacePath: options.worktreePath,\n\t\t\tcommand: claudeCommand,\n\t\t\t...(backgroundColor && { backgroundColor }),\n\t\t\ttitle: claudeTitle,\n\t\t\tincludeEnvSetup: (options.sourceEnvOnStart ?? false) && hasEnvFile,\n\t\t\t...(options.port !== undefined && { port: options.port, includePortExport: true }),\n\t\t}\n\t}\n\n\t/**\n\t * Build terminal options for dev server\n\t */\n\tprivate async buildDevServerTerminalOptions(\n\t\toptions: LaunchLoomOptions\n\t): Promise<TerminalWindowOptions> {\n\t\tconst devServerCommand = await getDevServerLaunchCommand(\n\t\t\toptions.worktreePath,\n\t\t\toptions.port,\n\t\t\toptions.capabilities\n\t\t)\n\t\tconst hasEnvFile = this.hasAnyEnvFiles(options.worktreePath)\n\t\tconst devServerTitle = `Dev Server - ${this.formatIdentifier(options.workflowType, options.identifier)}`\n\n\t\t// Only generate color if terminal coloring is enabled (default: true)\n\t\tconst backgroundColor = (options.colorTerminal ?? true)\n\t\t\t? options.colorHex\n\t\t\t\t? hexToRgb(options.colorHex)\n\t\t\t\t: generateColorFromBranchName(options.branchName).rgb\n\t\t\t: undefined\n\n\t\treturn {\n\t\t\tworkspacePath: options.worktreePath,\n\t\t\tcommand: devServerCommand,\n\t\t\t...(backgroundColor && { backgroundColor }),\n\t\t\ttitle: devServerTitle,\n\t\t\tincludeEnvSetup: (options.sourceEnvOnStart ?? false) && hasEnvFile,\n\t\t\tincludePortExport: options.capabilities.includes('web'),\n\t\t\t...(options.port !== undefined && { port: options.port }),\n\t\t}\n\t}\n\n\t/**\n\t * Build terminal options for standalone terminal\n\t * Runs `il shell <identifier>` which handles env loading internally\n\t */\n\tprivate buildStandaloneTerminalOptions(\n\t\toptions: LaunchLoomOptions\n\t): TerminalWindowOptions {\n\t\tconst terminalTitle = `Terminal - ${this.formatIdentifier(options.workflowType, options.identifier)}`\n\n\t\t// Build shell command with identifier\n\t\t// Use the same executable path pattern as buildClaudeTerminalOptions\n\t\tconst executable = options.executablePath ?? getExecutablePath()\n\t\tconst shellIdentifier = String(options.identifier)\n\t\tconst shellCommand = `${executable} shell ${shellIdentifier}`\n\n\t\t// Only generate color if terminal coloring is enabled (default: true)\n\t\tconst backgroundColor = (options.colorTerminal ?? true)\n\t\t\t? options.colorHex\n\t\t\t\t? hexToRgb(options.colorHex)\n\t\t\t\t: generateColorFromBranchName(options.branchName).rgb\n\t\t\t: undefined\n\n\t\treturn {\n\t\t\tworkspacePath: options.worktreePath,\n\t\t\tcommand: shellCommand,\n\t\t\t...(backgroundColor && { backgroundColor }),\n\t\t\ttitle: terminalTitle,\n\t\t\t// il shell handles env loading internally, so we don't need includeEnvSetup\n\t\t\tincludeEnvSetup: false,\n\t\t\tincludePortExport: options.capabilities.includes('web'),\n\t\t\t...(options.port !== undefined && { port: options.port }),\n\t\t}\n\t}\n\n\t/**\n\t * Launch multiple terminals (2+) as tabs in single window\n\t */\n\tprivate async launchMultipleTerminals(\n\t\tterminals: Array<{ type: string; options: TerminalWindowOptions }>,\n\t\t_options: LaunchLoomOptions\n\t): Promise<void> {\n\t\tconst terminalOptions = terminals.map((t) => t.options)\n\n\t\tawait openMultipleTerminalWindows(terminalOptions)\n\n\t\tconst terminalTypes = terminals.map((t) => t.type).join(' + ')\n\t\tgetLogger().info(`Multiple terminals opened: ${terminalTypes}`)\n\t}\n\n\t/**\n\t * Check if any dotenv-flow files exist in the workspace\n\t * Checks all files: .env, .env.local, .env.{NODE_ENV}, .env.{NODE_ENV}.local\n\t */\n\tprivate hasAnyEnvFiles(workspacePath: string): boolean {\n\t\tconst envFiles = getDotenvFlowFiles()\n\t\treturn envFiles.some(file => existsSync(join(workspacePath, file)))\n\t}\n\n\t/**\n\t * Format identifier for terminal tab titles\n\t */\n\tprivate formatIdentifier(workflowType: 'issue' | 'pr' | 'regular', identifier: string | number): string {\n\t\tif (workflowType === 'issue') {\n\t\t\treturn `Issue #${identifier}`\n\t\t} else if (workflowType === 'pr') {\n\t\t\treturn `PR #${identifier}`\n\t\t} else {\n\t\t\treturn `Branch: ${identifier}`\n\t\t}\n\t}\n}\n","import { execa } from 'execa'\nimport { logger } from './logger.js'\nimport type { IdeSettings } from '../lib/SettingsManager.js'\n\n// IDE preset configuration\nconst IDE_PRESETS = {\n\tvscode: { command: 'code', name: 'Visual Studio Code', args: [] },\n\tcursor: { command: 'cursor', name: 'Cursor', args: [] },\n\twebstorm: { command: 'webstorm', name: 'WebStorm', args: ['--nosplash'] },\n\tsublime: { command: 'subl', name: 'Sublime Text', args: [] },\n\tintellij: { command: 'idea', name: 'IntelliJ IDEA', args: ['--nosplash'] },\n\twindsurf: { command: 'surf', name: 'Windsurf', args: [] },\n\tantigravity: { command: 'agy', name: 'Antigravity', args: [] },\n} as const\n\ntype IdePreset = keyof typeof IDE_PRESETS\n\n// Resolve IDE configuration to command and args\nexport function getIdeConfig(ideSettings?: IdeSettings): {\n\tcommand: string\n\targs: string[]\n\tname: string\n} {\n\t// Default to vscode if not configured\n\tconst type = ideSettings?.type ?? 'vscode'\n\n\tconst preset = IDE_PRESETS[type as IdePreset]\n\treturn {\n\t\tcommand: preset.command,\n\t\targs: [...preset.args],\n\t\tname: preset.name,\n\t}\n}\n\n// Check if IDE is available\nexport async function isIdeAvailable(command: string): Promise<boolean> {\n\ttry {\n\t\tawait execa('command', ['-v', command], { shell: true, timeout: 5000 })\n\t\treturn true\n\t} catch {\n\t\treturn false\n\t}\n}\n\n// Get installation hint for IDE\nfunction getInstallHint(type: string): string {\n\tconst hints: Record<string, string> = {\n\t\tvscode:\n\t\t\t'Install command-line tools: Open VSCode > Command Palette > \"Shell Command: Install \\'code\\' command in PATH\"',\n\t\tcursor:\n\t\t\t'Install command-line tools: Open Cursor > Command Palette > \"Install \\'cursor\\' command in PATH\"',\n\t\twebstorm: 'Install via JetBrains Toolbox > Settings > Shell Scripts > Enable',\n\t\tsublime:\n\t\t\t'Create symlink: ln -s \"/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl\" /usr/local/bin/subl',\n\t\tintellij: 'Install via JetBrains Toolbox > Settings > Shell Scripts > Enable',\n\t\twindsurf:\n\t\t\t'Install command-line tools during Windsurf installation or create symlink manually',\n\t\tantigravity:\n\t\t\t'Install command-line tools during Antigravity installation or create symlink manually',\n\t}\n\treturn hints[type] ?? `Ensure the IDE command is available in your PATH`\n}\n\n// Open IDE window for workspace\nexport async function openIdeWindow(\n\tworkspacePath: string,\n\tideSettings?: IdeSettings\n): Promise<void> {\n\tconst config = getIdeConfig(ideSettings)\n\tconst available = await isIdeAvailable(config.command)\n\n\tif (!available) {\n\t\tconst type = ideSettings?.type ?? 'vscode'\n\t\tthrow new Error(\n\t\t\t`${config.name} is not available. The \"${config.command}\" command was not found in PATH.\\n` +\n\t\t\t\tgetInstallHint(type)\n\t\t)\n\t}\n\n\ttry {\n\t\tawait execa(config.command, [...config.args, workspacePath])\n\t\tlogger.debug(`Opened ${config.name} for workspace: ${workspacePath}`)\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to open ${config.name}: ${error instanceof Error ? error.message : 'Unknown error'}`\n\t\t)\n\t}\n}\n"],"mappings":"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","names":[]}
|
package/dist/README.md
CHANGED
|
@@ -51,7 +51,9 @@ iloom stops the "Context Window Tetris." It treats context as a first-class conc
|
|
|
51
51
|
* **Scale Understanding:** Because every loom holds its own isolated environment (Git worktree, DB branch, local server), you can switch between 5 complex features without losing your place or your AI's context.
|
|
52
52
|
|
|
53
53
|
* **Visible Reasoning:** The AI's decisions are documented publicly. Your team sees the plan, and "future you" knows exactly why a decision was made.
|
|
54
|
-
|
|
54
|
+
|
|
55
|
+
* **Automatic Session Summaries:** When you finish a loom, iloom captures key insights, decisions, and lessons learned from your Claude session and posts them to the issue. These summaries become institutional knowledge that informs future tasks.
|
|
56
|
+
|
|
55
57
|
|
|
56
58
|
_iloom is not just a tool for managing git worktrees - it's a control plane for maintaining alignment between you and your AI assistant._
|
|
57
59
|
|
|
@@ -73,8 +75,8 @@ iloom uses your existing Claude subscription to build a shared mental model of y
|
|
|
73
75
|
|
|
74
76
|
# ... You, the iloom agents and Claude build the feature together in the isolated environment ...
|
|
75
77
|
|
|
76
|
-
# 4. Finish & Merge # Validates code
|
|
77
|
-
il finish
|
|
78
|
+
# 4. Finish & Merge # Validates code, generates session summary, merges, and cleans up.
|
|
79
|
+
il finish
|
|
78
80
|
```
|
|
79
81
|
|
|
80
82
|
**The iloom Difference:** il start doesn't just create a branch. It launches a multi-agent workflow that surfaces assumptions and creates a structured plan in your issue tracker **before you even need to look at your IDE.**
|
|
@@ -138,8 +140,10 @@ Command Reference
|
|
|
138
140
|
| `il finish` | `dn` | Validate tests/lint, commit, handle conflicts, and merge/PR. |
|
|
139
141
|
| `il cleanup` | `remove` | Safely remove a loom and its database branch without merging. |
|
|
140
142
|
| `il list` | | Show active looms and paths. |
|
|
143
|
+
| `il projects` | | List configured projects (JSON output). |
|
|
141
144
|
| `il spin` | | Launch Claude inside the current loom with context auto-detected. |
|
|
142
145
|
| `il open` | `run` | Open loom in browser (web) or run your CLI tool. |
|
|
146
|
+
| `il dev-server` | `dev` | Start dev server in foreground for a workspace. |
|
|
143
147
|
| `il add-issue` | `a` | Create and AI-enhance a new issue without starting work yet. |
|
|
144
148
|
| `il init` | `config` | Interactive configuration wizard. |
|
|
145
149
|
| `il feedback` | `f` | Submit bug reports/feedback directly from the CLI. |
|
|
@@ -218,6 +222,12 @@ This example shows how to configure a project-wide default (e.g., GitHub remote)
|
|
|
218
222
|
"issue": {
|
|
219
223
|
"permissionMode": "acceptEdits" // Control Claude Code permissions
|
|
220
224
|
}
|
|
225
|
+
},
|
|
226
|
+
"spin": {
|
|
227
|
+
"model": "opus" // Claude model for spin orchestrator: opus (default), sonnet, or haiku
|
|
228
|
+
},
|
|
229
|
+
"summary": {
|
|
230
|
+
"model": "sonnet" // Claude model for session summaries: sonnet (default), opus, or haiku
|
|
221
231
|
}
|
|
222
232
|
}
|
|
223
233
|
```
|
|
@@ -8,12 +8,14 @@ import {
|
|
|
8
8
|
IloomSettingsSchemaNoDefaults,
|
|
9
9
|
NeonSettingsSchema,
|
|
10
10
|
SettingsManager,
|
|
11
|
+
SpinAgentSettingsSchema,
|
|
12
|
+
SummarySettingsSchema,
|
|
11
13
|
WorkflowPermissionSchema,
|
|
12
14
|
WorkflowPermissionSchemaNoDefaults,
|
|
13
15
|
WorkflowsSettingsSchema,
|
|
14
16
|
WorkflowsSettingsSchemaNoDefaults
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
import "./chunk-
|
|
17
|
+
} from "./chunk-VWNS6DH5.js";
|
|
18
|
+
import "./chunk-UYVWLISQ.js";
|
|
17
19
|
export {
|
|
18
20
|
AgentSettingsSchema,
|
|
19
21
|
CapabilitiesSettingsSchema,
|
|
@@ -23,9 +25,11 @@ export {
|
|
|
23
25
|
IloomSettingsSchemaNoDefaults,
|
|
24
26
|
NeonSettingsSchema,
|
|
25
27
|
SettingsManager,
|
|
28
|
+
SpinAgentSettingsSchema,
|
|
29
|
+
SummarySettingsSchema,
|
|
26
30
|
WorkflowPermissionSchema,
|
|
27
31
|
WorkflowPermissionSchemaNoDefaults,
|
|
28
32
|
WorkflowsSettingsSchema,
|
|
29
33
|
WorkflowsSettingsSchemaNoDefaults
|
|
30
34
|
};
|
|
31
|
-
//# sourceMappingURL=SettingsManager-
|
|
35
|
+
//# sourceMappingURL=SettingsManager-FJFU6JJD.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
SettingsMigrationManager
|
|
4
|
+
} from "./chunk-UYWAESOT.js";
|
|
5
|
+
import "./chunk-SJ2GZ6RF.js";
|
|
6
|
+
import "./chunk-UYVWLISQ.js";
|
|
7
|
+
export {
|
|
8
|
+
SettingsMigrationManager
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=SettingsMigrationManager-EH3J2TCN.js.map
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
MetadataManager
|
|
4
|
+
} from "./chunk-IJ7IGJT3.js";
|
|
2
5
|
import {
|
|
3
6
|
SettingsManager
|
|
4
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-VWNS6DH5.js";
|
|
5
8
|
import {
|
|
6
9
|
logger
|
|
7
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-UYVWLISQ.js";
|
|
8
11
|
|
|
9
12
|
// src/utils/git.ts
|
|
10
13
|
import path from "path";
|
|
@@ -16,7 +19,9 @@ async function executeGitCommand(args, options) {
|
|
|
16
19
|
timeout: (options == null ? void 0 : options.timeout) ?? 3e4,
|
|
17
20
|
encoding: "utf8",
|
|
18
21
|
stdio: (options == null ? void 0 : options.stdio) ?? "pipe",
|
|
19
|
-
verbose: logger.isDebugEnabled()
|
|
22
|
+
verbose: logger.isDebugEnabled(),
|
|
23
|
+
// Spread env conditionally - only include if defined
|
|
24
|
+
...(options == null ? void 0 : options.env) && { env: options.env }
|
|
20
25
|
});
|
|
21
26
|
return result.stdout;
|
|
22
27
|
} catch (error) {
|
|
@@ -304,6 +309,27 @@ async function findMainWorktreePathWithSettings(path2, settingsManager) {
|
|
|
304
309
|
const findOptions = settings.mainBranch ? { mainBranch: settings.mainBranch } : void 0;
|
|
305
310
|
return findMainWorktreePath(path2, findOptions);
|
|
306
311
|
}
|
|
312
|
+
async function findWorktreeForBranch(branchName, path2 = process.cwd()) {
|
|
313
|
+
try {
|
|
314
|
+
const output = await executeGitCommand(["worktree", "list", "--porcelain"], { cwd: path2 });
|
|
315
|
+
const worktrees = parseWorktreeList(output, branchName);
|
|
316
|
+
if (worktrees.length === 0) {
|
|
317
|
+
throw new Error("No worktrees found in repository");
|
|
318
|
+
}
|
|
319
|
+
const targetWorktree = worktrees.find((wt) => wt.branch === branchName);
|
|
320
|
+
if (!(targetWorktree == null ? void 0 : targetWorktree.path)) {
|
|
321
|
+
throw new Error(
|
|
322
|
+
`No worktree found with branch '${branchName}' checked out. Available worktrees: ${worktrees.map((wt) => `${wt.path} (${wt.branch})`).join(", ")}`
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
return targetWorktree.path;
|
|
326
|
+
} catch (error) {
|
|
327
|
+
if (error instanceof Error && (error.message.includes("No worktree found with branch") || error.message.includes("No worktrees found"))) {
|
|
328
|
+
throw error;
|
|
329
|
+
}
|
|
330
|
+
throw new Error(`Failed to find worktree for branch '${branchName}': ${error instanceof Error ? error.message : String(error)}`);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
307
333
|
async function hasUncommittedChanges(path2 = process.cwd()) {
|
|
308
334
|
try {
|
|
309
335
|
const result = await executeGitCommand(["status", "--porcelain"], { cwd: path2 });
|
|
@@ -332,7 +358,7 @@ async function getDefaultBranch(path2 = process.cwd()) {
|
|
|
332
358
|
}
|
|
333
359
|
async function findAllBranchesForIssue(issueNumber, path2 = process.cwd(), settingsManager) {
|
|
334
360
|
if (!settingsManager) {
|
|
335
|
-
const { SettingsManager: SM } = await import("./SettingsManager-
|
|
361
|
+
const { SettingsManager: SM } = await import("./SettingsManager-FJFU6JJD.js");
|
|
336
362
|
settingsManager = new SM();
|
|
337
363
|
}
|
|
338
364
|
const protectedBranches = await settingsManager.getProtectedBranches(path2);
|
|
@@ -472,6 +498,122 @@ async function isFileGitignored(filePath, cwd = process.cwd()) {
|
|
|
472
498
|
return false;
|
|
473
499
|
}
|
|
474
500
|
}
|
|
501
|
+
async function isBranchMergedIntoMain(branchName, mainBranch = "main", cwd = process.cwd()) {
|
|
502
|
+
try {
|
|
503
|
+
await executeGitCommand(["merge-base", "--is-ancestor", branchName, mainBranch], { cwd });
|
|
504
|
+
return true;
|
|
505
|
+
} catch {
|
|
506
|
+
return false;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
async function isRemoteBranchUpToDate(branchName, cwd) {
|
|
510
|
+
try {
|
|
511
|
+
const remoteResult = await executeGitCommand(["ls-remote", "--heads", "origin", branchName], { cwd });
|
|
512
|
+
if (remoteResult.trim().length === 0) {
|
|
513
|
+
return false;
|
|
514
|
+
}
|
|
515
|
+
const remoteCommit = remoteResult.trim().split(" ")[0];
|
|
516
|
+
const localCommit = await executeGitCommand(["rev-parse", branchName], { cwd });
|
|
517
|
+
return localCommit.trim() === remoteCommit;
|
|
518
|
+
} catch {
|
|
519
|
+
return false;
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
async function checkRemoteBranchStatus(branchName, cwd) {
|
|
523
|
+
try {
|
|
524
|
+
try {
|
|
525
|
+
await executeGitCommand(["fetch", "origin", branchName], { cwd, timeout: 3e4 });
|
|
526
|
+
} catch (fetchError) {
|
|
527
|
+
const fetchErrorMessage = fetchError instanceof Error ? fetchError.message : String(fetchError);
|
|
528
|
+
if (fetchErrorMessage.includes("Could not resolve host") || fetchErrorMessage.includes("unable to access") || fetchErrorMessage.includes("network") || fetchErrorMessage.includes("Connection refused") || fetchErrorMessage.includes("Connection timed out")) {
|
|
529
|
+
return {
|
|
530
|
+
exists: false,
|
|
531
|
+
remoteAhead: false,
|
|
532
|
+
localAhead: false,
|
|
533
|
+
networkError: true,
|
|
534
|
+
errorMessage: fetchErrorMessage
|
|
535
|
+
};
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
const remoteResult = await executeGitCommand(["ls-remote", "--heads", "origin", branchName], { cwd });
|
|
539
|
+
if (remoteResult.trim().length === 0) {
|
|
540
|
+
return {
|
|
541
|
+
exists: false,
|
|
542
|
+
remoteAhead: false,
|
|
543
|
+
localAhead: false,
|
|
544
|
+
networkError: false
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
const remoteCommit = remoteResult.trim().split(" ")[0];
|
|
548
|
+
if (!remoteCommit) {
|
|
549
|
+
return {
|
|
550
|
+
exists: false,
|
|
551
|
+
remoteAhead: false,
|
|
552
|
+
localAhead: false,
|
|
553
|
+
networkError: false
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
const localCommit = await executeGitCommand(["rev-parse", branchName], { cwd });
|
|
557
|
+
const localCommitTrimmed = localCommit.trim();
|
|
558
|
+
if (remoteCommit === localCommitTrimmed) {
|
|
559
|
+
return {
|
|
560
|
+
exists: true,
|
|
561
|
+
remoteAhead: false,
|
|
562
|
+
localAhead: false,
|
|
563
|
+
networkError: false
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
try {
|
|
567
|
+
await executeGitCommand(["merge-base", "--is-ancestor", localCommitTrimmed, remoteCommit], { cwd });
|
|
568
|
+
return {
|
|
569
|
+
exists: true,
|
|
570
|
+
remoteAhead: true,
|
|
571
|
+
localAhead: false,
|
|
572
|
+
networkError: false
|
|
573
|
+
};
|
|
574
|
+
} catch {
|
|
575
|
+
return {
|
|
576
|
+
exists: true,
|
|
577
|
+
remoteAhead: false,
|
|
578
|
+
localAhead: true,
|
|
579
|
+
networkError: false
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
} catch (error) {
|
|
583
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
584
|
+
if (errorMessage.includes("Could not resolve host") || errorMessage.includes("unable to access") || errorMessage.includes("network") || errorMessage.includes("Connection refused") || errorMessage.includes("Connection timed out")) {
|
|
585
|
+
return {
|
|
586
|
+
exists: false,
|
|
587
|
+
remoteAhead: false,
|
|
588
|
+
localAhead: false,
|
|
589
|
+
networkError: true,
|
|
590
|
+
errorMessage
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
return {
|
|
594
|
+
exists: false,
|
|
595
|
+
remoteAhead: false,
|
|
596
|
+
localAhead: false,
|
|
597
|
+
networkError: false
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
async function getMergeTargetBranch(worktreePath = process.cwd(), options) {
|
|
602
|
+
var _a;
|
|
603
|
+
const settingsManager = (options == null ? void 0 : options.settingsManager) ?? new SettingsManager();
|
|
604
|
+
const metadataManager = (options == null ? void 0 : options.metadataManager) ?? new MetadataManager();
|
|
605
|
+
logger.debug(`Checking for parent loom metadata at: ${worktreePath}`);
|
|
606
|
+
const metadata = await metadataManager.readMetadata(worktreePath);
|
|
607
|
+
if ((_a = metadata == null ? void 0 : metadata.parentLoom) == null ? void 0 : _a.branchName) {
|
|
608
|
+
logger.debug(`Using parent branch as merge target: ${metadata.parentLoom.branchName}`);
|
|
609
|
+
return metadata.parentLoom.branchName;
|
|
610
|
+
}
|
|
611
|
+
logger.debug("No parent loom metadata found, falling back to settings");
|
|
612
|
+
const settings = await settingsManager.loadSettings(worktreePath);
|
|
613
|
+
const mainBranch = settings.mainBranch ?? "main";
|
|
614
|
+
logger.debug(`Using configured main branch as merge target: ${mainBranch}`);
|
|
615
|
+
return mainBranch;
|
|
616
|
+
}
|
|
475
617
|
|
|
476
618
|
export {
|
|
477
619
|
executeGitCommand,
|
|
@@ -488,6 +630,7 @@ export {
|
|
|
488
630
|
getRepoRoot,
|
|
489
631
|
findMainWorktreePath,
|
|
490
632
|
findMainWorktreePathWithSettings,
|
|
633
|
+
findWorktreeForBranch,
|
|
491
634
|
hasUncommittedChanges,
|
|
492
635
|
getDefaultBranch,
|
|
493
636
|
findAllBranchesForIssue,
|
|
@@ -495,6 +638,10 @@ export {
|
|
|
495
638
|
ensureRepositoryHasCommits,
|
|
496
639
|
pushBranchToRemote,
|
|
497
640
|
isFileTrackedByGit,
|
|
498
|
-
isFileGitignored
|
|
641
|
+
isFileGitignored,
|
|
642
|
+
isBranchMergedIntoMain,
|
|
643
|
+
isRemoteBranchUpToDate,
|
|
644
|
+
checkRemoteBranchStatus,
|
|
645
|
+
getMergeTargetBranch
|
|
499
646
|
};
|
|
500
|
-
//# sourceMappingURL=chunk-
|
|
647
|
+
//# sourceMappingURL=chunk-2W2FBL5G.js.map
|