16 Commits
Author SHA1 Message Date
Qiu Yuzhou 3e64743237 fix(runtime): allow initial balancer startup
Initial multi-server checks can consume the entire five-second listener
budget before sslocal binds its inbound ports. Allow 15 seconds for
listeners and 30 seconds for GUI startup health confirmation.

Include endpoint readiness diagnostics and a delayed-start regression.
2026-10-30 08:52:36 +08:00
Qiu Yuzhou 366bb43711 test(agent): replace timed reload integration test 2026-10-24 02:51:15 +08:00
Qiu Yuzhou b6b9349d64 style: resolve SwiftLint violations 2026-10-23 01:10:40 +08:00
Qiu Yuzhou 2c75ee67ec feat(runtime): hot reload ACL rules with signals 2026-10-20 23:54:05 +08:00
Qiu Yuzhou 1d85e86b8e feat(diagnostics): unify log lines into one filtered view
Collapse the four definitions of "one log line" into LogLine (timestamp,
level, source, text) with a single renderer and parser. agent.log lines
now carry the uniform prefix, absorbing the ssxng: event marker into the
source column; legacy lines degrade to raw display without rewriting.
Level detection moves into the row model with a classic three-level
taxonomy whose unified-log projection stays unchanged.

The diagnostics log view merges GUI events and the agent.log tail through
DiagnosticLogIntake into one time-ordered list with level and source
filters; the tail window logic moves into the intake and blank lines are
kept for raw fidelity. The report whitelist projection and unified-log
routing are unchanged.
2026-10-20 14:42:51 +08:00
Qiu Yuzhou e0e2814b49 refactor: separate configuration, runtime, and log directories 2026-10-19 20:17:10 +08:00
Qiu Yuzhou e0db8b1e13 refactor(runtime): publish isolated supervision generations
Separate Agent supervision from sslocal input and preserve the latest intent after deployment failure. Persist failure barriers, serialize publication and retirement, and verify reload and single-instance behavior with real processes.

Refs #83
2026-10-19 03:00:33 +08:00
Qiu Yuzhou c49d605a5b chore(ng2): remove fork issue references from comments 2026-10-13 00:38:06 +08:00
Qiu Yuzhou a8cd6262c2 feat(proxy): remove PAC and accept ACL system proxy path
Remove the PAC product feature entirely: PAC HTTP service, port, health
probe, runtime extension, PAC URL system proxy projection, PAC rule
editing, and GFWList URL settings. The product now exposes rule / global /
direct modes only, all projected as a local SOCKS system-proxy target.

First-run defaults are rule + proxyWhenUnmatched, agent on, system proxy
off. Homepage and status menu share one ProxyControlSnapshot showing the
three modes and rule sub-options. Manual servers, subscriptions, Legacy
import, and independent SOCKS/HTTP inbounds are retained.

Fix: include verbose in SslocalListenFingerprint so a verbose-only
contract change restarts sslocal instead of leaving RUST_LOG stale.

Revise CONTEXT.md vocabulary, ADR-0007, and ADR-0009. Record GFWList
exception shadowing, IPv6 system-exception, DNS, and traffic-coverage
boundaries. Add host acceptance evidence document.

Closes #67
2026-09-26 21:58:12 +08:00
Qiu Yuzhou 827fb98be3 refactor(ng2): fix all swiftlint warnings
77 → 0 warnings. Split oversized functions and files: controller and
agent extension files, standalone RuleSet/ProxySettingsFileStore/
SslocalListenSettings/LegacyImportService, test classes into topic
extensions. Regroup activation options into RuntimeDocumentOptions and
converter metadata into Provenance.

Runtime controller DI seams widen private → internal so the extension
files stay cohesive; new controller files are registered in the
architecture guard exemption list; Agent target adds RuleSet and
SslocalListenSettings to project.yml. Test JSON literals wrap inside
the string literal only.
2026-09-26 17:13:31 +08:00
Qiu Yuzhou 39e25477bb feat(proxy): add ACL-backed direct mode 2026-09-26 11:46:45 +08:00
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 5e13c1716f feat(ng2): managed plugins end to end (#38)
- 受管插件静态事实表(v2ray-plugin v1.3.2,来源/许可证/版本/重签)与
  BundleManagedPluginProvider:受管集内且 bundle 内可执行文件在位才返回
  绝对路径;与 Vendor 清单双向锚定(D6/D10)
- 服务器编辑器插件区:受管选择器(无 + 受管列表),选中受管项才显示
  供应链事实与参数输入;集外引用显式「本版本未提供」并原样保留
- updateServer 插件落盘语义:「无」整体清除、参数写删钥匙串、集外不漂移
- wrapper 监听建立判定:3 秒未建立本地监听记 error 日志,监管继续(D10)
- 诊断导出新增受管插件清单(名称/版本/提供状态,无参数)
- 功能级兼容实测记录(docs/research/plugin-compat-record.md)与端到端
  冒烟:契约插件路径 → sslocal 拉起 → v2ray-plugin 进程建立 → 停止链
2026-09-21 10:38:30 +08:00
Qiu Yuzhou 2531eb35fb feat(ng2): add settings page and preferences (#33) 2026-09-21 08:54:12 +08:00
Qiu Yuzhou 8578de0ba4 feat(ng2): add PAC runtime and listen scope (#28) 2026-09-20 22:26:45 +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