RepoPilotOpen in app →

zhuhaow/SpechtLite

A rule-based proxy for macOS

Mixed

Stale — last commit 6y ago

worst of 4 axes
Use as dependencyConcerns

copyleft license (GPL-3.0) — review compatibility; last commit was 6y ago…

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.

  • 4 active contributors
  • GPL-3.0 licensed
  • CI configured
Show 5 more →
  • Tests present
  • Stale — last commit 6y ago
  • Small team — 4 contributors active in recent commits
  • Single-maintainer risk — top contributor 97% 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/zhuhaow/spechtlite?axis=fork)](https://repopilot.app/r/zhuhaow/spechtlite)

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

Onboarding doc

Onboarding: zhuhaow/SpechtLite

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/zhuhaow/SpechtLite 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 — Stale — last commit 6y ago

  • 4 active contributors
  • GPL-3.0 licensed
  • CI configured
  • Tests present
  • ⚠ Stale — last commit 6y ago
  • ⚠ Small team — 4 contributors active in recent commits
  • ⚠ Single-maintainer risk — top contributor 97% 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 zhuhaow/SpechtLite repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/zhuhaow/SpechtLite.

What it runs against: a local clone of zhuhaow/SpechtLite — 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 zhuhaow/SpechtLite | 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 master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 2245 days ago | Catches sudden abandonment since generation |

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

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "zhuhaow/SpechtLite(\\.git)?\\b" \\
  && ok "origin remote is zhuhaow/SpechtLite" \\
  || miss "origin remote is not zhuhaow/SpechtLite (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 master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "SpechtLite/AppDelegate.swift" \\
  && ok "SpechtLite/AppDelegate.swift" \\
  || miss "missing critical file: SpechtLite/AppDelegate.swift"
test -f "SpechtLite/Manager/ProfileManager.swift" \\
  && ok "SpechtLite/Manager/ProfileManager.swift" \\
  || miss "missing critical file: SpechtLite/Manager/ProfileManager.swift"
test -f "SpechtLite/Manager/ProxySettingManager.swift" \\
  && ok "SpechtLite/Manager/ProxySettingManager.swift" \\
  || miss "missing critical file: SpechtLite/Manager/ProxySettingManager.swift"
test -f "SpechtLite/ViewController/MenuBarController.swift" \\
  && ok "SpechtLite/ViewController/MenuBarController.swift" \\
  || miss "missing critical file: SpechtLite/ViewController/MenuBarController.swift"
test -f "SpechtLite/Manager/PreferenceManager.swift" \\
  && ok "SpechtLite/Manager/PreferenceManager.swift" \\
  || miss "missing critical file: SpechtLite/Manager/PreferenceManager.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 2245 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~2215d)"
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/zhuhaow/SpechtLite"
  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

SpechtLite is a rule-based proxy application for macOS that routes network traffic according to configurable rules, leveraging NEKit (now deprecated) for packet filtering and routing. It provides fine-grained control over which connections use which proxy servers, evaluated via pattern-matching rules stored in user profiles. Monolithic macOS app structure: SpechtLite/ contains the main application with Manager/ subdirectory for system managers (AutostartManager, ProxySettingManager, ProfileManager, LoggerManager). ProxyConfig/ is a separate command-line utility for system proxy configuration. AppDelegate.swift drives the UI, with XIB-based MainMenu interface. ViewController directory holds UI logic; no separate model layer visible.

👥Who it's for

macOS users and network administrators who need selective proxy routing without heavyweight VPN clients—specifically people managing traffic filtering, geo-routing, or corporate network policies who want rule-based control at the system level rather than per-application settings.

🌱Maturity & risk

This project is archived and unmaintained: the README explicitly states 'SpechtLite is archived as NEKit is deprecated.' NEKit (the core dependency) was Apple's network extension framework that is no longer supported. There is no visible CI pipeline beyond a legacy .travis.yml, and the codebase shows no recent activity. This is a reference implementation only, not suitable for new production use.

Critical risk: NEKit dependency is deprecated and no longer receives security updates from Apple. The Cartfile dependency manager setup suggests pinned but potentially outdated frameworks. Single-maintainer project (zhuhaow) with no active issue triage visible. macOS system-level proxy changes may break on newer OS versions due to API deprecations. Do not ship this in production; use as a reference only.

Active areas of work

Nothing—this repo is archived. The project is in maintenance-only mode with NEKit no longer developed. No active PRs, issues, or commits are being merged.

🚀Get running

Clone and open in Xcode: git clone https://github.com/zhuhaow/SpechtLite.git && cd SpechtLite && open SpechtLite.xcworkspace. Requires Carthage for dependency management: carthage update --platform macOS (after installing Carthage via brew install carthage).

Daily commands: Open SpechtLite.xcworkspace in Xcode, select SpechtLite scheme, and press Run (⌘R). The app runs as a macOS menu bar application. ProxyConfig is built separately: select ProxyConfig scheme and run.

🗺️Map of the codebase

  • SpechtLite/AppDelegate.swift — Main application entry point and lifecycle manager; initializes all managers and UI components on startup.
  • SpechtLite/Manager/ProfileManager.swift — Core abstraction for loading, parsing, and managing proxy rule profiles; all proxy routing logic depends on this.
  • SpechtLite/Manager/ProxySettingManager.swift — Bridges application state to macOS system proxy settings; critical for actually applying rules to the network stack.
  • SpechtLite/ViewController/MenuBarController.swift — Primary UI layer; status bar menu and profile selection interface that users interact with directly.
  • SpechtLite/Manager/PreferenceManager.swift — Persistence layer for user preferences and configuration; all user settings flow through this.
  • SpechtLite/ProxyHelper.swift — Wrapper for system-level proxy configuration; handles privileged operations and PAC file generation.

🧩Components & responsibilities

  • ProfileManager (Swift, file I/O, text parsing) — Parses proxy profile files (likely YAML/JSON format based on README context); validates and stores rule definitions.
    • Failure mode: Invalid or missing profile file → no rules loaded → all traffic routes to default proxy or direct; app reports parse error to UI.
  • ProxySettingManager (macOS Preferences framework (private), SCDynamics) — Bridges application state to macOS system proxy configuration; applies/revokes settings atomically.
    • Failure mode: Insufficient privileges → settings not applied; network traffic bypasses proxy rules.
  • ProxyHelper (Swift, JavaScript string generation, file system) — Generates PAC (JavaScript) files from parsed rules and manages PAC file lifecycle on disk.
    • Failure mode: Malformed PAC syntax → browser/system proxy engine error → default behavior (direct or no proxying).
  • MenuBarController (AppKit, NSMenu, NSStatusBar) — Renders status menu, handles user profile selection, and dispatches commands to managers.
    • Failure mode: UI crash → app remains running in background; user cannot interact; requires manual app restart.
  • UpdateManager (Sparkle framework, HTTP, XML parsing) — Monitors appcast for new versions and prompts user to install updates.
    • Failure mode: Network unreachable or appcast malformed → no update check; app continues on current version.

🔀Data flow

  • UserMenuBarController — User clicks menu bar icon or selects profile from dropdown.
  • MenuBarControllerProfileManager — Requests profile file for selected proxy configuration.
  • ProfileManagerProfileManager — Parses rules (blocked domains, proxy routing, direct access) from profile file.
  • ProfileManagerProxySettingManager — Passes validated rule set to apply to system.
  • ProxySettingManagerProxyHelper — Requests PA

🛠️How to make changes

Add a new preference option

  1. Define the preference key and getter/setter in PreferenceManager.swift (SpechtLite/Manager/PreferenceManager.swift)
  2. Add UI controls to the main menu in MainMenu.xib (SpechtLite/Base.lproj/MainMenu.xib)
  3. Wire the UI to PreferenceManager in MenuBarController.swift (SpechtLite/ViewController/MenuBarController.swift)

Add support for a new proxy rule format

  1. Extend profile parsing logic in ProfileManager.swift to handle the new format (SpechtLite/Manager/ProfileManager.swift)
  2. Update ProxyHelper.swift to generate appropriate PAC or system config for the new rule type (SpechtLite/ProxyHelper.swift)
  3. Trigger ProxySettingManager to apply the new configuration (SpechtLite/Manager/ProxySettingManager.swift)

Add a new system manager (e.g., for network monitoring)

  1. Create a new Swift file in SpechtLite/Manager/ (e.g., NetworkManager.swift) (SpechtLite/Manager/)
  2. Instantiate and initialize the manager in AppDelegate.swift (SpechtLite/AppDelegate.swift)
  3. Add logging calls via LoggerManager.swift if needed (SpechtLite/Manager/LoggerManager.swift)

🔧Why these technologies

  • Swift with Cocoa/AppKit — Native macOS development; direct access to system proxy APIs and menu bar integration; archived project notes NEKit deprecation.
  • PAC (Proxy Auto-Config) files — Standard mechanism for rule-based proxy routing on macOS without kernel extensions; avoids elevated privileges for normal operation.
  • macOS UserDefaults — Built-in, lightweight persistence for user preferences and configuration; no external database dependency.
  • Sparkle (implied by appcast/) — Standard macOS framework for checking and installing app updates; appcast XML files for version management.

⚖️Trade-offs already made

  • Rule-based proxy via system settings rather than local VPN/TUN

    • Why: Simpler architecture, no kernel extension required, easier privilege handling.
    • Consequence: Limited to HTTP/HTTPS and SOCKS proxies; cannot inspect/modify all traffic types; dependent on OS-level proxy support.
  • Single monolithic AppDelegate managing all managers

    • Why: Simple initialization and centralized control for a small macOS menu bar app.
    • Consequence: AppDelegate becomes a God Object; harder to test individual managers in isolation.
  • Archived project (NEKit deprecated)

    • Why: Original networking library (NEKit) was deprecated by Apple; maintaining compatibility became untenable.
    • Consequence: Project is no longer actively maintained; may not work on recent macOS versions or with modern Swift.

🚫Non-goals (don't propose these)

  • Cross-platform support (macOS-only)
  • Real-time traffic inspection or modification (PAC-based routing only)
  • User authentication or multi-user profiles
  • Kernel-level filtering or VPN integration
  • Support for modern Apple Network Extension Framework (project predates this)

🪤Traps & gotchas

NEKit deprecation: The entire application depends on NEKit, which Apple stopped maintaining. This will break on future macOS versions if not rewritten to use NetworkExtension.framework directly. Privileged proxy changes: ProxyConfig tool likely requires elevated privileges; examine code for sudo usage. No tests: Zero visible test suite—dangerous for a system-level networking tool. XIB-based UI: Xcode XIB files are XML; merge conflicts are painful. Legacy Carthage setup: Cartfile.resolved may pin outdated, vulnerable dependency versions.

🏗️Architecture

  • shadowsocks/shadowsocks-iOS — Similar rule-based proxy client for Apple platforms; demonstrates modern approaches to traffic routing post-NEKit deprecation
  • clowwindy/ShadowVPN — Alternative lightweight tunneling/proxy solution; provides context on macOS proxy tool ecosystem
  • eycorsican/leaf — Modern rule-based proxy framework written in Rust; shows current-generation approach to the same problem SpechtLite solves
  • apple/cups — Example of macOS system-level service integration; relevant for understanding privileged proxy configuration on macOS

🪄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.

Migrate SpechtLiteLaunchHelper from Objective-C to Swift for consistency

SpechtLiteLaunchHelper is written in Objective-C (AppDelegate.h/m, main.m) while the main SpechtLite app is entirely Swift. This creates maintenance burden and inconsistency. Since this is a launch helper for autostart functionality, modernizing it to Swift would improve code consistency, reduce bridging complexity, and make it easier for Swift-focused contributors to understand the full codebase.

  • [ ] Convert SpechtLiteLaunchHelper/AppDelegate.m to Swift (AppDelegate.swift)
  • [ ] Convert SpechtLiteLaunchHelper/Supporting Files/main.m to Swift entry point
  • [ ] Update SpechtLite.xcodeproj/xcshareddata/xcschemes/SpechtLiteLaunchHelper.xcscheme to reflect Swift target
  • [ ] Verify launch helper still communicates correctly with main app after conversion
  • [ ] Remove .h header files and update Info.plist if needed for Swift bridging

Add unit tests for Manager classes (PreferenceManager, ProfileManager, ProxySettingManager)

The Manager directory contains critical business logic (preference persistence, profile management, proxy configuration) but there are no visible test files in the repo structure. These managers handle stateful operations and system configuration that require reliable testing. Adding tests would improve reliability for contributors and catch regressions in core functionality.

  • [ ] Create SpechtLite/ManagerTests directory structure
  • [ ] Add PreferenceManagerTests.swift with tests for preference read/write operations
  • [ ] Add ProfileManagerTests.swift with tests for profile parsing and switching logic
  • [ ] Add ProxySettingManagerTests.swift with tests for proxy system integration
  • [ ] Integrate tests into SpechtLite.xcodeproj/xcshareddata/xcschemes/SpechtLite.xcscheme

Create GitHub Actions CI workflow to replace Travis CI (.travis.yml)

The repo uses .travis.yml for CI, which is outdated (Travis CI changed its free tier model in 2020). GitHub Actions is now the standard for GitHub repos and would provide free, integrated CI/CD. This workflow should build both SpechtLite and ProxyConfig targets, verify compilation, and optionally run linting.

  • [ ] Create .github/workflows/build.yml with macOS runner for Swift/Xcode builds
  • [ ] Add build steps for both SpechtLite and ProxyConfig targets
  • [ ] Configure workflow to trigger on push and pull requests
  • [ ] Add status badge to README.md
  • [ ] Document the new CI setup in CONTRIBUTING or development guide (if it exists)
  • [ ] Remove or deprecate .travis.yml after workflow is verified

🌿Good first issues

  • Add unit tests for ProfileManager rule-matching logic—currently zero test coverage visible; start with test cases for exact domain matches, regex patterns, and CIDR IP ranges
  • Document the rule format in README.md with examples—currently no rule syntax is explained; add a 'Configuration' section showing YAML/JSON profile structure and example rules
  • Add LocalizationKey strings to MainMenu.xib for internationalization—the XIB is hardcoded English; extract strings using Xcode's localization tools for future i18n

Top contributors

Click to expand
  • @zhuhaow — 97 commits
  • @Yohoa — 1 commits
  • [@Felix Liu](https://github.com/Felix Liu) — 1 commits
  • @imcotton — 1 commits

📝Recent commits

Click to expand
  • a8f8bc9 — Update readme (zhuhaow)
  • 7b8fde2 — Update Readme (zhuhaow)
  • df3b5bb — Merge pull request #77 from Yohoa/master (zhuhaow)
  • 389e186 — Typo fixed (Yohoa)
  • 77d99a0 — Bump version (zhuhaow)
  • 6c71cfe — Fix that launch helper is not terminated if the app is already running. (zhuhaow)
  • 141a7e0 — Reformat (zhuhaow)
  • 53a3aab — Fix that the launch helper checks for the wrong bundle identifier. (zhuhaow)
  • 79f1dda — Update MMDB (zhuhaow)
  • 8da37fb — Update MMDB library

The GeoIP library will be updated with every new version. (zhuhaow)

🔒Security observations

  • High · Archived Project with Deprecated Dependency — Repository root (README.md states 'SpechtLite is archived as NEKit is deprecated'). The project is archived and uses NEKit, which is deprecated. This means the codebase is no longer maintained and may contain unpatched security vulnerabilities. NEKit is a network extension framework that has known security issues and is no longer updated. Fix: Do not use this project in production. Consider migrating to actively maintained proxy solutions with modern network frameworks.
  • High · Encrypted Secret File Without Clear Key Management — secret.tar.enc (root directory). The presence of 'secret.tar.enc' indicates encrypted secrets exist in the repository. However, the encryption key management strategy is unclear. If the decryption key is stored in CI/CD configurations (like .travis.yml or circle.yml) or committed elsewhere, this creates a significant security risk. Fix: Ensure encryption keys are managed through secure secret management systems (e.g., HashiCorp Vault, AWS Secrets Manager). Never commit encryption keys to version control. Audit all CI/CD configurations for exposed secrets.
  • High · Privileged Helper Installation Script — SpechtLite/script/install_proxy_helper.sh. The file 'SpechtLite/script/install_proxy_helper.sh' suggests installation of a privileged helper, which is common for proxy applications on macOS. Shell scripts handling privilege escalation require careful review for injection vulnerabilities and improper credential handling. Fix: Review the shell script for: (1) Proper input validation and sanitization, (2) Secure temporary file handling, (3) Correct permission settings on executable files, (4) Absence of user-controllable paths in privilege escalation code.
  • Medium · ProxyConfig Utility with Elevated Privileges — ProxyConfig/ProxyConfig/main.swift. ProxyConfig appears to be a privileged utility for configuring system proxy settings. The presence of separate build schemes and main.swift indicates it may run with elevated privileges. Inadequate input validation in such utilities can lead to privilege escalation. Fix: Ensure all inputs to ProxyConfig are properly validated and sanitized. Implement principle of least privilege. Review for any command injection vectors in system calls or shell invocations.
  • Medium · Legacy Launch Helper with Objective-C Code — SpechtLiteLaunchHelper/AppDelegate.m. SpechtLiteLaunchHelper uses Objective-C (AppDelegate.m) and appears to run at launch time. Legacy code patterns in launch helpers may contain security vulnerabilities. The combination of Objective-C and launch-time execution requires careful security review. Fix: Review for: (1) Proper memory management (ARC compliance), (2) Secure API usage, (3) Absence of arbitrary code execution, (4) Proper verification of launched applications.
  • Medium · CI/CD Configuration Exposure Risk — .travis.yml, circle.yml, bin/sign_update. CI/CD configuration files (.travis.yml, circle.yml) are present. These files may contain references to secrets, API tokens, or signing certificates if not properly managed. The presence of appcast signing scripts (bin/sign_update) suggests code signing is automated. Fix: Ensure all CI/CD configurations use secure secret management and never commit sensitive values. Verify signing keys are not stored in version control. Use environment variables for all sensitive data.
  • Medium · Proxy Configuration Management Security — SpechtLite/Manager/ProxySettingManager.swift. ProxySettingManager.swift manages system proxy settings. If profile data or proxy configurations are stored insecurely or serialized without proper validation, this could lead to man-in-the-middle attacks or privilege escalation. Fix: Ensure: (1) Proxy configurations are cryptographically signed/verified, (2) Secure storage with proper file permissions, (3) No sensitive credentials stored in plaintext, (4) Validation of all proxy rules before application.
  • Low · Profile Manager without Visible Access Control — SpechtLite/Manager/ProfileManager.swift. ProfileManager.swift handles proxy profiles. Without access control mechanisms, unauthorized modification of profiles could affect proxy behavior. Fix: Implement access control checks to ensure only authorized

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 · zhuhaow/SpechtLite — RepoPilot