RepoPilotOpen in app →

tisfeng/Easydict

一个简洁优雅的词典翻译 macOS App。开箱即用,支持离线 OCR 识别,支持有道词典,🍎 苹果系统词典,🍎 苹果系统翻译,OpenAI,Gemini,DeepL,Google,Bing,腾讯,百度,阿里,小牛,彩云和火山翻译。A concise and elegant Dictionary and Translator macOS App for looking up words and translating text.

Mixed

Mixed signals — read the receipts

worst of 4 axes
Use as dependencyConcerns

copyleft license (GPL-3.0) — review compatibility

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 today
  • 3 active contributors
  • GPL-3.0 licensed
Show 5 more →
  • CI configured
  • Tests present
  • Small team — 3 contributors active in recent commits
  • Concentrated ownership — top contributor handles 75% of recent commits
  • GPL-3.0 is copyleft — check downstream compatibility
What would change the summary?
  • Use as dependency ConcernsMixed if: relicense under MIT/Apache-2.0 (rare for established libs)

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/tisfeng/easydict?axis=fork)](https://repopilot.app/r/tisfeng/easydict)

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/tisfeng/easydict on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: tisfeng/Easydict

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/tisfeng/Easydict 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 — Mixed signals — read the receipts

  • Last commit today
  • 3 active contributors
  • GPL-3.0 licensed
  • CI configured
  • Tests present
  • ⚠ Small team — 3 contributors active in recent commits
  • ⚠ Concentrated ownership — top contributor handles 75% of recent commits
  • ⚠ GPL-3.0 is copyleft — check downstream compatibility

<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 tisfeng/Easydict repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/tisfeng/Easydict.

What it runs against: a local clone of tisfeng/Easydict — 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 tisfeng/Easydict | Confirms the artifact applies here, not a fork | | 2 | License is still GPL-3.0 | Catches relicense before you depend on it | | 3 | Default branch dev exists | Catches branch renames | | 4 | Last commit ≤ 30 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>tisfeng/Easydict</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of tisfeng/Easydict. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/tisfeng/Easydict.git
#   cd Easydict
#
# 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 tisfeng/Easydict and re-run."
  exit 2
fi

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

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

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

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 30 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~0d)"
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/tisfeng/Easydict"
  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

Easydict is a native macOS dictionary and translation application written in Swift/Objective-C that provides out-of-the-box word lookup and text translation with automatic language detection. It integrates with 20+ translation services (Apple Dictionary, Apple Translate, OpenAI, Gemini, DeepL, Google Translate, Youdao, Tencent, Baidu, etc.) and uniquely combines input translation, selection-based translation, offline OCR screenshot translation, and multi-service parallel querying in a single unified interface. Hybrid architecture combining native macOS UI (Swift/Objective-C) with integration layers for multiple translation APIs. The codebase is organized as a monolithic app structure with modular service integrations rather than a library-based architecture. The .agents/ directory contains Claude-focused skill definitions and diagram generation tools, suggesting AI-assisted development practices.

👥Who it's for

macOS users (both casual and professional) who frequently look up words or translate text across languages, particularly those who value offline capabilities and seamless integration with system services. Contributors are Swift/macOS developers interested in translation service integration, OCR implementation, and native app architecture.

🌱Maturity & risk

Actively developed and production-ready: the repository shows substantial Swift/Objective-C codebase (~2M+ lines), has public releases with significant download counts, and maintains ongoing feature additions (multiple translation service integrations). The project demonstrates maturity through support for diverse translation backends and platform features like silent OCR and TTS, though specific CI/test coverage metrics are not visible in the file list.

Single-maintainer risk (tisfeng) is the primary concern for a user-facing macOS app. The project has many external API dependencies (20+ translation services with varying reliability and terms of service), requiring careful credential management and fallback handling. No visible test suite or CI pipeline in the provided file structure suggests testing is potentially manual or undocumented.

Active areas of work

Primary focus appears to be expanding translation service integrations (Groq, DeepSeek, Ollama, GitHub Models, Doubao recently added based on README) and adding supporting features like OCR improvements and TTS voice options. The .agents/ directory with Fireworks tech-graph skills suggests ongoing use of AI-assisted architecture documentation and potentially code generation.

🚀Get running

git clone https://github.com/tisfeng/Easydict.git
cd Easydict
# Open Easydict.xcodeproj in Xcode and build for macOS
open Easydict.xcodeproj
# Or build via command line:
xcodebuild -scheme Easydict -configuration Release

Daily commands: Open Easydict.xcodeproj in Xcode (macOS 12+) and press ⌘R to build and run. For CLI builds: xcodebuild -scheme Easydict -configuration Release -derivedDataPath build. The app launches as a native macOS menu bar application with global keyboard shortcut access (default: ⌘⇧D for lookup).

🗺️Map of the codebase

🛠️How to make changes

Start in Easydict/ directory structure (inferred from .xcodeproj pattern): translation service implementations likely in separate subdirectories under a Services/ folder, OCR logic under Features/OCR/, UI components in Views/. Search for Service, Translate, Query in Swift files to locate the service abstraction layer where new translators can be plugged in. Configuration/credential handling is typically in AppDelegate or a Config.swift file.

