Only in One · 首次打开必读
============================================================

这是团队内部工具，只在团队内部流转。

我们没有 Apple 开发者账号（$99/年），所以这个包：
  · 用的是 ad-hoc 签名（本机临时签名），不是 Apple 的 Developer ID 签名；
  · 没有提交 Apple 公证（notarization）。

因此第一次打开时，macOS 的 Gatekeeper 会拦住它。
这是"未公证"的固定提示 —— **不是说这个包里被检出了病毒**。


------------------------------------------------------------
一、你会看到什么，以及那两句话到底是什么意思
------------------------------------------------------------

可能看到（macOS 15 及以后）：

  未打开"Only in One.app"，因其包含恶意软件。此操作未对 Mac 造成危害。

或（更早的措辞）：

  "Only in One" 无法打开，因为 Apple 无法检查其是否包含恶意软件。

这两句是 macOS 对**所有未经公证的 App** 的固定文案。
确切含义是：Apple 手里没有这个 App 的公证记录，无法替它背书。
不是说扫描到了恶意代码 —— 一个纯手写、功能极简的内部工具也会收到一模一样的提示。

想自己确认"包没被检出病毒、也没被人改过"，在"终端"里粘这一行并回车：

    codesign --verify --deep --strict "/Applications/Only in One.app" && echo "包是完好的"

  · 输出「包是完好的」= 包的每一个文件都与签名记录完全一致，没有被篡改过。
  · 报错 / 没有输出后半句 = 包真的有问题。别用，重新要一份。

再看这一条（它一定会显示 rejected，这是预期）：

    spctl -a -t exec -v "/Applications/Only in One.app"

  → rejected

  rejected 的含义是"没有 Apple 的公证记录"，**不等于**"包含恶意软件"。
  任何没有花钱做公证的软件，都会得到这个结果 —— 包括很多商业软件的老版本。

一句话判据：
    codesign 通过 + spctl rejected  =  包是好的，只是没公证。
    codesign 不通过                 =  包是坏的，别用。


------------------------------------------------------------
二、怎么打开（两种办法，任选一种）
------------------------------------------------------------

【办法 1 · 推荐，全程点鼠标】系统设置 → 隐私与安全性 → 仍要打开
（一次性操作，之后双击就正常）

  1. 打开 dmg，把 "Only in One" 拖进旁边的"应用程序"文件夹。
  2. 在"访达"里双击 "Only in One"，会弹出拦截提示。
     点「完成」把提示关掉。
     —— 这一步不能省：系统要"看见"你被拦了一次，才会在设置里给出放行入口。
     （如果提示上的按钮是「移到废纸篓」，别点它，直接关掉窗口即可。）
  3. 点屏幕左上角 苹果菜单  →  系统设置  →  隐私与安全性。
  4. 往下滚到「安全性」一节，会看到一行：

        "Only in One" 已被阻止，以保护 Mac

     点它右边的「仍要打开」。
  5. 输入开机密码（或用触控 ID）。
  6. 系统再问一次「仍要打开"Only in One"吗？」→ 再点一次「仍要打开」。

  之后就正常了，以后双击直接进。

  ⚠️ 那个「仍要打开」按钮只在你被拦之后的约 1 小时内出现。
     翻遍了"隐私与安全性"也找不到 = 隔太久了。回到第 2 步再双击一次，
     然后立刻去系统设置，按钮就回来了。

  ⚠️ macOS 15（Sequoia）起，Apple 删掉了老办法「右键 App → 打开 → 再点"打开"」。
     现在右键菜单里没有那个"打开"项了。网上绝大多数教程还是旧版本的写法，
     照着找会找不到 —— 不是你的 Mac 有问题。

【办法 2 · 应急，用终端】open -a
（临时用一下可以，但不会改变"双击被拦"这件事）

  先把 App 拖进"应用程序"文件夹，然后打开"终端"，粘贴这一行并回车：

      open -a "/Applications/Only in One.app"

  这条命令不经过"访达"的那道检查，所以能直接起来。
  想让以后双击也正常，仍然要按办法 1 走一次（只需一次）。


------------------------------------------------------------
三、校验你拿到的包没被改过
------------------------------------------------------------

dmg 里不会放它自己的 SHA-256 —— 自己算自己，做不到。
哈希在 dmg 外面，和 dmg 放在一起的 SHA256SUMS.txt 里。

在 dmg 所在目录打开"终端"，跑：

    shasum -a 256 -c SHA256SUMS.txt

    OnlyInOne-0.2.0-mac-arm64.dmg: OK      ← 这一行两个都要 OK
    OnlyInOne-0.2.0-win-x64.zip:  OK

只想核对 dmg 这一个：

    shasum -a 256 OnlyInOne-0.2.0-mac-arm64.dmg

把输出的 64 位十六进制串，与发送方给你的值**逐字符**比对。
一致才用。不一致 = 传坏了或被人改过，请重新要一份，不要打开。

Windows 侧对应命令（PowerShell）：

    Get-FileHash .\OnlyInOne-0.2.0-win-x64.zip -Algorithm SHA256

装好之后想再确认一次 App 本体，用第一节的 codesign 命令。


------------------------------------------------------------
四、装完之后，数据存在哪
------------------------------------------------------------

只有一处，升级覆盖不会丢：

    ~/Library/Application Support/onlyinone-launcher

里面有 settings.json（服务器地址等设置）、credential.bin（登录态）、
logs/（日志）、app-cache/（设备列表缓存），以及 Chromium 自己的缓存目录。

程序本体在 /Applications/Only in One.app，和上面这个目录**完全分开**：
删掉 App 重装、换成新版本，数据都还在。

想自己看一眼：

    ls -la ~/Library/Application\ Support/onlyinone-launcher

彻底卸载（连数据一起删）：

    osascript -e 'quit app "Only in One"'      # 先从托盘菜单退出（关窗口 ≠ 退出）
    rm -rf "/Applications/Only in One.app"     # 程序本体
    rm -rf ~/Library/Application\ Support/onlyinone-launcher   # 数据（含登录态）
    defaults delete com.onlyinone.launcher     # 系统偏好设置里那条记录


------------------------------------------------------------
五、为什么每次换新版本，又要放行一次
------------------------------------------------------------

放行记录是跟"这个 App 的代码指纹（cdhash）"绑定的，不是跟文件名绑定。
我们的包是 ad-hoc 签名（没有团队标识），**每次重新打包，代码指纹都会变**。
系统于是认为"这又是一个没见过的新 App"，重新拦一次。

所以：
    **每次升级到新版本，都要重新走一次办法 1。**
    上次明明放行过、这次又被拦 —— 这是正常的，不是杀毒软件变严了，
    也不是新包出了问题。

要彻底消除这个提示，只有两条路：
  · 买 Apple 开发者账号（$99/年），做 Developer ID 签名 + 公证；
  · 或者把 Gatekeeper 关掉（不推荐：等于对整台机器关掉这道防线）。
团队目前选择不做，接受"每次升级点两下"。

遇到别的怪现象，先看仓库 docs/troubleshooting.md，
其中第 19 条就是"双击提示包含恶意软件打不开"的完整排查。
