Skip to content

Commit 4f04343

Browse files
committed
build(macos): 修复输入法不显示并加固用户域安装与部署/构建脚本
1 parent e8c7e20 commit 4f04343

12 files changed

Lines changed: 352 additions & 133 deletions

File tree

dev_mac.sh

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,23 @@ usage() {
1212
WindInput - Dev Menu (macOS) 调试版加前缀 d (如 d1 / d2 / dr / di / du)
1313
1414
-- 构建 --
15-
1 构建全部 (Go 服务 + 词库 + IME .app)
16-
2 仅构建 Go 服务 (跳过词库下载)
17-
app 仅构建 IME .app bundle
18-
clean 清 build/ 与 build_debug/
15+
1 构建全部 (Go 服务 + 词库 + IME .app + 设置应用)
16+
2 仅构建 Go 服务 (跳过词库下载)
17+
app 仅构建 IME .app bundle
18+
setting 仅构建设置应用 wind_setting.app (Wails)
19+
clean 清 build/ 与 build_debug/
1920
2021
-- 本机安装 / 卸载 --
21-
i 本机安装 (Go 服务 LaunchAgent + IME .app)
22+
i 本机安装全部 (Go 服务 LaunchAgent + IME .app + 设置应用)
23+
m <模块…> 单模块 构建+安装 (模块: service / app / setting; 如 m setting / m service app)
2224
redeploy IME .app 重签 + 重装 + TIS 验证 (需 SIGN_IDENTITY, macOS 26 主入口)
23-
u 本机卸载 (Go 服务 + IME .app)
25+
u 本机卸载全部 (Go 服务 + IME .app + 设置应用)
2426
2527
-- 远程 VM (余参透传给 scripts_mac/vm/deploy.sh) --
26-
deploy host→VM 一键部署 (服务 + .app)
28+
deploy host→VM 一键部署 (服务 + .app; 加 --setting 含设置应用)
2729
undeploy host→VM 远程卸载 + 验证清除
28-
(附加 --service-only / --app-only / 目标 admin@ip 均透传)
30+
(附加 --service-only / --app-only / --setting / --setting-only
31+
/ 目标 admin@ip 均透传)
2932
3033
-- 运行 / 诊断 (macOS IME 专用) --
3134
r 前台运行 Go 服务 (debug 日志)
@@ -57,24 +60,49 @@ case "$CHOICE" in
5760
esac
5861

5962
# ---- 构建 ----
60-
do_build_all() { "$MAC/build/build.sh" all ${VARIANT:+$VARIANT}; "$MAC/build/app.sh" ${VARIANT:+$VARIANT}; }
61-
do_build_svc() { "$MAC/build/build.sh" service ${VARIANT:+$VARIANT}; }
62-
do_build_app() { "$MAC/build/app.sh" ${VARIANT:+$VARIANT}; }
63-
do_clean() { "$MAC/build/build.sh" clean; }
63+
# 设置应用 (Wails) 无 debug 变体, VARIANT 仅作用于 Go 服务 / IME .app.
64+
do_build_all() { "$MAC/build/build.sh" all ${VARIANT:+$VARIANT}; "$MAC/build/app.sh" ${VARIANT:+$VARIANT}; "$MAC/build/setting.sh"; }
65+
do_build_svc() { "$MAC/build/build.sh" service ${VARIANT:+$VARIANT}; }
66+
do_build_app() { "$MAC/build/app.sh" ${VARIANT:+$VARIANT}; }
67+
do_build_setting() { "$MAC/build/setting.sh"; }
68+
do_clean() { "$MAC/build/build.sh" clean; }
6469

6570
# ---- 安装 / 部署 ----
66-
# install_service.sh 是 per-user (不要 sudo); install_app.sh 装到 /Library/ 需 sudo.
71+
# install_service.sh / install_app.sh / install_setting.sh 均为 per-user (装到 ~/Library
72+
# 或 ~/Applications), 都不要 sudo.
6773
do_install() {
6874
"$MAC/deploy/install_service.sh" ${VARIANT:+$VARIANT}
69-
sudo bash "$MAC/deploy/install_app.sh"
75+
bash "$MAC/deploy/install_app.sh"
76+
bash "$MAC/deploy/install_setting.sh"
7077
}
7178
do_redeploy() { bash "$MAC/deploy/redeploy.sh"; }
7279
do_deploy() { bash "$MAC/vm/deploy.sh" "$@"; }
7380

81+
# 单模块 构建+安装 (对位 Windows dev.ps1 的 m[N]). 模块: service / app / setting.
82+
do_module() {
83+
[[ $# -gt 0 ]] || { echo "[错误] m 需指定模块: service / app / setting (如 m setting)" >&2; exit 1; }
84+
local mod
85+
for mod in "$@"; do
86+
case "$mod" in
87+
service|svc)
88+
"$MAC/build/build.sh" service ${VARIANT:+$VARIANT}
89+
"$MAC/deploy/install_service.sh" ${VARIANT:+$VARIANT} ;;
90+
app)
91+
"$MAC/build/app.sh" ${VARIANT:+$VARIANT}
92+
bash "$MAC/deploy/install_app.sh" ;;
93+
setting|set)
94+
"$MAC/build/setting.sh"
95+
bash "$MAC/deploy/install_setting.sh" ;;
96+
*) echo "[错误] 未知模块: $mod (可选 service / app / setting)" >&2; exit 1 ;;
97+
esac
98+
done
99+
}
100+
74101
# ---- 卸载 ----
75102
do_uninstall() {
76103
"$MAC/deploy/install_service.sh" --uninstall
77-
sudo bash "$MAC/deploy/install_app.sh" --uninstall
104+
bash "$MAC/deploy/install_app.sh" --uninstall
105+
bash "$MAC/deploy/install_setting.sh" --uninstall
78106
}
79107

