mulmoterminal 5.3.0 → 5.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +2 -2
- package/README.ko.md +182 -0
- package/README.md +20 -5
- package/README.zh-TW.md +172 -0
- package/README.zh.md +2 -2
- package/bin/mulmoterminal.js +96 -32
- package/bin/server-supervision.d.ts +15 -0
- package/bin/server-supervision.js +122 -0
- package/common/mdPreviewMessage.ts +48 -0
- package/common/sessionReap.ts +34 -0
- package/common/survivingSessions.ts +1 -1
- package/dist/assets/{AllPackages-B1YCJRYB-Dq7RtcKf.js → AllPackages-B1YCJRYB-Bg-5uEoq.js} +1 -1
- package/dist/assets/{BaseConfiguration-B6s_tKOW-Cqnov2Sk.js → BaseConfiguration-B6s_tKOW-CEVr20RP.js} +1 -1
- package/dist/assets/{Element-BMI7Nj5w-BNxoLB0I.js → Element-BMI7Nj5w-CxpOvtBz.js} +1 -1
- package/dist/assets/{Entities-C8p_0jCn-nTjTp-hn.js → Entities-C8p_0jCn-CfRaPmLP.js} +1 -1
- package/dist/assets/{FunctionList-YWk54TCy-BE08xiex.js → FunctionList-YWk54TCy-BRhU6XBK.js} +1 -1
- package/dist/assets/{InputJax-C5dj-ntL-R1Dc7w96.js → InputJax-C5dj-ntL-DPXq9x02.js} +1 -1
- package/dist/assets/{MathItem-YJvQL-XJ-CLANtgp6.js → MathItem-YJvQL-XJ-DTodoxIm.js} +1 -1
- package/dist/assets/{MmlFactory-DSoKkE7s-5yVDGib6.js → MmlFactory-DSoKkE7s-BOTwBSWK.js} +1 -1
- package/dist/assets/{Options-oARQeeuT-8pBPNhr8.js → Options-oARQeeuT-CKZyyq2e.js} +1 -1
- package/dist/assets/{OutputJax-DfUZNNCu-DGRVixhw.js → OutputJax-DfUZNNCu-JkG_sEnw.js} +1 -1
- package/dist/assets/{PrioritizedList-6lun1Xqd-DRdQwlR3.js → PrioritizedList-6lun1Xqd-CJ_oyt8w.js} +1 -1
- package/dist/assets/{Styles-5NmwS-3M-CqPSzBzv.js → Styles-5NmwS-3M-BQCfw6EK.js} +1 -1
- package/dist/assets/{TeXAtom-B5ni9myz-7xixu72b.js → TeXAtom-B5ni9myz-DlmQMx8j.js} +1 -1
- package/dist/assets/{abnfDiagram-VCTEODGH-BGhi-oVb-D9vo48Kc.js → abnfDiagram-VCTEODGH-BGhi-oVb-DVHO3VHP.js} +1 -1
- package/dist/assets/{arc-CK5ru50N-BlqR_Ske.js → arc-CK5ru50N-CSq4Da5V.js} +1 -1
- package/dist/assets/architecture-7GRP2DOG-otSkCkT5-B3OuyEdV.js +1 -0
- package/dist/assets/{architectureDiagram-5GKGNRK7-ELuPYMlf-CXbm8lLb.js → architectureDiagram-5GKGNRK7-ELuPYMlf-CvE6U2W5.js} +1 -1
- package/dist/assets/{assistive-mml-CdU3rUpx-CCKquCU4.js → assistive-mml-CdU3rUpx-ZnIlympk.js} +1 -1
- package/dist/assets/{blockDiagram-I7D4REHJ-BZ7-OGWQ-B6ff9p2Y.js → blockDiagram-I7D4REHJ-BZ7-OGWQ-D68-xhm9.js} +1 -1
- package/dist/assets/{c4Diagram-7LVT6UL2-DCovPZ_4-DNdoEnm0.js → c4Diagram-7LVT6UL2-DCovPZ_4-Wayx7U25.js} +1 -1
- package/dist/assets/channel-Bmu_OOc6-BfH6zlgZ.js +1 -0
- package/dist/assets/{chunk-4HAMMTFA-DqpzLmar-ggP-4zbL.js → chunk-4HAMMTFA-DqpzLmar-CxazywNw.js} +1 -1
- package/dist/assets/{chunk-75Z2AOVW-CT5TYzp5-BAYR6Gyo.js → chunk-75Z2AOVW-CT5TYzp5-6W-06rom.js} +1 -1
- package/dist/assets/{chunk-DU6HZSFF-BVf-rtdf--dgDiPgV.js → chunk-DU6HZSFF-BVf-rtdf-NCxY40OI.js} +1 -1
- package/dist/assets/{chunk-F27PBJKO-rP8pUsk3-BUE2LzK8.js → chunk-F27PBJKO-rP8pUsk3-CIhzU0aa.js} +1 -1
- package/dist/assets/{chunk-IMKFNOWR-D_IT0r3G-DEq-HDMy.js → chunk-IMKFNOWR-D_IT0r3G-lwFWDDvW.js} +1 -1
- package/dist/assets/{chunk-POPQ4Y6H-C5YURnHe-BJUZN0LR.js → chunk-POPQ4Y6H-C5YURnHe-BeGNAWKL.js} +1 -1
- package/dist/assets/{chunk-SHT3W25Y-CfF0J8Qh-BLNIWgW0.js → chunk-SHT3W25Y-CfF0J8Qh-CSThIpbQ.js} +1 -1
- package/dist/assets/{chunk-SVP7TREG-CTZbRIbX-DzHNPM77.js → chunk-SVP7TREG-CTZbRIbX-DfOFlvDP.js} +1 -1
- package/dist/assets/{chunk-TICWLB2K-DP1lYmZm-hPrDbcf2.js → chunk-TICWLB2K-DP1lYmZm-BOfltZqL.js} +1 -1
- package/dist/assets/{chunk-XXDRQBXY-vg0kfC73-CA6dD2B2.js → chunk-XXDRQBXY-vg0kfC73-x0NSF3Hr.js} +1 -1
- package/dist/assets/classDiagram-ZZMXUADV-BDQOAOBf-t0VNRx5r.js +1 -0
- package/dist/assets/classDiagram-v2-VYDZK3BY-CwPXtzoF-t0VNRx5r.js +1 -0
- package/dist/assets/{cose-bilkent-JH36ORCC-qIiD3RGD-CgZnBXDi.js → cose-bilkent-JH36ORCC-qIiD3RGD-Cx3asJyh.js} +1 -1
- package/dist/assets/cynefin-OW5HDTMX-Xr6IPdZG-BsnKANcW.js +1 -0
- package/dist/assets/{cynefinDiagram-5FMLGOSQ-BZrUCS-v-lJIPhbyX.js → cynefinDiagram-5FMLGOSQ-BZrUCS-v-Bm3EP8ds.js} +1 -1
- package/dist/assets/{dagre-C2SZ8h4o-BgSfmUeF.js → dagre-C2SZ8h4o-jKFrEa2H.js} +1 -1
- package/dist/assets/{dagre-GXQ25YYZ-CQcLM4na-mO2les8S.js → dagre-GXQ25YYZ-CQcLM4na-CfHZQj_0.js} +1 -1
- package/dist/assets/{diagram-S7CK7UJ4-BdmcmUQh-DZZPbcxP.js → diagram-S7CK7UJ4-BdmcmUQh-B1zoMWcW.js} +1 -1
- package/dist/assets/{diagram-UQ7AKVKN-BtvmEiYl-CXPBFvdO.js → diagram-UQ7AKVKN-BtvmEiYl-CU9Mx297.js} +1 -1
- package/dist/assets/{diagram-VSXAHHWV-qEG6N0bV-2P5xWeyN.js → diagram-VSXAHHWV-qEG6N0bV-DGRRUOTd.js} +1 -1
- package/dist/assets/{diagram-VX7I27RA-BA8is49N-Ce8-XrQI.js → diagram-VX7I27RA-BA8is49N-BkLxnDAE.js} +1 -1
- package/dist/assets/{diagram-Z3DM3KII-XPcU7IOQ-obu8Hmlg.js → diagram-Z3DM3KII-XPcU7IOQ-jBNNnIsA.js} +1 -1
- package/dist/assets/{dist-DoZPZkgo.js → dist-BgskxEoA.js} +1 -1
- package/dist/assets/{dist-DDtEYLX4.js → dist-CEIAU_oR.js} +1 -1
- package/dist/assets/{dist-BaZxeAEj.js → dist-CY0trXbV.js} +1 -1
- package/dist/assets/{dist-DpShV5wo.js → dist-DLdTPhUQ.js} +1 -1
- package/dist/assets/{dist-DeiyD9Ki-B3Qn-Kh4.js → dist-DeiyD9Ki-CBWBvt-Y.js} +1 -1
- package/dist/assets/{ebnfDiagram-PWID7BFC-CTHIHdBS-oyDbKuK_.js → ebnfDiagram-PWID7BFC-CTHIHdBS-OWJzH8zW.js} +1 -1
- package/dist/assets/{erDiagram-RLTQ6QDP-DVpWTNZj-DD5MfJxq.js → erDiagram-RLTQ6QDP-DVpWTNZj-DtX_ExNn.js} +1 -1
- package/dist/assets/eventmodeling-NTZA5JFV-B7bRrpt_-bIFBS60f.js +1 -0
- package/dist/assets/flowDiagram-HODETNUW-r-3T5g30-Hkt1ezyN.js +1 -0
- package/dist/assets/{ganttDiagram-EL5Y4UJY-BfAgk15F-EJ3zMpou.js → ganttDiagram-EL5Y4UJY-BfAgk15F-JCy4j3kS.js} +1 -1
- package/dist/assets/gitGraph-4MIJSDKK-BhzSx5wq-2gCWor0n.js +1 -0
- package/dist/assets/{gitGraphDiagram-WWUBYQGX-DEVVZ6wt-Dj16r719.js → gitGraphDiagram-WWUBYQGX-DEVVZ6wt-3Y9AXg9N.js} +1 -1
- package/dist/assets/{graphlib-BYLhHyYO-BTZzAS5v.js → graphlib-BYLhHyYO-WF0qQjci.js} +1 -1
- package/dist/assets/{html-Z7dGbczU-DHXoUjco.js → html-Z7dGbczU-ZGdX0b8w.js} +1 -1
- package/dist/assets/{index-CziTLExz.css → index-DgrAGl1L.css} +1 -1
- package/dist/assets/{index-DE93mXAl.js → index-OJC0eK_5.js} +325 -325
- package/dist/assets/info-A6RAGUB7-fR2SUJmJ-B50g7Boc.js +1 -0
- package/dist/assets/{infoDiagram-27XIBGKW-CvHUhAHd-DQWRUxRY.js → infoDiagram-27XIBGKW-CvHUhAHd-BGTWNOQ7.js} +1 -1
- package/dist/assets/{ishikawaDiagram-5VMMS53U-CeqyKdwk-CaqBsvlx.js → ishikawaDiagram-5VMMS53U-CeqyKdwk-CaDKjofT.js} +1 -1
- package/dist/assets/{journeyDiagram-3NMN7TZE-Jfi7MPDi-D2E43LwV.js → journeyDiagram-3NMN7TZE-Jfi7MPDi-vqNDd8m3.js} +1 -1
- package/dist/assets/{kanban-definition-UXKFOSKX-yOrlojns-CHfxXoOA.js → kanban-definition-UXKFOSKX-yOrlojns-D9-zVcRW.js} +1 -1
- package/dist/assets/{lengths-CvmPfBid-pbRzi4y_.js → lengths-CvmPfBid-RdMjz3In.js} +1 -1
- package/dist/assets/{linear-jdmEy-qs-YK-i28xN.js → linear-jdmEy-qs-kigJmEfH.js} +1 -1
- package/dist/assets/{liteAdaptor-pH5MXTG0-3egTzN5I.js → liteAdaptor-pH5MXTG0-CI9Yt7wd.js} +1 -1
- package/dist/assets/{mathjax-DVEo4UYj-DJM3fB8M.js → mathjax-DVEo4UYj-BGMQiwz8.js} +1 -1
- package/dist/assets/{mermaid-parser.core-CzBW8Fof-BLYnlega.js → mermaid-parser.core-CzBW8Fof-D2FuIY02.js} +2 -2
- package/dist/assets/{mermaid.core-Dv4uylek-BEK0XLuu.js → mermaid.core-Dv4uylek-DKNPiJeq.js} +4 -4
- package/dist/assets/{mindmap-definition-YA3MSWOX-DP_2R9Ga-BCnJS2OL.js → mindmap-definition-YA3MSWOX-DP_2R9Ga-8SaXC-T7.js} +1 -1
- package/dist/assets/{mo-Xv_6CC7A-fsTVwGAJ.js → mo-Xv_6CC7A-DEA1AAm0.js} +1 -1
- package/dist/assets/packet-AYTQ26CC-B_oKR9KZ-YUVke5xN.js +1 -0
- package/dist/assets/{pegDiagram-XKGWAZYB-BsBWryhi-DnlKhijv.js → pegDiagram-XKGWAZYB-BsBWryhi-Dkva5TuZ.js} +1 -1
- package/dist/assets/pie-WAS4IAKB-D1ZXrN1W-BvO3OOJ7.js +1 -0
- package/dist/assets/{pieDiagram-E7YTZNPT-OugkS2pU-BQ62uhNn.js → pieDiagram-E7YTZNPT-OugkS2pU-Cu40AMV4.js} +1 -1
- package/dist/assets/{quadrantDiagram-AXDQQJYC-DXEAAaUE-DjfBVEH6.js → quadrantDiagram-AXDQQJYC-DXEAAaUE-CdSho5E4.js} +1 -1
- package/dist/assets/radar-RG4KPBEZ-BmUgDkiH-BhVMaCi1.js +1 -0
- package/dist/assets/railroad-74A4TZTK-6lEXVJo8-CEeoh6Q2.js +1 -0
- package/dist/assets/railroad-abnf-HS5TGJTU-BG28Qiz1-D0_mRIi6.js +1 -0
- package/dist/assets/railroad-ebnf-LZEXJU2U-DzpHhtTH-DTciaVU8.js +1 -0
- package/dist/assets/railroad-peg-WCYAUIDC-B2CHCTyG-ChdzAekV.js +1 -0
- package/dist/assets/{railroadDiagram-O6MQD6OU-BJys8O96-DT83nUM3.js → railroadDiagram-O6MQD6OU-BJys8O96-Q0gFWJuL.js} +1 -1
- package/dist/assets/{requirementDiagram-BXWQKSXE-BaDgCtM5-Bk6OMrCS.js → requirementDiagram-BXWQKSXE-BaDgCtM5-DE0Glawh.js} +1 -1
- package/dist/assets/{sankeyDiagram-P5KCCOFB-puZsr_vK-B3mb-QqF.js → sankeyDiagram-P5KCCOFB-puZsr_vK-KxkF5wKT.js} +1 -1
- package/dist/assets/{sequenceDiagram-WJ2MYXX4-D1ziEryC-DA35A244.js → sequenceDiagram-WJ2MYXX4-D1ziEryC-AvtXebaV.js} +1 -1
- package/dist/assets/{src-CLC0ddSd-DXUH8o27.js → src-CLC0ddSd-CxO1BMF0.js} +1 -1
- package/dist/assets/{stateDiagram-D77RDMKH-HSEurT6h-BZdzB2jB.js → stateDiagram-D77RDMKH-HSEurT6h-DVQCSe5S.js} +1 -1
- package/dist/assets/stateDiagram-v2-MP3YSRHH-DnOa-Otc-B9nBSGJq.js +1 -0
- package/dist/assets/{svg-D_RYJvQC-CymKx1MQ.js → svg-D_RYJvQC-Bnf4dPg8.js} +1 -1
- package/dist/assets/{swimlanes-42K2YHIH-umBsuvsI-CFo1naDR.js → swimlanes-42K2YHIH-umBsuvsI-lnbPDjFB.js} +1 -1
- package/dist/assets/swimlanesDiagram-VR7AAH4N-ZLUyNmnU-fOaL0SGa.js +8 -0
- package/dist/assets/{tex-Dx2UJ3VU-CQTk8uUD.js → tex-Dx2UJ3VU-D5fP6ox5.js} +1 -1
- package/dist/assets/{timeline-definition-24CTP7MA-D9plt22Y-BhW4PYii.js → timeline-definition-24CTP7MA-D9plt22Y-uB6GZ0E3.js} +1 -1
- package/dist/assets/treeView-Q6P3EWNA-BdvZ0_C5-SL3n8nN2.js +1 -0
- package/dist/assets/treemap-WGGIJYW6-CIJLPQlC-dBN3E-xL.js +1 -0
- package/dist/assets/{vennDiagram-4TSXK5OY-DZe7wY85-GcaRUyDZ.js → vennDiagram-4TSXK5OY-DZe7wY85-CJLX79pA.js} +1 -1
- package/dist/assets/wardley-WFR3VGLG-CKqtFD8V-CqN0hOPL.js +1 -0
- package/dist/assets/{wardleyDiagram-VM6X3IG4-DK9yytWx-D9owzIEw.js → wardleyDiagram-VM6X3IG4-DK9yytWx-BqjdSbwe.js} +1 -1
- package/dist/assets/{xychartDiagram-S5SC5T6Z-CLSO4Pc9-B-vSQvUZ.js → xychartDiagram-S5SC5T6Z-CLSO4Pc9-Diz8ByV4.js} +1 -1
- package/dist/index.html +2 -2
- package/package.json +1 -1
- package/server/agents/rate-limit-service.ts +113 -0
- package/server/backends/boot-backends.ts +109 -0
- package/server/backends/feeds-worker.ts +45 -0
- package/server/backends/remoteHost/getFeed.spec.ts +1 -1
- package/server/backends/remoteHost/handlers/deps.ts +1 -1
- package/server/backends/remoteHost/handlers/terminalSession.ts +30 -15
- package/server/backends/remoteHost/handlers.spec.ts +118 -21
- package/server/backends/remoteHost/hostBindings.ts +127 -0
- package/server/backends/remoteHost/hostScreens.ts +61 -0
- package/server/backends/remoteHost/hostSessionList.ts +65 -0
- package/server/backends/remoteHost/launchTerminal.ts +14 -1
- package/server/backends/remoteHost/workByCwd.ts +33 -0
- package/server/config/app-config.ts +7 -2
- package/server/config/config-routes.ts +14 -3
- package/server/files/files-browse.ts +39 -4
- package/server/files/mdPreviewEmbed.ts +129 -0
- package/server/files/renderedDoc.ts +3 -1
- package/server/git/git-status.ts +31 -3
- package/server/index.ts +46 -661
- package/server/infra/coalesce-by-key.ts +32 -0
- package/server/infra/legacy-cleanup.ts +25 -0
- package/server/infra/on-listening.ts +92 -0
- package/server/infra/server-exit.ts +10 -5
- package/server/infra/shutdown.ts +54 -3
- package/server/infra/tmux-routes.ts +4 -1
- package/server/infra/tmux.ts +27 -8
- package/server/routes/app-routes.ts +2 -0
- package/server/routes/dir-routes.ts +4 -1
- package/server/session/decision-digest-schedule.ts +20 -0
- package/server/session/persist-drain.ts +50 -0
- package/server/session/reap-schedule.ts +111 -0
- package/server/session/registry.ts +11 -0
- package/server/session/scheduled-sessions-boot.ts +67 -0
- package/server/session/session-lookup.ts +17 -0
- package/server/session/spawn-claude.ts +4 -0
- package/server/skills/mulmoterminal-config/SKILL.md +42 -1
- package/dist/assets/architecture-7GRP2DOG-otSkCkT5-ifTMCh6E.js +0 -1
- package/dist/assets/channel-Bmu_OOc6-DE5nBHdm.js +0 -1
- package/dist/assets/classDiagram-ZZMXUADV-BDQOAOBf-DxjUWGXR.js +0 -1
- package/dist/assets/classDiagram-v2-VYDZK3BY-CwPXtzoF-DxjUWGXR.js +0 -1
- package/dist/assets/cynefin-OW5HDTMX-Xr6IPdZG-DIN74MBN.js +0 -1
- package/dist/assets/eventmodeling-NTZA5JFV-B7bRrpt_-ByYnQ_YE.js +0 -1
- package/dist/assets/flowDiagram-HODETNUW-r-3T5g30-DVt4ibmB.js +0 -1
- package/dist/assets/gitGraph-4MIJSDKK-BhzSx5wq-De8cUs1t.js +0 -1
- package/dist/assets/info-A6RAGUB7-fR2SUJmJ-DfOs01lb.js +0 -1
- package/dist/assets/packet-AYTQ26CC-B_oKR9KZ-CIr_QE41.js +0 -1
- package/dist/assets/pie-WAS4IAKB-D1ZXrN1W-DtjU4bsm.js +0 -1
- package/dist/assets/radar-RG4KPBEZ-BmUgDkiH-CuKD9jQP.js +0 -1
- package/dist/assets/railroad-74A4TZTK-6lEXVJo8-DYg5FlhY.js +0 -1
- package/dist/assets/railroad-abnf-HS5TGJTU-BG28Qiz1-CmzKOp6N.js +0 -1
- package/dist/assets/railroad-ebnf-LZEXJU2U-DzpHhtTH-Ca4CUyup.js +0 -1
- package/dist/assets/railroad-peg-WCYAUIDC-B2CHCTyG-DW1BPRzc.js +0 -1
- package/dist/assets/stateDiagram-v2-MP3YSRHH-DnOa-Otc-CJvYdnZ6.js +0 -1
- package/dist/assets/swimlanesDiagram-VR7AAH4N-ZLUyNmnU-BUVjUqff.js +0 -8
- package/dist/assets/treeView-Q6P3EWNA-BdvZ0_C5-DXP8JL2N.js +0 -1
- package/dist/assets/treemap-WGGIJYW6-CIJLPQlC-DfNE0Ylm.js +0 -1
- package/dist/assets/wardley-WFR3VGLG-CKqtFD8V-Bq9rf08k.js +0 -1
package/README.ja.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# MulmoTerminal
|
|
2
2
|
|
|
3
|
-
[English](README.md) · **日本語** · [简体中文](README.zh.md)
|
|
3
|
+
[English](README.md) · **日本語** · [简体中文](README.zh.md) · [繁體中文](README.zh-TW.md) · [한국어](README.ko.md)
|
|
4
4
|
|
|
5
5
|
**コーディングエージェントのセッションを並列で走らせ、どれが自分を待っているかを見る。**
|
|
6
6
|
|
|
@@ -40,7 +40,7 @@ MulmoTerminal では、すべてのセルが自分の状態を一つのグリッ
|
|
|
40
40
|
作業中(青)、完了(緑)、**あなた待ち**(琥珀)。画面外のセルが琥珀になれば音が鳴ります。
|
|
41
41
|
さらに**1セッション1行の cockpit roster** があるので、1つに答えている間も残り4つを見失いません。
|
|
42
42
|
|
|
43
|
-
tmux が入っていればその**上で**動き、[再起動を越えて残ります](
|
|
43
|
+
tmux が入っていればその**上で**動き、[再起動を越えて残ります](README.md#session-persistence-tmux)。
|
|
44
44
|
|
|
45
45
|
## なぜ欲しくなるか
|
|
46
46
|
|
package/README.ko.md
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# MulmoTerminal
|
|
2
|
+
|
|
3
|
+
[English](README.md) · [日本語](README.ja.md) · [简体中文](README.zh.md) · [繁體中文](README.zh-TW.md) · **한국어**
|
|
4
|
+
|
|
5
|
+
**여러 코딩 에이전트 세션을 나란히 돌리고 —— 어느 것이 당신을 기다리는지 한눈에.**
|
|
6
|
+
|
|
7
|
+
**병렬 AI 코딩 에이전트**를 위한 **브라우저 터미널**입니다. 여러 세션이 한 칸씩 나란히 놓이고,
|
|
8
|
+
**당신을 기다리는 것이 색으로 드러납니다**. 기본은 **Claude Code**이고, 여섯 개의 CLI가 똑같이
|
|
9
|
+
일급 시민입니다 —— Codex, Antigravity, Grok, Muse, GitHub Copilot CLI, Cursor CLI.
|
|
10
|
+
에이전트 하나로 하는 vibe coding이라면 shell 하나로 충분합니다. 이 도구는 **여러 개를 동시에 돌리다가
|
|
11
|
+
누가 당신을 기다리는지 분간이 안 될 때**를 위한 것입니다. 세션은 새로고침을 견디고(tmux),
|
|
12
|
+
작업은 **git worktree**에 격리되며, 한 턴이 끝나면 **휴대폰으로 푸시**합니다.
|
|
13
|
+
|
|
14
|
+
**모든 칸이 진짜 pty입니다.** `htop`, `lazygit`, 개발 서버, Claude Code —— 여기서는 전부 같은 종류입니다.
|
|
15
|
+
그래서 "worktree 하나에 세션 하나"라는 제한은 **에이전트에만** 걸리고, shell이나 `yarn dev`는
|
|
16
|
+
일하고 있는 에이전트와 같은 worktree에 함께 있어도 됩니다.
|
|
17
|
+
|
|
18
|
+
## 데모
|
|
19
|
+
|
|
20
|
+

|
|
21
|
+
|
|
22
|
+
*실제로 돌고 있는 그리드 —— 각 칸이 **도는 중**, **끝남**, **당신을 기다림** 중 하나로 표시됩니다.*
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx mulmoterminal@latest # http://localhost:34567 에서 띄우고 브라우저를 엽니다
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**Node 22.12 이상**과, `PATH`에 있고 로그인된
|
|
29
|
+
[`claude`](https://claude.com/claude-code) CLI가 필요합니다.
|
|
30
|
+
`npx mulmoterminal@latest init`이 무엇이 빠졌는지 알려 줍니다.
|
|
31
|
+
|
|
32
|
+
### tmux + iTerm 분할 창으로는 안 되나요?
|
|
33
|
+
|
|
34
|
+
병렬로 띄우는 것 자체는 원래 어렵지 않고, tmux로도 됩니다. 놓치는 것은
|
|
35
|
+
**다섯 중에 어느 것이 당신을 기다리는가**입니다. 창 하나는 불투명합니다.
|
|
36
|
+
도는 중인지, 끝났는지, 권한 확인에서 멈춰 있는지 —— 읽어 보기 전에는 구분이 안 됩니다.
|
|
37
|
+
|
|
38
|
+
MulmoTerminal에서는 각 칸이 자기 상태를 같은 그리드에 보고합니다 ——
|
|
39
|
+
도는 중(파랑), 끝남(초록), **당신을 기다림**(호박색). 화면 밖 칸이 호박색으로 바뀌면 소리가 납니다.
|
|
40
|
+
거기에 **세션마다 한 줄인 cockpit roster**가 있어서, 그중 하나에 답하는 동안에도
|
|
41
|
+
나머지 넷의 자리를 놓치지 않습니다.
|
|
42
|
+
|
|
43
|
+
tmux가 깔려 있으면 그 **위에서** 돌고, [재시작도 견딥니다](README.md#session-persistence-tmux).
|
|
44
|
+
|
|
45
|
+
## 왜 쓰게 되는가
|
|
46
|
+
|
|
47
|
+
- **모든 에이전트를 한눈에.** 상태에 따라 색이 입혀진 세션 그리드 —— 도는 중(파랑),
|
|
48
|
+
**권한에 막힘 / 당신을 기다림**(호박색), **끝났지만 아직 안 읽음**(파랑), 유휴.
|
|
49
|
+
알림음과 툴바 카운트까지 더해져, 화면 밖에서 멈춘 에이전트가 그냥 지나가지 않습니다.
|
|
50
|
+
터미널 하나를 지켜보는 대신 열 개를 감독하게 됩니다. 하나를 확대해도 **cockpit roster**가
|
|
51
|
+
나머지를 시야에 남겨 둡니다 —— 세션마다 한 줄의 글: AI 요약, 직전 prompt, 최신 답변,
|
|
52
|
+
그리고 브랜치의 **PR 단계**(draft / CI 실패 / ready / merged).
|
|
53
|
+
- **터미널만이 아니라, 에이전트를 위한 GUI.** 터미널 옆의 **Canvas** 패널이 에이전트가 MCP로 내놓은 것 ——
|
|
54
|
+
**문서, 폼, 차트, 생성한 이미지, HTML, collection 카드** —— 를 각각 전용 플러그인으로 그립니다.
|
|
55
|
+
에이전트가 글자를 찍어 주는 대신 화면을 건네주는 셈입니다.
|
|
56
|
+
- **어디에 있든 다시 불려 옵니다.** 작업이 끝나거나 입력을 기다릴 때 **휴대폰으로 푸시**하고,
|
|
57
|
+
**RemoteHost**와 함께라면 휴대폰에서 세션을 보고 한 번 눌러 답할 수 있습니다
|
|
58
|
+
(**yes / no / continue**). 자리를 뜨고, 불려 오고, 돌아옵니다.
|
|
59
|
+
- **재시작해도 아무것도 잃지 않습니다.** `tmux`가 있으면 서버가 죽거나, 다시 시작하거나,
|
|
60
|
+
`node --watch`가 다시 읽어도 모든 세션이 살아 있습니다 —— 절반쯤 돌던 에이전트, 오래 걸리는 빌드,
|
|
61
|
+
개발 서버가 계속 돌고, 돌아오면 알아서 다시 이어집니다.
|
|
62
|
+
- **그리드를 떠나지 않고 배포까지.** 저장소 칸마다 **git 브랜치 라벨**이 붙고, 한 번에
|
|
63
|
+
**git worktree**로 격리하고, **diff** 패널을 열고, **commit / push / PR 열기**까지 합니다.
|
|
64
|
+
여러 에이전트가 같은 저장소에서 서로 방해하지 않고 일할 수 있습니다.
|
|
65
|
+
- **얼마를 썼는지 압니다.** 세션마다 **컨텍스트 %**, **token**, **추정 $**, 도구 호출의 **타임라인**,
|
|
66
|
+
그리고 셀 제목과 명령 출력의 **AI 요약** —— 벽을 가득 채운 병렬 에이전트를 읽을 수 있게 유지합니다.
|
|
67
|
+
- **당신의 방식대로.** 디렉터리마다 **테마, 색, 이름 배지**(`prod`는 빨강, `staging`은 호박색),
|
|
68
|
+
설정 가능한 헤더, 사용자 알림음, 그리고 칸에서 바로 프로젝트 스크립트와 `.claude/skills`,
|
|
69
|
+
deck을 띄우는 Run / Skill / Mulmo 메뉴.
|
|
70
|
+
|
|
71
|
+

|
|
72
|
+
|
|
73
|
+
*그리드는 **병렬 에이전트의 조종석**입니다. 각 칸의 헤더에는 판단에 필요한 것이 놓여 있습니다 ——
|
|
74
|
+
**모델 · 컨텍스트 %**, **token 수**(`⇡in ⇣out`), **git 브랜치 / 변경** 라벨,
|
|
75
|
+
그리고 이 에이전트가 지금 무엇을 하는지에 대한 AI 요약. **칸의 테두리 색이 상태**이고,
|
|
76
|
+
화면 밖에서 멈춘 칸은 소리로 당신을 불러옵니다.*
|
|
77
|
+
|
|
78
|
+
### 안에서는 무슨 일이 일어나는가
|
|
79
|
+
|
|
80
|
+
각 세션은 서버에서 진짜 PTY로 돕니다(에이전트 CLI를 의사 터미널에 넣습니다).
|
|
81
|
+
그리고 WebSocket을 통해 브라우저의 [xterm.js](https://xtermjs.org/) 터미널로 흘러갑니다.
|
|
82
|
+
|
|
83
|
+
**cockpit roster**는 모든 세션을 나열하고, 어느 것이 **도는 중**(에이전트가 생각하는 중)인지,
|
|
84
|
+
어느 것이 **당신을 기다리는지**(권한 확인이나 질문 —— 호박색 점, 답하기 전에는 더 나아가지 않습니다),
|
|
85
|
+
어느 것이 **끝났지만 아직 읽지 않았는지**(초록색 점)를 실시간으로 비춥니다. 이것은 **서버가 세션을 띄울 때
|
|
86
|
+
주입하는 Claude / Codex activity hook**에서 오는 것이지, 화면의 글자를 파싱해서 얻는 것이 아닙니다.
|
|
87
|
+
|
|
88
|
+
> 여기가 핵심입니다. 터미널 안에서 "권한 확인에 막힘"과 "아직 생각하는 중"은 **똑같아 보입니다** ——
|
|
89
|
+
> 둘 다 그냥 출력이 멎은 상태입니다. 화면을 읽어서는 구분되지 않고, hook은 구분합니다.
|
|
90
|
+
>
|
|
91
|
+
> (Codex는 "입력 대기"를 보고하지 않습니다. 확인 창을 자기 TUI 안에 그리고 rollout 파일에 남기지
|
|
92
|
+
> 않기 때문입니다. 그래서 Codex에는 "도는 중 / 끝남" 두 가지 상태만 있습니다.)
|
|
93
|
+
|
|
94
|
+
## 옮겨 온 사람들의 말
|
|
95
|
+
|
|
96
|
+
> 아래는 IDE나 분할 터미널에서 옮겨 온 사용자들의 피드백이며, 벤치마크도 아니고
|
|
97
|
+
> 우리가 측정한 결론도 아닙니다. 당신의 환경은 다를 수 있습니다.
|
|
98
|
+
|
|
99
|
+
**"더 이상 메모리를 잡아먹지 않는다"** —— IDE 창을 여러 개 띄워 에이전트를 격리하는 것은 비쌉니다.
|
|
100
|
+
창마다 편집기, 언어 서버, 확장, 파일 감시를 제 몫씩 들고 옵니다. 어떤 사용자는
|
|
101
|
+
**64GB 기기도 그 부하에서는 버벅였다**고 했고, 옮긴 뒤에는 괜찮아졌다고 했습니다.
|
|
102
|
+
여기서 에이전트는 서버의 PTY이고, 화면은 브라우저 탭입니다.
|
|
103
|
+
|
|
104
|
+
**"이제 엉뚱한 에이전트에 답하지 않는다"** —— 글자가 흐르는 창 여섯 개는 생김새가 똑같습니다.
|
|
105
|
+
어떤 사용자는 **다른 에이전트의 터미널에 답을 쳐 넣었고**, 애초에 그것에 무엇을 시켰는지조차
|
|
106
|
+
기억나지 않았다고 했습니다. 주의력의 문제가 아니라, 똑같은 창 N개가 머릿속에 N개의 맥락을
|
|
107
|
+
들고 있으라는 뜻이기 때문입니다. 상태 색, 이름 배지, 디렉터리별 색이 그 일을 머릿속에서 화면으로 옮깁니다.
|
|
108
|
+
|
|
109
|
+
**"많이 보기와 하나를 읽기가 더는 양자택일이 아니다"** —— 터미널을 여섯으로 쪼개면
|
|
110
|
+
각 창이 긴 답변 하나를 다 읽기에도 작습니다. 그래서 에이전트를 하나 더할 때마다
|
|
111
|
+
읽기 경험이 나빠지는 것을 말없이 받아들이게 됩니다. **그리드 ↔ 확대**는 그 맞바꿈을 없앱니다.
|
|
112
|
+
먼저 전부 보고, 하나를 확대해 제대로 읽으며, 그동안에도 cockpit roster가 나머지를 글로 남겨 둡니다.
|
|
113
|
+
|
|
114
|
+
**"쓰던 세션이 그대로 따라왔다"** —— 세션은 있는 그대로 복원됩니다
|
|
115
|
+
(같은 `claude --resume`, 같은 기록). 원래 쓰던 디렉터리를 가리키면 기록이 거기 있습니다.
|
|
116
|
+
옮길 것도, 다시 만들 것도 없습니다.
|
|
117
|
+
|
|
118
|
+
**에이전트가 열 개는 되어야 본전인 것은 아닙니다.** 어떤 사용자는 **1~3개**를 병렬로 돌릴 때부터
|
|
119
|
+
이미 옮길 만했다고 했습니다. 위의 이점들은 "더 많이 돌린다"가 아니라 "놓치지 않는다"에 대한 것입니다.
|
|
120
|
+
|
|
121
|
+
## 설치와 실행
|
|
122
|
+
|
|
123
|
+
**Node 22.12 이상**과, `PATH`에 있는 아래 CLI들이 필요합니다.
|
|
124
|
+
|
|
125
|
+
| | 도구 | 무엇을 해 주는가 | 설치 |
|
|
126
|
+
| --- | --- | --- | --- |
|
|
127
|
+
| **필수** | [`claude`](https://claude.com/claude-code) | 모든 Claude 세션. 이 앱은 그것의 조종석입니다 | `npm i -g @anthropic-ai/claude-code`, 그다음 `claude`를 한 번 띄워 로그인 |
|
|
128
|
+
| **필수** | `git` | worktree 격리, 칸마다의 브랜치 / 저장 안 된 점 / diff, PR footer | `brew install git` · `sudo apt install git` · Windows: [git-scm.com](https://git-scm.com/download/win) |
|
|
129
|
+
| **필수** | `gh` | 저장소를 가로지르는 **PR & Issue** 화면과 한 번에 PR 열기. 당신의 `gh` 로그인을 쓰고 토큰을 저장하지 않습니다 | [cli.github.com](https://cli.github.com), 그다음 `gh auth login` |
|
|
130
|
+
| 선택 | `glab` | **GitLab** 프로젝트에 같은 것을. 자체 호스팅 인스턴스도 지원 | `brew install glab`, 그다음 `glab auth login` |
|
|
131
|
+
| 권장 | `tmux` | **세션 지속** —— 터미널이 서버 재시작을 견딥니다 | `brew install tmux` · `sudo apt install tmux` · Windows에는 네이티브 빌드가 없습니다(일반 PTY로 되돌아갑니다) |
|
|
132
|
+
| 선택 | `codex` | 칸에서 **Codex 세션** 돌리기 | `npm i -g @openai/codex` |
|
|
133
|
+
| 선택 | `ffmpeg` | mulmo-script 패널에서 영상 렌더링 | `brew install ffmpeg` · `sudo apt install ffmpeg` |
|
|
134
|
+
| 선택 | `ollama` | 완전히 로컬인 모델로 Claude Code 돌리기 | [ollama.com/download](https://ollama.com/download) |
|
|
135
|
+
|
|
136
|
+
필수가 아닌 줄이 빠져 있어도 서버는 그대로 뜨고, 그 줄의 기능만 빠지며, 화면이 그 사실을 알려 줍니다.
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
npx mulmoterminal@latest # http://localhost:34567 에서 띄우고 브라우저를 엽니다
|
|
140
|
+
# 또는 전역으로 설치:
|
|
141
|
+
npm install -g mulmoterminal
|
|
142
|
+
mulmoterminal
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**멈추는 법.** 띄운 터미널에서 `Ctrl+C`를 누르세요. 그 터미널을 못 찾겠다면 브라우저에서
|
|
146
|
+
**Settings → Quit MulmoTerminal**을 쓰거나, 아무 터미널에서나
|
|
147
|
+
**`npx mulmoterminal@latest stop`**을 실행하세요. `tmux`가 깔려 있으면 에이전트 세션은 살아남아
|
|
148
|
+
**Settings → Sessions that survived a restart**에서 돌아옵니다.
|
|
149
|
+
|
|
150
|
+
**첫 설정(선택).** `npx mulmoterminal@latest init`이 환경을 점검하고,
|
|
151
|
+
당신의 Claude Code 기록에서 런처의 **디렉터리 프리셋**을 만들어
|
|
152
|
+
`~/.mulmoterminal/config.json`에 씁니다. **멱등**이므로 프리셋을 새로 고치고 싶으면
|
|
153
|
+
언제든 다시 돌려도 됩니다.
|
|
154
|
+
|
|
155
|
+
## 문서
|
|
156
|
+
|
|
157
|
+
**[receptron.github.io/mulmoterminal](https://receptron.github.io/mulmoterminal/)**
|
|
158
|
+
|
|
159
|
+
- **사용자 가이드(영문):** [English](https://receptron.github.io/mulmoterminal/guide/en/) ——
|
|
160
|
+
그리드 화면, 일상 작업 흐름, 전체 기능 목록, 설정, 휴대폰 푸시
|
|
161
|
+
- **사용자 가이드(일문):** [日本語](https://receptron.github.io/mulmoterminal/guide/ja/)
|
|
162
|
+
- **소식:** 새 버전과 새 기능은 X에 올라옵니다 ——
|
|
163
|
+
영문 [@mulmocast](https://x.com/mulmocast), 일문
|
|
164
|
+
[Singularity Society (@SingularitySoci)](https://x.com/SingularitySoci)
|
|
165
|
+
|
|
166
|
+
## 만드는 사람
|
|
167
|
+
|
|
168
|
+
**[receptron](https://github.com/receptron)** ——
|
|
169
|
+
마이크로소프트에서 **Windows 95**의 소프트웨어 아키텍트였던
|
|
170
|
+
**[中島聡 (Satoshi Nakajima)](https://x.com/snakajima)**와
|
|
171
|
+
**[有本勇 (Isamu Arimoto)](https://github.com/isamu)**,
|
|
172
|
+
즉 **[GraphAI](https://github.com/receptron/graphai)**를 만든 바로 그 둘입니다.
|
|
173
|
+
|
|
174
|
+
## 라이선스
|
|
175
|
+
|
|
176
|
+
MIT
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
> **이 문서는 영문 README 앞부분의 제품 소개와 설치에 해당합니다.**
|
|
181
|
+
> 설정, 아키텍처, 스크립트, skills, deck, worktree와 PR, 원격 호스트 같은 세부는
|
|
182
|
+
> [영문 README](README.md)와 [사용자 가이드](https://receptron.github.io/mulmoterminal/guide/en/)를 보세요.
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# MulmoTerminal
|
|
2
2
|
|
|
3
|
-
**English** · [日本語](README.ja.md) · [简体中文](README.zh.md)
|
|
3
|
+
**English** · [日本語](README.ja.md) · [简体中文](README.zh.md) · [繁體中文](README.zh-TW.md) · [한국어](README.ko.md)
|
|
4
4
|
|
|
5
5
|
**Run multiple coding-agent sessions in parallel — and see which one needs you.**
|
|
6
6
|
|
|
@@ -97,7 +97,8 @@ the same two behind **[GraphAI](https://github.com/receptron/graphai)**. [More
|
|
|
97
97
|
tap (**yes / no / continue**) from the phone itself — walk away, get pinged, jump back in.
|
|
98
98
|
- **Nothing is lost on a restart.** With `tmux`, every session survives a server crash,
|
|
99
99
|
restart, or `node --watch` reload — a mid-turn agent, a long build, a dev server all keep
|
|
100
|
-
running and reattach when you come back.
|
|
100
|
+
running and reattach when you come back. A crashed server is restarted for you, so the
|
|
101
|
+
tab you left open finds it again.
|
|
101
102
|
- **Ship without leaving the grid.** Each repo cell shows a **git branch chip**, isolates
|
|
102
103
|
work in a one-click **git worktree**, opens a **diff** panel, and does **commit / push /
|
|
103
104
|
open PR** — so several agents can work the same repo without colliding.
|
|
@@ -169,7 +170,7 @@ than as bytes (files within the session's working directory only):
|
|
|
169
170
|
|
|
170
171
|
| A clicked … | opens as |
|
|
171
172
|
|---|---|
|
|
172
|
-
| `.md` `.markdown` | **rendered** markdown in a new tab — the same sandboxed `…/md` HTML the Files preview
|
|
173
|
+
| `.md` `.markdown` | **rendered** markdown in a new tab — the same sandboxed `…/md` HTML the Files preview renders, minus the one script the preview needs to report where you are reading. It follows your system light/dark setting, since under the sandbox CSP it can't ask the app which theme is on |
|
|
173
174
|
| `.json` | **indented** in a new tab (Chrome and Safari otherwise show one long line) |
|
|
174
175
|
| `.csv` `.tsv` | a **table** in a new tab, with a sticky header that scrolls inside its own box |
|
|
175
176
|
| source, config, logs, and `.txt` — 46 extensions | the app's own **Files** view (`/files?path=`), where CodeMirror highlights it, the tree is right there, and it can be edited |
|
|
@@ -629,6 +630,18 @@ A long build, a dev server, or a mid-turn Claude session all survive `node --wat
|
|
|
629
630
|
reloads and crashes. It uses its **own** tmux server (`-L mulmoterminal`) and config, so
|
|
630
631
|
it never touches your personal tmux sessions or keybindings.
|
|
631
632
|
|
|
633
|
+
**And the server comes back by itself.** `npx mulmoterminal` supervises the server it
|
|
634
|
+
started: a crash is restarted with a short backoff, so the browser tab reconnects to the
|
|
635
|
+
sessions tmux kept rather than to a dead port — which matters most from a phone, where
|
|
636
|
+
there is no terminal to start it again in. A stop you asked for is still a stop:
|
|
637
|
+
`mulmoterminal stop`, the Stop button, Ctrl+C and `kill` all end it. A server that never
|
|
638
|
+
managed to bind is not restarted either — the reason it printed is the answer, and
|
|
639
|
+
retrying would bury it. Repeated failures give up rather than respawn forever.
|
|
640
|
+
|
|
641
|
+
**Not on Windows**, where it is not yet possible: Node has no real signals there, so every
|
|
642
|
+
way of stopping the server terminates it outright, and the launcher cannot tell that from
|
|
643
|
+
a crash. Windows keeps the old behaviour — the launcher ends when its server does.
|
|
644
|
+
|
|
632
645
|
**No tmux? No problem** — terminals fall back to plain (non-persistent) PTYs, exactly as
|
|
633
646
|
before. An explicit close (a cell's ✕) ends the tmux session; a machine reboot does not
|
|
634
647
|
survive (tmux itself is gone). Command-cell scripts are ephemeral and not persisted.
|
|
@@ -1251,8 +1264,10 @@ on, and how far down the tree was scrolled. The top line matters on its own —
|
|
|
1251
1264
|
neither the selection nor the caret, so someone reading without clicking would otherwise come back
|
|
1252
1265
|
to the top of a file they were in the middle of. The caret is kept as a line rather than a scroll offset, so it survives
|
|
1253
1266
|
the pane being a different width next time, and a line past the end of a file that has since been
|
|
1254
|
-
edited lands on the nearest real one. The Markdown preview's own scroll position
|
|
1255
|
-
|
|
1267
|
+
edited lands on the nearest real one. The Markdown preview's own scroll position comes back too,
|
|
1268
|
+
and as a pixel offset rather than a line, because a rendered document has no lines in it. The app
|
|
1269
|
+
still cannot read that frame — it stays sandboxed with no `allow-same-origin`, so the position is
|
|
1270
|
+
reported BY the document, through the one script the server is allowed to put in it.
|
|
1256
1271
|
|
|
1257
1272
|
**It also paints before it has finished reading.** The last listing of each directory is kept, so
|
|
1258
1273
|
opening the pane on one you have been to before shows that tree at once and swaps in what the
|
package/README.zh-TW.md
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# MulmoTerminal
|
|
2
|
+
|
|
3
|
+
[English](README.md) · [日本語](README.ja.md) · [简体中文](README.zh.md) · **繁體中文** · [한국어](README.ko.md)
|
|
4
|
+
|
|
5
|
+
**並行跑多個編碼代理程式的工作階段 —— 一眼看出哪一個在等你。**
|
|
6
|
+
|
|
7
|
+
一個給**並行 AI 編碼代理程式**用的**瀏覽器終端機**:多個工作階段並排,每個佔一格,
|
|
8
|
+
**正在等你的那一個用顏色標出來**。預設是 **Claude Code**,另有六個 CLI 同為一等公民 ——
|
|
9
|
+
Codex、Antigravity、Grok、Muse、GitHub Copilot CLI、Cursor CLI。單一代理程式的 vibe coding 一個 shell 就夠了,
|
|
10
|
+
這個工具是給**同時跑好幾個、然後分不清誰在等你**的時候用的。工作階段能撐過重新整理(tmux),
|
|
11
|
+
工作隔離在 **git worktree** 裡,一輪結束時**推播到手機**。
|
|
12
|
+
|
|
13
|
+
**每一格都是真正的 pty。** `htop`、`lazygit`、開發伺服器、Claude Code —— 在這裡是同一類東西。
|
|
14
|
+
所以「每個 worktree 一個工作階段」的限制**只對代理程式生效**,一個 shell 或 `yarn dev`
|
|
15
|
+
可以和正在幹活的代理程式待在同一個 worktree 裡。
|
|
16
|
+
|
|
17
|
+
## 展示
|
|
18
|
+
|
|
19
|
+

|
|
20
|
+
|
|
21
|
+
*實際執行中的網格 —— 每一格標為 **執行中**、**跑完了** 或 **等你**。*
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npx mulmoterminal@latest # 在 http://localhost:34567 啟動並開啟瀏覽器
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
需要 **Node 22.12 以上**,以及 `PATH` 上已登入的
|
|
28
|
+
[`claude`](https://claude.com/claude-code) CLI。
|
|
29
|
+
`npx mulmoterminal@latest init` 會告訴你缺了什麼。
|
|
30
|
+
|
|
31
|
+
### 為什麼不用 tmux + iTerm 分割窗格?
|
|
32
|
+
|
|
33
|
+
並行地跑起來從來不是難處,tmux 就做得到。丟掉的是**五個裡面哪一個在等你**。
|
|
34
|
+
一個窗格是不透明的:執行中、跑完了、卡在權限確認上 —— 不讀一遍就分不出來。
|
|
35
|
+
|
|
36
|
+
在 MulmoTerminal 裡,每一格都把自己的狀態回報給同一個網格 ——
|
|
37
|
+
執行中(藍)、跑完了(綠)、**等你**(琥珀)。螢幕外的格子轉琥珀色時會響一聲。
|
|
38
|
+
還有一個**每個工作階段一列的 cockpit roster**,所以你在回答其中一個的時候,
|
|
39
|
+
不會弄丟另外四個的位置。
|
|
40
|
+
|
|
41
|
+
裝了 tmux 的話它就跑在 tmux **之上**,[重啟也不會丟](README.md#session-persistence-tmux)。
|
|
42
|
+
|
|
43
|
+
## 為什麼你會想要它
|
|
44
|
+
|
|
45
|
+
- **一眼看完所有代理程式。** 依狀態著色的工作階段網格 —— 執行中(藍)、**被權限擋住 / 等你**(琥珀)、
|
|
46
|
+
**跑完但還沒看**(藍)、閒置。配上提示音和工具列計數,螢幕外卡住的代理程式不會溜過去。
|
|
47
|
+
不必再盯著一個終端機,改成監督十個。放大其中一個,**cockpit roster** 仍然讓其餘的留在視野裡 ——
|
|
48
|
+
每個工作階段一列文字:AI 摘要、上一則 prompt、最新回覆、以及分支的 **PR 階段**
|
|
49
|
+
(draft / CI 失敗 / ready / merged)。
|
|
50
|
+
- **給代理程式的 GUI,而不只是終端機。** 終端機旁邊的 **Canvas** 窗格會把代理程式透過 MCP 產出的東西 ——
|
|
51
|
+
**文件、表單、圖表、產生的圖片、HTML、collection 卡片** —— 各自用專屬外掛畫出來。
|
|
52
|
+
代理程式不是印一串文字給你,而是遞給你一個介面。
|
|
53
|
+
- **人在哪裡都能被叫回來。** 工作完成或等待輸入時會**推播到手機**,搭配 **RemoteHost**
|
|
54
|
+
還能在手機上看工作階段、點一下就回答(**yes / no / continue**)。走開、被叫、回來。
|
|
55
|
+
- **重啟不丟任何東西。** 有 `tmux` 的話,伺服器當掉、重啟、`node --watch` 重新載入,
|
|
56
|
+
每個工作階段都活著 —— 跑到一半的代理程式、長時間的建置、開發伺服器都繼續跑,回來時自動接上。
|
|
57
|
+
- **不離開網格就能發布。** 每個儲存庫格子帶 **git 分支標籤**,一鍵隔離到 **git worktree**,
|
|
58
|
+
開啟 **diff** 窗格,完成 **commit / push / 開 PR**。多個代理程式可以在同一個儲存庫裡互不干擾。
|
|
59
|
+
- **知道花了多少錢。** 每個工作階段的**上下文 %**、**token**、**預估 $**,工具呼叫的**時間軸**,
|
|
60
|
+
以及格子標題和指令輸出的 **AI 摘要** —— 讓一整面牆的並行代理程式保持可讀。
|
|
61
|
+
- **照你的習慣來。** 依目錄設定**主題、顏色和名稱徽章**(`prod` 紅色、`staging` 琥珀色)、
|
|
62
|
+
可設定的標頭、自訂提示音,以及在格子裡直接啟動專案指令碼、`.claude/skills` 和 deck 的
|
|
63
|
+
Run / Skill / Mulmo 選單。
|
|
64
|
+
|
|
65
|
+

|
|
66
|
+
|
|
67
|
+
*網格就是**並行代理程式的駕駛艙**。每個格子的標頭擺著你做判斷需要的東西 ——
|
|
68
|
+
**模型 · 上下文 %**、**token 數**(`⇡in ⇣out`)、**git 分支 / 變更**標籤,
|
|
69
|
+
以及這個代理程式正在做什麼的 AI 摘要。**格子的邊框顏色代表狀態**,螢幕外卡住的格子會用聲音把你叫回來。*
|
|
70
|
+
|
|
71
|
+
### 底層是怎麼回事
|
|
72
|
+
|
|
73
|
+
每個工作階段在伺服器上以真正的 PTY 執行(把代理程式 CLI 放進一個偽終端機),
|
|
74
|
+
透過 WebSocket 串流到瀏覽器裡的 [xterm.js](https://xtermjs.org/) 終端機。
|
|
75
|
+
|
|
76
|
+
**cockpit roster** 列出所有工作階段,並即時反映哪些**執行中**(代理程式在思考)、
|
|
77
|
+
哪些**在等你**(權限確認或提問 —— 琥珀色圓點,你不答它就不往下走)、
|
|
78
|
+
哪些**跑完了但你還沒看**(綠色圓點)。這些來自**伺服器在啟動工作階段時注入的
|
|
79
|
+
Claude / Codex activity hook**,不是去解析螢幕上的文字。
|
|
80
|
+
|
|
81
|
+
> 這是關鍵。在終端機裡,「卡在權限確認上」和「還在思考」**看起來一模一樣** ——
|
|
82
|
+
> 兩者都只是不再輸出了。讀螢幕分不出來,hook 可以。
|
|
83
|
+
>
|
|
84
|
+
> (Codex 不回報「等待輸入」:它的確認框畫在自己的 TUI 裡,不會進 rollout 檔。
|
|
85
|
+
> 所以對 Codex 來說只有「執行中 / 跑完了」兩種狀態。)
|
|
86
|
+
|
|
87
|
+
## 換過來的人怎麼說
|
|
88
|
+
|
|
89
|
+
> 以下是從 IDE 或分割終端機轉過來的使用者的回饋,不是基準測試,也不是我們量測過的結論。
|
|
90
|
+
> 你的環境可能不同。
|
|
91
|
+
|
|
92
|
+
**「它不再吃我的記憶體了」** —— 靠開多個 IDE 視窗來隔離代理程式的代價很高:
|
|
93
|
+
每個視窗都帶上自己的編輯器、語言伺服器、擴充功能和檔案監看。有使用者回報
|
|
94
|
+
**64GB 的機器在那種負載下會卡**,換過來之後就順了。在這裡代理程式是伺服器上的 PTY,
|
|
95
|
+
介面是瀏覽器分頁。
|
|
96
|
+
|
|
97
|
+
**「我不再回錯代理程式了」** —— 六個捲動文字的窗格長得一模一樣。
|
|
98
|
+
有使用者描述過**把回覆打進了另一個代理程式的終端機**,而且想不起來最初讓它做什麼。
|
|
99
|
+
問題不在注意力,而在於 N 個相同的窗格意味著要在腦子裡保持 N 份上下文。
|
|
100
|
+
狀態著色、名稱徽章和依目錄的顏色,把這件事從腦子裡搬到了螢幕上。
|
|
101
|
+
|
|
102
|
+
**「看很多和讀一個不再是二選一」** —— 把終端機切成六份,每個窗格都小到讀不完一段長回覆。
|
|
103
|
+
於是每加一個代理程式,你就默默接受更差的閱讀體驗。
|
|
104
|
+
**網格 ↔ 放大**去掉了這個取捨:先看全部,再把一個放大好好讀,
|
|
105
|
+
其間 cockpit roster 仍然以文字形式保留其餘的。
|
|
106
|
+
|
|
107
|
+
**「我原有的工作階段跟著一起過來了」** —— 工作階段原樣恢復(同樣的 `claude --resume`,同樣的紀錄)。
|
|
108
|
+
指向一個你本來就在用的目錄,歷史就在那裡。不必搬遷,也不必重做。
|
|
109
|
+
|
|
110
|
+
**不需要十個代理程式才划算。** 有使用者回報在並行 **1 到 3** 個工作階段時就已經值得換過來。
|
|
111
|
+
上面這些好處講的是「不再跟丟」,不是「跑得更多」。
|
|
112
|
+
|
|
113
|
+
## 安裝與執行
|
|
114
|
+
|
|
115
|
+
需要 **Node 22.12 以上**,以及 `PATH` 上的這些 CLI:
|
|
116
|
+
|
|
117
|
+
| | 工具 | 它帶來什麼 | 安裝 |
|
|
118
|
+
| --- | --- | --- | --- |
|
|
119
|
+
| **必要** | [`claude`](https://claude.com/claude-code) | 所有 Claude 工作階段,本應用程式是它的駕駛艙 | `npm i -g @anthropic-ai/claude-code`,然後跑一次 `claude` 登入 |
|
|
120
|
+
| **必要** | `git` | worktree 隔離、每格的分支 / 未儲存點 / diff、PR footer | `brew install git` · `sudo apt install git` · Windows: [git-scm.com](https://git-scm.com/download/win) |
|
|
121
|
+
| **必要** | `gh` | 跨儲存庫的 **PR & Issue** 檢視和一鍵開 PR。用你自己的 `gh` 登入,不存 token | [cli.github.com](https://cli.github.com),然後 `gh auth login` |
|
|
122
|
+
| 選用 | `glab` | 對 **GitLab** 專案做同樣的事,支援自架執行個體 | `brew install glab`,然後 `glab auth login` |
|
|
123
|
+
| 建議 | `tmux` | **工作階段持續存在** —— 終端機能撐過伺服器重啟 | `brew install tmux` · `sudo apt install tmux` · Windows 沒有原生版本(退回一般 PTY) |
|
|
124
|
+
| 選用 | `codex` | 在格子裡跑 **Codex 工作階段** | `npm i -g @openai/codex` |
|
|
125
|
+
| 選用 | `ffmpeg` | 從 mulmo-script 窗格算繪影片 | `brew install ffmpeg` · `sudo apt install ffmpeg` |
|
|
126
|
+
| 選用 | `ollama` | 用完全在本機的模型跑 Claude Code | [ollama.com/download](https://ollama.com/download) |
|
|
127
|
+
|
|
128
|
+
缺少非必要的那幾列,伺服器照樣啟動,只是少掉那一列的功能,而且介面會說明。
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
npx mulmoterminal@latest # 在 http://localhost:34567 啟動並開啟瀏覽器
|
|
132
|
+
# 或者全域安裝:
|
|
133
|
+
npm install -g mulmoterminal
|
|
134
|
+
mulmoterminal
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**怎麼停。** 在啟動它的終端機按 `Ctrl+C`;找不到那個終端機的話,用瀏覽器裡的
|
|
138
|
+
**Settings → Quit MulmoTerminal**,或者在任意終端機跑 **`npx mulmoterminal@latest stop`**。
|
|
139
|
+
裝了 `tmux` 的話代理程式的工作階段會活下來,從 **Settings → Sessions that survived a restart** 回來。
|
|
140
|
+
|
|
141
|
+
**第一次設定(選用)。** `npx mulmoterminal@latest init` 會檢查環境,
|
|
142
|
+
從你的 Claude Code 歷史裡產生啟動器的**目錄預設組**,並寫入 `~/.mulmoterminal/config.json`。
|
|
143
|
+
它是**冪等的**,想更新預設組隨時可以再跑一次。
|
|
144
|
+
|
|
145
|
+
## 文件
|
|
146
|
+
|
|
147
|
+
**[receptron.github.io/mulmoterminal](https://receptron.github.io/mulmoterminal/)**
|
|
148
|
+
|
|
149
|
+
- **使用者指南(英文):** [English](https://receptron.github.io/mulmoterminal/guide/en/) ——
|
|
150
|
+
網格檢視、日常工作流程、完整功能列表、設定、手機推播
|
|
151
|
+
- **使用者指南(日文):** [日本語](https://receptron.github.io/mulmoterminal/guide/ja/)
|
|
152
|
+
- **更新:** 新版本和新功能在 X 上發布 ——
|
|
153
|
+
英文 [@mulmocast](https://x.com/mulmocast),日文
|
|
154
|
+
[Singularity Society (@SingularitySoci)](https://x.com/SingularitySoci)
|
|
155
|
+
|
|
156
|
+
## 誰在做
|
|
157
|
+
|
|
158
|
+
**[receptron](https://github.com/receptron)** ——
|
|
159
|
+
在微軟擔任 **Windows 95** 軟體架構師的
|
|
160
|
+
**[中島聡 (Satoshi Nakajima)](https://x.com/snakajima)**
|
|
161
|
+
和 **[有本勇 (Isamu Arimoto)](https://github.com/isamu)**,
|
|
162
|
+
也就是做 **[GraphAI](https://github.com/receptron/graphai)** 的同一組人。
|
|
163
|
+
|
|
164
|
+
## 授權條款
|
|
165
|
+
|
|
166
|
+
MIT
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
> **本文對應英文 README 開頭的產品介紹與安裝部分。**
|
|
171
|
+
> 設定、架構、指令碼、skills、deck、worktree 與 PR、遠端主機等細節,
|
|
172
|
+
> 請看[英文 README](README.md) 和[使用者指南](https://receptron.github.io/mulmoterminal/guide/en/)。
|
package/README.zh.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# MulmoTerminal
|
|
2
2
|
|
|
3
|
-
[English](README.md) · [日本語](README.ja.md) · **简体中文**
|
|
3
|
+
[English](README.md) · [日本語](README.ja.md) · **简体中文** · [繁體中文](README.zh-TW.md) · [한국어](README.ko.md)
|
|
4
4
|
|
|
5
5
|
**并行跑多个编码智能体会话 —— 一眼看出哪一个在等你。**
|
|
6
6
|
|
|
@@ -38,7 +38,7 @@ npx mulmoterminal@latest # 在 http://localhost:34567 启动并打开浏
|
|
|
38
38
|
还有一个**每个会话一行的 cockpit roster**,所以你在回答其中一个的时候,
|
|
39
39
|
不会丢掉另外四个的位置。
|
|
40
40
|
|
|
41
|
-
装了 tmux 的话它就跑在 tmux **之上**,[重启也不会丢](
|
|
41
|
+
装了 tmux 的话它就跑在 tmux **之上**,[重启也不会丢](README.md#session-persistence-tmux)。
|
|
42
42
|
|
|
43
43
|
## 为什么你会想要它
|
|
44
44
|
|