mulmoterminal 1.1.0 → 1.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 +93 -39
- package/bin/mulmoterminal.js +118 -9
- package/common/themeColors.ts +30 -0
- package/dist/assets/{abnfDiagram-VRR7QNED-6nNByj6v-DGtwdUf8.js → abnfDiagram-VRR7QNED-6nNByj6v-SXl7Pz9E.js} +1 -1
- package/dist/assets/architecture-TIHT7OUA-CYMWc3UT-BLPeuYWZ.js +1 -0
- package/dist/assets/{architectureDiagram-ZJ3FMSHR-Bgnyaj_i-DGIWwfAV.js → architectureDiagram-ZJ3FMSHR-Bgnyaj_i-ByCp-wEV.js} +1 -1
- package/dist/assets/{blockDiagram-677ZJIJ3-DQ35o5E4-27RPR53D.js → blockDiagram-677ZJIJ3-DQ35o5E4-Bl7Nl_h2.js} +1 -1
- package/dist/assets/{c4Diagram-LMCZKHZV-ClWZeiWo-CqXuDI4P.js → c4Diagram-LMCZKHZV-ClWZeiWo-W0xATOrs.js} +1 -1
- package/dist/assets/channel-Di5rtkx0-CDk3axJK.js +1 -0
- package/dist/assets/{chunk-32BRIVSS-CCt9wtYd-CGaPp4LL.js → chunk-32BRIVSS-CCt9wtYd-DMNwmMDI.js} +1 -1
- package/dist/assets/{chunk-52WLFC77-FbBbR4uI-UAwhz_M9.js → chunk-52WLFC77-FbBbR4uI-Dq3MyK4L.js} +1 -1
- package/dist/assets/{chunk-C7G6YPKG-C87hlS9c-DedqefeW.js → chunk-C7G6YPKG-C87hlS9c-DR6sYwkH.js} +1 -1
- package/dist/assets/{chunk-EX3LRPZG-BqGqMXLN-Bb1Mz7iv.js → chunk-EX3LRPZG-BqGqMXLN-B5gHdEjC.js} +1 -1
- package/dist/assets/{chunk-FWX5IMBZ-BkbSAAuW-C2rOKQ0W.js → chunk-FWX5IMBZ-BkbSAAuW-CxD2-7BB.js} +2 -2
- package/dist/assets/{chunk-HOUHSVGY-Cxu0eDlh-Di1lybq-.js → chunk-HOUHSVGY-Cxu0eDlh-OVVKeEwm.js} +1 -1
- package/dist/assets/{chunk-ICXQ74PX-hiraF_Xj-CDR-rXNa.js → chunk-ICXQ74PX-hiraF_Xj-PJKyRqdA.js} +1 -1
- package/dist/assets/{chunk-MOJQB5TN-CqxshQHA--ID4cJe7.js → chunk-MOJQB5TN-CqxshQHA-ClImkhQQ.js} +1 -1
- package/dist/assets/{chunk-OGEWGWER-CjCr7ceX-D4uLoRem.js → chunk-OGEWGWER-CjCr7ceX-CY2Ma73l.js} +1 -1
- package/dist/assets/{chunk-PUDLZKDR-Dx6M-vz1-CAsrnK3r.js → chunk-PUDLZKDR-Dx6M-vz1-aQ2PGsaw.js} +1 -1
- package/dist/assets/{chunk-Q4XR5HBZ-CZd-9lTB-BJpdeIug.js → chunk-Q4XR5HBZ-CZd-9lTB-DJ_Gsi-r.js} +1 -1
- package/dist/assets/{chunk-V7JOEXUC-rI0xlC_O-f1PG3F-p.js → chunk-V7JOEXUC-rI0xlC_O-D6bV3CL4.js} +1 -1
- package/dist/assets/{chunk-VAUOI2AC-DrcykVNK-Dj0ZfRKp.js → chunk-VAUOI2AC-DrcykVNK-Bu15Aaxk.js} +1 -1
- package/dist/assets/{chunk-VR4S4FIN-O6iF8Yvf-BUapiHE2.js → chunk-VR4S4FIN-O6iF8Yvf-CmrdITwT.js} +1 -1
- package/dist/assets/{chunk-WYO6CB5R-B83L_z6I-DOF2nExc.js → chunk-WYO6CB5R-B83L_z6I-DnTETCPT.js} +1 -1
- package/dist/assets/{chunk-ZGVPDNZ5-BpFv9JSP-DYPeNPBm.js → chunk-ZGVPDNZ5-BpFv9JSP-DP7ded5M.js} +1 -1
- package/dist/assets/classDiagram-OUVF2IWQ-BgAZMSbT-D29avn_I.js +1 -0
- package/dist/assets/classDiagram-v2-EOCWNBFH-DxHTyui1-D29avn_I.js +1 -0
- package/dist/assets/cynefin-VYW2F7L2-DqA3n9nY-DQ0gBxJi.js +1 -0
- package/dist/assets/{cynefinDiagram-TSTJHNR4-x0-0sQ15-BLbtiLIJ.js → cynefinDiagram-TSTJHNR4-x0-0sQ15-CzU5Upe_.js} +1 -1
- package/dist/assets/{dagre-VKFMJZFB-CQdfl-bx-DZX-S9Hf.js → dagre-VKFMJZFB-CQdfl-bx-DcPeUMz5.js} +1 -1
- package/dist/assets/{diagram-FQU43EPY-BOSB6VUb-DYrk9-JY.js → diagram-FQU43EPY-BOSB6VUb-BIhZHMxB.js} +1 -1
- package/dist/assets/{diagram-G47NLZAW-DLXrcXsN-DMUMSDYC.js → diagram-G47NLZAW-DLXrcXsN-CTlnCEbu.js} +1 -1
- package/dist/assets/{diagram-NH7WQ7WH-BMQp1rkF-DZu3Xn7Y.js → diagram-NH7WQ7WH-BMQp1rkF-UWsfsl2X.js} +1 -1
- package/dist/assets/{diagram-OA4YK3LP-D1wQ0vUj-Ctkx0KEb.js → diagram-OA4YK3LP-D1wQ0vUj-Dv508zmC.js} +1 -1
- package/dist/assets/{diagram-WEI45ONY-RR0DpF8R-sQWvPoC1.js → diagram-WEI45ONY-RR0DpF8R-oEv5L1jw.js} +1 -1
- package/dist/assets/{ebnfDiagram-CCIWWBDH-M123uVJ8-edZCdQvS.js → ebnfDiagram-CCIWWBDH-M123uVJ8-D6Ske4uz.js} +1 -1
- package/dist/assets/{erDiagram-Q63AITRT-BWx_-PXG-CfR7msPF.js → erDiagram-Q63AITRT-BWx_-PXG-DKU24WNu.js} +1 -1
- package/dist/assets/eventmodeling-45OFAUF4-_BVSjAXf-u1qXGZdu.js +1 -0
- package/dist/assets/flowDiagram-23GEKE2U-BeOc_anm-CebM21zg.js +1 -0
- package/dist/assets/{ganttDiagram-NO4QXBWP-BOoJ1eTw-B73WAEs4.js → ganttDiagram-NO4QXBWP-BOoJ1eTw-DsO3nVYw.js} +1 -1
- package/dist/assets/gitGraph-TEB2WS4Q-CH12KLTN-C8kyxDSz.js +1 -0
- package/dist/assets/{gitGraphDiagram-IHSO6WYX-B2CJhk_G-D2IbZUGe.js → gitGraphDiagram-IHSO6WYX-B2CJhk_G-Dlxf3f4I.js} +1 -1
- package/dist/assets/index-B9r3UpP9.js +607 -0
- package/dist/assets/{index-SBAFcRMP.css → index-Cn-IsW4P.css} +1 -1
- package/dist/assets/info-DKCQHKI2-Cbw3mbiK-DQ383tsK.js +1 -0
- package/dist/assets/{infoDiagram-FWYZ7A6U-Mp1X3pBP-C20vVR0c.js → infoDiagram-FWYZ7A6U-Mp1X3pBP-eZYyiKdU.js} +1 -1
- package/dist/assets/{ishikawaDiagram-FXEZZL3T-BNG7tkJu-Dtf3IBKS.js → ishikawaDiagram-FXEZZL3T-BNG7tkJu-BCRoZI5q.js} +1 -1
- package/dist/assets/{journeyDiagram-5HDEW3XC-Dbp_hY9X-Z7iGrqwh.js → journeyDiagram-5HDEW3XC-Dbp_hY9X-CQxKREvH.js} +1 -1
- package/dist/assets/{kanban-definition-HUTT4EX6-DSTc5u3q-js-QvcYr.js → kanban-definition-HUTT4EX6-DSTc5u3q-DQIQ6_6J.js} +1 -1
- package/dist/assets/lib-Bbtb-Tqy.js +9 -0
- package/dist/assets/{line-B1wBwzrY-yLbpFjgh.js → line-B1wBwzrY-CwMW4Ip5.js} +1 -1
- package/dist/assets/{marp-8yMkefyS.js → marp-enphU_re.js} +6 -6
- package/dist/assets/material-symbols-outlined-BmmV8Mzf.woff2 +0 -0
- package/dist/assets/{mermaid-parser.core-DC7NPJ_M-IqvgPv4-.js → mermaid-parser.core-DC7NPJ_M-BaedRaqr.js} +2 -2
- package/dist/assets/{mermaid.core-DZM3Ha-E-964Ly4Uk.js → mermaid.core-DZM3Ha-E-rdYjJS0p.js} +3 -3
- package/dist/assets/{mindmap-definition-LN4V7U3C-DYtgcMsY-DzFenrqW.js → mindmap-definition-LN4V7U3C-DYtgcMsY-K6uJeeEh.js} +1 -1
- package/dist/assets/packet-7NZHBO7P-lwb58iYx-OSHU1XSi.js +1 -0
- package/dist/assets/{pegDiagram-2B236MQR-C43eIpKM-CPxm1zaJ.js → pegDiagram-2B236MQR-C43eIpKM-BHW_jqL8.js} +1 -1
- package/dist/assets/pie-RZYD4A2V-B1UWb4Gu-BMIW8vcB.js +1 -0
- package/dist/assets/{pieDiagram-ENE6RG2P-BkTqgJyR-SuQOUJv7.js → pieDiagram-ENE6RG2P-BkTqgJyR-C3oX3607.js} +1 -1
- package/dist/assets/{quadrantDiagram-ABIIQ3AL-Bm1Zjm45-CxN3pVD1.js → quadrantDiagram-ABIIQ3AL-Bm1Zjm45-BfAyRYOK.js} +1 -1
- package/dist/assets/radar-I7S5WNFK-7CKcb_l--ClBO14xv.js +1 -0
- package/dist/assets/railroad-3IZDKUUU-gCySKdnW-BKJlhX5g.js +1 -0
- package/dist/assets/railroad-abnf-AHOZXSZD-BophH4r--DlHUXjG8.js +1 -0
- package/dist/assets/railroad-ebnf-EBAXGLYW-AZNjl_Zu-CD7vm3L5.js +1 -0
- package/dist/assets/railroad-peg-LSFZ7HO6-BSiEEyeb-CjLQ3mQM.js +1 -0
- package/dist/assets/{railroadDiagram-RFXS5EU6-BkfbdeAs-x3RjQYe5.js → railroadDiagram-RFXS5EU6-BkfbdeAs-CdGjVPAR.js} +1 -1
- package/dist/assets/{requirementDiagram-TGXJPOKE-CrGTTjYg-CZVJXiB0.js → requirementDiagram-TGXJPOKE-CrGTTjYg-BD48F8p9.js} +1 -1
- package/dist/assets/{sankeyDiagram-HTMAVEWB-rWXPf03Z-DhdvF4v5.js → sankeyDiagram-HTMAVEWB-rWXPf03Z-B0nk9HyK.js} +1 -1
- package/dist/assets/{sequenceDiagram-DBY2YBRQ-nkJYWO2m-Dvi_zljF.js → sequenceDiagram-DBY2YBRQ-nkJYWO2m-DySViGYI.js} +1 -1
- package/dist/assets/{stateDiagram-2N3HPSRC-T4-clK8b-nnUFeTnz.js → stateDiagram-2N3HPSRC-T4-clK8b-CbTpst0f.js} +1 -1
- package/dist/assets/stateDiagram-v2-6OUMAXLB-DIp7nhRd-DkrXxlOr.js +1 -0
- package/dist/assets/{swimlanes-5IMT3BWC-HmQNEntu-CnEGBQ_x.js → swimlanes-5IMT3BWC-HmQNEntu-Q0AkeKcW.js} +1 -1
- package/dist/assets/swimlanesDiagram-G3AALYLV-BeoZhwg7-Py5ennCb.js +8 -0
- package/dist/assets/{timeline-definition-FHXFAJF6-CNc9jSTP-DzXY5BW4.js → timeline-definition-FHXFAJF6-CNc9jSTP-F72NAE1C.js} +1 -1
- package/dist/assets/treeView-QDETBFTQ-nIQcG1h9-DFzFH7by.js +1 -0
- package/dist/assets/treemap-6X3UGDF4-BnsvC8yL-C2_STcPQ.js +1 -0
- package/dist/assets/{vennDiagram-L72KCM5P-Dr3pTJ_0-Cz_J7qhF.js → vennDiagram-L72KCM5P-Dr3pTJ_0-CJVPekI4.js} +1 -1
- package/dist/assets/wardley-OPB4EBWU-8Odxkx6V-NAb8M8y5.js +1 -0
- package/dist/assets/{wardleyDiagram-EHGQE667-DSFc7ZZa-dN8C2khV.js → wardleyDiagram-EHGQE667-DSFc7ZZa-tG3BfHqv.js} +1 -1
- package/dist/assets/{xychartDiagram-FW5EYKEG-BP0Nn4Pp-BhdsqgjF.js → xychartDiagram-FW5EYKEG-BP0Nn4Pp-CmU7AEjl.js} +1 -1
- package/dist/index.html +2 -2
- package/package.json +29 -17
- package/plugins/plugins.json +3 -1
- package/server/backends/artifacts.ts +6 -43
- package/server/backends/collections.ts +59 -10
- package/server/backends/fileChange.ts +1 -1
- package/server/backends/fileOps.ts +101 -0
- package/server/backends/google.ts +118 -0
- package/server/backends/hostLogger.ts +9 -0
- package/server/backends/mulmoscript.spec.ts +123 -0
- package/server/backends/mulmoscript.ts +200 -0
- package/server/backends/notifier.ts +1 -1
- package/server/backends/remoteHost/googleCalendar.spec.ts +227 -0
- package/server/backends/remoteHost/googleCalendar.ts +131 -0
- package/server/backends/remoteHost/handlers.spec.ts +4 -0
- package/server/backends/remoteHost/handlers.ts +12 -0
- package/server/backends/remoteHost/skills.ts +1 -1
- package/server/backends/thumbnailStore.ts +1 -1
- package/server/backends/workspaceSetup.ts +1 -1
- package/server/cli-google.ts +74 -0
- package/server/cli-init.ts +101 -0
- package/server/{config-schema.ts → config/config-schema.ts} +2 -28
- package/server/config/cwd-presets.ts +78 -0
- package/server/{header-config.ts → config/header-config.ts} +0 -2
- package/server/{header-context.ts → config/header-context.ts} +3 -3
- package/server/{header-title.ts → config/header-title.ts} +3 -3
- package/server/{open-dir.ts → files/open-dir.ts} +1 -1
- package/server/git/ghItem.ts +24 -0
- package/server/{issues.ts → git/issues.ts} +4 -20
- package/server/{prs.ts → git/prs.ts} +10 -18
- package/server/index.ts +95 -36
- package/server/infra/collection-tool.ts +40 -0
- package/server/{host-tools.ts → infra/host-tools.ts} +5 -1
- package/server/{install-config-skill.ts → infra/install-config-skill.ts} +4 -3
- package/server/infra/pluginRuntime.ts +108 -0
- package/server/{plugins-registry.ts → infra/plugins-registry.ts} +31 -6
- package/server/{sandbox.ts → infra/sandbox.ts} +2 -1
- package/server/{web-push.ts → infra/web-push.ts} +1 -1
- package/server/mcp/broker.ts +1 -1
- package/server/{command-summary.ts → session/command-summary.ts} +1 -1
- package/bin/update-check.spec.ts +0 -46
- package/dist/assets/architecture-TIHT7OUA-CYMWc3UT-DZ-Znbwf.js +0 -1
- package/dist/assets/channel-Di5rtkx0-DQLsM284.js +0 -1
- package/dist/assets/classDiagram-OUVF2IWQ-BgAZMSbT-DkPZzR8t.js +0 -1
- package/dist/assets/classDiagram-v2-EOCWNBFH-DxHTyui1-DkPZzR8t.js +0 -1
- package/dist/assets/cynefin-VYW2F7L2-DqA3n9nY-BYm2Z0OV.js +0 -1
- package/dist/assets/eventmodeling-45OFAUF4-_BVSjAXf-BkWd65jm.js +0 -1
- package/dist/assets/flowDiagram-23GEKE2U-BeOc_anm-S4lNiAx3.js +0 -1
- package/dist/assets/gitGraph-TEB2WS4Q-CH12KLTN-TRRwXHmK.js +0 -1
- package/dist/assets/index-YA9xgtak.js +0 -357
- package/dist/assets/info-DKCQHKI2-Cbw3mbiK-D8Wk2Q2C.js +0 -1
- package/dist/assets/material-symbols-outlined-DKJDg2oJ.woff2 +0 -0
- package/dist/assets/packet-7NZHBO7P-lwb58iYx-BUFe98QC.js +0 -1
- package/dist/assets/pie-RZYD4A2V-B1UWb4Gu-CW09MPfM.js +0 -1
- package/dist/assets/radar-I7S5WNFK-7CKcb_l--DXFUvOtM.js +0 -1
- package/dist/assets/railroad-3IZDKUUU-gCySKdnW-BU8WcG97.js +0 -1
- package/dist/assets/railroad-abnf-AHOZXSZD-BophH4r--Bsm5mLm7.js +0 -1
- package/dist/assets/railroad-ebnf-EBAXGLYW-AZNjl_Zu-BpVcU0NO.js +0 -1
- package/dist/assets/railroad-peg-LSFZ7HO6-BSiEEyeb-Da2qBADq.js +0 -1
- package/dist/assets/stateDiagram-v2-6OUMAXLB-DIp7nhRd-BviIi3HE.js +0 -1
- package/dist/assets/swimlanesDiagram-G3AALYLV-BeoZhwg7-gz62UWNS.js +0 -8
- package/dist/assets/treeView-QDETBFTQ-nIQcG1h9-DfpLaR6K.js +0 -1
- package/dist/assets/treemap-6X3UGDF4-BnsvC8yL-76EFh-rZ.js +0 -1
- package/dist/assets/wardley-OPB4EBWU-8Odxkx6V-D573z6BH.js +0 -1
- package/server/activity-hook.spec.ts +0 -52
- package/server/activity-state.spec.ts +0 -55
- package/server/agents/registry.spec.ts +0 -44
- package/server/app-config.spec.ts +0 -255
- package/server/backends/collections.spec.ts +0 -662
- package/server/backends/feeds.spec.ts +0 -88
- package/server/backends/fileChange.spec.ts +0 -77
- package/server/backends/files.spec.ts +0 -67
- package/server/backends/html.spec.ts +0 -85
- package/server/backends/notifier.spec.ts +0 -80
- package/server/backends/scheduler.spec.ts +0 -175
- package/server/backends/shortcuts.spec.ts +0 -124
- package/server/backends/thumbnailStore.spec.ts +0 -61
- package/server/backends/translation.spec.ts +0 -133
- package/server/backends/viewToken.spec.ts +0 -111
- package/server/backends/wiki.spec.ts +0 -95
- package/server/backends/worklog.spec.ts +0 -49
- package/server/backends/workspaceSetup.spec.ts +0 -76
- package/server/claude-args.spec.ts +0 -63
- package/server/codex-args.spec.ts +0 -41
- package/server/codex-session.spec.ts +0 -142
- package/server/codex-sessions.spec.ts +0 -96
- package/server/codex-skills.spec.ts +0 -70
- package/server/command-summary.spec.ts +0 -122
- package/server/config-schema.spec.ts +0 -131
- package/server/cost.spec.ts +0 -107
- package/server/cwd-presets.spec.ts +0 -54
- package/server/cwd-presets.ts +0 -40
- package/server/dir-config.spec.ts +0 -269
- package/server/file-cache.spec.ts +0 -48
- package/server/files-browse.spec.ts +0 -81
- package/server/git-status.spec.ts +0 -101
- package/server/gitRemote.spec.ts +0 -157
- package/server/header-config.spec.ts +0 -147
- package/server/header-context.spec.ts +0 -16
- package/server/header-resolve.spec.ts +0 -179
- package/server/header-title.spec.ts +0 -156
- package/server/install-config-skill.spec.ts +0 -103
- package/server/issues.spec.ts +0 -38
- package/server/open-dir.spec.ts +0 -14
- package/server/pick-file.spec.ts +0 -51
- package/server/pr-for-branch.spec.ts +0 -50
- package/server/prs.spec.ts +0 -64
- package/server/sandbox.spec.ts +0 -172
- package/server/scripts.spec.ts +0 -95
- package/server/session-resolve.spec.ts +0 -41
- package/server/spa-fallback.spec.ts +0 -27
- package/server/terminal-replay.spec.ts +0 -41
- package/server/tmux-routes.spec.ts +0 -120
- package/server/tmux.spec.ts +0 -59
- package/server/transcript.spec.ts +0 -390
- package/server/web-push.spec.ts +0 -15
- package/server/worktree-diff.spec.ts +0 -83
- package/server/worktree-pr.spec.ts +0 -101
- package/server/worktree-routes.spec.ts +0 -252
- package/server/worktrees.spec.ts +0 -142
- /package/server/{claude-args.ts → agents/claude-args.ts} +0 -0
- /package/server/{codex-args.ts → agents/codex-args.ts} +0 -0
- /package/server/{codex-session.ts → agents/codex-session.ts} +0 -0
- /package/server/{codex-sessions.ts → agents/codex-sessions.ts} +0 -0
- /package/server/{codex-skills.ts → agents/codex-skills.ts} +0 -0
- /package/server/{app-config.ts → config/app-config.ts} +0 -0
- /package/server/{config-routes.ts → config/config-routes.ts} +0 -0
- /package/server/{dir-config.ts → config/dir-config.ts} +0 -0
- /package/server/{header-resolve.ts → config/header-resolve.ts} +0 -0
- /package/server/{files-browse.ts → files/files-browse.ts} +0 -0
- /package/server/{pick-file.ts → files/pick-file.ts} +0 -0
- /package/server/{scripts.ts → files/scripts.ts} +0 -0
- /package/server/{gh.ts → git/gh.ts} +0 -0
- /package/server/{git-status.ts → git/git-status.ts} +0 -0
- /package/server/{gitRemote.ts → git/gitRemote.ts} +0 -0
- /package/server/{pr-for-branch.ts → git/pr-for-branch.ts} +0 -0
- /package/server/{worktree-diff.ts → git/worktree-diff.ts} +0 -0
- /package/server/{worktree-pr.ts → git/worktree-pr.ts} +0 -0
- /package/server/{worktree-routes.ts → git/worktree-routes.ts} +0 -0
- /package/server/{worktrees.ts → git/worktrees.ts} +0 -0
- /package/server/{accounting-tool.ts → infra/accounting-tool.ts} +0 -0
- /package/server/{pubsub.ts → infra/pubsub.ts} +0 -0
- /package/server/{spa-fallback.ts → infra/spa-fallback.ts} +0 -0
- /package/server/{tmux-routes.ts → infra/tmux-routes.ts} +0 -0
- /package/server/{tmux.ts → infra/tmux.ts} +0 -0
- /package/server/{activity-hook.ts → session/activity-hook.ts} +0 -0
- /package/server/{activity-state.ts → session/activity-state.ts} +0 -0
- /package/server/{cost.ts → session/cost.ts} +0 -0
- /package/server/{file-cache.ts → session/file-cache.ts} +0 -0
- /package/server/{session-resolve.ts → session/session-resolve.ts} +0 -0
- /package/server/{terminal-replay.ts → session/terminal-replay.ts} +0 -0
- /package/server/{transcript.ts → session/transcript.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,28 +1,57 @@
|
|
|
1
1
|
# mulmoterminal
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
3
|
+
**Run a whole team of coding agents from your browser — and actually keep up with them.**
|
|
4
|
+
|
|
5
|
+
MulmoTerminal turns [Claude Code](https://claude.com/claude-code) (and OpenAI's **Codex**)
|
|
6
|
+
into a parallel, observable workspace: many agent sessions at once in a grid, each one
|
|
7
|
+
color-coded so you see at a glance which are **working**, which **need you**, and which are
|
|
8
|
+
**done** — plus rich GUI output, git worktrees with one-click PRs, cost readouts, and a
|
|
9
|
+
ping to your phone when a task finishes. One `npx` command, no Electron, no config.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npx mulmoterminal # starts on http://localhost:34567 and opens your browser
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Why you'll want it
|
|
16
|
+
|
|
17
|
+
- **See every agent at once.** A grid of live sessions, each cell color-coded by state —
|
|
18
|
+
**working** (blue), **blocked / needs a permission** (amber), **done, unreviewed** (blue),
|
|
19
|
+
**idle** — with an attention chime and a toolbar tally, so an off-screen agent that's stuck
|
|
20
|
+
never slips past you. Stop babysitting one terminal; supervise ten.
|
|
21
|
+
- **A GUI for your agents, not just a terminal.** Beside the terminal, a **Canvas** panel
|
|
22
|
+
renders what an agent produces over MCP — **documents, forms, charts, generated images,
|
|
23
|
+
HTML, collection cards** — each drawn by its own plugin. The agent doesn't just print
|
|
24
|
+
text; it hands you an interface.
|
|
25
|
+
- **Get pulled back from anywhere.** A finished background task sends a **Web Push to your
|
|
26
|
+
phone**, and the **RemoteHost** companion lets you watch and start sessions from the phone
|
|
27
|
+
itself — walk away, get pinged, jump back in.
|
|
28
|
+
- **Nothing is lost on a restart.** With `tmux`, every session survives a server crash,
|
|
29
|
+
restart, or `node --watch` reload — a mid-turn agent, a long build, a dev server all keep
|
|
30
|
+
running and reattach when you come back.
|
|
31
|
+
- **Ship without leaving the grid.** Each repo cell shows a **git branch chip**, isolates
|
|
32
|
+
work in a one-click **git worktree**, opens a **diff** panel, and does **commit / push /
|
|
33
|
+
open PR** — so several agents can work the same repo without colliding.
|
|
34
|
+
- **Know what it's costing.** Per-session **context %**, **token**, and **estimated $**
|
|
35
|
+
readouts, an **activity timeline** of tool calls, and **AI-summarized** cell titles and
|
|
36
|
+
command-output explanations — so a wall of parallel agents stays legible.
|
|
37
|
+
- **Make it yours.** Per-directory **themes, colors, and name badges** (`prod` in red,
|
|
38
|
+
`staging` in amber), a configurable header (buttons + info chips), custom attention sounds,
|
|
39
|
+
and Run / Skill menus to launch a project's scripts and `.claude/skills` right inside a cell.
|
|
40
|
+
|
|
41
|
+
### What it is, under the hood
|
|
42
|
+
|
|
43
|
+
Each session runs as a real PTY on the server (the agent CLI in a pseudo-terminal) and is
|
|
44
|
+
streamed to an [xterm.js](https://xtermjs.org/) terminal in the browser over a WebSocket. A
|
|
45
|
+
sidebar lists every session for the project and reflects, in real time, which are **working**
|
|
46
|
+
(the agent is thinking) and which **need attention** (waiting for input, or finished with
|
|
47
|
+
output you haven't seen) — driven by Claude/Codex activity hooks the server injects per spawn.
|
|
48
|
+
|
|
49
|
+
**Inserting a file path** — like a native terminal, you can put a file's absolute path into
|
|
50
|
+
the prompt: **drag a file** onto the terminal (works where the browser exposes the path via
|
|
51
|
+
`file://` — Firefox/Safari), or click the **📎 file button** in the terminal header, which
|
|
52
|
+
asks the local server to open the OS file dialog and inserts the chosen path (works in every
|
|
53
|
+
browser, including Chrome). The path is inserted at the cursor — it is not submitted, so you
|
|
54
|
+
can review it first.
|
|
26
55
|
|
|
27
56
|
---
|
|
28
57
|
|
|
@@ -41,6 +70,27 @@ npm install -g mulmoterminal
|
|
|
41
70
|
mulmoterminal
|
|
42
71
|
```
|
|
43
72
|
|
|
73
|
+
**First-run setup (optional).** `npx mulmoterminal init` checks your environment (Node ≥ 22.9,
|
|
74
|
+
the `claude` CLI, plus optional `tmux` / `gh` / `codex`), seeds the launcher's **directory
|
|
75
|
+
presets** from the projects in your Claude Code history, and writes `~/.mulmoterminal/config.json`.
|
|
76
|
+
It's **idempotent** — re-run it any time to refresh the presets; it overwrites the managed parts
|
|
77
|
+
and keeps your other settings. When `claude` is installed it can hand off to the
|
|
78
|
+
`/mulmoterminal-config` skill for interactive tweaks.
|
|
79
|
+
|
|
80
|
+
**Google account (optional).** Link a Google account to enable the chat's `google` tool and the
|
|
81
|
+
phone's `google.calendar.*` commands: read/create events on any calendar (not just your primary),
|
|
82
|
+
list the calendars you've subscribed to, and read the colour palettes. Sign in from
|
|
83
|
+
**Settings → Google account**, or run `npx mulmoterminal google login` — the CLI is the fallback
|
|
84
|
+
for when you're driving MulmoTerminal from another machine, since consent finishes on a loopback
|
|
85
|
+
listener and needs a browser **on the host**. Either way it needs a Desktop OAuth client JSON saved
|
|
86
|
+
as `~/.secrets/client_secret_*.json`; the refresh token lands in `~/.config/mulmo/google-token.json`
|
|
87
|
+
and is **shared with MulmoClaude**, so one link per machine covers both apps.
|
|
88
|
+
|
|
89
|
+
> **Already linked before the calendar-list / colour features?** They need a read scope your existing
|
|
90
|
+
> link doesn't have, so `listCalendars` (and, in practice, `colors`) fail with an insufficient-scope
|
|
91
|
+
> 403 until you re-authorize: **Settings → Google account → Unlink**, then sign in again (or re-run
|
|
92
|
+
> `google login`). Reading/creating events on your primary calendar keeps working without re-linking.
|
|
93
|
+
|
|
44
94
|
A global install isn't auto-updated, so on startup MulmoTerminal checks npm and
|
|
45
95
|
prints a one-line notice when a newer version is available (`npm i -g mulmoterminal`
|
|
46
96
|
to update). Disable with `MULMOTERMINAL_NO_UPDATE_CHECK=1` (or `NO_UPDATE_NOTIFIER=1`).
|
|
@@ -1083,22 +1133,26 @@ resumed session falls back to any on-disk `ai-title`.
|
|
|
1083
1133
|
server/
|
|
1084
1134
|
index.ts Express app, /api routes, upgrade routing, PTY lifecycle,
|
|
1085
1135
|
session state, hook injection, session discovery, GUI-MCP mount
|
|
1086
|
-
agents/ AgentAdapter seam
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
cost
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1136
|
+
agents/ AgentAdapter seam + per-agent args/sessions: claude.ts,
|
|
1137
|
+
codex.ts, registry.ts, claude-args.ts, codex-args.ts,
|
|
1138
|
+
codex-session(s).ts, codex-skills.ts
|
|
1139
|
+
config/ user + per-directory + header config: app-config.ts,
|
|
1140
|
+
config-routes.ts, config-schema.ts, dir-config.ts,
|
|
1141
|
+
cwd-presets.ts, header-*.ts
|
|
1142
|
+
session/ per-session transcript/activity/cost: transcript.ts,
|
|
1143
|
+
session-resolve.ts, activity-*.ts, cost.ts,
|
|
1144
|
+
command-summary.ts, terminal-replay.ts, file-cache.ts
|
|
1145
|
+
git/ git & GitHub (via gh) + worktrees: git-status.ts, gitRemote.ts,
|
|
1146
|
+
gh.ts, prs.ts, issues.ts, pr-for-branch.ts, worktrees.ts, worktree-*.ts
|
|
1147
|
+
files/ files-browse.ts (contained tree read/write), pick-file.ts,
|
|
1148
|
+
open-dir.ts, scripts.ts (Run-menu script.json loader)
|
|
1149
|
+
infra/ process/transport/misc: tmux.ts, tmux-routes.ts, sandbox.ts,
|
|
1150
|
+
pubsub.ts (socket.io /ws/pubsub), spa-fallback.ts, host-tools.ts,
|
|
1151
|
+
plugins-registry.ts, web-push.ts, install-config-skill.ts, accounting-tool.ts
|
|
1152
|
+
mcp/ per-session MCP broker
|
|
1153
|
+
backends/ wiki, collections, feeds, accounting, notifier,
|
|
1154
|
+
translation, whisper, remote-host, html, files
|
|
1155
|
+
skills/ bundled mulmoterminal-config skill assets
|
|
1102
1156
|
fix-pty-perms.js postinstall: fixes node-pty binary permissions
|
|
1103
1157
|
src/
|
|
1104
1158
|
App.vue Layout; owns the active session + single/grid view
|
package/bin/mulmoterminal.js
CHANGED
|
@@ -11,6 +11,7 @@ import { get as httpGet } from "node:http";
|
|
|
11
11
|
import { createRequire } from "node:module";
|
|
12
12
|
import { createServer } from "node:net";
|
|
13
13
|
import { dirname, join, resolve } from "node:path";
|
|
14
|
+
import { createInterface } from "node:readline";
|
|
14
15
|
import { fileURLToPath } from "node:url";
|
|
15
16
|
import { fetchLatestVersion, isNewerVersion } from "./update-check.js";
|
|
16
17
|
|
|
@@ -46,18 +47,104 @@ function checkForUpdate() {
|
|
|
46
47
|
});
|
|
47
48
|
}
|
|
48
49
|
|
|
49
|
-
|
|
50
|
+
// Detect a CLI on the user's PATH by asking for its version. Intentionally resolves from
|
|
51
|
+
// PATH — detecting the user's installed tools is the whole point of the pre-flight /
|
|
52
|
+
// `init` checks.
|
|
53
|
+
function hasCommand(cmd, versionArg = "--version") {
|
|
50
54
|
try {
|
|
51
|
-
// Intentionally resolves `claude` from the user's PATH — detecting their
|
|
52
|
-
// Claude Code CLI install is the whole point of this pre-flight check.
|
|
53
55
|
// eslint-disable-next-line sonarjs/no-os-command-from-path
|
|
54
|
-
execSync(
|
|
56
|
+
execSync(`${cmd} ${versionArg}`, { stdio: "pipe" });
|
|
55
57
|
return true;
|
|
56
58
|
} catch {
|
|
57
59
|
return false;
|
|
58
60
|
}
|
|
59
61
|
}
|
|
60
62
|
|
|
63
|
+
function claudeInstalled() {
|
|
64
|
+
return hasCommand("claude");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function promptYesNo(question) {
|
|
68
|
+
return new Promise((res) => {
|
|
69
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
70
|
+
rl.question(question, (answer) => {
|
|
71
|
+
rl.close();
|
|
72
|
+
res(/^y(es)?$/i.test(answer.trim()));
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// `npx mulmoterminal init` — idempotent first-run setup. Environment/CLI checks + the
|
|
78
|
+
// optional interactive-config launch live here (PATH-command detection); the config
|
|
79
|
+
// derivation + write is the tsx-run server/cli-init.ts.
|
|
80
|
+
async function runInit(initArgs) {
|
|
81
|
+
log("Setting up MulmoTerminal…\n");
|
|
82
|
+
|
|
83
|
+
const [maj, min] = process.versions.node.split(".").map((n) => Number.parseInt(n, 10));
|
|
84
|
+
const nodeOk = maj > 22 || (maj === 22 && min >= 9);
|
|
85
|
+
console.log(nodeOk ? ` ✓ Node ${process.versions.node}` : ` ✗ Node ${process.versions.node} — MulmoTerminal needs ≥ 22.9`);
|
|
86
|
+
|
|
87
|
+
const hasClaude = claudeInstalled();
|
|
88
|
+
if (hasClaude) {
|
|
89
|
+
console.log(" ✓ Claude Code CLI");
|
|
90
|
+
} else {
|
|
91
|
+
console.log(" ✗ Claude Code CLI — not found");
|
|
92
|
+
console.log(" → npm install -g @anthropic-ai/claude-code (then run `claude` and log in)");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
for (const [cmd, versionArg, why, hint] of [
|
|
96
|
+
["tmux", "-V", "sessions survive a restart", "brew install tmux · apt install tmux"],
|
|
97
|
+
["gh", "--version", "PRs & Issues view + one-click PRs", "https://cli.github.com (then: gh auth login)"],
|
|
98
|
+
["codex", "--version", "run OpenAI Codex as an agent", "npm install -g @openai/codex"],
|
|
99
|
+
]) {
|
|
100
|
+
console.log(hasCommand(cmd, versionArg) ? ` ✓ ${cmd} — ${why}` : ` ○ ${cmd} — optional (${why})\n → ${hint}`);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Config half: derive working-dir presets from Claude history + write config.json.
|
|
104
|
+
console.log("");
|
|
105
|
+
const initExit = await new Promise((res) => {
|
|
106
|
+
const child = spawn(process.execPath, ["--import", "tsx", join(PKG_DIR, "server", "cli-init.ts"), ...initArgs], {
|
|
107
|
+
cwd: PKG_DIR,
|
|
108
|
+
env: { ...process.env },
|
|
109
|
+
stdio: "inherit",
|
|
110
|
+
});
|
|
111
|
+
child.on("exit", (code) => res(code ?? 0));
|
|
112
|
+
});
|
|
113
|
+
if (initExit) {
|
|
114
|
+
process.exitCode = initExit;
|
|
115
|
+
error("Setup did not complete — see the error above.");
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Offer the interactive skill only in a real terminal; a non-TTY run (CI / piped input)
|
|
120
|
+
// must never block waiting on stdin.
|
|
121
|
+
if (hasClaude && process.stdin.isTTY && (await promptYesNo("\nConfigure interactively now with the /mulmoterminal-config skill? [y/N] "))) {
|
|
122
|
+
log("Launching Claude — use /mulmoterminal-config (or just ask it to configure MulmoTerminal).");
|
|
123
|
+
// eslint-disable-next-line sonarjs/no-os-command-from-path
|
|
124
|
+
spawn("claude", ["Use the mulmoterminal-config skill to configure MulmoTerminal."], { stdio: "inherit" });
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (hasClaude) log("Later: run `claude` in any project and use /mulmoterminal-config");
|
|
128
|
+
log("Setup done. Start MulmoTerminal: npx mulmoterminal");
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// `npx mulmoterminal google <command>` — Google account linking. Consent needs a
|
|
132
|
+
// loopback listener on this machine, so it can't be driven from the web UI (a phone
|
|
133
|
+
// browser can't reach 127.0.0.1 here); the flow lives in the tsx-run server/cli-google.ts.
|
|
134
|
+
function runGoogle(googleArgs) {
|
|
135
|
+
return new Promise((res) => {
|
|
136
|
+
const child = spawn(process.execPath, ["--import", "tsx", join(PKG_DIR, "server", "cli-google.ts"), ...googleArgs], {
|
|
137
|
+
cwd: PKG_DIR,
|
|
138
|
+
env: { ...process.env },
|
|
139
|
+
stdio: "inherit",
|
|
140
|
+
});
|
|
141
|
+
child.on("exit", (code) => {
|
|
142
|
+
process.exitCode = code ?? 0;
|
|
143
|
+
res();
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
61
148
|
function pickOpenCommand() {
|
|
62
149
|
if (process.platform === "darwin") return "open";
|
|
63
150
|
if (process.platform === "win32") return "start";
|
|
@@ -225,12 +312,17 @@ function runServer(port, noOpen, cwd, onChild) {
|
|
|
225
312
|
});
|
|
226
313
|
}
|
|
227
314
|
|
|
228
|
-
|
|
229
|
-
|
|
315
|
+
function printHelp() {
|
|
316
|
+
console.log(`
|
|
317
|
+
Usage: npx mulmoterminal [command] [options]
|
|
230
318
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
319
|
+
Commands:
|
|
320
|
+
(none) Start the server (default)
|
|
321
|
+
init First-run setup: check your environment, seed working-directory
|
|
322
|
+
presets from your Claude Code history, and write
|
|
323
|
+
~/.mulmoterminal/config.json (idempotent — safe to re-run)
|
|
324
|
+
google login Link a Google account (browser consent, on this machine) so the
|
|
325
|
+
Calendar tool and the phone's google.calendar.* commands can run
|
|
234
326
|
|
|
235
327
|
Options:
|
|
236
328
|
--cwd <dir> Working directory claude runs in (default: current directory; relative paths allowed)
|
|
@@ -239,6 +331,23 @@ Options:
|
|
|
239
331
|
--version Show version
|
|
240
332
|
--help Show this help
|
|
241
333
|
`);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
async function main() {
|
|
337
|
+
const args = process.argv.slice(2);
|
|
338
|
+
|
|
339
|
+
if (args[0] === "init") {
|
|
340
|
+
await runInit(args.slice(1));
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
if (args[0] === "google") {
|
|
345
|
+
await runGoogle(args.slice(1));
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
350
|
+
printHelp();
|
|
242
351
|
return;
|
|
243
352
|
}
|
|
244
353
|
if (args.includes("--version")) {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// The xterm ITheme keys a `.mulmoterminal.json` `colors` block may override. Shared across
|
|
2
|
+
// the build boundary: the server config schema validates/strips a config against this set,
|
|
3
|
+
// and the client dir-config parser re-checks the server-sanitized response against the same
|
|
4
|
+
// set. Kept in common/ so the two can't drift — a key in one list but not the other would be
|
|
5
|
+
// silently accepted on one side and dropped on the other.
|
|
6
|
+
export const THEME_COLOR_KEYS = [
|
|
7
|
+
"foreground",
|
|
8
|
+
"background",
|
|
9
|
+
"cursor",
|
|
10
|
+
"cursorAccent",
|
|
11
|
+
"selectionBackground",
|
|
12
|
+
"selectionForeground",
|
|
13
|
+
"selectionInactiveBackground",
|
|
14
|
+
"black",
|
|
15
|
+
"red",
|
|
16
|
+
"green",
|
|
17
|
+
"yellow",
|
|
18
|
+
"blue",
|
|
19
|
+
"magenta",
|
|
20
|
+
"cyan",
|
|
21
|
+
"white",
|
|
22
|
+
"brightBlack",
|
|
23
|
+
"brightRed",
|
|
24
|
+
"brightGreen",
|
|
25
|
+
"brightYellow",
|
|
26
|
+
"brightBlue",
|
|
27
|
+
"brightMagenta",
|
|
28
|
+
"brightCyan",
|
|
29
|
+
"brightWhite",
|
|
30
|
+
] as const;
|
|
@@ -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-
|
|
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-BaedRaqr.js";import"./chunk-WYO6CB5R-B83L_z6I-DnTETCPT.js";import"./chunk-VAUOI2AC-DrcykVNK-Bu15Aaxk.js";import{n as i,r as a,t as o}from"./chunk-MOJQB5TN-CqxshQHA-ClImkhQQ.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-BaedRaqr.js";export{e as createArchitectureServices};
|