80108
# ---- 运行 / 诊断 ----
@@ -118,8 +146,10 @@ case "$CHOICE" in
118146
1) do_build_all ;;
119147
2) do_build_svc ;;
120148
app) do_build_app ;;
149+
setting) do_build_setting ;;
121150
clean) do_clean ;;
122151
i) do_install ;;
152+
m) do_module "${@:2}" ;;
123153
redeploy) do_redeploy ;;
124154
u) do_uninstall ;;
125155
deploy) do_deploy "${@:2}" ;;

scripts_mac/AGENTS.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ WindInput 在 macOS 上的全部辅助脚本:Go 服务与 IMKit `.app` 的构
1616
| `test/` | TIS 注册状态诊断 |
1717
| `vm/` | host→tart VM 一键远程部署 |
1818

19-
仓库根 `dev_mac.sh`(macOS 开发菜单)调用本目录的 `build/build.sh``build/app.sh``deploy/install_app.sh``test/list_input_sources.swift`
19+
仓库根 `dev_mac.sh`(macOS 开发菜单)调用本目录的 `build/build.sh``build/app.sh``build/setting.sh``deploy/install_service.sh``deploy/install_app.sh``deploy/install_setting.sh``deploy/redeploy.sh``vm/deploy.sh``test/list_input_sources.swift`。「构建全部」(`1`)/「本机安装全部」(`i`)/「本机卸载全部」(`u`) 均含 `wind_setting``m <service|app|setting…>` 为单模块构建+安装(对位 Windows `dev.ps1``m[N]`
2020

2121
## Key Files
2222

@@ -32,8 +32,9 @@ WindInput 在 macOS 上的全部辅助脚本:Go 服务与 IMKit `.app` 的构
3232

3333
| File | Description |
3434
|------|-------------|
35-
| `install_app.sh` |`WindInput.app` 装到 `/Library/Input Methods/`:cp + 不重签(保留 build 阶段签名)+ `lsregister -f -R` 刷 LS DB + `WindInput --register-input-source` / `--enable-input-source` 让 IME 自身进程调 TIS API。`--uninstall` 卸载,`--build` 先 build。需 sudo |
36-
| `install_service.sh` | 把 Go 服务(`wind_input` + `data/`)装到 per-user `~/Library/Application Support/WindInput/service/`,生成并装 LaunchAgent `to.feng.windinput.service.plist``RunAtLoad`+`KeepAlive` 开机自启),`launchctl bootstrap/enable/kickstart` 启动,末尾验证 push socket + err.log。普通用户运行(不要 sudo)。开关:`--debug` / `--from <dir>`(指定源目录,部署脚本远程用)/ `--uninstall`。服务用 `exeDir/data` 定位词库,故二进制与 `data/` 必须同目录 |
35+
| `install_app.sh` |`WindInput.app` 装到 per-user `~/Library/Input Methods/`(用户域,**不要 sudo**):cp + 对 ad-hoc 产物原地去 hardened-runtime 重签(`codesign --force -s -` → 纯 ad-hoc `flags=0x2`,与 Fcitx5 一致;真证书产物则保留不降级)+ `lsregister -f -R` 刷 LS DB + `WindInput --register-input-source` 让 IME 自身进程调 TIS API。`--uninstall` 完整清理(删 .app + 清 HIToolbox plist + 缓存 + SIGTERM 重启 input agents),`--build` 先 build。**不再 `spctl --add`**(Tahoe 已移除该能力且证伪无必要)。能否进系统设置「可添加列表」取决于 `Info.plist` **不带** `tsInputModeDefaultStateKey`(带则 mode 注册即「已启用」却不落盘 → 被「+」列表过滤掉看不见,见 `wind_macos` Info.plist 说明) |
36+
| `install_service.sh` | 把 Go 服务(`wind_input` + `data/`)装到 per-user `~/Library/Application Support/WindInput/service/`,生成并装 LaunchAgent `to.feng.windinput.service.plist``RunAtLoad`+`KeepAlive` 开机自启),`launchctl bootstrap/enable/kickstart` 启动,末尾验证 push socket + err.log。普通用户运行(不要 sudo)。开关:`--debug` / `--from <dir>`(指定源目录,部署脚本远程用)/ `--uninstall`。装时 cp 后 `codesign --force -s -` 原地 ad-hoc 重签(跨机同路径 redeploy 触发 amfi cdhash 缓存失配 → `OS_REASON_CODESIGNING`)+ `pkill -f "$INSTALL_ROOT/wind_input"` 清孤儿进程(bootout 只杀托管实例)。服务用 `exeDir/data` 定位词库,故二进制与 `data/` 必须同目录 |
37+
| `install_setting.sh` |`wind_setting.app`(Wails 设置界面)装到 per-user `~/Applications/`,去 quarantine + ad-hoc 重签 + `lsregister -f -R` 刷 LS DB,让 IME 菜单 "设置…" 经 `NSWorkspace` 按 bundleID `com.wails.wind_setting` 启动。普通用户运行(不要 sudo,非输入法不进 `/Library/Input Methods`)。开关:`--build`(先跑 `build/setting.sh`)/ `--from <dir>` / `--uninstall`**绝不**对已删路径跑 `lsregister -u`(见 install_app.sh 血泪教训),卸载仅 rm + kill |
3738
| `redeploy.sh` | 一键 build + uninstall + install + 自动验证签名链 + 跑 TIS list 看是否被收录。必须以普通用户跑(codesign 要 user login keychain),内部对需 root 步骤显式 invoke sudo。强制用 `SIGN_IDENTITY` 真证书签名(默认 "WindInput Dev")。开发期 `.app` 主入口 |
3839
| `setup_signing.sh` | 命令行创建本机 self-signed Code Signing 证书:openssl 生成 RSA + X509(codeSigning EKU)→ PKCS12(`-legacy`)→ import 到 login keychain → `add-trusted-cert` 加 trust。子命令: 默认创建 / `check` / `remove` |
3940
| `setup_signing.md` | self-signed 证书的手动(Keychain Access GUI)创建步骤备份;macOS 26 Tahoe 上路径菜单与老版本不同时可作参考 |
@@ -48,7 +49,7 @@ WindInput 在 macOS 上的全部辅助脚本:Go 服务与 IMKit `.app` 的构
4849

