Commit Graph
111 Commits
Author SHA1 Message Date
Qiu Yuzhou 2c75ee67ec feat(runtime): hot reload ACL rules with signals 2026-10-20 23:54:05 +08:00
Qiu Yuzhou 8508080480 fix: observe agent deployment failures without port probes 2026-10-20 23:49:00 +08:00
Qiu Yuzhou 6f33260b3b chore(sslocal): pin fork v1.26.0 2026-10-20 17:21:44 +08:00
Qiu Yuzhou f2424af305 fix(logging): preserve line boundaries and chronology 2026-10-20 16:28:11 +08:00
Qiu Yuzhou 94ef128db8 feat(system-proxy): emit privileged helper events to unified log
The root system-proxy helper logged nothing and launchd discards its
stdout/stderr, leaving helper launches, connection refusals, GUI-side
timeouts and root-side failures invisible. Share the minimal unified-log
emission unit (SystemLog) across GUI, wrapper and helper, and add a
dedicated closed helper event enum (lifecycle minimum: listener ready,
connection accepted/rejected with peer pid, typed apply/clear results)
with ADR-0045 privacy splitting. The emission seam is injected at the
helper engine and listener for test doubles. Helper events are
Console-only: no stderr, no agent.log, no diagnostic view or report
surface (ADR-0047).
2026-10-20 15:59:38 +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 1541e97fb3 test(runtime): silence unified-log writes during test runs
Add the SSXNG_SYSTEM_LOG=0 test seam: RuntimeLog.emit and the sslocal
unified-log destination skip their os.Logger writes when it is set,
while stderr lines and the event sink are unaffected. Test execution
no longer floods the unified log store (a full validate run previously
recorded 795 entries under the shared subsystem, 743 from xctest and
52 from test-spawned agents).

The switch is injected by the schemes' test actions only (Run/Profile
keep system logging so debugging from Xcode still shows it), and set
explicitly in the fixtures that spawn the agent/sslocal processes,
including the fixture that strips inherited SSXNG_* path seams. The
main scheme is now declared explicitly to keep the variable out of the
Launch/Profile actions. Document the seam in ADR-0045.
2026-10-20 12:38:21 +08:00
Qiu Yuzhou b6817568f3 docs(adr): record unified log routing decision
Record ADR-0045: unified-log routing through the emission seam with
native os.Logger and no third-party logging library, the closed-enum
dispatch with public/private text split, and the sslocal output intake
as a second free-form stream that never enters RuntimeLogEvent. Point
the systemLogRoute comment at the ADR.
2026-10-20 12:24:34 +08:00
Qiu Yuzhou d099239e3e feat(agent): route sslocal output through a dual-destination intake
Collect line framing, password redaction and oversized-line discard in
one SslocalOutputIntake and dispatch redacted lines through a
destination seam: stderr (freopen'd into agent.log, raw capture kept
for ADR-0006 local viewing) and the unified log under category "sslocal",
reusing the shared subsystem.

Upstream free text is never routed through RuntimeLogEvent and is
marked private in the unified log as a whole (ADR-0014 warns default
upstream logs may contain server addresses). Levels derive from
whitespace-separated upstream level tokens: ERROR maps to .error,
WARN/WARNING maps to .default (unified logging has no warning level),
and anything else maps to .info so the unified-log surface persists
only detected problems while agent.log stays the persistent surface.

