feat(bootstrap): add mas package manager#10397
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds macOS App Store ("mas") bootstrap manager: new MasManager implementation, spec validation for numeric ADAM IDs, CLI flags/examples for --manager mas, documentation pages, usage/completions, and e2e/unit tests. ChangesMac App Store Package Manager Support
Sequence Diagram(s)sequenceDiagram
participant User
participant MiseCLI
participant MasManager
participant masCLI
participant AppStore
User->>MiseCLI: run 'mise bootstrap packages upgrade --manager mas'
MiseCLI->>MasManager: call installed()/upgrade(requests)
MasManager->>masCLI: spawn 'mas list --json' or 'mas install/upgrade <id>'
masCLI->>AppStore: query/update app by ADAM id
AppStore-->>masCLI: respond with metadata / update result
masCLI-->>MasManager: stdout/stderr + exit code
MasManager-->>MiseCLI: return PackageStatus results
MiseCLI-->>User: print status / errors
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
Greptile SummaryThis PR adds
Confidence Score: 5/5Safe to merge — the driver framework already guards against empty package lists and filters pinned packages before calling the manager, the three issues flagged in earlier review rounds have all been resolved, and the new code is well-tested. All previously flagged issues (wrong No files require special attention. Important Files Changed
Reviews (7): Last reviewed commit: "chore: merge main into mas bootstrap bra..." | Re-trigger Greptile |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/system/packages/mas.rs (1)
208-228: 💤 Low valueInstall error message could include stderr for better debugging.
Currently line 225 reports
"mas install failed"without context. Since you're not capturing stderr (line 221 setsstdinto null but leaves stderr unset), the user sees raw output, but the error message could be more helpful.Optional: capture and include stderr in error
debug!("$ mas {}", args.join(" ")); - let status = tokio::process::Command::new("mas") + let output = tokio::process::Command::new("mas") .args(&args) .stdin(Stdio::null()) - .status() + .output() .await?; - if !status.success() { - bail!("mas install failed"); + if !output.status.success() { + let stderr = String::from_utf8_lossy(&output.stderr); + bail!("mas install failed: {}", stderr.trim()); }(Same pattern applies to
upgrade()at lines 238-245.)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/system/packages/mas.rs` around lines 208 - 228, The error messages in install() (and similarly in upgrade()) are unhelpful because they only bail with "mas install failed" after calling Command::status() without capturing stderr; change both to run Command::output() (keep stdin(Stdio::null())), check output.status.success(), and if false include the captured stderr (convert from bytes to String lossily and trim) in the bail! message (e.g., bail!("mas install failed: {}", stderr_str)). This ensures install() and upgrade() produce error messages containing the process stderr for easier debugging.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@src/system/packages/mas.rs`:
- Around line 208-228: The error messages in install() (and similarly in
upgrade()) are unhelpful because they only bail with "mas install failed" after
calling Command::status() without capturing stderr; change both to run
Command::output() (keep stdin(Stdio::null())), check output.status.success(),
and if false include the captured stderr (convert from bytes to String lossily
and trim) in the bail! message (e.g., bail!("mas install failed: {}",
stderr_str)). This ensures install() and upgrade() produce error messages
containing the process stderr for easier debugging.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 7373c5f2-45b6-4d63-b678-a26bced92ffb
📒 Files selected for processing (13)
docs/bootstrap/packages/index.mddocs/bootstrap/packages/mas.mddocs/cli/bootstrap/packages/install.mddocs/cli/bootstrap/packages/upgrade.mddocs/cli/bootstrap/packages/use.mde2e/cli/test_system_statuse2e/cli/test_system_usesrc/cli/system/install.rssrc/cli/system/upgrade.rssrc/cli/system/use.rssrc/system/mod.rssrc/system/packages/mas.rssrc/system/packages/mod.rs
Hyperfine Performance
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.6.6 x -- echo |
19.4 ± 0.9 | 17.5 | 23.4 | 1.00 |
mise x -- echo |
20.3 ± 1.7 | 18.3 | 47.3 | 1.05 ± 0.10 |
mise env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.6.6 env |
19.2 ± 1.0 | 17.6 | 24.1 | 1.00 |
mise env |
19.5 ± 0.9 | 17.8 | 23.9 | 1.02 ± 0.07 |
mise hook-env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.6.6 hook-env |
19.9 ± 0.9 | 18.2 | 24.5 | 1.00 |
mise hook-env |
20.5 ± 0.9 | 18.5 | 24.4 | 1.03 ± 0.06 |
mise ls
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.6.6 ls |
16.3 ± 0.8 | 14.6 | 19.6 | 1.00 |
mise ls |
16.8 ± 0.9 | 15.3 | 21.8 | 1.03 ± 0.07 |
xtasks/test/perf
| Command | mise-2026.6.6 | mise | Variance |
|---|---|---|---|
| install (cached) | 134ms | 134ms | +0% |
| ls (cached) | 58ms | 60ms | -3% |
| bin-paths (cached) | 64ms | 63ms | +1% |
| task-ls (cached) | 125ms | 127ms | -1% |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit ce67d05. Configure here.

Summary
mas:as a first-class[bootstrap.packages]manager for Mac App Store appsmasmacOS-only and unavailable unless themasCLI is already on PATHValidation
cargo test system::packages::mascargo test system::tests::test_parse_use_specmise run test:e2e e2e/cli/test_system_use e2e/cli/test_system_statusNote
Medium Risk
New macOS-only path that runs external App Store installs (Apple account, purchases, and
masfailures); behavior matches other bootstrap managers but real installs are environment-dependent.Overview
Adds
masas a[bootstrap.packages]manager so Mac App Store apps can be declared asmas:<ADAM_ID>(numeric IDs only, e.g.mas:497799835for Xcode), with install, status, use, and upgrade wired through the existing bootstrap packages flow.A new
MasManagershells out to themasCLI (list/install/upgrade), is available only on macOS whenmasis on PATH, and does not support version pins (bundle IDs and@versionpins are rejected). Config parsing treatsmaslike Homebrew for@handling and warns/skips invalid IDs when loading config.CLI
--managerchoices, usage/man/docs, and e2e coverage for status/use/install dry-run are updated accordingly.Reviewed by Cursor Bugbot for commit f1fdeb4. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by CodeRabbit
New Features
Documentation
Tests