4950
| File | Description |
5051
|------|-------------|
51-
| `deploy.sh` | host→VM 一键部署:宿主机构建产物 rsync 到目标 macOS 机后远程调 `deploy/install_service.sh`/`deploy/install_app.sh`。目标解析顺序:位置参数 > `SSH_TARGET` 环境变量 > 默认 `admin@$(tart ip ime-dev)`。远端 staging(`~/wind_deploy`)镜像仓库结构(`scripts_mac/{deploy,test}/`+`build/`+`wind_macos/build/`)让 install 脚本 `REPO_DIR``$SCRIPT_DIR/../..`)自对齐到 staging 根。开关:`--build` / `--debug` / `--service-only` / `--app-only` / `--uninstall`(远程卸载服务+.app 并验证清除:LaunchAgent bootout、plist/service 目录、`.app`、TIS 残留条目;不需本地产物,可叠加 `--service-only`/`--app-only` 限定范围) |
52+
| `deploy.sh` | host→VM 一键部署:宿主机构建产物 rsync 到目标 macOS 机后远程调 `deploy/install_service.sh`/`deploy/install_app.sh`。目标解析顺序:位置参数 > `SSH_TARGET` 环境变量 > 默认 `admin@$(tart ip ime-dev)`。远端 staging(`~/wind_deploy`)镜像仓库结构(`scripts_mac/{deploy,test}/`+`build/`+`wind_macos/build/`)让 install 脚本 `REPO_DIR``$SCRIPT_DIR/../..`)自对齐到 staging 根。开关:`--build` / `--debug` / `--service-only` / `--app-only` / `--setting`(加部署 `wind_setting.app`)/ `--setting-only`(只部署设置应用)/ `--uninstall`(远程卸载服务+.app+设置 并验证清除:LaunchAgent bootout、plist/service 目录、`.app``~/Applications/wind_setting.app`TIS 残留条目;不需本地产物,可叠加 `--service-only`/`--app-only`/`--setting-only` 限定范围)。设置应用默认不部署(opt-in),远程调 `install_setting.sh`(普通用户|
5253

5354
## Usage
5455

@@ -74,14 +75,14 @@ scripts_mac/deploy/setup_signing.sh
7475
SIGN_IDENTITY="WindInput Dev" scripts_mac/deploy/redeploy.sh
7576
```
7677

77-
`redeploy.sh` 流程: 验证 identity → 解锁 keychain + partition list → `build/app.sh``sudo deploy/install_app.sh --uninstall``sudo deploy/install_app.sh`(cp + lsregister + IME 自身 `--register-input-source`/`--enable-input-source`)→ 验证签名 + `test/list_input_sources.swift` → ✓/✗ 总结。
78+
`redeploy.sh` 流程: 验证 identity → 解锁 keychain + partition list → `build/app.sh``deploy/install_app.sh --uninstall``deploy/install_app.sh`用户域 ~/Library,无 sudo;cp + lsregister + IME 自身 `--register-input-source`)→ 验证签名 + `test/list_input_sources.swift` → ✓/✗ 总结。
7879

7980
单独跑各步:
8081

8182
```bash
8283
SIGN_IDENTITY="WindInput Dev" scripts_mac/build/app.sh # 仅 build
83-
sudo SIGN_IDENTITY="WindInput Dev" scripts_mac/deploy/install_app.sh
84-
sudo scripts_mac/deploy/install_app.sh --uninstall
84+
scripts_mac/deploy/install_app.sh # 装到 ~/Library (用户域, 无 sudo)
85+
scripts_mac/deploy/install_app.sh --uninstall
8586

8687
swift scripts_mac/test/list_input_sources.swift # 第三方 IME
8788
swift scripts_mac/test/list_input_sources.swift --all # 全部

scripts_mac/build/build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,5 +260,5 @@ bold "==> Build complete"
260260
[[ -d "$BUILD_DIR/data" ]] && info "data : $BUILD_DIR/data ($(find "$BUILD_DIR/data" -type f | wc -l | tr -d ' ') 文件)"
261261
echo
262262
info "调试启动: cd $BUILD_DIR && WIND_INPUT_LOG_LEVEL=debug ./$EXE_NAME"
263-
info "日志: \$HOME/Library/Caches/WindInput/logs/wind_input.log"
263+
info "日志: \$HOME/Library/Logs/WindInput/wind_input.log"
264264
info "Socket: \$HOME/Library/Application Support/WindInput/bridge{,_push}.sock"

scripts_mac/build/setting.sh

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
#!/usr/bin/env bash
22
# build_macos_setting.sh — 在 macOS 上构建 wind_setting.app (Wails+Vue 设置界面)。
33
#
4-
# 处理本工程在新版工具链下的两个坑:
5-
# 1. pnpm 11 对未批准的构建脚本 (vue-demi) 退出码非 0 —— 用 `|| true` 容忍
6-
# 2. vue-tsc 严格类型检查失败 (TS6/Vite8) —— 直接用 vite build 跳过 tsc 门禁
4+
# 处理本工程在新版工具链下的坑:
5+
# - vue-tsc 严格类型检查失败 (TS6/Vite8) —— 直接用 vite build 跳过 tsc 门禁
6+
# (vue-demi 的构建脚本已由 frontend/pnpm-workspace.yaml 的 allowBuilds 显式批准,
7+
# pnpm 11 不再因 ignored-builds 报非 0 退出码)
78
#
89
# 并把程序数据 (data/: schemas/themes/词库) 拷进 .app, 因为设置界面按 exeDir/data
910
# 扫描内置方案与主题, 而 macOS .app 的可执行目录 (Contents/MacOS) 旁边没有 data。
@@ -31,8 +32,8 @@ cd "$SETTING_DIR"
3132
bold "==> [1/5] 生成 Wails JS 绑定 (frontend/wailsjs)"
3233
wails generate module
3334

34-
bold "==> [2/5] 安装前端依赖 (容忍 pnpm 11 的 ignored-builds 退出码)"
35-
( cd frontend && pnpm install || true )
35+
bold "==> [2/5] 安装前端依赖"
36+
( cd frontend && pnpm install )
3637

3738
bold "==> [3/5] 构建前端 (vite, 跳过 vue-tsc 严格门禁)"
3839
( cd frontend && ./node_modules/.bin/vite build )

0 commit comments

Comments
 (0)