mulmoterminal 1.3.1 → 1.5.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 (186) hide show
  1. package/README.md +45 -0
  2. package/bin/update-check.d.ts +2 -0
  3. package/common/dirChrome.ts +20 -0
  4. package/common/themeIds.ts +6 -0
  5. package/dist/assets/{abnfDiagram-VRR7QNED-6nNByj6v-DxXGZ8ah.js → abnfDiagram-VRR7QNED-6nNByj6v-BmTAK_lf.js} +1 -1
  6. package/dist/assets/architecture-TIHT7OUA-CYMWc3UT-ChEc_7wP.js +1 -0
  7. package/dist/assets/{architectureDiagram-ZJ3FMSHR-Bgnyaj_i-DVdTZaYg.js → architectureDiagram-ZJ3FMSHR-Bgnyaj_i-Rm4oPVV8.js} +1 -1
  8. package/dist/assets/{blockDiagram-677ZJIJ3-DQ35o5E4-BUjwzYiL.js → blockDiagram-677ZJIJ3-DQ35o5E4-CpSusKj_.js} +1 -1
  9. package/dist/assets/{c4Diagram-LMCZKHZV-ClWZeiWo-DVufWqeb.js → c4Diagram-LMCZKHZV-ClWZeiWo-CDPWcIZ7.js} +1 -1
  10. package/dist/assets/channel-Di5rtkx0-CW5bKrWi.js +1 -0
  11. package/dist/assets/{chunk-32BRIVSS-CCt9wtYd-BZ0yWACh.js → chunk-32BRIVSS-CCt9wtYd-BNsLemkR.js} +1 -1
  12. package/dist/assets/{chunk-52WLFC77-FbBbR4uI-CXT-XvoC.js → chunk-52WLFC77-FbBbR4uI-hDAV5e1Z.js} +1 -1
  13. package/dist/assets/{chunk-C7G6YPKG-C87hlS9c-CnkZ8N1c.js → chunk-C7G6YPKG-C87hlS9c-DfzZj0PL.js} +1 -1
  14. package/dist/assets/{chunk-EX3LRPZG-BqGqMXLN-BB3X7psT.js → chunk-EX3LRPZG-BqGqMXLN-uoc2Ztzj.js} +1 -1
  15. package/dist/assets/{chunk-FWX5IMBZ-BkbSAAuW-D_ITpYMt.js → chunk-FWX5IMBZ-BkbSAAuW-B397K7iE.js} +2 -2
  16. package/dist/assets/{chunk-HOUHSVGY-Cxu0eDlh-DtH0CcTR.js → chunk-HOUHSVGY-Cxu0eDlh-BgHFcMoQ.js} +1 -1
  17. package/dist/assets/{chunk-ICXQ74PX-hiraF_Xj-CAxRue72.js → chunk-ICXQ74PX-hiraF_Xj-BJT-y8zi.js} +1 -1
  18. package/dist/assets/{chunk-MOJQB5TN-CqxshQHA-QQH5sWOZ.js → chunk-MOJQB5TN-CqxshQHA-rfYFgPHl.js} +1 -1
  19. package/dist/assets/{chunk-OGEWGWER-CjCr7ceX-Blfojmss.js → chunk-OGEWGWER-CjCr7ceX-DuZ8UI47.js} +1 -1
  20. package/dist/assets/{chunk-PUDLZKDR-Dx6M-vz1-5dXqfAyQ.js → chunk-PUDLZKDR-Dx6M-vz1-C20tVRvs.js} +1 -1
  21. package/dist/assets/{chunk-Q4XR5HBZ-CZd-9lTB-Dgggyq-Y.js → chunk-Q4XR5HBZ-CZd-9lTB-BFkl1myD.js} +1 -1
  22. package/dist/assets/{chunk-V7JOEXUC-rI0xlC_O-DrrpCTNA.js → chunk-V7JOEXUC-rI0xlC_O-C2QrFL3o.js} +1 -1
  23. package/dist/assets/{chunk-VAUOI2AC-DrcykVNK-BCZszPgC.js → chunk-VAUOI2AC-DrcykVNK-BSJoRdEM.js} +1 -1
  24. package/dist/assets/{chunk-VR4S4FIN-O6iF8Yvf-o61xwbcr.js → chunk-VR4S4FIN-O6iF8Yvf-CL4V93u8.js} +1 -1
  25. package/dist/assets/{chunk-WYO6CB5R-B83L_z6I-Be0VbGoJ.js → chunk-WYO6CB5R-B83L_z6I-ybwRHaqV.js} +1 -1
  26. package/dist/assets/{chunk-ZGVPDNZ5-BpFv9JSP-BICQ9aJs.js → chunk-ZGVPDNZ5-BpFv9JSP-DQGEhX3k.js} +1 -1
  27. package/dist/assets/classDiagram-OUVF2IWQ-BgAZMSbT-BJBeI7ut.js +1 -0
  28. package/dist/assets/classDiagram-v2-EOCWNBFH-DxHTyui1-BJBeI7ut.js +1 -0
  29. package/dist/assets/cynefin-VYW2F7L2-DqA3n9nY-CHrZLRBv.js +1 -0
  30. package/dist/assets/{cynefinDiagram-TSTJHNR4-x0-0sQ15-DFvWQYHV.js → cynefinDiagram-TSTJHNR4-x0-0sQ15-B3DfOJaL.js} +1 -1
  31. package/dist/assets/{dagre-VKFMJZFB-CQdfl-bx-C6RuILUX.js → dagre-VKFMJZFB-CQdfl-bx-Bf4AA431.js} +1 -1
  32. package/dist/assets/{diagram-FQU43EPY-BOSB6VUb-37ofKWUh.js → diagram-FQU43EPY-BOSB6VUb-BO7S37GV.js} +1 -1
  33. package/dist/assets/{diagram-G47NLZAW-DLXrcXsN-BtcZ-NrA.js → diagram-G47NLZAW-DLXrcXsN-Cw4lBqWi.js} +1 -1
  34. package/dist/assets/{diagram-NH7WQ7WH-BMQp1rkF-Cu-opGPx.js → diagram-NH7WQ7WH-BMQp1rkF-B4OObXRC.js} +1 -1
  35. package/dist/assets/{diagram-OA4YK3LP-D1wQ0vUj-BOSp2edG.js → diagram-OA4YK3LP-D1wQ0vUj-CbSsGWhY.js} +1 -1
  36. package/dist/assets/{diagram-WEI45ONY-RR0DpF8R-o2o8fkEM.js → diagram-WEI45ONY-RR0DpF8R-CkVYiUn6.js} +1 -1
  37. package/dist/assets/{ebnfDiagram-CCIWWBDH-M123uVJ8-BLZrCpJZ.js → ebnfDiagram-CCIWWBDH-M123uVJ8-BIFkvee9.js} +1 -1
  38. package/dist/assets/{erDiagram-Q63AITRT-BWx_-PXG-CdDm8yUq.js → erDiagram-Q63AITRT-BWx_-PXG-DhFy59tl.js} +1 -1
  39. package/dist/assets/eventmodeling-45OFAUF4-_BVSjAXf-Dows47_h.js +1 -0
  40. package/dist/assets/flowDiagram-23GEKE2U-BeOc_anm-D8EOvOHn.js +1 -0
  41. package/dist/assets/{ganttDiagram-NO4QXBWP-BOoJ1eTw-Bz7l9tCX.js → ganttDiagram-NO4QXBWP-BOoJ1eTw-Cy64oRyD.js} +1 -1
  42. package/dist/assets/gitGraph-TEB2WS4Q-CH12KLTN-D0iLvwj3.js +1 -0
  43. package/dist/assets/{gitGraphDiagram-IHSO6WYX-B2CJhk_G-C1K6Dh6P.js → gitGraphDiagram-IHSO6WYX-B2CJhk_G-Do02StAh.js} +1 -1
  44. package/dist/assets/index-CkheN-4M.css +1 -0
  45. package/dist/assets/index-D7iecJBA.js +607 -0
  46. package/dist/assets/info-DKCQHKI2-Cbw3mbiK-BnqrlbY_.js +1 -0
  47. package/dist/assets/{infoDiagram-FWYZ7A6U-Mp1X3pBP-CWP8dYG3.js → infoDiagram-FWYZ7A6U-Mp1X3pBP-CTODYevC.js} +1 -1
  48. package/dist/assets/{ishikawaDiagram-FXEZZL3T-BNG7tkJu-sFnH9pBC.js → ishikawaDiagram-FXEZZL3T-BNG7tkJu-DWG68Fod.js} +1 -1
  49. package/dist/assets/{journeyDiagram-5HDEW3XC-Dbp_hY9X-BmrCa7oX.js → journeyDiagram-5HDEW3XC-Dbp_hY9X-C21LZ7jk.js} +1 -1
  50. package/dist/assets/{kanban-definition-HUTT4EX6-DSTc5u3q-jmvUmh_Z.js → kanban-definition-HUTT4EX6-DSTc5u3q-ahPtq3pf.js} +1 -1
  51. package/dist/assets/{lib-CnI5_dB7.js → lib-Df1jlz1Q.js} +1 -1
  52. package/dist/assets/{line-B1wBwzrY-D2DIxhfm.js → line-B1wBwzrY-DAl65sYb.js} +1 -1
  53. package/dist/assets/{marp-BD3FrYNL.js → marp-D5H57UyA.js} +1 -1
  54. package/dist/assets/{mermaid-parser.core-DC7NPJ_M-E1qyqaHf.js → mermaid-parser.core-DC7NPJ_M-QXgmJCuN.js} +2 -2
  55. package/dist/assets/{mermaid.core-DZM3Ha-E-CIDG7HYi.js → mermaid.core-DZM3Ha-E-B1G-85N2.js} +3 -3
  56. package/dist/assets/{mindmap-definition-LN4V7U3C-DYtgcMsY-_d3mZmSv.js → mindmap-definition-LN4V7U3C-DYtgcMsY-CBnOdPk8.js} +1 -1
  57. package/dist/assets/packet-7NZHBO7P-lwb58iYx-vktMe7EJ.js +1 -0
  58. package/dist/assets/{pegDiagram-2B236MQR-C43eIpKM-qN74Nqg3.js → pegDiagram-2B236MQR-C43eIpKM-hEGXt4rK.js} +1 -1
  59. package/dist/assets/pie-RZYD4A2V-B1UWb4Gu-DQdd8O0g.js +1 -0
  60. package/dist/assets/{pieDiagram-ENE6RG2P-BkTqgJyR-yUPUMjfY.js → pieDiagram-ENE6RG2P-BkTqgJyR-D84c_7gF.js} +1 -1
  61. package/dist/assets/{quadrantDiagram-ABIIQ3AL-Bm1Zjm45-DJGu6JX_.js → quadrantDiagram-ABIIQ3AL-Bm1Zjm45-m6ws2UZn.js} +1 -1
  62. package/dist/assets/radar-I7S5WNFK-7CKcb_l--C24Fc6mu.js +1 -0
  63. package/dist/assets/railroad-3IZDKUUU-gCySKdnW-CZSGevii.js +1 -0
  64. package/dist/assets/railroad-abnf-AHOZXSZD-BophH4r--CUsXkbxZ.js +1 -0
  65. package/dist/assets/railroad-ebnf-EBAXGLYW-AZNjl_Zu-CvkVfCff.js +1 -0
  66. package/dist/assets/railroad-peg-LSFZ7HO6-BSiEEyeb-DVG8HAZ0.js +1 -0
  67. package/dist/assets/{railroadDiagram-RFXS5EU6-BkfbdeAs-DeS-X5M4.js → railroadDiagram-RFXS5EU6-BkfbdeAs-BN3y7GqL.js} +1 -1
  68. package/dist/assets/{requirementDiagram-TGXJPOKE-CrGTTjYg-Z0jwe_3t.js → requirementDiagram-TGXJPOKE-CrGTTjYg-B0zoTBgF.js} +1 -1
  69. package/dist/assets/{sankeyDiagram-HTMAVEWB-rWXPf03Z-1opBvycI.js → sankeyDiagram-HTMAVEWB-rWXPf03Z-XgG2MUCe.js} +1 -1
  70. package/dist/assets/{sequenceDiagram-DBY2YBRQ-nkJYWO2m-CmwooUIR.js → sequenceDiagram-DBY2YBRQ-nkJYWO2m-BxK5UjRj.js} +1 -1
  71. package/dist/assets/{stateDiagram-2N3HPSRC-T4-clK8b-ChdecYpO.js → stateDiagram-2N3HPSRC-T4-clK8b-Y_DtKuon.js} +1 -1
  72. package/dist/assets/stateDiagram-v2-6OUMAXLB-DIp7nhRd-Cehiuymv.js +1 -0
  73. package/dist/assets/{swimlanes-5IMT3BWC-HmQNEntu-Dg13ofec.js → swimlanes-5IMT3BWC-HmQNEntu-D5dAJGJF.js} +1 -1
  74. package/dist/assets/swimlanesDiagram-G3AALYLV-BeoZhwg7-CoSHy1jT.js +8 -0
  75. package/dist/assets/{timeline-definition-FHXFAJF6-CNc9jSTP-Dl_ipjIx.js → timeline-definition-FHXFAJF6-CNc9jSTP-CRCAKMND.js} +1 -1
  76. package/dist/assets/treeView-QDETBFTQ-nIQcG1h9-CWUjubva.js +1 -0
  77. package/dist/assets/treemap-6X3UGDF4-BnsvC8yL-BKgXJcXq.js +1 -0
  78. package/dist/assets/{vennDiagram-L72KCM5P-Dr3pTJ_0-CEbSFm_A.js → vennDiagram-L72KCM5P-Dr3pTJ_0-DIFYkt_z.js} +1 -1
  79. package/dist/assets/wardley-OPB4EBWU-8Odxkx6V-BJhsIgOJ.js +1 -0
  80. package/dist/assets/{wardleyDiagram-EHGQE667-DSFc7ZZa-D7OYqfqr.js → wardleyDiagram-EHGQE667-DSFc7ZZa-BL_kqA2P.js} +1 -1
  81. package/dist/assets/{xychartDiagram-FW5EYKEG-BP0Nn4Pp-DZqTIa7u.js → xychartDiagram-FW5EYKEG-BP0Nn4Pp-q75mTWUr.js} +1 -1
  82. package/dist/index.html +2 -2
  83. package/package.json +12 -12
  84. package/server/agents/codex-sessions.ts +14 -8
  85. package/server/backends/collections.ts +355 -360
  86. package/server/backends/feeds.ts +1 -13
  87. package/server/backends/files.ts +3 -12
  88. package/server/backends/html.ts +3 -12
  89. package/server/backends/remoteHost/getFeed.spec.ts +9 -1
  90. package/server/backends/remoteHost/handlers.spec.ts +9 -1
  91. package/server/backends/remoteHost/handlers.ts +49 -0
  92. package/server/backends/remoteHost/index.ts +19 -2
  93. package/server/backends/remoteHost/sessionActivity.ts +93 -0
  94. package/server/backends/remoteHost/skills.spec.ts +14 -3
  95. package/server/backends/remoteHost/terminalInput.spec.ts +264 -0
  96. package/server/backends/remoteHost/terminalInput.ts +120 -0
  97. package/server/backends/remoteHost/terminalScreen.ts +107 -0
  98. package/server/backends/remoteView.ts +50 -30
  99. package/server/backends/shortcuts.ts +20 -1
  100. package/server/backends/statFileOr404.ts +20 -0
  101. package/server/config/app-config.ts +19 -13
  102. package/server/config/config-routes.ts +2 -14
  103. package/server/config/config-schema.ts +1 -1
  104. package/server/config/dir-config.ts +7 -23
  105. package/server/config/env.ts +21 -0
  106. package/server/config/header-resolve.ts +7 -0
  107. package/server/config/workspace.ts +23 -0
  108. package/server/errors.ts +6 -0
  109. package/server/files/atomic-write.ts +50 -0
  110. package/server/files/dirRequest.ts +30 -0
  111. package/server/files/open-dir.ts +3 -13
  112. package/server/git/dirty-count.ts +8 -0
  113. package/server/git/gh.ts +2 -17
  114. package/server/git/git-status.ts +1 -5
  115. package/server/git/gitRemote.ts +3 -16
  116. package/server/git/pr-for-branch.ts +5 -8
  117. package/server/git/prPhase.ts +121 -0
  118. package/server/git/spawn-collect.ts +23 -0
  119. package/server/git/ttl-cache.ts +24 -0
  120. package/server/git/worktree-diff.ts +1 -5
  121. package/server/git/worktree-pr.ts +5 -19
  122. package/server/git/worktrees.ts +14 -5
  123. package/server/index.ts +299 -1850
  124. package/server/infra/pty-env.ts +73 -0
  125. package/server/infra/sandbox.ts +117 -12
  126. package/server/infra/spawnCapture.ts +6 -0
  127. package/server/infra/tmux.ts +108 -10
  128. package/server/infra/web-push.ts +5 -1
  129. package/server/routes/dir-routes.ts +104 -0
  130. package/server/routes/repo-routes.ts +27 -0
  131. package/server/routes/session-routes.ts +198 -0
  132. package/server/routes/tool-routes.ts +83 -0
  133. package/server/routes/ws-routes.ts +372 -0
  134. package/server/session/activity-hook.ts +84 -7
  135. package/server/session/cost.ts +1 -8
  136. package/server/session/draft-injection.ts +113 -0
  137. package/server/session/handoff-text.ts +49 -0
  138. package/server/session/headlessScreen.ts +50 -0
  139. package/server/session/last-turn.ts +84 -0
  140. package/server/session/project-dir.ts +37 -0
  141. package/server/session/pty-connection.ts +127 -0
  142. package/server/session/pty-spawn.ts +63 -0
  143. package/server/session/pty-text.ts +34 -0
  144. package/server/session/reap-policy.ts +27 -0
  145. package/server/session/registry.ts +163 -0
  146. package/server/session/scheduled-sessions.ts +187 -0
  147. package/server/session/screen-rows.ts +123 -0
  148. package/server/session/session-list.ts +42 -0
  149. package/server/session/session-reads.ts +250 -0
  150. package/server/session/session-resolve.ts +24 -0
  151. package/server/session/shell-command.ts +28 -0
  152. package/server/session/spawn-claude.ts +111 -0
  153. package/server/session/spawn-codex.ts +78 -0
  154. package/server/session/spawn-deps.ts +19 -0
  155. package/server/session/spawn-shell.ts +69 -0
  156. package/server/session/terminal-replay.ts +65 -0
  157. package/server/session/tool-store.ts +169 -0
  158. package/server/session/transcript.ts +27 -2
  159. package/server/session/translation-prompt.ts +28 -0
  160. package/server/session/translation-worker.ts +122 -0
  161. package/server/session/types.ts +88 -0
  162. package/server/session/workPhase.ts +17 -0
  163. package/server/session/ws-frames.ts +51 -0
  164. package/dist/assets/architecture-TIHT7OUA-CYMWc3UT-CGRTzfux.js +0 -1
  165. package/dist/assets/channel-Di5rtkx0-De0a789a.js +0 -1
  166. package/dist/assets/classDiagram-OUVF2IWQ-BgAZMSbT-DVJA3t5B.js +0 -1
  167. package/dist/assets/classDiagram-v2-EOCWNBFH-DxHTyui1-DVJA3t5B.js +0 -1
  168. package/dist/assets/cynefin-VYW2F7L2-DqA3n9nY-BxrBj-DI.js +0 -1
  169. package/dist/assets/eventmodeling-45OFAUF4-_BVSjAXf-BBMcTtjD.js +0 -1
  170. package/dist/assets/flowDiagram-23GEKE2U-BeOc_anm-CofbWT6z.js +0 -1
  171. package/dist/assets/gitGraph-TEB2WS4Q-CH12KLTN-CjuBbb3l.js +0 -1
  172. package/dist/assets/index-BkezQA_M.js +0 -607
  173. package/dist/assets/index-Cn-IsW4P.css +0 -1
  174. package/dist/assets/info-DKCQHKI2-Cbw3mbiK-CKUwdoGo.js +0 -1
  175. package/dist/assets/packet-7NZHBO7P-lwb58iYx-CR5nKx9s.js +0 -1
  176. package/dist/assets/pie-RZYD4A2V-B1UWb4Gu-DPXpPnSu.js +0 -1
  177. package/dist/assets/radar-I7S5WNFK-7CKcb_l--DwucQtaK.js +0 -1
  178. package/dist/assets/railroad-3IZDKUUU-gCySKdnW-TaRPWy67.js +0 -1
  179. package/dist/assets/railroad-abnf-AHOZXSZD-BophH4r--Du2Uw6Rv.js +0 -1
  180. package/dist/assets/railroad-ebnf-EBAXGLYW-AZNjl_Zu-BQzmOlUV.js +0 -1
  181. package/dist/assets/railroad-peg-LSFZ7HO6-BSiEEyeb-B_nc80Sy.js +0 -1
  182. package/dist/assets/stateDiagram-v2-6OUMAXLB-DIp7nhRd-fAwVOT0y.js +0 -1
  183. package/dist/assets/swimlanesDiagram-G3AALYLV-BeoZhwg7-yHexCGwM.js +0 -8
  184. package/dist/assets/treeView-QDETBFTQ-nIQcG1h9-WfWXHBUK.js +0 -1
  185. package/dist/assets/treemap-6X3UGDF4-BnsvC8yL-Dms1rAHj.js +0 -1
  186. package/dist/assets/wardley-OPB4EBWU-8Odxkx6V-Dzf13uaZ.js +0 -1
package/README.md CHANGED
@@ -12,6 +12,10 @@ ping to your phone when a task finishes. One `npx` command, no Electron, no conf
12
12
  npx mulmoterminal # starts on http://localhost:34567 and opens your browser
13
13
  ```
14
14
 
15
+ ![MulmoTerminal's grid view — four live Claude sessions running side by side, each in its own color-coded project](https://raw.githubusercontent.com/receptron/mulmoterminal/main/docs/guide/images/grid-2x2-live.png)
16
+
17
+ *The grid is a **cockpit for parallel agents** — here, four live Claude sessions, each in its own color-coded project. Every cell's header carries what you need to triage at a glance: **model · context %**, **token counts** (`⇡in ⇣out`), the **git branch / changes** chip, and an AI summary of what the agent is doing. A cell's **border color signals state** — working / done (blue), needs-you (amber — e.g. waiting on a permission), idle — with an attention chime so a stuck cell off-screen still pulls you back. Supervise many; only step in where you're called.*
18
+
15
19
  ## Why you'll want it
16
20
 
17
21
  - **See every agent at once.** A grid of live sessions, each cell color-coded by state —
@@ -46,6 +50,10 @@ sidebar lists every session for the project and reflects, in real time, which ar
46
50
  (the agent is thinking) and which **need attention** (waiting for input, or finished with
47
51
  output you haven't seen) — driven by Claude/Codex activity hooks the server injects per spawn.
48
52
 
53
+ ![Single view — one agent in focus, terminal on the left and a GUI panel on the right](https://raw.githubusercontent.com/receptron/mulmoterminal/main/docs/guide/images/single-view.png)
54
+
55
+ *Besides the grid there's a **single view** for focusing on one agent: the conversation/terminal on the left, and a **GUI panel** ("Canvas") on the right where the agent's tool calls render as documents, forms, charts, images, and HTML — not just printed text. Switch between the two with the chat / grid icons in the toolbar.*
56
+
49
57
  **Inserting a file path** — like a native terminal, you can put a file's absolute path into
50
58
  the prompt: **drag a file** onto the terminal (works where the browser exposes the path via
51
59
  `file://` — Firefox/Safari), or click the **📎 file button** in the terminal header, which
