Shipped 1.x builds all carried CFBundleVersion 1: the old
Info.plist hardcoded it and the release flow only set the
marketing version. Same bundle id, so NG2 must exceed 1.
AGENTS.md keeps only the agent contract: hook enable step, gate
behavior, manual commands, rule-tuning policy. Install steps,
tool baselines, and config rationale are human-facing setup and
now live in README's 代码风格工具 section.
Update stale pointers that sent readers to AGENTS.md for tool
install (root AGENTS.md, pre-commit hook comment and error
message); hook behavior unchanged.
Pin sslocal v1.25.0 (aarch64-apple-darwin) and v2ray-plugin v1.3.2 via
committed manifests (tag + asset URL + archive SHA-256 + bundle location +
sign identifier):
- Scripts/fetch-external-binaries.sh downloads the pinned archive, verifies
its SHA-256 byte-for-byte, extracts only the named member (arm64-only
check) and stamps the local cache; archive hash mismatch fails hard, and
any manifest/local-artifact drift forces a re-verified refetch. It re-runs
as a pre-build phase so tampering fails the build itself.
- project.yml installs both binaries via Copy Files into
Contents/Helpers[/Plugins]; generate requires the artifacts to exist
(fetch before generate, else Copy Files phases are silently dropped).
- Scripts/sign-embedded-helpers.sh re-signs each helper Developer ID with
--options runtime --timestamp and the pinned identifier
(<bundle-id>[.plugin.]<name>) before Xcode seals the outer app signature.
- Scripts/packaging-gate.sh asserts strict nested signature verification,
DevID + Hardened Runtime on the app with no App Sandbox entitlement, and
exact per-binary manifest coverage under Contents/Helpers.
- Tests pin both manifests' schema and anchor hashes.
Verified: build + gate all green; byte-flip, foreign-binary and
missing-binary tampers each caught; 5 unit tests pass; no submodules or
in-repo builds; notarization stays out of scope (#39).
- ShadowsocksX-NG2/.swift-format: Apple Swift 6.4 toolchain default rules snapshot
- ShadowsocksX-NG2/.swiftlint.yml: default rules, excludes build artifacts and Legacy/
- .githooks/pre-commit: format staged NG2 Swift files into the index, then SwiftLint;
error-severity violations reject the commit; non-NG2 files pass through untouched
- ShadowsocksX-NG2/AGENTS.md: NG2-scoped conventions (tiered below root AGENTS.md)
- normalize skeleton sources to swift format baseline (2-space indent)
XcodeGen-managed SwiftUI menu bar app in ShadowsocksX-NG2/: LSUIElement,
inherited bundle id com.qiuyuzhou.ShadowsocksX-NG, macOS 15 arm64,
Hardened Runtime + Developer ID signing, empty entitlements dict (no App
Sandbox; Release disables base entitlement injection). Placeholder status
menu and main window; unit test target wired into the app scheme. Test
bundles sign with the Apple Development cert so Hardened Runtime library
validation accepts injection. Generated .xcodeproj and plists are
gitignored; project.yml is the source of truth. Legacy/ untouched.
Closes#22
Wayfinder #19: plugin program references persist verbatim, only managed
plugins are selectable, unavailable plugins are invalid activation
candidates, and plugin options are sensitive in their entirety.
- Remove GitHub Actions workflows and issue templates
- Move legacy ShadowsocksX-NG project into Legacy/
- Remove git submodules; dependencies will use prebuilt
binaries copied from upstream releases instead of
building in-repo
- Add ShadowsocksX-NG2/ directory for the new project
- Update .gitignore paths for the new layout
Improve the clarity of notifications in the QR code scanning feature:
1. Permission handling:
- Show notification when screen recording permission is missing
- Automatically open system settings for permission grant
2. Enhanced scanning status notifications:
When no QR code found:
- Title: "Scanned X displays"
- Subtitle: "No QR codes found"
- Body: "Try adjusting the QR code position on your screen"
When invalid QR codes found:
- Title: "Found X QR code(s)"
- Subtitle: "No valid Shadowsocks URLs"
- Body: "QR codes found are not Shadowsocks configuration"
When valid QR codes found:
- Title: "Found X Shadowsocks URL(s)"
- Subtitle: "Scanned X displays, found X QR codes"
- Body: "Successfully added X server configuration(s)"