RepoPilotOpen in app →

tw93/MiaoYan

⛷ Lightweight Markdown app to help you write great sentences.

Mixed

Single-maintainer risk — review before adopting

worst of 4 axes
Use as dependencyMixed

top contributor handles 96% of recent commits; no tests detected…

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 3d ago
  • 4 active contributors
  • MIT licensed
Show 4 more →
  • Small team — 4 contributors active in recent commits
  • Single-maintainer risk — top contributor 96% of recent commits
  • No CI workflows detected
  • No test directory detected
What would change the summary?
  • Use as dependency MixedHealthy if: diversify commit ownership (top <90%); add a test suite

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Forkable" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/tw93/miaoyan?axis=fork)](https://repopilot.app/r/tw93/miaoyan)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/tw93/miaoyan on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: tw93/MiaoYan

Generated by RepoPilot · 2026-05-10 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/tw93/MiaoYan shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Single-maintainer risk — review before adopting

  • Last commit 3d ago
  • 4 active contributors
  • MIT licensed
  • ⚠ Small team — 4 contributors active in recent commits
  • ⚠ Single-maintainer risk — top contributor 96% of recent commits
  • ⚠ No CI workflows detected
  • ⚠ No test directory detected

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live tw93/MiaoYan repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/tw93/MiaoYan.

What it runs against: a local clone of tw93/MiaoYan — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in tw93/MiaoYan | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch main exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 33 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>tw93/MiaoYan</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of tw93/MiaoYan. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/tw93/MiaoYan.git
#   cd MiaoYan
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of tw93/MiaoYan and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "tw93/MiaoYan(\\.git)?\\b" \\
  && ok "origin remote is tw93/MiaoYan" \\
  || miss "origin remote is not tw93/MiaoYan (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
  && ok "default branch main exists" \\
  || miss "default branch main no longer exists"

# 4. Critical files exist
test -f "Controllers/ViewController.swift" \\
  && ok "Controllers/ViewController.swift" \\
  || miss "missing critical file: Controllers/ViewController.swift"
test -f "Business/Note.swift" \\
  && ok "Business/Note.swift" \\
  || miss "missing critical file: Business/Note.swift"
test -f "Business/Markdown.swift" \\
  && ok "Business/Markdown.swift" \\
  || miss "missing critical file: Business/Markdown.swift"
test -f "Helpers/CustomTextStorage.swift" \\
  && ok "Helpers/CustomTextStorage.swift" \\
  || miss "missing critical file: Helpers/CustomTextStorage.swift"
test -f "Business/Storage.swift" \\
  && ok "Business/Storage.swift" \\
  || miss "missing critical file: Business/Storage.swift"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 33 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~3d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/tw93/MiaoYan"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

MiaoYan is a lightweight, Swift-native macOS markdown editor that prioritizes local-first note-taking without cloud data collection. It combines split editor/preview panes with advanced markdown features like wikilink backlinks, LaTeX, and Mermaid diagrams—delivering native app performance (written in Swift 6) rather than Electron bloat. Monolithic single-app structure: Controllers/ holds window and view controllers (MainWindowController.swift, ContentViewController.swift, preference screens), Business/ contains core models (Note.swift, Markdown.swift, Storage.swift, CloudSyncManager.swift), with CI/CD tooling in .agents/ (release, code-review, linting skills). State is managed through PrefsModel.swift and WikilinkIndex.swift.

👥Who it's for

macOS users (especially knowledge workers and writers) who want a distraction-free markdown note-taking app with local storage control, version history, and cross-platform sync via iCloud Drive. Also appeals to developers building CLI workflows via the bundled miao command-line tool.

🌱Maturity & risk

Actively developed and production-ready. The project is published on Mac App Store (paid), Homebrew, and GitHub releases; has meaningful commit activity and structured release notes (.github/RELEASE_NOTES.md). Swift codebase is well-organized with linting (.swiftlint.yml) and formatting (.swift-format) configs in place. However, appears to be primarily a single-maintainer project (tw93), so sustainability depends on continued author engagement.

Single-maintainer risk is the primary concern—no visible team or governance structure. The codebase is monolithic (1.3M lines of Swift) without visible test infrastructure in the top-level structure, raising concerns about regression detection. macOS-only focus limits platform reach. External risk is minimal: no heavy dependency tree visible (mostly native macOS frameworks), and storage relies on user-chosen local filesystem or iCloud.

Active areas of work

Active releases visible via .github/RELEASE_NOTES.md; infrastructure in place for automated AppStore submission, code review, and linting via .agents/skills/. Recent work inferred to involve markdown rendering, wikilink indexing, and cloud sync features. Version history support (VersionHistoryViewController.swift, NoteVersionManager.swift) suggests ongoing refinement of collaboration/backup features.

🚀Get running