The intake lives in Domain/Runtime so the hostless test mirror compiles
it; unit tests drive raw chunks against fake destinations instead of
parsing agent.log text. The 1 MiB agent.log retention policy deliberately
stays on the file side shared with wrapper event lines.
2026-10-20 12:18:41 +08:00
Qiu Yuzhou e0e2814b49 refactor: separate configuration, runtime, and log directories 2026-10-19 20:17:10 +08:00
Qiu Yuzhou 766d1a3d86 refactor(runtime): make deployment metadata references explicit 2026-10-19 19:59:23 +08:00
Qiu Yuzhou 8a53575d79 docs: shorten READMEs and extract topic guides 2026-10-19 19:42:38 +08:00
Qiu Yuzhou 12ae000cb0 refactor(runtime): separate sslocal output from GUI intent 2026-10-19 19:00:43 +08:00
Qiu Yuzhou 003e40d809 refactor(ng2): encrypt proxy listening configuration 2026-10-19 14:31:18 +08:00
Qiu Yuzhou 0f3454602f refactor: separate proxy preferences from listening configuration 2026-10-19 12:10:48 +08:00
Qiu Yuzhou 985153cd56 refactor(rules): separate rule values from storage models 2026-10-19 09:42:38 +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 85197d8172 docs(research): assess age encryption for sslocal runtime 2026-10-19 00:21:44 +08:00
Qiu Yuzhou f944133977 docs(ng2): update server library encryption format to v2 2026-10-18 18:07:32 +08:00
Qiu Yuzhou 507917ab67 refactor(ng2): store secrets directly in server library records 2026-10-18 17:58:30 +08:00
Qiu Yuzhou e8e4a33311 docs: document server library encryption format 2026-10-18 16:54:50 +08:00
Qiu Yuzhou 6cbef4e57a refactor(connectivity): store test URL in user defaults 2026-10-18 08:31:13 +08:00
Qiu Yuzhou d8a11f7b6b feat: encrypt persistent server library 2026-10-18 07:57:10 +08:00
Qiu Yuzhou 8ca2da494d refactor(runtime): drop ProxyModeError guards and silent desired-proxy skip
Make systemProxyConfiguration total so a runtime document can no longer
swallow derivation via try? and silently skip desired system proxy
convergence. Delete the unreachable ProxyModeError / .mode failure fact
and its presentation; port validity stays at the settings store and the
document contract.
2026-10-17 15:30:47 +08:00
Qiu Yuzhou 7bf46eb173 feat(settings): add application language selection 2026-10-15 19:07:25 +08:00
Qiu Yuzhou 297fc30c41 feat(connectivity): measure warmed HTTP latency phases 2026-10-15 17:39:13 +08:00
Qiu Yuzhou 7cf04544ce feat(ng2): add Nushell and Windows proxy environment commands 2026-10-14 12:27:25 +08:00
Qiu Yuzhou 790e2a26fa feat(home): add target catalog and connectivity testing 2026-10-14 11:19:07 +08:00
Qiu Yuzhou 3a6d143b17 refactor(settings): separate LAN enablement from listener mode 2026-10-13 21:46:04 +08:00
Qiu Yuzhou 2f0c0d7676 feat: separate local and LAN proxy listeners 2026-10-13 03:58:03 +08:00
Qiu Yuzhou dc64349702 feat(plugins): bundle Cloak v2 client 2026-10-12 12:38:32 +08:00
Qiu Yuzhou f72c50dceb feat(plugins): configure plugin transport mode 2026-10-11 23:58:47 +08:00
Qiu Yuzhou 84c292eb7f feat(plugin): support aliases and local startup arguments 2026-10-11 21:04:59 +08:00
Qiu Yuzhou e50f671975 feat(servers): add ordered favorites 2026-10-09 23:20:11 +08:00
Qiu Yuzhou 7ad7edee3c refactor(servers): use HSplitView for three columns 2026-10-09 19:23:44 +08:00
Qiu Yuzhou 801348c5b6 refactor(servers): use three-column table navigation 2026-10-09 19:07:44 +08:00
Qiu Yuzhou f23a24f203 feat(servers): add node creation and modification timestamps
CatalogEntry gains createdAt/updatedAt and the catalog document moves to
v5 (reads v1-v5, writes v5). Modification time is structure-sensitive:
editing a node's own fields bumps the node, a group's direct child set
or order changes bump the group, and a moved node keeps its timestamps.
No-op writes and unchanged subscription refreshes bump nothing; the
refresh rebuild compares per node, so surviving leaves keep theirs. All
times are passed in by callers as now: Date - one moment per logical
commit, the domain layer stays clock-free. Legacy documents load with
nil (unknown, never backfilled); duplicates and imports stamp fresh
times at the moment of the operation.

