collabmd 0.1.47 → 0.1.48

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 (100) hide show
  1. package/README.md +9 -6
  2. package/dist/client/assets/JetBrainsMono-Regular-BQaDgvhP.woff2 +0 -0
  3. package/dist/client/assets/babel-CY5KOv-I.js +16 -0
  4. package/dist/client/assets/comment-ui-shared-DuoyznXW.js +7 -0
  5. package/dist/client/assets/dist-ChRoo3IB.js +9 -0
  6. package/dist/client/assets/document-formatter-Dxl_a8XO.js +2 -0
  7. package/dist/client/assets/{drawio-editor-BjrxTe3l.js → drawio-editor-BVaNNtYp.js} +2 -2
  8. package/dist/client/assets/{drawioEditor-DUVZjSSr.js → drawioEditor-BkIBlXx0.js} +2 -2
  9. package/dist/client/assets/editor-session-DMyVdHLj.js +54 -0
  10. package/dist/client/assets/embedded-editor-base-B3l6Xy65.css +1 -0
  11. package/dist/client/assets/estree-CuT_pB8K.js +44 -0
  12. package/dist/client/assets/{excalidraw-editor-BlcN6umJ.css → excalidraw-editor-BbSbI80a.css} +1 -1
  13. package/dist/client/assets/excalidraw-editor-BjYaNEMY.js +9 -0
  14. package/dist/client/assets/{excalidrawEditor-B0jOK3lv.js → excalidrawEditor-ChqF_d82.js} +2 -2
  15. package/dist/client/assets/export-page-Dyu0XCbu.js +57 -0
  16. package/dist/client/assets/exportDocument-CJBx4Xjx.css +1 -0
  17. package/dist/client/assets/{exportDocument-Dg9MjkIk.js → exportDocument-Dgvfa2Sd.js} +2 -2
  18. package/dist/client/assets/{file-icon-svg-CQAjlWjK.js → file-icon-svg-Y_kpF957.js} +1 -1
  19. package/dist/client/assets/file-kind-BwMIcZbi.js +1 -0
  20. package/dist/client/assets/file-search-DDLyyLDU.js +1 -0
  21. package/dist/client/assets/html-Cdnr2qzU.js +25 -0
  22. package/dist/client/assets/index-CSNIMyOP.css +1 -0
  23. package/dist/client/assets/index-DG3N2Ps-.js +2 -0
  24. package/dist/client/assets/main-D0wCxpVn.js +903 -0
  25. package/dist/client/assets/markdown-CByV-4CU.js +70 -0
  26. package/dist/client/assets/mermaid.core-BJRLUQZE.js +11 -0
  27. package/dist/client/assets/{preview-render-compiler-BApvlLLo.js → preview-render-compiler-CrJIooVD.js} +2 -2
  28. package/dist/client/assets/preview-render-compiler-O0JxBVNF.js +1 -0
  29. package/dist/client/assets/{preview-render-profile-CE-5rVTC.js → preview-render-profile-B4RWYWHt.js} +1 -1
  30. package/dist/client/assets/{preview-render-worker-BmN79bVc.js → preview-render-worker-_QTxqKvP.js} +22 -22
  31. package/dist/client/assets/quick-switcher-controller-CaEjEtq_.js +1 -0
  32. package/dist/client/assets/standalone-6z5x8CWe.js +29 -0
  33. package/dist/client/assets/{vault-api-client-_LpV1aIn.js → vault-api-client-BkwdFjx0.js} +2 -2
  34. package/dist/client/assets/{es-CAsWR6hG.js → vault-utils-DvoSftJT.js} +1 -1
  35. package/dist/client/assets/yaml-9ltHPDNO.js +154 -0
  36. package/dist/client/drawio-editor.html +1 -1
  37. package/dist/client/excalidraw-editor.html +1 -1
  38. package/dist/client/export-document.html +2 -2
  39. package/dist/client/index.html +41 -19
  40. package/package.json +4 -1
  41. package/src/client/app/index.html +39 -17
  42. package/src/client/application/app-shell/export-feature.js +17 -1
  43. package/src/client/application/app-shell/git-feature.js +28 -9
  44. package/src/client/application/app-shell/ui-feature-identity.js +13 -0
  45. package/src/client/application/app-shell/ui-feature-shell.js +164 -9
  46. package/src/client/application/app-shell-elements.js +4 -0
  47. package/src/client/application/workspace-coordinator.js +21 -4
  48. package/src/client/application/workspace-preview-controller.js +120 -2
  49. package/src/client/application/workspace-route-controller.js +4 -1
  50. package/src/client/assets/vendor/jetbrains-mono/JetBrainsMono-Regular.woff2 +0 -0
  51. package/src/client/assets/vendor/jetbrains-mono/OFL.txt +93 -0
  52. package/src/client/bootstrap/collabmd-app-shell.js +21 -5
  53. package/src/client/domain/document-formatter.js +193 -0
  54. package/src/client/domain/file-search.js +73 -0
  55. package/src/client/domain/git-labels.js +5 -0
  56. package/src/client/domain/vault-paths.js +6 -4
  57. package/src/client/domain/wiki-link-completions.js +20 -20
  58. package/src/client/drawio-editor.js +8 -3
  59. package/src/client/excalidraw-editor.js +152 -6
  60. package/src/client/export/export-host.js +56 -35
  61. package/src/client/export/export-page.js +14 -4
  62. package/src/client/export/export-pipeline.js +266 -25
  63. package/src/client/infrastructure/editor-session.js +4 -0
  64. package/src/client/infrastructure/editor-view-adapter.js +60 -14
  65. package/src/client/presentation/bases-preview-controller.js +35 -11
  66. package/src/client/presentation/file-action-controller.js +15 -2
  67. package/src/client/presentation/file-explorer-controller.js +3 -0
  68. package/src/client/presentation/file-explorer-view.js +2 -1
  69. package/src/client/presentation/file-history-view-controller.js +6 -1
  70. package/src/client/presentation/file-tree-state.js +1 -11
  71. package/src/client/presentation/git-diff-view-controller.js +36 -11
  72. package/src/client/presentation/git-panel-controller.js +10 -6
  73. package/src/client/presentation/quick-switcher-controller.js +54 -154
  74. package/src/client/styles/components/scrollbars.css +10 -0
  75. package/src/client/styles/export-document.css +44 -29
  76. package/src/client/styles/features/collaboration-presence.css +13 -1
  77. package/src/client/styles/features/preview-markdown.css +54 -0
  78. package/src/client/styles/foundation/tokens.css +8 -0
  79. package/src/client/styles/layout/shell.css +76 -24
  80. package/src/client/styles/layout/view-modes.css +2 -0
  81. package/src/client/styles/overrides/codemirror.css +31 -19
  82. package/src/client/styles/surfaces/excalidraw-editor.css +42 -0
  83. package/src/domain/file-kind.js +12 -1
  84. package/src/server/domain/ripgrep-search-service.js +110 -37
  85. package/src/server/infrastructure/persistence/path-utils.js +10 -4
  86. package/src/server/infrastructure/persistence/vault-file-store.js +2 -0
  87. package/dist/client/assets/comment-ui-shared-DWkk9Vh3.js +0 -7
  88. package/dist/client/assets/editor-session-DfZuRgB_.js +0 -54
  89. package/dist/client/assets/embedded-editor-base-DvMynhKu.css +0 -1
  90. package/dist/client/assets/excalidraw-editor-D7pnUCLH.js +0 -9
  91. package/dist/client/assets/export-page-Bs3xE1fg.js +0 -57
  92. package/dist/client/assets/exportDocument-PnYU3v1s.css +0 -1
  93. package/dist/client/assets/file-kind-BbqgGzpc.js +0 -1
  94. package/dist/client/assets/index-BIpgxyGZ.css +0 -1
  95. package/dist/client/assets/index-Z5sI0Bj-.js +0 -2
  96. package/dist/client/assets/main-Dwnj9Gaq.js +0 -903
  97. package/dist/client/assets/mermaid.core-CLZBlpIW.js +0 -11
  98. package/dist/client/assets/preview-render-compiler-BQ_3h9vD.js +0 -1
  99. package/dist/client/assets/quick-switcher-controller-ButWPmCI.js +0 -12
  100. package/dist/client/assets/vault-utils-wdQ0RNR9.js +0 -1
