Just for Fun

OpenFX

intpfx/OpenFX/domains/dsh-openfx/packages/ambient-theme · ★ 0

intpfx

Fluid aurora, particle grid and whale point-cloud background for DeepSeek Harness web.

An English summary is not available; the Chinese summary is shown.

README body is shown in Chinese.

License
Apache-2.0
Added
2026-10-30
Maintenance
active
Install kind
github
Manifest status
Declared
Manifest path
package.json#dsh
Manifest checked
2026-10-30T14:19:05.227Z
Lifecycle scripts
None found

Static manifest checks report declarations only; they are not compatibility or security review.

安装

dsh plugin --profile web add 'github:intpfx/OpenFX#582f6350464105fb8763f6016ce35e69505668be&path:/domains/dsh-openfx/packages/ambient-theme'

GitHub 源码安装:首次需按提示配置 allowBuilds 构建授权后重试

For install and environment setup, plus plugin development tutorials, see DSH community docs ↗

README

Source README · body: zh · Read Chinese README

Table of contents
  1. 当前产品
  2. 私有设备网络
  3. 重复与相似文件
  4. 实况图片边界
  5. macOS 版本
  6. LivpExplorer 迁移与退役结论
  7. 仓库结构
  8. 开发
  9. Web 服务边界
  10. 特殊模块
  11. maci

OpenFX 是一个以 TypeScript 为主的个人项目集合。当前主产品是使用 OPFS 的 Web 文件库, 并由 Perry 提供复用同一 Web 产品的 macOS 版本;仓库同时保留可独立运行的 domain、历史 项目和可复用能力模块。

当前产品

web/ 提供 VitePlus + React 客户端和 Nitro 服务端,部署目标为 Deno Deploy。首页不是可静默枚举硬盘的本机文件浏览器,也不是营销页,而是由应用自管理的文件库:

  • 用户可从默认空间 HUD 直接唤起系统照片选择器,也可通过通用文件选择器、拖放、PWA 文件处理器或系统分享入口显式导入内容;浏览器不会静默读取完整 Photos 图库;
  • 支持 File System Access API 的安全顶层浏览器可以由用户明确连接一个本地文件夹,以只读 内容墙查看并逐项复制到 OPFS;目录句柄保存在同源 IndexedDB,浏览器可能在重开后再次请求 授权。不支持该 API 时,Bloub 来源按钮直接退化为通用文件导入;
  • 原始字节和索引保存在当前 origin 的 /openfx-file-library/ OPFS 空间,不保留本机路径映射;
  • 图片、实况图片、视频、音频、文本和 PDF 可在应用内预览;音频导入后会在本机后台读取 曲名、歌手、专辑、内嵌封面与内嵌歌词;网格优先以专辑封面展示,无封面时使用稳定纯色 与大字号曲名,HUD 与全屏播放器沿用同一音乐视觉;音乐播放控件复用视频播放器的 Video.js 10 状态与皮肤体系,并通过音频预设适配为紧凑时间轴、前后跳转、倍速和音量控制; 无时间轴歌词以大字号滚动正文展示,不伪造逐字同步;
  • 不支持预览的格式仍保留原件并提供下载;
  • 音频标签/封面/歌词、视频缩略图、字幕关系、播放位置、观看状态和媒体智能视图由文件库 索引维护;
  • 照片在导入落盘后由可取消 Worker 解析 EXIF、位置和 Motion Photo;HEIC/HEIF 同时在本机 生成 JPEG 预览代理,原始字节保持不变;任务状态持久化,中断后可恢复、失败后可重试;
  • 照片可按拍摄日期、实况、收藏、位置和相册派生查看,不复制原始字节;
  • 20 个内置 App 作为只读虚拟条目合并到同一内容墙,不占用 OPFS 配额。
  • 用户可以在本机创建不依赖账号的私有设备网络,或生成一次性配对请求加入已有网络;成员 证书和网络密钥保存在本机 OPFS,设备私钥作为不可导出的 CryptoKey 保存在同源 IndexedDB 密钥保险库,Deno Deploy 不保存私有网络状态。

文件库内容墙使用无间距正方形网格。OPFS 文件与受限远程目录条目会显示在同一内容墙,格子 右下角以绿色圆点表示原件已在 OPFS、蓝色圆点表示原件在其他设备;切换到用户选择的本地 文件夹后,空心圆点是“复制到 OPFS”的 44 px 触控目标,并依次显示导入中、成功或失败状态。 本地文件夹条目不会进入索引、私有设备目录、指纹或缩略图后台任务,只有明确点按圆点后才由 session 复制为独立 OPFS 快照;每次切回文件夹会重新扫描只读视图,但外部原件后续变化不会 自动同步进已有 OPFS 副本。远程格只投影受限元数据和派生缩略图,点按后仍进入私有网络面板 按需读取,不会自动传输原件。少量内容只占需要的列,未占用区域保持磨砂背景。

触屏可像照片应用一样双指缩放,在 2–5 列之间切换并保存本机显示偏好。完全相同或视觉相似 的内容会自动合并为一个联系表式网格格子;点按组格后,页面顶部 HUD 同时列出全部成员, 再点按其中一个才进入单文件查看器。普通内容仍直接更新 HUD 预览,点按可打开内容的 HUD 任意空白或预览区域会进入全屏详情;收藏操作只保留无底色的心形线条图标。视频与实况照片 被选中后会在 HUD 中默认静音循环播放;实况照片格只在左下角保留类型标识,不再叠加右上角 LIVE 标签。尚未选择内容时,HUD 默认显示设备当前月份的完整月历,日期下方使用天气图标; 上下滑动、滚轮或键盘翻页键可逐月切换。浏览器取得定位权限后直接向 Open-Meteo 请求本地当前 天气和日级天气码,定位、网络或预报范围不可用时只显示中性占位,不伪造预测,也不经过 Deno Deploy 保存坐标。已用空间、浏览器估算配额、剩余配额、持久存储状态、设备数和文件数收缩为 月历下方的边缘文字控件,设备控件同时是打开私有网络面板的入口。默认背景由铺满 HUD 的动态 像素点阵构成,已用空间按照片、视频、音乐、文档和其他文件着色,剩余容量统一使用白色点。各 颜色的点数只按真实字节占配额的比例取整,不为极小类型人为补点;动画只改变位置、明暗和呼吸 尺度,不改变容量比例,并尊重系统减少动态效果设置。当前只有本机浏览器能提供真实 OPFS 配额,远端目录中可见或已缓存的文件字节不会伪装成远端设备总容量。再次点按已选内容或组格会 取消选择并回到该概览;App 若只是说明型项目,不再进入独立详情页,而是由 HUD 直接展示 catalog 的名称、技术栈、 项目说明、关键能力、来源路径和可用入口;只有真实同源预览或可操作组件保留打开入口。 摘要型 App 的 GitHub 链接不占用正文空间,而以 GitHub 线性图标显示在右下角收藏图标旁; Greasy Fork、Userscript 下载等其他入口仍保留在摘要内。 当前选中格不使用高亮描边,而是轻微放大上移并覆盖相邻网格,形成从内容墙中被拾起的层次反馈。 来源控制和搜索合并为未选择内容时 HUD 底部的无边框横条。Nebula-Orb 以呼吸、聆听、扫描和 无结果震荡表达真实搜索状态;Bloub 在支持 File System Access API 时连接并切换 OPFS/本地 文件夹,不支持时直接触发导入,并以待机、思考、轨道、涡旋和警觉表达真实来源状态。两个 渲染器各自暂停隐藏帧、尊重减少动态效果,不循环播放无关形态。上游项目、版权、MIT 许可及 Bloub 的设计权利边界保存在根 NOTICE。搜索命中组内任意成员时 会保留整个组。选中单项后不再显示独立的打开按钮;保存链接、新建文本和手动查重入口及其创建 功能均不再提供。所有操作使用轻量线性图标,悬停只高亮图标线条。当前网格项数直接 写入搜索占位文案;页面不提供手动明暗开关,只实时跟随系统主题。移动端竖屏时 HUD 预览固定在顶部;手机竖屏的完整月历模式占约 58% 视口高度,为日期、天气和底部控件保留可触摸 尺寸,横屏与宽屏使用 2fr / 3fr 的左右分栏。下方或右侧内容矩阵以直角边界无缝衔接并独立 滚动。单文件 查看器不再使用独立的底部文件胶囊,而是沿用播放器的黑色玻璃控件语言:非视频内容把返回与 文件身份固定在左上角,收藏、信息、编辑、下载和删除组成右上角动作组;视频的返回、编辑、 下载和删除直接进入播放器内部的左上控件组,并通过同源、当前 iframe 与条目 ID 三重校验的 消息交回文件库执行。非 App 条目可在编辑面板 修改文件名,图片与实况图片还可同时维护相册,保存只更新索引与下载名,不重写原始字节。

私有设备网络

OpenFX 不使用账号区分设备。首台设备创建 PrivateMesh 后成为所有者,并生成网络根密钥、 本机签名/加密密钥、根签名的成员证书和恢复码。新设备自行生成密钥和十分钟有效的一次性 请求码;所有者设备验证请求签名、核对双方一致的六位验证码并明确批准后,才签发成员证书。 网络密钥通过临时 ECDH P-256 与 AES-256-GCM 加密给新设备,不以明文放入配对响应。

网络描述、成员证书、网络密钥和本机密钥引用保存在当前 origin 的 /openfx-private-mesh/state.json OPFS 文件中,与文件原件索引分离;实际设备私钥以不可导出 CryptoKey 保存在同源 IndexedDB。刷新会重新验证根签名成员证书及本机公私钥匹配关系, 损坏或篡改的状态不会被静默覆盖。旧版 v1 OPFS 状态会先把 JWK 导入不可导出保险库,完整 校验后保留 state.v1-backup.json 原文备份,再写入不含私钥材料的 v2 状态;迁移失败不会 覆盖原身份。

普通成员默认可以存储文件但不能邀请新设备;只有持有根签名密钥引用且证书允许邀请的所有者 设备可以批准加入。恢复码包含所有者权限材料,使用用户设置的恢复口令经 PBKDF2-SHA-256 派生 AES-256-GCM 密钥后加密,创建后只在当前面板显示;恢复码与口令必须分别离线保存。 不可导出可以阻止脚本读取原始私钥字节,但不能阻止已在同源执行的恶意脚本调用密钥,后续仍需 把 CSP、依赖供应链和 origin 隔离作为联网前的安全门。

当前实现还提供首个同一局域网传输切片:成员可人工交换由设备签名、十五分钟有效的 openfx-rtc-v1 offer/answer,建立不经过服务器的 WebRTC DataChannel。连接后先按条目传输 文件名、类型、大小和更新时间;接收设备会在连接码有效期内保留待接管通道,页面刷新或 session 停止才会提前取消等待。只有用户点按“读取”时才以 12 KiB 分块取回不超过 4 MiB 的 单文件原件。接收端逐块校验 SHA-256、更新有序哈希链并写入未索引的 OPFS 源文件;当前块 完成 flush 且双槽检查点落盘后才确认发送下一块。只有声明长度、分块数与最终哈希链全部 一致,才登记文件库索引。读取前会按剩余字节与 256 KiB 安全余量预检浏览器估算配额。