Semantics are recorded as glossary term 节点时间戳 and ADR 0031. No UI
in this change.
2026-10-09 18:04:48 +08:00
Qiu Yuzhou d06c04246d feat: move diagnostics to a standalone window 2026-10-06 15:20:39 +08:00
Qiu Yuzhou bdcbc6cd60 feat(servers): separate details from edit forms 2026-10-06 12:25:13 +08:00
Qiu Yuzhou be30f64f9f docs(design): 移除 to-spec 产物,去掉 user-plugin 文档的 -spec 后缀
两类文档来源不同,处理方式也不同:

- system-proxy-runtime-control-spec.md、terminal-command-address-spec.md 是
  to-spec 技能的原样产物(英文模板小节标题,无标题与日期头)。其内容已发布为
  Issue #72 / #73,人类需要的信息已由同日提交的无后缀中文文档承载;在仓库里再
  存一份,等于同一份规格有两个事实来源。删除后仍可从 git 历史追回。
- user-plugin-*-spec.md 四份来自 improve-codebase-architecture 会话:该技能把
  报告写进 OS 临时目录、不写 docs/design/,因此这四份是模型模仿仓库既有
  -spec.md 旧例命名(“猜测旧例”而非技能指令)。去掉后缀后仓库不再有该样板,
  后续模型少了可模仿的命名来源。四份保留原名主体,内容不动。

影响面:这六份文件全仓库零入站引用(含 docs/ 内部),移除与改名都无需改写链接。
docs/design/ 现为 12 份,无一带 -spec 后缀,与 AGENTS.md 的定位一致。

