Skip to content

feat(desktop): package the macOS desktop shell as Maka.app - #6208

Merged
M4n5ter merged 1 commit into
rust-previewfrom
feat/desktop-macos-app-bundle
Oct 21, 2026
Merged

M4n5ter merged 1 commit into
rust-previewfrom
feat/desktop-macos-app-bundle

Conversation

@UncertaintyDeterminesYou4ndMe

Copy link
Copy Markdown
Contributor

On macOS the desktop window showed up as maka-desktop-shell, with the generic executable icon, in the Dock, the app switcher and the menu bar. macOS names a process after the bundle its executable is in, also when another process starts it directly, so the shell now runs from inside Maka.app. Layout agreed in #6078 (discussioncomment-19089554).

macOS layout

  • build-cli stages Maka.app beside maka: Contents/MacOS/maka-desktop-shell, Contents/Resources/app/ (the shell already looks for ../Resources/app), Contents/Info.plist (name, id and version from app/gpui-shell.json, with the keys gpui-shell's own bundle command writes) and Contents/Resources/Maka.icns (assets/logo.png, which already has the macOS icon margin, as one 1024-pixel entry that macOS scales). A failed staging leaves the previous bundle in place. The app/ sidecar beside maka from earlier builds is removed; cargo's bare maka-desktop-shell stays.
  • maka desktop starts Maka.app/Contents/MacOS/maka-desktop-shell beside itself. Spawning, kill_on_drop and the cancel path are unchanged. Only just build refreshes the bundle, so after rebuilding the shell with Cargo alone, just build is needed again (noted in the desktop-shell README).
  • Opening Maka.app from Finder or Spotlight starts the shell without a Host, and the app reports MAKA_HOST_ENDPOINT is not set. maka desktop remains the way to start it.
  • The @maka-agent/cli-darwin-* packages carry bin/maka and bin/Maka.app/ instead of bin/maka-desktop-shell and bin/app/.
  • Linux and Windows are unchanged.

Package verification

Target names the desktop paths per target (desktop_executable, desktop_app, desktop_tree, desktop_members), and archive.rs derives its rules from them:

  • On macOS the required members include Info.plist and Maka.icns, so the receipt records them and the cache and import checks verify them.
  • Optional members, which may be empty, are accepted only inside the app directory.
  • Directory entries are accepted only for parents of required members and for directories inside the app.
  • cached() checks the whole Maka.app tree against the receipt, not only the app, because macOS reads more of a bundle than its Info.plist.
  • A darwin package or cache entry in the old layout is refused, and older executables refuse the new layout. rust-preview keeps no compatibility here.

release-cli and verify-release run --version on the bundled shell, so the macOS jobs in npm-publication.yml build, pack, install and run the bundle. ci.yml runs on Linux and needs no change.

Checked with a packed darwin-arm64 artifact

On macOS arm64, a release build packed with pack-cli (validated by maka host fetch) and installed with npm install --offline into a new directory:

  • bin/Maka.app/Contents/MacOS/maka-desktop-shell kept its executable bit.
  • maka desktop --root … started from an unrelated working directory opened the window with the bundled app.
  • lsappinfo reports the name Maka, bundle id org.apache.maka.desktop, version 0.1.0 and the bundle path inside node_modules; the Dock shows the logo.
  • SIGTERM to maka desktop ended the shell and the Host within about 3 s.

macOS names a process after the bundle its executable is in, so the
desktop window showed up as maka-desktop-shell with the generic
executable icon. On macOS, build-cli now stages Maka.app beside maka
(the shell, the authored app, an Info.plist from the app manifest and
an icon from assets/logo.png), maka desktop starts the shell inside it,
and the darwin native packages carry bin/Maka.app instead of
bin/maka-desktop-shell and bin/app. The archive checks derive their
member, directory and cache rules from per-target paths, so the receipt
covers the Info.plist and icon and the cache check covers the whole
bundle. Linux and Windows keep their layout.

Generated-by: Claude Code
@M4n5ter
M4n5ter merged commit 30513dc into rust-preview Oct 21, 2026
2 checks passed
@M4n5ter
M4n5ter deleted the feat/desktop-macos-app-bundle branch October 21, 2026 08:13

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review notice: This comment was posted by an automated review agent. It is not an independent human review and does not replace one.

Post-merge review of 658ea3b7ebee0ebe6fe01a31917d3b35dce690c2. This PR was merged into rust-preview as 30513dc9 at 08:13 UTC on October 21, before this review was posted. Two independent review passes looked at the whole change (merge base c3100120 → head, 17 files, +536/-108). Neither found a P0–P2 defect. The findings below are P3 follow-ups.

What holds up

  • Package acceptance (distribution/archive.rs, target.rs). On darwin, the bundle shell, Info.plist, Maka.icns and the two app files are required and must be non-empty regular files. Optional files are accepted only under bin/Maka.app/Contents/Resources/app/, using an exact prefix match. Anything else inside the bundle is refused, including Contents/Frameworks/*, _CodeSignature/* and the old darwin bin/app/* layout. Directory entries are only skipped, never created. The bundle shell is treated as the executable and goes through Mach-O validation. We found no way for a malformed or tampered archive to pass.
  • Cache integrity. The cache key and receipt binding are unchanged. cached() now walks the whole bin/Maka.app tree, which covers both locations the shell searches for its app. Symlinks and unrecorded files are refused.
  • Paths agree across scripts/rust/build-cli.mjs, cli/src/desktop.rs and distribution/target.rs, and with gpui-shell's lookup in host/installed.rs. Linux and Windows layouts are unchanged. There is no protocol or epoch change.

P3 follow-ups

  1. Existing macOS preview installs cannot self-update to the first release with this layout. maka upgrade and the deployment policy worker validate the new package with the installed binary's rules. Before this PR, those rules require bin/maka-desktop-shell and accept only bin/app/*. The new package is therefore refused with "native package contains an invalid, duplicate, or oversized member". No layout satisfies both versions, and the PR body discloses the break. Still, the error does not say why it failed, so the release notes should tell macOS preview users to reinstall with npm install -g @maka-agent/cli@rust-preview.
  2. The development bundle can go stale. The bundle is a copy. After a Cargo-only cargo build -p maka-desktop-shell, maka desktop on macOS keeps running the old shell until just build runs again. just build also removes target/*/app, so running the bare shell with no arguments no longer finds an app. Both behaviours are documented in the README.
  3. No CI exercised these changes. ci.yml runs only for PRs into main. The only check on this head was the Website validate job, and publication was skipped. The changed Rust tests (distribution tests, tests/integration/desktop.rs) have not been executed by CI or by us. We read them by hand and saw nothing that would fail. Please run cargo nextest run -p maka-cli and a manually dispatched npm-publication.yml (darwin build/pack/install/--version) on rust-preview.
  4. Signing and Gatekeeper are untested. The bundle carries only the linker's ad-hoc signature on the executable, and nothing seals the bundle's resources. That works when maka desktop spawns the shell, and the author confirmed it on arm64. codesign --verify, Gatekeeper on a quarantined copy, notarization, Dock identity and icon presentation still need a check on macOS.
  5. (Predates this PR, for information.) On Linux and Windows, gpui-shell checks <entry>/Resources/app before bin/app, but cached() walks only bin/app. An unrecorded Resources/app/ in a cache entry would therefore load without being detected. The cache directory is private, and the macOS layout added here is not affected.

Validation (Linux)

  • The 13 tests in the four related Node build, packaging, release and launcher test files passed with Node 24 and the pinned npm 11.19.0. With a newer local npm, pack-cli.test.mjs fails, but it fails the same way at the merge base.
  • We called the real stageDesktopBundle on the current 69 app files and the product logo. Every file stayed byte-identical. The plist parsed, and its identity, name and version match gpui-shell.json and gpui-shell's own bundler keys. The PNG decodes as 1024×1024, the ICNS payload is a valid ic10 entry, and the shell is 0755. A failed staging run (source symlink) kept the previous bundle and cleaned up its temporary directories. This probe used stand-in shell bytes, so it checks the packaging structure, not a real macOS binary.
  • The license check, JavaScript and Rust formatting, and git diff --check passed.
  • A Rust test build was attempted but did not reach the test bodies within a 30-minute budget. The default build lacked host X11/pkg-config tooling, and a --no-default-features build then timed out while compiling. Native macOS launch was not tested.

} else {
"bin/maka-desktop-shell"
match self {
Self::DarwinArm64 | Self::DarwinX64 => "bin/Maka.app/Contents/MacOS/maka-desktop-shell",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: every pre-PR darwin binary requires bin/maka-desktop-shell and accepts only bin/app/*, so maka upgrade and the policy worker's distribution::fetch will refuse the first package with this layout ("invalid, duplicate, or oversized member"). No layout can satisfy both, and the break is disclosed, but please say in the release notes that macOS preview users need to reinstall through npm.

await stageDesktopApp(repositoryRoot, join(dirname(binary), 'app'));
const directory = dirname(binary);
if (triple.includes('-apple-darwin')) {
await stageDesktopBundle(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: the bundle is a copy, so after cargo build -p maka-desktop-shell alone, maka desktop on macOS keeps running the old shell until just build runs again. The README documents this; noting it because before this PR the shell beside maka was the cargo output itself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants