mulmoterminal 4.2.0 → 4.3.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.md +92 -9
- package/common/toolGroups.ts +37 -0
- package/dist/assets/{abnfDiagram-VRR7QNED-RjiYivmv-Ko4XgYrQ.js → abnfDiagram-VRR7QNED-RjiYivmv-Bdog-CiH.js} +1 -1
- package/dist/assets/architecture-TIHT7OUA-0NsD2xW1-rsT_LNkQ.js +1 -0
- package/dist/assets/{architectureDiagram-ZJ3FMSHR-3nWA91tG-DXXAwU3I.js → architectureDiagram-ZJ3FMSHR-3nWA91tG-DY8jZRJO.js} +1 -1
- package/dist/assets/{blockDiagram-677ZJIJ3-BPuAJQRW-CKecg_L3.js → blockDiagram-677ZJIJ3-BPuAJQRW-CpOQ2oxU.js} +1 -1
- package/dist/assets/{c4Diagram-LMCZKHZV-C0LAqQso-5vO8udpQ.js → c4Diagram-LMCZKHZV-C0LAqQso-CWAcQCwl.js} +1 -1
- package/dist/assets/channel-7wUqSdoX-C_3NKRG1.js +1 -0
- package/dist/assets/{chunk-32BRIVSS-BRrYpgtb-G2dVX9R4.js → chunk-32BRIVSS-BRrYpgtb-BzcHZdCO.js} +1 -1
- package/dist/assets/{chunk-52WLFC77-BJ-ss3Xr-5jRfBwS-.js → chunk-52WLFC77-BJ-ss3Xr-Qq7iypNS.js} +1 -1
- package/dist/assets/{chunk-C7G6YPKG-BZEucKEL-dH1xp00-.js → chunk-C7G6YPKG-BZEucKEL-DU94jTaQ.js} +1 -1
- package/dist/assets/{chunk-EX3LRPZG-DLS6FBN1-Bm_0Dq7o.js → chunk-EX3LRPZG-DLS6FBN1-B8t9ONXm.js} +1 -1
- package/dist/assets/{chunk-FWX5IMBZ-DHLSFw1H-DMe5J-nM.js → chunk-FWX5IMBZ-DHLSFw1H-72qiJJFi.js} +2 -2
- package/dist/assets/{chunk-HOUHSVGY-Bhlt8hXJ-ByrE_Y0q.js → chunk-HOUHSVGY-Bhlt8hXJ-Dh_S4m7L.js} +1 -1
- package/dist/assets/{chunk-ICXQ74PX-DwgHBX_g-C7WGmPMk.js → chunk-ICXQ74PX-DwgHBX_g-i4M4RWjR.js} +1 -1
- package/dist/assets/{chunk-MOJQB5TN-CMZRaeqt-BwgEBlFh.js → chunk-MOJQB5TN-CMZRaeqt-ePkETRCM.js} +1 -1
- package/dist/assets/{chunk-OGEWGWER-8Qy4a8b5-DJR11LQX.js → chunk-OGEWGWER-8Qy4a8b5-BMPSaD1n.js} +1 -1
- package/dist/assets/{chunk-PUDLZKDR-DcrWQRYh-CRXRg8rj.js → chunk-PUDLZKDR-DcrWQRYh-CUfUNRZU.js} +1 -1
- package/dist/assets/{chunk-Q4XR5HBZ-ZXVGkG8Z-CuyNeF8W.js → chunk-Q4XR5HBZ-ZXVGkG8Z-vRCdUFJt.js} +1 -1
- package/dist/assets/{chunk-V7JOEXUC-DmGdheTX-BXL1l6dM.js → chunk-V7JOEXUC-DmGdheTX-BPzQ8JEc.js} +1 -1
- package/dist/assets/{chunk-VAUOI2AC-CS9QJ4yz-o20b35Qf.js → chunk-VAUOI2AC-CS9QJ4yz-DDJgABqC.js} +1 -1
- package/dist/assets/{chunk-VR4S4FIN-C6a91eNY-DcR5TXVW.js → chunk-VR4S4FIN-C6a91eNY-DZS-oJom.js} +1 -1
- package/dist/assets/{chunk-WYO6CB5R-BlzOfotS-CbdIi1Rx.js → chunk-WYO6CB5R-BlzOfotS-DMj-dLn7.js} +1 -1
- package/dist/assets/{chunk-ZGVPDNZ5-BYwxNFTK-DPJ63Ug-.js → chunk-ZGVPDNZ5-BYwxNFTK-tmcZjNpX.js} +1 -1
- package/dist/assets/classDiagram-OUVF2IWQ-BYlRi6YQ-I_77uR8C.js +1 -0
- package/dist/assets/classDiagram-v2-EOCWNBFH-BCHaYHxj-I_77uR8C.js +1 -0
- package/dist/assets/cynefin-VYW2F7L2-CGYr2F6h-BASJNDQ6.js +1 -0
- package/dist/assets/{cynefinDiagram-TSTJHNR4-DHA9iPo--C-vvAO00.js → cynefinDiagram-TSTJHNR4-DHA9iPo--BpiB89n2.js} +1 -1
- package/dist/assets/{dagre-VKFMJZFB--oJKqXBZ-j_nnCAk3.js → dagre-VKFMJZFB--oJKqXBZ-Ddms1XzR.js} +1 -1
- package/dist/assets/{diagram-FQU43EPY-CcJCB9bG-Bg8kALAQ.js → diagram-FQU43EPY-CcJCB9bG-BAHWVmAY.js} +1 -1
- package/dist/assets/{diagram-G47NLZAW-C_o-WGG1-D8IYmNOo.js → diagram-G47NLZAW-C_o-WGG1-DdaYFG9H.js} +1 -1
- package/dist/assets/{diagram-NH7WQ7WH-CXJCYvY--ntIh1pVU.js → diagram-NH7WQ7WH-CXJCYvY--CHgaNPap.js} +1 -1
- package/dist/assets/{diagram-OA4YK3LP-BMzeJ87A-1rD8ncO1.js → diagram-OA4YK3LP-BMzeJ87A-C7QgoRtB.js} +1 -1
- package/dist/assets/{diagram-WEI45ONY-D_93NKqo-DWStdu4t.js → diagram-WEI45ONY-D_93NKqo-DK7fOC2g.js} +1 -1
- package/dist/assets/{dist-CpuWpSIw.js → dist-1yVb2v37.js} +1 -1
- package/dist/assets/{dist-QEbKPDTX.js → dist-B8QpBddG.js} +1 -1
- package/dist/assets/{dist-w2lrwfZt.js → dist-BvnEqyXN.js} +1 -1
- package/dist/assets/{dist-C1t_ZgKo.js → dist-N43w-1Uv.js} +1 -1
- package/dist/assets/{ebnfDiagram-CCIWWBDH-CVai1Ii9-uJbtiAJU.js → ebnfDiagram-CCIWWBDH-CVai1Ii9-CVGfPNmr.js} +1 -1
- package/dist/assets/{erDiagram-Q63AITRT-CiABnA0s-C2GoR6NA.js → erDiagram-Q63AITRT-CiABnA0s-DY1yINPc.js} +1 -1
- package/dist/assets/eventmodeling-45OFAUF4-CWmqhm3a-DYbmMHSK.js +1 -0
- package/dist/assets/flowDiagram-23GEKE2U-DKSB5AiY-DxbRE59B.js +1 -0
- package/dist/assets/{ganttDiagram-NO4QXBWP-DQZvdFo1-BM70MIdN.js → ganttDiagram-NO4QXBWP-DQZvdFo1-BFu7XeTn.js} +1 -1
- package/dist/assets/gitGraph-TEB2WS4Q-BR9qPwdN-DDSyOJ1L.js +1 -0
- package/dist/assets/{gitGraphDiagram-IHSO6WYX-C2ovBouh-B_Pgy8IF.js → gitGraphDiagram-IHSO6WYX-C2ovBouh-CVNiO1pR.js} +1 -1
- package/dist/assets/index-C-UrTIoI.css +1 -0
- package/dist/assets/{index-DIMX-Lgi.js → index-CHZiol4M.js} +177 -177
- package/dist/assets/info-DKCQHKI2-Dplx5kMp-bM6jK96q.js +1 -0
- package/dist/assets/{infoDiagram-FWYZ7A6U-7UnoB5AP-Llrz1ikt.js → infoDiagram-FWYZ7A6U-7UnoB5AP-C93AGObv.js} +1 -1
- package/dist/assets/{ishikawaDiagram-FXEZZL3T-ByUDM_N2-DkyrG0F4.js → ishikawaDiagram-FXEZZL3T-ByUDM_N2-B2Dn2jAL.js} +1 -1
- package/dist/assets/{journeyDiagram-5HDEW3XC-c5xIah9o-C6nobV_J.js → journeyDiagram-5HDEW3XC-c5xIah9o-DQk5r-7H.js} +1 -1
- package/dist/assets/{kanban-definition-HUTT4EX6-Cnt6loYD-r8kRECnn.js → kanban-definition-HUTT4EX6-Cnt6loYD-1TZVG0gD.js} +1 -1
- package/dist/assets/{lib-CGMPNazU.js → lib-JfWkHMZA.js} +1 -1
- package/dist/assets/{line-D7ziSjKi-BGdO3L7C.js → line-D7ziSjKi-DhbbwYBs.js} +1 -1
- package/dist/assets/{marp-CYclI9Sp.js → marp-BfY_ww9b.js} +1 -1
- package/dist/assets/{mermaid-parser.core-DxEa8E3F-C7Z349Pq.js → mermaid-parser.core-DxEa8E3F-D6oVwac4.js} +2 -2
- package/dist/assets/{mermaid.core-V0OYwIz3-BAg6sjQI.js → mermaid.core-V0OYwIz3-B6uMFLWJ.js} +3 -3
- package/dist/assets/{mindmap-definition-LN4V7U3C-CexN3O6L-B4euhJCV.js → mindmap-definition-LN4V7U3C-CexN3O6L-B1FJ1HVs.js} +1 -1
- package/dist/assets/packet-7NZHBO7P-CQI3flND-M2i4X2qk.js +1 -0
- package/dist/assets/{pegDiagram-2B236MQR-BiM4G0cW-Brrbufeb.js → pegDiagram-2B236MQR-BiM4G0cW--wr3I5uW.js} +1 -1
- package/dist/assets/pie-RZYD4A2V-CnmKE2Wa-Bd_XkMs5.js +1 -0
- package/dist/assets/{pieDiagram-ENE6RG2P-B_fBBS-2-DognIWKZ.js → pieDiagram-ENE6RG2P-B_fBBS-2-_2feGczD.js} +1 -1
- package/dist/assets/{quadrantDiagram-ABIIQ3AL-BigGVxCR-BPBwmAdC.js → quadrantDiagram-ABIIQ3AL-BigGVxCR-BrtQISoY.js} +1 -1
- package/dist/assets/radar-I7S5WNFK-us6x-Z9R-C3vBieyU.js +1 -0
- package/dist/assets/railroad-3IZDKUUU-BKdz6pdN-CGQcIWsR.js +1 -0
- package/dist/assets/railroad-abnf-AHOZXSZD-m_CSSIfd-jWYezWwF.js +1 -0
- package/dist/assets/railroad-ebnf-EBAXGLYW-Nu3nAG7C-Csc9w5bS.js +1 -0
- package/dist/assets/railroad-peg-LSFZ7HO6--Y3mD4R_-D5bhRRBY.js +1 -0
- package/dist/assets/{railroadDiagram-RFXS5EU6--lNIlG64-5B9Ve7w1.js → railroadDiagram-RFXS5EU6--lNIlG64-Cl00PZJ3.js} +1 -1
- package/dist/assets/{requirementDiagram-TGXJPOKE-D-B0Y5Wu-iRCTL6WF.js → requirementDiagram-TGXJPOKE-D-B0Y5Wu-BBU6_YVY.js} +1 -1
- package/dist/assets/{sankeyDiagram-HTMAVEWB-DlutaXDv-BWx6oil_.js → sankeyDiagram-HTMAVEWB-DlutaXDv-DDG1vVfm.js} +1 -1
- package/dist/assets/{sequenceDiagram-DBY2YBRQ-BOLgtggH-Dyjw8haJ.js → sequenceDiagram-DBY2YBRQ-BOLgtggH-BLRc-c61.js} +1 -1
- package/dist/assets/{stateDiagram-2N3HPSRC-jf_dXUEU-DNMm4FaT.js → stateDiagram-2N3HPSRC-jf_dXUEU-IElGdQ_H.js} +1 -1
- package/dist/assets/stateDiagram-v2-6OUMAXLB-CuzgCL2v-KNFxI9rB.js +1 -0
- package/dist/assets/{swimlanes-5IMT3BWC-CYjtALQH-0aqXIsbo.js → swimlanes-5IMT3BWC-CYjtALQH-DWw64pD1.js} +1 -1
- package/dist/assets/swimlanesDiagram-G3AALYLV-3bmSBtKs-CjVzBocH.js +8 -0
- package/dist/assets/{timeline-definition-FHXFAJF6-DYJ4oUm8-BEW3_bqU.js → timeline-definition-FHXFAJF6-DYJ4oUm8-CmkjOn4R.js} +1 -1
- package/dist/assets/treeView-QDETBFTQ-D27HWG6Q-Db61iIhG.js +1 -0
- package/dist/assets/treemap-6X3UGDF4-CmGIU3H5-DX1IC1yH.js +1 -0
- package/dist/assets/{vennDiagram-L72KCM5P-CdKAHoek-ftlvelkp.js → vennDiagram-L72KCM5P-CdKAHoek-Ch4eXyRT.js} +1 -1
- package/dist/assets/wardley-OPB4EBWU-CbHWsb2k-IFR8KKBh.js +1 -0
- package/dist/assets/{wardleyDiagram-EHGQE667-BF6c4_CW-ND9jAABP.js → wardleyDiagram-EHGQE667-BF6c4_CW-B2NgeiNl.js} +1 -1
- package/dist/assets/{xychartDiagram-FW5EYKEG-CGiKngj7-BbHq6IVI.js → xychartDiagram-FW5EYKEG-CGiKngj7-B544fj9E.js} +1 -1
- package/dist/index.html +2 -2
- package/package.json +1 -1
- package/server/agents/antigravity-mcp.ts +11 -4
- package/server/agents/rate-limit-probe.spec.ts +11 -1
- package/server/config/app-config.ts +24 -4
- package/server/index.ts +4 -1
- package/server/infra/plugins-registry.ts +2 -4
- package/server/mcp/broker.ts +2 -2
- package/server/routes/ws-routes.ts +39 -9
- package/server/session/launcher-gui-mcp.ts +44 -9
- package/server/session/mcp-config.ts +48 -4
- package/server/session/registry.ts +9 -0
- package/server/session/session-settings.ts +9 -0
- package/server/session/spawn-claude.ts +3 -18
- package/server/session/spawn-codex.ts +14 -8
- package/server/session/tmux-size-sync.ts +9 -3
- package/dist/assets/architecture-TIHT7OUA-0NsD2xW1-C_A3J6UT.js +0 -1
- package/dist/assets/channel-7wUqSdoX-CYxVMjfv.js +0 -1
- package/dist/assets/classDiagram-OUVF2IWQ-BYlRi6YQ-D9PYh-Ds.js +0 -1
- package/dist/assets/classDiagram-v2-EOCWNBFH-BCHaYHxj-D9PYh-Ds.js +0 -1
- package/dist/assets/cynefin-VYW2F7L2-CGYr2F6h-BOGZ0d_V.js +0 -1
- package/dist/assets/eventmodeling-45OFAUF4-CWmqhm3a-iI1MrDgd.js +0 -1
- package/dist/assets/flowDiagram-23GEKE2U-DKSB5AiY-CrOlHoXQ.js +0 -1
- package/dist/assets/gitGraph-TEB2WS4Q-BR9qPwdN-DlP31iSf.js +0 -1
- package/dist/assets/index-C1urCATU.css +0 -1
- package/dist/assets/info-DKCQHKI2-Dplx5kMp-3WlBQbJQ.js +0 -1
- package/dist/assets/packet-7NZHBO7P-CQI3flND-CQk0f108.js +0 -1
- package/dist/assets/pie-RZYD4A2V-CnmKE2Wa-CpVaGdmz.js +0 -1
- package/dist/assets/radar-I7S5WNFK-us6x-Z9R-CKmLEdNO.js +0 -1
- package/dist/assets/railroad-3IZDKUUU-BKdz6pdN-oIAJF7wn.js +0 -1
- package/dist/assets/railroad-abnf-AHOZXSZD-m_CSSIfd-B4whEhXF.js +0 -1
- package/dist/assets/railroad-ebnf-EBAXGLYW-Nu3nAG7C-DPRdZSTX.js +0 -1
- package/dist/assets/railroad-peg-LSFZ7HO6--Y3mD4R_-CbVKtvJy.js +0 -1
- package/dist/assets/stateDiagram-v2-6OUMAXLB-CuzgCL2v-DW90BptC.js +0 -1
- package/dist/assets/swimlanesDiagram-G3AALYLV-3bmSBtKs-WTqIMZw2.js +0 -8
- package/dist/assets/treeView-QDETBFTQ-D27HWG6Q-IkkpQPxV.js +0 -1
- package/dist/assets/treemap-6X3UGDF4-CmGIU3H5-DgR55667.js +0 -1
- package/dist/assets/wardley-OPB4EBWU-CbHWsb2k-C-7aQQUL.js +0 -1
package/README.md
CHANGED
|
@@ -8,6 +8,10 @@ coding with a single agent needs nothing but a shell — this is for when you ru
|
|
|
8
8
|
track of which is waiting. Sessions survive a reload (tmux), work isolates in **git worktrees**,
|
|
9
9
|
and a **phone push** reaches you when a turn finishes.
|
|
10
10
|
|
|
11
|
+
**Every cell is a real pty.** `htop`, `lazygit`, a dev server and Claude Code are the same kind
|
|
12
|
+
of object here — which is why the one-session-per-worktree limit applies to **agents only**, and
|
|
13
|
+
a shell or a `yarn dev` launcher can sit in the same worktree an agent is working in.
|
|
14
|
+
|
|
11
15
|
### 📖 Documentation — **[receptron.github.io/mulmoterminal](https://receptron.github.io/mulmoterminal/)**
|
|
12
16
|
|
|
13
17
|
- **User guide:** [English](https://receptron.github.io/mulmoterminal/guide/en/) — the grid
|
|
@@ -386,9 +390,10 @@ today — **Claude Code** (the default), **Codex**, and **Antigravity** (`agy`).
|
|
|
386
390
|
|
|
387
391
|
- **Claude** — spawned as `claude` (override with `CLAUDE_BIN`). The server passes
|
|
388
392
|
`--session-id <uuid>`, so it knows the live session's id even before its transcript
|
|
389
|
-
file exists, and injects activity hooks
|
|
393
|
+
file exists, and injects activity hooks per spawn (see
|
|
390
394
|
[Claude hook injection](#claude-hook-injection)) plus the
|
|
391
395
|
[closing summary](#closing-summary) instruction.
|
|
396
|
+
The **whole** GUI MCP (`--mcp-config` + `--strict-mcp-config`) goes only to a session that is not a grid cell, or to a grid cell whose cwd IS the workspace — `carriesFullGuiMcp` in `server/session/spawn-claude.ts`, which is what gives a workspace cell the tools the single view had before 4.0.0 removed it. That equivalence is about what the session *carries*: a workspace cell is still a grid cell in every other respect. A cell in a project directory attaches neither flag, so Claude Code loads MCP servers the ordinary way — the directory's own local scope, any `.mcp.json` up the tree, and your global ones — including whichever [Canvas switches](#wiki-collections--the-gui-panel) are registered for it.
|
|
392
397
|
- **Codex** — spawned as `codex` (override with `CODEX_BIN`; `CODEX_MODEL` sets
|
|
393
398
|
`--model`). Codex runs on its own WebSocket (`/ws/codex`) and its sessions appear in the
|
|
394
399
|
cockpit roster next to Claude's. Because Codex only mints its rollout id **after** the first
|
|
@@ -547,7 +552,7 @@ The Settings modal (⚙) persists per-user UI choices to `~/.mulmoterminal/confi
|
|
|
547
552
|
| `repoDirs` | `{ "owner/repo": "/abs/path" }` — which local clone work on a repo starts in, when you keep several side by side. Only the *choice* is stored; which clones exist is re-derived from `cwdPresets` on every read, and an entry that no longer names a clone of that repo is ignored. |
|
|
548
553
|
| `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. |
|
|
549
554
|
| `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. |
|
|
550
|
-
| `userMcpServers` | `{ id, url }` HTTP MCP servers merged into the `--mcp-config` of the Claude sessions that carry the full GUI MCP — a cell whose working directory is the **workspace**, and
|
|
555
|
+
| `userMcpServers` | `{ id, url }` HTTP MCP servers merged into the `--mcp-config` of the Claude sessions that carry the full GUI MCP — a cell whose working directory is the **workspace**, and a session the server starts itself (the phone, a scheduled task) unless it asks for a grid cell's shape, as an issue's seed session does (`issueSpawnOptions`). A cell in a project directory loads its own MCP config instead. Takes effect on the next session. |
|
|
551
556
|
| `buttons` | Header action buttons — see [Header buttons](#header-buttons). Omit to keep the defaults; set to replace them. |
|
|
552
557
|
| `chips` | Header info chips (`dir` / `git` / `work` / `diff` / `ctx` / `usage` / `status` / `tools`, or custom text). Omit to keep the default set; `[]` hides all built-ins. `work` shows which PR / issue the cell is on (`#977 → #966`) and clears itself when the PR merges — see the [Configuration guide](https://receptron.github.io/mulmoterminal/guide/en/config.html#work-chip). |
|
|
553
558
|
| `pushEnabled` | `true` to send a **Web Push** to your registered devices. Off by default; only sends while the **RemoteHost** channel is connected (see below). The master switch — `pushKinds` picks which moments. |
|
|
@@ -707,7 +712,7 @@ malformed file is ignored.
|
|
|
707
712
|
| `theme` | xterm palette for terminals in this directory (one of the built-in theme ids). |
|
|
708
713
|
| `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. |
|
|
709
714
|
| `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. |
|
|
710
|
-
| `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
|
|
715
|
+
| `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 sort by it, so a project sits in the same place on both. The one exception is the **workspace** chip, which always leads the launcher's row regardless of any rank — it is not one of the directories being ranked against each other, and it is the one place every GUI tool is reachable (see [MCP server ids](#mcp-server-ids-why-a-workspace-cell-and-a-project-cell-disagree)). |
|
|
711
716
|
| `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. |
|
|
712
717
|
| `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. |
|
|
713
718
|
| `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. |
|
|
@@ -766,7 +771,22 @@ In dev, open the Vite URL; its proxy forwards `/ws`, `/ws/pubsub`, and `/api` to
|
|
|
766
771
|
## Scripts (Run menu)
|
|
767
772
|
|
|
768
773
|
An empty grid cell's launcher sets the **Working directory** by typing, by a preset
|
|
769
|
-
chip, or with the **📁 folder button** (a native OS folder dialog).
|
|
774
|
+
chip, or with the **📁 folder button** (a native OS folder dialog). The preset chips are
|
|
775
|
+
the directories you have launched in; the **workspace** leads them always, marked with an
|
|
776
|
+
icon, whether or not you have ever launched there — it is the one directory where a
|
|
777
|
+
session reaches every GUI tool, so it is never a click you can lose. It has no remove
|
|
778
|
+
button for the same reason.
|
|
779
|
+
|
|
780
|
+
**The launcher is shorter in the workspace**, because two of its choices do not apply
|
|
781
|
+
there. The per-directory **Canvas switches** are replaced by a line saying every GUI tool
|
|
782
|
+
is already available — a session there is handed the whole GUI MCP at spawn, so switches
|
|
783
|
+
would write a registration that `--strict-mcp-config` then ignores. And the **worktree**
|
|
784
|
+
section is hidden: a worktree isolates work on one codebase onto a branch, while the
|
|
785
|
+
workspace is what a session works *from* (the shared wiki, collections and accounting
|
|
786
|
+
live there), which is precisely what a detached branch would cut it off from. Both come
|
|
787
|
+
back the moment you point the field at a project directory.
|
|
788
|
+
|
|
789
|
+
It also offers a
|
|
770
790
|
**run a script** row
|
|
771
791
|
that launches project scripts (a dev server, tests, a build, …) **in that cell, in
|
|
772
792
|
the directory the cell is pointed at** — so a whole workflow lives in one window
|
|
@@ -1046,11 +1066,61 @@ GUI-protocol tools the agent calls — documents (`presentDocument`), forms (`pr
|
|
|
1046
1066
|
generated images, charts, HTML, and collection cards. Each result is drawn by its plugin's
|
|
1047
1067
|
own Vue view inside a Shadow-DOM `PluginFrame` (so a plugin's bundled CSS can't leak),
|
|
1048
1068
|
mirrors the active session, and replays history on re-select. Plugins reach the agent over
|
|
1049
|
-
an **in-process MCP server** served per session at `POST /api/mcp/:sessionId
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1069
|
+
an **in-process MCP server** served per session at `POST /api/mcp/:sessionId`. Which plugins
|
|
1070
|
+
load is gated by `plugins/plugins.json`; the shipped set includes markdown, form, image
|
|
1071
|
+
generation (needs `GEMINI_API_KEY`), chart, HTML, collection, and mulmoscript (MulmoCast
|
|
1072
|
+
video/slides/PDF playback) views. You can also merge your **own HTTP MCP servers** into a
|
|
1073
|
+
workspace session via Settings → `userMcpServers`.
|
|
1074
|
+
|
|
1075
|
+
### MCP server ids: why a workspace cell and a project cell disagree
|
|
1076
|
+
|
|
1077
|
+
A tool is never called by its own name. Every MCP client prefixes it with the id of the server
|
|
1078
|
+
it came from — `mcp__<id>__presentChart` in Claude Code, `mcp-<id>-presentChart` in Codex (which
|
|
1079
|
+
also rewrites `-` in the id to `_`). So the id you register under is repeated on every tool, in
|
|
1080
|
+
every listing, for the life of the session.
|
|
1081
|
+
|
|
1082
|
+
MulmoTerminal delivers the GUI MCP by **two different routes**, and they do not share an id:
|
|
1083
|
+
|
|
1084
|
+
| | Workspace cell / single view | Project-directory grid cell |
|
|
1085
|
+
|---|---|---|
|
|
1086
|
+
| How it arrives | generated per spawn into `--mcp-config` (Claude) or `-c mcp_servers.<id>.url=` (Codex) | the user's OWN per-folder config — `.mcp.json`, `claude mcp add -s local` |
|
|
1087
|
+
| Server id | **`mt`** | **`mulmoterminal-render`**, `-data`, `-media`, `-external` — one per tool group |
|
|
1088
|
+
| Tools carried | all of them, on one URL | only the groups that directory registered |
|
|
1089
|
+
| Tool name looks like | `mcp__mt__presentChart` | `mcp__mulmoterminal-render__presentChart` |
|
|
1090
|
+
|
|
1091
|
+
Which route a session takes is decided by `carriesFullGuiMcp()` in
|
|
1092
|
+
`server/session/mcp-config.ts` — the single view, a cell-less chat, or anything whose cwd **is**
|
|
1093
|
+
the workspace take the first; anything in a project directory takes the second.
|
|
1094
|
+
|
|
1095
|
+
**The workspace is agent-agnostic, and so is the way you start a terminal there.** All three
|
|
1096
|
+
agents and the launcher chips ask the same predicate, so two terminals in the workspace reach
|
|
1097
|
+
the same tools no matter how they were started:
|
|
1098
|
+
|
|
1099
|
+
| Started as | In the workspace | In a project directory |
|
|
1100
|
+
|---|---|---|
|
|
1101
|
+
| claude cell (including `?gui=0`) | `mt`, every tool | the directory's registered groups |
|
|
1102
|
+
| codex cell | `mt`, every tool | the directory's registered groups |
|
|
1103
|
+
| launcher chip running `claude` | `mt`, every tool — flags inserted into the command line | nothing injected; its own `.mcp.json` loads |
|
|
1104
|
+
| launcher chip running `codex` | `mt`, every tool — `-c` overrides inserted | the directory's registered groups |
|
|
1105
|
+
| launcher chip running anything else | untouched | untouched |
|
|
1106
|
+
|
|
1107
|
+
A chip is a command line the user wrote, so the injection is a **rewrite of their text** and is
|
|
1108
|
+
deliberately narrow: only a bare `claude` or `codex` is recognised, and anything else — a wrapper
|
|
1109
|
+
script, `FOO=1 claude` — is passed through unchanged.
|
|
1110
|
+
|
|
1111
|
+
A `claude` chip in the workspace is given `--strict-mcp-config`, same as the cell. That makes the
|
|
1112
|
+
generated config the only source — but it already contains your Settings `userMcpServers`, so
|
|
1113
|
+
**those still load and are still pre-approved**. What stops contributing is a project directory's
|
|
1114
|
+
per-folder `.mcp.json`, which in the workspace is the intent: that file is where the per-group URLs
|
|
1115
|
+
live, and the chip is being handed the all-tools URL instead.
|
|
1116
|
+
|
|
1117
|
+
**The asymmetry is deliberate.** `mt` is ours to name: nothing on disk holds it, it is
|
|
1118
|
+
regenerated on every spawn, so it was shortened to stop paying 17 characters per tool name. The
|
|
1119
|
+
group ids are the opposite — they are keys in config files **users wrote**, they are what the
|
|
1120
|
+
launcher's per-group switch reads back, and they are documented in the setup guide. Renaming
|
|
1121
|
+
them breaks working setups silently, and would need a migration that rewrites existing
|
|
1122
|
+
per-folder configs. Both live in [`common/toolGroups.ts`](common/toolGroups.ts), where the
|
|
1123
|
+
constants carry the same warning.
|
|
1054
1124
|
|
|
1055
1125
|
**Wiki.** The toolbar **Wiki** button opens a read-only browser over `<workspace>/data/wiki/`
|
|
1056
1126
|
— an **index** (tag-filterable page catalog), rendered **pages** with `[[wiki links]]` and
|
|
@@ -1730,6 +1800,19 @@ and `fetch` are mocked so the tests run without a server.
|
|
|
1730
1800
|
|
|
1731
1801
|
---
|
|
1732
1802
|
|
|
1803
|
+
## Who builds this
|
|
1804
|
+
|
|
1805
|
+
MulmoTerminal is built by the **[Singularity Society](https://singularitysociety.org)** team,
|
|
1806
|
+
including **[Satoshi Nakajima](https://x.com/snakajima)** — software architect for **Windows 95**,
|
|
1807
|
+
**Windows 98** and **Internet Explorer 3.0 / 4.0** at Microsoft, later founder of UIEvolution /
|
|
1808
|
+
Xevo, and still building from Seattle.
|
|
1809
|
+
|
|
1810
|
+
It exists because we run several coding agents every day and kept losing track of which one was
|
|
1811
|
+
waiting on us. Everything here was built for that, then kept because it worked. MIT licensed.
|
|
1812
|
+
|
|
1813
|
+
- **Updates** are announced in Japanese on X: [@SingularitySoci](https://x.com/SingularitySoci)
|
|
1814
|
+
- **Sister project:** [MulmoClaude](https://github.com/receptron/mulmoclaude)
|
|
1815
|
+
|
|
1733
1816
|
## Contributing
|
|
1734
1817
|
|
|
1735
1818
|
**Please open an issue rather than a pull request.** Bug reports and feature requests are very
|
package/common/toolGroups.ts
CHANGED
|
@@ -96,8 +96,45 @@ export const toolsInGroup = (group: ToolGroup): string[] => [...GROUP_BY_TOOL].f
|
|
|
96
96
|
// `mcp__<server id>__<tool>`, and the id comes from the USER's config key — so this is a
|
|
97
97
|
// convention the enable-it-for-this-folder affordance has to write, and a user who registers
|
|
98
98
|
// the same URL under another name simply gets permission prompts (nothing breaks).
|
|
99
|
+
//
|
|
100
|
+
// DELIBERATELY long, and deliberately NOT the same id as GUI_SERVER_ID below. The two are
|
|
101
|
+
// reached by different routes (see that constant), so the same tool is named
|
|
102
|
+
// `mcp__mulmoterminal-render__presentChart` in a project cell and `mcp__mt__presentChart` in a
|
|
103
|
+
// workspace one. That is not drift to be tidied up: shortening these would break every
|
|
104
|
+
// `.mcp.json` and `claude mcp add -s local` entry users have already written against them,
|
|
105
|
+
// which the launcher's per-group switch also reads back and the setup guide documents. It needs
|
|
106
|
+
// a migration over existing per-folder configs, not a rename. README's "MCP server ids" section
|
|
107
|
+
// is the long version.
|
|
99
108
|
export const toolGroupServerId = (group: ToolGroup): string => `mulmoterminal-${group}`;
|
|
100
109
|
|
|
110
|
+
// The MCP server id the SINGLE VIEW registers — every tool on one URL, rather than the per-group
|
|
111
|
+
// ids above. Unlike those, a user never writes this one: it is generated per spawn into
|
|
112
|
+
// `--mcp-config` (claude) or `-c mcp_servers.<id>.url=` (codex), so it is ours to name.
|
|
113
|
+
//
|
|
114
|
+
// Which of the two ids a session gets is decided by `carriesFullGuiMcp` in
|
|
115
|
+
// server/session/spawn-claude.ts: the single view, a cell-less chat, and a cell whose cwd IS the
|
|
116
|
+
// workspace carry this one; a cell in a project directory is handed no --mcp-config at all and
|
|
117
|
+
// reaches the group ids through the user's own per-folder config. Both are live, on purpose.
|
|
118
|
+
//
|
|
119
|
+
// It is SHORT because the id is not what the agent sees — the client prefixes every tool with it.
|
|
120
|
+
// claude turns `presentChart` into `mcp__<id>__presentChart` and codex into `mcp-<id>-presentChart`
|
|
121
|
+
// (with `-` in the id normalised to `_`), so a long id is paid on every tool name in every listing.
|
|
122
|
+
// `mulmoterminal-gui` cost 17 characters per tool to say what the surrounding config already says.
|
|
123
|
+
//
|
|
124
|
+
// It had been spelled out at four sites (this server's registration, the advertised server name,
|
|
125
|
+
// the allowedTools prefix and the reserved-id list). It lives here now because both the server and
|
|
126
|
+
// the UI-facing config validation decide from it — see the `common/` rule in CLAUDE.md.
|
|
127
|
+
export const GUI_SERVER_ID = "mt";
|
|
128
|
+
|
|
129
|
+
// Ids this project has shipped for the SAME single-view server before. Not live: kept so the place
|
|
130
|
+
// that must recognise our own past output still does — the Antigravity config merge, which deletes
|
|
131
|
+
// our entries by id and would otherwise leave a stale `mulmoterminal-gui` behind forever.
|
|
132
|
+
//
|
|
133
|
+
// Only where we WROTE them, though. A legacy id is not reserved against the user's own
|
|
134
|
+
// `userMcpServers`: nothing writes it any more, so a server someone names `mulmoterminal-gui`
|
|
135
|
+
// today is reachable and works, and treating it as ours would be claiming a name we abandoned.
|
|
136
|
+
export const LEGACY_GUI_SERVER_IDS: readonly string[] = ["mulmoterminal-gui"];
|
|
137
|
+
|
|
101
138
|
// The tools MulmoTerminal pre-approves via `--allowedTools`, so they run without a permission
|
|
102
139
|
// prompt. A list of TOOLS, not of groups: a group says which tools a directory can reach, and
|
|
103
140
|
// that is not the same question as which may run unattended.
|
|
@@ -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-
|
|
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-D6oVwac4.js";import"./chunk-WYO6CB5R-BlzOfotS-DMj-dLn7.js";import"./chunk-VAUOI2AC-CS9QJ4yz-DDJgABqC.js";import{n as i,r as a,t as o}from"./chunk-MOJQB5TN-CMZRaeqt-ePkETRCM.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-D6oVwac4.js";export{e as createArchitectureServices};
|