mulmoterminal 2.7.0 → 2.8.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.
Files changed (169) hide show
  1. package/README.md +67 -17
  2. package/common/bundledSkills.ts +31 -0
  3. package/common/launchAgent.ts +1 -1
  4. package/common/modelPresets.ts +1 -1
  5. package/common/pastedImageTypes.ts +23 -0
  6. package/common/sessionAgent.ts +22 -1
  7. package/dist/assets/{abnfDiagram-VRR7QNED-RjiYivmv-i7KLnuI-.js → abnfDiagram-VRR7QNED-RjiYivmv-rGHffQn8.js} +1 -1
  8. package/dist/assets/architecture-TIHT7OUA-0NsD2xW1-Dg-O9e_V.js +1 -0
  9. package/dist/assets/{architectureDiagram-ZJ3FMSHR-3nWA91tG-CL3Or8CZ.js → architectureDiagram-ZJ3FMSHR-3nWA91tG-ClBqZt07.js} +1 -1
  10. package/dist/assets/{blockDiagram-677ZJIJ3-BPuAJQRW-DFu8zII3.js → blockDiagram-677ZJIJ3-BPuAJQRW-CRpyIN7j.js} +1 -1
  11. package/dist/assets/{c4Diagram-LMCZKHZV-C0LAqQso-CByG3jFJ.js → c4Diagram-LMCZKHZV-C0LAqQso-CP3Nkj32.js} +1 -1
  12. package/dist/assets/channel-7wUqSdoX-Cc3ae2uC.js +1 -0
  13. package/dist/assets/{chunk-32BRIVSS-BRrYpgtb-Dc3x0Hgh.js → chunk-32BRIVSS-BRrYpgtb-bBx9h5ar.js} +1 -1
  14. package/dist/assets/{chunk-52WLFC77-BJ-ss3Xr-D6efVaUm.js → chunk-52WLFC77-BJ-ss3Xr-CJsYFk5u.js} +1 -1
  15. package/dist/assets/{chunk-C7G6YPKG-BZEucKEL-CUdIiVHU.js → chunk-C7G6YPKG-BZEucKEL-CySmS4KO.js} +1 -1
  16. package/dist/assets/{chunk-EX3LRPZG-DLS6FBN1-BH94eoNV.js → chunk-EX3LRPZG-DLS6FBN1-Bd6UgUyI.js} +1 -1
  17. package/dist/assets/{chunk-FWX5IMBZ-DHLSFw1H-Dw8tAp6e.js → chunk-FWX5IMBZ-DHLSFw1H-NTtO_c6Q.js} +2 -2
  18. package/dist/assets/{chunk-HOUHSVGY-Bhlt8hXJ-CEurvfOt.js → chunk-HOUHSVGY-Bhlt8hXJ-CZ6o_X29.js} +1 -1
  19. package/dist/assets/{chunk-ICXQ74PX-DwgHBX_g-DKrDQRbg.js → chunk-ICXQ74PX-DwgHBX_g-CLxX8cQ2.js} +1 -1
  20. package/dist/assets/{chunk-MOJQB5TN-CMZRaeqt-Ch-WBypm.js → chunk-MOJQB5TN-CMZRaeqt-LKJvD71K.js} +1 -1
  21. package/dist/assets/{chunk-OGEWGWER-8Qy4a8b5-BfJ1_Ye1.js → chunk-OGEWGWER-8Qy4a8b5-DaWsU33j.js} +1 -1
  22. package/dist/assets/{chunk-PUDLZKDR-DcrWQRYh-NggLAE5k.js → chunk-PUDLZKDR-DcrWQRYh-zTDqq542.js} +1 -1
  23. package/dist/assets/{chunk-Q4XR5HBZ-ZXVGkG8Z-DmtrERIM.js → chunk-Q4XR5HBZ-ZXVGkG8Z-Dtx2iGhH.js} +1 -1
  24. package/dist/assets/{chunk-V7JOEXUC-DmGdheTX-C8lSwSR3.js → chunk-V7JOEXUC-DmGdheTX-BgwCMqp5.js} +1 -1
  25. package/dist/assets/{chunk-VAUOI2AC-CS9QJ4yz-DNlwzQL1.js → chunk-VAUOI2AC-CS9QJ4yz-FXdeVJH3.js} +1 -1
  26. package/dist/assets/{chunk-VR4S4FIN-C6a91eNY-DX2Te6ga.js → chunk-VR4S4FIN-C6a91eNY-huBR399y.js} +1 -1
  27. package/dist/assets/{chunk-WYO6CB5R-BlzOfotS-BAOXGFjf.js → chunk-WYO6CB5R-BlzOfotS-B9k6Do_6.js} +1 -1
  28. package/dist/assets/{chunk-ZGVPDNZ5-BYwxNFTK-CS40JTYJ.js → chunk-ZGVPDNZ5-BYwxNFTK-17x7kiDu.js} +1 -1
  29. package/dist/assets/classDiagram-OUVF2IWQ-BYlRi6YQ-gmGwQCKi.js +1 -0
  30. package/dist/assets/classDiagram-v2-EOCWNBFH-BCHaYHxj-gmGwQCKi.js +1 -0
  31. package/dist/assets/cynefin-VYW2F7L2-CGYr2F6h-C5PuFrCb.js +1 -0
  32. package/dist/assets/{cynefinDiagram-TSTJHNR4-DHA9iPo--DUt8F5SJ.js → cynefinDiagram-TSTJHNR4-DHA9iPo--BmU0gwz5.js} +1 -1
  33. package/dist/assets/{dagre-VKFMJZFB--oJKqXBZ-BhcFRdM7.js → dagre-VKFMJZFB--oJKqXBZ-Cf0skqxL.js} +1 -1
  34. package/dist/assets/{diagram-FQU43EPY-CcJCB9bG-CBj7RNID.js → diagram-FQU43EPY-CcJCB9bG-XUWMFcgP.js} +1 -1
  35. package/dist/assets/{diagram-G47NLZAW-C_o-WGG1-DCAfQJQ2.js → diagram-G47NLZAW-C_o-WGG1-B6HfMZd3.js} +1 -1
  36. package/dist/assets/{diagram-NH7WQ7WH-CXJCYvY--133061sd.js → diagram-NH7WQ7WH-CXJCYvY--BACwoprc.js} +1 -1
  37. package/dist/assets/{diagram-OA4YK3LP-BMzeJ87A-DPt25PXB.js → diagram-OA4YK3LP-BMzeJ87A-zoxV9d9i.js} +1 -1
  38. package/dist/assets/{diagram-WEI45ONY-D_93NKqo-Bb2DJ3v3.js → diagram-WEI45ONY-D_93NKqo-e-eIgWvy.js} +1 -1
  39. package/dist/assets/{dist-4eLWDv4V.js → dist-BHoD_w15.js} +1 -1
  40. package/dist/assets/{dist-Do1AxSN7.js → dist-BWiUENTZ.js} +1 -1
  41. package/dist/assets/{dist-BmZVepIx.js → dist-CX4c9UBB.js} +1 -1
  42. package/dist/assets/{dist-CDpjkjbB.js → dist-Cm6rSKic.js} +1 -1
  43. package/dist/assets/{ebnfDiagram-CCIWWBDH-CVai1Ii9-CqvyVeoa.js → ebnfDiagram-CCIWWBDH-CVai1Ii9-DujO8khX.js} +1 -1
  44. package/dist/assets/{erDiagram-Q63AITRT-CiABnA0s-jrNyKW5P.js → erDiagram-Q63AITRT-CiABnA0s-DaHESKPI.js} +1 -1
  45. package/dist/assets/eventmodeling-45OFAUF4-CWmqhm3a-D1MuSTYF.js +1 -0
  46. package/dist/assets/flowDiagram-23GEKE2U-DKSB5AiY-DT6n3-Ft.js +1 -0
  47. package/dist/assets/{ganttDiagram-NO4QXBWP-DQZvdFo1-Dz1MAsy4.js → ganttDiagram-NO4QXBWP-DQZvdFo1-De_ebWFp.js} +1 -1
  48. package/dist/assets/gitGraph-TEB2WS4Q-BR9qPwdN-CNsR02rf.js +1 -0
  49. package/dist/assets/{gitGraphDiagram-IHSO6WYX-C2ovBouh-CV3qv2yf.js → gitGraphDiagram-IHSO6WYX-C2ovBouh-C4RETxbL.js} +1 -1
  50. package/dist/assets/{index-Zds0SlQi.css → index-BivYtiDo.css} +1 -1
  51. package/dist/assets/index-COmdTh0t.js +616 -0
  52. package/dist/assets/info-DKCQHKI2-Dplx5kMp-BeUJlQSg.js +1 -0
  53. package/dist/assets/{infoDiagram-FWYZ7A6U-7UnoB5AP-BZUR4_mA.js → infoDiagram-FWYZ7A6U-7UnoB5AP-DNsURlj_.js} +1 -1
  54. package/dist/assets/{ishikawaDiagram-FXEZZL3T-ByUDM_N2-BLGvRDOX.js → ishikawaDiagram-FXEZZL3T-ByUDM_N2-QyeLiJnO.js} +1 -1
  55. package/dist/assets/{journeyDiagram-5HDEW3XC-c5xIah9o-D9zqo5k7.js → journeyDiagram-5HDEW3XC-c5xIah9o-CFkMurTe.js} +1 -1
  56. package/dist/assets/{kanban-definition-HUTT4EX6-Cnt6loYD-BwfjKxOx.js → kanban-definition-HUTT4EX6-Cnt6loYD-DsoZE32R.js} +1 -1
  57. package/dist/assets/{lib-BWq7d2p0.js → lib-DC86gNgf.js} +1 -1
  58. package/dist/assets/{line-D7ziSjKi-ZOy-21z8.js → line-D7ziSjKi-Dz37a1T7.js} +1 -1
  59. package/dist/assets/{marp-IdFBx6Kk.js → marp-B-h6KS_6.js} +1 -1
  60. package/dist/assets/{mermaid-parser.core-DxEa8E3F-C_pDG6kL.js → mermaid-parser.core-DxEa8E3F-DteVxl8X.js} +2 -2
  61. package/dist/assets/{mermaid.core-V0OYwIz3--tUcNILl.js → mermaid.core-V0OYwIz3-DAwdqlFZ.js} +3 -3
  62. package/dist/assets/{mindmap-definition-LN4V7U3C-CexN3O6L-B08uU8xg.js → mindmap-definition-LN4V7U3C-CexN3O6L-B4GX796F.js} +1 -1
  63. package/dist/assets/packet-7NZHBO7P-CQI3flND-C_pMfWi_.js +1 -0
  64. package/dist/assets/{pegDiagram-2B236MQR-BiM4G0cW-CAmtHOOs.js → pegDiagram-2B236MQR-BiM4G0cW-BWBzRiaC.js} +1 -1
  65. package/dist/assets/pie-RZYD4A2V-CnmKE2Wa-bM2FdcNh.js +1 -0
  66. package/dist/assets/{pieDiagram-ENE6RG2P-B_fBBS-2-1Te1k2OW.js → pieDiagram-ENE6RG2P-B_fBBS-2-CsBnZfAY.js} +1 -1
  67. package/dist/assets/{quadrantDiagram-ABIIQ3AL-BigGVxCR-Bwmyhd3u.js → quadrantDiagram-ABIIQ3AL-BigGVxCR-B1j3aQ5d.js} +1 -1
  68. package/dist/assets/radar-I7S5WNFK-us6x-Z9R-BB9wirGo.js +1 -0
  69. package/dist/assets/railroad-3IZDKUUU-BKdz6pdN-CbOoELZg.js +1 -0
  70. package/dist/assets/railroad-abnf-AHOZXSZD-m_CSSIfd-uE3YbEg2.js +1 -0
  71. package/dist/assets/railroad-ebnf-EBAXGLYW-Nu3nAG7C-u4DQhs69.js +1 -0
  72. package/dist/assets/railroad-peg-LSFZ7HO6--Y3mD4R_-B2vytEWW.js +1 -0
  73. package/dist/assets/{railroadDiagram-RFXS5EU6--lNIlG64-B7viF_TQ.js → railroadDiagram-RFXS5EU6--lNIlG64-BjmRh1tU.js} +1 -1
  74. package/dist/assets/{requirementDiagram-TGXJPOKE-D-B0Y5Wu-C5VA5j5p.js → requirementDiagram-TGXJPOKE-D-B0Y5Wu-UJKUKfTI.js} +1 -1
  75. package/dist/assets/{sankeyDiagram-HTMAVEWB-DlutaXDv-DfD-musw.js → sankeyDiagram-HTMAVEWB-DlutaXDv-Bsrgx8aw.js} +1 -1
  76. package/dist/assets/{sequenceDiagram-DBY2YBRQ-BOLgtggH-DeYKXJK9.js → sequenceDiagram-DBY2YBRQ-BOLgtggH-BpxKPxVk.js} +1 -1
  77. package/dist/assets/{stateDiagram-2N3HPSRC-jf_dXUEU-Bq6BSHXK.js → stateDiagram-2N3HPSRC-jf_dXUEU-90vLBL-t.js} +1 -1
  78. package/dist/assets/stateDiagram-v2-6OUMAXLB-CuzgCL2v-B-UjCOGA.js +1 -0
  79. package/dist/assets/{swimlanes-5IMT3BWC-CYjtALQH-BwKcwh8j.js → swimlanes-5IMT3BWC-CYjtALQH-BQj65nKh.js} +1 -1
  80. package/dist/assets/swimlanesDiagram-G3AALYLV-3bmSBtKs-BMxuxpet.js +8 -0
  81. package/dist/assets/{timeline-definition-FHXFAJF6-DYJ4oUm8-D5NlLypk.js → timeline-definition-FHXFAJF6-DYJ4oUm8-Brr9I81k.js} +1 -1
  82. package/dist/assets/treeView-QDETBFTQ-D27HWG6Q-DvTQoVxm.js +1 -0
  83. package/dist/assets/treemap-6X3UGDF4-CmGIU3H5-DCrIc8uR.js +1 -0
  84. package/dist/assets/{vennDiagram-L72KCM5P-CdKAHoek-BAq00OzF.js → vennDiagram-L72KCM5P-CdKAHoek-BFYXaKjS.js} +1 -1
  85. package/dist/assets/wardley-OPB4EBWU-CbHWsb2k--RdJ9IY0.js +1 -0
  86. package/dist/assets/{wardleyDiagram-EHGQE667-BF6c4_CW-Dvh8PYFx.js → wardleyDiagram-EHGQE667-BF6c4_CW-BN4fz_6C.js} +1 -1
  87. package/dist/assets/{xychartDiagram-FW5EYKEG-CGiKngj7-C2sC6_Lu.js → xychartDiagram-FW5EYKEG-CGiKngj7-CJAizw9P.js} +1 -1
  88. package/dist/index.html +2 -2
  89. package/package.json +14 -8
  90. package/server/agents/agent-resume.ts +27 -0
  91. package/server/agents/antigravity-args.ts +39 -0
  92. package/server/agents/antigravity-mcp.ts +122 -0
  93. package/server/agents/antigravity-session.ts +68 -0
  94. package/server/agents/antigravity.ts +7 -0
  95. package/server/agents/registry.ts +2 -0
  96. package/server/agents/types.ts +1 -1
  97. package/server/backends/google.ts +3 -1
  98. package/server/backends/remoteHost/launchTerminal.ts +2 -2
  99. package/server/backends/remoteHost/routes.spec.ts +13 -1
  100. package/server/backends/remoteHost/routes.ts +6 -3
  101. package/server/backends/remoteHost/terminalScreen.ts +59 -2
  102. package/server/config/header-config.ts +1 -1
  103. package/server/config/header-context.ts +1 -1
  104. package/server/files/dirRequest.ts +2 -1
  105. package/server/files/pick-file.ts +2 -1
  106. package/server/git/worktree-routes.ts +5 -4
  107. package/server/index.ts +51 -14
  108. package/server/infra/install-bundled-skills.ts +7 -8
  109. package/server/infra/tmux-routes.ts +3 -2
  110. package/server/infra/tmux.ts +65 -1
  111. package/server/mcp/bridge.mjs +66 -0
  112. package/server/mcp/broker.ts +43 -8
  113. package/server/mcp/gui-call-history.ts +96 -0
  114. package/server/routes/app-routes.ts +29 -2
  115. package/server/routes/gui-mcp-routes.ts +6 -0
  116. package/server/routes/mcp-routes.ts +41 -1
  117. package/server/routes/plugin-routes.ts +14 -4
  118. package/server/routes/routeParams.ts +4 -2
  119. package/server/routes/same-origin-guard.ts +17 -3
  120. package/server/routes/terminal-ws-path.ts +2 -1
  121. package/server/routes/tool-routes.ts +14 -4
  122. package/server/routes/ws-routes.ts +90 -7
  123. package/server/session/background-chat.ts +24 -10
  124. package/server/session/command-summary.ts +2 -1
  125. package/server/session/lifecycle.ts +4 -0
  126. package/server/session/pty-connection.ts +24 -0
  127. package/server/session/pty-relay.ts +35 -0
  128. package/server/session/registry.ts +16 -0
  129. package/server/session/session-reads.ts +2 -1
  130. package/server/session/spawn-antigravity.ts +83 -0
  131. package/server/session/spawn-claude.ts +5 -1
  132. package/server/session/spawn-codex.ts +3 -19
  133. package/server/session/spawn-deps.ts +2 -0
  134. package/server/session/spawners.ts +2 -0
  135. package/server/session/task-push.ts +2 -2
  136. package/server/session/tmux-size-sync.ts +184 -0
  137. package/server/session/tool-store.ts +11 -5
  138. package/server/session/types.ts +4 -0
  139. package/server/skills/mulmoterminal-config/SKILL.md +110 -521
  140. package/server/skills/mulmoterminal-dirs/SKILL.md +227 -0
  141. package/server/skills/{mulmoterminal-config → mulmoterminal-dirs}/palettes.json +1 -1
  142. package/server/skills/mulmoterminal-header/SKILL.md +165 -0
  143. package/server/skills/mulmoterminal-keys/SKILL.md +153 -0
  144. package/server/skills/mulmoterminal-model/SKILL.md +102 -0
  145. package/server/skills/mulmoterminal-notify/SKILL.md +111 -0
  146. package/server/skills/mulmoterminal-theme/SKILL.md +128 -0
  147. package/dist/assets/architecture-TIHT7OUA-0NsD2xW1-DRxyAOZm.js +0 -1
  148. package/dist/assets/channel-7wUqSdoX-CryXErAP.js +0 -1
  149. package/dist/assets/classDiagram-OUVF2IWQ-BYlRi6YQ-Bh9HKUjT.js +0 -1
  150. package/dist/assets/classDiagram-v2-EOCWNBFH-BCHaYHxj-Bh9HKUjT.js +0 -1
  151. package/dist/assets/cynefin-VYW2F7L2-CGYr2F6h-CNhjzHRd.js +0 -1
  152. package/dist/assets/eventmodeling-45OFAUF4-CWmqhm3a-BzmuvEpa.js +0 -1
  153. package/dist/assets/flowDiagram-23GEKE2U-DKSB5AiY-D_olhK5u.js +0 -1
  154. package/dist/assets/gitGraph-TEB2WS4Q-BR9qPwdN-6E2-f_ab.js +0 -1
  155. package/dist/assets/index-CbJGZlpM.js +0 -616
  156. package/dist/assets/info-DKCQHKI2-Dplx5kMp-DxJGF13X.js +0 -1
  157. package/dist/assets/packet-7NZHBO7P-CQI3flND-C1R5Sk6K.js +0 -1
  158. package/dist/assets/pie-RZYD4A2V-CnmKE2Wa-fnUCv-1K.js +0 -1
  159. package/dist/assets/radar-I7S5WNFK-us6x-Z9R-DfxsmsH_.js +0 -1
  160. package/dist/assets/railroad-3IZDKUUU-BKdz6pdN-Cc9H2ZqM.js +0 -1
  161. package/dist/assets/railroad-abnf-AHOZXSZD-m_CSSIfd-CedxYTf_.js +0 -1
  162. package/dist/assets/railroad-ebnf-EBAXGLYW-Nu3nAG7C-DFUbcN03.js +0 -1
  163. package/dist/assets/railroad-peg-LSFZ7HO6--Y3mD4R_-7OkZDahF.js +0 -1
  164. package/dist/assets/stateDiagram-v2-6OUMAXLB-CuzgCL2v-cQTUIwVP.js +0 -1
  165. package/dist/assets/swimlanesDiagram-G3AALYLV-3bmSBtKs-SzBmSlrT.js +0 -8
  166. package/dist/assets/treeView-QDETBFTQ-D27HWG6Q-mArgqXY_.js +0 -1
  167. package/dist/assets/treemap-6X3UGDF4-CmGIU3H5-DcjdNdM5.js +0 -1
  168. package/dist/assets/wardley-OPB4EBWU-CbHWsb2k-C9OSQ_B-.js +0 -1
  169. package/server/agents/codex-resume.ts +0 -26
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # mulmoterminal
2
2
 
