diff --git a/.github/scripts/bundle-macos.sh b/.github/scripts/bundle-macos.sh index 5f6aa63d..b2566676 100755 --- a/.github/scripts/bundle-macos.sh +++ b/.github/scripts/bundle-macos.sh @@ -68,6 +68,40 @@ cat > "$APP/Contents/Info.plist" <CFBundlePackageTypeAPPL NSHighResolutionCapable NSPrincipalClassNSApplication + + NSCameraUsageDescription + A program running inside tty7 would like to access the camera. + NSMicrophoneUsageDescription + A program running inside tty7 would like to access the microphone. + NSContactsUsageDescription + A program running inside tty7 would like to access your contacts. + NSCalendarsFullAccessUsageDescription + A program running inside tty7 would like to access your calendar data. + NSRemindersFullAccessUsageDescription + A program running inside tty7 would like to access your reminders. + NSPhotoLibraryUsageDescription + A program running inside tty7 would like to access your photo library. + NSLocationUsageDescription + A program running inside tty7 would like to access your location information. + NSMotionUsageDescription + A program running inside tty7 would like to access motion data. + NSLocalNetworkUsageDescription + A program running inside tty7 would like to access the local network. + NSBluetoothAlwaysUsageDescription + A program running inside tty7 would like to use Bluetooth. + NSSpeechRecognitionUsageDescription + A program running inside tty7 would like to use speech recognition. + NSSystemAdministrationUsageDescription + A program running inside tty7 requires elevated privileges. + NSAppleEventsUsageDescription + A program running inside tty7 would like to control other applications via Apple Events. PLIST @@ -109,6 +143,18 @@ if [[ -n "$SIGN_ID" && -n "${APPLE_CERTIFICATE:-}" ]]; then com.apple.security.cs.allow-jit com.apple.security.cs.allow-unsigned-executable-memory com.apple.security.cs.disable-library-validation + ENT diff --git a/docs/features.md b/docs/features.md index 215cecf6..e8ea8231 100644 --- a/docs/features.md +++ b/docs/features.md @@ -122,6 +122,25 @@ a brief pause; `prefix` + an unbound key passes straight through. - Hot paths are lock-free — a big `cat` never waits on drawing - The daemon buffers up to 16 MiB ahead of the window before backpressure applies +## macOS privacy + +Panes are forked from the bundled executable, so macOS attributes a program's +request for a protected resource to tty7.app. tty7 declares the matching TCC +usage strings (camera, microphone, contacts, calendar, reminders, photos, +location, local network, Bluetooth, speech recognition, Apple Events, system +administration) so that program gets the normal one-time prompt instead of +being denied outright with no prompt at all. + +Not covered by usage strings: + +- **Full Disk Access** — Apple defines no usage-string key for it. Reaching + `~/Library/Mail`, `~/Library/Messages`, `~/Library/Safari` or + `~/Library/Containers` needs a manual grant in System Settings. + +Declaring a usage string is not the same as holding the permission: tty7.app +itself is granted none of these resources. Every prompt you see belongs to +whatever you ran in the pane, and you can revoke it under Privacy & Security. + ## Localization The GUI ships English and Simplified Chinese strings. Pick one in Settings → diff --git a/docs/features.zh-CN.md b/docs/features.zh-CN.md index 564ae3f7..99cc7af4 100644 --- a/docs/features.zh-CN.md +++ b/docs/features.zh-CN.md @@ -118,6 +118,23 @@ Aider、Amp、OpenCode 等约 17 个)并在其外围加功能 —— 绝不包 - 热路径全程无锁 —— 再大的 `cat` 也不会阻塞在渲染上 - 触发背压前,守护进程最多可领先窗口缓冲 16 MiB +## macOS 隐私 + +窗格是从 app bundle 里的可执行文件 fork 出来的,所以程序申请受保护资源时, +macOS 会把这次请求算到 tty7.app 头上。tty7 声明了对应的 TCC usage strings +(摄像头、麦克风、通讯录、日历、提醒、照片、定位、本地网络、蓝牙、语音识别、 +Apple Events、系统管理),这样程序才能正常弹出一次性授权窗口,而不是连弹窗都 +没有就被直接拒绝。 + +不受 usage strings 覆盖的: + +- **完全磁盘访问** —— 苹果没有为它定义 usage-string 键。要读写 + `~/Library/Mail`、`~/Library/Messages`、`~/Library/Safari` 或 + `~/Library/Containers`,需要在「系统设置」中手动授权。 + +声明 usage string 不等于持有权限:tty7.app 自己一项都没有拿到。你看到的每个 +授权弹窗都属于你在窗格里运行的那个程序,也可以在「隐私与安全性」中撤销。 + ## 本地化 GUI 目前提供英文和简体中文两套文案。在「设置 → 外观 → 语言」中选择,或直接改