git clone https://github.com/tw93/MiaoYan.git && cd MiaoYan && open MiaoYan.xcodeproj (requires Xcode 15+, macOS 11.5+ SDK). Build and run directly from Xcode; no external dependency managers visible (native Swift Package Manager or CocoaPods likely used internally).

Daily commands:

  1. Clone: git clone https://github.com/tw93/MiaoYan.git
  2. Open in Xcode: open MiaoYan.xcodeproj
  3. Select Product > Run (⌘R) or build Product > Build (⌘B)
  4. On first launch, set storage path in Preferences (⌘,) to a MiaoYan folder in iCloud Drive or local filesystem.

🗺️Map of the codebase

  • Controllers/ViewController.swift — Primary editor view controller—orchestrates markdown editing, preview rendering, and note management; central hub for all UI interactions.
  • Business/Note.swift — Core data model representing a markdown note; defines persistence, versioning, and attachment handling logic.
  • Business/Markdown.swift — Markdown parsing and rendering engine; handles conversion between raw markdown and display formats.
  • Helpers/CustomTextStorage.swift — Custom NSTextStorage subclass managing real-time syntax highlighting and markdown rule application in the editor.
  • Business/Storage.swift — File system abstraction layer; handles persistence, note loading, project structure, and disk I/O operations.
  • Controllers/AppDelegate.swift — Application entry point and lifecycle manager; initializes core services, URL routing, and window management.
  • Business/CloudSyncManager.swift — Cloud synchronization orchestrator; manages iCloud Drive integration and conflict resolution for notes.

🛠️How to make changes

Add a New Markdown Syntax Highlight Rule

  1. Define the regex pattern and styling in MarkdownRuleHighlighter.swift (Helpers/MarkdownRuleHighlighter.swift)
  2. Update CustomTextStorage.swift to apply the new rule during text processing (Helpers/CustomTextStorage.swift)
  3. Add theme colors in Theme.swift if new visual styles are needed (Helpers/Theme.swift)

Add a New Markdown Export Format

  1. Create export handler method in HtmlManager.swift or similar (Business/HtmlManager.swift)
  2. Add menu item and handler in EditorMenuManager.swift (Helpers/EditorMenuManager.swift)
  3. Implement format-specific export logic (e.g., PdfExportController for PDF) (Helpers/PdfExportController.swift)
  4. Wire export action in ViewController+Action.swift (Controllers/ViewController+Action.swift)

Add a New User Preference Setting

  1. Add property to PrefsModel.swift with getter/setter (Business/PrefsModel.swift)
  2. Create preference UI in appropriate PrefsViewController (e.g., GeneralPrefsViewController) (Controllers/GeneralPrefsViewController.swift)
  3. Bind preference change listener in UserDefaultsManagement.swift (Helpers/UserDefaultsManagement.swift)
  4. Apply preference effect in relevant view controller (e.g., ViewController.swift) (Controllers/ViewController.swift)

Add Image Processing or Link Feature

  1. Add parsing logic in ImageLinkParser.swift or LinkHighlighter.swift (Helpers/ImageLinkParser.swift)
  2. Implement visual representation in CustomTextStorage.swift highlighting (Helpers/CustomTextStorage.swift)
  3. Handle preview in ImagePreviewManager.swift (Helpers/ImagePreviewManager.swift)
  4. Integrate into editor actions in ViewController+Action.swift (Controllers/ViewController+Action.swift)

🔧Why these technologies

  • AppKit (macOS native) — Provides deep OS integration, system appearance support, and native text editing capabilities; essential for a native desktop markdown editor
  • iCloud Drive (CloudKit) — Enables seamless cross-device sync without backend infrastructure; aligns with macOS user expectations
  • NSTextStorage subclass (CustomTextStorage) — Allows real-time syntax highlighting without external markdown engine; provides responsive editor feedback
  • FSEvents + FileWatcher — Detects external file changes and enables multi-client sync; critical for collaborative editing scenarios
  • Swift language — Type-safe, modern macOS development language with excellent AppKit bindings

⚖️Trade-offs already made

  • Pure AppKit + local file storage vs. cloud-first backend
    • Why: undefined
    • Consequence: undefined

🪤Traps & gotchas

  1. Storage path not auto-initialized: App requires manual configuration of storage folder in Preferences on first launch—no defaults or auto-setup visible. 2. iCloud Drive sync logic: CloudSyncManager.swift likely has undocumented conflict resolution and edge cases around offline editing. 3. macOS version gating: Features may be guarded by macOS 11.5+ availability checks; test on minimum supported version. 4. No test directory visible: Lack of visible test infrastructure means manual testing may be required for validation. 5. AppKit legacy constraints: Some UI patterns may follow older AppKit conventions rather than modern SwiftUI—unfamiliar to newer iOS developers.

🏗️Architecture

