← 返回列表
未验证
在浏览器本地管理照片视频音乐并私有组网
尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/9/14 · 已提供中文文档
TypeScript 单体仓库 — Deno × Perry × VitePlus × React × Nitro
综合分
29.9
GitHub 分
29.9
用户评分
—
★ Stars
0
周下载量
—
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add intpfx/OpenFX该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
数据截至 2026/9/16(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动
README
OpenFX
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'。状态已变化时返回
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 ''。启用只显示功能,不自动连接或请求系统授权。
代理设置内的“停用并隐藏”先等待自有工作取消、网络恢复和状态读回,完成后移除全部代理入口;
失败或结果未知保留状态与恢复操作,不能把隐藏当作停止成功。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-backend,通过固定安装路径及 同证书 XPC
连接已有后台;此诊断路径不查询或写入 SMAppService,避免改变现有后台的应用归属。 登记和
--unregister-proxy-service 仍只允许正式安装实例;更新前应先确认后台停止,再显式注销。
已加载后台须由签名 XPC 核验停止和归属;已卸载后台须独立确认 launchd
任务不存在、自有内核退出、 本机 17897
端口空闲且全部网络服务无接管,不能把连接失败当作已卸载。注销后须读回未登记和任务不存在。
若系统明确报告代理后台因旧启动签名约束而无法执行,正式实例可在重新验签、确认许可仍开启,
并独立核验后台及内核进程均不存在、端口与网络设置均无接管后,显式注销该失效任务一次。
注销前再次核验同一任务;状态不明或变化时停止,不自动重放注销、重新登记或修改显示后台。
root 配置策略拒绝任意执行、外部文件引用、未审查字段及远程 HTTP proxy-provider;
远程内容必须先通过上述普通用户准备链,root 只接收已校验的 inline 配置。 后台保留旧版
provider 刷新请求的解码,但明确拒绝执行;inline provider
的更新时间变化不能冒充远程内容更新。 这不影响面板现有的主订阅更新或 provider 列表读取。
Geo/provider 更新、备份恢复、跨版本回退及长期运行均有独立验收边界,
不能据本机当前订阅的接通结果宣称 Clash Verge 全部功能已等价。公开分发与 GPL
对应源码义务另行核对。
deno task check:proxy 串行运行 domain、真实 YAML、迁移
fixture、脚本工作进程、HTTP/Unix socket、 隔离真实
mihomo、Provider/备份恢复组合、面板生命周期和后台 fake adapter 测试;不注册 root
服务、不改变系统代理/TUN, 不读取现有 Verge 的订阅凭据。deno task check:editions
检查两种实际 SwiftPM 依赖图。面板的真实内核夹具使用独立随机 loopback
端口,可与正在运行的本机代理并存;正式代理端口不变。
maci-proxy-network-tests --isolated-core-dns 已校验内核绝对路径 SHA256
可单独验证真实内核的 TCP/UDP DNS 传输:仅使用 localhost
配置与本机随机高端口,核验同一进程的监听与应答,
结束确认内核退出及端口释放;不接管网络、不使用订阅,也不代替 TUN 验收。
maci-proxy-sharing-tests --loopback-auth 已校验内核路径 SHA256
额外验证真实内核的共享鉴权、凭据更换、兼容入口的 HTTP CONNECT / SOCKS TCP 转发、UDP
不转发及端口释放。它仅使用随机高端口和本机 IPv4/IPv6 地址模拟本机、共享与兼容入口,
不开放物理局域网监听、不接管网络,也不能代替其他设备上的连通验收;默认检查不运行此选项。
额外的 maci-proxy-maintenance-tests SwiftPM
目标接收已校验内核路径;--public-provider-update 验证 MetaCubeX 公开规则的真实 HTTPS
下载和条件更新,--public-geo-update 验证官方四份 Geo 的完整下载与真实解析。
--read-existing-subscription 只读验证当前订阅的备份恢复;搭配
--stability-soak-seconds 60..3600
则单独运行指定时长的隔离内核测试,采样真实健康、规则、连接计数、HTTPS、内存和文件描述符,结束核验进程与端口释放。
持续测试不能与公开资源下载选项混用,不接管系统代理或 TUN;当前 Verge
可能仍承载其外层连接,
该报告不等同于日常系统接管、睡眠唤醒或跨日稳定性验收。所有这些联网/订阅读取选项均不属于默认检查。
Unix 控制器使用可取消、受总时限约束的非阻塞本机套接字,并复用有界 HTTP 解析;
测试覆盖完整响应后立即关闭、提前截断、超限、超时和取消,不自动重放请求。独立的
deno task test:proxy-existing --read-existing-subscription --output 私有测试目录
需要用户明确授权读取本机订阅后才能运行。它只读准备当前 Verge
订阅、原始增强、选择、应用功能设置及已启用的应用
DNS,核验源文件未变,并在测试目录保存私有副本;当前入口只接受裸 DNS mapping。
测试对齐当前生效的节点、策略组、规则及 DNS,使用 17897/17898
独立端口测试真实订阅下载、节点测速、HTTPS 请求、配置回退与面板关闭清理,不改现有
Verge、TUN 或系统代理。该入口不把资料导入正式 maci
配置目录;每次应使用新的测试目录。现有 TUN 保持运行时,测试结果不能代替退出 Verge
后的系统网络接管验收。首次安装使用 deno task install
安装默认完整版,代理保持未启用;安装只登记既有 GUI/显示后台。正式位置已有完整版时,日常
install 默认构建并提交保留后台的界面更新。
旧基础版迁入完整版必须显式使用维护路径;安装资料损坏或更新失败均停止,不自动回退到停机替换。
只有主动维护后台、内核或迁移旧版本时才使用
zsh scripts/install.sh --maintenance-runtime(内部裁剪版显式设
MACI_FEATURE_PROXY=0),
并先通过自有控制入口停止接管、注销代理后台;此路径保留原有停机检查和显示保护。
旧基础版迁入前,由候选的原生功能接口确认停用状态,避免重新启用历史代理资料;确认失败、超时或未知时不交换应用。
此停用选择在后续安装失败时也不会自动恢复。旧基础版需要保持裁剪时,可显式使用
deno task install:base。允许最后虚拟屏短暂断开须另加
--allow-last-display-loss,不能单独以该参数进入维护。
也可分步使用 deno task build:ui-update 和
deno task install:ui-update;默认准备完整版候选,
与正式安装版本类型不同则拒绝,不能绕过旧基础版的维护迁移。后者调用候选二进制的原生
agent app update-preview/update-apply;不通过旧安装流程停用后台。也可直接向候选的
Contents/MacOS/maci agent app update-preview --source /absolute/maci.app
提交本机候选,再将同次返回的
previewToken 和 stateToken 用于
apply。路径必须为规范绝对 .app 路径,允许空格,不接受 URL、相对路径或 ./..
路径段。
这条事务更新 GUI
与其附属资源,要求候选与正式安装的后台、内核、启动配置及其受保护资源字节和权限相同,
并在更新前后核验同一运行状态摘要。代理处于健康运行或明确停止状态才可继续;未知、试用、
待恢复状态均拒绝。存在自有虚拟屏时须已启用无屏常驻,否则退出 GUI
会释放屏幕,更新将拒绝。它不会升级代理
daemon/core、重新登记代理或显示后台,也不会恢复用户关闭的系统许可。
旧版公共资料目录保持原权限;更新记录与暂存仍使用私有目录。安装适配器与 Agent
共用原生更新事务、跨进程锁、候选复验和恢复记录;失败或回执未知时先读取
agent app update-status,不要自动重放
apply。若交换已完整完成,只是最终确认未收到,可用同次状态中的 stateToken 显式调用
agent app update-reconcile --expect …;它须重新核验安装、实际 GUI 及保留后台,
只提交确认回执,不重新交换文件、重启 GUI
或控制后台。部分交换、资料不符或无法读回的其他未知结果仍保留
恢复材料,须人工审阅,不能用 reconcile 强行标记成功。
后台或内核的维护更新不保证已有连接不断流。参数与 fake 事务测试不代表正式更新验收;
真实安装后仍须确认 GUI 版本、后台与内核原进程、显示及代理状态保持。代理核心的下载归档
SHA-256、未签名前/包内签名后的二进制摘要和来源记录随包保存,并保留 mihomo GPL-3.0 与
Yams 许可证。完整代理包目前用于本机开发;公开分发前仍需落实
对应源码与第三方许可证义务、正式签名和公证。基础版不携带该代理 payload。
音乐下方的闪念输入框用于随手记录灵感:支持 ⌘V 粘贴,以及系统剪切、复制、全选
快捷键;输入后按回车或点击加号保存,圆形勾选标记完成,已完成
事项默认折叠,可用输入框右侧的勾选圆图标展开恢复。列表最多显示三条(126
点),超出后在列表内部滚动,悬停查看完整文字;每行复制按钮将完整
内容写入剪贴板,并短暂显示成功勾号。删除后可撤销最近一次
删除,下一次修改或退出应用后撤销失效。每条最多 2,000 字,共最多 500 条。已保存事项写入
~/Library/Application Support/maci/thoughts.json,仅保存在本机,不发送给翻译模型;未提交草稿
只在当前运行中保留。保存失败不清空草稿或更改已保存列表,读取失败不覆盖原文件。
预览是一张静态截图,需退出后才能操作原应用。按住空格查看原图,松开恢复译文;点击文字块
展开完整译文与原文,并可复制该段译文。文字过长时在原位置截尾,不缩小字号或自动盖住相邻
文字。再次按当前翻译快捷键或 Esc 退出并清除本次内容。切换应用、原窗口移动/缩放/关闭或
显示器布局变化时自动退出;预览期间仅检查窗口元数据,不持续截屏。截图、识别文本与译文
不写入文件或日志,旧任务的迟到结果不能进入新预览。
面板“快捷键”可改为 ⌃⌥T 或 ⌃⌥⌘T,选择后立即生效并在重启后保留;注册冲突时保留
原有快捷键。默认译为简体中文,可切换英语、日语和韩语。已识别为目标语言的块和纯数字保留
原样;未完成翻译的块保留原图,失败时显示提示。菜单可选择 Apple 高质量、Apple 快速或 腾讯
Hy-MT2 窗口翻译;高质量策略需要 macOS 26.4,未启用 Apple Intelligence 时系统可能
回退到传统模型,界面不保证实际使用了哪一种 Apple 模型。腾讯模式携带最近三段有限上下文,
同一窗口串行翻译,关闭预览时释放模型。未保存引擎偏好且腾讯模型已就绪时默认使用腾讯;
否则默认请求 Apple 高质量策略。
Apple 的两种策略均通过系统 TranslationSession
在设备上翻译;所需语言包未安装时需要联网下载。 腾讯模式加载本机模型,仅通过 loopback
调用本机推理进程;首次下载模型与运行时需要网络。 两者都可在所需资源准备完成后离线使用。
电影字幕(首版):macOS 26 及 Apple Silicon 上,将播放器切到前台,打开 maci,点击
“电影字幕 → 启动”。默认识别英语,在该行设置中可选日语、韩语或普通话;输出语言使用上方
“译为”。只读取目标应用的声音,不使用麦克风、不执行 OCR;SpeechAnalyzer 在本机产生
临时与最终识别结果,Hy-MT2-1.8B Q4 按短段翻译,底部字幕层不遮住整个画面、不抢焦点,
鼠标可操作播放器。临时结果会修订,并非逐字译文稳定不变;译文与对应原文成对更新。
菜单栏始终只显示内存百分比,面板内显示字幕准备、聆听或错误状态。点击“停止”或按当前翻译快捷键
停止;切换应用、源窗口关闭/更换或显示器布局变化也会停止,关闭菜单本身不停止电影字幕。
字幕随同一源窗口移动,停止后清空音频、字幕与上下文,并结束自有推理进程。
首次使用点击“下载腾讯翻译模型(约 1.1 GB)”,或在 domains/maci 执行
deno task setup-translation。脚本从官方来源下载固定版本运行时与模型,校验 SHA256、保留
许可证,安装在 ~/Library/Application Support/maci/translation/;不需要管理员权限。
语音语言包由系统 Speech 框架准备。模型首次启动可能需十几秒,准备完成后再开始播放。
该模式按应用捕获:浏览器其他标签的声音也可能被包含,不能宣称单标签隔离;不保证受保护
影片能取音。无音频时等待对白,长时间静音后清除旧字幕;配乐、口音和重叠说话会影响识别。
队列有界,跟不上播放速度时停止并提示,避免不断积压延迟。首版尚未接入字幕文件/字幕轨
读取、持续 OCR、播放器时间轴/拖动跳转同步或提前翻译,不能保证字幕与任意影片无延迟同步。
运行需要 macOS 15 或更新版本。窗口截取需要用户授予屏幕录制权限;不请求辅助功能或全局
键盘监听权限。首次使用语言对时,系统可能提示确认下载语言包;翻译在本机执行,语言包
可用后可离线使用。固定图片开发演示通过 --demo 执行真实 OCR
与所选引擎翻译,无需屏幕录制
权限。仅识别当前窗口画面,段落分组是保守的几何判断,复杂多栏、混合语言、小字、动态或受
保护画面仍可能识别或翻译失败;单次识别上限为 12,000 字符,超过上限明确提示,不静默
截断。固定图片 demo 使用菜单中选择的窗口翻译引擎。
应用图标采用银色模块化机器人、青色耳鳍与环绕能量带;菜单栏仅显示内存百分比,电影字幕
运行时也不添加图标。图稿保存在
domains/maci/Assets/AppIconArtwork.png,构建自动导出含透明圆角与留白的多尺寸 ICNS。
maci 的归档入口是独立、按需启动的 Finder Service,提供解压、解压到指定目录、ZIP、7z
和压缩选项。归档不占用菜单面板;参数、密码、进度与取消使用临时原生窗口。退出菜单栏 maci
不会停止服务已接收的任务。默认一次运行一个任务,最多等待十六个;同次多选归档分别
提取,同组分卷合并识别。源文件保留,结果先完整校验,再用新名称原子发布,不合并或覆盖
已有结果,不自动展开包内其他压缩包。完成后列出实际生成的位置,用户可以点按“在 Finder
中显示”;部分失败或取消的批次只列出已经发布的结果。
暂存初始化或首份事务记录写入失败时,清理会核验已创建目录的身份,再回收自有暂存。
归档能力表位于 Sources/MaciArchives/ArchiveCapabilities.swift,创建选项复用这张表。
创建支持 ZIP、7z、TAR、GZIP、BZIP2、XZ、LZIP、Brotli、Zstandard、LRZIP、WIM、ISO、 DMG
和 Apple Archive。提取还包括 RAR/RAR5、ZIPX、PAX、CPIO/CPGZ、LZMA、CAB/MSI、
JAR/WAR/IPA/APK/APPX/XPI/SPK、Compact Pro、InstallShield 3、WPRESS,以及已识别的
7z/RAR/ZIP 自解压容器。EXE/MSI 仅提取内容,绝不执行安装程序。扩展名只作路由提示,密码、
压缩方法、分卷和元数据分别验证:
- ZIP 设置密码时默认 AES-256,可明确选择传统兼容加密;7z 支持固实和加密文件名。ZIP/7z
可创建分卷, 数字分卷与传统 ZIP/RAR 卷组分别识别;保留 Mac 属性暂不能与加密同时使用。
- ZIPX 验证 BZIP2/LZMA/PPMd8/XZ/Zstd。WPRESS 支持 v1/v2、raw/zlib/bzip2 与 AES-256-CBC,
密码先通过备份格式的校验块验证;CBC 和旧版无 CRC 内容不被表述为认证加密。
- DMG 创建未压缩 UDRO,内含 ISO9660/Rock Ridge/Joliet;不创建 APFS 或加密镜像。
提取可以读取已验证的 APFS/HFS/ISO 内容,全程不挂载镜像。
- Apple Archive 支持 AA01 与有界 LZFSE,.aar 中的 Android ZIP 按内容区分;不支持 AEA。
AAR 的单条属性块和磁盘镜像的单个属性目前各限 128 KiB。
- Compact Pro 验证 RLE/LZH、CRC、资源叉、FinderInfo 与 MacBinary
打包;加密和多卷尚不支持。InstallShield 3 验证 Fast/Medium/High/No 历史 .Z
归档,不泛指所有 InstallShield 安装器。SFX 只查找有界前缀中已识别的载荷,不宣称所有
EXE、加密或多卷 SFX 兼容。
XIP 已实现系统信任检查及 XAR→PBZX→XZ→CPIO 解码链;因尚无有效 Apple 签名正例完成 签名
Worker 的全链验收,仍不开放产品入口。当前还不能称为完整 Keka 平替。
7-Zip 26.03 使用完整归档回调接口;固定 libarchive 3.7.4、liblzma 5.8.4、Brotli 1.2.0 和
Zstd 1.5.7 通过有界分配器运行;LRZIP 0.7.2 使用继承同一沙箱的包内 helper,CPT/IS3
使用固定内存的专用解码器。解码只在无网络权限的 App Sandbox XPC Worker 内执行,
它接收只读匿名输入快照和输出管道,不能得到最终目录的写权限。宿主逐项校验路径、链接、
大小写和 Unicode 冲突,以目录描述符写出;默认最多十万实际节点、16 GiB 实际输出,并保留
至少 64 MiB 空间。密码只存在本次内存;下载来源的 quarantine 继续传给结果。兼容分享与
保留 Mac 属性是显式选项,格式不能表达的属性不会被冒充为已保留。
已接收请求的 ID、动作和来源 URL 保存在权限为 0600 的
~/Library/Application Support/maci/archive/pending.json;内容和密码不写入该文件。
重启时明确选择稍后处理、重新排队或放弃记录,自定义参数需要重新输入。目录内的私有事务
记录用于核对是否已经发布;无法确认旧引擎停止时,服务保留队列和租约。损坏记录保留原件,
不依赖旧 PID 清理进程、不盲目重跑,也不宣称支持断点续解。目标卷不支持
原子且不覆盖的发布时明确失败。引擎使用包内固定产物,不依赖 Keka 或 Homebrew 运行时;
许可证、来源 SHA-256 和对应源码归档随 Service 打包。
恢复弹窗可以保留记录、清理已发布记录或放弃已确认中断的暂存。清理会重新核对目录锁、
inode、记录原文与发布阶段;已发布结果始终保留。活跃事务、不确定状态和没有目录锁协议的
旧版记录只保留,不提供删除操作。
cd domains/maci
deno task build:archives
deno task check:archives
python3 scripts/install-archives.py # 仅显示安装计划
归档构建需要 Xcode Command Line Tools、CMake 和 Python 3.12 或更新版本;脚本优先选择
满足版本要求的现有解释器,也可通过 MACI_ARCHIVE_PYTHON 指定。旧版 macOS 系统 Python
不提供所需的受限 tar 解包过滤器,构建不会为兼容它而降低源码提取检查。
检查同时覆盖空缓存中的固定来源解包:接受合法根目录,拒绝越界、未知链接和特殊条目,
并确认拒绝时尚未写入源码目录。 真实 XPC
检查会将已验签产物原样暂存到专用临时目录,并核对文件、权限和签名,避免 macOS
受保护目录限制沙箱初始化;不重签、不安装,也不修改系统权限。
归档检查会在专用临时目录创建 32 MiB HFS+ 测试映像,核验真实满盘和只读错误,再正常卸载
并清理该映像;这项检查不能替代外置卷拔出、ExFAT 或网络卷验收。
Finder 一级 maci 菜单由包内 Contents/PlugIns/maciFinder.appex 提供;需在 macOS
中启用该 Finder 扩展,并安装下述独立归档服务。扩展仅保存本次菜单的有界文件选择,通过私有
pasteboard
调用既有服务,不枚举目录、不读取原件、不访问代理资料。五个菜单动作仍由同一归档事务执行,Agent
使用既有 archive 接口。归档服务仅向 maci Finder 扩展声明菜单上下文,Finder
的“服务”中不再重复显示这五个命令;未启用扩展时需先启用,或使用“打开方式”与 Agent 接口。
独立产物为 dist/archive/maci Archive.service。只有明确选择后才执行安装脚本的
--install,安装至 ~/Library/Services/maci Archive.service 并刷新
Services;NSRequiredContext.NSApplicationIdentifier 固定为
com.siaovon.maci.finder,保留扩展调用而隐藏 Finder 中的重复服务入口。 --uninstall
只移除自己的服务。运行中的任务持有租约,更新会延后。安装不设置默认文件关联、不卸载
Keka,也不启动菜单面板。同一服务声明能力表中的文件类型为 Viewer/Alternate,并通过打开
文件事件进入相同队列;用户可自行选择“打开方式”及默认应用。Finder 菜单的位置、打开方式
发现以及是否需要在系统设置开启 Services,由 macOS 决定。隔离探针和本地构建不能替代
真实安装后的 Finder、外置卷和系统文件关联验收。
deno task build 使用 SwiftPM 与 Package.resolved
锁定依赖,首次构建需要联网获取依赖, 缓存位于 domains/maci/dist/swift-build/;生成
dist/maci.app(默认 ad-hoc,配置专用身份后使用稳定本机签名)及 bin/maci
入口,并携带独立归档 Service;不安装或修改登录启动项。设置
MACI_SIGNING_MODE=adhoc-validation
可做明确的本地临时签名验证,不读取已配置的私有证书;
普通构建仍遵循已有固定签名配置。ad-hoc 构建更新会改变代码签名;若旧屏幕录制授权失效,
需在系统设置重新登记已安装的 maci 并重启,不能仅依据开关状态判断权限。
deno task install 才安装至 ~/Applications/maci.app,停用旧 Memory Guardian
LaunchAgent 并启用新服务;旧 plist、helper 和
~/Library/Application Support/CodexMemoryGuardian/ 内历史数据完整保留。
更新先暂存并校验签名;已使用包内注册且后台二进制、启动配置未变化时保持其运行,只替换菜单界面。
旧外部 LaunchAgent 迁入包内注册必须受控停止并卸载旧任务后再注册;新任务分别使用
com.siaovon.maci.menu-agent 与 com.siaovon.maci.display-agent,避免旧式后台活动记录
阻碍应用归组。显示 XPC 接口仍为 com.siaovon.maci.display-service。旧 plist 归档保留;
显示后台迁移同样经过最后一屏保护。
旧版虚拟屏由菜单进程持有,首次迁移无法直接转交对象:检测到可能仅有旧版虚拟屏时,安装会在停止服务之前退出。
应接入备用屏幕,或明确接受短暂断屏后运行
deno task install --maintenance-runtime --allow-last-display-loss。
显示后台自身升级或卸载同样经过最后一屏保护;失败时保留配置和回退副本,不强制杀死真实服务。
cd domains/maci
deno task build
deno task check
deno task install
deno task status
deno task test:movie 是显式的真实模型集成验证:先完成 setup-translation,测试通过
系统语音合成生成已知英语音频,运行真实 SpeechAnalyzer 与 Hy-MT2,检查识别、翻译、取消和
进程清理;不采集播放器或麦克风。首次可能需要系统准备语音语言包。它独立于常规 check,
不能替代授权后的真实播放器取音与字幕层验收。
deno task benchmark:movie 对用户当前选择播放的 Safari 音频做
显式短段评测:看到 CAPTURE_READY 后播放影片,看到 CAPTURE_FINISHED 后暂停。
采集期间只保留有界内存,最终取前八个完整识别句段,以相同原文、无历史上下文比较 Apple
快速、Apple 高质量请求与 Hy-MT2;每段每引擎重复三次、轮换顺序,另计模型启动和预热。
结果仅输出到调用终端,不写录音、字幕或报告文件;不要把控制台重定向到日志,除非明确需要
保存评测原文。识别最终化延迟是基于音频时间戳的近似值,翻译耗时是接口完成时间;二者不能
冒充已实测的播放到字幕显示延迟。Apple 实际使用的高质量模型无法由该接口确认。
同一发现与停止边界也提供给自动化验收:
bin/maci --sample-memory-percentage
bin/maci --list-dev-services-json
bin/maci --stop-dev-service
bin/maci --display-service-status
bin/maci --set-display-headless on
bin/maci --restore-displays
~/Applications/maci.app/Contents/MacOS/maci --startup-status
安装后由 ~/Applications/maci.app/Contents/Library/LaunchAgents/ 内两个启动项
在用户登录时启动,主程序与独立签名的显示后台均位于 Contents/MacOS/。 新日志保存于
~/Library/Application Support/maci/。status 分别核对包内注册状态、真实进程与 launchd
监管 PID;已安装 App 的 --startup-status 不启动后台。未安装的构建产物返回
notInstalled,不查询系统注册,以免系统把正式后台的 App 路径改指向构建目录。
安装和卸载脚本调用已安装 App 的 --register-startup gui|display 与
--unregister-startup gui|display,后者停止运行中的显示后台必须先获得其停止确认。
uninstall 只停止并注销这两个服务,保留 App 和所有历史运行数据,不自动恢复旧服务。
bin/maci --stop-display-service
会释放后台持有的虚拟屏;涉及最后一屏时拒绝执行,只有明确接受断屏后 才可加
--allow-last-display-loss。这不会删除已保存的屏幕定义。
构建后可直接运行 open dist/maci.app --args --demo 试用固定图片翻译,或使用
open dist/maci.app --args --show-panel 打开菜单栏面板。重复打开已运行的 App
不会重新传递 启动参数,但会重新打开菜单栏面板;日常使用也可点击菜单栏入口。
文档约定
项目源码只维护两份 Markdown 文档:
- README.md:面向人的产品、架构、运行和迁移说明;
- AGENTS.md:面向开发 Agent 的工作约束与验证规则。
不要新增 domain 级 README、AGENTS、SKILL、历史计划或设计 QA 文档;相关有效信息应归并
到上述两份文件。LICENSE、NOTICE、代码注释、API 类型和测试不属于此限制。
清理记录
- 历史 Perry 桌面端、Proxy、Downip、LivpExplorer 与完整 PlaysVideo domain 已移除;新的
openfx-macos 只承载当前文件库的 WKWebView 和原生 Photos 导入,不恢复旧桌面产品;
- PlaysVideo 仍被使用的最小发布引擎已固定在 domains/media-player/vendor/;
- _shared 中没有产品调用的历史工具已删除;只服务 how-much 的 KV adapter 已回归其
domain,livp-codec.ts 按文件库事实边界保留;
- 历史设计稿、重复上游说明和旧清理报告已在文档收口时删除。
协议与来源
仓库主体使用 Apache-2.0,见 LICENSE 与 NOTICE。包含独立许可证的 domain
继续以各自目录中的 LICENSE 为准。主要上游来源包括 BewlyCat/BewlyBewly、
ChronoFrame、maptoposter 和 playsvideo;保留其源码许可与第三方声明。扫码进群