An open-source native macOS screenshot and screen recording app. A CleanShot X alternative.
This report summarizes scanner evidence for duongductrong/Snapzy, a Swift project with 3,466 GitHub stars. SynthScan examined 254,201 lines of code across 922 source files, recording 283 pattern matches distributed across 9 syntactic categories. The legacy adjusted pattern signal is 1.8 (Low pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Payload schema: 1.0.0 · Engine: 2.0.0 · Scoring: heuristic-density-v1 · Scan date: 2026-10-31.
Can maintainers explain intent, assumptions, and trade-offs? 231 finding(s).
Are imports declared and package/API names verified? 2 finding(s).
Are wrappers, guards, and repeated structures necessary? 50 finding(s).
Which changes need focused human review? 283 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 283 distinct pattern matches across 9 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | uninstall.sh | 1 | #!/usr/bin/env bash | COMMENT |
| LOW | uninstall.sh | 101 | # Once the .app is deleted, LaunchServices can no longer resolve the | COMMENT |
| LOW | install.sh | 1 | #!/usr/bin/env bash | COMMENT |
| LOW | install.sh | 141 | COMMENT | |
| LOW | …s/Features/Annotate/AnnotateViewportUIStateTests.swift | 1 | // | COMMENT |
| LOW | …eatures/Annotate/AnnotateCanvasPresetActionTests.swift | 1 | // | COMMENT |
| LOW | SnapzyTests/Features/Annotate/AnnotateMockupTests.swift | 1 | // | COMMENT |
| LOW | …ests/Features/Annotate/AnnotateTextSnappingTests.swift | 1 | // | COMMENT |
| LOW | …atures/Annotate/AnnotateBackgroundRedactionTests.swift | 1 | // | COMMENT |
| LOW | …pzyTests/Features/Annotate/AnnotateImageOpsTests.swift | 1 | // | COMMENT |
| LOW | SnapzyTests/Features/Annotate/AnnotateCropTests.swift | 1 | // | COMMENT |
| LOW | …Tests/Features/Annotate/AnnotateTextEditingTests.swift | 1 | // | COMMENT |
| LOW | …/Features/Annotate/AnnotateSelectionEditingTests.swift | 1 | // | COMMENT |
| LOW | SnapzyTests/Helpers/CITestGate.swift | 1 | // | COMMENT |
| LOW | …Capture/AreaSelectionOverlayOffscreenCursorTests.swift | 1 | // | COMMENT |
| LOW | …ervices/Capture/Issue690InputLockRegressionTests.swift | 1 | // | COMMENT |
| LOW | …AreaSelectionLivePassthroughWindowDetectionTests.swift | 1 | // | COMMENT |
| LOW | …es/Capture/AreaSelectionOverlayLumaSamplingTests.swift | 1 | // | COMMENT |
| LOW | …ces/Capture/SingleFrameStreamCaptureSessionTests.swift | 1 | // | COMMENT |
| LOW | …ure/AreaSelectionMultiMonitorReconciliationTests.swift | 1 | // | COMMENT |
| LOW | …ure/AreaSelectionMultiMonitorReconciliationTests.swift | 21 | /// `setSelectionEnabled(_:)`. The controller's authoritative `selectionEnabled(for:)` is: | COMMENT |
| LOW | …ure/AreaSelectionMultiMonitorReconciliationTests.swift | 41 | /// `reconcileSelectionEnabledAcrossPooledWindows()` iterates ALL of `windowPool` regardless of which | COMMENT |
| LOW | …ure/AreaSelectionMultiMonitorReconciliationTests.swift | 81 | realWindow.overlayView.setSelectionEnabled(true) | COMMENT |
| LOW | …yTests/Services/Capture/CaptureOutputNamingTests.swift | 561 | /// adopts the user's locale renders the Buddhist year under a Thai (`th_TH`) | COMMENT |
| LOW | …yTests/Services/Capture/CaptureOutputNamingTests.swift | 641 | /// Pins the narrower contract of the calendar-only fix: a Gregorian calendar | COMMENT |
| LOW | …ts/Services/Capture/BackgroundCursorControlTests.swift | 1 | // | COMMENT |
| LOW | …Capture/AreaSelectionCaptureCoordinateSpaceTests.swift | 1 | // | COMMENT |
| LOW | …Capture/AreaSelectionCaptureCoordinateSpaceTests.swift | 41 | COMMENT | |
| LOW | …apture/AreaSelectionLivePassthroughKeyboardTests.swift | 1 | // | COMMENT |
| LOW | …ests/Services/Capture/ScreenCaptureAreaCropTests.swift | 1 | // | COMMENT |
| LOW | …vices/Capture/AreaSelectionHoverPerformanceTests.swift | 1 | // | COMMENT |
| LOW | …reaSelectionOverlayPassthroughStaleLocationTests.swift | 1 | // | COMMENT |
| LOW | …ortcuts/RecordingSessionShortcutObservationTests.swift | 1 | // | COMMENT |
| LOW | …sts/Services/Shortcuts/HotkeyUnregistrationTests.swift | 1 | // | COMMENT |
| LOW | …es/Shortcuts/RecordingSessionShortcutGatingTests.swift | 1 | // | COMMENT |
| LOW | Snapzy/App/MenuBarItemKind.swift | 1 | // | COMMENT |
| LOW | Snapzy/App/SnapzyApp.swift | 421 | /// Called when the user opens one or more image files with Snapzy from | COMMENT |
| LOW | Snapzy/Features/Capture/OCRResultNotifier.swift | 1 | // | COMMENT |
| LOW | Snapzy/Features/Capture/CaptureViewModel.swift | 1461 | /// snapshot leaves out `CaptureChromeWindowRegistry` windows by ID — the same | COMMENT |
| LOW | …tures/Preferences/Models/PreferencesSearchEngine.swift | 1 | // | COMMENT |
| LOW | …references/Components/PreferencesAnnotatePreview.swift | 1 | // | COMMENT |
| LOW | Snapzy/Features/VideoEditor/VideoEditorState.swift | 1201 | } | COMMENT |
| LOW | …VideoEditor/Managers/VideoEditorWindowController.swift | 1 | // | COMMENT |
| LOW | …tures/VideoEditor/Models/VideoEditorTimelineClip.swift | 1 | // | COMMENT |
| LOW | …s/VideoEditor/Models/VideoEditorTimelineViewport.swift | 1 | // | COMMENT |
| LOW | …atures/VideoEditor/Models/VideoEditorSessionData.swift | 1 | // | COMMENT |
| LOW | …tures/VideoEditor/Models/VideoEditorSpeedSegment.swift | 1 | // | COMMENT |
| LOW | …oEditor/Components/VideoEditorSettingsPillButton.swift | 1 | // | COMMENT |
| LOW | …itor/Components/VideoEditorTimelineScrollCatcher.swift | 1 | // | COMMENT |
| LOW | …/VideoEditor/Components/VideoEditorTimelineRuler.swift | 1 | // | COMMENT |
| LOW | …/VideoEditor/Components/VideoEditorClipStripView.swift | 61 | let fromIndex: Int | COMMENT |
| LOW | …/VideoEditor/Components/VideoEditorSegmentChrome.swift | 1 | // | COMMENT |
| LOW | …ditor/Components/VideoEditorTimelineZoomControls.swift | 1 | // | COMMENT |
| LOW | …oEditor/Components/VideoEditorSpeedTimelineTrack.swift | 1 | // | COMMENT |
| LOW | …itor/Components/VideoEditorExportProgressOverlay.swift | 1 | // | COMMENT |
| LOW | …VideoEditor/Components/VideoEditorEmptyStateView.swift | 1 | // | COMMENT |
| LOW | …/VideoEditor/Services/VideoEditorTimelineTimeMap.swift | 1 | // | COMMENT |
| LOW | …tures/Recording/Components/RecordingWaveformView.swift | 1 | // | COMMENT |
| LOW | …ures/Recording/Components/RecordingStatusBarView.swift | 1 | // | COMMENT |
| LOW | …zy/Features/Annotate/InlineAreaMagnifierHostView.swift | 1 | // | COMMENT |
| 115 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | uninstall.sh | 30 | # ─── Auto-detect bundle ID from app name ───────────────────────── | COMMENT |
| MEDIUM | uninstall.sh | 69 | # ─── Confirmation ──────────────────────────────────────────────── | COMMENT |
| MEDIUM | uninstall.sh | 93 | # ─── 1. Kill running app ──────────────────────────────────────── | COMMENT |
| MEDIUM | uninstall.sh | 98 | # ─── 2. Reset ALL TCC permissions ─────────────────────────────── | COMMENT |
| MEDIUM | uninstall.sh | 158 | # ─── 3. Remove app bundle ─────────────────────────────────────── | COMMENT |
| MEDIUM | uninstall.sh | 186 | # ─── 4. Remove Application Support data ───────────────────────── | COMMENT |
| MEDIUM | uninstall.sh | 209 | # ─── 5. Remove user preferences (defaults) ────────────────────── | COMMENT |
| MEDIUM | uninstall.sh | 220 | # ─── 6. Remove caches ─────────────────────────────────────────── | COMMENT |
| MEDIUM | uninstall.sh | 232 | # ─── 7. Remove saved application state ────────────────────────── | COMMENT |
| MEDIUM | uninstall.sh | 240 | # ─── 8. Remove Sparkle update data ────────────────────────────── | COMMENT |
| MEDIUM | uninstall.sh | 254 | # ─── 9. Login items ───────────────────────────────────────────── | COMMENT |
| MEDIUM | uninstall.sh | 259 | # ─── 10. Clean temp files ────────────────────────────────────── | COMMENT |
| MEDIUM | uninstall.sh | 271 | # ─── 11. Sandbox containers ───────────────────────────────────── | COMMENT |
| MEDIUM | uninstall.sh | 283 | # ─── Done ──────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | install.sh | 14 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | install.sh | 16 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | install.sh | 38 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | install.sh | 40 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | install.sh | 48 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | install.sh | 50 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | install.sh | 71 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | install.sh | 73 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | install.sh | 86 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | install.sh | 88 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | install.sh | 115 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | install.sh | 117 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | install.sh | 142 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | install.sh | 144 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | install.sh | 146 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | install.sh | 151 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | reset-permissions.sh | 15 | # ─── Auto-detect bundle ID from app name ───────────────────────── | COMMENT |
| MEDIUM | reset-permissions.sh | 39 | # ─── Resolve installed app version ─────────────────────────────── | COMMENT |
| MEDIUM | reset-permissions.sh | 103 | # ─── Confirmation ──────────────────────────────────────────────── | COMMENT |
| MEDIUM | reset-permissions.sh | 126 | # ─── 1. Kill running app ──────────────────────────────────────── | COMMENT |
| MEDIUM | reset-permissions.sh | 131 | # ─── 2. Reset ALL TCC permissions ─────────────────────────────── | COMMENT |
| MEDIUM | reset-permissions.sh | 173 | # ─── Done ──────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | scripts/test-update-local.sh | 45 | # ─── Helpers ──────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | scripts/test-update-local.sh | 427 | # ─── Commands ─────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | scripts/test-update-local.sh | 543 | # ─── Main ─────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | .github/workflows/release-notify.yml | 9 | # ────────────────────────────────────────────── | COMMENT |
| MEDIUM | .github/workflows/release-notify.yml | 11 | # ────────────────────────────────────────────── | COMMENT |
| MEDIUM | .github/workflows/release-notify.yml | 57 | # ────────────────────────────────────────────── | COMMENT |
| MEDIUM | .github/workflows/release-notify.yml | 59 | # ────────────────────────────────────────────── | COMMENT |
| MEDIUM | .github/workflows/release-notify.yml | 132 | # ────────────────────────────────────────────── | COMMENT |
| MEDIUM | .github/workflows/release-notify.yml | 165 | # ────────────────────────────────────────────── | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | docs/SELF_SIGNED_CERT.md | 38 | # Step 1: Generate cert and import into login keychain | COMMENT |
| LOW⚡ | docs/SELF_SIGNED_CERT.md | 41 | # Step 2: Build, sign with self-signed cert, install as v1 | COMMENT |
| LOW⚡ | docs/SELF_SIGNED_CERT.md | 45 | # Step 3: Re-sign and replace (simulates Sparkle update) | COMMENT |
| LOW⚡ | …atures/Annotate/Components/AnnotateBottomBarView.swift | 572 | // Step 1: Render flattened image with annotations BEFORE uploading | COMMENT |
| LOW⚡ | …atures/Annotate/Components/AnnotateBottomBarView.swift | 576 | // Step 2: Decide the upload target. Manual combine sessions must NOT overwrite the | COMMENT |
| LOW⚡ | Snapzy/Features/Onboarding/SnapzyOnboardingState.swift | 75 | // Step 1: Capture > Quick Access > Annotate Lifecycle State | COMMENT |
| LOW⚡ | Snapzy/Features/Onboarding/SnapzyOnboardingState.swift | 83 | // Step 2: Screen Recording & Video Editor Lifecycle State | COMMENT |
| LOW⚡ | Snapzy/Features/Onboarding/SnapzyOnboardingState.swift | 93 | // Step 3: Shortcuts & Config Mock State | COMMENT |
| LOW | Snapzy/Shared/Localization/L10n.swift | 1902 | /// Step 1: Capture | COMMENT |
| LOW | Snapzy/Shared/Localization/L10n.swift | 1944 | /// Step 2: Recording | COMMENT |
| LOW | Snapzy/Shared/Localization/L10n.swift | 1995 | /// Step 3: Shortcuts | COMMENT |
| LOW | Snapzy/Shared/Localization/L10n.swift | 2027 | /// Step 4: Permissions | COMMENT |
| LOW | Snapzy/Services/Cloud/GoogleDriveCloudProvider.swift | 342 | // Step 1: Initiate session | COMMENT |
| LOW | Snapzy/Services/Cloud/GoogleDriveCloudProvider.swift | 377 | // Step 2: Upload chunks | COMMENT |
| LOW⚡ | scripts/dry-run-release.sh | 35 | # Step 1: Requirements Check | COMMENT |
| LOW⚡ | scripts/dry-run-release.sh | 45 | # Step 2: Build Release Archive (Unsigned) | COMMENT |
| LOW⚡ | scripts/dry-run-release.sh | 57 | # Step 3: Ditto from archive | COMMENT |
| LOW⚡ | scripts/dry-run-release.sh | 65 | # Step 4: Dry-Run Codesigning (using Ad-hoc identity "-" to test the CI pipeline structure) | COMMENT |
| LOW | scripts/dry-run-release.sh | 125 | # Step 5: Verify App Bundle | COMMENT |
| LOW | scripts/dry-run-release.sh | 138 | # Step 6: Create DMG (optional preview) | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | …atures/Annotate/Components/AnnotateBottomBarView.swift | 572 | // Step 1: Render flattened image with annotations BEFORE uploading | COMMENT |
| LOW⚡ | …atures/Annotate/Components/AnnotateBottomBarView.swift | 576 | // Step 2: Decide the upload target. Manual combine sessions must NOT overwrite the | COMMENT |
| LOW⚡ | Snapzy/Features/Onboarding/SnapzyOnboardingState.swift | 75 | // Step 1: Capture > Quick Access > Annotate Lifecycle State | COMMENT |
| LOW⚡ | Snapzy/Features/Onboarding/SnapzyOnboardingState.swift | 83 | // Step 2: Screen Recording & Video Editor Lifecycle State | COMMENT |
| LOW⚡ | Snapzy/Features/Onboarding/SnapzyOnboardingState.swift | 93 | // Step 3: Shortcuts & Config Mock State | COMMENT |
| LOW | Snapzy/Shared/Localization/L10n.swift | 1902 | /// Step 1: Capture | COMMENT |
| LOW | Snapzy/Shared/Localization/L10n.swift | 1944 | /// Step 2: Recording | COMMENT |
| LOW | Snapzy/Shared/Localization/L10n.swift | 1995 | /// Step 3: Shortcuts | COMMENT |
| LOW | Snapzy/Shared/Localization/L10n.swift | 2027 | /// Step 4: Permissions | COMMENT |
| LOW | Snapzy/Services/Cloud/GoogleDriveCloudProvider.swift | 342 | // Step 1: Initiate session | COMMENT |
| LOW | Snapzy/Services/Cloud/GoogleDriveCloudProvider.swift | 377 | // Step 2: Upload chunks | COMMENT |
| LOW⚡ | scripts/dry-run-release.sh | 35 | # Step 1: Requirements Check | COMMENT |
| LOW⚡ | scripts/dry-run-release.sh | 45 | # Step 2: Build Release Archive (Unsigned) | COMMENT |
| LOW⚡ | scripts/dry-run-release.sh | 57 | # Step 3: Ditto from archive | COMMENT |
| LOW⚡ | scripts/dry-run-release.sh | 65 | # Step 4: Dry-Run Codesigning (using Ad-hoc identity "-" to test the CI pipeline structure) | COMMENT |
| LOW | scripts/dry-run-release.sh | 125 | # Step 5: Verify App Bundle | COMMENT |
| LOW | scripts/dry-run-release.sh | 138 | # Step 6: Create DMG (optional preview) | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | …zyTests/Services/Capture/AXElementInspectorTests.swift | 19 | // is robust against unusual NSScreen.screens orderings on CI. | COMMENT |
| MEDIUM | …s/Components/PreferencesQuickAccessSwipeZoneView.swift | 125 | // End the line exactly at the arrow head center for seamless joint | COMMENT |
| MEDIUM | Snapzy/Features/Splash/SplashOnboardingRootView.swift | 67 | // Stable opaque base — extends behind titlebar for seamless look | COMMENT |
| MEDIUM | Snapzy/Features/Annotate/AnnotateState.swift | 1292 | /// - displayPadding: The padding in display coordinates (already scaled) - unused for seamless alignment | COMMENT |
| MEDIUM | …ures/Annotate/Components/AnnotateCropOverlayView.swift | 193 | /// Use canvas background color for seamless masking | COMMENT |
| MEDIUM | Snapzy/Services/Capture/AreaSelectionWindow.swift | 651 | // Observe space changes and activation to keep selection session robust | COMMENT |
| MEDIUM | …swift-tools/video-editor-performance/assemble-probe.py | 45 | chunks.append(f"#sourceLocation(file: {json.dumps(str(harness))}, line: 1)\n{harness.read_text()}\n#sourceLocation() | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | uninstall.sh | 4 | # Usage: | COMMENT |
| LOW⚡ | install.sh | 4 | # Usage: | COMMENT |
| LOW | reset-permissions.sh | 4 | # Usage: | COMMENT |
| LOW | scripts/test-update-local.sh | 11 | # Usage: | COMMENT |
| LOW | scripts/run-tests.sh | 4 | # Usage: | COMMENT |
| LOW | scripts/run-ocr-readme-benchmark.sh | 4 | # Usage: | COMMENT |
| LOW | scripts/run-scrolling-capture-accuracy-benchmark.sh | 4 | # Usage: | COMMENT |
| LOW | scripts/test-tcc-local.sh | 4 | # Usage: | COMMENT |
| LOW | scripts/run-qr-detection-performance-probe.sh | 4 | # Usage: | COMMENT |
| LOW | scripts/lint-corner-radius.sh | 8 | # Usage: | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | scripts/generate_dmg_background.py | 24 | except Exception as e: | CODE |
| MEDIUM⚡ | scripts/generate_dmg_background.py | 25 | print(f"Error downloading bold font: {e}") | CODE |
| LOW⚡ | scripts/generate_dmg_background.py | 33 | except Exception as e: | CODE |
| MEDIUM⚡ | scripts/generate_dmg_background.py | 34 | print(f"Error downloading medium font: {e}") | CODE |
| LOW | scripts/generate_dmg_background.py | 60 | except Exception as e: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | scripts/test-dmg.sh | 5 | # Check if create-dmg is installed | COMMENT |
| LOW | .github/workflows/release-prepare.yml | 139 | # Check if previous tag exists | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | SnapzyTests/Features/Annotate/AnnotateCoreTests.swift | 339 | let text = "admin@example.com" | STRING |
| LOW | SnapzyTests/Features/Annotate/AnnotateCoreTests.swift | 358 | let matchRange = (text as NSString).range(of: "admin@example.com") | STRING |