🪤Traps & gotchas

API credential management is critical: each translation service (OpenAI, DeepL, Gemini, etc.) requires valid API keys or OAuth tokens, and the app must handle rate limiting and fallback gracefully. OCR functionality requires Vision framework permissions and appropriate macOS version support. No visible package manager file (Podfile/Package.swift snippet shown) means dependency management approach is unclear—Swift Package Manager or CocoaPods integration may be required but undocumented in provided files. The .agents/ directory is AI-tooling-specific and should not be modified for core app changes.

💡Concepts to learn

  • Service Abstraction/Provider Pattern — Easydict's core strength is supporting 20+ translation backends; understanding how services are abstracted (likely via protocol/interface) is essential for adding new translators or modifying existing ones
  • OCR (Optical Character Recognition) — Silent screenshot OCR is a key differentiator feature; understanding Vision framework integration and text recognition accuracy tradeoffs is critical for OCR-related contributions
  • Automatic Language Detection — Easydict detects source/target language automatically; this likely uses NLP techniques or language identification APIs, crucial for the 'out of box' experience
  • API Rate Limiting & Fallback Strategies — With 20+ external APIs, handling quota exhaustion, circuit breaking, and graceful degradation is essential to prevent user-facing failures
  • Global Keyboard Shortcuts & Event Hooking (macOS) — The app's 'select translate' feature requires registering global hotkeys; understanding AppKit event handling and keyboard event interception is needed for input method modifications
  • Text-to-Speech (TTS) Synthesis — The app supports multiple TTS voice services; understanding AVFoundation and TTS API integration is needed for audio playback and voice selection features
  • Credential & Configuration Management in Native Apps — Securely storing API keys for 20+ services without hardcoding requires Keychain integration and secure credential storage; critical for production app security
  • shadowsocks/ShadowsocksX-NG — Alternative native macOS menu-bar utility with multi-service integration architecture, similar UI pattern for managing multiple external backends
  • soulverteam/SoulverCore — Native Swift macOS app demonstrating system integration (similar use of AppKit, Vision framework) and extensible service plugin architecture
  • quicktype/quicktype — Multi-language code generation tool showing how to integrate diverse backend APIs and provide unified CLI/UI experience
  • LibreTranslate/LibreTranslate — Open-source translation service aggregator providing self-hosted alternative to cloud services Easydict uses, useful reference for offline translation fallback
  • deanishe/alfred-workflow-template — Complementary macOS productivity tool architecture (Alfred workflows) showing alternative patterns for system-wide text/selection handling

🪄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 GitHub Actions CI workflow for Easydict macOS app builds and releases

The repo has .github/ISSUE_TEMPLATE but no visible CI/CD workflows (.github/workflows directory is absent from the file list). For a macOS app with active releases, automated builds, code signing, and notarization workflows would prevent regressions and streamline distribution. This is critical for a tool with 'downloads' badge showing significant user base.

  • [ ] Create .github/workflows/build.yml for macOS builds using xcodebuild
  • [ ] Add code signing and Apple notarization steps for release builds
  • [ ] Create .github/workflows/test.yml for running unit/integration tests on pull requests
  • [ ] Add workflow for automated release creation and artifact uploads to GitHub releases

Create integration tests for translation service providers (Youdao, Apple Translator, OpenAI, etc.)

The README lists 13+ translation/dictionary services (Youdao, Apple Dictionary, Apple Translator, OpenAI, Gemini, DeepL, Google, Bing, Tencent, Baidu, Alibaba, Niutrans, Caiyun, Volcano). No test files are visible in the provided structure. Adding provider integration tests would catch API changes, credential issues, and service-specific bugs early.

  • [ ] Create Tests/ or tests/ directory (if not present) following Xcode conventions
  • [ ] Add mock tests for each provider to verify request formatting and response parsing
  • [ ] Add optional integration tests requiring API keys (marked as skipped in CI by default)
  • [ ] Create a test fixture file documenting expected request/response formats for each service

Add comprehensive API documentation for offline OCR and translation service integrations

The README mentions 'offline OCR recognition' and 13+ services but .agents/skills/fireworks-tech-graph suggests this repo may have architectural documentation needs. No docs/ directory is visible. Contributors need clear documentation on how to add new translation providers or configure OCR, especially given the complex multi-service architecture.

  • [ ] Create docs/ARCHITECTURE.md explaining the service provider abstraction and plugin system
  • [ ] Create docs/ADD_TRANSLATION_SERVICE.md with step-by-step guide and code examples
  • [ ] Create docs/OCR_CONFIGURATION.md documenting offline OCR setup and customization
  • [ ] Add service provider interface documentation referencing specific source files in the main app

