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/README.md ADDED
@@ -0,0 +1,517 @@
1
+ <p align="center">
2
+ <img src="src/renderer/assets/logo.svg" alt="markupr Logo" width="120" height="120">
3
+ </p>
4
+
5
+ <h1 align="center">markupr</h1>
6
+
7
+ <p align="center">
8
+ <strong>Turn voice narration into AI-ready Markdown with intelligent screenshots</strong>
9
+ </p>
10
+
11
+ <p align="center">
12
+ <a href="https://github.com/eddiesanjuan/markupr/actions/workflows/ci.yml"><img src="https://github.com/eddiesanjuan/markupr/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
13
+ <a href="https://github.com/eddiesanjuan/markupr/actions/workflows/release.yml"><img src="https://github.com/eddiesanjuan/markupr/actions/workflows/release.yml/badge.svg" alt="Release"></a>
14
+ <a href="https://github.com/eddiesanjuan/markupr/releases"><img src="https://img.shields.io/github/v/release/eddiesanjuan/markupr?style=flat-square" alt="Latest Release"></a>
15
+ <a href="https://github.com/eddiesanjuan/markupr/releases"><img src="https://img.shields.io/github/downloads/eddiesanjuan/markupr/total?style=flat-square" alt="Downloads"></a>
16
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square" alt="License"></a>
17
+ <a href="https://ko-fi.com/eddiesanjuan"><img src="https://img.shields.io/badge/Support-Ko--fi-FF5E5B?style=flat-square&logo=ko-fi" alt="Ko-fi"></a>
18
+ </p>
19
+
20
+ <p align="center">
21
+ <a href="#features">Features</a> |
22
+ <a href="#quick-start">Quick Start</a> |
23
+ <a href="#how-it-works">How It Works</a> |
24
+ <a href="#installation">Installation</a> |
25
+ <a href="#usage">Usage</a> |
26
+ <a href="#keyboard-shortcuts">Shortcuts</a> |
27
+ <a href="#export-formats">Export</a> |
28
+ <a href="#development">Development</a> |
29
+ <a href="#contributing">Contributing</a>
30
+ </p>
31
+
32
+ ---
33
+
34
+ markupr is a menu bar app that intelligently captures developer feedback. Press a hotkey, talk through what you see, and markupr records your screen while transcribing your voice. When you stop, an intelligent post-processing pipeline correlates your transcript timestamps with the screen recording to extract the right frames at the right moments -- then stitches everything into a structured, AI-ready Markdown document.
35
+
36
+ One hotkey to start. One hotkey to stop. A Markdown file with your words, contextually-placed screenshots, and intelligent structure -- ready to hand to your AI coding agent, paste into a GitHub issue, or drop in a Slack thread.
37
+
38
+ If markupr saves you hours, consider supporting development on [Ko-fi](https://ko-fi.com/eddiesanjuan) so updates and fixes ship faster.
39
+
40
+ ## Features
41
+
42
+ ### Voice-Driven Capture
43
+ - **Local Whisper transcription** runs entirely on your machine -- no API key, no internet required
44
+ - **Optional OpenAI cloud transcription** for higher accuracy (BYOK)
45
+ - **Intelligent screenshot timing** captures automatically during voice pauses
46
+ - **Audio waveform visualization** for real-time feedback
47
+
48
+ ### Intelligent Post-Processing Pipeline
49
+ - **Timestamp-correlated frame extraction** -- every screenshot corresponds to what you were describing
50
+ - **Key-moment detection** analyzes your transcript to find the most important moments
51
+ - **Video frame extraction** via ffmpeg pulls precise frames from the screen recording
52
+ - **Structured Markdown output** optimized for LLM consumption (llms.txt inspired)
53
+
54
+ ### Smart Screenshots
55
+ - **Voice Activity Detection (VAD)** triggers captures at natural pause points
56
+ - **Manual screenshot hotkey** (`Cmd+Shift+S`) for precise control
57
+ - **Multi-monitor support** with display selection
58
+ - **Window-specific capture** for focused feedback
59
+
60
+ ### AI-Ready Output
61
+ - **Markdown format** with contextually-placed screenshots and structured feedback items
62
+ - **Multiple export formats**: Markdown, PDF, HTML, JSON
63
+ - **Clipboard bridge** -- file path is copied to clipboard so AI tools can read the full document
64
+
65
+ ### Bulletproof Reliability
66
+ - **7-state finite state machine** with watchdog timer -- no state the app can enter and not exit
67
+ - **Crash recovery** with 5-second auto-save -- never lose a feedback session
68
+ - **Graceful degradation** -- if transcription fails, frame extraction continues; if ffmpeg is missing, transcript-only output is generated
69
+ - **Auto-updater** for seamless updates
70
+
71
+ ### Professional Experience
72
+ - **Native macOS menu bar** integration (no dock icon)
73
+ - **Windows system tray** support
74
+ - **Global hotkeys** that work from any application
75
+ - **Annotation tools** (arrow, circle, rectangle, freehand, text)
76
+ - **Session history browser** with search and export
77
+ - **Dark/light/system theme** support
78
+ - **Onboarding experience** for first-run setup
79
+
80
+ ## Quick Start
81
+
82
+ 1. **Download** the latest release for your platform
83
+ 2. **Install** the application (DMG for macOS, installer for Windows)
84
+ 3. **Press** `Cmd+Shift+F` (macOS) or `Ctrl+Shift+F` (Windows) to start recording
85
+ 4. **Narrate** your feedback while markupr captures screenshots at pause points
86
+ 5. **Press** the hotkey again to stop -- the post-processing pipeline runs automatically
87
+ 6. **Paste** the file path from your clipboard into your AI coding agent
88
+
89
+ **No API key required!** markupr uses local Whisper transcription by default. Add your OpenAI API key in Settings for cloud transcription.
90
+
91
+ ## How It Works
92
+
93
+ ### The Post-Processing Pipeline
94
+
95
+ When you press stop, markupr's intelligent pipeline takes over:
96
+
97
+ 1. **Transcribe** -- Your audio is transcribed using local Whisper (or OpenAI API if configured)
98
+ 2. **Analyze** -- The transcript is analyzed to identify key moments, topic changes, and important observations
99
+ 3. **Extract** -- Video frames are extracted at the exact timestamps corresponding to each key moment
100
+ 4. **Generate** -- Everything is stitched into a structured Markdown document with screenshots placed exactly where they belong
101
+
102
+ The result isn't just "screenshots taken during pauses" -- it's contextually-aware frame extraction that ensures every image in the document shows exactly what you were talking about.
103
+
104
+ ### The Clipboard Bridge
105
+
106
+ When a session completes, the **file path** to your Markdown document is copied to clipboard. Not the content -- the path. This is deliberate:
107
+
108
+ - If your clipboard gets overwritten, the file lives on disk permanently
109
+ - AI tools like Claude Code can read the file path and process the full document including screenshots
110
+ - The file is yours -- local, private, no cloud dependency
111
+
112
+ ### Session State Machine
113
+
114
+ The recording session is governed by a 7-state FSM with timeouts:
115
+
116
+ ```
117
+ idle ─→ starting (5s timeout) ─→ recording (30min max) ─→ stopping (3s timeout)
118
+
119
+
120
+ processing (10s timeout) ─→ complete (30s auto-idle)
121
+
122
+
123
+ error (5s auto-recover)
124
+ ```
125
+
126
+ Every state has a maximum duration. A watchdog timer monitors state age and forces recovery if anything gets stuck.
127
+
128
+ ## Installation
129
+
130
+ ### macOS
131
+
132
+ Download the `.dmg` file from the [releases page](https://github.com/eddiesanjuan/markupr/releases).
133
+
134
+ 1. Open the DMG file
135
+ 2. Drag markupr to your Applications folder
136
+ 3. Launch markupr from Applications
137
+ 4. Grant required permissions (Microphone, Screen Recording)
138
+
139
+ ### Windows
140
+
141
+ Download the `.exe` installer from the [releases page](https://github.com/eddiesanjuan/markupr/releases).
142
+
143
+ 1. Run the installer
144
+ 2. Follow the installation wizard
145
+ 3. Launch markupr from the Start menu
146
+
147
+ ### Linux
148
+
149
+ Download the `.AppImage` or `.deb` file from the [releases page](https://github.com/eddiesanjuan/markupr/releases).
150
+
151
+ ```bash
152
+ # AppImage
153
+ chmod +x markupr-*.AppImage
154
+ ./markupr-*.AppImage
155
+
156
+ # Debian/Ubuntu
157
+ sudo dpkg -i markupr_*.deb
158
+ ```
159
+
160
+ ## Configuration
161
+
162
+ ### Transcription
163
+
164
+ markupr works out of the box with **local Whisper** transcription -- no API key needed. On first run, you'll be prompted to download a Whisper model (~75MB for tiny, ~500MB for base).
165
+
166
+ For cloud post-session transcription with higher accuracy, add your OpenAI API key:
167
+
168
+ 1. Sign up at [platform.openai.com/api-keys](https://platform.openai.com/api-keys)
169
+ 2. Create an API key with "Usage" permissions
170
+ 3. Open Settings > Advanced > Transcription Service
171
+ 4. Enter your OpenAI API key
172
+
173
+ OpenAI usage is billed to your own API account.
174
+
175
+ ### AI-Enhanced Analysis (Optional)
176
+
177
+ Add your Anthropic API key for Claude-powered document analysis:
178
+
179
+ 1. Get an API key at [console.anthropic.com](https://console.anthropic.com/)
180
+ 2. Open Settings > Advanced > AI Analysis
181
+ 3. Enter your Anthropic API key
182
+
183
+ Claude analyzes your transcript alongside screenshots to produce an intelligent document -- grouping related feedback, identifying patterns, and writing actionable summaries.
184
+
185
+ ### Settings Overview
186
+
187
+ | Category | Setting | Description |
188
+ |----------|---------|-------------|
189
+ | **General** | Output Directory | Where sessions are saved |
190
+ | | Launch at Login | Start markupr on system boot |
191
+ | **Recording** | Countdown | 0, 3, or 5 second countdown before recording |
192
+ | | Transcription Preview | Show live transcription overlay |
193
+ | | Audio Waveform | Visual audio level feedback |
194
+ | **Capture** | Pause Threshold | Voice pause duration before screenshot (500-3000ms) |
195
+ | | Min Time Between | Minimum gap between screenshots |
196
+ | **Appearance** | Theme | Dark, Light, or System |
197
+ | | Accent Color | Customize UI accent color |
198
+ | **Hotkeys** | Toggle Recording | Default: `Cmd/Ctrl+Shift+F` |
199
+ | | Manual Screenshot | Default: `Cmd/Ctrl+Shift+S` |
200
+
201
+ ## Usage
202
+
203
+ ### Basic Workflow
204
+
205
+ 1. **Start Recording**: Press `Cmd+Shift+F` (macOS) or `Ctrl+Shift+F` (Windows)
206
+ 2. **Select Source**: Choose which screen or window to capture
207
+ 3. **Narrate**: Speak naturally about what you see
208
+ 4. **Screenshots**: Captured automatically during pauses (or press `Cmd+Shift+S` manually)
209
+ 5. **Stop Recording**: Press the hotkey again
210
+ 6. **Post-Processing**: Pipeline automatically transcribes, analyzes, extracts frames, and generates output
211
+ 7. **Use Output**: File path is on your clipboard -- paste into your AI tool
212
+
213
+ ### Recording Tips
214
+
215
+ - **Speak naturally** -- markupr detects pauses to time screenshots
216
+ - **Pause briefly** when you want a screenshot captured
217
+ - **Use manual capture** (`Cmd+Shift+S`) for precise timing
218
+ - **Review before export** to remove unwanted items
219
+
220
+ ### Using with AI Coding Agents
221
+
222
+ After a session completes, the file path is on your clipboard. Paste it into:
223
+
224
+ - **Claude Code**: `Read the feedback session at [paste path]`
225
+ - **Cursor/Windsurf**: Reference the file path in your prompt
226
+ - **GitHub Issues**: Copy the Markdown content directly
227
+
228
+ ### AI Agent Setup
229
+
230
+ For coding agents, use the one-liner from repo root:
231
+
232
+ ```bash
233
+ npm run setup:markupr
234
+ ```
235
+
236
+ Detailed agent setup notes are in [`docs/AI_AGENT_QUICKSTART.md`](docs/AI_AGENT_QUICKSTART.md).
237
+
238
+ ### Session Output
239
+
240
+ Sessions are saved to an organized folder:
241
+
242
+ ```
243
+ ~/markupr/sessions/2026-02-05_14-23-41/
244
+ feedback-report.md # Structured Markdown with inline screenshots
245
+ metadata.json # Session metadata (source, duration, environment)
246
+ screenshots/
247
+ fb-001.png # Extracted frames from key moments
248
+ fb-002.png
249
+ fb-003.png
250
+ session-recording.webm # Full screen recording (optional)
251
+ ```
252
+
253
+ ## Keyboard Shortcuts
254
+
255
+ ### Recording
256
+
257
+ | Action | macOS | Windows/Linux |
258
+ |--------|-------|---------------|
259
+ | Start/Stop Recording | `Cmd+Shift+F` | `Ctrl+Shift+F` |
260
+ | Manual Screenshot | `Cmd+Shift+S` | `Ctrl+Shift+S` |
261
+ | Pause/Resume | `Cmd+Shift+P` | `Ctrl+Shift+P` |
262
+
263
+ ### Navigation
264
+
265
+ | Action | macOS | Windows/Linux |
266
+ |--------|-------|---------------|
267
+ | Open Settings | `Cmd+,` | `Ctrl+,` |
268
+ | Session History | `Cmd+H` | `Ctrl+H` |
269
+ | Keyboard Shortcuts | `Cmd+/` | `Ctrl+/` |
270
+ | Close Dialog | `Escape` | `Escape` |
271
+
272
+ ### Editing
273
+
274
+ | Action | macOS | Windows/Linux |
275
+ |--------|-------|---------------|
276
+ | Delete Selected | `Backspace` | `Delete` |
277
+ | Edit Item | `Enter` | `Enter` |
278
+ | Move Up | `Cmd+Up` | `Ctrl+Up` |
279
+ | Move Down | `Cmd+Down` | `Ctrl+Down` |
280
+ | Undo | `Cmd+Z` | `Ctrl+Z` |
281
+ | Redo | `Cmd+Shift+Z` | `Ctrl+Shift+Z` |
282
+ | Select All | `Cmd+A` | `Ctrl+A` |
283
+
284
+ ### Annotation Tools
285
+
286
+ | Tool | Shortcut |
287
+ |------|----------|
288
+ | Arrow | `1` |
289
+ | Circle | `2` |
290
+ | Rectangle | `3` |
291
+ | Freehand | `4` |
292
+ | Text | `5` |
293
+ | Clear Annotations | `Cmd/Ctrl+Backspace` |
294
+
295
+ ## Export Formats
296
+
297
+ ### Markdown (.md)
298
+
299
+ AI-optimized format inspired by [llms.txt](https://llms.txt). Includes:
300
+
301
+ - Structured headings with timestamps
302
+ - Feedback items with categories and severity
303
+ - Inline screenshot references
304
+ - Summary table with session metadata
305
+
306
+ ```markdown
307
+ # Feedback Report: My App
308
+
309
+ ## Summary
310
+ - **Duration**: 2m 34s
311
+ - **Items**: 5 feedback points
312
+ - **Screenshots**: 3 captured
313
+
314
+ ## Feedback Items
315
+
316
+ ### FB-001: Login button not visible
317
+ **Timestamp**: 00:15 | **Type**: Bug
318
+
319
+ > The login button is hidden behind the header on mobile viewport...
320
+
321
+ ![Screenshot](./screenshots/fb-001.png)
322
+ ```
323
+
324
+ ### PDF (.pdf)
325
+
326
+ Professional document with embedded screenshots, print-ready layout, and theme support.
327
+
328
+ ### HTML (.html)
329
+
330
+ Self-contained web page with embedded images, dark/light theme toggle, and mobile responsive design.
331
+
332
+ ### JSON (.json)
333
+
334
+ Machine-readable format for integrations and automation.
335
+
336
+ ## Architecture
337
+
338
+ ```
339
+ markupr/
340
+ ├── src/
341
+ │ ├── main/ # Electron main process
342
+ │ │ ├── index.ts # Entry point, orchestration
343
+ │ │ ├── SessionController # 7-state FSM with watchdog
344
+ │ │ ├── CrashRecovery # Auto-save and crash detection
345
+ │ │ ├── ai/ # Claude AI analysis pipeline
346
+ │ │ ├── audio/ # Audio capture and VAD
347
+ │ │ ├── capture/ # Screen capture services
348
+ │ │ ├── output/ # Document generation (MD, PDF, HTML, JSON)
349
+ │ │ ├── pipeline/ # Post-processing (transcribe → analyze → extract → generate)
350
+ │ │ ├── settings/ # Settings with secure API key storage
351
+ │ │ ├── transcription/ # Whisper + tier management
352
+ │ │ └── windows/ # Window management (popover, taskbar)
353
+ │ ├── renderer/ # React UI
354
+ │ │ ├── App.tsx # Main component
355
+ │ │ ├── components/ # UI components (30+)
356
+ │ │ ├── audio/ # Renderer-side audio bridge
357
+ │ │ ├── capture/ # Renderer-side screen recording
358
+ │ │ └── hooks/ # React hooks (theme, animation)
359
+ │ ├── preload/ # Electron preload (secure IPC bridge)
360
+ │ └── shared/ # Shared types and constants
361
+ ├── tests/ # Test suite (356 tests)
362
+ ├── docs/ # Documentation
363
+ ├── site/ # Landing page
364
+ └── package.json
365
+ ```
366
+
367
+ ## Development
368
+
369
+ ### Prerequisites
370
+
371
+ - Node.js 18+
372
+ - npm 9+
373
+ - macOS, Windows, or Linux
374
+
375
+ ### Setup
376
+
377
+ ```bash
378
+ # Clone the repository
379
+ git clone https://github.com/eddiesanjuan/markupr.git
380
+ cd markupr
381
+ ```
382
+
383
+ Use either npm or bun:
384
+
385
+ ```bash
386
+ # npm
387
+ npm install
388
+
389
+ # Start development mode
390
+ npm run dev
391
+ ```
392
+
393
+ ```bash
394
+ # bun
395
+ bun install
396
+
397
+ # Start development mode
398
+ bun run dev
399
+ ```
400
+
401
+ ### Scripts
402
+
403
+ | Script | Description |
404
+ |--------|-------------|
405
+ | `npm run dev` | Start in development mode with hot reload |
406
+ | `npm run build` | Build for production |
407
+ | `npm run build:desktop` | Build desktop app only |
408
+ | `npm run package` | Package for current platform |
409
+ | `npm run package:mac` | Package for macOS |
410
+ | `npm run package:win` | Package for Windows |
411
+ | `npm run package:linux` | Package for Linux |
412
+ | `npm test` | Run all tests |
413
+ | `npm run test:unit` | Run unit tests only |
414
+ | `npm run test:watch` | Run tests in watch mode |
415
+ | `npm run lint` | Lint code |
416
+ | `npm run lint:fix` | Auto-fix lint issues |
417
+ | `npm run typecheck` | TypeScript type checking |
418
+
419
+ You can run the same scripts with bun (`bun run dev`, `bun run test`, etc.).
420
+
421
+ ### Running Tests
422
+
423
+ ```bash
424
+ # Run all tests
425
+ npm test
426
+
427
+ # Run with coverage
428
+ npm run test:coverage
429
+
430
+ # Run specific test file
431
+ npx vitest tests/unit/postProcessor.test.ts
432
+ ```
433
+
434
+ ## Contributing
435
+
436
+ We welcome contributions! markupr is MIT licensed and community-driven.
437
+
438
+ ### Quick Start for Contributors
439
+
440
+ 1. Fork the repository
441
+ 2. Create a feature branch: `git checkout -b feature/amazing-feature`
442
+ 3. Make your changes
443
+ 4. Run tests: `npm test`
444
+ 5. Run lint: `npm run lint`
445
+ 6. Commit: `git commit -m 'Add amazing feature'`
446
+ 7. Push: `git push origin feature/amazing-feature`
447
+ 8. Open a Pull Request
448
+
449
+ ### Guidelines
450
+
451
+ - **Tests required** for new functionality
452
+ - **Lint clean** -- run `npm run lint` before submitting
453
+ - **TypeScript strict** -- run `npm run typecheck`
454
+ - **Small PRs preferred** -- focused changes are easier to review
455
+ - **Follow existing patterns** -- check CLAUDE.md for architecture details
456
+
457
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for full guidelines.
458
+
459
+ ## Troubleshooting
460
+
461
+ ### Common Issues
462
+
463
+ **Microphone not detected**
464
+ - Check System Preferences > Security & Privacy > Microphone
465
+ - Grant markupr microphone access
466
+
467
+ **Screen recording permission denied**
468
+ - macOS: System Preferences > Security & Privacy > Screen Recording
469
+ - Restart markupr after granting permission
470
+
471
+ **Whisper model download failing**
472
+ - Check your internet connection
473
+ - Try a smaller model first (tiny: ~75MB)
474
+ - Downloads support resume if interrupted
475
+
476
+ **OpenAI API connection failed**
477
+ - Verify your API key is correct
478
+ - Check your internet connection
479
+ - Ensure your OpenAI project has billing enabled
480
+
481
+ **Hotkeys not working**
482
+ - Check for conflicts with other applications
483
+ - Try customizing hotkeys in Settings > Hotkeys
484
+
485
+ **ffmpeg not found for frame extraction**
486
+ - Install ffmpeg: `brew install ffmpeg` (macOS) or download from [ffmpeg.org](https://ffmpeg.org/)
487
+ - markupr gracefully degrades to transcript-only output without ffmpeg
488
+
489
+ See [docs/TROUBLESHOOTING.md](docs/TROUBLESHOOTING.md) for more solutions.
490
+
491
+ ## Support markupr
492
+
493
+ If markupr is useful in your workflow and you want to keep it improving quickly:
494
+
495
+ - [Support on Ko-fi](https://ko-fi.com/eddiesanjuan)
496
+ - Share the project with a teammate who writes bug reports
497
+ - Open issues with reproducible feedback sessions so fixes land faster
498
+
499
+ ## License
500
+
501
+ MIT License - see [LICENSE](LICENSE) for details.
502
+
503
+ ## Acknowledgments
504
+
505
+ - [Whisper](https://github.com/openai/whisper) for local speech recognition
506
+ - [Anthropic Claude](https://anthropic.com) for AI-enhanced document analysis
507
+ - [OpenAI](https://platform.openai.com) for cloud transcription
508
+ - [Electron](https://electronjs.org) for cross-platform desktop framework
509
+ - [React](https://reactjs.org) for the UI framework
510
+ - [Vite](https://vitejs.dev) for blazing fast builds
511
+
512
+ ---
513
+
514
+ <p align="center">
515
+ Built by <a href="https://github.com/eddiesanjuan">Eddie San Juan</a>. Open source. MIT licensed.<br>
516
+ <a href="https://ko-fi.com/eddiesanjuan">Support markupr on Ko-fi</a>
517
+ </p>
package/SECURITY.md ADDED
@@ -0,0 +1,51 @@
1
+ # Security Policy
2
+
3
+ ## Reporting a Vulnerability
4
+
5
+ **DO NOT create public GitHub issues for security vulnerabilities.**
6
+
7
+ Email: **security@markupr.app**
8
+
9
+ Alternatively, use GitHub's private vulnerability reporting feature.
10
+
11
+ ### What to Include
12
+
13
+ - Description of the vulnerability
14
+ - Steps to reproduce
15
+ - Potential impact
16
+ - Suggested fix (if any)
17
+
18
+ ### Response Timeline
19
+
20
+ - **Acknowledgment**: Within 48 hours
21
+ - **Initial Assessment**: Within 7 days
22
+ - **Fix Target**: Within 30 days for critical issues
23
+ - **Public Disclosure**: 90 days after report (coordinated disclosure)
24
+
25
+ ### Scope
26
+
27
+ In scope:
28
+ - Remote code execution
29
+ - Data exfiltration (audio, screenshots, transcriptions)
30
+ - Privilege escalation
31
+ - Authentication bypass
32
+ - API key exposure
33
+ - Clipboard injection attacks
34
+
35
+ Out of scope:
36
+ - Social engineering attacks
37
+ - Physical access attacks
38
+ - Issues in dependencies (report upstream)
39
+
40
+ ### Safe Harbor
41
+
42
+ We will not take legal action against researchers who:
43
+ - Act in good faith
44
+ - Avoid privacy violations
45
+ - Do not exploit vulnerabilities beyond proof-of-concept
46
+ - Report vulnerabilities promptly
47
+ - Allow 90 days before public disclosure
48
+
49
+ ### Recognition
50
+
51
+ Responsible disclosures may be credited in release notes (opt-in).