markupr 2.1.8

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 (299) hide show
  1. package/.claude/commands/review-feedback.md +47 -0
  2. package/.eslintrc.json +35 -0
  3. package/.github/CODEOWNERS +16 -0
  4. package/.github/FUNDING.yml +1 -0
  5. package/.github/ISSUE_TEMPLATE/bug_report.md +56 -0
  6. package/.github/ISSUE_TEMPLATE/feature_request.md +54 -0
  7. package/.github/PULL_REQUEST_TEMPLATE.md +89 -0
  8. package/.github/dependabot.yml +70 -0
  9. package/.github/workflows/ci.yml +184 -0
  10. package/.github/workflows/deploy-landing.yml +134 -0
  11. package/.github/workflows/nightly.yml +288 -0
  12. package/.github/workflows/release.yml +318 -0
  13. package/CHANGELOG.md +127 -0
  14. package/CLAUDE.md +137 -0
  15. package/CODE_OF_CONDUCT.md +9 -0
  16. package/CONTRIBUTING.md +390 -0
  17. package/LICENSE +21 -0
  18. package/PRODUCT_VISION.md +277 -0
  19. package/README.md +517 -0
  20. package/SECURITY.md +51 -0
  21. package/SIGNING_INSTRUCTIONS.md +284 -0
  22. package/assets/DMG_BACKGROUND_INSTRUCTIONS.md +130 -0
  23. package/assets/svg-source/dmg-background.svg +70 -0
  24. package/assets/svg-source/icon.svg +20 -0
  25. package/assets/svg-source/tray-icon-processing.svg +7 -0
  26. package/assets/svg-source/tray-icon-recording.svg +7 -0
  27. package/assets/svg-source/tray-icon.svg +6 -0
  28. package/assets/tray-complete.png +0 -0
  29. package/assets/tray-complete@2x.png +0 -0
  30. package/assets/tray-completeTemplate.png +0 -0
  31. package/assets/tray-completeTemplate@2x.png +0 -0
  32. package/assets/tray-error.png +0 -0
  33. package/assets/tray-error@2x.png +0 -0
  34. package/assets/tray-errorTemplate.png +0 -0
  35. package/assets/tray-errorTemplate@2x.png +0 -0
  36. package/assets/tray-icon-processing.png +0 -0
  37. package/assets/tray-icon-processing@2x.png +0 -0
  38. package/assets/tray-icon-processingTemplate.png +0 -0
  39. package/assets/tray-icon-processingTemplate@2x.png +0 -0
  40. package/assets/tray-icon-recording.png +0 -0
  41. package/assets/tray-icon-recording@2x.png +0 -0
  42. package/assets/tray-icon-recordingTemplate.png +0 -0
  43. package/assets/tray-icon-recordingTemplate@2x.png +0 -0
  44. package/assets/tray-icon.png +0 -0
  45. package/assets/tray-icon@2x.png +0 -0
  46. package/assets/tray-iconTemplate.png +0 -0
  47. package/assets/tray-iconTemplate@2x.png +0 -0
  48. package/assets/tray-idle.png +0 -0
  49. package/assets/tray-idle@2x.png +0 -0
  50. package/assets/tray-idleTemplate.png +0 -0
  51. package/assets/tray-idleTemplate@2x.png +0 -0
  52. package/assets/tray-processing-0.png +0 -0
  53. package/assets/tray-processing-0@2x.png +0 -0
  54. package/assets/tray-processing-0Template.png +0 -0
  55. package/assets/tray-processing-0Template@2x.png +0 -0
  56. package/assets/tray-processing-1.png +0 -0
  57. package/assets/tray-processing-1@2x.png +0 -0
  58. package/assets/tray-processing-1Template.png +0 -0
  59. package/assets/tray-processing-1Template@2x.png +0 -0
  60. package/assets/tray-processing-2.png +0 -0
  61. package/assets/tray-processing-2@2x.png +0 -0
  62. package/assets/tray-processing-2Template.png +0 -0
  63. package/assets/tray-processing-2Template@2x.png +0 -0
  64. package/assets/tray-processing-3.png +0 -0
  65. package/assets/tray-processing-3@2x.png +0 -0
  66. package/assets/tray-processing-3Template.png +0 -0
  67. package/assets/tray-processing-3Template@2x.png +0 -0
  68. package/assets/tray-processing.png +0 -0
  69. package/assets/tray-processing@2x.png +0 -0
  70. package/assets/tray-processingTemplate.png +0 -0
  71. package/assets/tray-processingTemplate@2x.png +0 -0
  72. package/assets/tray-recording.png +0 -0
  73. package/assets/tray-recording@2x.png +0 -0
  74. package/assets/tray-recordingTemplate.png +0 -0
  75. package/assets/tray-recordingTemplate@2x.png +0 -0
  76. package/build/DMG_BACKGROUND_SPEC.md +50 -0
  77. package/build/dmg-background.png +0 -0
  78. package/build/dmg-background@2x.png +0 -0
  79. package/build/entitlements.mac.inherit.plist +27 -0
  80. package/build/entitlements.mac.plist +41 -0
  81. package/build/favicon-16.png +0 -0
  82. package/build/favicon-180.png +0 -0
  83. package/build/favicon-192.png +0 -0
  84. package/build/favicon-32.png +0 -0
  85. package/build/favicon-48.png +0 -0
  86. package/build/favicon-512.png +0 -0
  87. package/build/favicon-64.png +0 -0
  88. package/build/icon-128.png +0 -0
  89. package/build/icon-16.png +0 -0
  90. package/build/icon-24.png +0 -0
  91. package/build/icon-256.png +0 -0
  92. package/build/icon-32.png +0 -0
  93. package/build/icon-48.png +0 -0
  94. package/build/icon-64.png +0 -0
  95. package/build/icon.icns +0 -0
  96. package/build/icon.ico +0 -0
  97. package/build/icon.iconset/icon_128x128.png +0 -0
  98. package/build/icon.iconset/icon_128x128@2x.png +0 -0
  99. package/build/icon.iconset/icon_16x16.png +0 -0
  100. package/build/icon.iconset/icon_16x16@2x.png +0 -0
  101. package/build/icon.iconset/icon_256x256.png +0 -0
  102. package/build/icon.iconset/icon_256x256@2x.png +0 -0
  103. package/build/icon.iconset/icon_32x32.png +0 -0
  104. package/build/icon.iconset/icon_32x32@2x.png +0 -0
  105. package/build/icon.iconset/icon_512x512.png +0 -0
  106. package/build/icon.iconset/icon_512x512@2x.png +0 -0
  107. package/build/icon.png +0 -0
  108. package/build/installer-header.bmp +0 -0
  109. package/build/installer-header.png +0 -0
  110. package/build/installer-sidebar.bmp +0 -0
  111. package/build/installer-sidebar.png +0 -0
  112. package/build/installer.nsh +45 -0
  113. package/build/overlay-processing.png +0 -0
  114. package/build/overlay-recording.png +0 -0
  115. package/build/toolbar-record.png +0 -0
  116. package/build/toolbar-screenshot.png +0 -0
  117. package/build/toolbar-settings.png +0 -0
  118. package/build/toolbar-stop.png +0 -0
  119. package/dist/main/index.mjs +12612 -0
  120. package/dist/preload/index.mjs +907 -0
  121. package/dist/renderer/assets/index-CCmUjl9K.js +19495 -0
  122. package/dist/renderer/assets/index-CUqz_Gs6.css +2270 -0
  123. package/dist/renderer/index.html +27 -0
  124. package/docs/AI_AGENT_QUICKSTART.md +42 -0
  125. package/docs/AI_PIPELINE_DESIGN.md +595 -0
  126. package/docs/API.md +514 -0
  127. package/docs/ARCHITECTURE.md +460 -0
  128. package/docs/CONFIGURATION.md +336 -0
  129. package/docs/DEVELOPMENT.md +508 -0
  130. package/docs/EXPORT_FORMATS.md +451 -0
  131. package/docs/GETTING_STARTED.md +236 -0
  132. package/docs/KEYBOARD_SHORTCUTS.md +334 -0
  133. package/docs/TROUBLESHOOTING.md +418 -0
  134. package/docs/landing/index.html +672 -0
  135. package/docs/landing/script.js +342 -0
  136. package/docs/landing/styles.css +1543 -0
  137. package/electron-builder.yml +140 -0
  138. package/electron.vite.config.ts +63 -0
  139. package/package.json +108 -0
  140. package/railway.json +12 -0
  141. package/scripts/build.mjs +51 -0
  142. package/scripts/generate-icons.mjs +314 -0
  143. package/scripts/generate-installer-images.cjs +253 -0
  144. package/scripts/generate-tray-icons.mjs +258 -0
  145. package/scripts/notarize.cjs +180 -0
  146. package/scripts/one-click-clean-test.sh +147 -0
  147. package/scripts/postinstall.mjs +36 -0
  148. package/scripts/setup-markupr.sh +55 -0
  149. package/setup +17 -0
  150. package/site/index.html +1835 -0
  151. package/site/package.json +11 -0
  152. package/site/railway.json +12 -0
  153. package/site/server.js +31 -0
  154. package/src/main/AutoUpdater.ts +392 -0
  155. package/src/main/CrashRecovery.ts +655 -0
  156. package/src/main/ErrorHandler.ts +703 -0
  157. package/src/main/HotkeyManager.ts +399 -0
  158. package/src/main/MenuManager.ts +529 -0
  159. package/src/main/PermissionManager.ts +420 -0
  160. package/src/main/SessionController.ts +1465 -0
  161. package/src/main/TrayManager.ts +540 -0
  162. package/src/main/ai/AIPipelineManager.ts +199 -0
  163. package/src/main/ai/ClaudeAnalyzer.ts +339 -0
  164. package/src/main/ai/ImageOptimizer.ts +176 -0
  165. package/src/main/ai/StructuredMarkdownBuilder.ts +379 -0
  166. package/src/main/ai/index.ts +16 -0
  167. package/src/main/ai/types.ts +258 -0
  168. package/src/main/analysis/ClarificationGenerator.ts +385 -0
  169. package/src/main/analysis/FeedbackAnalyzer.ts +531 -0
  170. package/src/main/analysis/index.ts +19 -0
  171. package/src/main/audio/AudioCapture.ts +978 -0
  172. package/src/main/audio/audioUtils.ts +100 -0
  173. package/src/main/audio/index.ts +20 -0
  174. package/src/main/capture/index.ts +1 -0
  175. package/src/main/index.ts +1693 -0
  176. package/src/main/ipc/captureHandlers.ts +272 -0
  177. package/src/main/ipc/index.ts +45 -0
  178. package/src/main/ipc/outputHandlers.ts +302 -0
  179. package/src/main/ipc/sessionHandlers.ts +56 -0
  180. package/src/main/ipc/settingsHandlers.ts +471 -0
  181. package/src/main/ipc/types.ts +56 -0
  182. package/src/main/ipc/windowHandlers.ts +277 -0
  183. package/src/main/output/ClipboardService.ts +369 -0
  184. package/src/main/output/ExportService.ts +539 -0
  185. package/src/main/output/FileManager.ts +416 -0
  186. package/src/main/output/MarkdownGenerator.ts +791 -0
  187. package/src/main/output/MarkdownPatcher.ts +299 -0
  188. package/src/main/output/index.ts +186 -0
  189. package/src/main/output/sessionAdapter.ts +207 -0
  190. package/src/main/output/templates/html-template.ts +553 -0
  191. package/src/main/pipeline/FrameExtractor.ts +330 -0
  192. package/src/main/pipeline/PostProcessor.ts +399 -0
  193. package/src/main/pipeline/TranscriptAnalyzer.ts +226 -0
  194. package/src/main/pipeline/index.ts +36 -0
  195. package/src/main/platform/WindowsTaskbar.ts +600 -0
  196. package/src/main/platform/index.ts +16 -0
  197. package/src/main/settings/SettingsManager.ts +730 -0
  198. package/src/main/settings/index.ts +19 -0
  199. package/src/main/transcription/ModelDownloadManager.ts +494 -0
  200. package/src/main/transcription/TierManager.ts +219 -0
  201. package/src/main/transcription/TranscriptionRecoveryService.ts +340 -0
  202. package/src/main/transcription/WhisperService.ts +748 -0
  203. package/src/main/transcription/index.ts +56 -0
  204. package/src/main/transcription/types.ts +135 -0
  205. package/src/main/windows/PopoverManager.ts +284 -0
  206. package/src/main/windows/TaskbarIntegration.ts +452 -0
  207. package/src/main/windows/index.ts +23 -0
  208. package/src/preload/index.ts +1047 -0
  209. package/src/renderer/App.tsx +515 -0
  210. package/src/renderer/AppWrapper.tsx +28 -0
  211. package/src/renderer/assets/logo-dark.svg +7 -0
  212. package/src/renderer/assets/logo.svg +7 -0
  213. package/src/renderer/audio/AudioCaptureRenderer.ts +454 -0
  214. package/src/renderer/capture/ScreenRecordingRenderer.ts +492 -0
  215. package/src/renderer/components/AnnotationOverlay.tsx +836 -0
  216. package/src/renderer/components/AudioWaveform.tsx +811 -0
  217. package/src/renderer/components/ClarificationQuestions.tsx +656 -0
  218. package/src/renderer/components/CountdownTimer.tsx +495 -0
  219. package/src/renderer/components/CrashRecoveryDialog.tsx +632 -0
  220. package/src/renderer/components/DonateButton.tsx +127 -0
  221. package/src/renderer/components/ErrorBoundary.tsx +308 -0
  222. package/src/renderer/components/ExportDialog.tsx +872 -0
  223. package/src/renderer/components/HotkeyHint.tsx +261 -0
  224. package/src/renderer/components/KeyboardShortcuts.tsx +787 -0
  225. package/src/renderer/components/ModelDownloadDialog.tsx +844 -0
  226. package/src/renderer/components/Onboarding.tsx +1830 -0
  227. package/src/renderer/components/ProcessingOverlay.tsx +157 -0
  228. package/src/renderer/components/RecordingOverlay.tsx +423 -0
  229. package/src/renderer/components/SessionHistory.tsx +1746 -0
  230. package/src/renderer/components/SessionReview.tsx +1321 -0
  231. package/src/renderer/components/SettingsPanel.tsx +217 -0
  232. package/src/renderer/components/Skeleton.tsx +347 -0
  233. package/src/renderer/components/StatusIndicator.tsx +86 -0
  234. package/src/renderer/components/ThemeProvider.tsx +429 -0
  235. package/src/renderer/components/Tooltip.tsx +370 -0
  236. package/src/renderer/components/TranscriptionPreview.tsx +183 -0
  237. package/src/renderer/components/TranscriptionTierSelector.tsx +640 -0
  238. package/src/renderer/components/UpdateNotification.tsx +377 -0
  239. package/src/renderer/components/WindowSelector.tsx +947 -0
  240. package/src/renderer/components/index.ts +99 -0
  241. package/src/renderer/components/primitives/ApiKeyInput.tsx +98 -0
  242. package/src/renderer/components/primitives/ColorPicker.tsx +65 -0
  243. package/src/renderer/components/primitives/DangerButton.tsx +45 -0
  244. package/src/renderer/components/primitives/DirectoryPicker.tsx +41 -0
  245. package/src/renderer/components/primitives/Dropdown.tsx +34 -0
  246. package/src/renderer/components/primitives/KeyRecorder.tsx +117 -0
  247. package/src/renderer/components/primitives/SettingsSection.tsx +32 -0
  248. package/src/renderer/components/primitives/Slider.tsx +43 -0
  249. package/src/renderer/components/primitives/Toggle.tsx +36 -0
  250. package/src/renderer/components/primitives/index.ts +10 -0
  251. package/src/renderer/components/settings/AdvancedTab.tsx +174 -0
  252. package/src/renderer/components/settings/AppearanceTab.tsx +77 -0
  253. package/src/renderer/components/settings/GeneralTab.tsx +40 -0
  254. package/src/renderer/components/settings/HotkeysTab.tsx +79 -0
  255. package/src/renderer/components/settings/RecordingTab.tsx +84 -0
  256. package/src/renderer/components/settings/index.ts +9 -0
  257. package/src/renderer/components/settings/settingsStyles.ts +673 -0
  258. package/src/renderer/components/settings/tabConfig.tsx +85 -0
  259. package/src/renderer/components/settings/useSettingsPanel.ts +447 -0
  260. package/src/renderer/contexts/ProcessingContext.tsx +227 -0
  261. package/src/renderer/contexts/RecordingContext.tsx +683 -0
  262. package/src/renderer/contexts/UIContext.tsx +326 -0
  263. package/src/renderer/contexts/index.ts +24 -0
  264. package/src/renderer/donateMessages.ts +69 -0
  265. package/src/renderer/hooks/index.ts +75 -0
  266. package/src/renderer/hooks/useAnimation.tsx +544 -0
  267. package/src/renderer/hooks/useTheme.ts +313 -0
  268. package/src/renderer/index.html +26 -0
  269. package/src/renderer/main.tsx +52 -0
  270. package/src/renderer/styles/animations.css +1093 -0
  271. package/src/renderer/styles/app-shell.css +662 -0
  272. package/src/renderer/styles/globals.css +515 -0
  273. package/src/renderer/styles/theme.ts +578 -0
  274. package/src/renderer/types/electron.d.ts +385 -0
  275. package/src/shared/hotkeys.ts +283 -0
  276. package/src/shared/types.ts +809 -0
  277. package/tests/clipboard.test.ts +228 -0
  278. package/tests/e2e/criticalPaths.test.ts +594 -0
  279. package/tests/feedbackAnalyzer.test.ts +303 -0
  280. package/tests/integration/sessionFlow.test.ts +583 -0
  281. package/tests/markdownGenerator.test.ts +418 -0
  282. package/tests/output.test.ts +96 -0
  283. package/tests/setup.ts +486 -0
  284. package/tests/unit/appIntegration.test.ts +676 -0
  285. package/tests/unit/appViewState.test.ts +281 -0
  286. package/tests/unit/audioIpcChannels.test.ts +17 -0
  287. package/tests/unit/exportService.test.ts +492 -0
  288. package/tests/unit/hotkeys.test.ts +92 -0
  289. package/tests/unit/navigationPreload.test.ts +94 -0
  290. package/tests/unit/onboardingFlow.test.ts +345 -0
  291. package/tests/unit/permissionManager.test.ts +175 -0
  292. package/tests/unit/permissionManagerExpanded.test.ts +296 -0
  293. package/tests/unit/screenRecordingRenderer.test.ts +368 -0
  294. package/tests/unit/sessionController.test.ts +515 -0
  295. package/tests/unit/tierManager.test.ts +61 -0
  296. package/tests/unit/tierManagerExpanded.test.ts +142 -0
  297. package/tests/unit/transcriptAnalyzer.test.ts +64 -0
  298. package/tsconfig.json +25 -0
  299. package/vitest.config.ts +46 -0