@@ -344,6 +352,10 @@ CLAUDE_CWD=/Users/you/my-project
344
352
  The Settings modal (⚙) persists per-user UI choices to `~/.mulmoterminal/config.json`
345
353
  (read/written via `GET`/`POST /api/config`):
346
354
 
355
+ ![The Settings modal — theme, notification sound, PR repos, launch commands, and MCP servers](https://raw.githubusercontent.com/receptron/mulmoterminal/main/docs/guide/images/settings.png)
356
+
357
+ *Open it from the ⚙ button in the toolbar. Pick a **theme**, set a custom **attention sound**, list the repos the cross-repo **PRs & Issues** view should aggregate, add **launch commands** for grid cells, and register your own **MCP servers** — no need to hand-edit the config file.*
358
+
347
359
  | Field | Meaning |
348
360
  | ------------ | ------- |
349
361
  | `cwdPresets` | Quick-pick directories offered when launching a terminal. |
@@ -434,6 +446,10 @@ malformed file is ignored.
434
446
  }
435
447
  ```
436
448
 
449
+ ![Four projects color-coded in the grid, each in its own palette](https://raw.githubusercontent.com/receptron/mulmoterminal/main/docs/guide/images/grid-colors.png)
450
+
451
+ *As cells pile up it gets hard to tell which project is which. Give each repo a **name badge** and its own colors in `.mulmoterminal.json` and they're unmistakable — `headerColor`/`badgeColor` tint the frame, while `colors` reaches all the way into the **terminal's own background and text**. (The example above dresses four repos in Mondrian / van Gogh / Picasso / Matisse palettes.)*
452
+
437
453
  | Field | Meaning |
438
454
  | ------------ | ------- |
439
455
  | `name` | Label shown as a badge in the terminal/cell header. |
@@ -467,6 +483,7 @@ yarn dev:client # Vite dev server only
467
483
 
468
484
  yarn build # type-check (vue-tsc) + vite build -> dist/
469
485
  yarn typecheck:server # type-check the server (tsconfig.server.json)
486
+ yarn typecheck:test # type-check the specs (tsconfig.test*.json)
470
487
  yarn server # run backend; serves dist/ + the APIs on :34567
471
488
  yarn test # vitest run
472
489
  ```
