mulmoterminal 2.2.0 → 2.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.
Files changed (110) hide show
  1. package/README.md +34 -1
  2. package/common/githubRepo.ts +22 -0
  3. package/common/terminalClipboard.ts +19 -0
  4. package/dist/assets/{abnfDiagram-VRR7QNED-RjiYivmv-6R9yRbUC.js → abnfDiagram-VRR7QNED-RjiYivmv-B8nu2pUR.js} +1 -1
  5. package/dist/assets/architecture-TIHT7OUA-0NsD2xW1-TY_v-qbq.js +1 -0
  6. package/dist/assets/{architectureDiagram-ZJ3FMSHR-3nWA91tG-DzS5ABJE.js → architectureDiagram-ZJ3FMSHR-3nWA91tG-ByxXyiOP.js} +1 -1
  7. package/dist/assets/{blockDiagram-677ZJIJ3-BPuAJQRW-Cw9RkJxY.js → blockDiagram-677ZJIJ3-BPuAJQRW-Brt9e7H_.js} +1 -1
  8. package/dist/assets/{c4Diagram-LMCZKHZV-C0LAqQso-CWltXMHP.js → c4Diagram-LMCZKHZV-C0LAqQso-D598g8JV.js} +1 -1
  9. package/dist/assets/channel-7wUqSdoX-DRUj8A2e.js +1 -0
  10. package/dist/assets/{chunk-32BRIVSS-BRrYpgtb-DrrsZ2u5.js → chunk-32BRIVSS-BRrYpgtb-BEOPPcME.js} +1 -1
  11. package/dist/assets/{chunk-52WLFC77-BJ-ss3Xr-WJMq_L8L.js → chunk-52WLFC77-BJ-ss3Xr-BmZ-jgWV.js} +1 -1
  12. package/dist/assets/{chunk-C7G6YPKG-BZEucKEL-BafXJkh7.js → chunk-C7G6YPKG-BZEucKEL-DhvCnMVg.js} +1 -1
  13. package/dist/assets/{chunk-EX3LRPZG-DLS6FBN1-Q8lsrJXs.js → chunk-EX3LRPZG-DLS6FBN1-CxeaHZOV.js} +1 -1
  14. package/dist/assets/{chunk-FWX5IMBZ-DHLSFw1H-Cgm5-zaI.js → chunk-FWX5IMBZ-DHLSFw1H-COykUZUW.js} +2 -2
  15. package/dist/assets/{chunk-HOUHSVGY-Bhlt8hXJ-Cp5J5cOD.js → chunk-HOUHSVGY-Bhlt8hXJ-DFKJuoMh.js} +1 -1
  16. package/dist/assets/{chunk-ICXQ74PX-DwgHBX_g-CLdnp-d2.js → chunk-ICXQ74PX-DwgHBX_g-CFoH6Yjf.js} +1 -1
  17. package/dist/assets/{chunk-MOJQB5TN-CMZRaeqt-BsIB0ZXR.js → chunk-MOJQB5TN-CMZRaeqt-Dy6S_sS_.js} +1 -1
  18. package/dist/assets/{chunk-OGEWGWER-8Qy4a8b5-DlTM-RTP.js → chunk-OGEWGWER-8Qy4a8b5-XcjK3kCc.js} +1 -1
  19. package/dist/assets/{chunk-PUDLZKDR-DcrWQRYh-XujP_H1v.js → chunk-PUDLZKDR-DcrWQRYh-CFVQ5Aq8.js} +1 -1
  20. package/dist/assets/{chunk-Q4XR5HBZ-ZXVGkG8Z-DhxnzVDy.js → chunk-Q4XR5HBZ-ZXVGkG8Z-D2iTH8ap.js} +1 -1
  21. package/dist/assets/{chunk-V7JOEXUC-DmGdheTX-C-xPmCQA.js → chunk-V7JOEXUC-DmGdheTX-Dfius2MW.js} +1 -1
  22. package/dist/assets/{chunk-VAUOI2AC-CS9QJ4yz-Cng5RPUP.js → chunk-VAUOI2AC-CS9QJ4yz-Dd_VpRsu.js} +1 -1
  23. package/dist/assets/{chunk-VR4S4FIN-C6a91eNY-Bmb0moA3.js → chunk-VR4S4FIN-C6a91eNY-U_jwmwMS.js} +1 -1
  24. package/dist/assets/{chunk-WYO6CB5R-BlzOfotS-DmR4SyZL.js → chunk-WYO6CB5R-BlzOfotS-04XZ1Jfd.js} +1 -1
  25. package/dist/assets/{chunk-ZGVPDNZ5-BYwxNFTK-CD8nNM8_.js → chunk-ZGVPDNZ5-BYwxNFTK-DBPsh-p3.js} +1 -1
  26. package/dist/assets/classDiagram-OUVF2IWQ-BYlRi6YQ-BVAZDjb0.js +1 -0
  27. package/dist/assets/classDiagram-v2-EOCWNBFH-BCHaYHxj-BVAZDjb0.js +1 -0
  28. package/dist/assets/cynefin-VYW2F7L2-CGYr2F6h-CFSruy5n.js +1 -0
  29. package/dist/assets/{cynefinDiagram-TSTJHNR4-DHA9iPo--pv1DCSfy.js → cynefinDiagram-TSTJHNR4-DHA9iPo--D-iTSsn0.js} +1 -1
  30. package/dist/assets/{dagre-VKFMJZFB--oJKqXBZ-BPcGEiSl.js → dagre-VKFMJZFB--oJKqXBZ-G72EKlyP.js} +1 -1
  31. package/dist/assets/{diagram-FQU43EPY-CcJCB9bG-CCOrHV0U.js → diagram-FQU43EPY-CcJCB9bG-DgT-eqMs.js} +1 -1
  32. package/dist/assets/{diagram-G47NLZAW-C_o-WGG1-Crm_IB8Y.js → diagram-G47NLZAW-C_o-WGG1-D_JxH6o2.js} +1 -1
  33. package/dist/assets/{diagram-NH7WQ7WH-CXJCYvY--UcH8gkTE.js → diagram-NH7WQ7WH-CXJCYvY--pVhp9uBi.js} +1 -1
  34. package/dist/assets/{diagram-OA4YK3LP-BMzeJ87A-7C9Me5sS.js → diagram-OA4YK3LP-BMzeJ87A-CFoCoA1K.js} +1 -1
  35. package/dist/assets/{diagram-WEI45ONY-D_93NKqo-BBztQ9hK.js → diagram-WEI45ONY-D_93NKqo-COhtVv5k.js} +1 -1
  36. package/dist/assets/{ebnfDiagram-CCIWWBDH-CVai1Ii9-TkJNOqEw.js → ebnfDiagram-CCIWWBDH-CVai1Ii9-cHbupDvE.js} +1 -1
  37. package/dist/assets/{erDiagram-Q63AITRT-CiABnA0s-DS2blJuc.js → erDiagram-Q63AITRT-CiABnA0s-Ch6F8aLL.js} +1 -1
  38. package/dist/assets/eventmodeling-45OFAUF4-CWmqhm3a-B09FMUUq.js +1 -0
  39. package/dist/assets/flowDiagram-23GEKE2U-DKSB5AiY-BswknzuF.js +1 -0
  40. package/dist/assets/{ganttDiagram-NO4QXBWP-DQZvdFo1-ZB_lhurA.js → ganttDiagram-NO4QXBWP-DQZvdFo1-DcmaS_P9.js} +1 -1
  41. package/dist/assets/gitGraph-TEB2WS4Q-BR9qPwdN-Bg_TZB3f.js +1 -0
  42. package/dist/assets/{gitGraphDiagram-IHSO6WYX-C2ovBouh-Vm6I27hg.js → gitGraphDiagram-IHSO6WYX-C2ovBouh-CgaMpUqZ.js} +1 -1
  43. package/dist/assets/index-DWePsXYt.css +1 -0
  44. package/dist/assets/{index-BP05wTLW.js → index-QEGG3YTz.js} +197 -197
  45. package/dist/assets/info-DKCQHKI2-Dplx5kMp-BAI4sdgi.js +1 -0
  46. package/dist/assets/{infoDiagram-FWYZ7A6U-7UnoB5AP-Cr34YkAb.js → infoDiagram-FWYZ7A6U-7UnoB5AP-f2daXl9J.js} +1 -1
  47. package/dist/assets/{ishikawaDiagram-FXEZZL3T-ByUDM_N2-at4P1zMV.js → ishikawaDiagram-FXEZZL3T-ByUDM_N2-DYE7Ld9-.js} +1 -1
  48. package/dist/assets/{journeyDiagram-5HDEW3XC-c5xIah9o-D4ZV57k7.js → journeyDiagram-5HDEW3XC-c5xIah9o-B0woNVtP.js} +1 -1
  49. package/dist/assets/{kanban-definition-HUTT4EX6-Cnt6loYD-BiJ3JUjX.js → kanban-definition-HUTT4EX6-Cnt6loYD-Dm8evmYs.js} +1 -1
  50. package/dist/assets/{lib-Du_IVDkN.js → lib-DtgnGSMW.js} +1 -1
  51. package/dist/assets/{line-D7ziSjKi-CPM0FMWw.js → line-D7ziSjKi-CRwDdfSt.js} +1 -1
  52. package/dist/assets/{marp-BBre1w8X.js → marp-Djuncd6G.js} +1 -1
  53. package/dist/assets/{mermaid-parser.core-DxEa8E3F-CO4zEYzL.js → mermaid-parser.core-DxEa8E3F-BILJo_fK.js} +2 -2
  54. package/dist/assets/{mermaid.core-V0OYwIz3-CzPQxhwu.js → mermaid.core-V0OYwIz3-CabnyPOO.js} +3 -3
  55. package/dist/assets/{mindmap-definition-LN4V7U3C-CexN3O6L-Nez_xicT.js → mindmap-definition-LN4V7U3C-CexN3O6L-DF1aNqGu.js} +1 -1
  56. package/dist/assets/packet-7NZHBO7P-CQI3flND-Bqib4t7m.js +1 -0
  57. package/dist/assets/{pegDiagram-2B236MQR-BiM4G0cW-0AEyhHwQ.js → pegDiagram-2B236MQR-BiM4G0cW-q-89nsVP.js} +1 -1
  58. package/dist/assets/pie-RZYD4A2V-CnmKE2Wa-C7f4Ij-s.js +1 -0
  59. package/dist/assets/{pieDiagram-ENE6RG2P-B_fBBS-2-DXBEfgPl.js → pieDiagram-ENE6RG2P-B_fBBS-2-B3pcC0Pg.js} +1 -1
  60. package/dist/assets/{quadrantDiagram-ABIIQ3AL-BigGVxCR-dZ16XJ8-.js → quadrantDiagram-ABIIQ3AL-BigGVxCR-BBKSbiVD.js} +1 -1
  61. package/dist/assets/radar-I7S5WNFK-us6x-Z9R-C0_E6OiV.js +1 -0
  62. package/dist/assets/railroad-3IZDKUUU-BKdz6pdN-C2_X_Txm.js +1 -0
  63. package/dist/assets/railroad-abnf-AHOZXSZD-m_CSSIfd-wMka3Tbm.js +1 -0
  64. package/dist/assets/railroad-ebnf-EBAXGLYW-Nu3nAG7C-B7uu2NPX.js +1 -0
  65. package/dist/assets/railroad-peg-LSFZ7HO6--Y3mD4R_-D4Sj2mdo.js +1 -0
  66. package/dist/assets/{railroadDiagram-RFXS5EU6--lNIlG64-DHNapLB9.js → railroadDiagram-RFXS5EU6--lNIlG64-Do0ZI2kT.js} +1 -1
  67. package/dist/assets/{requirementDiagram-TGXJPOKE-D-B0Y5Wu-C-9SVxpD.js → requirementDiagram-TGXJPOKE-D-B0Y5Wu-B4oci7Dv.js} +1 -1
  68. package/dist/assets/{sankeyDiagram-HTMAVEWB-DlutaXDv-Cv-mFz76.js → sankeyDiagram-HTMAVEWB-DlutaXDv-KRXYn9rF.js} +1 -1
  69. package/dist/assets/{sequenceDiagram-DBY2YBRQ-BOLgtggH-BR0sUcBe.js → sequenceDiagram-DBY2YBRQ-BOLgtggH-zw0J8MZu.js} +1 -1
  70. package/dist/assets/{stateDiagram-2N3HPSRC-jf_dXUEU-DjqY9a1u.js → stateDiagram-2N3HPSRC-jf_dXUEU-vFGH-mvy.js} +1 -1
  71. package/dist/assets/stateDiagram-v2-6OUMAXLB-CuzgCL2v-PiMBzK3e.js +1 -0
  72. package/dist/assets/{swimlanes-5IMT3BWC-CYjtALQH-DV8Ha8XJ.js → swimlanes-5IMT3BWC-CYjtALQH-DhegOTK_.js} +1 -1
  73. package/dist/assets/swimlanesDiagram-G3AALYLV-3bmSBtKs-ByceWEns.js +8 -0
  74. package/dist/assets/{timeline-definition-FHXFAJF6-DYJ4oUm8-D2oq5bFn.js → timeline-definition-FHXFAJF6-DYJ4oUm8-a7d-hF5Y.js} +1 -1
  75. package/dist/assets/treeView-QDETBFTQ-D27HWG6Q-Bf6uz3xV.js +1 -0
  76. package/dist/assets/treemap-6X3UGDF4-CmGIU3H5-CLzvNsC2.js +1 -0
  77. package/dist/assets/{vennDiagram-L72KCM5P-CdKAHoek-I-wP-h9k.js → vennDiagram-L72KCM5P-CdKAHoek-La4xWHGC.js} +1 -1
  78. package/dist/assets/wardley-OPB4EBWU-CbHWsb2k-OXtZqto9.js +1 -0
  79. package/dist/assets/{wardleyDiagram-EHGQE667-BF6c4_CW-BkrH7vLX.js → wardleyDiagram-EHGQE667-BF6c4_CW-M6-Z6fe5.js} +1 -1
  80. package/dist/assets/{xychartDiagram-FW5EYKEG-CGiKngj7-DMYCP46V.js → xychartDiagram-FW5EYKEG-CGiKngj7-BtTeKKIV.js} +1 -1
  81. package/dist/index.html +2 -2
  82. package/package.json +1 -1
  83. package/server/agents/claude-args.ts +5 -0
  84. package/server/agents/session-summary-prompt.ts +49 -0
  85. package/server/config/app-config.ts +13 -0
  86. package/server/git/github-star.ts +63 -0
  87. package/server/routes/repo-routes.ts +25 -0
  88. package/server/skills/mulmoterminal-config/SKILL.md +28 -1
  89. package/dist/assets/architecture-TIHT7OUA-0NsD2xW1-C95zkDEU.js +0 -1
  90. package/dist/assets/channel-7wUqSdoX-BYaGw2yS.js +0 -1
  91. package/dist/assets/classDiagram-OUVF2IWQ-BYlRi6YQ-EDJcEZLp.js +0 -1
  92. package/dist/assets/classDiagram-v2-EOCWNBFH-BCHaYHxj-EDJcEZLp.js +0 -1
  93. package/dist/assets/cynefin-VYW2F7L2-CGYr2F6h-Co-phwWx.js +0 -1
  94. package/dist/assets/eventmodeling-45OFAUF4-CWmqhm3a-D-dhMOz8.js +0 -1
  95. package/dist/assets/flowDiagram-23GEKE2U-DKSB5AiY-KiTeh-IZ.js +0 -1
  96. package/dist/assets/gitGraph-TEB2WS4Q-BR9qPwdN-Cd1rBWSG.js +0 -1
  97. package/dist/assets/index-CGwcisib.css +0 -1
  98. package/dist/assets/info-DKCQHKI2-Dplx5kMp-Dic4-0_Y.js +0 -1
  99. package/dist/assets/packet-7NZHBO7P-CQI3flND-BBywyu3N.js +0 -1
  100. package/dist/assets/pie-RZYD4A2V-CnmKE2Wa-CoicOL1H.js +0 -1
  101. package/dist/assets/radar-I7S5WNFK-us6x-Z9R-BeFXvO0F.js +0 -1
  102. package/dist/assets/railroad-3IZDKUUU-BKdz6pdN-BZY5Z4oN.js +0 -1
  103. package/dist/assets/railroad-abnf-AHOZXSZD-m_CSSIfd-Dubi7PGc.js +0 -1
  104. package/dist/assets/railroad-ebnf-EBAXGLYW-Nu3nAG7C-wnb7FBOh.js +0 -1
  105. package/dist/assets/railroad-peg-LSFZ7HO6--Y3mD4R_-P7vJjL8M.js +0 -1
  106. package/dist/assets/stateDiagram-v2-6OUMAXLB-CuzgCL2v-DjKerI1O.js +0 -1
  107. package/dist/assets/swimlanesDiagram-G3AALYLV-3bmSBtKs-Dm5TS_6E.js +0 -8
  108. package/dist/assets/treeView-QDETBFTQ-D27HWG6Q-H3pflPYY.js +0 -1
  109. package/dist/assets/treemap-6X3UGDF4-CmGIU3H5-CIoNkikG.js +0 -1
  110. package/dist/assets/wardley-OPB4EBWU-CbHWsb2k-JQdCXyum.js +0 -1