🌿Good first issues

  • Add unit tests for translation service abstraction layer: create a test file covering the service protocol implementations (likely in Services/), currently no test bundle is visible in the file structure
  • Implement missing localization for the .agents/skills/fireworks-tech-graph/ documentation (README.zh.md exists but English style-guide references may need Chinese translations)
  • Document the new translation service integration pattern: create a template/guide at .docs/Contributing-New-Translator-Service.md with step-by-step instructions for adding a new translator, referencing real examples like the recent Groq/DeepSeek additions

Top contributors

Click to expand

📝Recent commits

Click to expand
  • e6a02a3 — fix(mdict): preserve original attributes when inlining scripts (KurodaKayn)
  • 33a5e23 — fix(mdict): inline mdict-sound URLs and run lookups in caller task (KurodaKayn)
  • ab85c5b — fix(mdict): percent-encode commas in secret data URIs (KurodaKayn)
  • e21cf32 — Merge branch 'dev' into feature/mdict-dictionary-support (tisfeng)
  • bf5ae93 — fix(mdict): decompress key blocks by header instead of size heuristic (KurodaKayn)
  • d5dd229 — fix(mdict): harden sound and script rewriting (KurodaKayn)
  • 74e9705 — fix(mdict): deduplicate in-flight dictionary loading (KurodaKayn)
  • 761e96a — fix(mdict): resolve review issues for import and lookup (KurodaKayn)
  • c396cc6 — fix(mdict): preserve lookup task cancellation (KurodaKayn)
  • eef6117 — fix(mdict): avoid caching budget-truncated stylesheets (KurodaKayn)

🔒Security observations

The Easydict codebase demonstrates a reasonably secure foundation with proper use of version control, linting tools, and modular structure. However, there are several areas for improvement: 1) Third-party dependencies require security verification, 2) Script execution risks need mitigation, 3) Debug/local configuration files should be reviewed and properly excluded, 4) API key management practices should be validated, 5) A formal security policy and SAST tools should be implemented. The application's integration with multiple external translation services requires careful credential management. No critical vulnerabilities were identified in the visible file structure, but a deeper code review would be needed to assess runtime security risks, especially around API credential handling and input validation.

  • Medium · External Dependency with Unclear Security Status — .agents/skills/fireworks-tech-graph/, Package.json. The codebase includes a dependency on '@yizhiyanhua-ai/fireworks-tech-graph' (v1.0.4) which appears to be a custom/third-party package. There is limited visibility into the security practices, update frequency, and maintenance status of this dependency. The package is used for diagram generation and includes scripts that process external data. Fix: Verify the security posture of this dependency by: 1) Checking npm audit results, 2) Reviewing the source repository for security policies and update frequency, 3) Implementing dependency scanning in CI/CD pipeline, 4) Consider using npm lockfile to pin exact versions.
  • Low · Potential Script Execution Risk — .agents/skills/fireworks-tech-graph/scripts/. The fireworks-tech-graph skill contains shell scripts (generate-diagram.sh, test-all-styles.sh, validate-svg.sh) and Python scripts (generate-from-template.py) that are included in the repository. If these scripts process untrusted input, they could pose injection risks. Fix: Audit all shell and Python scripts to ensure: 1) Input validation is performed on all external data, 2) Command injection is prevented through proper argument quoting/escaping, 3) Scripts have appropriate file permissions (not world-writable), 4) Consider using safer alternatives like Python subprocess with shell=False.
  • Low · Debug Configuration Exposed — Easydict-debug.xcconfig, .claude/settings.local.json, .gemini/commands/. The repository contains debug configuration files (Easydict-debug.xcconfig) which may contain development-specific settings that should not be in the repository. Additionally, '.claude/settings.local.json' and '.gemini/commands' suggest local configuration files that might contain sensitive settings. Fix: Review these files to ensure they don't contain: 1) Credentials or API keys, 2) Development server endpoints, 3) Debug modes that expose sensitive information. Add them to .gitignore if they contain local/sensitive data. Use environment variables for sensitive configuration instead.
  • Low · Incomplete Security Configuration Visibility — .swiftlint.yml, .swiftformat, .gitignore, Repository root. The codebase includes linting and formatting config files (.swiftlint.yml, .swiftformat) but no apparent security-focused configuration (e.g., no SAST configuration, no security policy, limited visibility into security practices). Fix: Implement additional security measures: 1) Add SECURITY.md file with security policy and reporting procedures, 2) Configure Swift-specific security linting rules, 3) Set up automated dependency scanning, 4) Implement SAST (Static Application Security Testing) in CI/CD, 5) Review and enhance .gitignore to prevent accidental credential commits.
  • Low · Third-Party Service Integration Risks — Source code (not fully visible in provided structure). The application integrates with multiple translation APIs (OpenAI, Gemini, DeepL, Google, Bing, 腾讯, 百度, 阿里, etc.) based on the description. This requires API key management and secure credential storage. Fix: Ensure: 1) API keys are never hardcoded, 2) Use secure credential storage (Keychain on macOS), 3) Implement API key rotation policies, 4) Use environment variables or secure configuration management, 5) Implement rate limiting and request signing to prevent API abuse, 6) Log API interactions without exposing sensitive data.

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 · tisfeng/Easydict — RepoPilot