macOS support, GitHub Releases updates, and a semi-automatic Root wizard (v1.0.7)#4
Merged
Birditch merged 15 commits intoJul 15, 2026
Merged
Conversation
- CliLauncher: branch by platform. macOS now writes an equivalent .command shell script with the same numbered menu and opens it in Terminal.app; previously it hardcoded cmd.exe + .bat and failed silently on macOS. - Surface launch failures via Notifier (toast) instead of only logging. - Add cli.unsupported / cli.launchFailed strings to both ResX files. - Packaging: generate AppIcon.icns from atv-icon.png (sips + iconutil) and set CFBundleIconFile so the macOS .app shows an icon in Dock/Finder.
Sync version across AppInfo, App/Mini/Mini.Mac project metadata, app.manifest, packaging scripts, wix, docs, and README.
- Platform badge Windows -> Windows + macOS - Describe as cross-platform (Windows + macOS Apple Silicon), not Windows-only - Generalize the usage section and add a macOS subsection (Terminal.app CLI, drag to /Applications, Gatekeeper). English README already covered this.
分步向导:上传刷机包→提取 boot.img→手机端官方 Magisk 修补→进 bootloader→flash boot,写操作前强制确认+自动备份原始 boot。双平台(Windows/macOS)。
- 构建时打包固定版 Magisk APK(SHA-256 校验),运行时 adb install - 修补改用已装 App 自带的 boot_patch.sh + native 组件,不再桌面侧拆各 ABI 二进制 - 同步 §1.1/§2/§3/§4/§5.1/§6.2/§7/§8/§10/§11/§13 - 保留第 4 步实机验证警告(已装 App 脚本能否被 adb shell 直接调到仍待验证)
…con' into fix/macos-cli-terminal-and-app-icon # Conflicts: # CLAUDE.md
Adds the semi-automatic Root wizard: extract boot/init_boot from a user-supplied firmware package, patch it with components taken from the pinned official Magisk APK, and flash it after backup, ADB-to-fastboot identity verification, unlock/layout checks and explicit confirmation. This is a deliberate exception to the read-only stance: the wizard writes only an evidence-backed boot / init_boot image. It never unlocks the bootloader and never touches system, vendor, vbmeta, recovery or super. Patch flags are probed on the device with official Magisk's own app_init (app_functions.sh) and passed to boot_patch.sh as environment variables. This is not optional: boot_patch.sh silently defaults a missing flag to false and ends in a bare `true`, so its exit code proves nothing. On a system-as-root device KEEPVERITY=false strips `logical` and `first_stage_mount` off the /system fstab entry, leaving first-stage init unable to mount the root filesystem — a guaranteed bootloop. Verified on a real Redmi Note 9 5G (cannon, MT6853, Android 12/MIUI 14): with the probed flags the patcher reproduces the official Magisk app's output byte-for-byte; without them it does not. As defence in depth, the patched image's own config is read back out of the ramdisk and compared against the probed flags before the image is allowed anywhere near the flash step. Neither the exit code nor a header check can catch a wrongly-flagged image — it is structurally valid. Bumps every aligned version field to 1.0.7 and points the README device screenshot at the image that actually exists (v1.0.5); it had referenced a v1.0.6 file that was never added. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ChatGPT PR 初审我会先对改动里最容易影响发布和真实设备写入的部分做针对性检查:打包脚本、Root 写入门控、更新解析和 CI 校验。重点只放在能明确导致构建/发布失败或用户设备风险的证据上。 结论建议通过。基于提供的 diff,未发现高置信度的构建、CI、发布、安全或真实用户必现故障阻塞项。Root 向导确实改变项目原本的只读边界,但 PR 已明确披露风险,并在代码/文档层面加入备份、身份校验、目标分区限制、确认门控和打包隔离,是否接受该产品方向属于维护者决策,不应作为自动评审阻塞。 阻塞问题无 非阻塞建议
这是自动初审建议,不代表维护者正式批准。第三方 PR 的代码没有在此 workflow 中执行。 |
`tools/verify-scrcpy-latest.ps1` asserts the pin equals the latest upstream release, so the Publish workflow started failing the moment scrcpy 4.1 shipped on 2026-07-12. Unrelated to anything else in this branch. Verified by running the packaged binary, not by trusting the pin: the rebuilt osx-arm64 bundle reports `scrcpy 4.1`. Worth knowing for the next bump: `Get-ScrcpyRoot` in build-update-zip.ps1 caches at artifacts/tools/scrcpy/<rid> and keys the cache on whether the executable exists, not on its version. A local rebuild after a version bump therefore keeps the old binary and silently produces a stale package — CI is unaffected because it always starts from a clean tree. Delete artifacts/tools/scrcpy to force it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The macOS packaging job died with "/usr/bin/test is not recognized". `test` lives at /bin/test on macOS; /usr/bin/test is a Linux path. Only the App osx-arm64 job reached this branch, so it was the only one to fail. Uses System.IO.File.GetUnixFileMode instead of shelling out, which needs no external binary and no assumption about its path. Reproduced the failure and verified the fix locally under pwsh on macOS, including stripping the exec bit to confirm the check still rejects a non-executable payload-dumper-go. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
拉取请求 (Pull Request)
摘要 (Summary)
This branch carries three separable bodies of work: macOS support, an update path backed by GitHub
Releases, and a semi-automatic Root wizard. The Root wizard is the one that needs a real decision from
you, because it deliberately changes the project's read-only guarantee — this PR edits
AGENTS.mdto carve out one exception.
The exception is narrow: the wizard extracts
boot/init_bootfrom a user-supplied firmware package,patches it with components taken from the pinned official Magisk APK, and flashes only that
evidence-backed image, after a backup, ADB-to-fastboot identity verification, unlock/layout checks and
an explicit risk acknowledgement. It never unlocks the bootloader and never writes
system,vendor,vbmeta,recoveryorsuper.What you should weigh: this can brick a phone, and there is no environment-variable kill switch —
the only thing between a user and a real write is the in-app confirmation screen and its checkbox. If
the read-only guarantee is load-bearing for you, this section is a "no" and the other two parts still
stand on their own; say so and they can be split out.
SIGN 声明 (SIGN Declaration)
(I certify that I have the right to submit this work and agree it is provided under this repository's license.)
类型 (Type)
细节 (Details)
1. Root wizard — validated end-to-end on real hardware
Verified on a real Redmi Note 9 5G (cannon, MT6853, Android 12 / MIUI 14): extract → patch → flash →
boot. The device boots normally and is rooted —
magisk -creports30.7:MAGISK:R (30700), i.e. thedaemon is live, which only happens if the patched boot actually booted.
Getting there surfaced the bug worth reviewing carefully.
boot_patch.shsilently defaults a missingflag to
falseand ends in a baretrue, so its exit code proves nothing. The first implementationinvoked it with no environment at all. On a system-as-root device
KEEPVERITY=falsestripslogicaland
first_stage_mountoff the/systemfstab entry:First-stage init then cannot mount the root filesystem — a guaranteed bootloop, which is exactly what
happened on the first real flash. Note this is not the AOSP "no avb, mount directly" fallback: the
entry loses
first_stage_mountentirely, so first-stage never considers it.The fix runs official Magisk's own
app_initprobe (app_functions.sh) on the device and passes thederived flags to
boot_patch.sh. Measured against the official Magisk app's output for the sameboot.img:992692fb…61d9c187…61d9c187…Byte-for-byte identical to what the official app produces.
As defence in depth, the patched image's own config is read back out of the ramdisk and compared to
the probed flags before the image can reach the flash step. Neither an exit code nor a header check
can catch a wrongly-flagged image — it is structurally valid. With the fix reverted, this gate rejects
the image with the exact diagnostic, before any write.
Deliberately not done: no vbmeta flashing. Official Magisk flashes a single partition, this device
reports
PATCHVBMETAFLAG=false, and upstream documentsfastboot flash vbmeta --disable-verityasoptional and data-wiping. Keeping vbmeta out of scope is correct.
2. macOS support
CLI terminal fix, app bundle icon with safe-area padding, signed
.appbundles, and aMini.MacAvalonia variant.
3. Updates via GitHub Releases
Replaces the previous private HTTP index (
NekoIndexUpdateService, pointing at a hard-coded LANaddress) with
GitHubUpdateServicereading GitHub Releases, plus SHA-256 verification of assets.安全影响 (Security Impact)
(No GitHub Actions, release scripts, packaging scripts, or binary artifacts were changed.)
(If sensitive areas were changed, I explained why in the summary or details.)
Sensitive areas changed, and why:
.github/workflows/publish.yml— verifies the Root tool pins, and asserts Mini ZIPs contain noroot-tools/(Root tooling is App-only).build/AndroidTreeView.RootTools.targets(new) — downloads the pinned Magisk APK andpayload-dumper-go, each SHA-256 verified at build time.
build/AndroidTreeView.Scrcpy.targets— pins platform-tools to an explicit version + SHA-256instead of
-latest, and folds in a SHA-256-verifiedfastboot.tools/verify-roottools-latest.ps1(new) — mirrors the existing scrcpy pin check for Root tools.packaging/build-update-zip.ps1,packaging/build-msi.ps1,packaging/*.wxs— version bump only.No third-party binary is committed to the repository; every bundled tool is fetched at build time from
its official release URL and checked against a pinned SHA-256.
验证 (Verification)
dotnet build -c Release通过 (build succeeds).dotnet test -c Release通过 (tests pass). — 419 tests, 0 failures.dotnet format --verify-no-changes(或已格式化)(code is formatted).On the format box — left unchecked on purpose.
dotnet format --verify-no-changescurrently failsrepo-wide with ~7028
ENDOFLINEerrors, including files this PR never touches (AppInfo.cs,Mini/Program.cs,GitHubUpdateService.cs, …). The tree stores CRLF while.editorconfig(
end_of_line = lf) and.gitattributes(* text=auto eol=lf) both specify LF. That is apre-existing condition; renormalizing the whole repo would bury this PR under an unrelated diff, so it
is left alone. Worth a separate cleanup — note
AGENTS.mdalso documents "CRLF line endings", whichcontradicts both config files.
Also built and verified all four release ZIPs at 1.0.7 (App/Mini × win-x64/osx-arm64), and bumped every
field in
docs/app-contract.md's alignment list.Fixes a pre-existing broken README image link on the way past: it pointed at
docs/images/product-devices-v1.0.6.png, which was never added to the repo. Now points atv1.0.5,which exists.
关联 Issue (Related Issues)
🤖 Generated with Claude Code