package/README.md CHANGED
@@ -223,6 +223,7 @@ The launcher detects it and prints the exact, OS-appropriate removal command; ru
223
223
  - [Session model](#session-model)
224
224
  - [Session lifecycle](#session-lifecycle)
225
225
  - [Claude hook injection](#claude-hook-injection)
226
+ - [Closing summary](#closing-summary)
226
227
  - [Session discovery & titles](#session-discovery--titles)
227
228
  - [Project structure](#project-structure)
228
229
  - [Testing](#testing)
@@ -287,7 +288,8 @@ today — **Claude Code** (the default) and **Codex**.
287
288
  - **Claude** — spawned as `claude` (override with `CLAUDE_BIN`). The server passes
288
289
  `--session-id <uuid>`, so it knows the live session's id even before its transcript
289
290
  file exists, and injects activity hooks + the GUI MCP per spawn (see
290
- [Claude hook injection](#claude-hook-injection)).
291
+ [Claude hook injection](#claude-hook-injection)) plus the
292
+ [closing summary](#closing-summary) instruction.
291
293
  - **Codex** — spawned as `codex` (override with `CODEX_BIN`; `CODEX_MODEL` sets
292
294
  `--model`). Codex runs on its own WebSocket (`/ws/codex`) and its sessions appear in the
293
295
  sidebar next to Claude's. Because Codex only mints its rollout id **after** the first
@@ -465,6 +467,7 @@ The Settings modal (⚙) persists per-user UI choices to `~/.mulmoterminal/confi
465
467
  | `worklogEnabled` | `true` to run the built-in **dev worklog** batch (see below). Off by default (each run spawns an LLM session, so it costs tokens). |
466
468
  | `worklogIntervalHours` | Worklog cadence in hours (default `6`, clamped to `1`–`168`). |
467
469
  | `terminalSubmit` | Which bytes Claude reads as **submit** vs **newline**: `"cr"` (default — Enter submits, Shift+Enter makes a newline) or `"esc-cr"` (for a Claude Code rebound the other way). Applies to the keyboard **and** the phone remote-view submit, for **Claude sessions only** (shell/codex keep plain Enter). See the [Configuration guide](https://receptron.github.io/mulmoterminal/guide/en/config.html#terminal-submit). |
470
+ | `copyOnSelect` | `true` puts a **mouse selection on the clipboard the moment it settles**, with no key pressed (the PuTTY / iTerm2 behaviour). **Off by default** — it changes the clipboard when you may only have meant to highlight something. No Settings UI: edit the file and reload the tab. Composes with the `copy` keymap action rather than replacing it. Over plain `http://` the browser gives a page no clipboard access, so a fallback asks xterm to copy instead; see the [Configuration guide](https://receptron.github.io/mulmoterminal/guide/en/config.html#copy-on-select). |
468
471
  | `prWorkdirFooter` | Ends the body of a PR **⧉ Open PR** creates with `work in <clone>` — the directory name of the clone the work happened in, so a PR says which of several side-by-side checkouts produced it. **On by default**; set `false` to opt out — read from the file per PR, so no restart is needed (there is no Settings control for it). Only applied to PRs this app creates (pressing the button again on an existing PR never re-appends). |
469
472
  | `fontFamily` | The **terminal font** every session renders in — a CSS font-family stack, e.g. `"'Cica', 'MS Gothic', monospace"`. No Settings UI: edit the file, then **restart** (this config is read once at startup). Unset uses the built-in stack (JetBrains Mono / Fira Code / Menlo / Consolas, then CJK faces for Japanese, Korean and Chinese). Unlike the per-browser font **size**, this is one value for the whole host — it names fonts, and which fonts exist is a property of the machine. A directory can override it. See the [Configuration guide](https://receptron.github.io/mulmoterminal/guide/en/config.html#font-family). |
470
473
 
@@ -920,6 +923,11 @@ Favorited collections get their own toolbar buttons.
920
923
  session.
921
924
  - **Notifications** (🔔) — a toolbar bell with an unread badge and a dropdown of active
922
925
  notifications; click a row to jump to its session.
926
+ - **Star MulmoTerminal** — a star button in the grid toolbar that stars the project on GitHub
927
+ through your own `gh` login, in one click. It is a one-time ask: once the repo is starred the
928
+ button is gone for good and stops calling the server at all. It shows **only when `gh` can
929
+ answer** — with no `gh`, no login, or no network, one click couldn't star anything, so nothing
930
+ is shown and nothing is recorded. Set `gh` up later and the button appears by itself.
923
931
  - **Voice input** — dictate a prompt via on-device Whisper (`POST /api/transcribe`, macOS
924
932
  only; the model downloads on first use). Settings picks **the language you dictate in**
925
933
  (per browser): your browser's, whisper's own per-clip detection, or a fixed one. Worth
@@ -1102,6 +1110,7 @@ same-origin-guarded.
1102
1110
  | `GET /api/worktrees?cwd=` · `GET /api/worktrees/diff?cwd=` | List managed worktrees / diff one vs its base. |
1103
1111
  | `POST /api/worktrees/create` · `/remove` · `/push` · `/pr` | Create on `agent/<slug>`, remove (managed root only), push, open a PR (`gh`, else compare URL). |
1104
1112
  | `GET /api/prs` · `GET /api/issues` | Open PRs / issues across the configured `prRepos` (via `gh`). |
1113
+ | `GET /api/github/star` · `POST /api/github/star` | Whether you have starred MulmoTerminal, and star it (via `gh`). `starred: null` means `gh` could not answer, and hides the button. |
1105
1114
 
1106
1115
  **Workspace views**
1107
1116
 
@@ -1328,6 +1337,30 @@ knows the live session's id — even before the session's `.jsonl` file exists.
1328
1337
 
1329
1338
  ---
1330
1339
 
1340
+ ## Closing summary
1341
+
1342
+ Every Claude session is spawned with `claude --append-system-prompt '<text>'`, asking the
1343
+ agent to end a reply with a short summary **when it hands control back** — the work is
1344
+ finished, or it is stopping to ask a question. Coming back to a grid cell after a while, the
1345
+ standing request and what came of it are otherwise only recoverable by scrolling the whole
1346
+ session.
1347
+
1348
+ The summary states three things: the request **for the conversation as a whole** (not the
1349
+ last message — several turns of refinement do not replace what was asked first), what was
1350
+ achieved, and what was not and why. It is written in the language of the conversation, and
1351
+ placed last with nothing after it.
1352
+
1353
+ It is deliberately **not** written on every turn: mid-work replies and short factual answers
1354
+ carry no standing request, and a summary that always appears stops being read. The wording
1355
+ lives in `server/agents/session-summary-prompt.ts`; there is no setting to turn it off.
1356
+
1357
+ Passed inline rather than as `--append-system-prompt-file` for the same reason `--settings`
1358
+ is: the sandbox spawn runs in a container that cannot read a host path.
1359
+
1360
+ Codex sessions are unaffected — the CLI has no equivalent flag.
1361
+
1362
+ ---
1363
+
1331
1364
  ## Session discovery & titles
1332
1365
 
1333
1366
  Claude stores each project's sessions as JSONL files under
@@ -0,0 +1,22 @@
1
+ // This project's own GitHub repository, and the wire shape of the star endpoints that act on it.
2
+ // Both sides decide from these — the server builds the `gh api` path and types its response,
3
+ // the client parses that response — so they live here rather than as two copies.
4
+ import { isRecord } from "./isRecord.js";
5
+
6
+ export const GITHUB_REPO = "receptron/mulmoterminal";
7
+
8
+ // GitHub's "star a repository" endpoint for this repo: GET reports the current state, PUT stars it.
9
+ export const STAR_API_PATH = `/user/starred/${GITHUB_REPO}`;
10
+
11
+ // GET/POST /api/github/star. `null` means the server could not tell — no `gh`, not logged in,
12
+ // offline. That is a DIFFERENT answer from "not starred": one click cannot star anything in that
13
+ // state, so the client hides the button rather than offering one that would do nothing.
14
+ export interface GithubStarState {
15
+ starred: boolean | null;
16
+ }
17
+
18
+ // Read a star state off an untrusted response body. Anything unparseable reads as "cannot tell",
19
+ // which is the same degradation as a failed request, so the caller needs no separate error path.
20
+ export function parseStarState(value: unknown): boolean | null {
21
+ return isRecord(value) && typeof value.starred === "boolean" ? value.starred : null;
22
+ }
@@ -50,3 +50,22 @@ export function clipboardActionFor(keymap: Keymap, e: ClipboardKeyEvent, hasSele
50
50
  // to be reversed.
51
51
  return action === "copy" && !hasSelection ? null : action;
52
52
  }
53
+
54
+ // Copy-on-select: the text a settled selection should put on the clipboard, or null to leave the
55
+ // clipboard alone. `lastCopied` is what this terminal wrote last, so an unchanged selection is not
56
+ // written twice.
57
+ //
58
+ // Unlike the rules above, this one ends in a clipboard WRITE — no keystroke happened, so nothing in
59
+ // the browser was ever going to copy anything by itself. That is what makes the two skips here
60
+ // matter more than they look:
61
+ //
62
+ // - Whitespace only. Dragging across empty terminal space selects spaces, and silently replacing
63
+ // the user's clipboard with a run of them is this feature's worst failure. Anyone who really
64
+ // wants indentation still has the `copy` keymap action.
65
+ // - Unchanged text. A second identical write buys nothing and costs a duplicate entry in the OS
66
+ // clipboard history (Win+V), which is the same reason the caller waits for the selection to
67
+ // settle instead of writing on every onSelectionChange.
68
+ export function selectionToCopy(enabled: boolean, selection: string, lastCopied: string | null): string | null {
69
+ if (!enabled || selection.trim() === "" || selection === lastCopied) return null;
70
+ return selection;
71
+ }
@@ -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-CO4zEYzL.js";import"./chunk-WYO6CB5R-BlzOfotS-DmR4SyZL.js";import"./chunk-VAUOI2AC-CS9QJ4yz-Cng5RPUP.js";import{n as i,r as a,t as o}from"./chunk-MOJQB5TN-CMZRaeqt-BsIB0ZXR.js";import{t as s}from"./chunk-JWPE2WC7-BQ3zXr2k-DSd3Ct95.js";var c=r().RailroadAbnf.parser.LangiumParser,l=e(e=>{let t=e.alternatives.map(u);return t.length===1?t[0]:{type:`choice`,alternatives:t}},`transformAlternation`),u=e(e=>{let t=e.elements.map(f);return t.length===1?t[0]:{type:`sequence`,elements:t}},`transformConcatenation`),d=e(e=>{if(e.includes(`*`)){let[t,n]=e.split(`*`);return{min:t?parseInt(t,10):0,max:n?parseInt(n,10):1/0}}let t=parseInt(e,10);return{min:t,max:t}},`parseRepeat`),f=e(e=>{let t=p(e.primary);if(!e.repeat)return t;let{min:n,max:r}=d(e.repeat);return n===0&&r===1?{type:`optional`,element:t}:{type:`repetition`,element:t,min:n,max:r}},`transformElement`),p=e(e=>{switch(e.$type){case`AbnfStringLiteral`:return{type:`terminal`,value:e.value};case`AbnfNumVal`:return{type:`terminal`,value:e.value};case`AbnfRuleName`:return{type:`nonterminal`,name:e.name};case`AbnfGroup`:return l(e.element);case`AbnfOptionalGroup`:return{type:`optional`,element:l(e.element)};default:throw Error(`Unsupported ABNF primary node: ${e.$type}`)}},`transformPrimary`),m=e(e=>({name:e.name,definition:l(e.definition)}),`transformRule`),h=e(e=>{s(e,a),e.title&&a.setTitle(e.title),e.rules.map(e=>a.addRule(m(e)))},`populateDb`),g={parser:{parse:e(e=>{a.clear(),t.debug(`[ABNF Parser] Starting Langium parse`);let r=c.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new n(r);let i=r.value;t.debug(`[ABNF Parser] Parsed rules:`,i.rules.length),h(i),t.debug(`[ABNF Parser] Parse complete`)},`parse`),parser:{yy:a}},db:a,renderer:o,styles:i};export{g as diagram};
1
+ import{n as e}from"./chunk-Y2CYZVJY-Bdt8pFDJ-DsF7k-Jl.js";import{f as t}from"./src-Brzfja-q-ch1VcTiG.js";import{_ as n,g as r}from"./mermaid-parser.core-DxEa8E3F-BILJo_fK.js";import"./chunk-WYO6CB5R-BlzOfotS-04XZ1Jfd.js";import"./chunk-VAUOI2AC-CS9QJ4yz-Dd_VpRsu.js";import{n as i,r as a,t as o}from"./chunk-MOJQB5TN-CMZRaeqt-Dy6S_sS_.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-BILJo_fK.js";export{e as createArchitectureServices};