Qiu Yuzhou
00fcd61a99
refactor(ng2): change bundle id to ShadowsocksX-NG2
...
Distinct id from Legacy (com.qiuyuzhou.ShadowsocksX-NG) lets NG2 own
~/Library/Application Support/ShadowsocksX-NG2/ directly; the v2/
subdir prefix is removed from all runtime paths.
- app/agent/tests targets + LaunchAgent plist renamed accordingly
- keychain service, queue labels, and Vendor signIdentifiers follow
the new bundle id; embedded helpers re-sign at build time
- Legacy handoff/import constants keep pointing at the old id
Migration: dev data under ShadowsocksX-NG/v2/ is not carried over
(fresh catalog/activation); old LaunchAgent registration and old
keychain entries must be cleaned up manually.
2026-09-21 20:33:37 +08:00
Qiu Yuzhou
6bfd3c0d35
feat(ng2): proxy runtime LaunchAgent, wrapper and sslocal lifecycle ( #27 )
...
GUI → LaunchAgent → wrapper → sslocal full chain (spec #21 D2/D5):
- ShadowsocksX-NG2Agent: Swift BundleProgram tool target embedded at
Contents/MacOS, supervised by launchd via SMAppService agent plist
(Contents/Library/LaunchAgents, bundle-relative ProgramArguments,
KeepAlive={SuccessfulExit:false}). Wrapper reads the cross-process
contract v2/sslocal-active.json, spawns sslocal -c <absolute path>
and supervises it: SIGTERM chain stop, SIGUSR1 forward for
server-only changes vs graceful restart on listen fingerprint
changes, non-zero exit on unexpected child loss for KeepAlive
replay, invalid/missing contract → clean exit with plain unlink.
- Runtime file protocol: RuntimeFileStore reuses AtomicFileWriter
(0700 dir self-heal, 0600 temp at creation, atomic replace);
explicit-stop cleanup unlinks contract, agent pid file and stale
temporaries. Shared read-side validation via
SslocalRuntimeDocument.decodeValidated so GUI and wrapper cannot
drift. Wrapper pid file bridges SMAppService's missing pid.
- GUI: ProxyRuntimeController consumes ActivationStateMachine effects
through pure ProxyRuntimePlan decision table (ordered actions,
idempotent skip of identical contract); proxy toggle and launch
failure presentation (naming endpoint:port) in the status menu;
launch resync reconciles agent registration, wrapper liveness and
on-disk contract; catalog commits re-expand immediately.
- Log sanitization baseline: closed RuntimeLogEvent enum plus Redactor,
wrapper/sslocal output converged to a 0600 agent.log with RUST_LOG
defaulting to warn.
Tests (126 total, all green): stub-sslocal driven wrapper lifecycle
(start/stop order, SIGTERM chain, crash replay, cleanup, reload
protocol), real sslocal smoke (SOCKS port binding + full SOCKS5
handshake), plan decision table, controller flows with fakes,
runtime file permissions/atomic replace, endpoint probe, redaction.
Manual release-gate items (real launchd/SMAppService): agent
registration approval flow, GUI-quit persistence, bootout behaviors.
Closes #27
2026-09-20 20:26:54 +08:00