3
- **Run a whole team of coding agents from your browser — and actually keep up with them.**
3
+ **Run multiple Claude Code and Codex sessions in parallel — and see which one needs you.**
4
4
 
5
5
  A **browser terminal** for **parallel AI coding agents**: several **Claude Code** and **Codex**
6
6
  sessions side by side, each in its own cell, with the one that needs you marked in colour. Vibe
@@ -14,6 +14,9 @@ and a **phone push** reaches you when a turn finishes.
14
14
  view, everyday workflows, the full feature list, configuration, and mobile push notifications.
15
15
  - **ユーザーガイド:** [日本語](https://receptron.github.io/mulmoterminal/guide/ja/) —
16
16
  グリッドの使い方・日々のワークフロー・機能一覧・設定・スマホ通知の設定はこちら。
17
+ - **Updates / アップデート情報:** new releases and features are announced **in Japanese** on X —
18
+ 新バージョンや新機能のお知らせは X の
19
+ [Singularity Society (@SingularitySoci)](https://x.com/SingularitySoci) で。
17
20
 
18
21
  ![MulmoTerminal — a grid of live Claude Code sessions, each color-coded by state, updating in real time](https://raw.githubusercontent.com/receptron/mulmoterminal/main/docs/guide/images/hero.gif)
19
22
 
@@ -101,6 +104,17 @@ when the session ends, and any left by a crash are swept at the next start. Up t
101
104
  file — the same ceiling as a phone attachment. **A session already running when you upgrade
102
105
  was launched without that grant**, so drops into it still prompt; new sessions don't.
103
106
 
107
+ **Pasting a screenshot** — take a screenshot and paste it straight into the terminal
108
+ (`Cmd`/`Ctrl`+`V`). The image is saved to the session's own drop directory — the same place a
109
+ dropped file goes, with the same grant, the same 110 MiB ceiling and the same cleanup when the
110
+ session ends — and its **absolute path** is inserted at the cursor, so the agent can read it.
111
+ Unlike a drop, this does not need the browser to expose a path — the bytes are on the
112
+ clipboard — so it also covers Chrome, where dropping a file cannot insert a path. It works
113
+ wherever the browser puts the image on the clipboard as `image/png`, `image/jpeg`,
114
+ `image/gif`, or `image/webp`. Anything else is left to the terminal's own paste handling,
115
+ exactly as before — including a paste that carries **plain text** next to the image, which
116
+ copying from a web page usually does, so that pasting text keeps working.
117
+
104
118
  <a id="clicking-a-file-path"></a>
105
119
 
106
120
  **Clicking a file path** — the other direction. A path an agent *prints* becomes a link, and
@@ -215,7 +229,10 @@ and every CLI in the table above), seeds the launcher's **directory
215
229
  presets** from the projects in your Claude Code history, and writes `~/.mulmoterminal/config.json`.
216
230
  It's **idempotent** — re-run it any time to refresh the presets; it overwrites the managed parts
217
231
  and keeps your other settings. When `claude` is installed it can hand off to the
218
- `/mulmoterminal-config` skill for interactive tweaks.
232
+ `/mulmoterminal-config` skill for interactive tweaks — it routes to the one that owns what you
233
+ want to change. Once the app is up you can also reach them from **Settings**: each section that a
234
+ skill can write ends in a button that starts that skill in a new session, which is how the settings
235
+ with no UI (a theme of your own, `keymap`) get written without hand-editing JSON.
219
236
 
220
237
  **Google account (optional).** Link a Google account to enable the chat's `google` tool and the
221
238
  phone's `google.calendar.*` commands: read/create events on any calendar (not just your primary),
@@ -352,12 +369,12 @@ SDK; we drive the real interactive CLI and relay its TTY over the WebSocket.
352
369
 
353
370
  ---
354
371
 
355
- ## Agents: Claude & Codex
372
+ ## Agents: Claude, Codex & Antigravity
356
373
 
357
374
  MulmoTerminal drives **interactive coding-agent CLIs**, not just Claude. An
358
375
  `AgentAdapter` seam abstracts the per-agent bits (which binary to spawn, how it resumes)
359
- so the PTY, grid, persistence, and GUI-panel plumbing stay shared. Two adapters ship
360
- today — **Claude Code** (the default) and **Codex**.
376
+ so the PTY, grid, persistence, and GUI-panel plumbing stay shared. Three adapters ship
377
+ today — **Claude Code** (the default), **Codex**, and **Antigravity** (`agy`).
361
378
 
362
379
  - **Claude** — spawned as `claude` (override with `CLAUDE_BIN`). The server passes
363
380
  `--session-id <uuid>`, so it knows the live session's id even before its transcript
@@ -371,10 +388,34 @@ today — **Claude Code** (the default) and **Codex**.
371
388
  `CODEX_HOME`) and maps the new rollout to the session — attributed only when it's
372
389
  unambiguous, never by "newest wins". Resume reattaches a live PTY, adopts a surviving
373
390
  tmux session, or cold-resumes the rollout id.
391
+ - **Antigravity** — spawned as `agy` (override with `ANTIGRAVITY_BIN`; `ANTIGRAVITY_MODEL` sets
392
+ `--model`). Antigravity runs on its own WebSocket (`/ws/antigravity`). Like Codex it mints its
393
+ own conversation id, so the server watches `~/.gemini/antigravity-cli/brain/` (home overridable
394
+ via `ANTIGRAVITY_HOME`) for the directory the new conversation creates — attributed only when
395
+ unambiguous — and cold-resumes it with `--conversation <id>`.
396
+
397
+ Its **GUI tools work differently**, because `agy` takes no MCP flag: it reads its servers from
398
+ `.agents/mcp_config.json` in the working directory. MulmoTerminal writes that file from the
399
+ directory's [Canvas switches](#wiki-collections--the-gui-panel) — the same switches Claude's cells read — so
400
+ one switch serves every agent, and rewrites it whenever a switch flips or an agy session starts.
401
+ Servers in it that MulmoTerminal did not write are left alone, the file is removed once no group
402
+ is on, and it is kept out of your `git status` through `.git/info/exclude` — a local switch on a
403
+ local machine, so it never reaches a diff or your team. The entry runs `server/mcp/bridge.mjs`, a stdio-to-HTTP shim onto the same in-process
404
+ GUI MCP server the other agents call. The **session id is never written into that file** — it is
405
+ per directory and shared by every session running there — and reaches the bridge through the agy
406
+ process's own environment instead.
407
+
408
+ The Docker sandbox does NOT cover agy: it stays claude-only until `buildDockerRunArgs` is
409
+ generalized (see `plans/feat-multi-agent-support.md`, PR#5). `agy` also ships as a standalone
410
+ binary rather than an npm package, so the sandbox image has nothing to install.
374
411
 
375
412
  **Choosing an agent.** The single view has a **New Codex session** button; each grid
376
- cell's launch form and the Collections browser carry a **Claude / Codex** toggle (your
377
- choice is remembered).
413
+ cell's launch form carries a **Claude / Codex / Antigravity / Shell** toggle, and the
414
+ Collections browser a **Claude / Codex / Antigravity** one (your choice is remembered).
415
+ **Shell** is not an agent: it runs your OS default shell (`$SHELL`, or `/bin/sh`) in the
416
+ chosen directory, with nothing to install and nothing to configure. It starts a launcher
417
+ cell, so it has no model, no MCP registration, and no worktree — those rows disappear
418
+ while it is picked.
378
419
 
379
420
  **Other models.**
380
421
  Claude Code can run against any **Anthropic-compatible** backend (OpenRouter, Moonshot, a
@@ -501,7 +542,14 @@ the `claude` / `codex` sessions themselves.
501
542
  | `CODEX_BIN` | `codex` | The Codex CLI binary to spawn. |
502
543
  | `CODEX_MODEL`| codex default | Model passed to Codex as `--model` (unset = Codex's own default). |
503
544
  | `CODEX_HOME` | `~/.codex` | Codex home — where its session rollouts and MulmoTerminal-mirrored skills live. |
545
+ | `ANTIGRAVITY_BIN` | `agy` | The Antigravity CLI binary to spawn. |
546
+ | `ANTIGRAVITY_MODEL` | agy default | Model passed to Antigravity as `--model` (unset = agy's own default). |
547
+ | `ANTIGRAVITY_HOME` | `~/.gemini/antigravity-cli` | Antigravity home directory containing session brain storage. |
504
548
  | `MULMOTERMINAL_HOME` | `~/.mulmoterminal` | Root for managed **git worktrees**. |
549
+ | `CLAUDE_CONFIG_DIR` | `~` | Claude Code's own config directory. `.claude.json` lives **inside** it, so relocating your Claude Code config moves that file too — MulmoTerminal reads it to tell whether the per-project GUI MCP server is registered (`server/infra/gui-mcp-registration.ts`). Leave it unset and `~/.claude.json` is used. |
550
+ | `MULMOCLAUDE_WORKSPACE_PATH` | `~/mulmoclaude` | Where the managed MulmoClaude workspace lives. MulmoTerminal seeds presets/helps **only** into this directory, so launching in an arbitrary project never writes them there (`server/backends/workspaceSetup.ts`). Set it to the same value MulmoClaude uses. |
551
+ | `MULMOTERMINAL_NO_SKILL_INSTALL` | unset | Set to any value to skip installing the bundled skills (`mulmoterminal-config` and the `-dirs` / `-theme` / `-header` / `-keys` / `-model` / `-notify` / `-bug-report` / `-decisions` family) into `~/.claude/skills/` and the Codex skills root on startup. |
552
+ | `GEMINI_IMAGE_MODEL` | `gemini-3.1-flash-image-preview` | Model used for image generation (needs `GEMINI_API_KEY`). The default is a **preview** model Google schedules for retirement around mid-2026, so pin a stable one here (e.g. `gemini-2.5-flash-image`) rather than waiting for a code change. |
505
553
  | `WAIT_REAP_GRACE_MS` | `1800000` | How long a **waiting** background session is kept before it's auto-reaped (`0` or negative = never). |
506
554
 
507
555
  The Docker-sandbox variables (`MULMOTERMINAL_SANDBOX`, `MULMOTERMINAL_SANDBOX_IMAGE`,
@@ -531,7 +579,7 @@ The Settings modal (⚙) persists per-user UI choices to `~/.mulmoterminal/confi
531
579
  | `soundKinds` | Which moments beep — see [Notification sounds](#notification-sounds). Defaults to `["finished","waiting"]`; the other kinds are opt-in. |
532
580
  | `sounds` | Per-kind sound: `{ "waiting": "preset:coin" }`. A `preset:<id>` reference or an absolute path; a kind with no entry falls back to `soundFile`. |
533
581
  | `prRepos` | `owner/repo` entries whose open PRs/issues the cross-repo **PRs & Issues** view aggregates (via your `gh` login). |
534
- | `launchers` | `{ label, command }` entries offered in a grid cell's launcher besides Claudea plain shell, `codex`, any interactive command. |
582
+ | `launchers` | `{ label, command }` entries offered in a grid cell's launcher besides the agents any interactive command. A plain shell needs no entry: the launch form's **Shell** toggle opens `$SHELL` unconfigured. |
535
583
  | `quickCommands` | `{ label, text, agents? }` phrases the **phone** offers as chips on a session's terminal view. Tapping one puts `text` in the input box; it is not sent until you press send. `agents` (`"claude"` / `"codex"` / `"shell"`) scopes a chip to session kinds — omit it to offer the chip everywhere. Empty by default. |
536
584
  | `userMcpServers` | `{ id, url }` HTTP MCP servers merged into the **single-view** Claude session's `--mcp-config` (a `localhost` URL is reached over `host.docker.internal` in the Docker sandbox). Takes effect on the next session. |
537
585
  | `buttons` | Header action buttons — see [Header buttons](#header-buttons). Omit to keep the defaults; set to replace them. |
@@ -569,8 +617,8 @@ agent), or `"open"`. An `open` button targets one of `url` / `reveal` (OS file m
569
617
  opened next to the current one) / `pr: true` (open the current branch's PR — the button is hidden when
570
618
  there's no open PR) / `pickFile: true` (OS file dialog → insert the path).
571
619
  `${dir}`, `${branch}`, `${repo}`, … substitute live context, and `when` (e.g. `"isGitRepo"`) gates
572
- visibility. The `/mulmoterminal-config` skill writes a valid config interactively; per-dir buttons
573
- merge over the global ones by `id`.
620
+ visibility. The `/mulmoterminal-header` skill writes a valid config interactively; per-dir buttons
621
+ merge over the global ones by `id`, while `chips` replace the global list wholesale.
574
622
 
575
623
  ### Notification sounds
576
624
 
@@ -666,7 +714,7 @@ malformed file is ignored.
666
714
  "colors": { "background": "#190a23", "cursor": "#ff2e63" }, // per-key palette overrides
667
715
  "fontSize": 16, // terminal font size in px (8–32); overrides Settings
668
716
  "fontFamily": "'Cica', monospace", // terminal font stack; overrides the global config
669
- "orderPriority": 10, // rank in the grid's "priority" ordering (lowest first)
717
+ "orderPriority": 10, // rank in the grid's "priority" order and the launcher chips (lowest first)
670
718
  "sound": "./.mulmoterminal/alert.mp3", // attention sound, RELATIVE to this directory
671
719
  "sounds": { "command-failed": "preset:gong" }, // per-notification-kind override
672
720
  "appendSystemPrompt": false // no closing summary here; omit to follow the global setting
@@ -690,7 +738,7 @@ malformed file is ignored.
690
738
  | `theme` | xterm palette for terminals in this directory (one of the built-in theme ids). |
691
739
  | `colors` | Per-key xterm palette overrides applied on top of `theme` (or the app theme when `theme` is unset). Keys are xterm `ITheme` names (`background`, `foreground`, `cursor`, `selectionBackground`, the 16 ANSI colors, …); values are hex (`#rgb` / `#rrggbb` / `#rrggbbaa`). Unknown keys / bad values are dropped. |
692
740
  | `fontSize` | Terminal font size in px for this directory (8–32), overriding the Settings value. A size outside the range is clamped; a non-number is ignored. Changing it re-fits the terminal, so the PTY learns the new width — unlike browser zoom, which leaves the two disagreeing. |
693
- | `orderPriority` | This directory's rank in the grid's **priority** ordering — the third mode on the toolbar's ordering button, next to auto (attention-first) and manual (the move buttons). Any integer, **lowest first**; negatives are allowed. Directories that set nothing sort last, keeping their existing order, so adding the key to one project doesn't shuffle the rest. Only the priority mode reads it. |
741
+ | `orderPriority` | This directory's rank in the grid's **priority** ordering — the third mode on the toolbar's ordering button, next to auto (attention-first) and manual (the move buttons). Any integer, **lowest first**; negatives are allowed. Directories that set nothing sort last, keeping their existing order, so adding the key to one project doesn't shuffle the rest. The grid reads it in **priority** mode only; the launcher's directory chips always sort by it, so a project sits in the same place on both. |
694
742
  | `fontFamily` | CSS font-family stack for this directory's terminals, overriding the global `fontFamily`. Use the names as your OS lists them (`"'Cica', 'MS Gothic', monospace"`). An unusable stack is ignored whole rather than half-applied; `monospace` is appended if you name no generic family. Prefer fonts whose fullwidth glyphs are exactly twice the Latin width, or box-drawing frames tear. |
695
743
  | `sound` | Attention sound for this directory's sessions, a path **relative to the directory** (served at `GET /api/dir-sound`). The fallback for every kind. |
696
744
  | `sounds` | Per-kind override of `sound`: `{ "command-failed": "preset:gong" }`. Each value is a `preset:<id>` or a directory-relative path, under the same confinement. |
@@ -701,7 +749,7 @@ malformed file is ignored.
701
749
  paths and any `../` that escapes the directory are rejected, and the path is never taken from the
702
750
  HTTP request, so an opened project can't point the player at arbitrary files.
703
751
  **When changes take effect.** A write made *through Claude's tools* — which includes the
704
- `mulmoterminal-config` skill — applies **live**: the tool hook that reports the write doubles
752
+ `mulmoterminal-dirs` skill — applies **live**: the tool hook that reports the write doubles
705
753
  as the reload signal, so colors, palette, font size and grid order update without reopening
706
754
  anything. There is no filesystem watcher, so an edit made **outside** a session (your own
707
755
  editor) is picked up when the terminal is next opened.
@@ -759,8 +807,9 @@ alongside the Claude sessions. Scripts are **per-directory**: the cell reads the
759
807
  different projects' scripts.
760
808
 
761
809
  The same launcher also has an **or launch** row for your configured **launch commands**
762
- a plain interactive shell, `codex`, any command — set in Settings (⚙) → **Launch
763
- commands** as `{ label, command }` (e.g. `Shell` → `$SHELL`, `Codex` → `codex`). Unlike
810
+ any interactive command — set in Settings (⚙) → **Launch commands** as
811
+ `{ label, command }` (e.g. `htop` → `htop`, `Codex` → `codex`). A plain shell needs no
812
+ entry here: the launch form's **Shell** toggle already opens `$SHELL`. Unlike
764
813
  a one-shot script, a launcher runs as a **persistent terminal in the cell's directory**:
765
814
  it survives grid page switches and reconnects, and its dot shows running vs. exited (it
766
815
  has no Claude hooks, so no blocked/done states).
@@ -905,7 +954,7 @@ repo without colliding. Worktrees live under `~/.mulmoterminal/worktrees/` (over
905
954
 
906
955
  ![An empty cell's launch form — choose the agent, working directory, or a worktree](https://raw.githubusercontent.com/receptron/mulmoterminal/main/docs/guide/images/grid-launch-form.png)
907
956
 
908
- *Every empty grid cell shows this launch form: toggle **Claude / Codex**, type a **working directory** (frequent ones autocomplete from your presets), or — in a git repo — name a task under **OR ISOLATE IN A WORKTREE** and hit **+ New worktree** to start the agent on its own isolated branch. **OR LAUNCH** starts a plain shell or any launch command instead.*
957
+ *Every empty grid cell shows this launch form: toggle **Claude / Codex / Antigravity / Shell**, type a **working directory** (frequent ones autocomplete from your presets), or — in a git repo — name a task under **OR ISOLATE IN A WORKTREE** and hit **+ New worktree** to start the agent on its own isolated branch. **Shell** runs your OS default shell there instead of an agent; **OR LAUNCH** runs one of your configured launch commands.*
909
958
 
910
959
  A worktree cell's header carries a **diff badge** (`+<commits> ●<dirty>`); click it for a
911
960
  **Changes vs `<base>`** panel (file list + patch) with actions:
@@ -1567,7 +1616,8 @@ server/
1567
1616
  mcp/ per-session MCP broker
1568
1617
  backends/ wiki, collections, feeds, accounting, notifier,
1569
1618
  translation, whisper, remote-host, html, files
1570
- skills/ bundled skills (mulmoterminal-config, mulmoterminal-bug-report, mulmoterminal-decisions)
1619
+ skills/ bundled skills: mulmoterminal-config (entry point + audit), -dirs, -theme,
1620
+ -header, -keys, -model, -notify, -bug-report, -decisions
1571
1621
  fix-pty-perms.js postinstall: fixes node-pty binary permissions
1572
1622
  src/
1573
1623
  App.vue Layout; owns the active session + single/grid view
@@ -0,0 +1,31 @@
1
+ // The skills MulmoTerminal ships, named once for both sides.
2
+ //
3
+ // Shared rather than mirrored because BOTH sides decide from these: the server COPIES these
4
+ // directories into the user's skills roots at boot, and the client LAUNCHES one by name from the
5
+ // Settings section that owns it. A name that lives in two places is a name that can drift, and it
6
+ // did — the grid view and the single view each spelled the appearance skill out, a rename updated
7
+ // one of them, and the same button then launched a different skill depending on which view you
8
+ // pressed it from. Each half was self-consistent, so nothing failed (Codex review on #1103).
9
+ // `BundledSkillName` is what keeps the Settings buttons honest now: a slug naming no shipped skill
10
+ // is a type error rather than an agent replying that it can't find one.
11
+
12
+ /** Every skill directory under `server/skills/`, in the order the installer walks them. A spec
13
+ * pins this list against what is actually on disk: adding a directory is not what ships it, and
14
+ * one nobody lists is copied nowhere with no error at any point. */
15
+ export const BUNDLED_SKILL_NAMES = [
16
+ "mulmoterminal-config",
17
+ "mulmoterminal-dirs",
18
+ "mulmoterminal-theme",
19
+ "mulmoterminal-header",
20
+ "mulmoterminal-keys",
21
+ "mulmoterminal-model",
22
+ "mulmoterminal-notify",
23
+ "mulmoterminal-bug-report",
24
+ "mulmoterminal-decisions",
25
+ ] as const;
26
+
27
+ export type BundledSkillName = (typeof BUNDLED_SKILL_NAMES)[number];
28
+
29
+ /** The skill that owns `<project>/.mulmoterminal.json` — the one the generated JSON Schema ships
30
+ * beside, so the schema sits with the skill that actually writes that file. */
31
+ export const DIR_CONFIG_SKILL = "mulmoterminal-dirs";
@@ -4,7 +4,7 @@
4
4
  // Deliberately NOT the configured `launchers` list: those are arbitrary user commands, and
5
5
  // the phone picks from a fixed set the host can name. "shell" is the OS default shell, the
6
6
  // same thing the header's new-terminal button opens.
7
- export const LAUNCH_AGENTS = ["shell", "claude", "codex"] as const;
7
+ export const LAUNCH_AGENTS = ["shell", "claude", "codex", "antigravity"] as const;
8
8
 
9
9
  export type LaunchAgent = (typeof LAUNCH_AGENTS)[number];
10
10
 
@@ -2,7 +2,7 @@
2
2
  // backend, and how well each one actually drove Claude Code when it was measured.
3
3
  //
4
4
  // Shared across the build boundary (like themeIds / dirChrome): the launch picker reads
5
- // it in the browser, and the mulmoterminal-config skill reads it to know what it may
5
+ // it in the browser, and the mulmoterminal-model skill reads it to know what it may
6
6
  // suggest. One list, one source of truth.
7
7
  //
8
8
  // WHY THE NUMBERS: a model that answers a plain prompt can still be unusable, because the
@@ -0,0 +1,23 @@
1
+ // The image types a pasted screenshot can be saved as. BOTH sides decide from this list, so
2
+ // it lives here rather than in either of them: the client only takes a paste away from xterm
3
+ // when the server will accept it, and the server only writes a type it can name a file for.
4
+ // Were the two to drift, a paste would vanish from the terminal and then fail to upload —
5
+ // the user would see nothing happen at all.
6
+ //
7
+ // SVG is deliberately absent: it is a script-bearing document, not a screenshot, and nothing
8
+ // puts one on the clipboard as an image.
9
+ const EXTENSION_BY_MIME: ReadonlyMap<string, string> = new Map([
10
+ ["image/png", ".png"],
11
+ ["image/jpeg", ".jpg"],
12
+ ["image/gif", ".gif"],
13
+ ["image/webp", ".webp"],
14
+ ]);
15
+
16
+ /** The file extension for a pasteable image type, or null when it isn't one. */
17
+ export function extensionForImageMime(mime: string): string | null {
18
+ return EXTENSION_BY_MIME.get(mime.toLowerCase().trim()) ?? null;
19
+ }
20
+
21
+ export function isPasteableImageMime(mime: string): boolean {
22
+ return extensionForImageMime(mime) !== null;
23
+ }
@@ -1,8 +1,29 @@
1
1
  // What a remote-host session is running. The server decides it (from the PtyEntry, or from
2
2
  // what tmux says is in the pane) and the settings UI offers it as the scope for a quick
3
3
  // command, so the list of kinds is a value both sides read.
4
- export const SESSION_AGENTS = ["claude", "codex", "shell"] as const;
4
+ export const SESSION_AGENTS = ["claude", "codex", "antigravity", "shell"] as const;
5
5
 
6
6
  // Null anywhere this appears means the host cannot tell — a session that outlived a restart
7
7
  // exists only in tmux, and nothing recorded what launched it. That is distinct from "shell".
8
8
  export type SessionAgent = (typeof SESSION_AGENTS)[number];
9
+
10
+ // The agents a terminal can be LAUNCHED as, which is the session kinds minus "shell" (a shell is
11
+ // a launcher, not an agent). Claude is first because it is the default everywhere below.
12
+ export const TERMINAL_AGENTS = ["claude", "codex", "antigravity"] as const;
13
+
14
+ export type TerminalAgent = (typeof TERMINAL_AGENTS)[number];
15
+
16
+ // A remembered agent — a persisted grid cell, a localStorage toggle, a query param — read back.
17
+ // Validated rather than cast: anything unrecognised is Claude, which is also what an older
18
+ // persisted cell (written before the field existed) means.
19
+ export const asTerminalAgent = (value: unknown): TerminalAgent => (TERMINAL_AGENTS.some((agent) => agent === value) ? (value as TerminalAgent) : "claude");
20
+
21
+ // A cell / connection / header button carries its agent as booleans, because Claude is the
22
+ // default and the default is the absence of a flag. One function turns them back into the name,
23
+ // so the precedence lives in one place rather than in a ternary repeated at every call site —
24
+ // and adding a fourth agent is one edit here.
25
+ export function terminalAgent(flags: { codex?: boolean | null; antigravity?: boolean | null }): TerminalAgent {
26
+ if (flags.antigravity) return "antigravity";
27
+ if (flags.codex) return "codex";
28
+ return "claude";
29
+ }
@@ -1 +1 @@
1
- import{n as e}from"./chunk-Y2CYZVJY-Bdt8pFDJ-DsF7k-Jl.js";import{f as t}from"./src-Brzfja-q-ch1VcTiG.js";import{_ as n,g as r}from"./mermaid-parser.core-DxEa8E3F-C_pDG6kL.js";import"./chunk-WYO6CB5R-BlzOfotS-BAOXGFjf.js";import"./chunk-VAUOI2AC-CS9QJ4yz-DNlwzQL1.js";import{n as i,r as a,t as o}from"./chunk-MOJQB5TN-CMZRaeqt-Ch-WBypm.js";import{t as s}from"./chunk-JWPE2WC7-BQ3zXr2k-DSd3Ct95.js";var c=r().RailroadAbnf.parser.LangiumParser,l=e(e=>{let t=e.alternatives.map(u);return t.length===1?t[0]:{type:`choice`,alternatives:t}},`transformAlternation`),u=e(e=>{let t=e.elements.map(f);return t.length===1?t[0]:{type:`sequence`,elements:t}},`transformConcatenation`),d=e(e=>{if(e.includes(`*`)){let[t,n]=e.split(`*`);return{min:t?parseInt(t,10):0,max:n?parseInt(n,10):1/0}}let t=parseInt(e,10);return{min:t,max:t}},`parseRepeat`),f=e(e=>{let t=p(e.primary);if(!e.repeat)return t;let{min:n,max:r}=d(e.repeat);return n===0&&r===1?{type:`optional`,element:t}:{type:`repetition`,element:t,min:n,max:r}},`transformElement`),p=e(e=>{switch(e.$type){case`AbnfStringLiteral`:return{type:`terminal`,value:e.value};case`AbnfNumVal`:return{type:`terminal`,value:e.value};case`AbnfRuleName`:return{type:`nonterminal`,name:e.name};case`AbnfGroup`:return l(e.element);case`AbnfOptionalGroup`:return{type:`optional`,element:l(e.element)};default:throw Error(`Unsupported ABNF primary node: ${e.$type}`)}},`transformPrimary`),m=e(e=>({name:e.name,definition:l(e.definition)}),`transformRule`),h=e(e=>{s(e,a),e.title&&a.setTitle(e.title),e.rules.map(e=>a.addRule(m(e)))},`populateDb`),g={parser:{parse:e(e=>{a.clear(),t.debug(`[ABNF Parser] Starting Langium parse`);let r=c.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new n(r);let i=r.value;t.debug(`[ABNF Parser] Parsed rules:`,i.rules.length),h(i),t.debug(`[ABNF Parser] Parse complete`)},`parse`),parser:{yy:a}},db:a,renderer:o,styles:i};export{g as diagram};
1
+ import{n as e}from"./chunk-Y2CYZVJY-Bdt8pFDJ-DsF7k-Jl.js";import{f as t}from"./src-Brzfja-q-ch1VcTiG.js";import{_ as n,g as r}from"./mermaid-parser.core-DxEa8E3F-DteVxl8X.js";import"./chunk-WYO6CB5R-BlzOfotS-B9k6Do_6.js";import"./chunk-VAUOI2AC-CS9QJ4yz-FXdeVJH3.js";import{n as i,r as a,t as o}from"./chunk-MOJQB5TN-CMZRaeqt-LKJvD71K.js";import{t as s}from"./chunk-JWPE2WC7-BQ3zXr2k-DSd3Ct95.js";var c=r().RailroadAbnf.parser.LangiumParser,l=e(e=>{let t=e.alternatives.map(u);return t.length===1?t[0]:{type:`choice`,alternatives:t}},`transformAlternation`),u=e(e=>{let t=e.elements.map(f);return t.length===1?t[0]:{type:`sequence`,elements:t}},`transformConcatenation`),d=e(e=>{if(e.includes(`*`)){let[t,n]=e.split(`*`);return{min:t?parseInt(t,10):0,max:n?parseInt(n,10):1/0}}let t=parseInt(e,10);return{min:t,max:t}},`parseRepeat`),f=e(e=>{let t=p(e.primary);if(!e.repeat)return t;let{min:n,max:r}=d(e.repeat);return n===0&&r===1?{type:`optional`,element:t}:{type:`repetition`,element:t,min:n,max:r}},`transformElement`),p=e(e=>{switch(e.$type){case`AbnfStringLiteral`:return{type:`terminal`,value:e.value};case`AbnfNumVal`:return{type:`terminal`,value:e.value};case`AbnfRuleName`:return{type:`nonterminal`,name:e.name};case`AbnfGroup`:return l(e.element);case`AbnfOptionalGroup`:return{type:`optional`,element:l(e.element)};default:throw Error(`Unsupported ABNF primary node: ${e.$type}`)}},`transformPrimary`),m=e(e=>({name:e.name,definition:l(e.definition)}),`transformRule`),h=e(e=>{s(e,a),e.title&&a.setTitle(e.title),e.rules.map(e=>a.addRule(m(e)))},`populateDb`),g={parser:{parse:e(e=>{a.clear(),t.debug(`[ABNF Parser] Starting Langium parse`);let r=c.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new n(r);let i=r.value;t.debug(`[ABNF Parser] Parsed rules:`,i.rules.length),h(i),t.debug(`[ABNF Parser] Parse complete`)},`parse`),parser:{yy:a}},db:a,renderer:o,styles:i};export{g as diagram};
@@ -0,0 +1 @@
1
+ import{f as e}from"./mermaid-parser.core-DxEa8E3F-DteVxl8X.js";export{e as createArchitectureServices};