package/docs/API.md ADDED
@@ -0,0 +1,514 @@
1
+ # API Reference
2
+
3
+ markupr uses Electron's IPC (Inter-Process Communication) for all communication between the main process and renderer. This document covers the internal API for developers.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Architecture Overview](#architecture-overview)
8
+ - [IPC Channels](#ipc-channels)
9
+ - [Preload API](#preload-api)
10
+ - [Event System](#event-system)
11
+ - [Plugin Architecture](#plugin-architecture)
12
+ - [Type Definitions](#type-definitions)
13
+
14
+ ## Architecture Overview
15
+
16
+ ```
17
+ ┌─────────────────────────────────────────────────────────────┐
18
+ │ Renderer Process │
19
+ │ ┌─────────────────────────────────────────────────────┐ │
20
+ │ │ React Application │ │
21
+ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
22
+ │ │ │ App.tsx │ │Components│ │ Hooks │ │ │
23
+ │ │ └────┬────┘ └────┬────┘ └────┬────┘ │ │
24
+ │ │ │ │ │ │ │
25
+ │ │ └────────────┴────────────┘ │ │
26
+ │ │ │ │ │
27
+ │ │ window.markupr │ │
28
+ │ └─────────────────────┬───────────────────────────────┘ │
29
+ │ │ │
30
+ ├────────────────────────┼─────────────────────────────────────┤
31
+ │ Preload Script │
32
+ │ contextBridge.exposeInMainWorld │
33
+ ├────────────────────────┼─────────────────────────────────────┤
34
+ │ │ │
35
+ │ ipcMain │
36
+ │ │ │
37
+ │ ┌─────────────────────┴───────────────────────────────┐ │
38
+ │ │ Main Process │ │
39
+ │ │ │ │
40
+ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
41
+ │ │ │ Session │ │ Capture │ │Transcript│ │ │
42
+ │ │ │Controller│ │ Service │ │ Service │ │ │
43
+ │ │ └──────────┘ └──────────┘ └──────────┘ │ │
44
+ │ │ │ │
45
+ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
46
+ │ │ │ Hotkey │ │ Tray │ │ Settings │ │ │
47
+ │ │ │ Manager │ │ Manager │ │ Manager │ │ │
48
+ │ │ └──────────┘ └──────────┘ └──────────┘ │ │
49
+ │ └───────────────────────────────────────────────────────┘ │
50
+ │ Main Process │
51
+ └─────────────────────────────────────────────────────────────┘
52
+ ```
53
+
54
+ ## IPC Channels
55
+
56
+ All IPC channels are defined in `src/shared/types.ts` with the `IPC_CHANNELS` constant.
57
+
58
+ ### Session Channels
59
+
60
+ #### Renderer to Main
61
+
62
+ | Channel | Method | Description | Returns |
63
+ |---------|--------|-------------|---------|
64
+ | `markupr:session:start` | invoke | Start recording | `{success, sessionId?, error?}` |
65
+ | `markupr:session:stop` | invoke | Stop recording | `{success, session?, error?}` |
66
+ | `markupr:session:cancel` | invoke | Cancel without saving | `{success}` |
67
+ | `markupr:session:get-status` | invoke | Get current status | `SessionStatusPayload` |
68
+ | `markupr:session:get-current` | invoke | Get session data | `SessionPayload | null` |
69
+
70
+ #### Main to Renderer
71
+
72
+ | Channel | Description | Payload |
73
+ |---------|-------------|---------|
74
+ | `markupr:session:state-changed` | State transition | `{state, session}` |
75
+ | `markupr:session:status-update` | Periodic status | `SessionStatusPayload` |
76
+ | `markupr:session:complete` | Session finished | `SessionPayload` |
77
+ | `markupr:session:feedback-item` | New item captured | `FeedbackItemPayload` |
78
+ | `markupr:session:error` | Error occurred | `{message}` |
79
+
80
+ ### Capture Channels
81
+
82
+ #### Renderer to Main
83
+
84
+ | Channel | Method | Description | Returns |
85
+ |---------|--------|-------------|---------|
86
+ | `markupr:capture:get-sources` | invoke | List sources | `CaptureSource[]` |
87
+ | `markupr:capture:manual-screenshot` | invoke | Take screenshot | `{success}` |
88
+
89
+ #### Main to Renderer
90
+
91
+ | Channel | Description | Payload |
92
+ |---------|-------------|---------|
93
+ | `markupr:capture:screenshot-taken` | Screenshot captured | `ScreenshotCapturedPayload` |
94
+ | `markupr:capture:manual-triggered` | Manual hotkey used | `{timestamp}` |
95
+
96
+ ### Audio Channels
97
+
98
+ #### Communication Flow
99
+
100
+ ```
101
+ Main Process Renderer Process
102
+ │ │
103
+ │ ─── AUDIO_START_CAPTURE ───> │ Start audio capture
104
+ │ │
105
+ │ <── AUDIO_CAPTURE_STARTED ─── │ Confirm started
106
+ │ │
107
+ │ <── AUDIO_CHUNK ──────────── │ Audio data (100ms chunks)
108
+ │ <── AUDIO_CHUNK ──────────── │
109
+ │ <── AUDIO_CHUNK ──────────── │
110
+ │ │
111
+ │ ─── AUDIO_STOP_CAPTURE ────> │ Stop capture
112
+ │ │
113
+ │ <── AUDIO_CAPTURE_STOPPED ── │ Confirm stopped
114
+ ```
115
+
116
+ ### Settings Channels
117
+
118
+ | Channel | Method | Description | Returns |
119
+ |---------|--------|-------------|---------|
120
+ | `markupr:settings:get` | invoke | Get single setting | `AppSettings[K]` |
121
+ | `markupr:settings:get-all` | invoke | Get all settings | `AppSettings` |
122
+ | `markupr:settings:set` | invoke | Set single setting | `AppSettings` |
123
+ | `markupr:settings:get-api-key` | invoke | Get API key (secure) | `string | null` |
124
+ | `markupr:settings:set-api-key` | invoke | Set API key (secure) | `boolean` |
125
+
126
+ ### Update Channels
127
+
128
+ | Channel | Method | Description | Returns |
129
+ |---------|--------|-------------|---------|
130
+ | `markupr:update:check` | invoke | Check for updates | `UpdateInfo` |
131
+ | `markupr:update:download` | invoke | Download update | `void` |
132
+ | `markupr:update:install` | invoke | Install and restart | `void` |
133
+
134
+ #### Main to Renderer
135
+
136
+ | Channel | Description | Payload |
137
+ |---------|-------------|---------|
138
+ | `markupr:update:status` | Update status change | `UpdateStatusPayload` |
139
+
140
+ ## Preload API
141
+
142
+ The preload script (`src/preload/index.ts`) exposes a safe API to the renderer via `window.markupr`.
143
+
144
+ ### Session API
145
+
146
+ ```typescript
147
+ // Start a recording session
148
+ const result = await window.markupr.session.start(sourceId);
149
+ // Returns: { success: boolean; sessionId?: string; error?: string }
150
+
151
+ // Stop the current session
152
+ const result = await window.markupr.session.stop();
153
+ // Returns: { success: boolean; session?: SessionPayload; error?: string }
154
+
155
+ // Cancel without saving
156
+ const result = await window.markupr.session.cancel();
157
+ // Returns: { success: boolean }
158
+
159
+ // Get current status
160
+ const status = await window.markupr.session.getStatus();
161
+ // Returns: SessionStatusPayload
162
+
163
+ // Get current session data
164
+ const session = await window.markupr.session.getCurrent();
165
+ // Returns: SessionPayload | null
166
+
167
+ // Subscribe to state changes
168
+ const unsubscribe = window.markupr.session.onStateChange(({ state, session }) => {
169
+ console.log('State:', state);
170
+ });
171
+
172
+ // Subscribe to new feedback items
173
+ const unsubscribe = window.markupr.session.onFeedbackItem((item) => {
174
+ console.log('New item:', item);
175
+ });
176
+
177
+ // Subscribe to errors
178
+ const unsubscribe = window.markupr.session.onError(({ message }) => {
179
+ console.error('Error:', message);
180
+ });
181
+ ```
182
+
183
+ ### Capture API
184
+
185
+ ```typescript
186
+ // Get available capture sources
187
+ const sources = await window.markupr.capture.getSources();
188
+ // Returns: CaptureSource[]
189
+
190
+ // Trigger manual screenshot
191
+ await window.markupr.capture.manualScreenshot();
192
+
193
+ // Subscribe to screenshots
194
+ const unsubscribe = window.markupr.capture.onScreenshot((data) => {
195
+ console.log('Screenshot:', data.id, data.count);
196
+ });
197
+ ```
198
+
199
+ ### Audio API
200
+
201
+ ```typescript
202
+ // Get available devices (enumeration happens in renderer)
203
+ const devices = await window.markupr.audio.getDevices();
204
+
205
+ // Set preferred device
206
+ await window.markupr.audio.setDevice(deviceId);
207
+
208
+ // Subscribe to audio level (for visualization)
209
+ const unsubscribe = window.markupr.audio.onLevel((level) => {
210
+ // level is 0-1 normalized amplitude
211
+ });
212
+
213
+ // Subscribe to voice activity
214
+ const unsubscribe = window.markupr.audio.onVoiceActivity((isActive) => {
215
+ // isActive is boolean
216
+ });
217
+ ```
218
+
219
+ ### Settings API
220
+
221
+ ```typescript
222
+ // Get a single setting
223
+ const theme = await window.markupr.settings.get('theme');
224
+
225
+ // Get all settings
226
+ const settings = await window.markupr.settings.getAll();
227
+
228
+ // Set a setting
229
+ const updated = await window.markupr.settings.set('theme', 'dark');
230
+
231
+ // Get API key from secure storage
232
+ const apiKey = await window.markupr.settings.getApiKey('openai');
233
+
234
+ // Set API key in secure storage
235
+ const success = await window.markupr.settings.setApiKey('openai', 'your-key');
236
+ ```
237
+
238
+ ### Hotkeys API
239
+
240
+ ```typescript
241
+ // Get current configuration
242
+ const config = await window.markupr.hotkeys.getConfig();
243
+ // Returns: HotkeyConfig
244
+
245
+ // Update configuration
246
+ const result = await window.markupr.hotkeys.updateConfig({
247
+ toggleRecording: 'CommandOrControl+Shift+G'
248
+ });
249
+ // Returns: { config: HotkeyConfig; results: RegistrationResult[] }
250
+
251
+ // Subscribe to hotkey triggers
252
+ const unsubscribe = window.markupr.hotkeys.onTriggered(({ action, accelerator }) => {
253
+ console.log('Hotkey:', action);
254
+ });
255
+ ```
256
+
257
+ ### Output API
258
+
259
+ ```typescript
260
+ // Save current session
261
+ const result = await window.markupr.output.save();
262
+ // Returns: SaveResult
263
+
264
+ // Copy to clipboard
265
+ const success = await window.markupr.output.copyClipboard();
266
+
267
+ // Open output folder
268
+ await window.markupr.output.openFolder();
269
+
270
+ // List saved sessions
271
+ const sessions = await window.markupr.output.listSessions();
272
+
273
+ // Delete a session
274
+ await window.markupr.output.deleteSession(sessionId);
275
+
276
+ // Export a session
277
+ await window.markupr.output.exportSession(sessionId, 'pdf');
278
+ ```
279
+
280
+ ### Crash Recovery API
281
+
282
+ ```typescript
283
+ // Check for incomplete sessions
284
+ const { hasIncomplete, session } = await window.markupr.crashRecovery.check();
285
+
286
+ // Recover an incomplete session
287
+ const result = await window.markupr.crashRecovery.recover(sessionId);
288
+
289
+ // Discard incomplete session
290
+ await window.markupr.crashRecovery.discard();
291
+
292
+ // Get crash logs
293
+ const logs = await window.markupr.crashRecovery.getLogs(10);
294
+
295
+ // Subscribe to found incomplete sessions (on startup)
296
+ const unsubscribe = window.markupr.crashRecovery.onIncompleteFound(({ session }) => {
297
+ // Show recovery dialog
298
+ });
299
+ ```
300
+
301
+ ### Updates API
302
+
303
+ ```typescript
304
+ // Check for updates
305
+ await window.markupr.updates.check();
306
+
307
+ // Download available update
308
+ await window.markupr.updates.download();
309
+
310
+ // Install and restart
311
+ await window.markupr.updates.install();
312
+
313
+ // Subscribe to update status
314
+ const unsubscribe = window.markupr.updates.onStatus((status) => {
315
+ console.log('Update status:', status.status);
316
+ if (status.percent) {
317
+ console.log('Progress:', status.percent);
318
+ }
319
+ });
320
+ ```
321
+
322
+ ## Event System
323
+
324
+ ### Event Subscription Pattern
325
+
326
+ All event subscriptions return an unsubscribe function:
327
+
328
+ ```typescript
329
+ // Subscribe
330
+ const unsubscribe = window.markupr.session.onStateChange((data) => {
331
+ // Handle event
332
+ });
333
+
334
+ // Later, clean up
335
+ unsubscribe();
336
+ ```
337
+
338
+ ### Using with React
339
+
340
+ ```tsx
341
+ import { useEffect, useState } from 'react';
342
+
343
+ function useSessionState() {
344
+ const [state, setState] = useState<SessionState>('idle');
345
+
346
+ useEffect(() => {
347
+ const unsubscribe = window.markupr.session.onStateChange(({ state }) => {
348
+ setState(state);
349
+ });
350
+
351
+ return unsubscribe; // Clean up on unmount
352
+ }, []);
353
+
354
+ return state;
355
+ }
356
+ ```
357
+
358
+ ## Plugin Architecture
359
+
360
+ markupr is designed to support plugins in future versions.
361
+
362
+ ### Planned Plugin Types
363
+
364
+ 1. **Output Formatters**: Add new export formats
365
+ 2. **Transcription Services**: Alternative to OpenAI
366
+ 3. **Integrations**: Connect to external services
367
+ 4. **Annotation Tools**: Custom drawing tools
368
+
369
+ ### Plugin Interface (Draft)
370
+
371
+ ```typescript
372
+ interface markuprPlugin {
373
+ name: string;
374
+ version: string;
375
+ type: 'formatter' | 'transcription' | 'integration' | 'annotation';
376
+
377
+ // Lifecycle hooks
378
+ onLoad(): Promise<void>;
379
+ onUnload(): Promise<void>;
380
+
381
+ // Type-specific methods
382
+ // ...
383
+ }
384
+
385
+ // Example: Custom formatter plugin
386
+ interface FormatterPlugin extends markuprPlugin {
387
+ type: 'formatter';
388
+
389
+ format(session: Session): Promise<{
390
+ content: string;
391
+ extension: string;
392
+ mimeType: string;
393
+ }>;
394
+ }
395
+ ```
396
+
397
+ ## Type Definitions
398
+
399
+ ### Core Types
400
+
401
+ ```typescript
402
+ // Session state machine
403
+ type SessionState = 'idle' | 'recording' | 'processing' | 'complete';
404
+
405
+ // Session status
406
+ type SessionStatus = 'idle' | 'recording' | 'processing' | 'complete' | 'error';
407
+
408
+ // Tray icon states
409
+ type TrayState = 'idle' | 'recording' | 'processing' | 'error';
410
+ ```
411
+
412
+ ### Payload Types
413
+
414
+ ```typescript
415
+ // Session status (sent during recording)
416
+ interface SessionStatusPayload {
417
+ state: SessionState;
418
+ duration: number;
419
+ feedbackCount: number;
420
+ screenshotCount: number;
421
+ }
422
+
423
+ // Feedback item (sent when captured)
424
+ interface FeedbackItemPayload {
425
+ id: string;
426
+ timestamp: number;
427
+ text: string;
428
+ confidence: number;
429
+ hasScreenshot: boolean;
430
+ screenshotId?: string;
431
+ }
432
+
433
+ // Screenshot captured
434
+ interface ScreenshotCapturedPayload {
435
+ id: string;
436
+ timestamp: number;
437
+ count: number;
438
+ width?: number;
439
+ height?: number;
440
+ }
441
+
442
+ // Transcript chunk
443
+ interface TranscriptChunkPayload {
444
+ text: string;
445
+ timestamp: number;
446
+ confidence: number;
447
+ isFinal: boolean;
448
+ words?: Array<{
449
+ word: string;
450
+ start: number;
451
+ end: number;
452
+ confidence: number;
453
+ }>;
454
+ }
455
+ ```
456
+
457
+ ### Configuration Types
458
+
459
+ ```typescript
460
+ // Hotkey configuration
461
+ interface HotkeyConfig {
462
+ toggleRecording: string;
463
+ manualScreenshot: string;
464
+ }
465
+
466
+ // Application settings
467
+ interface AppSettings {
468
+ outputDirectory: string;
469
+ launchAtLogin: boolean;
470
+ checkForUpdates: boolean;
471
+ defaultCountdown: 0 | 3 | 5;
472
+ showTranscriptionPreview: boolean;
473
+ showAudioWaveform: boolean;
474
+ pauseThreshold: number;
475
+ minTimeBetweenCaptures: number;
476
+ imageFormat: 'png' | 'jpeg';
477
+ imageQuality: number;
478
+ maxImageWidth: number;
479
+ theme: 'dark' | 'light' | 'system';
480
+ accentColor: string;
481
+ hotkeys: HotkeyConfig;
482
+ audioDeviceId: string | null;
483
+ debugMode: boolean;
484
+ keepAudioBackups: boolean;
485
+ }
486
+ ```
487
+
488
+ ### Capture Types
489
+
490
+ ```typescript
491
+ // Capture source
492
+ interface CaptureSource {
493
+ id: string;
494
+ name: string;
495
+ type: 'screen' | 'window';
496
+ thumbnail?: string;
497
+ appIcon?: string;
498
+ display?: DisplayInfo;
499
+ }
500
+
501
+ // Display info (multi-monitor)
502
+ interface DisplayInfo {
503
+ id: number;
504
+ label: string;
505
+ bounds: { x: number; y: number; width: number; height: number };
506
+ workArea: { x: number; y: number; width: number; height: number };
507
+ scaleFactor: number;
508
+ isPrimary: boolean;
509
+ rotation: 0 | 90 | 180 | 270;
510
+ internal: boolean;
511
+ }
512
+ ```
513
+
514
+ For the complete type definitions, see `src/shared/types.ts`.