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.
- package/.claude/commands/review-feedback.md +47 -0
- package/.eslintrc.json +35 -0
- package/.github/CODEOWNERS +16 -0
- package/.github/FUNDING.yml +1 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +56 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +54 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +89 -0
- package/.github/dependabot.yml +70 -0
- package/.github/workflows/ci.yml +184 -0
- package/.github/workflows/deploy-landing.yml +134 -0
- package/.github/workflows/nightly.yml +288 -0
- package/.github/workflows/release.yml +318 -0
- package/CHANGELOG.md +127 -0
- package/CLAUDE.md +137 -0
- package/CODE_OF_CONDUCT.md +9 -0
- package/CONTRIBUTING.md +390 -0
- package/LICENSE +21 -0
- package/PRODUCT_VISION.md +277 -0
- package/README.md +517 -0
- package/SECURITY.md +51 -0
- package/SIGNING_INSTRUCTIONS.md +284 -0
- package/assets/DMG_BACKGROUND_INSTRUCTIONS.md +130 -0
- package/assets/svg-source/dmg-background.svg +70 -0
- package/assets/svg-source/icon.svg +20 -0
- package/assets/svg-source/tray-icon-processing.svg +7 -0
- package/assets/svg-source/tray-icon-recording.svg +7 -0
- package/assets/svg-source/tray-icon.svg +6 -0
- package/assets/tray-complete.png +0 -0
- package/assets/tray-complete@2x.png +0 -0
- package/assets/tray-completeTemplate.png +0 -0
- package/assets/tray-completeTemplate@2x.png +0 -0
- package/assets/tray-error.png +0 -0
- package/assets/tray-error@2x.png +0 -0
- package/assets/tray-errorTemplate.png +0 -0
- package/assets/tray-errorTemplate@2x.png +0 -0
- package/assets/tray-icon-processing.png +0 -0
- package/assets/tray-icon-processing@2x.png +0 -0
- package/assets/tray-icon-processingTemplate.png +0 -0
- package/assets/tray-icon-processingTemplate@2x.png +0 -0
- package/assets/tray-icon-recording.png +0 -0
- package/assets/tray-icon-recording@2x.png +0 -0
- package/assets/tray-icon-recordingTemplate.png +0 -0
- package/assets/tray-icon-recordingTemplate@2x.png +0 -0
- package/assets/tray-icon.png +0 -0
- package/assets/tray-icon@2x.png +0 -0
- package/assets/tray-iconTemplate.png +0 -0
- package/assets/tray-iconTemplate@2x.png +0 -0
- package/assets/tray-idle.png +0 -0
- package/assets/tray-idle@2x.png +0 -0
- package/assets/tray-idleTemplate.png +0 -0
- package/assets/tray-idleTemplate@2x.png +0 -0
- package/assets/tray-processing-0.png +0 -0
- package/assets/tray-processing-0@2x.png +0 -0
- package/assets/tray-processing-0Template.png +0 -0
- package/assets/tray-processing-0Template@2x.png +0 -0
- package/assets/tray-processing-1.png +0 -0
- package/assets/tray-processing-1@2x.png +0 -0
- package/assets/tray-processing-1Template.png +0 -0
- package/assets/tray-processing-1Template@2x.png +0 -0
- package/assets/tray-processing-2.png +0 -0
- package/assets/tray-processing-2@2x.png +0 -0
- package/assets/tray-processing-2Template.png +0 -0
- package/assets/tray-processing-2Template@2x.png +0 -0
- package/assets/tray-processing-3.png +0 -0
- package/assets/tray-processing-3@2x.png +0 -0
- package/assets/tray-processing-3Template.png +0 -0
- package/assets/tray-processing-3Template@2x.png +0 -0
- package/assets/tray-processing.png +0 -0
- package/assets/tray-processing@2x.png +0 -0
- package/assets/tray-processingTemplate.png +0 -0
- package/assets/tray-processingTemplate@2x.png +0 -0
- package/assets/tray-recording.png +0 -0
- package/assets/tray-recording@2x.png +0 -0
- package/assets/tray-recordingTemplate.png +0 -0
- package/assets/tray-recordingTemplate@2x.png +0 -0
- package/build/DMG_BACKGROUND_SPEC.md +50 -0
- package/build/dmg-background.png +0 -0
- package/build/dmg-background@2x.png +0 -0
- package/build/entitlements.mac.inherit.plist +27 -0
- package/build/entitlements.mac.plist +41 -0
- package/build/favicon-16.png +0 -0
- package/build/favicon-180.png +0 -0
- package/build/favicon-192.png +0 -0
- package/build/favicon-32.png +0 -0
- package/build/favicon-48.png +0 -0
- package/build/favicon-512.png +0 -0
- package/build/favicon-64.png +0 -0
- package/build/icon-128.png +0 -0
- package/build/icon-16.png +0 -0
- package/build/icon-24.png +0 -0
- package/build/icon-256.png +0 -0
- package/build/icon-32.png +0 -0
- package/build/icon-48.png +0 -0
- package/build/icon-64.png +0 -0
- package/build/icon.icns +0 -0
- package/build/icon.ico +0 -0
- package/build/icon.iconset/icon_128x128.png +0 -0
- package/build/icon.iconset/icon_128x128@2x.png +0 -0
- package/build/icon.iconset/icon_16x16.png +0 -0
- package/build/icon.iconset/icon_16x16@2x.png +0 -0
- package/build/icon.iconset/icon_256x256.png +0 -0
- package/build/icon.iconset/icon_256x256@2x.png +0 -0
- package/build/icon.iconset/icon_32x32.png +0 -0
- package/build/icon.iconset/icon_32x32@2x.png +0 -0
- package/build/icon.iconset/icon_512x512.png +0 -0
- package/build/icon.iconset/icon_512x512@2x.png +0 -0
- package/build/icon.png +0 -0
- package/build/installer-header.bmp +0 -0
- package/build/installer-header.png +0 -0
- package/build/installer-sidebar.bmp +0 -0
- package/build/installer-sidebar.png +0 -0
- package/build/installer.nsh +45 -0
- package/build/overlay-processing.png +0 -0
- package/build/overlay-recording.png +0 -0
- package/build/toolbar-record.png +0 -0
- package/build/toolbar-screenshot.png +0 -0
- package/build/toolbar-settings.png +0 -0
- package/build/toolbar-stop.png +0 -0
- package/dist/main/index.mjs +12612 -0
- package/dist/preload/index.mjs +907 -0
- package/dist/renderer/assets/index-CCmUjl9K.js +19495 -0
- package/dist/renderer/assets/index-CUqz_Gs6.css +2270 -0
- package/dist/renderer/index.html +27 -0
- package/docs/AI_AGENT_QUICKSTART.md +42 -0
- package/docs/AI_PIPELINE_DESIGN.md +595 -0
- package/docs/API.md +514 -0
- package/docs/ARCHITECTURE.md +460 -0
- package/docs/CONFIGURATION.md +336 -0
- package/docs/DEVELOPMENT.md +508 -0
- package/docs/EXPORT_FORMATS.md +451 -0
- package/docs/GETTING_STARTED.md +236 -0
- package/docs/KEYBOARD_SHORTCUTS.md +334 -0
- package/docs/TROUBLESHOOTING.md +418 -0
- package/docs/landing/index.html +672 -0
- package/docs/landing/script.js +342 -0
- package/docs/landing/styles.css +1543 -0
- package/electron-builder.yml +140 -0
- package/electron.vite.config.ts +63 -0
- package/package.json +108 -0
- package/railway.json +12 -0
- package/scripts/build.mjs +51 -0
- package/scripts/generate-icons.mjs +314 -0
- package/scripts/generate-installer-images.cjs +253 -0
- package/scripts/generate-tray-icons.mjs +258 -0
- package/scripts/notarize.cjs +180 -0
- package/scripts/one-click-clean-test.sh +147 -0
- package/scripts/postinstall.mjs +36 -0
- package/scripts/setup-markupr.sh +55 -0
- package/setup +17 -0
- package/site/index.html +1835 -0
- package/site/package.json +11 -0
- package/site/railway.json +12 -0
- package/site/server.js +31 -0
- package/src/main/AutoUpdater.ts +392 -0
- package/src/main/CrashRecovery.ts +655 -0
- package/src/main/ErrorHandler.ts +703 -0
- package/src/main/HotkeyManager.ts +399 -0
- package/src/main/MenuManager.ts +529 -0
- package/src/main/PermissionManager.ts +420 -0
- package/src/main/SessionController.ts +1465 -0
- package/src/main/TrayManager.ts +540 -0
- package/src/main/ai/AIPipelineManager.ts +199 -0
- package/src/main/ai/ClaudeAnalyzer.ts +339 -0
- package/src/main/ai/ImageOptimizer.ts +176 -0
- package/src/main/ai/StructuredMarkdownBuilder.ts +379 -0
- package/src/main/ai/index.ts +16 -0
- package/src/main/ai/types.ts +258 -0
- package/src/main/analysis/ClarificationGenerator.ts +385 -0
- package/src/main/analysis/FeedbackAnalyzer.ts +531 -0
- package/src/main/analysis/index.ts +19 -0
- package/src/main/audio/AudioCapture.ts +978 -0
- package/src/main/audio/audioUtils.ts +100 -0
- package/src/main/audio/index.ts +20 -0
- package/src/main/capture/index.ts +1 -0
- package/src/main/index.ts +1693 -0
- package/src/main/ipc/captureHandlers.ts +272 -0
- package/src/main/ipc/index.ts +45 -0
- package/src/main/ipc/outputHandlers.ts +302 -0
- package/src/main/ipc/sessionHandlers.ts +56 -0
- package/src/main/ipc/settingsHandlers.ts +471 -0
- package/src/main/ipc/types.ts +56 -0
- package/src/main/ipc/windowHandlers.ts +277 -0
- package/src/main/output/ClipboardService.ts +369 -0
- package/src/main/output/ExportService.ts +539 -0
- package/src/main/output/FileManager.ts +416 -0
- package/src/main/output/MarkdownGenerator.ts +791 -0
- package/src/main/output/MarkdownPatcher.ts +299 -0
- package/src/main/output/index.ts +186 -0
- package/src/main/output/sessionAdapter.ts +207 -0
- package/src/main/output/templates/html-template.ts +553 -0
- package/src/main/pipeline/FrameExtractor.ts +330 -0
- package/src/main/pipeline/PostProcessor.ts +399 -0
- package/src/main/pipeline/TranscriptAnalyzer.ts +226 -0
- package/src/main/pipeline/index.ts +36 -0
- package/src/main/platform/WindowsTaskbar.ts +600 -0
- package/src/main/platform/index.ts +16 -0
- package/src/main/settings/SettingsManager.ts +730 -0
- package/src/main/settings/index.ts +19 -0
- package/src/main/transcription/ModelDownloadManager.ts +494 -0
- package/src/main/transcription/TierManager.ts +219 -0
- package/src/main/transcription/TranscriptionRecoveryService.ts +340 -0
- package/src/main/transcription/WhisperService.ts +748 -0
- package/src/main/transcription/index.ts +56 -0
- package/src/main/transcription/types.ts +135 -0
- package/src/main/windows/PopoverManager.ts +284 -0
- package/src/main/windows/TaskbarIntegration.ts +452 -0
- package/src/main/windows/index.ts +23 -0
- package/src/preload/index.ts +1047 -0
- package/src/renderer/App.tsx +515 -0
- package/src/renderer/AppWrapper.tsx +28 -0
- package/src/renderer/assets/logo-dark.svg +7 -0
- package/src/renderer/assets/logo.svg +7 -0
- package/src/renderer/audio/AudioCaptureRenderer.ts +454 -0
- package/src/renderer/capture/ScreenRecordingRenderer.ts +492 -0
- package/src/renderer/components/AnnotationOverlay.tsx +836 -0
- package/src/renderer/components/AudioWaveform.tsx +811 -0
- package/src/renderer/components/ClarificationQuestions.tsx +656 -0
- package/src/renderer/components/CountdownTimer.tsx +495 -0
- package/src/renderer/components/CrashRecoveryDialog.tsx +632 -0
- package/src/renderer/components/DonateButton.tsx +127 -0
- package/src/renderer/components/ErrorBoundary.tsx +308 -0
- package/src/renderer/components/ExportDialog.tsx +872 -0
- package/src/renderer/components/HotkeyHint.tsx +261 -0
- package/src/renderer/components/KeyboardShortcuts.tsx +787 -0
- package/src/renderer/components/ModelDownloadDialog.tsx +844 -0
- package/src/renderer/components/Onboarding.tsx +1830 -0
- package/src/renderer/components/ProcessingOverlay.tsx +157 -0
- package/src/renderer/components/RecordingOverlay.tsx +423 -0
- package/src/renderer/components/SessionHistory.tsx +1746 -0
- package/src/renderer/components/SessionReview.tsx +1321 -0
- package/src/renderer/components/SettingsPanel.tsx +217 -0
- package/src/renderer/components/Skeleton.tsx +347 -0
- package/src/renderer/components/StatusIndicator.tsx +86 -0
- package/src/renderer/components/ThemeProvider.tsx +429 -0
- package/src/renderer/components/Tooltip.tsx +370 -0
- package/src/renderer/components/TranscriptionPreview.tsx +183 -0
- package/src/renderer/components/TranscriptionTierSelector.tsx +640 -0
- package/src/renderer/components/UpdateNotification.tsx +377 -0
- package/src/renderer/components/WindowSelector.tsx +947 -0
- package/src/renderer/components/index.ts +99 -0
- package/src/renderer/components/primitives/ApiKeyInput.tsx +98 -0
- package/src/renderer/components/primitives/ColorPicker.tsx +65 -0
- package/src/renderer/components/primitives/DangerButton.tsx +45 -0
- package/src/renderer/components/primitives/DirectoryPicker.tsx +41 -0
- package/src/renderer/components/primitives/Dropdown.tsx +34 -0
- package/src/renderer/components/primitives/KeyRecorder.tsx +117 -0
- package/src/renderer/components/primitives/SettingsSection.tsx +32 -0
- package/src/renderer/components/primitives/Slider.tsx +43 -0
- package/src/renderer/components/primitives/Toggle.tsx +36 -0
- package/src/renderer/components/primitives/index.ts +10 -0
- package/src/renderer/components/settings/AdvancedTab.tsx +174 -0
- package/src/renderer/components/settings/AppearanceTab.tsx +77 -0
- package/src/renderer/components/settings/GeneralTab.tsx +40 -0
- package/src/renderer/components/settings/HotkeysTab.tsx +79 -0
- package/src/renderer/components/settings/RecordingTab.tsx +84 -0
- package/src/renderer/components/settings/index.ts +9 -0
- package/src/renderer/components/settings/settingsStyles.ts +673 -0
- package/src/renderer/components/settings/tabConfig.tsx +85 -0
- package/src/renderer/components/settings/useSettingsPanel.ts +447 -0
- package/src/renderer/contexts/ProcessingContext.tsx +227 -0
- package/src/renderer/contexts/RecordingContext.tsx +683 -0
- package/src/renderer/contexts/UIContext.tsx +326 -0
- package/src/renderer/contexts/index.ts +24 -0
- package/src/renderer/donateMessages.ts +69 -0
- package/src/renderer/hooks/index.ts +75 -0
- package/src/renderer/hooks/useAnimation.tsx +544 -0
- package/src/renderer/hooks/useTheme.ts +313 -0
- package/src/renderer/index.html +26 -0
- package/src/renderer/main.tsx +52 -0
- package/src/renderer/styles/animations.css +1093 -0
- package/src/renderer/styles/app-shell.css +662 -0
- package/src/renderer/styles/globals.css +515 -0
- package/src/renderer/styles/theme.ts +578 -0
- package/src/renderer/types/electron.d.ts +385 -0
- package/src/shared/hotkeys.ts +283 -0
- package/src/shared/types.ts +809 -0
- package/tests/clipboard.test.ts +228 -0
- package/tests/e2e/criticalPaths.test.ts +594 -0
- package/tests/feedbackAnalyzer.test.ts +303 -0
- package/tests/integration/sessionFlow.test.ts +583 -0
- package/tests/markdownGenerator.test.ts +418 -0
- package/tests/output.test.ts +96 -0
- package/tests/setup.ts +486 -0
- package/tests/unit/appIntegration.test.ts +676 -0
- package/tests/unit/appViewState.test.ts +281 -0
- package/tests/unit/audioIpcChannels.test.ts +17 -0
- package/tests/unit/exportService.test.ts +492 -0
- package/tests/unit/hotkeys.test.ts +92 -0
- package/tests/unit/navigationPreload.test.ts +94 -0
- package/tests/unit/onboardingFlow.test.ts +345 -0
- package/tests/unit/permissionManager.test.ts +175 -0
- package/tests/unit/permissionManagerExpanded.test.ts +296 -0
- package/tests/unit/screenRecordingRenderer.test.ts +368 -0
- package/tests/unit/sessionController.test.ts +515 -0
- package/tests/unit/tierManager.test.ts +61 -0
- package/tests/unit/tierManagerExpanded.test.ts +142 -0
- package/tests/unit/transcriptAnalyzer.test.ts +64 -0
- package/tsconfig.json +25 -0
- 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`.
|