💡Concepts to learn

  • Wikilink Graph & Backlink Index — MiaoYan's differentiating feature (WikilinkIndex.swift) enables knowledge graph navigation; understanding bidirectional linking and graph traversal is core to the app's value proposition
  • Markdown AST Parsing & Rendering — Markdown.swift and HtmlManager.swift work together to parse markdown into an AST and render to HTML; this dual-pass approach is critical for supporting custom syntax (LaTeX, Mermaid) beyond standard CommonMark
  • CloudKit Synchronization & Conflict Resolution — CloudSyncManager.swift handles iCloud Drive sync; understanding CRDT patterns or last-write-wins strategies is essential for distributed note-taking without user data loss
  • AppKit View Controller Hierarchy & Responder Chain — MiaoYan uses legacy AppKit (not SwiftUI); the MainWindowController and ContentViewController rely on responder chain for keyboard handling and focus management
  • File-Based Persistence & Local-First Architecture — Storage.swift manages note files directly; local-first design (no server backend) means offline-first sync and privacy are architectural, not features—affects how notes are versioned and merged
  • Version History & Snapshot Management — NoteVersionManager.swift and VersionHistoryViewController.swift enable rollback; understanding immutable snapshots vs. diffs is key to efficient storage of edit history
  • LaTeX & Mermaid Embedded Rendering — HtmlManager.swift must delegate LaTeX and Mermaid blocks to external renderers (likely via JavaScript or native frameworks); understanding the markup convention and render pipeline is critical for extending markdown features
  • obsidian-md/obsidian-releases — Direct competitor: Obsidian is a closed-source, cross-platform markdown app with wikilinks and graph features; studying its design patterns informs feature parity discussions
  • dennisvanbrummelen/Bear — Sibling macOS markdown app with Apple ecosystem focus; shares similar target audience and platform constraints
  • marktext/marktext — Cross-platform, open-source markdown editor written in Electron; comparison point for why MiaoYan chose native Swift for performance
  • notable/notable — Electron-based markdown note app with local storage; represents the 'bloated alternative' MiaoYan is positioned against
  • jzhang38/quartz — Obsidian plugin ecosystem and static site generation companion; many MiaoYan users may want similar publish workflows

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add unit tests for Business logic layer (Note.swift, Storage.swift, Markdown.swift)

The Business folder contains critical data handling logic (Note management, Storage operations, Markdown processing) but there's no visible test suite in the repository. This is a high-value contribution for a Markdown app where data integrity is crucial. Tests would cover note creation/deletion, file storage operations, and markdown parsing edge cases.

  • [ ] Create Tests/ directory with NoteTesting.swift for Note.swift lifecycle tests
  • [ ] Add StorageTesting.swift to test file I/O operations in Storage.swift
  • [ ] Add MarkdownTesting.swift to test markdown parsing edge cases in Markdown.swift
  • [ ] Test CloudSyncManager.swift sync conflict scenarios
  • [ ] Ensure tests cover WikilinkIndex.swift link resolution

Add GitHub Actions CI workflow for Swift linting and build validation

The repo contains .swiftlint.yml and .swift-format configuration files, indicating linting/formatting standards are defined, but there's no visible GitHub Actions workflow to enforce them. This prevents lint drift and build failures from being caught before merge. A workflow would validate all PRs meet the project's code standards.

  • [ ] Create .github/workflows/swift-lint.yml to run swiftlint on all Swift files
  • [ ] Add swift-format validation to the workflow using .swift-format config
  • [ ] Include macOS build validation step to catch compilation errors early
  • [ ] Configure the workflow to fail PR checks if linting violations are found
  • [ ] Add workflow badge to README.md showing CI status

Refactor ViewController.swift and related files into smaller, focused modules

The Controllers folder shows ViewController.swift is extended across multiple files (ViewController+Action.swift, ViewController+Editor.swift, ViewController+Layout.swift, ViewController+Data.swift), indicating the main view controller is handling too many concerns. A comprehensive refactoring to extract these into proper coordinator/presenter patterns would improve maintainability and testability.

  • [ ] Extract UI action handling into a dedicated EditorActionCoordinator.swift
  • [ ] Create EditorLayoutManager.swift to encapsulate layout logic from ViewController+Layout.swift
  • [ ] Extract data binding logic into EditorDataBinder.swift from ViewController+Data.swift
  • [ ] Create EditorToolbarController.swift for editor toolbar actions from ViewController+Editor.swift
  • [ ] Update MainWindowController.swift to use new coordinators instead of directly extending ViewController
  • [ ] Document the new architecture in CONTRIBUTING.md