有意不做:不加“docs/design/*.md 必须带可解析 日期:/状态: 头”的确定性检查。
AI 输出本就无法保证规范化;更关键的是这类文档的“状态”只描述某次改进上下文,
不跟踪现状,把它当可校验字段是假精确。日期是写作时点的事实,两回事。
2026-10-05 22:39:58 +08:00
Qiu Yuzhou a335e00a38 chore(agents): 同步 docs/agents 配置到当前 skills 并去掉仓库硬编码
对照 ~/.agents/skills/setup-matt-pocock-skills 的当前模板逐字节核对三份配置:

- triage-labels.md 与模板完全一致,无漂移,未改动。
- domain.md 同步标点(— 改为 :)与措辞(Single-context repo (this repo)
  改为 (most repos)),现与模板一致。
- issue-tracker.md 同步标点漂移,并把硬编码的
  --repo qiuyuzhou/ShadowsocksX-NG 换成从 clone 推导
  (gh repo view --json nameWithOwner)后显式 pin。保留「绝不写入其他仓库」的
  安全规则与那次误发事故的教训,但去掉仓库名,使该配置在合并进上游后仍然成立。
  AGENTS.md 的一行摘要同步去掉仓库名。

.scratch/ 加入 .gitignore 与 .zcodeignore:这是 setup-matt-pocock-skills 为
local-markdown tracker 约定的目录,切到本地 tracker 时 spec 文件不落进 git。

docs/design/ 与 docs/research/ 的去留尚未决定,本次不引入任何排除机制。
2026-10-05 22:25:42 +08:00
Qiu Yuzhou 7ab774fcfd chore(legacy): 移除 Legacy/ 旧版源码,归档到 legacy-v1 分支
旧版实现已由 shadowsocks/ShadowsocksX-NG 的 legacy-v1 分支跟踪,本仓库不再
保留同一份代码副本。删除 Legacy/ 下 603 个跟踪文件,被 gitignore 的
.DS_Store 一并清理。

删除前核对:Legacy/ShadowsocksX-NG/PACUtils.swift 的 blob hash 与
upstream/legacy-v1 的同名文件完全相同,且工作区在 Legacy/ 下无未提交改动。

配套改动:

- 根 README、AGENTS.md、ShadowsocksX-NG2/README.md:目录结构只留
  ShadowsocksX-NG2/;旧版说明改为指向 shadowsocks/ShadowsocksX-NG 的
  legacy-v1 分支(含其 README);pre-commit 说明去掉 Legacy/。
- codegraph.json 删除 "exclude": ["Legacy/"];.gitignore 与 .zcodeignore
  删除 Legacy 构建产物与依赖条目;.swiftlint.yml 删除 ../Legacy 排除项;
  .githooks/pre-commit 头部注释去掉冻结目录表述。
- docs/research 的 4 份历史研究报告(issue 7/11/12/17)中 129 处
  ../../Legacy/... 相对链接改写为 legacy-v1 的 GitHub blob 链接,正文未改;
  把新 URL 反替换回原相对路径后与 HEAD 版本逐字节相同,证明只动了链接。

验证:全仓库不再有指向 Legacy/ 的路径引用;剩余 Legacy 字样均为概念性用法
(Legacy 导入功能、ADR 与术语表、历史报告正文中的冻结陈述)。本次未改任何
NG2 源码或构建配置,暂存区无 NG2 .swift 文件,pre-commit 直接放行。
2026-10-05 21:39:06 +08:00
Qiu Yuzhou a31e2fa4bf docs(adr): 记录源码目录即分层与主题及守卫约定
App/ 按分层、Domain/ 按主题组织,两个根层只放子目录、不放平铺文件;边界由
Tests/SkeletonTests.swift 的守卫正面圈定断言,而不是禁令加豁免登记。

ADR-0029 只记录组织原则本身:分层与主题划分的依据(Domain 主题名取自
GLOSSARY.md 的章节划分)、四条被否决的备选(平铺加豁免登记、feature-first、
Domain 照搬分层、守卫锁定目录集合),以及两条在代码里不可见的 XcodeGen
约束和跨进程契约按文件引用的代价。

ADR 不维护目录与文件清单——清单由 ShadowsocksX-NG2/README.md 的工程结构
一节维护,避免记录随事实漂移。

project.yml 的两处分层注释与 README 的工程结构一节各加一处引用:前者按该
文件既有写法引用编号,后者用完整链接。
2026-10-05 20:27:11 +08:00
Qiu Yuzhou 0f2855f453 fix(ui): 关闭服务器表单密码框的系统密码自动填充
系统对 NSSecureTextField 默认提供钥匙串/密码 App 的自动填充入口,且不
取决于字段语义:实测底层字段 contentType 已是 nil,既有
.textContentType(nil) 不足以关掉它,AppKit 也没有公开开关。

改用字段级私有开关 _setPasswordAutofillEnabled:(responds(to:) 守卫,
方法消失时静默回退、不崩溃)。PasswordAutofillOptOut 以同帧背景探针
认领承载密码控件的文本框,只关密码列自己;明文/密文切换换成新实例后
重新认领。

新增 PasswordAutofillOptOutTests 固定认领范围与切换行为;全量单测
1022 通过,人工验证通过。取舍与后果记入 ADR-0028。
2026-10-05 19:23:55 +08:00
Qiu Yuzhou a6ebb69bbf feat(servers): add group sharing popover 2026-10-05 16:57:48 +08:00
Qiu Yuzhou bd68e45ea4 feat(servers): present sharing in a popover 2026-10-05 16:41:18 +08:00
Qiu Yuzhou fd6fa65a8d feat(share): rework server share as QR sheet
- Replace toolbar QR popover with a window sheet per sketch: top hint,
  280pt white-backed QR, copy-image / save-image / copy-ss:// actions
  and a Done button; all buttons share a 260pt min label width
- Freeze share payload and suggested file name at presentation time;
  transient "copied" feedback on copy actions
- Add ImageClipboard seam (PNG normative type + TIFF in AppKit adapter)
  and QrImageSaver seam (NSSavePanel PNG, sanitized suggested name)
- Register new typed failures in the presentation whitelist; extend
  platform-effects architecture guard and seam tests
- Record spec in docs/design/server-share-sheet.md; GLOSSARY server
  share now covers saved QR image files
2026-10-05 13:54:59 +08:00
Qiu Yuzhou 86779b63ee feat(plugins): add settings management UI 2026-10-05 12:03:52 +08:00
Qiu Yuzhou 3d8d56b8e1 test(plugins): cover mapping commit and runtime convergence 2026-10-05 11:13:42 +08:00
Qiu Yuzhou e74f8dfc01 refactor(plugins): derive server form facts from effective catalog 2026-10-05 00:46:43 +08:00