@@ -15,16 +15,16 @@
15
15
  document.documentElement.setAttribute('data-initial-file-requested', 'true');
16
16
  }
17
17
  </script>
18
- <script type="module" crossorigin src="./assets/index-Z5sI0Bj-.js"></script>
18
+ <script type="module" crossorigin src="./assets/index-DG3N2Ps-.js"></script>
19
19
  <link rel="modulepreload" crossorigin href="./assets/modulepreload-polyfill-P2Xu9kJm.js">
20
20
  <link rel="modulepreload" crossorigin href="./assets/preload-helper-HclGiUj8.js">
21
21
  <link rel="modulepreload" crossorigin href="./assets/base-BYODPHdS.js">
22
22
  <link rel="stylesheet" crossorigin href="./assets/base-CaIEJUF9.css">
23
- <link rel="stylesheet" crossorigin href="./assets/index-BIpgxyGZ.css">
23
+ <link rel="stylesheet" crossorigin href="./assets/index-CSNIMyOP.css">
24
24
  </head>
25
25
  <body>
26
26
 
27
- <a href="#editorContainer" class="sr-only skip-link">Skip to editor</a>
27
+ <a href="#editorContainer" class="sr-only skip-link" id="skipToEditor">Skip to editor</a>
28
28
 
29
29
  <div class="app-shell">