🌿Good first issues

  • Add unit tests for Markdown.swift parsing: The core markdown engine lacks visible test coverage; add tests for LaTeX, Mermaid, and wikilink parsing to prevent regressions.
  • Improve error messaging in Storage.swift: Add user-friendly alerts when file I/O fails (disk full, permission denied) instead of silent failures.
  • Document CLI tool behavior in README: The miao CLI is mentioned but not documented with examples; add usage guide and man page to scripts/ directory.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 6124efd — chore: clean up local-only docs (tw93)
  • 8d454a5 — fix: split-mode scrollbar and preview re-entry (tw93)
  • 60c2f70 — perf: tighten preview, PPT, and CRUD transitions (tw93)
  • cb46c98 — fix: durable saves and delete safety (tw93)
  • 9c8f1e1 — fix(pdf): graceful mermaid failures for export (tw93)
  • c376245 — fix: normalize attachment filenames (#523) (mrdear)
  • 30d1c5f — chore: clean up regex declarations and fix stale doc comment (tw93)
  • 7ca1169 — fix: snapshot URL encoding for paths with spaces + symlink perf (tw93)
  • 642de94 — fix: eliminate dark mode flash on first/second note open (tw93)
  • ea74726 — fix: paint UIWindow/NavBar/TabBar background to paper color (tw93)

🔒Security observations

MiaoYan is a macOS markdown editor with moderate security posture. No critical vulnerabilities were identified from static analysis, but several medium and low-risk areas require attention: cloud sync security, keychain implementation, file system operations validation, HTML content sanitization, and image processing. The application handles user files and cloud synchronization, necessitating proper encryption and authentication mechanisms. Key recommendations include implementing strict input validation across file operations, ensuring secure cloud communications with proper authentication, sanitizing HTML output, and validating URL scheme parameters. The codebase appears well-structured without obvious hardcoded secrets in filenames, but requires examination of actual implementation details for complete security assessment.

  • Medium · Potential Insecure Keychain Password Storage — Helpers/KeychainPasswordItem.swift. The file 'Helpers/KeychainPasswordItem.swift' suggests password storage implementation. If not properly implemented with secure coding practices, keychain interactions could be vulnerable to memory dumping or improper access control. Fix: Ensure keychain operations use SecureEnclave when available, implement proper access control attributes (kSecAttrAccessible), and validate all keychain queries use appropriate protection classes.
  • Medium · Cloud Sync Manager Security — Business/CloudSyncManager.swift. The 'Business/CloudSyncManager.swift' file indicates cloud synchronization functionality. Without examining the implementation, potential risks include: unencrypted data transmission, improper authentication/authorization, or insecure credential handling during sync operations. Fix: Implement TLS/SSL for all cloud communications, use certificate pinning, ensure end-to-end encryption for sensitive data, validate SSL certificates properly, and use OAuth2/tokens instead of storing credentials.
  • Medium · File System Operations Without Validation — Extensions/FileManager+.swift, Helpers/FileWatcher.swift, Business/Storage.swift. The 'Extensions/FileManager+.swift' and 'Helpers/FileWatcher.swift' suggest file system operations. Without proper path validation, these could be vulnerable to path traversal attacks or unauthorized file access. Fix: Implement strict path validation, use sandboxed file access APIs, verify file permissions before operations, and avoid constructing paths from untrusted input.
  • Low · HTML Content Handling — Business/HtmlManager.swift, Extensions/MPreviewView+Export.swift. The 'Business/HtmlManager.swift' file handles HTML content conversion/export. If user markdown is converted to HTML without proper sanitization, XSS vulnerabilities could occur if the output is displayed in a web context. Fix: Sanitize all HTML output, use content security policies, escape user-controlled content, and use established HTML sanitization libraries when generating HTML from markdown.
  • Low · Image Processing and Attachment Handling — Helpers/ImagesProcessor.swift, Business/NoteAttachment.swift, Helpers/ImageLinkParser.swift. The 'Helpers/ImagesProcessor.swift' and 'Business/NoteAttachment.swift' handle file attachments and image processing. Without proper validation, this could lead to processing malicious files or arbitrary code execution. Fix: Validate file types and signatures, implement file size limits, scan attachments for malicious content, use sandboxed image processing, and avoid executing user-supplied code.
  • Low · URL Routing Without Validation — Controllers/AppDelegate+URLRoutes.swift. The 'Controllers/AppDelegate+URLRoutes.swift' handles custom URL schemes. Improper validation could lead to arbitrary command execution or unauthorized actions. Fix: Validate all URL scheme parameters, implement strict whitelist of allowed actions, verify caller identity, use URLComponents for parsing, and avoid passing unvalidated user input to system calls.
  • Low · Clipboard Manager Information Disclosure — Helpers/ClipboardManager.swift. The 'Helpers/ClipboardManager.swift' handles clipboard operations. Sensitive data in clipboard history could be exposed if not properly managed. Fix: Clear clipboard after sensitive operations, implement timeout for clipboard clearing, use secure pasteboard operations, and inform users about clipboard usage.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · tw93/MiaoYan — RepoPilot