mulmoterminal 2.8.0 → 2.9.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 +44 -13
- package/common/fileWriteChannel.ts +6 -0
- package/common/sessionAgent.ts +21 -8
- package/common/terminalSubmit.ts +29 -0
- package/dist/assets/{abnfDiagram-VRR7QNED-RjiYivmv-rGHffQn8.js → abnfDiagram-VRR7QNED-RjiYivmv-FRF8kLeT.js} +1 -1
- package/dist/assets/architecture-TIHT7OUA-0NsD2xW1-DrblApEd.js +1 -0
- package/dist/assets/{architectureDiagram-ZJ3FMSHR-3nWA91tG-ClBqZt07.js → architectureDiagram-ZJ3FMSHR-3nWA91tG-D1pPQlOf.js} +1 -1
- package/dist/assets/{blockDiagram-677ZJIJ3-BPuAJQRW-CRpyIN7j.js → blockDiagram-677ZJIJ3-BPuAJQRW-d5-ljc-N.js} +1 -1
- package/dist/assets/{c4Diagram-LMCZKHZV-C0LAqQso-CP3Nkj32.js → c4Diagram-LMCZKHZV-C0LAqQso-BGlEwCQt.js} +1 -1
- package/dist/assets/channel-7wUqSdoX-BgZgYLWN.js +1 -0
- package/dist/assets/{chunk-32BRIVSS-BRrYpgtb-bBx9h5ar.js → chunk-32BRIVSS-BRrYpgtb-SXiKhjnH.js} +1 -1
- package/dist/assets/{chunk-52WLFC77-BJ-ss3Xr-CJsYFk5u.js → chunk-52WLFC77-BJ-ss3Xr-DKigFAu-.js} +1 -1
- package/dist/assets/{chunk-C7G6YPKG-BZEucKEL-CySmS4KO.js → chunk-C7G6YPKG-BZEucKEL-Cb5wXOXv.js} +1 -1
- package/dist/assets/{chunk-EX3LRPZG-DLS6FBN1-Bd6UgUyI.js → chunk-EX3LRPZG-DLS6FBN1-CzTNcARU.js} +1 -1
- package/dist/assets/{chunk-FWX5IMBZ-DHLSFw1H-NTtO_c6Q.js → chunk-FWX5IMBZ-DHLSFw1H-BZvgg4po.js} +2 -2
- package/dist/assets/{chunk-HOUHSVGY-Bhlt8hXJ-CZ6o_X29.js → chunk-HOUHSVGY-Bhlt8hXJ-DL5Y_3yg.js} +1 -1
- package/dist/assets/{chunk-ICXQ74PX-DwgHBX_g-CLxX8cQ2.js → chunk-ICXQ74PX-DwgHBX_g-BDvSo2KT.js} +1 -1
- package/dist/assets/{chunk-MOJQB5TN-CMZRaeqt-LKJvD71K.js → chunk-MOJQB5TN-CMZRaeqt-BPbi0qBZ.js} +1 -1
- package/dist/assets/{chunk-OGEWGWER-8Qy4a8b5-DaWsU33j.js → chunk-OGEWGWER-8Qy4a8b5-BmITYHk7.js} +1 -1
- package/dist/assets/{chunk-PUDLZKDR-DcrWQRYh-zTDqq542.js → chunk-PUDLZKDR-DcrWQRYh-CXK8yMcj.js} +1 -1
- package/dist/assets/{chunk-Q4XR5HBZ-ZXVGkG8Z-Dtx2iGhH.js → chunk-Q4XR5HBZ-ZXVGkG8Z-SCGIXxMq.js} +1 -1
- package/dist/assets/{chunk-V7JOEXUC-DmGdheTX-BgwCMqp5.js → chunk-V7JOEXUC-DmGdheTX-gZgY507i.js} +1 -1
- package/dist/assets/{chunk-VAUOI2AC-CS9QJ4yz-FXdeVJH3.js → chunk-VAUOI2AC-CS9QJ4yz-BQv37MCq.js} +1 -1
- package/dist/assets/{chunk-VR4S4FIN-C6a91eNY-huBR399y.js → chunk-VR4S4FIN-C6a91eNY-ZNRLU9H7.js} +1 -1
- package/dist/assets/{chunk-WYO6CB5R-BlzOfotS-B9k6Do_6.js → chunk-WYO6CB5R-BlzOfotS-Bx9N57Se.js} +1 -1
- package/dist/assets/{chunk-ZGVPDNZ5-BYwxNFTK-17x7kiDu.js → chunk-ZGVPDNZ5-BYwxNFTK-Bg7w-yJo.js} +1 -1
- package/dist/assets/classDiagram-OUVF2IWQ-BYlRi6YQ-0zi7Cgn2.js +1 -0
- package/dist/assets/classDiagram-v2-EOCWNBFH-BCHaYHxj-0zi7Cgn2.js +1 -0
- package/dist/assets/cynefin-VYW2F7L2-CGYr2F6h-Bi7e0oXc.js +1 -0
- package/dist/assets/{cynefinDiagram-TSTJHNR4-DHA9iPo--BmU0gwz5.js → cynefinDiagram-TSTJHNR4-DHA9iPo--abCAh98z.js} +1 -1
- package/dist/assets/{dagre-VKFMJZFB--oJKqXBZ-Cf0skqxL.js → dagre-VKFMJZFB--oJKqXBZ-CA9PU3rn.js} +1 -1
- package/dist/assets/{diagram-FQU43EPY-CcJCB9bG-XUWMFcgP.js → diagram-FQU43EPY-CcJCB9bG-BgmurMGW.js} +1 -1
- package/dist/assets/{diagram-G47NLZAW-C_o-WGG1-B6HfMZd3.js → diagram-G47NLZAW-C_o-WGG1-CZ6ymH57.js} +1 -1
- package/dist/assets/{diagram-NH7WQ7WH-CXJCYvY--BACwoprc.js → diagram-NH7WQ7WH-CXJCYvY--5Ej1o0wj.js} +1 -1
- package/dist/assets/{diagram-OA4YK3LP-BMzeJ87A-zoxV9d9i.js → diagram-OA4YK3LP-BMzeJ87A-Br_Yz55A.js} +1 -1
- package/dist/assets/{diagram-WEI45ONY-D_93NKqo-e-eIgWvy.js → diagram-WEI45ONY-D_93NKqo-C2UMN3qi.js} +1 -1
- package/dist/assets/{dist-Cm6rSKic.js → dist-C8-kYY50.js} +1 -1
- package/dist/assets/{dist-CX4c9UBB.js → dist-DOaExQFB.js} +1 -1
- package/dist/assets/{dist-BHoD_w15.js → dist-_cuIeZ2Q.js} +1 -1
- package/dist/assets/{dist-BWiUENTZ.js → dist-nsS3Kg7p.js} +1 -1
- package/dist/assets/{ebnfDiagram-CCIWWBDH-CVai1Ii9-DujO8khX.js → ebnfDiagram-CCIWWBDH-CVai1Ii9-DHqre3sw.js} +1 -1
- package/dist/assets/{erDiagram-Q63AITRT-CiABnA0s-DaHESKPI.js → erDiagram-Q63AITRT-CiABnA0s-BO4koo_A.js} +1 -1
- package/dist/assets/eventmodeling-45OFAUF4-CWmqhm3a-BRn6nrMK.js +1 -0
- package/dist/assets/flowDiagram-23GEKE2U-DKSB5AiY-CnFfxuAw.js +1 -0
- package/dist/assets/{ganttDiagram-NO4QXBWP-DQZvdFo1-De_ebWFp.js → ganttDiagram-NO4QXBWP-DQZvdFo1-BpNj4GGQ.js} +1 -1
- package/dist/assets/gitGraph-TEB2WS4Q-BR9qPwdN-65Nmo9BB.js +1 -0
- package/dist/assets/{gitGraphDiagram-IHSO6WYX-C2ovBouh-C4RETxbL.js → gitGraphDiagram-IHSO6WYX-C2ovBouh-C-DD21zp.js} +1 -1
- package/dist/assets/index-Fs9P1rOl.css +1 -0
- package/dist/assets/{index-COmdTh0t.js → index-jKUTVgQT.js} +199 -199
- package/dist/assets/info-DKCQHKI2-Dplx5kMp-BRtvzheB.js +1 -0
- package/dist/assets/{infoDiagram-FWYZ7A6U-7UnoB5AP-DNsURlj_.js → infoDiagram-FWYZ7A6U-7UnoB5AP-Cjtq7aHi.js} +1 -1
- package/dist/assets/{ishikawaDiagram-FXEZZL3T-ByUDM_N2-QyeLiJnO.js → ishikawaDiagram-FXEZZL3T-ByUDM_N2-CJ7Dm1DX.js} +1 -1
- package/dist/assets/{journeyDiagram-5HDEW3XC-c5xIah9o-CFkMurTe.js → journeyDiagram-5HDEW3XC-c5xIah9o-DmEyfShK.js} +1 -1
- package/dist/assets/{kanban-definition-HUTT4EX6-Cnt6loYD-DsoZE32R.js → kanban-definition-HUTT4EX6-Cnt6loYD-CEonRig7.js} +1 -1
- package/dist/assets/{lib-DC86gNgf.js → lib-BP6_kjsB.js} +1 -1
- package/dist/assets/{line-D7ziSjKi-Dz37a1T7.js → line-D7ziSjKi-ZN0lN31b.js} +1 -1
- package/dist/assets/{marp-B-h6KS_6.js → marp-CUPxjfPv.js} +1 -1
- package/dist/assets/{mermaid-parser.core-DxEa8E3F-DteVxl8X.js → mermaid-parser.core-DxEa8E3F-C7AoyBVj.js} +2 -2
- package/dist/assets/{mermaid.core-V0OYwIz3-DAwdqlFZ.js → mermaid.core-V0OYwIz3-CXLOt97m.js} +3 -3
- package/dist/assets/{mindmap-definition-LN4V7U3C-CexN3O6L-B4GX796F.js → mindmap-definition-LN4V7U3C-CexN3O6L-DOiqhmPh.js} +1 -1
- package/dist/assets/packet-7NZHBO7P-CQI3flND-CmU_E5Rs.js +1 -0
- package/dist/assets/{pegDiagram-2B236MQR-BiM4G0cW-BWBzRiaC.js → pegDiagram-2B236MQR-BiM4G0cW-Dxt7poMV.js} +1 -1
- package/dist/assets/pie-RZYD4A2V-CnmKE2Wa-CZEE10z2.js +1 -0
- package/dist/assets/{pieDiagram-ENE6RG2P-B_fBBS-2-CsBnZfAY.js → pieDiagram-ENE6RG2P-B_fBBS-2-COQUiiOs.js} +1 -1
- package/dist/assets/{quadrantDiagram-ABIIQ3AL-BigGVxCR-B1j3aQ5d.js → quadrantDiagram-ABIIQ3AL-BigGVxCR-B-eWI2XH.js} +1 -1
- package/dist/assets/radar-I7S5WNFK-us6x-Z9R-r15uJDA8.js +1 -0
- package/dist/assets/railroad-3IZDKUUU-BKdz6pdN-Dw_fxGlH.js +1 -0
- package/dist/assets/railroad-abnf-AHOZXSZD-m_CSSIfd-CKyTy_kj.js +1 -0
- package/dist/assets/railroad-ebnf-EBAXGLYW-Nu3nAG7C-DKG1VzHP.js +1 -0
- package/dist/assets/railroad-peg-LSFZ7HO6--Y3mD4R_-DfP1SMYD.js +1 -0
- package/dist/assets/{railroadDiagram-RFXS5EU6--lNIlG64-BjmRh1tU.js → railroadDiagram-RFXS5EU6--lNIlG64-DeaxglIg.js} +1 -1
- package/dist/assets/{requirementDiagram-TGXJPOKE-D-B0Y5Wu-UJKUKfTI.js → requirementDiagram-TGXJPOKE-D-B0Y5Wu-1CMezKi3.js} +1 -1
- package/dist/assets/{sankeyDiagram-HTMAVEWB-DlutaXDv-Bsrgx8aw.js → sankeyDiagram-HTMAVEWB-DlutaXDv-D7DwjyX1.js} +1 -1
- package/dist/assets/{sequenceDiagram-DBY2YBRQ-BOLgtggH-BpxKPxVk.js → sequenceDiagram-DBY2YBRQ-BOLgtggH-CsJUqii0.js} +1 -1
- package/dist/assets/{stateDiagram-2N3HPSRC-jf_dXUEU-90vLBL-t.js → stateDiagram-2N3HPSRC-jf_dXUEU-DzQL5WUm.js} +1 -1
- package/dist/assets/stateDiagram-v2-6OUMAXLB-CuzgCL2v-CVaAK8RL.js +1 -0
- package/dist/assets/{swimlanes-5IMT3BWC-CYjtALQH-BQj65nKh.js → swimlanes-5IMT3BWC-CYjtALQH-C0XGpuvl.js} +1 -1
- package/dist/assets/swimlanesDiagram-G3AALYLV-3bmSBtKs-Dgs9N-of.js +8 -0
- package/dist/assets/{timeline-definition-FHXFAJF6-DYJ4oUm8-Brr9I81k.js → timeline-definition-FHXFAJF6-DYJ4oUm8-CV7c2zBI.js} +1 -1
- package/dist/assets/treeView-QDETBFTQ-D27HWG6Q-DBE7pPBH.js +1 -0
- package/dist/assets/treemap-6X3UGDF4-CmGIU3H5-DTrYIIrW.js +1 -0
- package/dist/assets/{vennDiagram-L72KCM5P-CdKAHoek-BFYXaKjS.js → vennDiagram-L72KCM5P-CdKAHoek-D3MiyDV3.js} +1 -1
- package/dist/assets/wardley-OPB4EBWU-CbHWsb2k-JRYl6PcW.js +1 -0
- package/dist/assets/{wardleyDiagram-EHGQE667-BF6c4_CW-BN4fz_6C.js → wardleyDiagram-EHGQE667-BF6c4_CW-CJynIPoh.js} +1 -1
- package/dist/assets/{xychartDiagram-FW5EYKEG-CGiKngj7-CJAizw9P.js → xychartDiagram-FW5EYKEG-CGiKngj7-Co6wcyGy.js} +1 -1
- package/dist/index.html +2 -2
- package/package.json +1 -1
- package/server/agents/rate-limit-probe.spec.ts +55 -2
- package/server/agents/rate-limit-probe.ts +6 -1
- package/server/backends/feed-summary.ts +1 -1
- package/server/backends/remoteHost/collectionPage.ts +10 -4
- package/server/backends/remoteHost/getFeed.spec.ts +2 -1
- package/server/backends/remoteHost/handlers/deps.ts +43 -0
- package/server/backends/remoteHost/handlers/getCollection.ts +17 -0
- package/server/backends/remoteHost/handlers/getFeed.ts +22 -0
- package/server/backends/remoteHost/handlers/getRemoteView.ts +18 -0
- package/server/backends/remoteHost/handlers/getRemoteViewItems.ts +27 -0
- package/server/backends/remoteHost/handlers/index.ts +62 -0
- package/server/backends/remoteHost/handlers/listAccountingBooks.ts +12 -0
- package/server/backends/remoteHost/handlers/listCollections.ts +11 -0
- package/server/backends/remoteHost/handlers/listFeeds.ts +18 -0
- package/server/backends/remoteHost/handlers/listShortcuts.ts +10 -0
- package/server/backends/remoteHost/handlers/listSkills.ts +16 -0
- package/server/backends/remoteHost/handlers/mutateRemoteView.ts +29 -0
- package/server/backends/remoteHost/handlers/startChat.ts +51 -0
- package/server/backends/remoteHost/handlers/terminalSession.ts +63 -0
- package/server/backends/remoteHost/handlers.spec.ts +2 -1
- package/server/backends/remoteHost/index.ts +2 -1
- package/server/backends/remoteHost/terminalInput.spec.ts +166 -19
- package/server/backends/remoteHost/terminalInput.ts +24 -2
- package/server/backends/remoteView.ts +1 -1
- package/server/config/workspace.ts +45 -15
- package/server/files/pick-file.ts +5 -1
- package/server/files/win-folder-dialog.ts +3 -0
- package/server/files/win-powershell-utf8.ts +17 -0
- package/server/index.ts +7 -1
- package/server/routes/app-routes.ts +4 -4
- package/server/routes/dir-routes.ts +30 -22
- package/server/routes/routeParams.ts +19 -1
- package/server/routes/session-routes.ts +13 -11
- package/server/routes/ws-routes.ts +80 -43
- package/server/session/antigravity-conversations.ts +71 -0
- package/server/session/cost.ts +6 -3
- package/server/session/draft-injection.ts +34 -8
- package/server/session/last-turn.ts +0 -4
- package/server/session/registry.ts +52 -2
- package/server/session/session-reads.ts +2 -6
- package/server/session/spawn-antigravity.ts +7 -5
- package/server/session/spawn-claude.ts +7 -3
- package/server/session/tmux-size-sync.ts +0 -2
- package/server/skills/mulmoterminal-notify/SKILL.md +13 -0
- package/dist/assets/architecture-TIHT7OUA-0NsD2xW1-Dg-O9e_V.js +0 -1
- package/dist/assets/channel-7wUqSdoX-Cc3ae2uC.js +0 -1
- package/dist/assets/classDiagram-OUVF2IWQ-BYlRi6YQ-gmGwQCKi.js +0 -1
- package/dist/assets/classDiagram-v2-EOCWNBFH-BCHaYHxj-gmGwQCKi.js +0 -1
- package/dist/assets/cynefin-VYW2F7L2-CGYr2F6h-C5PuFrCb.js +0 -1
- package/dist/assets/eventmodeling-45OFAUF4-CWmqhm3a-D1MuSTYF.js +0 -1
- package/dist/assets/flowDiagram-23GEKE2U-DKSB5AiY-DT6n3-Ft.js +0 -1
- package/dist/assets/gitGraph-TEB2WS4Q-BR9qPwdN-CNsR02rf.js +0 -1
- package/dist/assets/index-BivYtiDo.css +0 -1
- package/dist/assets/info-DKCQHKI2-Dplx5kMp-BeUJlQSg.js +0 -1
- package/dist/assets/packet-7NZHBO7P-CQI3flND-C_pMfWi_.js +0 -1
- package/dist/assets/pie-RZYD4A2V-CnmKE2Wa-bM2FdcNh.js +0 -1
- package/dist/assets/radar-I7S5WNFK-us6x-Z9R-BB9wirGo.js +0 -1
- package/dist/assets/railroad-3IZDKUUU-BKdz6pdN-CbOoELZg.js +0 -1
- package/dist/assets/railroad-abnf-AHOZXSZD-m_CSSIfd-uE3YbEg2.js +0 -1
- package/dist/assets/railroad-ebnf-EBAXGLYW-Nu3nAG7C-u4DQhs69.js +0 -1
- package/dist/assets/railroad-peg-LSFZ7HO6--Y3mD4R_-B2vytEWW.js +0 -1
- package/dist/assets/stateDiagram-v2-6OUMAXLB-CuzgCL2v-B-UjCOGA.js +0 -1
- package/dist/assets/swimlanesDiagram-G3AALYLV-3bmSBtKs-BMxuxpet.js +0 -8
- package/dist/assets/treeView-QDETBFTQ-D27HWG6Q-DvTQoVxm.js +0 -1
- package/dist/assets/treemap-6X3UGDF4-CmGIU3H5-DCrIc8uR.js +0 -1
- package/dist/assets/wardley-OPB4EBWU-CbHWsb2k--RdJ9IY0.js +0 -1
- package/server/backends/remoteHost/handlers.ts +0 -311
package/README.md
CHANGED
|
@@ -74,15 +74,19 @@ npx mulmoterminal@latest # starts on http://localhost:34567 and opens you
|
|
|
74
74
|
|
|
75
75
|
*Zoomed in, the **cockpit roster** replaces thumbnails with information: every session as a
|
|
76
76
|
text row — directory, AI summary, your last prompt, the agent's latest reply, a status word,
|
|
77
|
-
and the branch's **PR phase** badge.
|
|
77
|
+
and the branch's **PR phase** badge. A row whose agent is **waiting on you** rings amber and
|
|
78
|
+
blinks; one that has merely **finished** rings green and stays still (Settings → Waiting rows
|
|
79
|
+
turns the movement off). Click a row to swap the enlarged terminal.*
|
|
78
80
|
|
|
79
81
|
### What it is, under the hood
|
|
80
82
|
|
|
81
83
|
Each session runs as a real PTY on the server (the agent CLI in a pseudo-terminal) and is
|
|
82
84
|
streamed to an [xterm.js](https://xtermjs.org/) terminal in the browser over a WebSocket. A
|
|
83
85
|
sidebar lists every session for the project and reflects, in real time, which are **working**
|
|
84
|
-
(the agent is thinking)
|
|
85
|
-
|
|
86
|
+
(the agent is thinking, a spinner), which are **waiting on you** (a permission prompt or a
|
|
87
|
+
question — an amber dot; nothing proceeds until you answer) and which are **finished with output
|
|
88
|
+
you haven't seen** (a green dot) — driven by Claude/Codex activity hooks the server injects per
|
|
89
|
+
spawn. The horizontal tab bar carries the same two dots.
|
|
86
90
|
|
|
87
91
|

|
|
88
92
|
|
|
@@ -392,7 +396,9 @@ today — **Claude Code** (the default), **Codex**, and **Antigravity** (`agy`).
|
|
|
392
396
|
`--model`). Antigravity runs on its own WebSocket (`/ws/antigravity`). Like Codex it mints its
|
|
393
397
|
own conversation id, so the server watches `~/.gemini/antigravity-cli/brain/` (home overridable
|
|
394
398
|
via `ANTIGRAVITY_HOME`) for the directory the new conversation creates — attributed only when
|
|
395
|
-
unambiguous — and cold-resumes it with `--conversation <id>`.
|
|
399
|
+
unambiguous — and cold-resumes it with `--conversation <id>`. That mapping is appended to
|
|
400
|
+
`~/.mulmoterminal/antigravity-conversations.jsonl`, so a conversation is still resumable after
|
|
401
|
+
the server restarts.
|
|
396
402
|
|
|
397
403
|
Its **GUI tools work differently**, because `agy` takes no MCP flag: it reads its servers from
|
|
398
404
|
`.agents/mcp_config.json` in the working directory. MulmoTerminal writes that file from the
|
|
@@ -1028,8 +1034,8 @@ your **own HTTP MCP servers** into the single-view session via Settings → `use
|
|
|
1028
1034
|
**Wiki.** The toolbar **Wiki** button opens a read-only browser over `<workspace>/data/wiki/`
|
|
1029
1035
|
— an **index** (tag-filterable page catalog), rendered **pages** with `[[wiki links]]` and
|
|
1030
1036
|
backlinks, a **graph** view (pages ranked by references), and a **lint** report (orphans /
|
|
1031
|
-
broken links / tag drift). Read-only endpoints:
|
|
1032
|
-
`/api/wiki/lint`.
|
|
1037
|
+
broken links / tag drift) whose `[[links]]` are clickable too. Read-only endpoints:
|
|
1038
|
+
`GET /api/wiki`, `/api/wiki/graph`, `/api/wiki/lint`.
|
|
1033
1039
|
|
|
1034
1040
|
**Collections.** The toolbar **Collections** button browses the workspace's collection
|
|
1035
1041
|
"cards" (`@mulmoclaude/collection-plugin`). Running a collection **action** fetches a seed
|
|
@@ -1136,13 +1142,32 @@ newest first, including freshly-created sessions that aren't yet written to disk
|
|
|
1136
1142
|
- `500 { "error": string }` on an unexpected filesystem error. A missing project
|
|
1137
1143
|
directory is **not** an error — it yields an empty `sessions` array.
|
|
1138
1144
|
|
|
1145
|
+
### Directories that cannot be used
|
|
1146
|
+
|
|
1147
|
+
Every `?cwd=` — on the terminal sockets and on the read routes alike — names the directory
|
|
1148
|
+
the request is about. When one is named and cannot be used, the server says so instead of
|
|
1149
|
+
quietly answering about the **default workspace** (#1151):
|
|
1150
|
+
|
|
1151
|
+
| Where | What happens |
|
|
1152
|
+
| --- | --- |
|
|
1153
|
+
| `/ws`, `/ws/codex`, `/ws/antigravity`, `/ws/launch`, `/ws/run` | The socket is closed with `{ type: "error", message }`, which the terminal shows as a red banner and does not retry. |
|
|
1154
|
+
| A session that is still running (`?session=` names a live PTY or a surviving tmux session) | **Attaches anyway**, with a warning in the server log. Moving or renaming a directory must not shut you out of an agent that is still working in it — and the cwd reported back comes from the running PTY, not from the request. |
|
|
1155
|
+
| `GET /api/scripts`, `/api/skills`, `/api/dir-config`, `/api/dir-sound`, `/api/git-status`, `/api/pr-phase`, `/api/header`, `/api/sessions`, `/api/codex/sessions`, `/api/session/:id`, `/api/transcript/*`, `/api/cost` | `404 { error, cwd }` — a directory that is not there. |
|
|
1156
|
+
| A `?cwd=` that cannot name a directory at all (relative, or repeated as `?cwd=a&cwd=b`) | `400 { error, cwd }`. |
|
|
1157
|
+
|
|
1158
|
+
A request that names **no** directory is unaffected: `CLAUDE_CWD` is then the answer it
|
|
1159
|
+
asked for. The wording of the refusal is the one a refused spawn already uses, so the same
|
|
1160
|
+
condition reads the same whether it is caught here or by `ptySpawn` itself.
|
|
1161
|
+
|
|
1139
1162
|
### HTTP: `GET /api/scripts`
|
|
1140
1163
|
|
|
1141
1164
|
The runnable entries from `<cwd>/script.json` for a cell's chosen directory
|
|
1142
|
-
(`?cwd=<dir>`,
|
|
1143
|
-
[Scripts (Run menu)](#scripts-run-menu). The resolved `cwd` is echoed back
|
|
1144
|
-
|
|
1145
|
-
|
|
1165
|
+
(`?cwd=<dir>`, or `CLAUDE_CWD` when none is named); see
|
|
1166
|
+
[Scripts (Run menu)](#scripts-run-menu). The resolved `cwd` is echoed back, and each
|
|
1167
|
+
entry carries its `index` (the position the client sends back to `/ws/run`). A `?cwd=`
|
|
1168
|
+
that names a directory the server cannot enter is answered `404 { error, cwd }` rather
|
|
1169
|
+
than with the default workspace's scripts — see
|
|
1170
|
+
[Directories that cannot be used](#directories-that-cannot-be-used).
|
|
1146
1171
|
|
|
1147
1172
|
```jsonc
|
|
1148
1173
|
// GET /api/scripts?cwd=/Users/me/proj
|
|
@@ -1160,8 +1185,8 @@ A missing or invalid `script.json` is **not** an error — it yields an empty
|
|
|
1160
1185
|
|
|
1161
1186
|
### HTTP: `GET /api/skills`
|
|
1162
1187
|
|
|
1163
|
-
The Claude skills discoverable for a terminal's chosen directory (`?cwd=<dir>`,
|
|
1164
|
-
|
|
1188
|
+
The Claude skills discoverable for a terminal's chosen directory (`?cwd=<dir>`, or
|
|
1189
|
+
`CLAUDE_CWD` when none is named) — project scope (`<cwd>/.claude/skills`) plus user scope
|
|
1165
1190
|
(`~/.claude/skills`), deduped by slug (project shadows user), **working-dir skills
|
|
1166
1191
|
first**; see [Skills (Skill menu)](#skills-skill-menu). A `skills` allowlist in that
|
|
1167
1192
|
directory's `.mulmoterminal.json` narrows and reorders the result; absent → all. The
|
|
@@ -1628,13 +1653,19 @@ src/
|
|
|
1628
1653
|
Terminal.vue xterm.js terminal; /ws, /ws/codex, /ws/run
|
|
1629
1654
|
AppToolbar.vue shared header + toolbar buttons
|
|
1630
1655
|
GridView.vue, TerminalGrid.vue, TerminalCell.vue, CommandCell.vue, LauncherCell.vue
|
|
1656
|
+
CellLaunchForm.vue what an EMPTY cell shows: dir + target + resume /
|
|
1657
|
+
scripts / worktrees / tool groups
|
|
1631
1658
|
GuiPanel.vue, PluginFrame.vue GUI panel (Canvas) + Shadow-DOM plugin host
|
|
1632
1659
|
FilesOverlay.vue file browser + CodeMirror editor
|
|
1633
1660
|
GitBranchChip.vue, ModelContextBadge.vue header chips / badges
|
|
1634
1661
|
PrsOverlay.vue cross-repo PRs & Issues
|
|
1635
1662
|
Wiki*View.vue, Collections*.vue, AccountingOverlay.vue workspace views
|
|
1636
1663
|
TimelineOverlay.vue, ToolsPane.vue, NotificationBell.vue, RemoteHostControl.vue
|
|
1637
|
-
SettingsModal.vue ⚙ settings
|
|
1664
|
+
SettingsModal.vue ⚙ settings — the dialog shell + section order
|
|
1665
|
+
settings/ one file per settings section (theme, sounds,
|
|
1666
|
+
web push, google, PR repos, launchers, quick
|
|
1667
|
+
commands, MCP, cost, shortcuts, …), plus the
|
|
1668
|
+
shared SettingsStepper / SettingsListRow
|
|
1638
1669
|
composables/ useSessions, usePubSub, useGitStatus, useCost,
|
|
1639
1670
|
useChatLauncher, useFilesView, useWikiBrowse,
|
|
1640
1671
|
useCollectionBrowse, useNotifications, useVoiceInput, …
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { isRecord } from "./isRecord.js";
|
|
2
|
+
|
|
1
3
|
// The pub/sub channel carrying "an agent just wrote this file". Both sides decide from it —
|
|
2
4
|
// the server publishes, the editor listens to know its open file moved under it — so the name
|
|
3
5
|
// and the payload shape live here rather than as a string literal on each side.
|
|
@@ -7,3 +9,7 @@ export const FILE_WRITE_CHANNEL = "file-write";
|
|
|
7
9
|
export interface FileWriteEvent {
|
|
8
10
|
file: string;
|
|
9
11
|
}
|
|
12
|
+
|
|
13
|
+
/** Both sides go through this rather than re-spelling `{ file: string }`: the publisher pins its
|
|
14
|
+
* payload with `satisfies`, the subscriber narrows an untyped pub/sub frame with it. */
|
|
15
|
+
export const isFileWriteEvent = (data: unknown): data is FileWriteEvent => isRecord(data) && typeof data.file === "string";
|
package/common/sessionAgent.ts
CHANGED
|
@@ -18,12 +18,25 @@ export type TerminalAgent = (typeof TERMINAL_AGENTS)[number];
|
|
|
18
18
|
// persisted cell (written before the field existed) means.
|
|
19
19
|
export const asTerminalAgent = (value: unknown): TerminalAgent => (TERMINAL_AGENTS.some((agent) => agent === value) ? (value as TerminalAgent) : "claude");
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
export interface AgentBadge {
|
|
22
|
+
/** Where there is room for it — a sidebar row, a header bar. */
|
|
23
|
+
full: string;
|
|
24
|
+
/** For the tab bar, which fits about two characters between the dot and the title. */
|
|
25
|
+
short: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Claude has no badge on purpose: it is the default everywhere, so badging it would put one on
|
|
29
|
+
// nearly every row and stop the badge meaning "this one is different". A shell is not an agent
|
|
30
|
+
// and reaches this with no entry, which is the same answer.
|
|
31
|
+
const AGENT_BADGES: Partial<Record<TerminalAgent, AgentBadge>> = {
|
|
32
|
+
codex: { full: "codex", short: "cx" },
|
|
33
|
+
antigravity: { full: "agy", short: "agy" },
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/** How a session row announces which agent it is running, or null when it wears no badge. The one
|
|
37
|
+
* place the wording lives: the sidebar and the tab bar show the SAME list, so a literal compared
|
|
38
|
+
* in each is how the two came to disagree about a third agent. */
|
|
39
|
+
export function agentBadge(agent: string | null | undefined): AgentBadge | null {
|
|
40
|
+
const known = TERMINAL_AGENTS.find((candidate) => candidate === agent);
|
|
41
|
+
return known ? (AGENT_BADGES[known] ?? null) : null;
|
|
29
42
|
}
|
package/common/terminalSubmit.ts
CHANGED
|
@@ -30,6 +30,35 @@ export const newlineSequence = (mode: TerminalSubmitMode): string => (mode === "
|
|
|
30
30
|
// where ESC+CR is Alt+Enter, not submit.
|
|
31
31
|
export const submitSequenceForAgent = (agent: string | undefined, mode: TerminalSubmitMode): string => (agent === "claude" ? submitSequence(mode) : CR);
|
|
32
32
|
|
|
33
|
+
// Text we are about to submit ON the user's behalf, ended so Claude Code has no completion menu
|
|
34
|
+
// open when the submit byte(s) arrive.
|
|
35
|
+
//
|
|
36
|
+
// Claude Code holds a completion menu open while the cursor sits at the end of a completion token
|
|
37
|
+
// — a `/command` or an `@path` — and an open menu consumes the key that should have submitted.
|
|
38
|
+
// Measured against Claude Code 2.1.220:
|
|
39
|
+
//
|
|
40
|
+
// `/help` + CR submits (the one case that always worked)
|
|
41
|
+
// `/help` + ESC CR does NOT submit — the menu's own `escape` binding eats the ESC, so the
|
|
42
|
+
// "esc-cr" submit never lands, however often it is sent
|
|
43
|
+
// `@path` + CR does NOT submit — the file picker takes that CR for itself
|
|
44
|
+
// either + a trailing space submits: the space ends the token, closing the menu
|
|
45
|
+
//
|
|
46
|
+
// So this is NOT specific to the reversed submit mapping (#1142 was reported there, but the
|
|
47
|
+
// `@path` half hits the default mapping too), and it is deliberately not a list of Claude Code's
|
|
48
|
+
// trigger characters: a trigger we failed to enumerate would silently restore a dead end that
|
|
49
|
+
// looks like a broken feature.
|
|
50
|
+
//
|
|
51
|
+
// For auto-submitted text only. A draft the user still edits keeps exactly what was handed over —
|
|
52
|
+
// their own Enter is a keystroke they can retry once they see the menu.
|
|
53
|
+
export const submittableLine = (text: string): string => (/\S$/.test(text) ? `${text} ` : text);
|
|
54
|
+
|
|
55
|
+
// The same Claude-only scoping as submitSequenceForAgent, and for a sharper reason: the completion
|
|
56
|
+
// menu is Claude Code's behaviour, while for every other target the trailing space would be REAL
|
|
57
|
+
// input. A shell line ending in `\` escapes the newline and waits for more (`echo foo\` → a
|
|
58
|
+
// continuation prompt); with a space appended it is an escaped space and runs instead. So a
|
|
59
|
+
// shell/codex/command session's bytes stay exactly what the sender wrote.
|
|
60
|
+
export const submittableLineForAgent = (agent: string | undefined, text: string): string => (agent === "claude" ? submittableLine(text) : text);
|
|
61
|
+
|
|
33
62
|
// The structural shape of a keydown the override needs. A real DOM KeyboardEvent satisfies
|
|
34
63
|
// it, and so does a plain test object — no DOM dependency, so this stays testable and shared.
|
|
35
64
|
export interface EnterKeyEvent {
|
|
@@ -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-C7AoyBVj.js";import"./chunk-WYO6CB5R-BlzOfotS-Bx9N57Se.js";import"./chunk-VAUOI2AC-CS9QJ4yz-BQv37MCq.js";import{n as i,r as a,t as o}from"./chunk-MOJQB5TN-CMZRaeqt-BPbi0qBZ.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-C7AoyBVj.js";export{e as createArchitectureServices};
|