mulmoterminal 4.0.0 → 4.1.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 +3 -2
- package/common/dirConfigSource.ts +1 -1
- package/common/issueStartPlan.ts +58 -0
- package/common/keymap.ts +8 -8
- package/common/prPhase.ts +1 -1
- package/common/repoEntry.ts +77 -0
- package/common/sessionAgent.ts +1 -1
- package/common/terminalSubmit.ts +1 -1
- package/common/themeVars.ts +10 -4
- package/common/voiceInputStatus.ts +14 -0
- package/dist/assets/{abnfDiagram-VRR7QNED-RjiYivmv-Ds795mMl.js → abnfDiagram-VRR7QNED-RjiYivmv-BCXxUk19.js} +1 -1
- package/dist/assets/architecture-TIHT7OUA-0NsD2xW1-vpkNSsXO.js +1 -0
- package/dist/assets/{architectureDiagram-ZJ3FMSHR-3nWA91tG-C_pKLVRy.js → architectureDiagram-ZJ3FMSHR-3nWA91tG-Bs3iPPHw.js} +1 -1
- package/dist/assets/{blockDiagram-677ZJIJ3-BPuAJQRW-C1XW9rk5.js → blockDiagram-677ZJIJ3-BPuAJQRW-CxIHRfjJ.js} +1 -1
- package/dist/assets/{c4Diagram-LMCZKHZV-C0LAqQso-B_DJUxYS.js → c4Diagram-LMCZKHZV-C0LAqQso-D1Zp3ZLf.js} +1 -1
- package/dist/assets/channel-7wUqSdoX-BmaXSumw.js +1 -0
- package/dist/assets/{chunk-32BRIVSS-BRrYpgtb-muO9l3Wd.js → chunk-32BRIVSS-BRrYpgtb-iqbVrSxA.js} +1 -1
- package/dist/assets/{chunk-52WLFC77-BJ-ss3Xr-2G1qxJCe.js → chunk-52WLFC77-BJ-ss3Xr-DsGxy9sK.js} +1 -1
- package/dist/assets/{chunk-C7G6YPKG-BZEucKEL-DcP1Ik_Y.js → chunk-C7G6YPKG-BZEucKEL-FHV3qMNI.js} +1 -1
- package/dist/assets/{chunk-EX3LRPZG-DLS6FBN1-DzGx10EI.js → chunk-EX3LRPZG-DLS6FBN1-D3JiHJ-E.js} +1 -1
- package/dist/assets/{chunk-FWX5IMBZ-DHLSFw1H-C_1-WiA5.js → chunk-FWX5IMBZ-DHLSFw1H-BLB-Jc4x.js} +2 -2
- package/dist/assets/{chunk-HOUHSVGY-Bhlt8hXJ-CNQLLKZo.js → chunk-HOUHSVGY-Bhlt8hXJ-B9Sp5Rm4.js} +1 -1
- package/dist/assets/{chunk-ICXQ74PX-DwgHBX_g-zUyYvMip.js → chunk-ICXQ74PX-DwgHBX_g-Couvoogt.js} +1 -1
- package/dist/assets/{chunk-MOJQB5TN-CMZRaeqt-CuddDdck.js → chunk-MOJQB5TN-CMZRaeqt-pTxGJtb7.js} +1 -1
- package/dist/assets/{chunk-OGEWGWER-8Qy4a8b5-OusgHU3N.js → chunk-OGEWGWER-8Qy4a8b5-Bjam2Bd1.js} +1 -1
- package/dist/assets/{chunk-PUDLZKDR-DcrWQRYh-CbEu-YVk.js → chunk-PUDLZKDR-DcrWQRYh-z_O9UUQX.js} +1 -1
- package/dist/assets/{chunk-Q4XR5HBZ-ZXVGkG8Z-C8R8rf8U.js → chunk-Q4XR5HBZ-ZXVGkG8Z-yi9fnIVw.js} +1 -1
- package/dist/assets/{chunk-V7JOEXUC-DmGdheTX-CAvev2P-.js → chunk-V7JOEXUC-DmGdheTX-DTtWrQx1.js} +1 -1
- package/dist/assets/{chunk-VAUOI2AC-CS9QJ4yz-6Fqcztnb.js → chunk-VAUOI2AC-CS9QJ4yz-DW0Tgecw.js} +1 -1
- package/dist/assets/{chunk-VR4S4FIN-C6a91eNY-Oo6w4umS.js → chunk-VR4S4FIN-C6a91eNY-BSK94OLt.js} +1 -1
- package/dist/assets/{chunk-WYO6CB5R-BlzOfotS-CIUpBpsn.js → chunk-WYO6CB5R-BlzOfotS-D5Vl4QYq.js} +1 -1
- package/dist/assets/{chunk-ZGVPDNZ5-BYwxNFTK-DJKhMGKs.js → chunk-ZGVPDNZ5-BYwxNFTK-BnFKS269.js} +1 -1
- package/dist/assets/classDiagram-OUVF2IWQ-BYlRi6YQ-jw8dvfs2.js +1 -0
- package/dist/assets/classDiagram-v2-EOCWNBFH-BCHaYHxj-jw8dvfs2.js +1 -0
- package/dist/assets/cynefin-VYW2F7L2-CGYr2F6h-Bb2l8CKT.js +1 -0
- package/dist/assets/{cynefinDiagram-TSTJHNR4-DHA9iPo--D510DZwZ.js → cynefinDiagram-TSTJHNR4-DHA9iPo--CaO8WZ9J.js} +1 -1
- package/dist/assets/{dagre-VKFMJZFB--oJKqXBZ-BqyoygxX.js → dagre-VKFMJZFB--oJKqXBZ-i_xOpR1t.js} +1 -1
- package/dist/assets/{diagram-FQU43EPY-CcJCB9bG-DfnckLd4.js → diagram-FQU43EPY-CcJCB9bG-Dawy0bUD.js} +1 -1
- package/dist/assets/{diagram-G47NLZAW-C_o-WGG1-BPt0rgWP.js → diagram-G47NLZAW-C_o-WGG1-DQMAjcpJ.js} +1 -1
- package/dist/assets/{diagram-NH7WQ7WH-CXJCYvY--CkJBzBK2.js → diagram-NH7WQ7WH-CXJCYvY--BdH6UDVY.js} +1 -1
- package/dist/assets/{diagram-OA4YK3LP-BMzeJ87A-COSn3f12.js → diagram-OA4YK3LP-BMzeJ87A-DdlsuPDl.js} +1 -1
- package/dist/assets/{diagram-WEI45ONY-D_93NKqo-Dp8Om4pW.js → diagram-WEI45ONY-D_93NKqo-BYxqHeiT.js} +1 -1
- package/dist/assets/{dist-JstXoCzo.js → dist-CCytdxgu.js} +1 -1
- package/dist/assets/{dist-DZD6s32q.js → dist-Cl-hw6ph.js} +1 -1
- package/dist/assets/{dist-DiEF7DGo.js → dist-D9fZbRmf.js} +1 -1
- package/dist/assets/{dist-gls9ajYD.js → dist-SjIG9fJN.js} +1 -1
- package/dist/assets/{ebnfDiagram-CCIWWBDH-CVai1Ii9-Di2Rnx6S.js → ebnfDiagram-CCIWWBDH-CVai1Ii9-CqbaCkfN.js} +1 -1
- package/dist/assets/{erDiagram-Q63AITRT-CiABnA0s-dgCq9gZ-.js → erDiagram-Q63AITRT-CiABnA0s-CFRhcxJL.js} +1 -1
- package/dist/assets/eventmodeling-45OFAUF4-CWmqhm3a-CV0AXWMH.js +1 -0
- package/dist/assets/flowDiagram-23GEKE2U-DKSB5AiY-BzXDVc32.js +1 -0
- package/dist/assets/{ganttDiagram-NO4QXBWP-DQZvdFo1-Cia0ajA1.js → ganttDiagram-NO4QXBWP-DQZvdFo1-D_cPrHuB.js} +1 -1
- package/dist/assets/gitGraph-TEB2WS4Q-BR9qPwdN-DePJCG9u.js +1 -0
- package/dist/assets/{gitGraphDiagram-IHSO6WYX-C2ovBouh-Dh1y0VXZ.js → gitGraphDiagram-IHSO6WYX-C2ovBouh-CmpMFHzx.js} +1 -1
- package/dist/assets/index-CNOunTbV.js +616 -0
- package/dist/assets/index-Cdf9kaYt.css +1 -0
- package/dist/assets/info-DKCQHKI2-Dplx5kMp-CmgoBoly.js +1 -0
- package/dist/assets/{infoDiagram-FWYZ7A6U-7UnoB5AP-BqYiXSaj.js → infoDiagram-FWYZ7A6U-7UnoB5AP-1qH_6MSO.js} +1 -1
- package/dist/assets/{ishikawaDiagram-FXEZZL3T-ByUDM_N2-CcZgH7Ew.js → ishikawaDiagram-FXEZZL3T-ByUDM_N2-C4Y9h3Kc.js} +1 -1
- package/dist/assets/{journeyDiagram-5HDEW3XC-c5xIah9o-DdArPeNL.js → journeyDiagram-5HDEW3XC-c5xIah9o-2CHdMO52.js} +1 -1
- package/dist/assets/{kanban-definition-HUTT4EX6-Cnt6loYD-DmJ152Sf.js → kanban-definition-HUTT4EX6-Cnt6loYD-C3tvejl6.js} +1 -1
- package/dist/assets/{lib-Db3KPEnF.js → lib-l0WFljNN.js} +1 -1
- package/dist/assets/{line-D7ziSjKi-B3NE0st9.js → line-D7ziSjKi-BgJrHM2o.js} +1 -1
- package/dist/assets/{marp-SCu9aKhI.js → marp-DXxN_4Os.js} +1 -1
- package/dist/assets/{mermaid-parser.core-DxEa8E3F-nhwF9Zmw.js → mermaid-parser.core-DxEa8E3F-XDB5rg1G.js} +2 -2
- package/dist/assets/{mermaid.core-V0OYwIz3-COnZ7RY6.js → mermaid.core-V0OYwIz3-BE18ndG4.js} +3 -3
- package/dist/assets/{mindmap-definition-LN4V7U3C-CexN3O6L-DAFbTZnf.js → mindmap-definition-LN4V7U3C-CexN3O6L-B_Z8XGvs.js} +1 -1
- package/dist/assets/packet-7NZHBO7P-CQI3flND-Ckhq3qGx.js +1 -0
- package/dist/assets/{pegDiagram-2B236MQR-BiM4G0cW-DVdp8F2g.js → pegDiagram-2B236MQR-BiM4G0cW-CoS_Je3G.js} +1 -1
- package/dist/assets/pie-RZYD4A2V-CnmKE2Wa-COGnIXXn.js +1 -0
- package/dist/assets/{pieDiagram-ENE6RG2P-B_fBBS-2-dOKbqFlT.js → pieDiagram-ENE6RG2P-B_fBBS-2-q0d7psft.js} +1 -1
- package/dist/assets/{quadrantDiagram-ABIIQ3AL-BigGVxCR-B0K7Bi_G.js → quadrantDiagram-ABIIQ3AL-BigGVxCR-DX-o6YRc.js} +1 -1
- package/dist/assets/radar-I7S5WNFK-us6x-Z9R-DYVN7hVv.js +1 -0
- package/dist/assets/railroad-3IZDKUUU-BKdz6pdN-Ccr316bA.js +1 -0
- package/dist/assets/railroad-abnf-AHOZXSZD-m_CSSIfd-1lHKiwjs.js +1 -0
- package/dist/assets/railroad-ebnf-EBAXGLYW-Nu3nAG7C-CDsiITOB.js +1 -0
- package/dist/assets/railroad-peg-LSFZ7HO6--Y3mD4R_-BVRC2yH2.js +1 -0
- package/dist/assets/{railroadDiagram-RFXS5EU6--lNIlG64-IX0DQMzv.js → railroadDiagram-RFXS5EU6--lNIlG64-wRRd9wDB.js} +1 -1
- package/dist/assets/{requirementDiagram-TGXJPOKE-D-B0Y5Wu-7ePp-6uY.js → requirementDiagram-TGXJPOKE-D-B0Y5Wu-C29F0qnM.js} +1 -1
- package/dist/assets/{sankeyDiagram-HTMAVEWB-DlutaXDv-DcPeO3wM.js → sankeyDiagram-HTMAVEWB-DlutaXDv-BPq3vrC9.js} +1 -1
- package/dist/assets/{sequenceDiagram-DBY2YBRQ-BOLgtggH-BPKloVvU.js → sequenceDiagram-DBY2YBRQ-BOLgtggH-Cq_jo_ss.js} +1 -1
- package/dist/assets/{stateDiagram-2N3HPSRC-jf_dXUEU-Bd6-ZMXE.js → stateDiagram-2N3HPSRC-jf_dXUEU-DKYpGC0n.js} +1 -1
- package/dist/assets/stateDiagram-v2-6OUMAXLB-CuzgCL2v-CC7z1AQz.js +1 -0
- package/dist/assets/{swimlanes-5IMT3BWC-CYjtALQH-UC879FAu.js → swimlanes-5IMT3BWC-CYjtALQH-jmF9axmm.js} +1 -1
- package/dist/assets/swimlanesDiagram-G3AALYLV-3bmSBtKs-i5S7soVG.js +8 -0
- package/dist/assets/{timeline-definition-FHXFAJF6-DYJ4oUm8-ByREbTkR.js → timeline-definition-FHXFAJF6-DYJ4oUm8-B8bL7wcx.js} +1 -1
- package/dist/assets/treeView-QDETBFTQ-D27HWG6Q-DnDVKvX3.js +1 -0
- package/dist/assets/treemap-6X3UGDF4-CmGIU3H5-Dkb6cQ10.js +1 -0
- package/dist/assets/{vennDiagram-L72KCM5P-CdKAHoek-CznsE58R.js → vennDiagram-L72KCM5P-CdKAHoek-D9FWFG6j.js} +1 -1
- package/dist/assets/wardley-OPB4EBWU-CbHWsb2k-Za38PV_G.js +1 -0
- package/dist/assets/{wardleyDiagram-EHGQE667-BF6c4_CW-MMgJtZmB.js → wardleyDiagram-EHGQE667-BF6c4_CW-BffT3P-h.js} +1 -1
- package/dist/assets/{xychartDiagram-FW5EYKEG-CGiKngj7-D9mjkddh.js → xychartDiagram-FW5EYKEG-CGiKngj7-vPRabLJJ.js} +1 -1
- package/dist/index.html +2 -2
- package/package.json +3 -3
- package/server/agents/antigravity-mcp.ts +4 -3
- package/server/agents/antigravity-session.ts +3 -3
- package/server/agents/antigravity-sessions.ts +104 -0
- package/server/agents/codex-sessions.ts +7 -32
- package/server/agents/probe-transcript.ts +8 -11
- package/server/agents/transcript-head.ts +47 -0
- package/server/backends/collectionNotifierAdapter.ts +3 -2
- package/server/backends/collections.ts +23 -13
- package/server/backends/html.ts +2 -1
- package/server/backends/mulmoscript.ts +2 -1
- package/server/backends/openPath.ts +7 -0
- package/server/backends/presentPathRoot.ts +123 -0
- package/server/backends/remoteHost/getFeed.spec.ts +1 -0
- package/server/backends/remoteHost/handlers/deps.ts +9 -0
- package/server/backends/remoteHost/handlers/index.ts +5 -0
- package/server/backends/remoteHost/handlers/issueWork.ts +116 -0
- package/server/backends/remoteHost/handlers.spec.ts +3 -0
- package/server/backends/remoteHost/index.ts +1 -0
- package/server/backends/remoteHost/issueWork.spec.ts +244 -0
- package/server/backends/remoteHost/terminalScreen.ts +6 -4
- package/server/backends/remoteView.ts +3 -3
- package/server/backends/scheduler.ts +6 -3
- package/server/backends/shortcuts.ts +13 -9
- package/server/backends/translation.ts +12 -7
- package/server/backends/viewToken.ts +14 -8
- package/server/config/app-config.ts +12 -6
- package/server/config/cwd-presets.ts +4 -2
- package/server/config/header-context.ts +2 -14
- package/server/config/update-status.ts +6 -1
- package/server/files/scripts.ts +2 -1
- package/server/git/forge-host.ts +80 -0
- package/server/git/forge-support.ts +73 -0
- package/server/git/gitRemote.ts +31 -25
- package/server/git/glab-items.ts +73 -0
- package/server/git/glab.ts +29 -0
- package/server/git/issue-work.ts +129 -13
- package/server/git/issues.ts +17 -5
- package/server/git/pr-for-branch.ts +3 -2
- package/server/git/prs.ts +17 -6
- package/server/git/repo-dirs.ts +2 -3
- package/server/git/worktrees.ts +17 -1
- package/server/index.ts +26 -7
- package/server/infra/gui-mcp-registration.ts +4 -4
- package/server/mcp/broker.ts +8 -3
- package/server/routes/app-routes.ts +9 -0
- package/server/routes/dir-routes.ts +9 -6
- package/server/routes/issue-work-routes.ts +20 -17
- package/server/routes/session-routes.ts +22 -0
- package/server/session/background-chat.ts +2 -1
- package/server/session/cleared-transcripts.ts +1 -1
- package/server/session/issue-spawn-options.ts +20 -0
- package/server/session/registry.ts +12 -0
- package/server/session/scheduled-sessions.ts +1 -1
- package/server/session/session-cwd.ts +23 -0
- package/dist/assets/architecture-TIHT7OUA-0NsD2xW1-_YNv0NMb.js +0 -1
- package/dist/assets/channel-7wUqSdoX-6DJ89-Qe.js +0 -1
- package/dist/assets/classDiagram-OUVF2IWQ-BYlRi6YQ-B85sB4KG.js +0 -1
- package/dist/assets/classDiagram-v2-EOCWNBFH-BCHaYHxj-B85sB4KG.js +0 -1
- package/dist/assets/cynefin-VYW2F7L2-CGYr2F6h-CVLC7hXj.js +0 -1
- package/dist/assets/eventmodeling-45OFAUF4-CWmqhm3a-D-U4pUhx.js +0 -1
- package/dist/assets/flowDiagram-23GEKE2U-DKSB5AiY-CeqmKjiQ.js +0 -1
- package/dist/assets/gitGraph-TEB2WS4Q-BR9qPwdN-Dv8G0LNT.js +0 -1
- package/dist/assets/index-BBcSnsqR.js +0 -616
- package/dist/assets/index-Dal2P4Y6.css +0 -1
- package/dist/assets/info-DKCQHKI2-Dplx5kMp-Gtb9rU5N.js +0 -1
- package/dist/assets/packet-7NZHBO7P-CQI3flND-BlSkfnzl.js +0 -1
- package/dist/assets/pie-RZYD4A2V-CnmKE2Wa-PTCmAnlr.js +0 -1
- package/dist/assets/radar-I7S5WNFK-us6x-Z9R-sOU_Qtf_.js +0 -1
- package/dist/assets/railroad-3IZDKUUU-BKdz6pdN-CZse0pRF.js +0 -1
- package/dist/assets/railroad-abnf-AHOZXSZD-m_CSSIfd-DD141lVl.js +0 -1
- package/dist/assets/railroad-ebnf-EBAXGLYW-Nu3nAG7C-6h3qaEy8.js +0 -1
- package/dist/assets/railroad-peg-LSFZ7HO6--Y3mD4R_-D3yOgOUU.js +0 -1
- package/dist/assets/stateDiagram-v2-6OUMAXLB-CuzgCL2v--iFusbAN.js +0 -1
- package/dist/assets/swimlanesDiagram-G3AALYLV-3bmSBtKs-B7GGyqBW.js +0 -8
- package/dist/assets/treeView-QDETBFTQ-D27HWG6Q-COPupObu.js +0 -1
- package/dist/assets/treemap-6X3UGDF4-CmGIU3H5-DebmT2Ye.js +0 -1
- package/dist/assets/wardley-OPB4EBWU-CbHWsb2k-CqYCfIUl.js +0 -1
package/README.md
CHANGED
|
@@ -536,7 +536,7 @@ The Settings modal (⚙) persists per-user UI choices to `~/.mulmoterminal/confi
|
|
|
536
536
|
| `soundFile` | Absolute path to a custom **attention sound**, the fallback for every kind. Empty/unset uses the built-in synthesized chime. |
|
|
537
537
|
| `soundKinds` | Which moments beep — see [Notification sounds](#notification-sounds). Defaults to `["finished","waiting"]`; the other kinds are opt-in. |
|
|
538
538
|
| `sounds` | Per-kind sound: `{ "waiting": "preset:coin" }`. A `preset:<id>` reference or an absolute path; a kind with no entry falls back to `soundFile`. |
|
|
539
|
-
| `prRepos` | `owner/repo` entries whose open PRs/issues the cross-repo **PRs & Issues** view aggregates (via your `gh` login). |
|
|
539
|
+
| `prRepos` | `owner/repo` entries whose open PRs/issues the cross-repo **PRs & Issues** view aggregates (via your `gh` login). An entry may name its host (`gitlab.com/group/project`); only github.com is read today, and other hosts show a row saying so. |
|
|
540
540
|
| `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. |
|
|
541
541
|
| `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. |
|
|
542
542
|
| `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. |
|
|
@@ -1167,7 +1167,7 @@ quietly answering about the **default workspace** (#1151):
|
|
|
1167
1167
|
| --- | --- |
|
|
1168
1168
|
| `/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. |
|
|
1169
1169
|
| 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. |
|
|
1170
|
-
| `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. |
|
|
1170
|
+
| `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/antigravity/sessions`, `/api/session/:id`, `/api/transcript/*`, `/api/cost` | `404 { error, cwd }` — a directory that is not there. |
|
|
1171
1171
|
| A `?cwd=` that cannot name a directory at all (relative, or repeated as `?cwd=a&cwd=b`) | `400 { error, cwd }`. |
|
|
1172
1172
|
|
|
1173
1173
|
A request that names **no** directory is unaffected: `CLAUDE_CWD` is then the answer it
|
|
@@ -1288,6 +1288,7 @@ same-origin-guarded.
|
|
|
1288
1288
|
| -------- | ------- |
|
|
1289
1289
|
| `GET /api/session/:id?cwd=` | One session's summary — cumulative `usage` and `context` (model + last-turn context tokens). Backs the cell token & ctx% badges. |
|
|
1290
1290
|
| `GET /api/codex/sessions?cwd=` | Codex sessions for the project (from `~/.codex` rollouts), newest first. |
|
|
1291
|
+
| `GET /api/antigravity/sessions?cwd=` | Antigravity conversations for the project, newest first. agy does record a workspace, but never as a complete conversation-to-workspace map (`cache/last_conversations.json` keeps one conversation per directory and is written at exit; `history.jsonl` carries no conversation id), so the project comes from MulmoTerminal's own `~/.mulmoterminal/antigravity-conversations.jsonl`; agy's transcript supplies the title. |
|
|
1291
1292
|
| `GET /api/cost?cwd=&session=` | Estimated $ cost — session / today / month. |
|
|
1292
1293
|
| `GET /api/transcript/timeline?session=&cwd=` | Per-session activity timeline (tools run). |
|
|
1293
1294
|
| `GET /api/transcript/last-turn?session=&cwd=&agent=` | A session's last completed exchange (`prompt`, `reply`) plus the `text` to paste into another terminal. `agent=codex` reads the codex rollout instead of the Claude transcript. |
|
|
@@ -82,7 +82,7 @@ export const EMPTY_DIR_CONFIG_EXTRAS: DirConfigExtras = {
|
|
|
82
82
|
function isEmptyValue(value: unknown): boolean {
|
|
83
83
|
if (value === null || value === undefined) return true;
|
|
84
84
|
if (Array.isArray(value)) return value.length === 0;
|
|
85
|
-
if (typeof value === "object") return Object.keys(value
|
|
85
|
+
if (typeof value === "object") return Object.keys(value).length === 0;
|
|
86
86
|
return false;
|
|
87
87
|
}
|
|
88
88
|
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// Whether work on one repo can start here, decided from the repo -> clone answer alone (#1173).
|
|
2
|
+
// Pure, because the three outcomes are the whole behaviour: on the desktop they are a button, a
|
|
3
|
+
// menu, or a disabled button that says why (IssueStartButton.vue).
|
|
4
|
+
//
|
|
5
|
+
// In `common/` because BOTH hosts decide from it: the phone asks the same question over the remote
|
|
6
|
+
// command channel (#1184) and must reach the same answer — with one difference it makes itself,
|
|
7
|
+
// not one encoded here. It cannot offer the menu (the phone never picks a directory, see
|
|
8
|
+
// docs/remote-host-protocol.md), so it refuses `choose` where the desktop opens it.
|
|
9
|
+
import type { RepoDirs } from "./repoDirs";
|
|
10
|
+
import { GITHUB_HOST, GITLAB_HOST, parseRepoEntry } from "./repoEntry";
|
|
11
|
+
|
|
12
|
+
// Where work can be STARTED — the issue is read and a worktree cut. A host that is merely listable
|
|
13
|
+
// still refuses, and says which host it is rather than blaming a missing clone (#981).
|
|
14
|
+
const STARTABLE_HOSTS: ReadonlySet<string> = new Set([GITHUB_HOST, GITLAB_HOST]);
|
|
15
|
+
|
|
16
|
+
/** The hosts named in a refusal, read off the set rather than written out beside it — a hardcoded
|
|
17
|
+
* "github.com only" survived GitLab becoming startable and told users the opposite of the truth
|
|
18
|
+
* (Codex review). Exported so the phone's refusal says the same thing. */
|
|
19
|
+
export const startableHosts = (): string => [...STARTABLE_HOSTS].join(" and ");
|
|
20
|
+
|
|
21
|
+
export type IssueStartPlan =
|
|
22
|
+
/** No clone of this repo on this machine, so there is nowhere for the work to happen. */
|
|
23
|
+
| { kind: "no-clone" }
|
|
24
|
+
/** The repo is on a forge whose issues can be LISTED but not started from (#981). Distinct from
|
|
25
|
+
* `no-clone`, which would send the reader off to add a clone that would not help. */
|
|
26
|
+
| { kind: "unsupported-forge"; host: string }
|
|
27
|
+
/** Exactly one answer — either recorded, or the only candidate. One click starts. */
|
|
28
|
+
| { kind: "ready"; dir: string }
|
|
29
|
+
/** Several clones and nothing recorded yet: the user picks, and the pick is remembered. */
|
|
30
|
+
| { kind: "choose"; dirs: RepoDirs["dirs"] };
|
|
31
|
+
|
|
32
|
+
/** A plan that cannot start work as it stands. Named so a caller that has already narrowed to it
|
|
33
|
+
* can be given a sentence rather than a nullable one — see the phone's refusal (#1184). */
|
|
34
|
+
export type BlockedIssueStartPlan = Exclude<IssueStartPlan, { kind: "ready" }>;
|
|
35
|
+
|
|
36
|
+
// `repo` is REQUIRED, not optional, even though only one branch reads it: a caller that omitted it
|
|
37
|
+
// would get `no-clone` for a GitLab repo, which is the exact wrong answer this parameter was added
|
|
38
|
+
// to fix. Making the compiler ask for it is what stops that coming back.
|
|
39
|
+
export function issueStartPlan(entry: RepoDirs | undefined, repo: string): IssueStartPlan {
|
|
40
|
+
// Checked before the clone list, because a GitLab repo has no entry there and would otherwise
|
|
41
|
+
// read as "no clone" — a reason that is not true and points at the wrong fix.
|
|
42
|
+
const parsed = parseRepoEntry(repo);
|
|
43
|
+
if (parsed && !STARTABLE_HOSTS.has(parsed.host)) return { kind: "unsupported-forge", host: parsed.host };
|
|
44
|
+
const dirs = entry?.dirs ?? [];
|
|
45
|
+
if (dirs.length === 0) return { kind: "no-clone" };
|
|
46
|
+
// A recording wins even when the repo has one clone: it is still the same answer, and treating
|
|
47
|
+
// the two cases the same keeps "recorded" from being a state the UI has to distinguish.
|
|
48
|
+
const recorded = entry?.primary;
|
|
49
|
+
if (recorded) return { kind: "ready", dir: recorded };
|
|
50
|
+
if (dirs.length === 1) return { kind: "ready", dir: dirs[0].path };
|
|
51
|
+
return { kind: "choose", dirs };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Why the control is disabled, for the row's title text. Null when it is not disabled. */
|
|
55
|
+
export function issueStartBlockedReason(plan: IssueStartPlan, repo: string): string | null {
|
|
56
|
+
if (plan.kind === "unsupported-forge") return `Starting work supports ${startableHosts()} — ${plan.host} issues are listed here, not started from`;
|
|
57
|
+
return plan.kind === "no-clone" ? `No local clone of ${repo} — add one to your directory presets to start work here` : null;
|
|
58
|
+
}
|
package/common/keymap.ts
CHANGED
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
// "keymap": { "zoom-next": "PageDown", "zoom-prev": "Shift+PageUp" }
|
|
11
11
|
|
|
12
12
|
// Actions a key can be bound to. Adding one here is all it takes for the config to accept it.
|
|
13
|
+
import { isRecord } from "./isRecord.js";
|
|
14
|
+
|
|
13
15
|
export const KEYMAP_ACTIONS = [
|
|
14
16
|
"zoom-toggle",
|
|
15
17
|
"zoom-next",
|
|
@@ -23,7 +25,7 @@ export const KEYMAP_ACTIONS = [
|
|
|
23
25
|
] as const;
|
|
24
26
|
export type KeymapAction = (typeof KEYMAP_ACTIONS)[number];
|
|
25
27
|
|
|
26
|
-
export const isKeymapAction = (value: unknown): value is KeymapAction => typeof value === "string" && (
|
|
28
|
+
export const isKeymapAction = (value: unknown): value is KeymapAction => typeof value === "string" && KEYMAP_ACTIONS.some((action) => action === value);
|
|
27
29
|
|
|
28
30
|
// action -> binding string. Absent action = unbound = that shortcut does nothing.
|
|
29
31
|
// Actions the GRID's key handler must never claim, because they are decided inside the terminal
|
|
@@ -122,8 +124,7 @@ export function actionForKey(keymap: Keymap, e: KeymapKeyEvent): KeymapAction |
|
|
|
122
124
|
return null;
|
|
123
125
|
}
|
|
124
126
|
|
|
125
|
-
const isSendBinding = (value: unknown): value is SendBinding =>
|
|
126
|
-
typeof value === "object" && value !== null && typeof (value as SendBinding).key === "string" && typeof (value as SendBinding).bytes === "string";
|
|
127
|
+
const isSendBinding = (value: unknown): value is SendBinding => isRecord(value) && typeof value.key === "string" && typeof value.bytes === "string";
|
|
127
128
|
|
|
128
129
|
// The bytes this keydown should put into the terminal, or null when it is not a send binding.
|
|
129
130
|
//
|
|
@@ -160,7 +161,7 @@ export function validateKeymap(input: unknown): KeymapProblem[] {
|
|
|
160
161
|
if (typeof input !== "object" || Array.isArray(input)) {
|
|
161
162
|
return [{ action: "keymap", binding: input, reason: "`keymap` must be an object of action -> key binding", fatal: true }];
|
|
162
163
|
}
|
|
163
|
-
const entries = Object.entries(input
|
|
164
|
+
const entries = Object.entries(input);
|
|
164
165
|
// A claim on one keystroke. `rank` is DISPATCH order, so the winner can be named: every action
|
|
165
166
|
// outranks every send binding, because the grid's handler runs in the capture phase and stops
|
|
166
167
|
// the event before the terminal — see sendBytesFor.
|
|
@@ -241,12 +242,11 @@ const canonicalBinding = (b: KeyBinding): string => `${b.shift ? "S" : ""}${b.al
|
|
|
241
242
|
// malformed bindings are dropped rather than rejecting the whole map, matching how the
|
|
242
243
|
// rest of the config treats one bad entry.
|
|
243
244
|
export function sanitizeKeymap(input: unknown): Keymap {
|
|
244
|
-
if (
|
|
245
|
-
const
|
|
246
|
-
const entries = Object.entries(raw).filter(
|
|
245
|
+
if (!isRecord(input)) return {};
|
|
246
|
+
const entries = Object.entries(input).filter(
|
|
247
247
|
(entry): entry is [KeymapAction, string] => isKeymapAction(entry[0]) && typeof entry[1] === "string" && parseKeyBinding(entry[1]) !== null,
|
|
248
248
|
);
|
|
249
|
-
const send = sanitizeSendBindings(
|
|
249
|
+
const send = sanitizeSendBindings(input.send);
|
|
250
250
|
return { ...Object.fromEntries(entries), ...(send.length ? { send } : {}) };
|
|
251
251
|
}
|
|
252
252
|
|
package/common/prPhase.ts
CHANGED
|
@@ -10,7 +10,7 @@ export type PrPhase = "none" | "draft" | "ci-failing" | "changes-requested" | "c
|
|
|
10
10
|
|
|
11
11
|
export const PR_PHASES: readonly PrPhase[] = ["none", "draft", "ci-failing", "changes-requested", "ci-running", "ready", "merged", "closed"];
|
|
12
12
|
|
|
13
|
-
export const isPrPhase = (v: unknown): v is PrPhase => typeof v === "string" && (
|
|
13
|
+
export const isPrPhase = (v: unknown): v is PrPhase => typeof v === "string" && PR_PHASES.some((phase) => phase === v);
|
|
14
14
|
|
|
15
15
|
// The /api/pr-phase response. `phase` and `prUrl` predate the rest and the roster reads them;
|
|
16
16
|
// the numbers are what lets a cell say WHICH work it is on rather than just how far along it is.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// Reading a configured repository entry — `owner/repo`, or `host/owner/repo` for one that is not
|
|
2
|
+
// on GitHub (#981).
|
|
3
|
+
//
|
|
4
|
+
// In `common/` because BOTH sides decide from it: the server turns an entry into a forge to know
|
|
5
|
+
// which CLI to run, and the browser needs the same answer to say why a control is off. Written
|
|
6
|
+
// twice it would drift, and the two answers disagreeing is precisely the failure this abstraction
|
|
7
|
+
// is undoing.
|
|
8
|
+
|
|
9
|
+
export const GITHUB_HOST = "github.com";
|
|
10
|
+
export const GITLAB_HOST = "gitlab.com";
|
|
11
|
+
|
|
12
|
+
// A leading segment containing a DOT is the host. GitHub user and organisation names may hold only
|
|
13
|
+
// alphanumerics and hyphens, so `owner/repo` and `host/owner/repo` cannot be confused.
|
|
14
|
+
const HOST_SEGMENT = /\./;
|
|
15
|
+
|
|
16
|
+
export interface RepoEntry {
|
|
17
|
+
host: string;
|
|
18
|
+
/** The segments after the host — how many of them name a project is the HOST's rule, not this. */
|
|
19
|
+
path: string[];
|
|
20
|
+
/** True when the entry spelled the host out. `owner/repo` implies github.com without saying it. */
|
|
21
|
+
declared: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Split an entry into host and path, or null when it is not one.
|
|
25
|
+
*
|
|
26
|
+
* Null for an empty segment — a doubled, leading or trailing slash. Forgiving those would let
|
|
27
|
+
* `owner//repo` parse as `owner/repo` while the entry is STORED verbatim and handed to a CLI with
|
|
28
|
+
* the extra slash still in it, which is a parse error there.
|
|
29
|
+
*/
|
|
30
|
+
export function parseRepoEntry(entry: string): RepoEntry | null {
|
|
31
|
+
const segments = entry.trim().split("/");
|
|
32
|
+
if (segments.some((segment) => segment === "")) return null;
|
|
33
|
+
const declared = segments.length > 1 && HOST_SEGMENT.test(segments[0]);
|
|
34
|
+
return declared ? { host: segments[0].toLowerCase(), path: segments.slice(1), declared } : { host: GITHUB_HOST, path: segments, declared };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** The identity a repository is known by ON ITS OWN HOST — `owner/repo` for GitHub, the group path
|
|
38
|
+
* for GitLab — with any declared host stripped.
|
|
39
|
+
*
|
|
40
|
+
* `/api/repo-dirs` keys by this, because it derives the name from a clone's remote URL where the
|
|
41
|
+
* host is not part of the path. A configured entry may spell the host out (`github.com/owner/repo`
|
|
42
|
+
* became storable in #981 step 2a), so comparing the raw entry against those keys finds nothing
|
|
43
|
+
* and reports "no local clone" for a repo that has one (Codex review).
|
|
44
|
+
*/
|
|
45
|
+
export const canonicalRepo = (entry: string): string => parseRepoEntry(entry)?.path.join("/") ?? entry.trim();
|
|
46
|
+
|
|
47
|
+
/** The identity used to MATCH a configured entry against a resolved clone: always host-qualified.
|
|
48
|
+
*
|
|
49
|
+
* Distinct from `canonicalRepo`, which strips the host because that is what a CLI's `--repo`
|
|
50
|
+
* wants. Matching needs the opposite: without the host, `github.com/a/b` and `gitlab.com/a/b`
|
|
51
|
+
* collapse to the same key, and a clone of one would answer for the other (#981).
|
|
52
|
+
*/
|
|
53
|
+
export const repoIdentity = (entry: string): string => {
|
|
54
|
+
const parsed = parseRepoEntry(entry);
|
|
55
|
+
return parsed ? `${parsed.host}/${parsed.path.join("/")}`.toLowerCase() : entry.trim().toLowerCase();
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// The value reaches a CLI's `--repo`, so no spaces and nothing readable as a flag.
|
|
59
|
+
const REPO_CHARS_RE = /^[A-Za-z0-9._/-]+$/;
|
|
60
|
+
// Every forge names a project as namespace + name, so one segment is never a repository.
|
|
61
|
+
const NAMESPACED = 2;
|
|
62
|
+
|
|
63
|
+
/** Whether a string may be stored and used as a repository entry.
|
|
64
|
+
*
|
|
65
|
+
* The ONE rule. It was written out four times — the config sanitizer, both issue-start endpoints
|
|
66
|
+
* and the Settings field — and widening only the first meant an entry the user could save was
|
|
67
|
+
* rejected by everything downstream, including the form that was supposed to accept it (#981).
|
|
68
|
+
*
|
|
69
|
+
* A hostless entry must be exactly `owner/repo`: `gh --repo` reads `a/b/c` as host `a`, so
|
|
70
|
+
* accepting it would have this side and the CLI aiming at different servers. A declared host may
|
|
71
|
+
* be followed by a nested GitLab group.
|
|
72
|
+
*/
|
|
73
|
+
export function isRepoEntry(entry: string): boolean {
|
|
74
|
+
const parsed = REPO_CHARS_RE.test(entry.trim()) ? parseRepoEntry(entry) : null;
|
|
75
|
+
if (!parsed) return false;
|
|
76
|
+
return parsed.declared ? parsed.path.length >= NAMESPACED : parsed.path.length === NAMESPACED;
|
|
77
|
+
}
|
package/common/sessionAgent.ts
CHANGED
|
@@ -16,7 +16,7 @@ export type TerminalAgent = (typeof TERMINAL_AGENTS)[number];
|
|
|
16
16
|
// A remembered agent — a persisted grid cell, a localStorage toggle, a query param — read back.
|
|
17
17
|
// Validated rather than cast: anything unrecognised is Claude, which is also what an older
|
|
18
18
|
// persisted cell (written before the field existed) means.
|
|
19
|
-
export const asTerminalAgent = (value: unknown): TerminalAgent => (
|
|
19
|
+
export const asTerminalAgent = (value: unknown): TerminalAgent => (typeof value === "string" && isTerminalAgent(value) ? value : "claude");
|
|
20
20
|
|
|
21
21
|
// Narrowing rather than coercing, for the callers that must be able to say "this is not an agent
|
|
22
22
|
// at all": a shell is a session kind but not something a cell can be relaunched AS, and reading
|
package/common/terminalSubmit.ts
CHANGED
|
@@ -13,7 +13,7 @@ export type TerminalSubmitMode = (typeof TERMINAL_SUBMIT_MODES)[number];
|
|
|
13
13
|
export const DEFAULT_TERMINAL_SUBMIT_MODE: TerminalSubmitMode = "cr";
|
|
14
14
|
|
|
15
15
|
export const isTerminalSubmitMode = (value: unknown): value is TerminalSubmitMode =>
|
|
16
|
-
typeof value === "string" && (
|
|
16
|
+
typeof value === "string" && TERMINAL_SUBMIT_MODES.some((mode) => mode === value);
|
|
17
17
|
|
|
18
18
|
// CR on its own. ESC+CR is what a terminal emits for Alt/Meta+Enter.
|
|
19
19
|
const CR = "\r";
|
package/common/themeVars.ts
CHANGED
|
@@ -50,7 +50,7 @@ export function isThemeIdLike(value: unknown): value is string {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
export function isBuiltinThemeId(id: string): id is ThemeId {
|
|
53
|
-
return (
|
|
53
|
+
return THEME_IDS.some((builtin) => builtin === id);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
/** Whether an id may be used for a CUSTOM theme. Built-in ids are refused rather than merged
|
|
@@ -70,13 +70,19 @@ export interface CustomThemeInput {
|
|
|
70
70
|
/** The full variable set for a theme: the base it extends, with its own colours on top.
|
|
71
71
|
* `builtins` supplies the base sets so this stays pure — the client reads them from the
|
|
72
72
|
* stylesheet's source of truth, the specs from a fixture. */
|
|
73
|
+
// Every variable present, which is what separates a set we can paint with from one we cannot.
|
|
74
|
+
// A guard rather than a length check on the missing keys: both ask the same question, but only
|
|
75
|
+
// this one hands the answer to the compiler.
|
|
76
|
+
function isCompleteThemeVars(vars: Partial<ThemeVars>): vars is ThemeVars {
|
|
77
|
+
return THEME_VAR_KEYS.every((key) => !!vars[key]);
|
|
78
|
+
}
|
|
79
|
+
|
|
73
80
|
export function resolveThemeVars(theme: CustomThemeInput, builtins: Record<ThemeId, ThemeVars>): ThemeVars | null {
|
|
74
81
|
const base = theme.extends ? builtins[theme.extends] : null;
|
|
75
|
-
const merged = { ...(base ?? {}), ...theme.colors }
|
|
76
|
-
const missing = THEME_VAR_KEYS.filter((key) => !merged[key]);
|
|
82
|
+
const merged: Partial<ThemeVars> = { ...(base ?? {}), ...theme.colors };
|
|
77
83
|
// No base and an incomplete list is the one case we cannot paint: report it rather than
|
|
78
84
|
// leaving the gaps to whatever the previously applied theme put on the element.
|
|
79
|
-
return
|
|
85
|
+
return isCompleteThemeVars(merged) ? merged : null;
|
|
80
86
|
}
|
|
81
87
|
|
|
82
88
|
function channel(hex: string, at: number): number {
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
// package implements transcription behind it is not the UI's business. The server's
|
|
7
7
|
// `getVoiceInputStatus(): VoiceInputStatus` annotation is what keeps the two in step.
|
|
8
8
|
|
|
9
|
+
import { isRecord } from "./isRecord.js";
|
|
10
|
+
|
|
9
11
|
export type VoiceModelState = "idle" | "downloading" | "ready" | "error";
|
|
10
12
|
|
|
11
13
|
export interface VoiceInputStatus {
|
|
@@ -19,3 +21,15 @@ export interface VoiceInputStatus {
|
|
|
19
21
|
error?: string;
|
|
20
22
|
};
|
|
21
23
|
}
|
|
24
|
+
|
|
25
|
+
export const VOICE_MODEL_STATES: readonly VoiceModelState[] = ["idle", "downloading", "ready", "error"];
|
|
26
|
+
|
|
27
|
+
/** The wire response as it arrives from `GET /api/transcribe/model`. Lives beside the type so the
|
|
28
|
+
* guard and the shape it checks cannot drift; the UI treats anything else as "no status". */
|
|
29
|
+
export function isVoiceInputStatus(value: unknown): value is VoiceInputStatus {
|
|
30
|
+
if (!isRecord(value) || typeof value.capable !== "boolean" || !isRecord(value.model)) return false;
|
|
31
|
+
const { name, state, progress, error } = value.model;
|
|
32
|
+
if (typeof name !== "string" || !VOICE_MODEL_STATES.some((known) => known === state)) return false;
|
|
33
|
+
if (progress !== undefined && typeof progress !== "number") return false;
|
|
34
|
+
return error === undefined || typeof error === "string";
|
|
35
|
+
}
|
|
@@ -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-XDB5rg1G.js";import"./chunk-WYO6CB5R-BlzOfotS-D5Vl4QYq.js";import"./chunk-VAUOI2AC-CS9QJ4yz-DW0Tgecw.js";import{n as i,r as a,t as o}from"./chunk-MOJQB5TN-CMZRaeqt-pTxGJtb7.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-XDB5rg1G.js";export{e as createArchitectureServices};
|