@rightkit/document-workspace 0.0.0-stage → 0.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.
Files changed (262) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/LICENSE-APACHE +201 -0
  3. package/LICENSE-MIT +21 -0
  4. package/README.md +51 -2
  5. package/dist/app/App.d.ts +1 -0
  6. package/dist/app/App.js +6 -0
  7. package/dist/app/AppDialogs.d.ts +52 -0
  8. package/dist/app/AppDialogs.js +23 -0
  9. package/dist/app/AppDialogsHost.d.ts +31 -0
  10. package/dist/app/AppDialogsHost.js +30 -0
  11. package/dist/app/AppLifecycle.d.ts +19 -0
  12. package/dist/app/AppLifecycle.js +87 -0
  13. package/dist/app/AppProvider.d.ts +317 -0
  14. package/dist/app/AppProvider.js +217 -0
  15. package/dist/app/AppRoot.d.ts +8 -0
  16. package/dist/app/AppRoot.js +159 -0
  17. package/dist/app/AppShell.d.ts +2 -0
  18. package/dist/app/AppShell.js +81 -0
  19. package/dist/app/CommandPalette.d.ts +13 -0
  20. package/dist/app/CommandPalette.js +47 -0
  21. package/dist/app/DocActionBar.d.ts +36 -0
  22. package/dist/app/DocActionBar.js +300 -0
  23. package/dist/app/DocumentContextMenu.d.ts +29 -0
  24. package/dist/app/DocumentContextMenu.js +122 -0
  25. package/dist/app/DocumentPane.d.ts +52 -0
  26. package/dist/app/DocumentPane.js +30 -0
  27. package/dist/app/DocumentRouterTable.d.ts +58 -0
  28. package/dist/app/DocumentRouterTable.js +143 -0
  29. package/dist/app/ErrorBoundary.d.ts +12 -0
  30. package/dist/app/ErrorBoundary.js +16 -0
  31. package/dist/app/FindBar.d.ts +12 -0
  32. package/dist/app/FindBar.js +199 -0
  33. package/dist/app/LiveTitle.d.ts +14 -0
  34. package/dist/app/LiveTitle.js +14 -0
  35. package/dist/app/OpeningProgress.d.ts +13 -0
  36. package/dist/app/OpeningProgress.js +21 -0
  37. package/dist/app/PrintPreviewWindow.d.ts +2 -0
  38. package/dist/app/PrintPreviewWindow.js +57 -0
  39. package/dist/app/ShortcutHelp.d.ts +3 -0
  40. package/dist/app/ShortcutHelp.js +99 -0
  41. package/dist/app/Sidebar.d.ts +36 -0
  42. package/dist/app/Sidebar.js +121 -0
  43. package/dist/app/ToastViewport.d.ts +1 -0
  44. package/dist/app/ToastViewport.js +31 -0
  45. package/dist/app/Toolbar.d.ts +26 -0
  46. package/dist/app/Toolbar.js +63 -0
  47. package/dist/app/activeFormatSavers.d.ts +7 -0
  48. package/dist/app/activeFormatSavers.js +4 -0
  49. package/dist/app/clipboardPaths.d.ts +1 -0
  50. package/dist/app/clipboardPaths.js +31 -0
  51. package/dist/app/documentDrafts.d.ts +17 -0
  52. package/dist/app/documentDrafts.js +104 -0
  53. package/dist/app/draftResolution.d.ts +5 -0
  54. package/dist/app/draftResolution.js +25 -0
  55. package/dist/app/markdownPaletteActions.d.ts +8 -0
  56. package/dist/app/markdownPaletteActions.js +107 -0
  57. package/dist/app/resourceCensusDev.d.ts +41 -0
  58. package/dist/app/resourceCensusDev.js +518 -0
  59. package/dist/app/setupRecovery.d.ts +34 -0
  60. package/dist/app/setupRecovery.js +70 -0
  61. package/dist/app/shell/DocStatsPill.d.ts +18 -0
  62. package/dist/app/shell/DocStatsPill.js +32 -0
  63. package/dist/app/shell/DocumentTools.d.ts +9 -0
  64. package/dist/app/shell/DocumentTools.js +73 -0
  65. package/dist/app/shell/InfoInspector.d.ts +9 -0
  66. package/dist/app/shell/InfoInspector.js +67 -0
  67. package/dist/app/shell/StartPage.d.ts +9 -0
  68. package/dist/app/shell/StartPage.js +49 -0
  69. package/dist/app/shell/readEdit.d.ts +6 -0
  70. package/dist/app/shell/readEdit.js +6 -0
  71. package/dist/app/sidebar/SidebarDocumentMenu.d.ts +20 -0
  72. package/dist/app/sidebar/SidebarDocumentMenu.js +56 -0
  73. package/dist/app/sidebar/SidebarExpandedPanel.d.ts +9 -0
  74. package/dist/app/sidebar/SidebarExpandedPanel.js +78 -0
  75. package/dist/app/sidebar/SidebarIcons.d.ts +3 -0
  76. package/dist/app/sidebar/SidebarIcons.js +18 -0
  77. package/dist/app/sidebar/SidebarMenus.d.ts +19 -0
  78. package/dist/app/sidebar/SidebarMenus.js +64 -0
  79. package/dist/app/sidebar/SidebarPathUtils.d.ts +10 -0
  80. package/dist/app/sidebar/SidebarPathUtils.js +55 -0
  81. package/dist/app/sidebar/SidebarPrimitives.d.ts +12 -0
  82. package/dist/app/sidebar/SidebarPrimitives.js +45 -0
  83. package/dist/app/sidebar/SidebarRail.d.ts +5 -0
  84. package/dist/app/sidebar/SidebarRail.js +37 -0
  85. package/dist/app/sidebar/explorer/ExplorerRowMenu.d.ts +21 -0
  86. package/dist/app/sidebar/explorer/ExplorerRowMenu.js +37 -0
  87. package/dist/app/sidebar/explorer/ExplorerSections.d.ts +16 -0
  88. package/dist/app/sidebar/explorer/ExplorerSections.js +259 -0
  89. package/dist/app/sidebar/explorer/ExplorerTree.d.ts +46 -0
  90. package/dist/app/sidebar/explorer/ExplorerTree.js +387 -0
  91. package/dist/app/sidebar/explorer/explorerState.d.ts +37 -0
  92. package/dist/app/sidebar/explorer/explorerState.js +135 -0
  93. package/dist/app/tabMountPolicy.d.ts +45 -0
  94. package/dist/app/tabMountPolicy.js +104 -0
  95. package/dist/app/tabWarmOrder.d.ts +7 -0
  96. package/dist/app/tabWarmOrder.js +48 -0
  97. package/dist/app/tabs/TabFuseCurves.d.ts +3 -0
  98. package/dist/app/tabs/TabFuseCurves.js +15 -0
  99. package/dist/app/tabs/TabOverview.d.ts +24 -0
  100. package/dist/app/tabs/TabOverview.js +121 -0
  101. package/dist/app/tabs/TabStrip.d.ts +42 -0
  102. package/dist/app/tabs/TabStrip.js +380 -0
  103. package/dist/app/tabs/tabIds.d.ts +5 -0
  104. package/dist/app/tabs/tabIds.js +7 -0
  105. package/dist/app/tabs/useTabDirty.d.ts +3 -0
  106. package/dist/app/tabs/useTabDirty.js +11 -0
  107. package/dist/app/useAppChromeState.d.ts +21 -0
  108. package/dist/app/useAppChromeState.js +48 -0
  109. package/dist/app/useAppCommands.d.ts +66 -0
  110. package/dist/app/useAppCommands.js +71 -0
  111. package/dist/app/useAppDocumentCore.d.ts +210 -0
  112. package/dist/app/useAppDocumentCore.js +40 -0
  113. package/dist/app/useAppEffects.d.ts +18 -0
  114. package/dist/app/useAppEffects.js +52 -0
  115. package/dist/app/useAppPaneSearch.d.ts +37 -0
  116. package/dist/app/useAppPaneSearch.js +74 -0
  117. package/dist/app/useAppShellSetup.d.ts +40 -0
  118. package/dist/app/useAppShellSetup.js +52 -0
  119. package/dist/app/useAppSlots.d.ts +28 -0
  120. package/dist/app/useAppSlots.js +40 -0
  121. package/dist/app/useAppTabChrome.d.ts +51 -0
  122. package/dist/app/useAppTabChrome.js +66 -0
  123. package/dist/app/useAutoSave.d.ts +34 -0
  124. package/dist/app/useAutoSave.js +116 -0
  125. package/dist/app/useCloseAll.d.ts +52 -0
  126. package/dist/app/useCloseAll.js +295 -0
  127. package/dist/app/useClosedTabEviction.d.ts +10 -0
  128. package/dist/app/useClosedTabEviction.js +38 -0
  129. package/dist/app/useCommandPalette.d.ts +44 -0
  130. package/dist/app/useCommandPalette.js +254 -0
  131. package/dist/app/useCrossDocSearch.d.ts +7 -0
  132. package/dist/app/useCrossDocSearch.js +94 -0
  133. package/dist/app/useDistractionFree.d.ts +21 -0
  134. package/dist/app/useDistractionFree.js +73 -0
  135. package/dist/app/useDocumentCreation.d.ts +18 -0
  136. package/dist/app/useDocumentCreation.js +63 -0
  137. package/dist/app/useDocumentDirty.d.ts +31 -0
  138. package/dist/app/useDocumentDirty.js +46 -0
  139. package/dist/app/useDocumentLoader.d.ts +55 -0
  140. package/dist/app/useDocumentLoader.js +267 -0
  141. package/dist/app/useDocumentOutputActions.d.ts +6 -0
  142. package/dist/app/useDocumentOutputActions.js +45 -0
  143. package/dist/app/useDocumentRuntimeEffects.d.ts +36 -0
  144. package/dist/app/useDocumentRuntimeEffects.js +458 -0
  145. package/dist/app/useDocumentSaver.d.ts +58 -0
  146. package/dist/app/useDocumentSaver.js +511 -0
  147. package/dist/app/useDocumentTabs.d.ts +41 -0
  148. package/dist/app/useDocumentTabs.js +207 -0
  149. package/dist/app/useDocumentWatcher.d.ts +83 -0
  150. package/dist/app/useDocumentWatcher.js +393 -0
  151. package/dist/app/useDocumentZoom.d.ts +24 -0
  152. package/dist/app/useDocumentZoom.js +104 -0
  153. package/dist/app/useDocuments.d.ts +169 -0
  154. package/dist/app/useDocuments.js +455 -0
  155. package/dist/app/useDraftConfirmGate.d.ts +27 -0
  156. package/dist/app/useDraftConfirmGate.js +47 -0
  157. package/dist/app/useFileDragOverlay.d.ts +12 -0
  158. package/dist/app/useFileDragOverlay.js +49 -0
  159. package/dist/app/useFormatApis.d.ts +13 -0
  160. package/dist/app/useFormatApis.js +62 -0
  161. package/dist/app/useFormatDirtyState.d.ts +29 -0
  162. package/dist/app/useFormatDirtyState.js +81 -0
  163. package/dist/app/useGlobalShortcuts.d.ts +47 -0
  164. package/dist/app/useGlobalShortcuts.js +359 -0
  165. package/dist/app/useHtmlSession.d.ts +68 -0
  166. package/dist/app/useHtmlSession.js +463 -0
  167. package/dist/app/useHtmlSessionProps.d.ts +33 -0
  168. package/dist/app/useHtmlSessionProps.js +57 -0
  169. package/dist/app/useLibrary.d.ts +21 -0
  170. package/dist/app/useLibrary.js +81 -0
  171. package/dist/app/useOpenFromClipboard.d.ts +7 -0
  172. package/dist/app/useOpenFromClipboard.js +44 -0
  173. package/dist/app/usePaneLiveness.d.ts +29 -0
  174. package/dist/app/usePaneLiveness.js +199 -0
  175. package/dist/app/usePendingSavePaths.d.ts +19 -0
  176. package/dist/app/usePendingSavePaths.js +67 -0
  177. package/dist/app/useReadyShow.d.ts +12 -0
  178. package/dist/app/useReadyShow.js +142 -0
  179. package/dist/app/useSearchController.d.ts +22 -0
  180. package/dist/app/useSearchController.js +114 -0
  181. package/dist/app/useSetupRecovery.d.ts +41 -0
  182. package/dist/app/useSetupRecovery.js +153 -0
  183. package/dist/app/useTabChrome.d.ts +40 -0
  184. package/dist/app/useTabChrome.js +115 -0
  185. package/dist/app/useViewState.d.ts +27 -0
  186. package/dist/app/useViewState.js +160 -0
  187. package/dist/appName.d.ts +2 -0
  188. package/dist/appName.js +8 -0
  189. package/dist/documents/DocumentRouter.d.ts +102 -0
  190. package/dist/documents/DocumentRouter.js +153 -0
  191. package/dist/documents/FileTypeIcon.d.ts +6 -0
  192. package/dist/documents/FileTypeIcon.js +93 -0
  193. package/dist/documents/ImageDocument.d.ts +14 -0
  194. package/dist/documents/ImageDocument.js +61 -0
  195. package/dist/documents/capabilities.d.ts +17 -0
  196. package/dist/documents/capabilities.js +18 -0
  197. package/dist/documents/html/HtmlDocument.d.ts +15 -0
  198. package/dist/documents/html/HtmlDocument.js +584 -0
  199. package/dist/documents/html/HtmlDocumentLayout.d.ts +87 -0
  200. package/dist/documents/html/HtmlDocumentLayout.js +25 -0
  201. package/dist/documents/html/HtmlDocumentProps.d.ts +60 -0
  202. package/dist/documents/html/HtmlDocumentProps.js +1 -0
  203. package/dist/documents/html/HtmlDocumentSource.d.ts +34 -0
  204. package/dist/documents/html/HtmlDocumentSource.js +28 -0
  205. package/dist/documents/markdown/MarkdownSplitPane.d.ts +115 -0
  206. package/dist/documents/markdown/MarkdownSplitPane.js +352 -0
  207. package/dist/documents/mdx/MdxSplitPane.d.ts +32 -0
  208. package/dist/documents/mdx/MdxSplitPane.js +60 -0
  209. package/dist/documents/txt/LinkDialog.d.ts +8 -0
  210. package/dist/documents/txt/LinkDialog.js +34 -0
  211. package/dist/documents/txt/MarkdownSourceToolbar.d.ts +8 -0
  212. package/dist/documents/txt/MarkdownSourceToolbar.js +25 -0
  213. package/dist/documents/txt/SourceEditorToolbar.d.ts +12 -0
  214. package/dist/documents/txt/SourceEditorToolbar.js +4 -0
  215. package/dist/documents/txt/TxtEditor.d.ts +39 -0
  216. package/dist/documents/txt/TxtEditor.js +186 -0
  217. package/dist/documents/txt/sourceEditorTypes.d.ts +49 -0
  218. package/dist/documents/txt/sourceEditorTypes.js +1 -0
  219. package/dist/documents/txt/sourceExtensions.d.ts +38 -0
  220. package/dist/documents/txt/sourceExtensions.js +444 -0
  221. package/dist/documents/txt/sourceFormatting.d.ts +18 -0
  222. package/dist/documents/txt/sourceFormatting.js +183 -0
  223. package/dist/documents/txt/sourceTheme.d.ts +5 -0
  224. package/dist/documents/txt/sourceTheme.js +220 -0
  225. package/dist/documents/txt/useCodeMirrorSourceEditor.d.ts +69 -0
  226. package/dist/documents/txt/useCodeMirrorSourceEditor.js +546 -0
  227. package/dist/documents/txt/useSourceSearch.d.ts +39 -0
  228. package/dist/documents/txt/useSourceSearch.js +122 -0
  229. package/dist/documents/txt/useTextEditorCommands.d.ts +26 -0
  230. package/dist/documents/txt/useTextEditorCommands.js +151 -0
  231. package/dist/documents/web/LivePreviewPane.d.ts +11 -0
  232. package/dist/documents/web/LivePreviewPane.js +58 -0
  233. package/dist/env.d.ts +66 -0
  234. package/dist/index.d.ts +121 -0
  235. package/dist/index.js +123 -0
  236. package/dist/settings/AppearanceMenu.d.ts +9 -0
  237. package/dist/settings/AppearanceMenu.js +54 -0
  238. package/dist/settings/SettingsPanel.d.ts +7 -0
  239. package/dist/settings/SettingsPanel.js +104 -0
  240. package/dist/settings/publishedSections.d.ts +22 -0
  241. package/dist/settings/publishedSections.js +79 -0
  242. package/dist/settings/sections/AboutSection.d.ts +1 -0
  243. package/dist/settings/sections/AboutSection.js +13 -0
  244. package/dist/settings/sections/DiagnosticsSection.d.ts +1 -0
  245. package/dist/settings/sections/DiagnosticsSection.js +42 -0
  246. package/dist/settings/sections/PrivacySection.d.ts +3 -0
  247. package/dist/settings/sections/PrivacySection.js +51 -0
  248. package/dist/settings/sections/UpdateLicenseBlock.d.ts +10 -0
  249. package/dist/settings/sections/UpdateLicenseBlock.js +158 -0
  250. package/dist/state/explorer.d.ts +32 -0
  251. package/dist/state/explorer.js +111 -0
  252. package/dist/state/legal.d.ts +51 -0
  253. package/dist/state/legal.js +130 -0
  254. package/dist/state/library.d.ts +33 -0
  255. package/dist/state/library.js +110 -0
  256. package/dist/state/updateLicense.d.ts +31 -0
  257. package/dist/state/updateLicense.js +340 -0
  258. package/dist/styles/explorer.css +219 -0
  259. package/dist/styles/index.css +1477 -0
  260. package/dist/styles/tabs.css +467 -0
  261. package/dist/styles.css +6 -0
  262. package/package.json +88 -3