@@ -475,6 +492,12 @@ The backend is TypeScript run directly via `tsx` (no build step); `server/` is
475
492
  type-checked separately through `tsconfig.server.json` (`strict`), kept out of
476
493
  the main `build` so the two type-check independently.
477
494
 
495
+ Specs sit outside both of those projects, and vitest strips types rather than
496
+ checking them — so `yarn typecheck:test` is what keeps them honest. It mirrors
497
+ the same split: `tsconfig.test.json` (client specs, DOM + `.vue`) and
498
+ `tsconfig.test-server.json` (server specs, node). CI runs it alongside the
499
+ other two.
500
+
478
501
  In dev, open the Vite URL; its proxy forwards `/ws`, `/ws/pubsub`, and `/api` to
479
502
  `:34567`. In production, run `yarn build` then `yarn server` and open
480
503
  `http://localhost:34567`.
@@ -610,6 +633,10 @@ separate working tree that shares the repo's `.git`, so several agents can work
610
633
  repo without colliding. Worktrees live under `~/.mulmoterminal/worktrees/` (override with
611
634
  `MULMOTERMINAL_HOME`), and existing ones are listed for reuse.
612
635
 
636
+ ![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)
637
+
638
+ *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.*
639
+
613
640
  A worktree cell's header carries a **diff badge** (`+<commits> ●<dirty>`); click it for a