30
30
  <aside id="sidebar" class="sidebar">
@@ -216,6 +216,16 @@
216
216
  </div>
217
217
 
218
218
  <div class="toolbar-right">
219
+ <button class="ui-button ui-button--ghost ui-button--compact hidden" id="reviewFileChangesBtn" type="button" aria-label="Review changes to this file" title="Review changes to this file">
220
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
221
+ <line x1="6" y1="3" x2="6" y2="15"></line>
222
+ <circle cx="18" cy="6" r="3"></circle>
223
+ <circle cx="6" cy="18" r="3"></circle>
224
+ <path d="M18 9a9 9 0 0 1-9 9"></path>
225
+ </svg>
226
+ <span class="ui-toolbar-button-label">Review changes</span>
227
+ </button>
228
+
219
229
  <button class="ui-button ui-button--ghost ui-button--toolbar mobile-view-toggle" id="mobileViewToggle" aria-label="Toggle editor/preview" title="Toggle view">
220
230
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
221
231
  <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
@@ -227,9 +237,13 @@
227
237
  <div class="toolbar-status-cluster" aria-label="Workspace status">
228
238
  <span class="ui-pill-badge ui-pill-badge--accent hidden toolbar-badge" id="toolbarDiffBadge">Diff</span>
229
239
  <span class="ui-pill-badge ui-pill-badge--muted hidden toolbar-badge" id="gitOperationStatus" aria-live="polite" aria-atomic="true"></span>
240
+ </div>
241
+
242
+ <div class="toolbar-presence-cluster">
243
+ <div class="user-avatars" id="userAvatars"></div>
230
244
  <button
231
245
  type="button"
232
- class="ui-pill-badge ui-pill-badge--muted toolbar-badge toolbar-badge-button"
246
+ class="ui-pill-badge ui-pill-badge--muted toolbar-badge toolbar-badge-button toolbar-presence-count"
233
247
  id="userCount"
234
248
  aria-controls="presencePanel"
235
249
  aria-expanded="false"
@@ -237,8 +251,6 @@
237
251
  ></button>
238
252
  </div>
239
253
 
240
- <div class="user-avatars toolbar-presence-cluster" id="userAvatars"></div>
241
-
242
254
  <section class="collaboration-popover presence-panel hidden" id="presencePanel" aria-label="Online users" aria-hidden="true">
243
255
  <div class="presence-panel-header">
244
256
  <div>
@@ -483,6 +495,14 @@
483
495
  </svg>
484
496
  <span class="ui-action-label">Comment</span>
485
497
  </button>
498
+ <button class="ui-button ui-button--ghost ui-button--compact ui-button--toggle" id="editorFormatBtn" aria-label="Format document" title="Format document">
499
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
500
+ <path d="M4 7h10"></path>
501
+ <path d="M4 12h16"></path>
502
+ <path d="M4 17h10"></path>
503
+ </svg>
504
+ <span class="ui-action-label">Format</span>
505
+ </button>
486
506
  <button class="ui-button ui-button--ghost ui-button--compact ui-button--toggle" id="toggleWrapBtn" aria-label="Disable line wrap" title="Disable line wrap">