读取期间按钮会切换为“取消”。用户明确取消或关闭面板会向提供设备发送取消消息并删除未完成 内容;意外断线、超时、暂存写入失败或 session 停止则保留最近一次已确认检查点 24 小时。 用户重新交换连接码并再次点按同一远端条目的“读取”后,提供设备会重算已确认前缀哈希链, 匹配同一原件才从下一块继续;崩溃后多写但未确认的尾部会先回滚。过期、缺失、元数据改变或 与原件不匹配的暂存不会进入索引。此切片不传本机 OPFS 路径,不自动复制文件,也暂不传 Live Photo 组合或超过 4 MiB 的文件。连接默认只收集本机候选地址; 用户可以在双方设备上明确允许公共 STUN 辅助寻址, 当前固定使用 Cloudflare STUN,只帮助 WebRTC 发现可直连地址,不传目录或文件,也不提供中继。若设备网络阻断 STUN UDP,公共模式 可能在候选收集阶段超时;同一局域网内可关闭该选项,继续使用本机候选直连。

每次成功读取的远端目录都会作为该设备的完整快照写入 /openfx-private-mesh/catalog.json。页面重开或设备离线后仍可显示最近一次受限元数据,但会 明确标成“离线缓存”并禁止读取原件;重新连线后的新快照会整体替换该设备旧快照。加载和成员 变更时只保留当前网络仍获授权的远端成员,撤销设备的缓存随即从展示和持久记录中移除。这个 缓存只是派生展示状态,不是成员权限、文件存在性或同步完成的事实来源;损坏缓存可以忽略, 不会覆盖本机文件索引或阻止打开已验证的网络身份。

在线连接期间,本机受限目录确实变化后只发送轻量失效事件,不把目录或原件塞进通知;接收端 仍通过 DataChannel 请求、校验并整体替换该设备的完整快照。同一设备在一次刷新期间连续产生 的失效事件会合并为至多一次补充刷新,避免导入和后台处理造成并发请求风暴。这个自动汇合只 覆盖当前仍在线的一跳连接,不会自动复制原件,也不等于离线传播或跨重启自动重连。

图片与已有视频预览还会在文件所在设备上按需生成最长边 320 px、不超过 128 KiB 的 WebP 派生缩略图。目录只保存缩略图版本描述,不内联图像字节;远程设备 连线时,文件面板通过同一端到端 DataChannel 自动按需读取,并在 /openfx-private-mesh/thumbnails/ 下单独缓存。每次 session 最多发起 32 个唯一远程 缩略图请求;损坏、超限、不支持或离线时只退回扩展名占位,不会请求、覆盖或丢弃原件。 HEIC/HEIF 仅使用已有 JPEG 代理生成派生缩略图,原始静态帧仍用于下载、指纹和 LIVP。 目录版本更换或成员被撤销时,不再可达的派生缩略图也会从本机缓存移除。

所有者设备可以撤销普通成员。撤销会先把网络 epoch 单调增加、生成新的 256 位网络密钥, 再由根密钥为全部保留成员重新签发当前代次证书;旧成员证书因此不能再与已更新设备建立新 连接。每台保留设备获得只用其 ECDH 私钥才能解开的 openfx-epoch-v1 更新码。已连接设备在 本机持久化新状态后通过 DataChannel 返回确认,离线设备则由用户手工粘贴专用更新码;未确认的 更新码会继续保存在所有者 OPFS,设备以新代次重新连接后才移除。由于没有中心状态源,撤销时 同时离线且尚未更新的旧代次设备之间仍可能暂时互通,不能把本机撤销误述为全网即时抹除。

当前还没有实现自动设备发现、跨重启自动重连、TURN 中继或 Iroh 公网连接、离线目录传播或 多跳汇合、全库缩略图收敛与容量策略、超过 4 MiB 的大文件传输、副本策略、恢复码导入、撤销状态 自动汇合或多所有者协作。即使允许公共 STUN,受 NAT 或防火墙限制的设备仍可能无法直连,刷新后也需要重新交换连接码。后续传输层 必须保持可替换,并把公共发现或中继视为不可信的端到端加密数据通道;Deno Deploy 继续只提供 Web 应用和既有公开产品入口,不新增账号、设备目录、信令、文件索引或网络密钥服务。

重复与相似文件

文件库会在导入完成后以可取消的后台任务生成版本化指纹:

  • 所有普通文件使用 SHA-256 检测字节完全一致的副本;
  • 图片使用 256 位 PDQ 感知哈希识别缩放、压缩或轻微调整后的相似内容;
  • 视频在 8%–92% 的相对时间位置抽取最多 8 帧,按 PDQ 序列、时长容差和多数帧匹配;
  • 实况图片必须同时满足静态图与动态片段相似;完全重复还要求两部分 SHA-256 均一致;
  • 旧索引升级后会自动补算指纹;失败项在每次会话启动时自动重试一次,单个文件失败不影响其 原件、下载和其他分析任务。

SHA-256 完全相同关系与视觉相似关系会共同形成互不重叠的连通组。只有组内所有成员的原始 字节指纹都相同时才标记为“完全相同”,否则标记为“相似内容”;每个组在内容墙只占一个格子, 组内原件仍各自保存在 OPFS。自动归组不会删除、覆盖或替用户保留某个版本,用户仍需从组 HUD 逐项打开确认并使用现有删除操作,避免感知哈希误判造成数据损失。

首页 HUD 还提供独立的“照片来源核对”面板,用于比较用户明确选择的两个临时只读来源:一侧 是从 Apple Photos 手动导出的普通文件夹,另一侧是 USB 上的文件夹。这个流程不会直读或枚举 iCloud 共享图库,不会把所选内容导入 OPFS,也不会保存目录句柄、清单或核对结果;关闭或清空 面板后即丢弃当前状态。不支持 File System Access API 时退化为用户明确选择文件夹内容的浏览器 输入。目录按顺序读取并保留来源类型与相对路径;同目录同名的图片与 MOV/MP4 先组成一个逻辑 Live Photo,OpenFX .livp 则解包后按原始静态帧与动态片段比较。只有两部分原始字节的 SHA-256 都一致才显示“完全重复”;PDQ 图片/视频相似结果只显示为人工审阅候选。该面板不提供 导入、移动、覆盖、删除或自动保留版本操作,原有 macOS 系统选择器的一次一张 Live Photo 导入 入口保持不变。

实况图片边界

当前文件库已经实现:

  1. 同名图片与 MOV/MP4 的导入配对;
  2. JPEG Motion Photo 的 XMP 检测、尾部 MP4 提取与 OPFS 保存;
  3. OpenFX 旧二进制与 ZIP .livp 双格式探测和导入,并以无压缩 UTF-8 ZIP 作为 canonical 导出格式;
  4. HEIC/HEIF 原片的本机 Worker 解码,以 JPEG 代理正常显示静态帧,同时保留原片用于下载、 SHA-256 和 LIVP;
  5. 静态图与动态片段的全窗口查看,包括桌面悬停、移动端长按、松手复位、静音和触觉反馈;
  6. 实况图片可下载为原片静态帧 + MOV/MP4 的 ZIP、JPEG + MOV/MP4 的兼容 ZIP,或包含原片 静态帧与动态片段的单文件 OpenFX LIVP;
  7. JPEG EXIF 的方向、尺寸、拍摄时间、相机、镜头、曝光、评分和 GPS 解析;
  8. 持久化照片分析队列,以及收藏、相册、日期和位置派生视图。

OpenFX 二进制 .livp 与 ZIP 容器不是同一格式,因此导入时先探测再解码。ZIP 读取支持 stored 和 deflate 条目;未知变体仍作为普通文件安全保存。这里的 .livp 是 OpenFX 交换格式,不应对外宣称已经支持无授权枚举 Apple Photos 图库、Quick Look 或所有第三方 变体。普通浏览器中的“Photos”入口仍由用户在系统文件选择器中明确授权具体文件,安装为 PWA 后也可接收系统分享;macOS App 则使用下面的原生 Photos 选择边界。

macOS 版本

domains/openfx-macos/ 使用 Perry 提供持久化 WKWebView,并在固定的 http://127.0.0.1:15501 origin 加载当前 Web 构建。原生桥接只监听 loopback;用户点按 “Photos”后,系统 PHPickerViewController 只允许选择一张 Live Photo,再通过 PhotoKit 读取该资产的原始静态帧与 paired video。两个资源以流式响应交给 Web,转换为同名 File[] 后继续调用 file-library-session.ts 的既有导入入口,由同一 OPFS store 完成配对、 落盘、预览代理和后台分析。选择器由独立的 AppKit 窗口承载,不依赖 Perry WebView 暴露的 contentViewController;取消后原生桥会释放窗口和请求状态,因此可以立即再次打开。 主窗口保留原生红绿灯和系统窗口行为,但隐藏标题与独立标题栏;WKWebView 延伸到窗口顶部, 让系统红绿灯直接嵌入文件库 HUD 的内容背景中,并在红绿灯右侧保留透明原生拖拽区。loopback 静态服务会把 /hlc/ 这类目录 URL 解析为目录内的 index.html,避免嵌入式 App 错误回退到 文件库根页面。

这实现了“一次选择完整导入”,但没有绕过系统授权,也不会枚举未选择的照片。原生资源接口 使用每次启动随机生成的 session token,不使用 base64 搬运大文件。WKWebView 与 Safari、 Chrome 各自拥有独立的物理网站数据容器,因此它们共享存储模型和代码,不共享同一份 OPFS 字节;macOS App 自身重启后会继续使用自己的持久库。

LivpExplorer 迁移与退役结论

原 domains/LivpExplorer/ 是从 ChronoFrame 导入并改名的独立自托管照片库,使用 Nuxt 4、Vue、SQLite/Drizzle 和独立 pnpm workspace。它从未成为 Web 首页的运行依赖。

可迁移的本地照片能力已经由 web/src/file-library/ 和 domains/_shared/livp-codec.ts 接管:同名配对、Motion Photo、Live Photo 交互、EXIF/GPS、 相册/收藏/派生视图、可恢复处理任务,以及 LIVP 双格式导入和 canonical 导出均不再依赖 原 Nuxt 应用。迁入实现使用浏览器 File、Worker 和 OPFS 边界,没有复制 Vue 页面、Drizzle 模型或 SQLite 服务。

分享/reaction、账号体系、SQLite、S3/OpenList、服务端公开 URL、反向地理编码供应商和 管理后台属于另一个多用户产品,不迁入本地优先文件库。若未来需要同步,应作为可选 适配器重新设计,而不是保留对 LivpExplorer 的依赖。

迁移回归验证完成后,domains/LivpExplorer/ 上游源码快照已于 2026-08-10 物理删除, deno.json 中仅用于跳过该独立工具链的两条排除项也已移除。迁入代码的 ChronoFrame MIT 归属继续固化在根 NOTICE,不依赖旧目录存在。

仓库结构

domains/          独立产品、历史项目和共享能力
  _shared/        运行时边界明确的共享算法与基础设施
  BewlyScript/    B 站桌面原站美化 userscript
  dsh-openfx/      DSH Web 五个能力包与一键组合包
  e/              运行时无关的 Agent 执行框架
  maci/            macOS 菜单栏内存、开发服务与窗口翻译
  media-player/   文件库专用最小播放器
  openink/        本地优先压感绘图工作台
  openfx-macos/   Perry WKWebView 与原生 Photos 导入桥
web/              OPFS 文件库与 React + Nitro Web 产品

主要 domain:

Domain 定位 与 Web 首页的关系
_shared 文件库 LIVP 容器编解码边界 被 Web 文件库引用
BewlyScript Vue userscript,输出单文件安装包 内置 App 与安装入口
chinagas-wms-qrcode WMS 物料二维码 userscript 内置 App 介绍
costing-assistant 浏览器本地工程计价助手 动态预览 App
dsh-openfx DSH Web 主题、壳层、批注、用量与浏览器套件 六个内置 App 介绍
e Agent core、reference runtime 与前台协议 内置 App 介绍
finlyzer 本地优先账单分析 Electron 应用 动态预览 App
gasmap 燃气工程单线图工具 动态预览 App
hlc 圣灯社区 PWA/CMS 只读同源展示 App
how-much 商品价格查询与地图报告 Web API 与内置 App
map-poster OSM 地图海报生成器 Web API 与内置 App
maci macOS 菜单栏工具、软件、容器与下载管理 独立本机运维工具
media-player OPFS 视频读取、Video.js 控件和播放引擎 文件能力,不重复作为 App
openink 本地优先压感绘图、OPFS 多画稿与导出 动态预览 App
openfx-macos Perry macOS 壳与原生 Photos Live Photo 复用完整 Web 文件库
wanone 早期静态站点纪念项目 动态预览 App

Web 文件库还索引 Smartisax、LiveSystem 和 WanderingPlan 等外部项目。App 的公开文案、 preview 和链接保存在 web/content/library-apps.json;ID、详情 renderer 与嵌入策略由 web/library-app-catalog.ts 统一校验。

文件库界面在手机竖屏让完整月历 HUD 占约 58% 视口并固定在顶部;手机横屏和桌面宽屏统一 切换为 2fr / 3fr 的左侧固定 HUD、右侧独立滚动矩阵。默认 HUD 以月历和本地天气为主体, 真实存储点阵位于月历背景,搜索与统一导入入口贴合底边;单项操作悬浮在所选内容预览内。 两种布局都保持内容格为正方形,并支持双指缩放调整列数。

Web 入口的几个深 Module 分别承担稳定边界:

  • src/file-library/file-library-session.ts 管理 OPFS 加载、用户 mutation、存储状态、 私有网络创建/配对、照片/音频标签/指纹/视频缩略图队列,以及文件处理器和播放器消息;React 首页 只订阅 snapshot;
  • src/file-library/private-mesh.ts 保存运行时无关的网络身份、根签名成员证书、一次性配对和 ECDH 密钥传递;private-mesh-key-vault.ts 保存不可导出密钥句柄并提供 IndexedDB adapter, private-mesh-recovery.ts 负责口令加密恢复材料,private-mesh-store.ts 只负责独立 OPFS 状态、v1 备份迁移和加载校验;private-mesh-catalog.ts 定义受限远端目录与成员过滤, private-mesh-catalog-store.ts 持久化派生目录与缩略图缓存,private-mesh-thumbnail.ts 在本机生成有界 WebP; private-mesh-transport.ts 负责成员签名的人工 WebRTC 信令和 DataChannel 生命周期, private-mesh-transfer.ts 负责目录元数据、目录失效事件、派生缩略图、带逐块确认/完整性校验与取消 协议的分块按需读取和已确认的在线 epoch 更新,private-mesh-staged-file.ts 负责把流式 sink 收束为可提交、可保留续传或可丢弃的暂存状态机;OPFS store 使用双槽持久检查点、 配额预检与 24 小时过期清理,private-mesh-catalog-sync.ts 合并同一设备的密集目录刷新;
  • library-app-catalog.ts 将 App 内容清单和 renderer 能力收成一份可校验 catalog;
  • publication-targets.ts 是 Nitro 静态资产、Vite 开发代理和构建前准备目标的共同事实源;
  • domains/openfx-macos/ 只负责 WKWebView 生命周期、loopback 静态服务和 PhotoKit I/O, 导入后的文件状态与 OPFS mutation 仍由 Web session 管理;
  • domains/map-poster/src/web-service.ts 管理地图海报输入与生成 use case, viewport.ts 管理纯 Web Mercator/瓦片计算,Web 服务层只注入 Nominatim adapter。
  • domains/openink/src/drawing-document.ts 保存版本化文档、原始压力点、不可变历史、变换纯函数与 perfect-freehand 派生轮廓命中;drawing-library.ts 以不可变正文修订和双槽目录管理多画稿、原子提交与旧 localStorage v1 迁移,opfs-text-store.ts 只适配同源 OPFS;stroke-renderer.ts 复用同一轮廓并收束 SVG 导出,React 页面只处理 Pointer Events、渲染、交互编排与下载。

开发

前置依赖为 Deno。根目录常用命令:

deno task dev
deno task dev:client
deno task dev:server
deno task build
deno task check
  • dev 先准备 HLC 与播放器静态资源,再同时启动客户端和服务端;
  • dev:client 只启动当前源码的 Vite 客户端:http://localhost:5501;
  • dev:server 只启动 Nitro API 与静态资源服务:http://localhost:3000;
  • 日常开发应进入 5501;3000 主要供 5501 的开发代理使用,不作为前端热更新入口;
  • 并行实例可分别用 OPENFX_VITE_DEV_PORT 与 Nitro 标准的 PORT 改写端口;
  • 根 deno.lock 管理 Web 与 Deno workspace 依赖。
  • 根目录和 web/ 只以各自 deno.json 为配置源;根 package.json 与 package-lock.json 已移除,并由 deno task guard:deno-only 防止回归。
  • Web 客户端通过 Deno 脚本调用 VitePlus Core,不依赖 vp 对 package.json workspace 的发现行为。

根 deno.json 同时保存 Deno Deploy 的构建与动态运行时配置。本机 Deno 2.9.5 可直接 上传当前 checkout 并创建预览 revision:

deno task deploy

命令从仓库根上传源码,在 Deploy 构建环境运行 deno task build,随后以 web/.output 为运行目录、server/index.ts 为动态入口。Nitro 使用 Deno 文件系统静态 资源处理器读取同目录下的 public/,避免把大型 Worker、WASM 和媒体资源内联进 server entry 而拖慢 Deploy warm-up。根配置固定发布到 universes/openfx;只有明确准备切换生产 流量时才追加 --prod。CI 或 Agent 使用 DENO_DEPLOY_TOKEN,并追加 --json --non-interactive。

domains/media-player/.openfx-public/ 保存最小播放器的确定性发布快照。普通开发和 GitHub CI 会从 domain 源码重新构建它,CI 同时检查快照无差异;Deno Deploy 直接复用该 快照,避免在 3 GiB builder 中再次运行独立 pnpm 安装。

这里的“统一”为根产品工具链收口,不是删除所有 domain 的独立构建边界。下列产品仍由其 自身配置和工具链构建;需要包清单或独立锁文件的上游项目继续保留:

独立工具链:

范围 常用命令
domains/BewlyScript bun install、bun run dev、bun run check:userscript
domains/dsh-openfx pnpm install、pnpm test、pnpm typecheck、pnpm build
domains/media-player deno run --no-config -A openfx/build.ts、deno run --no-config -A npm:pnpm@9.15.9 test
domains/map-poster bun test、bun run typecheck
domains/maci deno task check、deno task install、deno task status
domains/finlyzer pnpm dev、pnpm dist:win
domains/openink deno task check、deno task build
domains/openfx-macos bun install、bun run check、bun run build

Web 服务边界