614
641
  **Changes vs `<base>`** panel (file list + patch) with actions:
615
642
 
@@ -635,6 +662,10 @@ independently. Backed by `GET /api/prs` and `GET /api/issues`.
635
662
  Each grid cell's header shows two badges for its session, refreshed when a turn finishes
636
663
  (from `GET /api/session/:id`):
637
664
 
665
+ ![A live Claude cell — the header shows the model·context and token badges this section describes](https://raw.githubusercontent.com/receptron/mulmoterminal/main/docs/guide/images/grid-cell-live.png)
666
+
667
+ *Both badges, live on a real Claude session: **`Opus · ctx 5%`** (model family + how full its context window is) and **`⇡427k ⇣1.8k`** (cumulative input / output tokens for the session). They sit in the header's first row alongside the **status dot**, directory, and **git chip** (`⎇ main ●2`), with what the agent is doing to the right; the icon buttons and the **timeline** (🕘) of tool calls are on the second row.*
668
+
638
669
  - **Context badge** — e.g. `Opus · ctx 35%`: the model family plus how full its context
639
670
  window is (the *last* turn's input + cache tokens ÷ the model's window — **1M** for
640
671
  current-gen Opus / Sonnet / Fable, **200k** otherwise; an unknown model shows the label
@@ -692,8 +723,21 @@ Favorited collections get their own toolbar buttons.
692
723
  (pulsing blue), **blocked** (amber — needs a permission / answer), **done** (blue —
693
724
  finished, output unreviewed), and **idle** — and the toolbar shows a tally across all
694
725
  pages so you notice an off-screen cell that needs you.
726
+ - **Zoom & filmstrip** — a cell's **⤢** enlarges one agent while the rest shrink to
727
+ thumbnails in a bottom **filmstrip**; click a thumbnail to switch, **⤡** to return to the
728
+ grid — so you can flip between "see everything" and "focus on one" in a click.
729
+
730
+ ![Zoom — one agent enlarged, the others as a filmstrip along the bottom](https://raw.githubusercontent.com/receptron/mulmoterminal/main/docs/guide/images/grid-zoom.png)
731
+
695
732
  - **Timeline** (🕘) — a read-only per-session activity timeline (tools run, newest first),
696
733
  from `GET /api/transcript/timeline`.
734
+ - **Bring another cell's turn here** (💬) — pick another terminal in the grid and its
735
+ **last completed turn** is pasted into *this* cell's input box, so you can have Claude
736
+ and Codex look at each other's work (or pull in a session running in a different repo).
737
+ The excerpt comes from the agent's own log, not the screen buffer, so it carries no
738
+ ANSI debris and nothing lost to scrollback. It is **pasted, never sent** — you read
739
+ what arrived and press Enter, in the cell you were already in. A turn still running
740
+ isn't available yet (Codex writes its rollout only once the turn ends).
697
741
  - **Tools pane** — the available GUI tools plus a live tool-call history for the active
698
742
  session.
699
743
  - **Notifications** (🔔) — a toolbar bell with an unread badge and a dropdown of active
@@ -859,6 +903,7 @@ same-origin-guarded.
859
903
  | `GET /api/codex/sessions?cwd=` | Codex sessions for the project (from `~/.codex` rollouts), newest first. |
860
904
  | `GET /api/cost?cwd=&session=` | Estimated $ cost — session / today / month. |
861
905
  | `GET /api/transcript/timeline?session=&cwd=` | Per-session activity timeline (tools run). |
906
+ | `GET /api/transcript/last-turn?session=&cwd=&agent=` | A session's last completed exchange (`prompt`, `reply`) plus the `text` to paste into another terminal. `agent=codex` reads the codex rollout instead of the Claude transcript. |
862
907
 
863
908
  **Git & worktrees**
864
909
 
@@ -0,0 +1,2 @@
1
+ export declare function fetchLatestVersion(pkg?: string): Promise<string | null>;
2
+ export declare function isNewerVersion(latest: string, current: string): boolean;
@@ -0,0 +1,20 @@
1
+ // The name + fixed-color fields a `.mulmoterminal.json` may set. Shared across the
2
+ // build boundary: the server's DirConfig/PublicDirConfig and the client's DirConfig
3
+ // all extend this, so a field added on one side can't go missing on the other.
4
+ // `theme` and `colors` stay out of it — each side declares them with its own type
5
+ // (the server keeps the validated strings, the client narrows them to xterm's ITheme).
6
+ export interface DirChrome {
7
+ name: string | null;
8
+ badgeColor: string | null;
9
+ // The cell header's own background / text color (grid cell + single view). Hex
10
+ // #rrggbb, or null to keep the theme default. Distinct from `colors` (the xterm
11
+ // palette) — these tint the chrome around the terminal, not the terminal itself.
12
+ headerColor: string | null;
13
+ headerTextColor: string | null;
14
+ // The cell frame + accents (grid cell): body background, border, the idle status
15
+ // dot, and the header's icon buttons. Hex #rrggbb or null for the theme default.
16
+ cellColor: string | null;
17
+ cellBorderColor: string | null;
18
+ dotColor: string | null;
19
+ buttonColor: string | null;
20
+ }
@@ -0,0 +1,6 @@
1
+ // The app's theme ids, shared across the build boundary: the server's zod schema
2
+ // (config-schema.ts) enumerates them and the client (useTheme.ts) types + validates
3
+ // against them. Kept in common/ so adding a theme is one edit, not two that can
4
+ // drift — same reason THEME_COLOR_KEYS lives here (see themeColors.ts).
5
+ export const THEME_IDS = ["midnight", "nord", "daylight", "solarized"] as const;
6
+ export type ThemeId = (typeof THEME_IDS)[number];
@@ -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-DC7NPJ_M-E1qyqaHf.js";import"./chunk-WYO6CB5R-B83L_z6I-Be0VbGoJ.js";import"./chunk-VAUOI2AC-DrcykVNK-BCZszPgC.js";import{n as i,r as a,t as o}from"./chunk-MOJQB5TN-CqxshQHA-QQH5sWOZ.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-DC7NPJ_M-QXgmJCuN.js";import"./chunk-WYO6CB5R-B83L_z6I-ybwRHaqV.js";import"./chunk-VAUOI2AC-DrcykVNK-BSJoRdEM.js";import{n as i,r as a,t as o}from"./chunk-MOJQB5TN-CqxshQHA-rfYFgPHl.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-DC7NPJ_M-QXgmJCuN.js";export{e as createArchitectureServices};