487
507
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
488
508
  <path d="M3 6h14a4 4 0 1 1 0 8H9"></path>
@@ -513,6 +533,7 @@
513
533
  <div class="pane-header">
514
534
  <span class="pane-label">Preview</span>
515
535
  <div class="pane-header-actions">
536
+ <button class="ui-button ui-button--ghost ui-button--compact ui-button--toggle hidden" id="htmlPreviewMaximize" aria-label="Maximize HTML preview" title="Maximize HTML preview"></button>
516
537
  <div id="backlinksHeaderPanel" class="backlinks-panel backlinks-panel-header hidden" data-backlinks-variant="header">
517
538
  <button type="button" class="backlinks-header" aria-expanded="false">
518
539
  <svg class="backlinks-chevron" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
@@ -619,16 +640,10 @@
619
640
  </button>
620
641
  <div class="diff-toolbar-actions-group diff-toolbar-actions-group-git" id="diffGitActionsGroup" role="group" aria-label="Git file actions">
621
642
  <button class="ui-button ui-button--secondary ui-button--action ui-button--wide ui-button--surface" id="diffPrimaryActionBtn" type="button" disabled>
622
- Stage
643
+ Include in commit
623
644
  </button>
624
645
  <button class="ui-button ui-button--primary ui-button--action ui-button--wide" id="diffCommitBtn" type="button" disabled>
625
- Commit Staged
626
- </button>
627
- </div>
628
- <span class="diff-toolbar-actions-divider" id="diffToolbarDivider" aria-hidden="true"></span>
629
- <div class="diff-toolbar-actions-group" id="diffEditorActionsGroup" role="group" aria-label="Navigation actions">
630
- <button class="ui-button ui-button--secondary ui-button--action ui-button--wide ui-button--surface diff-open-editor-btn" id="diffOpenEditorBtn" type="button" disabled>
631
- Open in Editor
646
+ Commit included files
632
647
  </button>
633
648
  </div>
634
649
  </div>
@@ -646,6 +661,12 @@
646
661
  <button class="ui-segmented-btn active view-btn diff-mode-btn" data-diff-mode="unified" type="button">Unified</button>
647
662
  <button class="ui-segmented-btn view-btn diff-mode-btn" data-diff-mode="split" type="button">Split</button>
648
663
  </div>
664
+ <span class="diff-toolbar-actions-divider" id="diffToolbarDivider" aria-hidden="true"></span>
665
+ <div class="diff-toolbar-actions-group" id="diffEditorActionsGroup" role="group" aria-label="Navigation actions">
666
+ <button class="ui-button ui-button--secondary ui-button--action ui-button--wide ui-button--surface diff-open-editor-btn" id="diffOpenEditorBtn" type="button" disabled>
667
+ Open in editor
668
+ </button>
669
+ </div>
649
670
  </div>
650
671
  </div>
651
672
  <div class="diff-scroll" id="diffScroll">
@@ -694,16 +715,17 @@
694
715
  <dialog class="app-dialog" id="gitCommitDialog">
695
716
  <form class="app-dialog-form" id="gitCommitForm" method="dialog">
696
717
  <div class="app-dialog-header">
697
- <h2 class="app-dialog-title" id="gitCommitTitle">Commit staged changes</h2>
698
- <p class="app-dialog-copy" id="gitCommitCopy">All staged changes will be included.</p>
718
+ <h2 class="app-dialog-title" id="gitCommitTitle">Commit included files</h2>
719
+ <p class="app-dialog-copy" id="gitCommitCopy">All included changes will be committed.</p>
699
720
  </div>
700
721
  <label class="app-dialog-field" for="gitCommitInput">
701
- <span class="app-dialog-label">Commit message</span>
702
- <input type="text" class="ui-input" id="gitCommitInput" name="gitCommitMessage" autocomplete="off" spellcheck="true" required>
722
+ <span class="app-dialog-label">What changed?</span>
723
+ <input type="text" class="ui-input" id="gitCommitInput" name="gitCommitMessage" autocomplete="off" spellcheck="true" aria-describedby="gitCommitHint" required>
724
+ <span class="app-dialog-hint" id="gitCommitHint">This becomes the Git commit message.</span>
703
725
  </label>
704
726
  <div class="app-dialog-actions">