公开入口包括:

  • GET /api/health
  • /api/how-much/*
  • POST /api/map-poster/render
  • /media-player/*
  • /hlc/*
  • /openink/*

Map Poster 生产环境需要:

  • OPENFX_MAP_POSTER_NOMINATIM_SEARCH_URL
  • OPENFX_MAP_POSTER_NOMINATIM_REVERSE_URL

生产构建使用有界 Deno 入口:请求体在进入 Nitro 前限制为 64 KiB,并使用运行时真实远端 地址覆盖外部伪造的转发地址。

特殊模块

  • media-player 只保留 OPFS 读取、字幕、续播、Video.js 10 控件以及 playsvideo@0.4.7 的直通、解封装、分段和必要音频转码。完整 PlaysVideo domain 已物理删除;固定引擎保存在 vendor 包中。

  • HLC Web 展示只复制地图和艺术资产,不发布认证、内容工作流或写入接口。修改 domains/hlc/source/index.html 后运行:

    deno run --no-config --allow-read --allow-write domains/hlc/tools/build-display-app.ts
    
  • BewlyScript 只交付 userscript,不恢复 WebExtension popup/options/商店打包。 m.bilibili.com 只显示请求桌面站提示,不挂载主 Vue App。

  • domains/e 的 core 必须保持运行时无关;文件系统、模型、Git、MCP 和副作用通过接口 注入,危险动作经过 SafetyActionGate。

  • domains/openink 以原始压力点作为画稿事实,perfect-freehand 只负责生成可重算的轮廓;选择移动与缩放只修改变换。画稿库在同源 OPFS 中保存不可变正文修订与双槽目录,支持缩略图列表、新建、重命名、复制和原子恢复;首次打开 会在 OPFS 成功吸收后迁移并清除旧 localStorage v1 单画稿;兼容存储产生的新稿也会在 OPFS 恢复后先并入现有画稿库。用户显式选择的纸张照片会以原始字节留在本机,并通过手动 四角透视、背景/阴影清理、阈值、降噪和粗细控制生成可重建蒙版与 SDF;套索可整笔选择原生 笔画,并把圈内照片墨迹切成可统一移动、缩放和删除的片段。画稿 v3 用从底到顶的显式图层 组织原生笔画与照片墨迹,支持活动层、新建、重命名、排序、显隐、锁定和确认删除,旧 v1/v2 画稿会无损迁入默认层。“默认、黑板、蓝图、正文、纸张、像素、素描、沃霍尔”是八种画稿级 统一材质,分别使用粉笔颗粒、发光网格、凸版压痕、横线渗墨、整组栅格像素、石墨纹理与套色 网点等确定性 SVG 工艺;实时画布、画稿缩略图和导出保持一致。SVG 是 canonical 导出,PNG 由包含照片墨迹的 SVG 本机派生;尚未实现自动边缘 识别、旋转、逐图层材质、整张画稿删除、标签、云同步或 Carbo 专有格式读写。

  • domains/openfx-macos 的 bun run build 会先构建并暂存 Web 公共资源,校验 Perry 与 Swift/C ABI 桥,产出 ad-hoc Hardened Runtime 签名的 dist/OpenFX.app;正式分发仍需单独 配置 Developer ID、notarization 或 App Store 签名。

maci

原生 Agent 接口

maci 将可自动化操作作为原生接口维护。Agent 与面板调用同一套配置迁入、代理接管和恢复事务, 无须依靠界面坐标。入口为应用中的 Contents/MacOS/maci agent …,构建后也可用 domains/maci/bin/maci agent …。先读取 agent capabilities 获得当前版本的完整参数及读写影响; 能力的 available 表示该版本包含实现,实际后台是否运行、签名和许可是否满足仍以操作结果为准。 连接能力的 effects 会声明 vergeImportedProfileEnablesLoopbackTCP7897,供 Agent 在接管前识别固定兼容监听。

命令 当前支持
agent capabilities 当前构建的能力、协议版本和参数查询,不连接后台或启用可选功能
agent app status 当前版本、版本类型、正式安装位置及 GUI 进程状态
agent app update-preview --source /absolute/maci.app 只读验证界面更新候选、正式安装及后台保持条件,返回五分钟预览与状态令牌
agent app update-apply --source … --preview-token … --expect … 复验候选与运行状态后更新正式 GUI,保持同一代理和显示后台,重开 GUI 并核验结果
agent app update-status 只读查询更新回执及其 stateToken;未知结果不自动重放
agent app update-reconcile --expect … 只确认已完整交换、实际 GUI 和保留后台均经重新核验的更新回执,不重放安装或重启进程
agent proxy profiles 配置 ID、修订号、名称和功能开关;不返回订阅或配置原文
agent proxy status 真实后台、接管方式、路由模式、运行代次、共享状态、本机兼容端口和恢复提示
agent proxy feature-status 离线读取功能启用状态、恢复提示与前置令牌,不解析订阅或启动后台
agent proxy feature-enable --expect … 显式启用功能,仅保存选择,不注册后台或连接网络
agent proxy feature-disable --expect … 与面板共用锁和恢复事务,确认停止接管后停用;失败或未知保留处理入口
agent proxy import-preview --source verge 只读预览当前 Verge 来源、现有迁入及五分钟提交令牌
agent proxy import-commit --preview-token … --expect … 重验来源、当前手选、Geo 和目的库代次后迁入;拒绝重复覆盖
agent proxy connect --profile-id … --capture system|tun --expect … 使用已批准且正在运行的代理后台接管,不自动注册或停用其他代理
agent proxy disconnect --expect … 通过同一恢复事务断开并核验实际结果
agent proxy mode --mode rule|global|direct --expect … 持久保存并读回路由模式
agent archive capabilities 两个版本的归档格式与限制,不启动 Worker
agent archive preflight --intent-fd N 读取有界 JSON 意图、建立匿名源快照并返回五分钟预检与状态令牌
agent archive create --intent-fd N --preview-token … --expect … [--password-fd N] 重验完整意图、源内容、目标目录和期限后创建并回读发布结果
agent archive extract --intent-fd N --preview-token … --expect … [--password-fd N] 经相同事务解压单包或所选分卷组,不执行包内程序
agent archive status [--job-id UUID] / agent archive result --job-id UUID 读取有界作业回执与最终路径,遗留未结束作业显示为未知
agent archive cancel --job-id UUID --expect … 比较作业状态后请求取消,等待执行器确认清理
agent archive recovery --destination /absolute/path 只读检查指定目录的恢复记录与完整状态令牌
agent archive recover --destination … --record-id … --decision removePublishedRecord|discardInterrupted --expect … 重验目录、记录与锁后,仅清理明确选中的自有记录或未发布暂存
agent software status / agent software list 按实际软件来源读取本机清单、更新候选与操作回执
agent software preview --id … --operation upgrade|uninstall 预览来源操作、依赖与影响,返回五分钟令牌
agent software apply --id … --operation … --preview-token … --expect … 复验库存及回执,在同一来源执行并读回
agent software reconcile --expect … 只核对未知操作是否已经完成,不重新升级或卸载
agent software acknowledge --id UUID --expect … 人工核对当前状态后结束指定未知回执,保留未知结果与历史
agent containers status / list / images 检测系统、Apple container 版本、容器及镜像,不启动运行时
agent containers logs --id … [--tail 100] 显式读取指定容器的有界日志,不进入状态回执
agent containers preview --operation … / apply --operation … --preview-token … --expect … 安装包准备、服务启停、容器创建及启停删除;完整选项由 capabilities 枚举
agent containers reconcile --expect … 核对未知容器操作的实际结果,不重放操作
agent containers acknowledge --id UUID --expect … 人工核对后结束未知回执,不重放容器操作或抹去历史
agent downloads status / agent downloads list 读取任务、进度、速度、连接数和状态令牌,不启动下载进程
agent downloads preview --url … --destination /absolute/directory [--name …] 校验目标与文件名,预览不覆盖的新任务
agent downloads add --url … --destination … --preview-token … --expect … [--name …] 持久保存任务后启动独立下载进程
agent downloads pause|resume|cancel|retry|remove --job-id UUID --expect … 经状态比较控制任务;移除历史不删除已完成文件
agent downloads reconcile --job-id UUID --expect … 只在发布身份、长度和内容摘要重新匹配时确认已完成,不重放下载或重命名
agent displays status 读取已运行后台的显示场景、能力与状态令牌,不注册或启动服务
agent displays preview --mode only|mirror|extended --display-id N [--mirror-target N] 预览自有虚拟屏的唯一、镜像或扩展场景
agent displays apply --mode … --display-id … --preview-token … --expect … [--mirror-target …] 复验实际布局后进入 15 秒显示试用
agent displays confirm|cancel --pending-id UUID --expect … 核验保留试用或恢复之前布局,拒绝过期状态与重复操作

归档意图使用 UTF-8 JSON,最多 64 KiB,只接受已声明的字段,拒绝未知及重复键。例如创建 ZIP 的意图:

{
  "schemaVersion": 1,
  "operation": "create",
  "sources": ["/absolute/source.txt"],
  "destination": "/absolute/output",
  "outputName": "example.zip",
  "format": "zip"
}

可选字段为 level(0–9,默认 5)、solid、encryptHeaders、zipLegacyCrypto、preserveMac、 volumeBytes 和 requiresPassword;不适用于所选格式的组合会拒绝。解压使用 operation: "extract"、 一个所选归档路径和输出目录名,省略创建专用选项。预检只统计源条目或输入卷及其字节, 并未解码或验证压缩包内的全部成员。格式、加密与分卷的支持以实际能力表及验证结果为准。

调用方将 JSON 放入已打开的只读文件或管道 FD,例如 maci agent archive preflight --intent-fd 3 3<intent.json; 随后用同一意图重新打开 FD,传入返回的 previewToken 与 stateToken 执行 create 或 extract。 需要密码时,意图显式设置 requiresPassword: true,提交阶段另传 --password-fd。 密码是最多 4,096 字节的 UTF-8 原文,允许换行、不允许 NUL;FD 必须由调用方供应,不放进 argv、环境或 JSON 意图。 Service 仅在有界内存和私有管道中接收;自动化调用不弹出密码窗口,也不自动重试错误密码。

归档 Agent 通过自身包内已验签 Service 执行,无须安装或注册 Finder Services。发送私有请求前, 会验证当前应用的签名资源封装及 Service 的实际进程身份;仅保持相同 ID 的重签替换仍会被拒绝。Finder 与 Agent 共用准备、受限 XPC Worker、发布、恢复及完整事务租约;基础版不因此引入代理依赖。 作业回执位于本机 archive/jobs.json,最多保留 64 项;已确认终态超过 24 小时可在接受新作业时清理, 未确认作业不自动淘汰。回执不保存密码、源内容或完整意图;pending.json 仍仅保存原有请求 ID、动作和 URL。 读取缺失状态不会创建文件。取消标记可能已写入但同步或读回失败时返回 unknown,调用方不得自动重试。 创建与解压在 150 秒期限到达时取消,调用方等待有界清理; 停止仍未确认时返回 unknown,Service 保持租约直到获得真实停止证据。遗留请求必须由用户显式审阅, Agent 遇到未处理的 pending 记录返回 recoveryRequired,不自动重放;恢复暂存也不授权重跑原请求。

读取返回的 data.stateToken 是下一次写入的 --expect;配置迁入使用 profiles/preview 的令牌, 网络操作使用 proxy status 的令牌,不能混用。一个命令只执行一个事务,不自动重试。 例如先运行 maci agent proxy status,再以其令牌运行 maci agent proxy disconnect --expect '<stateToken>'。状态已变化时返回 conflict,应重新读取并决定下一步。 所有命令可附加 --api-version 1 和 UUID 格式的 --request-id;请求 ID 仅关联回执,不提供重复执行授权。

stdout 只有一份 JSON,包含 schemaVersion/requestID/domain/action/ok/outcome/data/error,最大 1 MiB。 outcome=applied 表示事务持久提交并读回验证;成功读取的 notApplied 表示没有业务写入。 unknown 表示可能已产生部分或全部效果,必须先检查状态及恢复材料,不能自动重放原命令。 退出码 0 表示成功,64 表示参数或协议版本错误,69 表示不可用/缺少前置条件,75 表示冲突或忙碌, 70 表示其他失败或结果未知;应以 JSON 中的错误代码和 outcome 为准。参数、响应和执行期限都有上限, 取消后等待事务清理,不能把进程退出当作网络已恢复。

普通读取与业务命令不会打开面板或新建终端;显示场景命令只连接已经运行的显示后台,显式界面更新会退出并重开 GUI。 基础版对代理返回 notIncluded。 代理状态仅尝试连接已存在的正式后台,后台未运行或未获批准时返回明确失败;系统授权仍由用户在 macOS 完成。 目前音乐、闪念、终端交互、翻译以及代理维护/共享设置尚未纳入这一统一协议;原有诊断入口仍保留, 不能把它们表述为完整的 Agent 接口覆盖。以后新增或变更功能必须按 AGENTS 中的同源事务、能力登记、 前置条件、结构化回执和自动化行为测试标准同步实现。

软件管理区分 Homebrew 工具、Homebrew 应用、App Store 与独立应用,按精确应用路径合并来源记录。 Homebrew 普通 formula/cask 可预览后升级或卸载;固定版本、含安装器或自定义卸载流程的应用会说明限制。 普通独立应用可预览后移到废纸篓,保留个人资料;系统应用、maci 自身和可能含后台或扩展的应用交由原来源管理。 App Store 使用本机收据与可选 mas JSON 清单,更新入口打开系统商店,不接管商店账户或管理员授权。 没有 Homebrew 或 mas 时保留本机应用清单,不自动安装软件源。状态与未知操作回执存于独立的 ~/Library/Application Support/maci/software/;GUI 与 Agent 共用库存复验和跨进程事务锁。 软件与容器操作的未知结果可先重新核验;仍无法证明完成时,用户可核对当前实际状态并明确结束该回执。 结束操作只记录人工确认,原业务结果仍为未知,保留历史并拒绝旧预览重放;后续操作必须重新预览。

容器管理适配 Apple container 1.4.1 的结构化接口,需要 Apple 芯片与 macOS 26 或更新版本。 未安装时可准备固定版本的官方签名 PKG,校验 SHA-256 和系统安装信任后,由用户点按交给系统 Installer; 管理员授权在系统安装器完成,安装后重新检测,启动服务是独立动作。其他版本明确显示待适配,不猜测 JSON 模型。 首轮提供镜像清单、单容器创建、启停、删除及日志;创建可设置名称、CPU、内存和 loopback TCP 端口映射。 删除前要求停止并预览,保留持久卷;容器可写层会随删除消失。服务停止、首次 Linux 环境准备也需显式选择。 这不是 Docker API 或 Compose 兼容层。操作回执和已验证安装包位于独立的 maci/containers/ 资料目录。

下载区是全宽矩形树图,位于开发服务与终端之间。任务面积按总字节比例分配,色相区分任务,色深表达进度; 较大块显示名称、大小、进度、速度及连接数,小块通过点按查看详情。新增入口也是树图内同纹理的小色块,只保留白色加号。 HTTP(S) 下载使用系统 URLSession 和独立的按需进程,面板隐藏或 GUI 退出不停止已启动的下载,不注册新的登录后台。 任务和续传检查点存于 ~/Library/Application Support/maci/downloads/,带查询参数的完整链接只保存在私有任务资料中, Agent 状态不返回它们。目标文件夹由用户选择;临时文件在目标卷,完成后校验并以不覆盖方式发布,保留 quarantine。 安全续传要求服务器支持 Range 和稳定的 ETag 或 Last-Modified;源变化会拒绝拼接。最多同时执行三个任务,每任务一个连接, 不宣称多连接提速、限速、BT/磁力、网页媒体解析或浏览器全局接管。重启系统后的中断任务需明确恢复。 界面更新在下载活跃或结果未知时延后;更新锁同时阻止新任务提交,避免更新期间出现下载竞态。 结果未知的任务可核对最终文件;只有目录、文件身份、长度和 SHA-256 全部匹配保存的检查点时才确认完成, 其他情况继续保留未知状态,不重新下载、不覆盖、不删除文件。 新增模块的行为验证入口为 deno task test:management,使用模拟软件源/容器与隔离的本机 HTTP 下载夹具。

domains/maci/ 是独立的 macOS 用户级菜单栏工具。内存监测只保留每 5 秒 显示一次 100 - 系统可用内存百分比,该数字是已用估算而不是剩余内存;菜单栏不再展示 压力等级、颜色状态、事件数量或诊断结果。

点开菜单栏面板会按当前用户的 TCP 监听进程扫描本机开发服务,显示项目/运行时和实际端口; 当前支持识别 Vite、Nitro、Nuxt、Next、Prisma Dev、常见本机开发服务器,以及位于用户项目 目录内的 Deno、Node、Bun 等运行时。每个服务名称左侧的停止方块会展开同格确认,确认后再次核对 PID、完整命令和监听端口,再只发送一次 SIGTERM。进程未按时退出时只提示失败,不会升级为 SIGKILL、终止整个进程组或删除项目文件。

内存子系统不订阅 Dispatch memory-pressure 事件,不保存新事件、快照、队列或报告,也不 调用模型。翻译是独立的用户触发工作流,不接入内存采样。

maci 常驻于菜单栏,无独立主窗口或 Dock 图标。默认按 ⌥T(Option + T),或点击 面板“翻译前台窗口”,通过 ScreenCaptureKit 截取当时前台应用最靠前的普通窗口,再用 Apple Vision OCR 与所选翻译引擎按文字块翻译。译文出现在原窗口位置的临时 翻译预览上,图片与界面布局保留在截图中;菜单面板提供终端区、闪念区、翻译入口、设置和服务控制。 面板紧贴菜单栏入口,保持顶部锚定,固定 340 点宽、28 点连续圆角。顶部为 maci 名称、单色形象锁定开关,以及窗口翻译、电影字幕、显示设置、翻译设置与退出图标。 软件管理与容器管理使用顶部显示器旁的网格、立方体图标,详情沿用面板内覆盖层。 这行工具栏默认隐藏,鼠标移入或在面板内移动时以 180 毫秒淡入,静止 1.5 秒后淡出; 停在工具栏上、键盘聚焦其中控件、展开详情或长按退出时保持显示。翻译/字幕运行时与 VoiceOver 开启时也保持可见;Tab 可在没有鼠标操作时唤出工具栏,减少动态效果时直接切换显隐。 工具栏覆盖在月面上,不挤动正文;状态反馈和显示试用确认独立可见。面板关闭时清理计时与输入监听。 悬停显示动作与快捷键;设置图标在面板内覆盖式展开目标语言、快捷键、窗口引擎、对白语言及模型下载;切换设置或权限详情不会改变面板尺寸或挤动终端。 翻译或字幕运行时图标高亮,状态和失败反馈收在顶部;正文依次呈现音乐、闪念、开发服务、下载树图和底部终端。 各区只用细分隔线区分,不显示区域标题和计数;没有开发服务时收起对应空白占位。 低频的显示设置收在顶部显示器图标中,与翻译和字幕控件并排;点击后在面板内展开可滚动的 玻璃覆盖层,不改变主体高度。显示试用确认始终独立可见,不被设置覆盖。 屏幕与系统音频共用一项授权,由顶部 maci 字标颜色表示:黄色表示待授权、正在检查或需重开应用, 绿色仅表示系统预检已授权。点击 maci 字标查看详情、主动授权或重新检查;打开面板和返回应用只读取 权限,不自动弹出授权请求,也不把麦克风、辅助功能或输入监控列为必需权限。 未授权时窗口翻译与电影字幕启动按钮置灰;已有任务的取消、停止入口仍可用。 本机开发构建默认临时签名,修改二进制后可能使旧屏幕授权失效。明确选择稳定本机签名时, 在 domain 内手动运行 deno task setup-signing,为 maci 创建专用身份;该步骤不能由构建或安装 自动触发。身份只保存在 ~/Library/Application Support/maci/signing/,不上传、不使用现有私钥; 后续构建固定使用该证书,签名失败时停止,不悄悄退回临时签名。配置脚本不修改证书信任; 自签名证书如需信任,必须另外明确授权,仅授予当前用户、该证书的代码签名用途。 签名工具临时将专用钥匙串加入搜索范围,结束时移除自身条目并重新上锁,不改变默认钥匙串。 首次从临时签名切换到固定证书仍需在 macOS 重新登记已安装应用并重开;后续版本以证书约束保持身份一致。

面板顶部保持水平;点击 maci 形象切换锁定,点亮后保持展开。默认点击外部收起,锁定后仍可按 Esc 或再次点击菜单栏百分比关闭。锁定状态仅保留在本次运行中,重启恢复未锁定;关闭菜单 不停止已启动的电影字幕。顶部退出入口是一个 16 点实心红点,保留 30×32 点点击范围;长按时放大到 20 点, 外围同步显示从顶部开始的进度环,让指针遮住圆内时仍能看到进度。按住 2 秒,进度环转满一圈后短暂微光并退出整个应用、结束终端和字幕。 提前松开或拖出按钮时进度环逐渐回退,圆点保持红色;切换应用、关闭面板或失去焦点取消长按。 键盘聚焦后也可按住空格;普通点击不退出。 LaunchAgent 仅在异常退出时恢复,正常退出后等待下次手动打开或登录。内核文件锁避免系统 “退出并重新打开”与后台恢复产生重复实例。安装时只刷新正式 App 的 LaunchServices 注册, 清理同 bundle ID 的构建目录旧注册,不全局清空图标缓存。开发服务使用 28 点高的连续单行, 小停止方块、名称与全部端口依次横排,服务间以短竖线区分,不设卡片底色或边框。 长名称、多端口及更多服务都不换行,超出面板宽度时在区内横向滚动,滚动条隐藏。 停止方块保留 22 点宽的点击范围;点击后左侧原位显示红色“停止”,条目末尾显示取消叉号, 再次点击“停止”才执行。确认预留固定位置,不改变条目尺寸或挤动其他服务;只有真实服务才占位。 不再提供手动刷新按钮:打开面板立即检查,面板显示时约每秒、隐藏时约每五秒自动扫描。 扫描在独立队列串行执行,只发布变化,不影响停止确认;退出时停止扫描,停止服务期间拒绝旧扫描结果。

音乐直接融入整块面板,移植 Gift 的流体月面着色器、手写字体与低语/手写/散字歌词场景。 月面铺满面板宽度并延伸至顶部工具栏背后,不设独立黑底或圆角卡片;歌词与歌名直接浮在玻璃上。 音乐底部用细线与闪念分隔,尚未选歌时不显示“音乐”占位标题。 封面主色形成的柔和光晕延伸至下方原生工具区,工具栏在固定位置自动显隐,音乐之后依次为闪念区、服务横排、下载树图和终端。 不另设搜索按钮或底部控制条:点击歌名前的灵动点展开透明径向搜索星盘,月面保留在背景; 输入后自动搜索,拖动、滚轮或聚焦星盘后按方向键旋转结果,松手惯性吸附到歌曲。 再次点击圆点、选择歌曲或按 Esc 返回播放画面;搜索关闭后 Esc 才收起整个面板。 短按月面产生触点波纹并播放/暂停,绕月面转动按累计角度调节进度,一圈对应整首歌曲。 月面边缘显示真实播放进度;拖动与长按不会误触播放。长按 520 ms 切换流体月面与专辑封面, 播放和暂停时行为一致,歌词、歌曲信息、进度和播放状态始终保留;无封面时保持原月面。 暂停冻结流体并缩至 84%,进度环保持原尺寸;拖动时流体纹理随歌曲进度转动, 封面模式使用 18 秒唱片旋转并释放流体 GPU 资源,切回时完成首帧后显影。 减少动态效果设置下停用运动; 键盘可聚焦月面,用空格播放/暂停、左右键调整 5 秒、Home/End 跳至首尾。

歌词沿用 Gift 的三幕结构与逐字显影,短面板内只缩放排版以保留完整歌词。 散字渐变为手写字体的外伸笔画预留绘制范围,字距与换行不随之扩大。 点击歌名缓存完整音频、封面和歌词,歌名按封面主色填色并在完成时发光;已缓存时再次点击仅删除 maci 的本地歌曲缓存。 搜索空白内容显示本机歌曲,搜索结果本地优先,网络失败仍可选择已缓存歌曲;重开 maci 后可以直接离线播放。 缓存位于 ~/Library/Application Support/maci/music-cache/,每首音频与封面合计最多 64 MiB、封面最多 8 MiB、 总缓存最多 512 MiB;先检查可用空间和下载完整性,使用临时目录及原子索引提交。 失败和取消不登记半首歌曲;索引损坏保留原件并阻止覆盖,删除不触碰其他应用或用户音乐文件。 正在播放本地缓存时删除会先释放该音源,之后可重新在线播放。

在线搜索使用 Gift 同款 GD Studio 公开音乐接口,音源固定为网易;仅主动搜索、选曲或缓存时请求网络, 不依赖 Gift 开发服务、账号或生日阶段。音频由原生 AVPlayer 播放,不申请麦克风或屏幕权限。 搜索与切歌取消旧请求并拒绝迟到结果。包内 WKWebView 承载视觉和月面/灵动点/歌名交互, 消息桥只接受这些明确动作,不允许网页指定音源或文件路径;隐藏面板暂停视觉动画,播放会话继续。 退出 maci 释放音源并取消未完成的缓存。Gift 字体作为用户本机资源迁入;源码中未附公开再分发许可, 公开分发前需核实字体授权。

显示设置与无屏常驻

点击顶部显示器图标打开显示设置;收起设置只隐藏控件,不断开虚拟屏。 设置沿用现有玻璃面板内的覆盖层,列出系统在线屏幕, 显示逻辑尺寸、HiDPI 与刷新率,悬停查看实际渲染像素;分辨率菜单只使用系统报告适合桌面的模式。 使用原生 CoreGraphics 切换分辨率或镜像,均为显示后台进程生命周期内的临时配置,不写永久显示器覆盖。 创建虚拟屏使用隔离的 CGVirtualDisplay 私有运行时桥,先校验类和方法签名;接口不可用时禁用新建, 保留现有屏幕管理。无需管理员服务、内核驱动、录屏或辅助功能权限,不会绕过 macOS 的接口限制。

首版最多保存两块虚拟屏,提供 16∶9、16∶10、3∶2、竖屏和自定逻辑尺寸;宽高各为 480–2560, HiDPI 将两维渲染像素翻倍,总量最多 16,384,000 像素。每块最多六种同比分辨率,固定 SDR、60 Hz。新建屏使用扩展桌面,自有虚拟屏的模式菜单提供“唯一 / 镜像 / 扩展”。 唯一模式把所选虚拟屏保留为有效桌面,其他显示通过隔离的 CGSConfigureDisplayEnabled 桥退出桌面; 接口不可用时明确禁用,不用黑屏或设主屏代替。镜像模式以所选自有屏为源,扩展模式解除该自有屏的镜像。 切回镜像或扩展先恢复进入唯一模式前的布局,再应用所选模式。不接管其他工具的虚拟屏对象; 普通镜像/扩展不会拆散与所选自有屏无关的镜像组,唯一模式的预览则明确列出停用其他桌面的影响。 断开只释放自有对象,删除在对应条目内确认。

新建、重连、分辨率和三模式切换均先试用 15 秒,顶部固定覆盖层确认保留;实际模式、启用状态或镜像未就绪时不能确认。 未确认自动恢复,关闭面板不取消倒计时;显示布局变化时确认层保持锚定。回退失败会保留错误与重试入口, 即使原屏恢复失败也独立尝试释放本次新建屏。菜单进程退出、GUI 连接失效或睡眠时撤销尚未确认的更改。 Agent 发起的场景试用由服务计时,不随单次 CLI 退出取消,仍须在 15 秒内另行 confirm。 已确认的唯一或镜像场景也只保留在服务会话中,睡眠、最后 GUI 退出、停止后台或断开自有屏前先恢复原桌面; 恢复无法核验时保留自有屏与恢复状态,不冒险释放最后桌面。不跨后台重启自动重放场景。 SIGTERM/SIGINT 也先恢复并核验;系统强杀、SIGKILL 或进程崩溃无法保证完成恢复。 保留场景恢复布局时,界面更新要求先切回扩展并确认,以免退出 GUI 时恢复布局破坏更新的显示保持条件。 ~/Library/Application Support/maci/displays.json 原子保存虚拟屏定义、启用意图、“登录后恢复”及“无屏常驻”偏好;旧版配置可直接读取。 创建确认后才保存,配置损坏时保留原件并禁止覆盖。默认不自动创建,开启恢复后重建已启用的自有虚拟屏。 启动、唤醒和意外离线的恢复最多尝试五次、二十秒截止;实际读回逻辑尺寸与 HiDPI 渲染像素后才报告成功, 失败后的布局通知不会无限重试。可在面板点击恢复或运行 bin/maci --restore-displays,重新尝试已保存且启用的屏幕。

虚拟屏、配置写入和试用倒计时由独立的 maci-display-service 用户级后台持有,面板通过本机 XPC 发送操作和接收状态;场景 Agent 使用同用户私有 Unix socket 连接已运行的后台,并调用相同 Host 与事务。 读取不会登记或唤醒服务。旧后台没有场景能力时需显式维护更新,日常 GUI 更新不会偷偷替换后台。 后台不加载音乐、终端或翻译。无屏常驻默认关闭,须先确认至少一块启用的虚拟屏。 开启后自动启用登录恢复,退出菜单应用会继续保留已确认的虚拟屏;关闭常驻时,退出菜单应用释放自有虚拟屏。 在常驻模式下断开或删除最后可用的自有虚拟桌面、关闭常驻保障,均需原位二次确认;后台停止也会重新核验屏幕。 手选分辨率和镜像关系仍不跨后台重启恢复,完整显示配置、主屏和排列预设尚未实现。

安装时通过 SMAppService.agent 登记包内的菜单与显示后台两个用户 LaunchAgent, 均在用户图形登录后启动,异常退出由 launchd 拉起。系统按所属 com.siaovon.maci 应用归组并读取自定义图标,不再依赖旧式外部 plist 的 AssociatedBundleIdentifiers 与 Team ID。注册状态只读检查;用户关闭后台许可后,重新打开或更新应用不会自动恢复许可, 须在系统设置的“登录项与扩展”中重新允许 maci。 更新完成前会核验菜单进程的实际路径与稳定运行状态;若系统明确报告旧启动签名约束失效, 安装器在重新验签和核验许可后仅重建一次菜单注册,再检查启动结果。其他失败保留诊断副本, 不会反复注册或重启未变化的显示后台。 正常退出不自动拉起,重新打开面板也不会重启已明确停止的显示后台,需主动点刷新。 这不提供 FileVault 解锁前或登录前的虚拟屏,不修改自动登录、系统信任、UU 远程或其他远程软件设置。 真实无实体显示器冷启动、睡眠唤醒和 UU 远程重连仍需在对应使用环境验收。

显示器逻辑与恢复测试使用注入 adapter,不改真实布局,包含在 deno task check 中,也可单独运行 deno task test:displays、deno task test:display-service 与 deno task test:display-modes。 bin/maci --list-displays-json 是只读枚举;bin/maci --display-service-status 读取后台状态,不启动已停止的后台。 deno task test:display-lifecycle 用临时 LaunchAgent 和模拟显示后端验证跨进程退出、崩溃重启及重连,结束移除测试任务。 显式加 --native 会临时创建一块 TEST 屏,在测试后台异常退出后核验其重建、HiDPI 和原有屏幕未改变; 该命令不读取用户显示配置,也不属于默认检查。另一显式硬件验证命令 xcrun swift run --scratch-path dist/swift-build --configuration release maci-display-integration --exercise-owned-displays 临时创建两块 TEST 屏,只对这两块进行模式、镜像、恢复和重连验证,结束清理并核验原有屏幕未改变; 不包含在默认检查中。HDR、画中画、串流和物理屏任意 HiDPI 解锁不属于首版。

终端位于现有面板最底部,始终展开,启动 maci 时预备一个本机 /bin/zsh -l -i 登录交互式 shell;关闭最后一个标签后自动补上新的待用会话,退出应用时不补建。点击标签末尾的纯加号可添加标签。 标签放在输出下方,组成 28 点高、全宽贴底的连续玻璃带;选中项使用轻微底色,标签间以细竖线分隔, 不再使用悬浮圆角方块。关闭按钮保留 24 点点击范围,加号紧跟标签;较多标签可横向滚动, 切换时显示选中项,选中末尾标签时同时露出加号。关闭确认和异常信息位于标签带上方。 底栏、选中背景与原生材质统一使用 28 点连续圆角遮罩;材质自己的 maskImage 随实际尺寸与缩放更新,并刷新窗口阴影。显式桌面合成测试在不同高度下检查边角亮块与保留阴影, 常规检查覆盖离屏遮罩及 1×/2× alpha;离屏检查不替代安装后的桌面实图验收。 视口默认预留五行,按真实字体行高计算,超过的输出在终端内部滚动;首次 PTY 尺寸与界面保持一致。竖向滚动条及右侧占位隐藏,滚轮、触控板回看输出与交互程序的鼠标行为保持可用。 不显示区域标题、会话计数、折叠、常驻操作提示或中断按钮,异常与退出状态仍显示。 shell 从用户主目录开始,加载用户自己的 shell 配置。PTY 在 shell 启动前按面板的实际尺寸初始化,避免首个提示符留下独立的 %; 命令未以换行结束时,zsh 正常的行尾标记仍保留。最多同时打开六个独立标签,分别保留工作目录、环境变量和 终端屏幕;支持彩色输出、中文、方向键、历史命令、交互式程序与 ⌘V 粘贴。保留上方全部工具和 340 点面板宽度,终端透明背景透出面板磨砂材质,内容过高时在面板内滚动;切换标签或关闭面板都不重启会话。 ⌃C 发送终端中断字符;关闭标签需面板内确认,随后挂断该 PTY 和前台任务。退出 maci 结束全部会话,显式脱离终端的守护进程遵循 shell 自身的生命周期。 每个标签保留最多 1,000 行回滚内容,maci 不额外写命令记录或输出日志、不在重启后重放命令; shell 自己的历史文件仍按用户配置工作。终端使用固定版本 SwiftTerm 1.20.0,许可证随 App 打包; 仅用户主动复制/粘贴访问剪贴板,不接受终端转义序列读取或修改剪贴板。

统一分发与可选代理模块:默认只构建一个完整版,deno task build 输出 dist/maci.app / bin/maci。代理默认关闭并隐藏;普通设置、工具栏和首次使用流程不显示代理入口。 未启用时只保留轻量功能状态读取,不创建代理面板、订阅刷新器或后台连接,也不注册代理服务。 build:proxy、install:proxy 和 bin/maci-proxy 保留为同一完整版的兼容入口。 内部裁剪验证仍可显式使用 MACI_FEATURE_PROXY=0 或 deno task build:base,输出隔离的 dist/base/maci.app / bin/maci-base,完整省略代理 domain、UI、Yams、mihomo 和 LaunchDaemon。 包内 MaciEdition=proxy/base 是更新协议兼容标记,不代表功能当前已启用。 构建从新暂存目录装配并核验实际包文件与二进制符号;旧 dist/proxy 不再作为输出。 两种内部构建保持同一显示后台构建路径与签名约束。

高级使用:打开翻译设置中的“关于 maci”,按住 Option 点击版本号,再点“启用网络代理功能”。 普通点击版本号没有副作用;关闭“关于”或收起面板后隐藏解锁项。也可先运行 maci agent proxy feature-status,再将返回的 stateToken 传给 maci agent proxy feature-enable --expect '<stateToken>'。启用只显示功能,不自动连接或请求系统授权。 代理设置内的“停用并隐藏”先等待自有工作取消、网络恢复和状态读回,完成后移除全部代理入口; 失败或结果未知保留状态与恢复操作,不能把隐藏当作停止成功。GUI 在重开面板和收到状态变更提示时重新读取, 不信任通知内容。独立 proxy/feature.json 保存选择,恢复检查点阻止未知结果自动重放; 旧代理资料只按已有启用字段迁入,显式关闭的意图保持关闭,不删除配置和订阅。 兼容发现会有界读取旧资料字节,但只解码启用元信息;已有独立功能状态时不再打开旧配置。 deno task test:proxy-feature 使用临时目录和模拟后台验证隐藏入口、延迟加载、恢复与跨进程状态重读, 不需要停止本机正在运行的代理;完整隔离内核回归仍要求测试端口可用。

代理构建默认使用上游标准内核。Apple Silicon 上可显式使用 MACI_PROXY_CORE_VARIANT=go122 deno task build:proxy 生成同版本兼容内核的诊断包; 两种内核各自固定下载摘要并隔离缓存,包内来源信息记录实际变体。该选项不安装应用、 不更改后台许可,也不代表已决定采用兼容内核分发;基础版不读取或携带这些内核。

启用后在终端底栏右侧提供状态入口,左侧标签单独横向滚动。控制面板向上展开, 配置、节点、规则、连接和 DNS 在覆盖层内滚动,不增加主面板高度。 首页只保留连接开关、线路入口和“更多”;关闭连接须原位确认,取消后继续运行。 底栏使用纯文字显示“探测出口地区 · 接管方式 · 路由模式”,不重复叠加模式图标; 接管方式来自实际状态,普通本机会话显示“本机”,不会把其他代理的 TUN 显示成 maci 接管。 展开后显示出口 IP、物理 Wi-Fi/以太网的局域网 IP、上下行速度、最近 60 秒共用刻度趋势、 本次内核运行累计量及当前连接数。LAN 地址可选择复制,多接口与 IPv6 信息可悬停查看; 展示地址不开放局域网代理共享。计量使用十进制 B/KB/MB,仅代表内核记录的接管流量, 包含经内核直连的流量,不是全机带宽、每日用量或订阅额度。 出口通过 maci 本机 SOCKS 端口访问固定的 Cloudflare trace HTTPS 端点, 服务端会看到该请求的出口 IP;不上传局域网地址、订阅或节点名,不绕过代理直连回退。 仅在自有内核运行且主面板可见时查询,最多每分钟一次,线路、模式、内核或本机网络变化后重新检测。 地区仅代表这一探测目标的出口,规则分流与 IPv4/IPv6 可能存在多个出口;读取失败显示未知, 旧探测不能覆盖新的线路。地址与最多 61 个图表采样只保留在内存,隐藏面板停止采样, 恢复后裁剪过期数据;缺测不补零,内核重启或累计值回退时清空旧代次。 配置、节点、规则、连接与 DNS 的完整现有控制收在“更多”中;界面简化不删除这些能力。 完整版本通过独立系统后台运行固定 mihomo 1.19.29, 本机混合端口为 127.0.0.1:17897。首次连接默认选择系统代理,可在断开时于“更多”切换为 TUN; 选择偏好单独持久保存,打开面板、重开功能或导入配置不会自动接管。 首次连接保留来源配置的路由模式;手动切换并读回成功后,按配置记住规则/全局/直连选择, 停止或重开功能不清除这项偏好。失败或结果未知的切换不保存为下次连接模式。 连接前先完成普通用户候选校验,随后才由显式连接动作登记后台;已存在其他代理内核时拒绝日常接管。 支持原始 YAML/部分节点链接导入、订阅更新与自动更新间隔、规则/全局/直连模式、 策略组选择与测速、连接断开、规则查询、DNS 查询及缓存清理。配置原文及选择保存在 ~/Library/Application Support/maci/proxy/profiles.json,原文不会被规范化后的运行配置替换。 订阅支持条件请求、流量/到期元数据和有界下载;自动更新原文后需重新应用生效。 节点链接目前支持 SS、Trojan、VLESS、HTTP(S)、SOCKS5;无法保真转换的参数或协议明确拒绝。

全局和单配置增强分别支持递归合并 YAML 与 main(config, name) JavaScript,按 全局合并、全局脚本、单配置合并、单配置脚本的顺序执行;最后重新覆盖应用拥有的控制端口、 鉴权、监听与 TUN 字段。脚本在独立 JavaScriptCore 子进程运行,限制输入、输出和时长, 超时/取消结束自有工作进程,不向脚本暴露本机文件、网络或 Objective-C 对象。 全局增强保存在同一私有目录的 enhancements.json。配置候选先由真实内核预检,启动并读回验证后 才提交活动配置;日常接管使用 root-session.json 和独立 root-session-recovery.json, 恢复标记覆盖元数据、最后可用配置与原子重命名后的写入失败。 旧普通用户会话的 session.json 独立保留。出现不确定结果时保留材料,不能自动重放连接或切换; 界面保持“状态未知”,确认后台停止后才能移除接管反馈。损坏、符号链接或归属不符的状态文件不被覆盖。 nameserver-policy、proxy-server-nameserver-policy 和 fallback-policy 保留声明顺序, 脚本输入和内核运行配置也不得重新排序。 显式迁入的应用 DNS 保留原始字节,在增强前整体替换 DNS,增强后恢复其 ipv6 设置。 配置页的“从 Verge 迁入”先显示只读摘要,确认迁入后保留原始订阅、完整增强链、规则/节点编辑、 启用的应用 DNS、应用层 TUN 等功能参数、有效手选线路和订阅更新方式;不改 Verge 文件或 maci 全局增强。 迁入时还通过 Verge 固定本机 socket 只读当前线路意图;预览后意图或源配置变化会拒绝提交并要求重新准备。 原索引的历史选择保留在来源附件中,实际配置分别保存普通手选组的当前选择与 URLTest 的 fixed 偏好, 不把自动测速的 now 当作手选,也不把过时历史选择重新固定。未固定的组继续自动选择;隐式 GLOBAL 与已确认偏好在重连、模式切换和回退时恢复。Fallback 的固定偏好具有不同失效行为,当前明确拒绝迁入该状态。 迁入还保留 Verge 显式的“切换线路时关闭旧连接”偏好;缺省不主动关闭。 选择成功读回并持久保存后,才限量清理连接链中经过旧线路的连接,其他连接不受影响。 清理失败或结果未知不回退已提交的线路,面板分别提示线路已切换与旧连接清理未完成。 Country.mmdb、geoip.dat、geosite.dat、ASN.mmdb 先作为内容摘要命名的不可变快照保存在私有 assets/, 再通过有界、按次序且逐文件核验 SHA-256 的通道交给 root;root 只接收固定文件类型,不接受路径或下载地址。 预检、启动、切换和内核恢复使用同一份快照。缺失或损坏依赖拒绝启动,不隐式下载 Geo 数据; 更多页可更新 Geo 与 Provider。Geo 更新只从 MetaCubeX 官方数据仓库解析一次 release commit, 四份文件固定到同一 commit,核对文件大小、Git blob 摘要和 SHA-256;先校验当前配置, 再通过两份固定的离线规则配置强制内核解析四类数据库,全部通过才发布快照。 每份大文件总时限为 15 分钟,连续 30 秒无数据则失败;更新可主动取消,旧配置继续生效。 普通用户下载失败、取消或内核校验失败均保留原配置;root 从不自行下载或接受外部文件路径。 root 最多保留四份完整 Geo 快照,回收时保护当前、上一份及事务/试用正在引用的快照。 上传取消与旧快照回收均可在写入中断后重试;未知或损坏材料保留并报告需恢复,不作为可删除的缓存处理。 Provider 在完整增强执行后由普通用户准备,保留名称、分组引用和健康检查设置,转换为 inline 内容。 支持 HTTPS 节点 YAML/JSON、规则 YAML/text 及条件更新;每份最多 2 MiB、总内容最多 4 MiB, 规则条目还须经隔离内核的实际 ruleCount 核对,防止解析器静默丢弃。 当前明确拒绝 provider 本机文件、MRS、加密/URI 内容、自定义下载代理及无法无损转换的字段。 缓存与来源声明绑定,存入私有 providers/ 的不可变快照;内容变化时按原接管事务应用, 仅校验元数据更新且运行配置相同时不重启内核。

更多页提供默认关闭的“局域网共享”。停止态开启只保存偏好,主动连接代理后才建立共享监听, 不自动登记后台或接管网络。共享地址仅来自本机 Wi-Fi/以太网的私有地址,固定端口 17897, 支持带独立用户名和密码的 HTTP / SOCKS5 TCP 代理;不提供局域网 UDP 转发。 控制器及本机混合监听继续限制在 loopback;普通本机代理访问不需要共享密码。 凭据由 root 随机生成,只有点按“查看连接信息”时才读取,复制前再次核验当前凭据; 收起面板、离开设置或状态未知时清除面板内缓存,代理配置备份不包含共享密码。 开启、关闭与更换凭据复用同一接管事务,监听、鉴权或持久保存失败时恢复原状态; 停止代理保留共享偏好和凭据,但不保留监听。旧后台缺少共享能力时不开启该开关。 局域网地址变化导致监听无法确认时显示未知或未生效,由用户检查后重新连接,不把旧地址当作仍可访问。

更多页支持 .maciproxy 本机备份,包含原始配置、完整增强、选择和引用的 Geo/Provider 资源, 不含 root 恢复日志、控制器鉴权、运行进程或流量地址记录。备份文件为 0600 的未加密包,包含订阅和节点凭据, 保存界面会明确提示;最大 256 MiB,以版本化清单、固定路径和逐文件摘要核验,损坏或未知版本拒绝恢复。 恢复先在独立私有目录中验证资源和真实内核配置,Provider 只能复用归档内容,不重新下载; 全部通过后追加新 ID 的配置,保留目的库原内容、启用状态与当前连接,由用户主动选择恢复的配置。 恢复的全局增强上下文单独保留,不与目的库全局脚本混合。包含新 Provider 引用或恢复上下文的资料使用 schema 2, 旧版读取会明确拒绝并保留文件,不能直接降级后忽略新增语义;基础版仍不读取代理资料。 显式修改全局合并或脚本前会自动保存一份完整代理备份,最多保留三份不同内容的历史版本; 取消后重试相同修改会复用相同备份。备份失败、原资料被并发修改或历史材料损坏时拒绝保存新增强。 自动备份位于代理私有目录的 auto-backups/,恢复选择器优先打开该目录。 “恢复全局增强”是独立动作,先备份当前内容,再恢复归档中的全局合并和脚本; 不改变当前连接,下次主动应用配置时生效。追加配置仍保留目的库的全局增强。

顶部设置的“代理功能”开关停止自有内核和订阅任务、保存关闭状态并移除底部入口; 重新打开功能不会自动启动代理。收起面板保持已启动会话;完整退出 GUI 只断开正式代理的客户端连接, 后台继续保持已确认的接管,重新打开面板读取实际后台及匹配的本机恢复记录,不重复启动内核。 正式连接从 Verge 迁入的配置时,额外提供固定 127.0.0.1:7897 的 HTTP CONNECT / SOCKS TCP 兼容入口,保留原本机 HTTP_PROXY/HTTPS_PROXY/ALL_PROXY 使用习惯;主端口仍是 17897。 这是固定的 Verge 兼容端口,不表示恢复任意自定义旧端口;普通配置和隔离试用不启用。 兼容入口只绑定本机 IPv4 回环,不开放 LAN 或 UDP。端口被其他进程占用时拒绝接管,不抢占监听。 启动、模式切换、失败回退及后台恢复共同保留这一状态,显式断开或关闭功能会释放监听。 agent proxy status 的 legacyLoopbackPort 只有在运行中的自有监听已核验时才为 7897,否则为 null; 代理尚未运行时,显式指向该端口的程序不能仅依靠系统 TUN 自动绕过它。 退出按钮与 SIGTERM 统一从主 RunLoop 发起退出,避免 AppKit 等待异步清理时阻塞主队列; 基础版和代理版检查均包含独立 AppKit 子进程的信号、控件请求退出回归。 关闭功能或显式断开仍等待自有普通用户内核和系统接管清理; 恢复失败时保留入口和错误反馈,不把关闭开关当作停止成功。 代理后台收到正常退出或拥有者离开图形登录会话时有界恢复网络、停止自有内核并保存 Fake-IP 检查点, 保留正式启用意图;拥有者再次进入图形会话后才能恢复。未知登录状态和其他用户会话不接管,重复事件不重启。 试用会话仍在客户端断开或原 60 秒期限到达时清理,后台重启不恢复试用。 上述生命周期已覆盖 fake adapter 行为测试;53 版本机正式接管通过了真实 GUI 退出与重开、 同一代理内核持续运行及 HTTPS/DNS 验证。Verge 内核停止后,7897 的 HTTP CONNECT / SOCKS TCP 请求均通过;已有 Codex 进程无需重启即可建立该端口的新连接,连续 60 秒未新增原来的连接拒绝错误。 这是短时连接回归;实际注销、重启、睡眠唤醒及长时间接管仍需独立验收。 bin/maci --show-proxy-panel 只展开已启用的代理面板,不解锁功能、启动代理或请求系统权限。 基础版不会读取已有代理资料,切换版本也不删除这些资料。

专用代理 LaunchDaemon、同签名/同用户 XPC 白名单、root 私有运行目录、完整候选/上一配置日志、 系统代理所有权恢复及遗留进程阻断已实现并以 fake OS adapter 验证; 它与显示后台完全独立。构建/安装不注册该系统后台;面板日常连接使用同一后台事务。 内核固定保存在 root 私有运行目录的 maci-mihomo,停止后保留已校验文件,避免每次连接都产生新的 防火墙应用名称。复用前重新核验文件归属、权限、摘要和签名;更新先暂存校验,再在目录锁与遗留进程 检查通过后原子替换。来源不明、签名失效或仍有活进程时保留原件并拒绝更新,不修改系统防火墙设置。 安装前同样检查包内代理后台及新旧路径的活内核;后台登记消失不能代替进程退出证据。 每次返回接通前,后台核验保留子进程的身份与其真实监听 FD、控制器配置及系统代理逐服务读回。 状态携带内核运行代次、源配置摘要和 Geo 快照 ID,跨切换或内核重启的迟到控制器响应会被拒绝。 fake-IP 内核正常退出后,后台保存自身地址池与分配进度;模式切换、重连及候选回退均继承最新映射, 避免向仍缓存旧地址的应用重新分配同一个地址。快照仅存于 root 私有目录,每份最多 64 MiB,最多保留当前与上一份; 不读取 Verge 的 DNS 历史缓存。异常退出、快照缺失/损坏、保存失败或已有映射时改变地址池会阻止重新接管并保留恢复材料, 不能用重置地址池或清除系统 DNS 缓存冒充恢复成功。 日常 DNS 页只清除解析缓存;Fake-IP 映射不提供重置按钮,后台也拒绝旧版客户端的重置请求, 防止仍持有旧地址的应用连接到另一个域名。 已安装代理版提供显式接通测试入口:--proxy-service-status 读取后台状态, --register-proxy-service 登记独立代理后台;首次运行仍须通过 macOS 的后台批准。 后台登记为已启用、codesign --verify 通过,都不代表 root 后台已获准执行。 默认固定本机身份使用自签证书;若系统日志同时出现 AMFI 证书链拒绝与启动约束不匹配, 须先解决签名身份问题,不能反复批准或把 XPC 超时归为未授权。 Apple 建议应用与嵌入后台使用同一 Apple 签发的代码签名身份。 改用其他证书及私钥必须另行授权;不自动修改系统信任,实际接管仍以后台运行读回和网络证据为准。 经授权后,代理版可使用 ~/Library/Application Support/maci/signing/proxy-signing.json: {"version":1,"kind":"appleDevelopment","certificateSHA256":"获授权证书的64位SHA256摘要"}。 该文件须由当前用户拥有且权限为 0600;签名工具只使用摘要精确匹配、有效且通过 Apple 代码签名证书链校验的现有身份,不创建证书、不导出私钥、不改系统信任。 代理 GUI、内核、配置工作进程与代理后台使用同一身份,基础版和显示后台保留原本机签名。 此配置存在但损坏、过期或缺少对应私钥时构建失败,不回退其他身份。 --unregister-proxy-service --repair-inactive-registration 仅供明确授权清理已退回待批准的 启动约束失效登记;仍逐项核验签名、同一失败任务、后台/内核不存在、端口空闲与全部网络服务无接管, 执行一次正式注销并读回,不恢复批准、不自动重新登记。 --prepare-proxy-connection --read-existing-subscription 可先独立完成普通用户预检和节点实测, 不登记后台或修改系统网络。接管测试使用固定 HTTPS 探测,原生请求最多下载 2 MiB, 系统代理按同一次 HTTPS 事务的本机地址/端口、内核连接链和系统代理标记关联; TUN 按同次事务的完整源/目标地址、端口、传输协议与内核 Tun 连接及节点链核对, 域名缺失不能单独作为失败或成功依据。每个成功的网络事务均须独立匹配,不能拼接不同事务的证据, 也不能混用系统代理和 TUN 的接管标记;缺少归属证据时不报告接管通过。 deno task test:proxy-connection --read-existing-subscription --capture system 使用现有订阅的 可用节点测试真实系统代理;--capture tun 仅在没有其他代理内核运行时允许进入。 测试不改正式配置库或 Verge。默认先在普通用户隔离目录预检原配置,再以全局节点配置验证接管链路; 这份基础候选不包含完整 Geo 规则,不能代替原规则/DNS 等价验收。 加 --full-configuration 时逐项比对原生效配置的完整节点、策略组、有序规则、DNS、策略声明顺序与其余功能参数, 仅允许明确的应用监听/控制器/接管归属字段差异;同时传入相同 Geo 字节和有效手选线路。 完整试用在规则模式下核验源摘要、全部运行规则、DNS 解析语义,以及原生请求经自有内核的直连/代理分支; 完整预检额外显式启动仅绑定 loopback 的临时 DNS 监听,先核验 TCP/UDP 端口空闲;普通运行默认不启用此监听。 TUN 再向固定文档保留地址发送有界 DNS 问题,与同一完整 DNS 处理链的隔离 UDP 基线核对,覆盖 hosts 与 fake-IP, 不把控制器解析器查询成功视为系统 DNS 已接管。与独立预检基线相比,fake-IP 分配只允许在原配置声明的同一地址池内变化, 普通 localhost 应答保留精确地址核对;A/AAAA 缺失、返回码或地址类别变化都不能通过。 fake-IP 连接在控制器目标已变为域名或解析后的真实地址时,必须额外绑定同一内核在请求前后返回的精确 DNS 地址集合, 并核验配置摘要、完整试用回执、fake-IP 模式、当前进程的新连接及请求时间窗;仅地址落在合成池内不能通过。 同次请求的源地址/端口、协议、目标端口、域名、规则链及正常 TLS 校验仍独立核验;该证据表示地址转换关联,不能冒充内核导出的原始目标元组。 全局节点 TUN 试用候选同时开启 IPv4/IPv6 与双栈 DNS;完整配置保留来源的 IPv6 设置, 来源启用 IPv6 时同样运行 IPv6 探测;仅明确关闭 IPv6 才可跳过,缺少 AAAA 地址视为未通过。 不能通过仅探测 IPv4 掩盖系统请求的 IPv6 绕行; 默认 HTTPS 请求后,再通过固定的 ipify IPv6 端点 单独探测 IPv6。 完整配置验收要求同一试用回执、同一网址的两道检查同时通过:系统 URLSession 自动选路请求正常完成且逐事务归属于自有 TUN, 以及独立 curl --ipv6 请求的客户端源/目标均为 IPv6、正常 TLS/HTTP 200、最多 4 KiB 的正文是单个非 mapped IPv6 地址。 自动请求可由 macOS 选择 IPv4 Fake-IP,但不能将它计作客户端原生 IPv6;强制请求不能用 IPv4 回退通过。 强制请求的每个候选连接还须是本次 curl 的新连接,起始时间落在请求窗口内,元数据、规则和连接链保持稳定; 完整元组只能对应一个合格连接,fake-IP 转换须具备同一 DNS 处理链的前后证据。正文仅在内存校验,结果不保存或输出出口地址。 两道检查及网络恢复全部完成才报告完整 IPv6 接管通过;全局节点候选仍要求系统请求本身使用 IPv6。 完整 TUN 的 IPv6 请求失败时,可在原 60 秒期限内追加固定 Cloudflare IPv6 字面地址的 HTTPS 诊断,以及同网址的传输与延后诊断; 字面地址诊断保留正常证书校验,并要求客户端与内核观测到同次连接的精确 IPv6 源/目标元组,不使用 fake-IP 转换例外。 自动组测速历史只作为排查信息,后续诊断成功也不覆盖首次失败或冒充接管验收通过。 单次系统请求的 DNS、控制器读取、HTTPS 与归属核验共用最多 23 秒预算,并在原试用期限前至少一秒取消; 取消时先阻止未启动请求,再等待自有网络操作结束,不因开始新探测而延长试用。 后台在接管前持久标记测试会话,60 秒后自动恢复系统代理并结束自有内核;客户端正常完成时提前恢复, 后台重启也不得恢复测试接管。只有原后台处于停止状态才可开始,测试期间不接受其他配置写入。 主动清理依据成功试用回执、完整状态代次/修订号和当前用户核验归属,不依赖节点列表或流量读取成功; 内核崩溃仍应尝试恢复,回执未知或状态已被其他操作改变时保留独立超时恢复边界。 成功清理后还原完整的原停止配置;试用期间的冗余停止日志写失败不应阻断实际回退, 但最终原配置必须成功落盘才能确认完成。恢复包含已禁用的网络服务,缺失服务不能被当作已恢复。 备份损坏或系统设置发生冲突时保留恢复材料并明确报告未完成, 不会将超时本身当作恢复成功,也不会关闭仍被系统设置引用的监听端口。 网络设置读回、HTTPS 连通与清理分别报告;现有 Verge TUN 仍运行时,不将结果表述为独立替代成功。 本机此前已完成全局节点候选在系统代理及独立 TUN 下 IPv4/IPv6 HTTPS 的逐事务归属与结束恢复验证; 完整配置和日常面板使用各自的显式测试结果,不复用此前全局候选结果作为验收。 2026-09-13 的 50 版在受控且具备 IPv6 出口的同一线路下,通过完整 621 条有序规则、DNS、 原生请求直连/代理分流及完整 IPv6 双请求门槛;原生客户端 IPv6 证据来自独立 curl --ipv6, 不把系统自动选择的 IPv4 fake-IP 请求算作原生 IPv6。固定内核获防火墙放行后,面板 TCP/UDP DNS、 三次模式切换后的映射连续性和结束恢复也通过。首次放行前的 TCP 超时仍保留为失败记录; 这些结果不代表所有订阅节点都有 IPv6 出口,也不代替正式常驻、重启或真实局域网设备验收。 受保护的切换测试在停止 Verge 前捕获当前固定/自动状态,以有界私有环境数据交给显式测试入口; 入口核验源摘要、时效、组与成员,正常面板不读取该测试环境数据。结束恢复同时核对 Verge 的固定/自动状态。 完整接通与面板测试需要切换测试驱动提供 MACI_PROXY_TEST_VERGE_INTENT(最多 64 KiB、有效期五分钟); 缺失时拒绝测试,不回退到索引中的历史选择。 --prepare-proxy-connection --read-existing-subscription --full-configuration 则在 Verge 仍运行时直接进行只读预检,不保存测试快照或接管网络。 --test-proxy-panel --read-existing-subscription --capture system|tun [--installed-backend] 通过真实面板模型在独立私有资料目录验证迁入、连接、图表/地址、三种模式、线路、隐藏、关闭功能和退出。 TUN 面板试用还在三次模式切换后重复 DNS 问题,要求已分配 fake-IP 的地址集合保持不变。 该入口先显式启用同一后台的固定 60 秒面板试用保护,测试连接仍走正常事务; 到期或客户端断开先取消并等待当前事务及回退,再恢复原停止配置,同一测试连接结束后不能再次接管或延长期限。 面板测试额外加 --disconnect-checkpoint 时,在接通后输出有界私有回执并固定等待十秒,供测试驱动终止其自身持有的诊断进程; 普通面板和显示后台不参与该故障注入。独立 --observe-proxy-panel-disconnect [--installed-backend] 从 MACI_PROXY_PANEL_DISCONNECT_WITNESS 读取这份 base64 回执,只读核验同代后台在原期限前停止、无接管且试用标记全部清除; 它不发送停止请求。驱动仍须另外核验内核退出、端口、系统网络及原配置恢复;等到六十秒后才停止不能证明断连恢复通过。 面板测试可另选 --maintenance-checkpoint,与断线故障注入互斥:连接前及停止后在独立私有库中, 调用与界面共用的备份、暂存和追加恢复流程,核对原配置与接管状态未变化;原 60 秒保护内验证 Provider 内容未变化的更新保持同一内核运行回执。该步骤不在保护期内下载 Geo,也不操作正式配置库。 TUN 面板试用可单独加 --dns-transport-checkpoint,与维护检查和断线故障注入互斥。 它在切换模式或线路前,分别经 UDP/TCP 向固定文档地址查询 localhost;每次请求前后均核对同一 后台代次、试用回执、源配置摘要和 Geo 快照,要求两种传输均返回成功的 A 答复且地址集合完全相同。 合法的 localhost fake-IP 答复不会被误判为传输故障;此处只比较同一内核的传输结果,不判定 DNS 语义等价。 TCP 的连接、发送与分帧读取共用三秒截止,取消关闭自有连接;整个面板试用仍受原六十秒保护。 失败先完成正常清理再报告失败。该检查仅用于定位 TUN DNS 传输,不能替代原生 HTTPS 或完整 IPv6 验收。 签名构建产物可在状态或连接测试命令末尾显式加入 `--installed-ba

…