@@ -0,0 +1,254 @@
1
+ import { createElement, useMemo } from "react";
2
+ import { File } from "@phosphor-icons/react/dist/icons/File";
3
+ import { ClockCounterClockwise } from "@phosphor-icons/react/dist/icons/ClockCounterClockwise";
4
+ import { FilePlus } from "@phosphor-icons/react/dist/icons/FilePlus";
5
+ import { FolderOpen } from "@phosphor-icons/react/dist/icons/FolderOpen";
6
+ import { GlobeSimple } from "@phosphor-icons/react/dist/icons/GlobeSimple";
7
+ import { ArrowClockwise } from "@phosphor-icons/react/dist/icons/ArrowClockwise";
8
+ import { Gear } from "@phosphor-icons/react/dist/icons/Gear";
9
+ import { Keyboard } from "@phosphor-icons/react/dist/icons/Keyboard";
10
+ import { CircleHalf } from "@phosphor-icons/react/dist/icons/CircleHalf";
11
+ import { TextAlignLeft } from "@phosphor-icons/react/dist/icons/TextAlignLeft";
12
+ import { Palette } from "@phosphor-icons/react/dist/icons/Palette";
13
+ import { Copy } from "@phosphor-icons/react/dist/icons/Copy";
14
+ import { ClipboardText } from "@phosphor-icons/react/dist/icons/ClipboardText";
15
+ import { Export } from "@phosphor-icons/react/dist/icons/Export";
16
+ import { FloppyDisk } from "@phosphor-icons/react/dist/icons/FloppyDisk";
17
+ import { Printer } from "@phosphor-icons/react/dist/icons/Printer";
18
+ import { Eye } from "@phosphor-icons/react/dist/icons/Eye";
19
+ import { Code } from "@phosphor-icons/react/dist/icons/Code";
20
+ import { capabilitiesFor } from "../documents/capabilities.js";
21
+ import { displayTitle } from "@rightkit/document-core/documents/types";
22
+ import { BASE_THEME_IDS, themeById } from "@rightkit/document-core/settings/themes";
23
+ import { shortcutLabel } from "@rightkit/document-core/platform";
24
+ // Decorative leading glyph for a palette row. Kept tiny + weight-regular to match the compact list.
25
+ // biome-ignore lint/suspicious/noExplicitAny: Phosphor's icon props are structurally identical here.
26
+ const ic = (I) => createElement(I, { size: 16, weight: "regular" });
27
+ /**
28
+ * Command-palette entries: open tabs + recents + context-aware commands. Routes through the
29
+ * existing document handlers — the palette is just a uniform, cross-format way to reach them.
30
+ * Format-specific commands (save/print/view) gate on `capabilitiesFor`, not ad-hoc format checks.
31
+ */
32
+ export function useCommandPalette(d) {
33
+ const { openDocs, recents, active, activeEditable, titleFor, activate, openRecent, newDocument, onOpenDialog, onOpenUrl, onSave, onSaveAs, onPrint, docxMenu, onChangeView, settings, update, openSettings, reopenClosed, showHelp, copyContents, exportMarkdown, copyRendered, copyAsMarkdown, duplicate, } = d;
34
+ return useMemo(() => {
35
+ const tabItems = openDocs.map((doc) => ({
36
+ id: `tab:${doc.path}`,
37
+ label: titleFor(doc),
38
+ hint: "open tab",
39
+ icon: ic(File),
40
+ run: () => void activate(doc.path),
41
+ }));
42
+ const recentItems = recents.map((r) => ({
43
+ id: `recent:${r.token}`,
44
+ label: displayTitle(r.displayName),
45
+ hint: "recent",
46
+ icon: ic(ClockCounterClockwise),
47
+ run: () => void openRecent(r),
48
+ }));
49
+ const cmds = [
50
+ {
51
+ id: "cmd:new",
52
+ label: "New text document",
53
+ hint: shortcutLabel("mod+n"),
54
+ icon: ic(FilePlus),
55
+ run: newDocument,
56
+ },
57
+ {
58
+ id: "cmd:open",
59
+ label: "Open file…",
60
+ hint: shortcutLabel("mod+o"),
61
+ icon: ic(FolderOpen),
62
+ run: () => void onOpenDialog(),
63
+ },
64
+ {
65
+ id: "cmd:open-url",
66
+ label: "Open URL…",
67
+ hint: "web",
68
+ icon: ic(GlobeSimple),
69
+ run: onOpenUrl,
70
+ },
71
+ {
72
+ id: "cmd:reopen",
73
+ label: "Reopen closed tab",
74
+ hint: shortcutLabel("mod+shift+t"),
75
+ icon: ic(ArrowClockwise),
76
+ run: reopenClosed,
77
+ },
78
+ { id: "cmd:settings", label: "Settings", icon: ic(Gear), run: openSettings },
79
+ {
80
+ id: "cmd:shortcuts",
81
+ label: "Keyboard shortcuts",
82
+ hint: "?",
83
+ icon: ic(Keyboard),
84
+ run: showHelp,
85
+ },
86
+ {
87
+ id: "cmd:contrast",
88
+ label: `Contrast: ${settings.contrast === "high" ? "Normal" : "High"}`,
89
+ hint: "typography",
90
+ icon: ic(CircleHalf),
91
+ run: () => update({ contrast: settings.contrast === "high" ? "normal" : "high" }),
92
+ },
93
+ {
94
+ id: "cmd:wrap",
95
+ label: `Word wrap: ${settings.wordWrap ? "Off" : "On"}`,
96
+ hint: "editor",
97
+ icon: ic(TextAlignLeft),
98
+ run: () => update({ wordWrap: !settings.wordWrap }),
99
+ },
100
+ ...BASE_THEME_IDS.map((id) => {
101
+ const theme = themeById(id);
102
+ return {
103
+ id: `cmd:theme-${id}`,
104
+ label: `Theme: ${theme.name}`,
105
+ hint: "theme",
106
+ icon: ic(Palette),
107
+ run: () => update({ themeId: id }),
108
+ };
109
+ }),
110
+ ];
111
+ if (active) {
112
+ const c = capabilitiesFor(active.format);
113
+ if (copyContents)
114
+ cmds.push({
115
+ id: "cmd:copy-contents",
116
+ label: "Copy document contents",
117
+ hint: "clipboard",
118
+ icon: ic(Copy),
119
+ run: copyContents,
120
+ });
121
+ if (copyRendered)
122
+ cmds.push({
123
+ id: "cmd:copy-rendered",
124
+ label: "Copy rendered Markdown (for sharing)",
125
+ hint: "clipboard",
126
+ icon: ic(ClipboardText),
127
+ run: copyRendered,
128
+ });
129
+ if (copyAsMarkdown)
130
+ cmds.push({
131
+ id: "cmd:copy-as-markdown",
132
+ label: "Copy as Markdown",
133
+ hint: "clipboard",
134
+ icon: ic(ClipboardText),
135
+ run: copyAsMarkdown,
136
+ });
137
+ if (duplicate)
138
+ cmds.push({
139
+ id: "cmd:duplicate",
140
+ label: "Duplicate as draft",
141
+ hint: "new copy",
142
+ icon: ic(Copy),
143
+ run: duplicate,
144
+ });
145
+ if (exportMarkdown) {
146
+ cmds.push({
147
+ id: "cmd:export-html",
148
+ label: "Export as HTML…",
149
+ hint: "markdown",
150
+ icon: ic(Export),
151
+ run: () => exportMarkdown("html"),
152
+ });
153
+ cmds.push({
154
+ id: "cmd:export-txt",
155
+ label: "Export as plain text…",
156
+ hint: "markdown",
157
+ icon: ic(Export),
158
+ run: () => exportMarkdown("txt"),
159
+ });
160
+ }
161
+ if (activeEditable) {
162
+ cmds.push({
163
+ id: "cmd:save",
164
+ label: "Save",
165
+ hint: shortcutLabel("mod+s"),
166
+ icon: ic(FloppyDisk),
167
+ run: () => (active.format === "docx" ? void docxMenu?.save() : void onSave(active)),
168
+ });
169
+ }
170
+ if (c.canSaveAs) {
171
+ cmds.push({
172
+ id: "cmd:saveas",
173
+ label: "Save As…",
174
+ hint: shortcutLabel("mod+shift+s"),
175
+ icon: ic(FloppyDisk),
176
+ run: () => void onSaveAs(active),
177
+ });
178
+ }
179
+ if (c.canPrintInApp)
180
+ cmds.push({
181
+ id: "cmd:print",
182
+ label: "Print",
183
+ hint: shortcutLabel("mod+p"),
184
+ icon: ic(Printer),
185
+ run: () => onPrint(active),
186
+ });
187
+ else if (active.format === "docx")
188
+ cmds.push({
189
+ id: "cmd:print",
190
+ label: "Print",
191
+ hint: shortcutLabel("mod+p"),
192
+ icon: ic(Printer),
193
+ run: () => void docxMenu?.print(),
194
+ });
195
+ if (c.canSwitchView) {
196
+ if (active.format === "html") {
197
+ cmds.push({
198
+ id: "cmd:view-interactive",
199
+ label: "View: Interactive",
200
+ icon: ic(Eye),
201
+ run: () => void onChangeView("interactive"),
202
+ });
203
+ cmds.push({
204
+ id: "cmd:view-safe",
205
+ label: "View: Safe",
206
+ icon: ic(Eye),
207
+ run: () => void onChangeView("preview"),
208
+ });
209
+ }
210
+ else {
211
+ cmds.push({
212
+ id: "cmd:view-preview",
213
+ label: "View: Preview",
214
+ icon: ic(Eye),
215
+ run: () => void onChangeView("preview"),
216
+ });
217
+ cmds.push({
218
+ id: "cmd:view-source",
219
+ label: "View: Source",
220
+ icon: ic(Code),
221
+ run: () => void onChangeView("source"),
222
+ });
223
+ }
224
+ }
225
+ }
226
+ return [...tabItems, ...recentItems, ...cmds];
227
+ }, [
228
+ openDocs,
229
+ recents,
230
+ active,
231
+ activeEditable,
232
+ titleFor,
233
+ activate,
234
+ openRecent,
235
+ newDocument,
236
+ onOpenDialog,
237
+ onOpenUrl,
238
+ onSave,
239
+ onSaveAs,
240
+ onPrint,
241
+ docxMenu,
242
+ onChangeView,
243
+ settings,
244
+ update,
245
+ openSettings,
246
+ reopenClosed,
247
+ showHelp,
248
+ copyContents,
249
+ exportMarkdown,
250
+ duplicate,
251
+ copyRendered,
252
+ copyAsMarkdown,
253
+ ]);
254
+ }
@@ -0,0 +1,7 @@
1
+ import type { LoadedDocument, SearchProvider } from "@rightkit/document-core/documents/types";
2
+ /**
3
+ * Build a synthetic SearchProvider that aggregates matches across multiple warm tabs.
4
+ * The provider fans out find() to all registered providers, builds a flat match list in
5
+ * tab order, and navigates between tabs on next/prev.
6
+ */
7
+ export declare function buildCrossDocProvider(providers: Map<string, SearchProvider>, openDocs: LoadedDocument[], activate: (path: string) => Promise<void>): SearchProvider;
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Build a synthetic SearchProvider that aggregates matches across multiple warm tabs.
3
+ * The provider fans out find() to all registered providers, builds a flat match list in
4
+ * tab order, and navigates between tabs on next/prev.
5
+ */
6
+ export function buildCrossDocProvider(providers, openDocs, activate) {
7
+ let matches = [];
8
+ let globalActive = -1;
9
+ let lastQuery = "";
10
+ let lastOptions = { matchCase: false, wholeWord: false };
11
+ const orderedDocs = openDocs.filter((d) => providers.has(d.path));
12
+ const find = async (query, options) => {
13
+ matches = [];
14
+ globalActive = -1;
15
+ lastQuery = query;
16
+ lastOptions = options;
17
+ if (!query)
18
+ return { count: 0, activeIndex: -1 };
19
+ // Each provider.find() is an independent per-doc search (some cross a render/IPC boundary,
20
+ // e.g. docx) — fan them out concurrently, then stitch the results back together in the
21
+ // existing orderedDocs order so matches/globalIndex stay deterministic regardless of which
22
+ // provider actually finishes first.
23
+ const perDocResults = await Promise.all(orderedDocs.map(async (doc) => {
24
+ const provider = providers.get(doc.path);
25
+ if (!provider)
26
+ return null;
27
+ try {
28
+ return { doc, res: await provider.find(query, options) };
29
+ }
30
+ catch {
31
+ // Skip providers that fail (e.g. cold docx tabs).
32
+ return null;
33
+ }
34
+ }));
35
+ for (const entry of perDocResults) {
36
+ if (!entry)
37
+ continue;
38
+ for (let i = 0; i < entry.res.count; i++) {
39
+ matches.push({
40
+ path: entry.doc.path,
41
+ displayName: entry.doc.displayName,
42
+ matchIndexWithinDoc: i,
43
+ globalIndex: matches.length,
44
+ });
45
+ }
46
+ }
47
+ globalActive = matches.length > 0 ? 0 : -1;
48
+ if (globalActive >= 0) {
49
+ await navigateTo(globalActive);
50
+ }
51
+ return { count: matches.length, activeIndex: globalActive };
52
+ };
53
+ const navigateTo = async (idx) => {
54
+ if (idx < 0 || idx >= matches.length)
55
+ return;
56
+ const m = matches[idx];
57
+ await activate(m.path);
58
+ const provider = providers.get(m.path);
59
+ if (!provider)
60
+ return;
61
+ if (provider.seek) {
62
+ provider.seek(m.matchIndexWithinDoc);
63
+ return;
64
+ }
65
+ await provider.find(lastQuery, lastOptions);
66
+ for (let i = 0; i < m.matchIndexWithinDoc; i++) {
67
+ await provider.next();
68
+ }
69
+ };
70
+ const step = async (dir) => {
71
+ if (matches.length === 0)
72
+ return { count: 0, activeIndex: -1 };
73
+ globalActive = (((globalActive + dir) % matches.length) + matches.length) % matches.length;
74
+ await navigateTo(globalActive);
75
+ return { count: matches.length, activeIndex: globalActive };
76
+ };
77
+ return {
78
+ kind: "source",
79
+ canReplace: false,
80
+ supportsMatchCase: true,
81
+ supportsWholeWord: true,
82
+ find,
83
+ next: () => step(1),
84
+ prev: () => step(-1),
85
+ close: () => {
86
+ matches = [];
87
+ globalActive = -1;
88
+ // Close all sub-providers' find state.
89
+ for (const doc of orderedDocs) {
90
+ providers.get(doc.path)?.close();
91
+ }
92
+ },
93
+ };
94
+ }
@@ -0,0 +1,21 @@
1
+ import type { LoadedDocument } from "@rightkit/document-core/documents/types";
2
+ import type { createBlockDraftRegistry } from "@rightkit/document-core/app/blockDrafts";
3
+ type Registry = ReturnType<typeof createBlockDraftRegistry>;
4
+ /** Distraction-free reading mode: the toggle (guarded by unresolved block drafts), the Esc-exit
5
+ * effect, and the confirm-dialog handlers. Extracted verbatim from App.tsx. */
6
+ export declare function useDistractionFree({ active, blockDrafts, overlayOpen, }: {
7
+ active: LoadedDocument | null;
8
+ blockDrafts: Registry;
9
+ /** True while settings / palette / help / open-url own Esc. */
10
+ overlayOpen: boolean;
11
+ }): {
12
+ distractionFree: boolean;
13
+ toggleDistractionFree: () => void;
14
+ fullscreenConfirm: {
15
+ onDone: () => Promise<void>;
16
+ onDiscard: () => Promise<void>;
17
+ onStay: () => void;
18
+ error: string | null;
19
+ } | null;
20
+ };
21
+ export {};
@@ -0,0 +1,73 @@
1
+ import { useRef, useState } from "react";
2
+ import { toast, useDismiss } from "@rightkit/platform-ui/headless";
3
+ import { shortcutLabel } from "@rightkit/document-core/platform";
4
+ import { resolveDocumentDrafts } from "./draftResolution.js";
5
+ /** Distraction-free reading mode: the toggle (guarded by unresolved block drafts), the Esc-exit
6
+ * effect, and the confirm-dialog handlers. Extracted verbatim from App.tsx. */
7
+ export function useDistractionFree({ active, blockDrafts, overlayOpen, }) {
8
+ const [distractionFree, setDistractionFree] = useState(false);
9
+ const [pendingFullscreenDraft, setPendingFullscreenDraft] = useState(null);
10
+ const flipDistractionFree = () => setDistractionFree((on) => {
11
+ if (!on)
12
+ toast(`Distraction-free — press ${shortcutLabel("esc")} or ${shortcutLabel("mod+shift+f")} to exit`, "info");
13
+ return !on;
14
+ });
15
+ const toggleDistractionFree = () => {
16
+ const path = active?.path;
17
+ if (path && blockDrafts.snapshotModified(path).length > 0) {
18
+ setPendingFullscreenDraft({ drafts: blockDrafts.snapshotModified(path) });
19
+ return;
20
+ }
21
+ // Clean draft closes silently before entering fullscreen
22
+ if (path) {
23
+ const clean = blockDrafts.snapshotAll(path);
24
+ for (const d of clean)
25
+ blockDrafts.discard(d.identity);
26
+ }
27
+ flipDistractionFree();
28
+ };
29
+ // Esc leaves distraction-free reading (when nothing else owns Esc).
30
+ // Bubble phase on the window, like the handler it replaces, so an overlay or modal that takes
31
+ // Escape in the capture phase keeps its own Escape.
32
+ const windowTarget = useRef(typeof window === "undefined" ? null : window);
33
+ useDismiss(() => setDistractionFree(false), {
34
+ enabled: distractionFree && !overlayOpen,
35
+ escapeTarget: windowTarget,
36
+ outside: false,
37
+ preventDefault: true,
38
+ stopPropagation: false,
39
+ imeGuard: false,
40
+ });
41
+ const onDone = async () => {
42
+ const path = active?.path;
43
+ if (!path) {
44
+ setPendingFullscreenDraft(null);
45
+ return;
46
+ }
47
+ const outcome = await resolveDocumentDrafts(blockDrafts, path, "view-change", "done");
48
+ if (outcome !== "resolved") {
49
+ setPendingFullscreenDraft({ drafts: blockDrafts.snapshotModified(path) });
50
+ return;
51
+ }
52
+ setPendingFullscreenDraft(null);
53
+ flipDistractionFree();
54
+ };
55
+ const onDiscard = async () => {
56
+ const path = active?.path;
57
+ if (path)
58
+ await resolveDocumentDrafts(blockDrafts, path, "view-change", "discard");
59
+ setPendingFullscreenDraft(null);
60
+ flipDistractionFree();
61
+ };
62
+ const confirm = pendingFullscreenDraft
63
+ ? {
64
+ onDone,
65
+ onDiscard,
66
+ onStay: () => setPendingFullscreenDraft(null),
67
+ error: pendingFullscreenDraft.drafts.find((d) => d.error)?.error ??
68
+ pendingFullscreenDraft.drafts.find((d) => d.reason)?.reason ??
69
+ null,
70
+ }
71
+ : null;
72
+ return { distractionFree, toggleDistractionFree, fullscreenConfirm: confirm };
73
+ }
@@ -0,0 +1,18 @@
1
+ import { type Dispatch, type MutableRefObject, type SetStateAction } from "react";
2
+ import { type LoadedDocument, type ViewMode } from "@rightkit/document-core/documents/types";
3
+ import type { DocumentTabs } from "./useDocumentTabs.js";
4
+ /** New-untitled / duplicate-as-draft creation and the txt keystroke path (edits + draft persistence). */
5
+ export declare function useDocumentCreation(deps: {
6
+ untitledSeq: MutableRefObject<number>;
7
+ withTabKey: <T extends LoadedDocument>(doc: T, existingKey?: string) => T;
8
+ setOpenDocs: DocumentTabs["setOpenDocs"];
9
+ setActivePath: DocumentTabs["setActivePath"];
10
+ setViews: Dispatch<SetStateAction<Record<string, ViewMode>>>;
11
+ writeEdits: DocumentTabs["writeEdits"];
12
+ writeEditsLive: DocumentTabs["writeEditsLive"];
13
+ queueAutoSave: (path: string) => void;
14
+ }): {
15
+ newDocument: (format?: "txt" | "md" | "docx") => void;
16
+ duplicateAsDraft: (text: string, toastMsg?: string) => void;
17
+ onTxtChange: (path: string, content: string, text: string) => void;
18
+ };
@@ -0,0 +1,63 @@
1
+ import { useCallback } from "react";
2
+ import { docTitle, isUntitled } from "@rightkit/document-core/documents/types";
3
+ import { bufferToBase64, createBlankDocxBuffer } from "@rightkit/docx-editor/documents/docx/blankDocx";
4
+ import { clearDraft, clearFileDraft, writeDraftDebounced, writeFileDraftDebounced, } from "./documentDrafts.js";
5
+ import { toast } from "@rightkit/platform-ui/headless";
6
+ /** New-untitled / duplicate-as-draft creation and the txt keystroke path (edits + draft persistence). */
7
+ export function useDocumentCreation(deps) {
8
+ const { untitledSeq, withTabKey, setOpenDocs, setActivePath, setViews, writeEdits, writeEditsLive, queueAutoSave, } = deps;
9
+ const newDocument = useCallback((format = "txt") => {
10
+ const path = `untitled:${untitledSeq.current++}`;
11
+ const content = format === "docx" ? bufferToBase64(createBlankDocxBuffer()) : "";
12
+ const doc = withTabKey({
13
+ path,
14
+ displayName: docTitle(path),
15
+ format,
16
+ content,
17
+ });
18
+ setOpenDocs((prev) => [...prev, doc]);
19
+ if (format !== "docx")
20
+ writeEdits((e) => ({ ...e, [path]: "" }));
21
+ setViews((v) => ({ ...v, [path]: "preview" }));
22
+ setActivePath(path);
23
+ }, [untitledSeq, writeEdits, setOpenDocs, setViews, setActivePath, withTabKey]);
24
+ // Duplicate a document's text into a new, never-saved draft (Word-style "make a copy") — leaves the
25
+ // original untouched on disk; the copy is a scratch buffer the user can edit and Save As later.
26
+ const duplicateAsDraft = useCallback((text, toastMsg = "Duplicated as a draft") => {
27
+ const path = `untitled:${untitledSeq.current++}`;
28
+ const doc = withTabKey({
29
+ path,
30
+ displayName: docTitle(path),
31
+ format: "txt",
32
+ content: "",
33
+ });
34
+ setOpenDocs((prev) => [...prev, doc]);
35
+ writeEdits((e) => ({ ...e, [path]: text }));
36
+ setViews((v) => ({ ...v, [path]: "preview" }));
37
+ setActivePath(path);
38
+ toast(toastMsg, "success");
39
+ }, [untitledSeq, writeEdits, setOpenDocs, setViews, setActivePath, withTabKey]);
40
+ const onTxtChange = useCallback((path, content, text) => {
41
+ // Keystroke path: writeEditsLive mutates editsRef + notifies only this path's live subscribers
42
+ // (the bottom-bar word-count/dirty and this tab's title) — App does NOT re-render. The save/dirty
43
+ // path reads editsRef, so it always sees the latest text.
44
+ writeEditsLive(path, text);
45
+ queueAutoSave(path);
46
+ // Untitled buffers: persist to draftKey so they restore on next launch. The write is debounced
47
+ // (T2-1) — clearDraft cancels any pending debounced write so an equal-to-saved edit can't be
48
+ // resurrected by a stale write landing after the clear.
49
+ if (isUntitled(path)) {
50
+ if (text === content)
51
+ clearDraft(path);
52
+ else
53
+ writeDraftDebounced(path, text);
54
+ return;
55
+ }
56
+ // File-backed txt (Notepad-style): persist edit + the disk base so we can detect stale drafts.
57
+ if (text === content)
58
+ clearFileDraft(path);
59
+ else
60
+ writeFileDraftDebounced(path, { base: content, text });
61
+ }, [queueAutoSave, writeEditsLive]);
62
+ return { newDocument, duplicateAsDraft, onTxtChange };
63
+ }
@@ -0,0 +1,31 @@
1
+ import { type MutableRefObject } from "react";
2
+ import { type LoadedDocument } from "@rightkit/document-core/documents/types";
3
+ import type { BlockDraftRegistry } from "@rightkit/document-core/app/blockDrafts";
4
+ import type { DocumentTabs } from "./useDocumentTabs.js";
5
+ /** Dirty/title/draft read helpers (pure reads over tab refs + the block-draft registry). */
6
+ export declare function useDocumentDirty(deps: {
7
+ blockDrafts: BlockDraftRegistry;
8
+ pdfDirtyRef: DocumentTabs["pdfDirtyRef"];
9
+ docxDirtyRef: DocumentTabs["docxDirtyRef"];
10
+ imageDirtyRef: DocumentTabs["imageDirtyRef"];
11
+ editsRef: MutableRefObject<Record<string, string>>;
12
+ htmlPagesRef: DocumentTabs["htmlPagesRef"];
13
+ }): {
14
+ hasModifiedDraft: (path: string) => boolean;
15
+ snapshotModified: (path?: string) => Readonly<{
16
+ identity: import("@rightkit/document-core/app/blockDrafts").BlockDraftIdentity;
17
+ blockKind: string;
18
+ originalRevision: string | number;
19
+ sourceRange?: import("@rightkit/document-core/app/blockDrafts").BlockDraftSourceRange;
20
+ sourceChecksum?: string;
21
+ originalText: string;
22
+ currentText: string;
23
+ targetTag?: string;
24
+ selectionBookmark?: import("@rightkit/document-core/app/blockDrafts").BlockDraftSelectionBookmark;
25
+ status: import("@rightkit/document-core/app/blockDrafts").BlockDraftStatus;
26
+ reason?: string;
27
+ error?: string;
28
+ }>[];
29
+ isDirty: (doc: LoadedDocument) => boolean;
30
+ titleFor: (doc: LoadedDocument) => string;
31
+ };
@@ -0,0 +1,46 @@
1
+ import { useCallback } from "react";
2
+ import { displayTitle, isUntitled, untitledTitle, } from "@rightkit/document-core/documents/types";
3
+ import { isWebDocument } from "@rightkit/document-core/documents/web/webUrl";
4
+ /** Dirty/title/draft read helpers (pure reads over tab refs + the block-draft registry). */
5
+ export function useDocumentDirty(deps) {
6
+ const { blockDrafts, docxDirtyRef, pdfDirtyRef, editsRef, imageDirtyRef, htmlPagesRef } = deps;
7
+ const hasModifiedDraft = useCallback((path) => blockDrafts.snapshotModified(path).length > 0, [blockDrafts]);
8
+ const snapshotModified = useCallback((path) => blockDrafts.snapshotModified(path), [blockDrafts]);
9
+ const isDirty = useCallback((doc) => {
10
+ if (isWebDocument(doc))
11
+ return false;
12
+ if (doc.format === "pdf")
13
+ return pdfDirtyRef.current.has(doc.path);
14
+ // An open block draft counts as unsaved work (close/quit must resolve it).
15
+ if (hasModifiedDraft(doc.path))
16
+ return true;
17
+ if (doc.format === "docx")
18
+ return docxDirtyRef.current.has(doc.path);
19
+ if (doc.format === "image")
20
+ return imageDirtyRef.current.has(doc.path);
21
+ // Read the synchronous mirrors so a save/close in the same tick as a keystroke sees the latest
22
+ // text. Reactivity is preserved because every edit also calls a setter, which re-renders.
23
+ const entryDirty = (editsRef.current[doc.path] ?? doc.content) !== doc.content;
24
+ if (doc.format === "html") {
25
+ if (entryDirty)
26
+ return true;
27
+ // An HTML tab is also dirty if any navigated sub-page in its session has unsaved edits.
28
+ const session = htmlPagesRef.current[doc.path];
29
+ if (session)
30
+ for (const p in session)
31
+ if (session[p].edited !== session[p].original)
32
+ return true;
33
+ return false;
34
+ }
35
+ return entryDirty;
36
+ }, [hasModifiedDraft, docxDirtyRef, pdfDirtyRef, editsRef, imageDirtyRef, htmlPagesRef]);
37
+ // Reads editsRef.current (a live ref). Keystrokes never re-render App; the expanded-sidebar rows +
38
+ // the titlebar get LIVE untitled titles by subscribing to this doc's edit slice (LiveTitle/useEditText),
39
+ // which re-renders just that label and re-invokes titleFor with the fresh ref value.
40
+ const titleFor = useCallback((doc) => isWebDocument(doc)
41
+ ? doc.displayName
42
+ : isUntitled(doc.path)
43
+ ? untitledTitle(editsRef.current[doc.path] ?? "")
44
+ : displayTitle(doc.path), [editsRef]);
45
+ return { hasModifiedDraft, snapshotModified, isDirty, titleFor };
46
+ }
@@ -0,0 +1,55 @@
1
+ import { type Dispatch, type MutableRefObject, type SetStateAction } from "react";
2
+ import { type LoadedDocument, type ViewMeta, type ViewMode } from "@rightkit/document-core/documents/types";
3
+ import { type FileEntry } from "../state/library.js";
4
+ import type { DocumentTabs } from "./useDocumentTabs.js";
5
+ export interface OpenDocumentOptions {
6
+ /** Add the tab without activating it. */
7
+ background?: boolean;
8
+ /** Skip the per-open recents refresh; the caller refreshes once after a batch. */
9
+ deferLibraryRefresh?: boolean;
10
+ /** Leave the current error banner alone. Session-restore opens use this so they cannot clear an
11
+ * error they didn't set (e.g. a launched file that failed to open). Their own failures still
12
+ * report. */
13
+ keepError?: boolean;
14
+ /** Place the new tab within the open-tab list (applied in the same state update that adds it), so
15
+ * a batch opener can insert tabs at their final position instead of re-ordering them later. */
16
+ arrange?: (docs: LoadedDocument[]) => LoadedDocument[];
17
+ }
18
+ interface DocumentLoaderDeps {
19
+ openDocs: LoadedDocument[];
20
+ setOpenDocs: DocumentTabs["setOpenDocs"];
21
+ setViews: Dispatch<SetStateAction<Record<string, ViewMode>>>;
22
+ viewsRef: MutableRefObject<Record<string, ViewMode>>;
23
+ viewMetaRef: MutableRefObject<Record<string, ViewMeta>>;
24
+ writeEdits: DocumentTabs["writeEdits"];
25
+ setError: Dispatch<SetStateAction<string | null>>;
26
+ setOpeningPath: Dispatch<SetStateAction<string | null>>;
27
+ setActivePath: DocumentTabs["setActivePath"];
28
+ fingerprints: MutableRefObject<Map<string, {
29
+ mtimeMs: number;
30
+ size: number;
31
+ }>>;
32
+ refreshLibrary: () => Promise<void>;
33
+ syncPinned: (path: string) => Promise<void>;
34
+ isDirty: (doc: LoadedDocument) => boolean;
35
+ clearImageDirty: (path: string) => void;
36
+ withTabKey: <T extends LoadedDocument>(doc: T, existingKey?: string) => T;
37
+ }
38
+ /**
39
+ * Open/read paths into tabs: file-picker open, live-URL "tabs", reopening a known-recent entry, the
40
+ * open-file dialog, and paging to a sibling image in place. Extracted verbatim from useDocuments —
41
+ * bodies, error handling, restore-draft logic, and view-default selection are unchanged. `activate`
42
+ * stays with the orchestrator (it's just an activePath setter, and requestClose/doClose/reload all
43
+ * need it too), so loader functions take it as a dependency instead of owning it.
44
+ */
45
+ export declare function useDocumentLoader({ openDocs, setOpenDocs, setViews, viewsRef, viewMetaRef, writeEdits, setError, setOpeningPath, setActivePath, fingerprints, refreshLibrary, syncPinned, isDirty, clearImageDirty, withTabKey, }: DocumentLoaderDeps): {
46
+ activate: (path: string) => Promise<void>;
47
+ open: (path: string, opts?: OpenDocumentOptions) => Promise<void>;
48
+ openLiveUrl: (input: string, opts?: {
49
+ background?: boolean;
50
+ }) => Promise<void>;
51
+ openRecent: (entry: FileEntry) => Promise<void>;
52
+ onOpenDialog: () => Promise<void>;
53
+ openImageSibling: (currentPath: string, targetPath: string) => Promise<void>;
54
+ };
55
+ export {};