705
727
  <button type="button" class="ui-button ui-button--secondary" id="gitCommitCancel">Cancel</button>
706
- <button type="submit" class="ui-button ui-button--primary" id="gitCommitSubmit">Commit staged changes</button>
728
+ <button type="submit" class="ui-button ui-button--primary" id="gitCommitSubmit">Commit included files</button>
707
729
  </div>
708
730
  </form>
709
731
  </dialog>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "collabmd",
3
- "version": "0.1.47",
3
+ "version": "0.1.48",
4
4
  "type": "module",
5
5
  "description": "Collaborative markdown vault — like Obsidian, but online. Serve any directory of markdown files for realtime collaborative editing.",
6
6
  "repository": {
@@ -69,6 +69,7 @@
69
69
  "dependencies": {
70
70
  "@codemirror/autocomplete": "^6.20.3",
71
71
  "@codemirror/commands": "^6.11.0",
72
+ "@codemirror/lang-html": "^6.4.11",
72
73
  "@codemirror/lang-markdown": "^6.5.2",
73
74
  "@codemirror/lang-yaml": "^6.1.3",
74
75
  "@codemirror/language": "^6.12.4",
@@ -87,7 +88,9 @@
87
88
  "lib0": "^0.2.117",
88
89
  "markdown-it": "^15.0.0",
89
90
  "mermaid": "^11.17.0",
91
+ "mermaid-formatter": "^0.3.0",
90
92
  "openid-client": "^6.8.7",
93
+ "prettier": "^3.9.6",
91
94
  "react": "^19.2.8",
92
95
  "react-dom": "^19.2.8",
93
96
  "sharp": "^0.35.3",
@@ -18,7 +18,7 @@
18
18
  </head>
19
19
  <body>
20
20
 
21
- <a href="#editorContainer" class="sr-only skip-link">Skip to editor</a>
21
+ <a href="#editorContainer" class="sr-only skip-link" id="skipToEditor">Skip to editor</a>
22
22
 
23
23
  <div class="app-shell">
24
24
  <aside id="sidebar" class="sidebar">
@@ -210,6 +210,16 @@
210
210
  </div>
211
211
 
212
212
  <div class="toolbar-right">
213
+ <button class="ui-button ui-button--ghost ui-button--compact hidden" id="reviewFileChangesBtn" type="button" aria-label="Review changes to this file" title="Review changes to this file">
214
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
215
+ <line x1="6" y1="3" x2="6" y2="15"></line>
216
+ <circle cx="18" cy="6" r="3"></circle>
217
+ <circle cx="6" cy="18" r="3"></circle>
218
+ <path d="M18 9a9 9 0 0 1-9 9"></path>
219
+ </svg>
220
+ <span class="ui-toolbar-button-label">Review changes</span>
221
+ </button>
222
+
213
223
  <button class="ui-button ui-button--ghost ui-button--toolbar mobile-view-toggle" id="mobileViewToggle" aria-label="Toggle editor/preview" title="Toggle view">
214
224
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
215
225
  <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
@@ -221,9 +231,13 @@
221
231
  <div class="toolbar-status-cluster" aria-label="Workspace status">
222
232
  <span class="ui-pill-badge ui-pill-badge--accent hidden toolbar-badge" id="toolbarDiffBadge">Diff</span>
223
233
  <span class="ui-pill-badge ui-pill-badge--muted hidden toolbar-badge" id="gitOperationStatus" aria-live="polite" aria-atomic="true"></span>
234
+ </div>
235
+
236
+ <div class="toolbar-presence-cluster">
237
+ <div class="user-avatars" id="userAvatars"></div>
224
238
  <button
225
239
  type="button"
226
- class="ui-pill-badge ui-pill-badge--muted toolbar-badge toolbar-badge-button"
240
+ class="ui-pill-badge ui-pill-badge--muted toolbar-badge toolbar-badge-button toolbar-presence-count"
227
241
  id="userCount"
228
242
  aria-controls="presencePanel"
229
243
  aria-expanded="false"
@@ -231,8 +245,6 @@
231
245
  ></button>
232
246
  </div>
233
247
 
234
- <div class="user-avatars toolbar-presence-cluster" id="userAvatars"></div>
235
-
236
248
  <section class="collaboration-popover presence-panel hidden" id="presencePanel" aria-label="Online users" aria-hidden="true">
237
249
  <div class="presence-panel-header">
238
250
  <div>
@@ -477,6 +489,14 @@
477
489
  </svg>
478
490
  <span class="ui-action-label">Comment</span>
479
491
  </button>
492
+ <button class="ui-button ui-button--ghost ui-button--compact ui-button--toggle" id="editorFormatBtn" aria-label="Format document" title="Format document">
493
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
494
+ <path d="M4 7h10"></path>
495
+ <path d="M4 12h16"></path>
496
+ <path d="M4 17h10"></path>
497
+ </svg>
498
+ <span class="ui-action-label">Format</span>
499
+ </button>
480
500
  <button class="ui-button ui-button--ghost ui-button--compact ui-button--toggle" id="toggleWrapBtn" aria-label="Disable line wrap" title="Disable line wrap">
481
501
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
482
502
  <path d="M3 6h14a4 4 0 1 1 0 8H9"></path>
@@ -507,6 +527,7 @@
507
527
  <div class="pane-header">
508
528
  <span class="pane-label">Preview</span>
509
529
  <div class="pane-header-actions">
530
+ <button class="ui-button ui-button--ghost ui-button--compact ui-button--toggle hidden" id="htmlPreviewMaximize" aria-label="Maximize HTML preview" title="Maximize HTML preview"></button>
510
531
  <div id="backlinksHeaderPanel" class="backlinks-panel backlinks-panel-header hidden" data-backlinks-variant="header">
511
532
  <button type="button" class="backlinks-header" aria-expanded="false">
512
533
  <svg class="backlinks-chevron" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
@@ -613,16 +634,10 @@
613
634
  </button>
614
635
  <div class="diff-toolbar-actions-group diff-toolbar-actions-group-git" id="diffGitActionsGroup" role="group" aria-label="Git file actions">
615
636
  <button class="ui-button ui-button--secondary ui-button--action ui-button--wide ui-button--surface" id="diffPrimaryActionBtn" type="button" disabled>
616
- Stage
637
+ Include in commit
617
638
  </button>
618
639
  <button class="ui-button ui-button--primary ui-button--action ui-button--wide" id="diffCommitBtn" type="button" disabled>
619
- Commit Staged
620
- </button>
621
- </div>
622
- <span class="diff-toolbar-actions-divider" id="diffToolbarDivider" aria-hidden="true"></span>
623
- <div class="diff-toolbar-actions-group" id="diffEditorActionsGroup" role="group" aria-label="Navigation actions">
624
- <button class="ui-button ui-button--secondary ui-button--action ui-button--wide ui-button--surface diff-open-editor-btn" id="diffOpenEditorBtn" type="button" disabled>
625
- Open in Editor
640
+ Commit included files
626
641
  </button>
627
642
  </div>
628
643
  </div>
@@ -640,6 +655,12 @@
640
655
  <button class="ui-segmented-btn active view-btn diff-mode-btn" data-diff-mode="unified" type="button">Unified</button>
641
656
  <button class="ui-segmented-btn view-btn diff-mode-btn" data-diff-mode="split" type="button">Split</button>
642
657
  </div>
658
+ <span class="diff-toolbar-actions-divider" id="diffToolbarDivider" aria-hidden="true"></span>
659
+ <div class="diff-toolbar-actions-group" id="diffEditorActionsGroup" role="group" aria-label="Navigation actions">
660
+ <button class="ui-button ui-button--secondary ui-button--action ui-button--wide ui-button--surface diff-open-editor-btn" id="diffOpenEditorBtn" type="button" disabled>
661
+ Open in editor
662
+ </button>
663
+ </div>
643
664
  </div>
644
665
  </div>
645
666
  <div class="diff-scroll" id="diffScroll">
@@ -688,16 +709,17 @@
688
709
  <dialog class="app-dialog" id="gitCommitDialog">
689
710
  <form class="app-dialog-form" id="gitCommitForm" method="dialog">
690
711
  <div class="app-dialog-header">
691
- <h2 class="app-dialog-title" id="gitCommitTitle">Commit staged changes</h2>
692
- <p class="app-dialog-copy" id="gitCommitCopy">All staged changes will be included.</p>
712
+ <h2 class="app-dialog-title" id="gitCommitTitle">Commit included files</h2>
713
+ <p class="app-dialog-copy" id="gitCommitCopy">All included changes will be committed.</p>
693
714
  </div>
694
715
  <label class="app-dialog-field" for="gitCommitInput">
695
- <span class="app-dialog-label">Commit message</span>
696
- <input type="text" class="ui-input" id="gitCommitInput" name="gitCommitMessage" autocomplete="off" spellcheck="true" required>
716
+ <span class="app-dialog-label">What changed?</span>
717
+ <input type="text" class="ui-input" id="gitCommitInput" name="gitCommitMessage" autocomplete="off" spellcheck="true" aria-describedby="gitCommitHint" required>
718
+ <span class="app-dialog-hint" id="gitCommitHint">This becomes the Git commit message.</span>
697
719
  </label>
698
720
  <div class="app-dialog-actions">
699
721
  <button type="button" class="ui-button ui-button--secondary" id="gitCommitCancel">Cancel</button>
700
- <button type="submit" class="ui-button ui-button--primary" id="gitCommitSubmit">Commit staged changes</button>
722
+ <button type="submit" class="ui-button ui-button--primary" id="gitCommitSubmit">Commit included files</button>
701
723
  </div>
702
724
  </form>
703
725
  </dialog>
@@ -1,5 +1,5 @@
1
1
  import { isMarkdownFilePath } from '../../../domain/file-kind.js';
2
- import { exportDocument, initializeExportBridge } from '../../export/export-host.js';
2
+ import { exportDirectory, exportDocument, initializeExportBridge } from '../../export/export-host.js';
3
3
 
4
4
  export const exportFeature = {
5
5
  initializeExportBridge() {
@@ -15,6 +15,22 @@ export const exportFeature = {
15
15
  this._exportBridgeInitialized = true;
16
16
  },
17
17
 
18
+ async handleDirectoryExportRequest(directoryPath, format) {
19
+ try {
20
+ await exportDirectory({
21
+ currentFilePath: this.currentFilePath,
22
+ currentMarkdownText: this.session?.getText?.() ?? '',
23
+ directoryPath,
24
+ fileList: this.fileExplorer?.flatDocumentFiles ?? [],
25
+ format,
26
+ });
27
+ return true;
28
+ } catch (error) {
29
+ this.toastController?.show(error instanceof Error ? error.message : 'Failed to start folder export');
30
+ return false;
31
+ }
32
+ },
33
+
18
34
  async handleExportRequest(format) {
19
35
  const filePath = String(this.currentFilePath ?? '').trim();
20
36
  if (!isMarkdownFilePath(filePath)) {
@@ -1,3 +1,4 @@
1
+ import { commitButtonLabel } from '../../domain/git-labels.js';
1
2
  import { createWorkspaceChange } from '../../../domain/workspace-change.js';
2
3
 
3
4
  export const gitFeature = {
@@ -89,6 +90,7 @@ export const gitFeature = {
89
90
  this.elements.gitSidebarTab?.classList.toggle('has-changes', hasChanges);
90
91
 
91
92
  this.gitDiffView.setRepoStatus(this.gitRepoAvailable ? status : null);
93
+ this.syncReviewFileChangesButton();
92
94
 
93
95
  if (!this.gitRepoAvailable && this.activeSidebarTab === 'git') {
94
96
  this.syncFileHistoryButton({ mode: this.navigation.getHashRoute().type === 'git-file-preview' ? 'history-preview' : 'editor' });
@@ -146,6 +148,21 @@ export const gitFeature = {
146
148
  button.title = 'View file history';
147
149
  },
148
150
 
151
+ syncReviewFileChangesButton({
152
+ filePath = this.currentFilePath,
153
+ mode = 'editor',
154
+ } = {}) {
155
+ const button = this.elements.reviewFileChangesButton;
156
+ if (!button) {
157
+ return;
158
+ }
159
+
160
+ button.classList.toggle(
161
+ 'hidden',
162
+ !this.gitRepoAvailable || mode !== 'editor' || !filePath,
163
+ );
164
+ },
165
+
149
166
  syncMainChrome({ badgeLabel = '', mode, title = null } = {}) {
150
167
  const isSpecialMode = mode === 'diff' || mode === 'history' || mode === 'history-preview';
151
168
  this.elements.toolbarViewToggle?.classList.toggle('hidden', isSpecialMode);
@@ -161,6 +178,7 @@ export const gitFeature = {
161
178
  }
162
179
 
163
180
  this.syncFileHistoryButton({ filePath: this.currentFilePath, mode });
181
+ this.syncReviewFileChangesButton({ filePath: this.currentFilePath, mode });
164
182
  },
165
183
 
166
184
  async showGitDiff({ filePath = null, scope = 'all' } = {}) {
@@ -635,17 +653,18 @@ export const gitFeature = {
635
653
  return;
636
654
  }
637
655
 
656
+ const includedFileCount = Number(this.gitPanel.status?.summary?.staged || 0);
657
+ const commitLabel = commitButtonLabel(includedFileCount);
638
658
  if (this.elements.gitCommitTitle) {
639
- this.elements.gitCommitTitle.textContent = 'Commit staged changes';
659
+ this.elements.gitCommitTitle.textContent = commitLabel;
640
660
  }
641
661
  if (this.elements.gitCommitCopy) {
642
- const stagedCount = Number(this.gitPanel.status?.summary?.staged || 0);
643
- this.elements.gitCommitCopy.textContent = stagedCount > 0
644
- ? `${stagedCount} staged file${stagedCount === 1 ? '' : 's'} will be included.`
645
- : 'All staged changes will be included.';
662
+ this.elements.gitCommitCopy.textContent = includedFileCount > 0
663
+ ? `This commit will include ${includedFileCount} file${includedFileCount === 1 ? '' : 's'}.`
664
+ : 'All included changes will be committed.';
646
665
  }
647
666
  if (this.elements.gitCommitSubmit) {
648
- this.elements.gitCommitSubmit.textContent = 'Commit staged changes';
667
+ this.elements.gitCommitSubmit.textContent = commitLabel;
649
668
  }
650
669
  input.value = '';
651
670
 
@@ -673,7 +692,7 @@ export const gitFeature = {
673
692
  }
674
693
  if (!message) {
675
694
  input.focus();
676
- this.toastController.show('Commit message cannot be empty');
695
+ this.toastController.show('Describe what changed before committing');
677
696
  return;
678
697
  }
679
698
 
@@ -693,10 +712,10 @@ export const gitFeature = {
693
712
  });
694
713
  dialog.close();
695
714
  } catch (error) {
696
- this.toastController.show(error.message || 'Failed to commit staged changes');
715
+ this.toastController.show(error.message || 'Failed to commit included changes');
697
716
  } finally {
698
717
  if (submit) {
699
- submit.textContent = 'Commit staged changes';
718
+ submit.textContent = 'Commit included files';
700
719
  }
701
720
  submit?.toggleAttribute('disabled', false);
702
721
  }
@@ -44,6 +44,7 @@ function openDisplayNameDialog({ mode = 'edit' } = {}) {
44
44
  if (!dialog || !input) return;
45
45
 
46
46
  const isOnboarding = mode === 'onboarding';
47
+ this._displayNameDialogMode = mode;
47
48
  if (title) {
48
49
  title.textContent = isOnboarding ? 'Choose your display name' : 'Update display name';
49
50
  }
@@ -88,6 +89,17 @@ function promptForDisplayNameIfNeeded() {
88
89
  });
89
90
  }
90
91
 
92
+ /** @this {UiIdentityContext} */
93
+ function handleDisplayNameCancel() {
94
+ if (this._displayNameDialogMode === 'onboarding' && !this.getStoredUserName()) {
95
+ const guestName = this.getCurrentUserName();
96
+ if (guestName) {
97
+ this.preferences.setUserName(guestName);
98
+ }
99
+ }
100
+ this.elements.displayNameDialog?.close();
101
+ }
102
+
91
103
  /** @this {UiIdentityContext} */
92
104
  function handleDisplayNameSubmit() {
93
105
  if (this.isIdentityManagedByAuth()) {
@@ -164,6 +176,7 @@ export const uiFeatureIdentityMethods = {
164
176
  getCurrentUser,
165
177
  getCurrentUserName,
166
178
  getStoredUserName,
179
+ handleDisplayNameCancel,
167
180
  handleDisplayNameSubmit,
168
181
  isIdentityManagedByAuth,
169
182
  openDisplayNameDialog,