Skip to content

feat(bootstrap): add mas package manager#10397

Merged
jdx merged 8 commits into
mainfrom
codex/add-mas-bootstrap-packages
Jun 13, 2026
Merged

feat(bootstrap): add mas package manager#10397
jdx merged 8 commits into
mainfrom
codex/add-mas-bootstrap-packages

Conversation

@jdx

@jdx jdx commented Jun 13, 2026

Copy link
Copy Markdown
Owner

Summary

  • add mas: as a first-class [bootstrap.packages] manager for Mac App Store apps
  • keep mas macOS-only and unavailable unless the mas CLI is already on PATH
  • document usage, caveats, and add e2e/unit coverage

Validation

  • cargo test system::packages::mas
  • cargo test system::tests::test_parse_use_spec
  • mise run test:e2e e2e/cli/test_system_use e2e/cli/test_system_status

Note

Medium Risk
New macOS-only path that runs external App Store installs (Apple account, purchases, and mas failures); behavior matches other bootstrap managers but real installs are environment-dependent.

Overview
Adds mas as a [bootstrap.packages] manager so Mac App Store apps can be declared as mas:<ADAM_ID> (numeric IDs only, e.g. mas:497799835 for Xcode), with install, status, use, and upgrade wired through the existing bootstrap packages flow.

A new MasManager shells out to the mas CLI (list/install/upgrade), is available only on macOS when mas is on PATH, and does not support version pins (bundle IDs and @version pins are rejected). Config parsing treats mas like Homebrew for @ handling and warns/skips invalid IDs when loading config.

CLI --manager choices, 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

    • Added macOS App Store (mas) as a supported bootstrap package manager. Declare mas:<ADAM_ID> entries; install/use/upgrade supported. Upgrades run mas upgrade for installed apps; pinned mas entries are skipped with a warning when pins can’t be applied.
  • Documentation

    • CLI help, man page, and docs updated with mas examples, ID-discovery tips, macOS/PATH prerequisites, and note that mas does not support version pins.
  • Tests

    • E2E tests extended to cover mas in status, use, install, and upgrade scenarios.

@coderabbitai

coderabbitai Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds 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.

Changes

Mac App Store Package Manager Support

Layer / File(s) Summary
MasManager implementation and package manager integration
src/system/packages/mas.rs, src/system/packages/mod.rs
New MasManager implements SystemPackageManager; parses mas list JSON/text, computes package statuses, runs mas install/mas upgrade, validates ADAM IDs, includes unit tests, and is registered in manager factory.
Opaque package spec parsing and validation
src/system/mod.rs
parse_use_spec treats mas as opaque (no @ splitting). Adds is_opaque_package_manager/normalize_use_spec_package_name/validate_package_name` enforcing numeric ADAM IDs; config-derived invalid entries are warned+skipped and CLI specs error.
CLI flags, help, usage, and completions
src/cli/system/install.rs, src/cli/system/upgrade.rs, src/cli/system/use.rs, mise.usage.kdl, xtasks/fig/src/mise.ts, man/man1/mise.1, docs/cli/bootstrap/packages/*
--manager value parsers and long-help/examples for install, upgrade, and use now include mas. Usage strings, generated usage spec, Fig completion lists, and man page entries are updated.
Documentation and examples for mas
docs/bootstrap/packages/mas.md, docs/bootstrap/packages/index.md
New mas.md documents experimental mas usage, ADAM ID requirements, platform/PATH caveats, command mappings, and upgrade behavior; index includes mas examples and macOS-specific semantics.
E2E test coverage for mas functionality
e2e/cli/test_system_status, e2e/cli/test_system_use
Tests verify mise bootstrap packages status includes mas, --manager mas --dry-run behavior conditioned on Darwin/mas on PATH, and use dry-run normalization/rejection of mas: inputs.

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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • jdx/mise#10346: Introduces opaque package-manager parsing behaviors that this PR extends to mas.

Poem

🐰 I hop to the App Store with cheer,
mas: IDs now draw near,
From list to install and update,
CLI, docs, tests neatly made,
Mise tends seeds of macOS gear.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title 'feat(bootstrap): add mas package manager' accurately and concisely describes the main change: adding support for the macOS 'mas' (Mac App Store) package manager to the bootstrap packages system.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

Comment thread src/system/packages/mas.rs
@greptile-apps

greptile-apps Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds mas (Mac App Store CLI) as a first-class bootstrap package manager, accepting only numeric ADAM IDs (e.g. mas:497799835). It is macOS-only and skipped gracefully when the mas binary is not on PATH.

  • New MasManager in src/system/packages/mas.rs implements install/upgrade/status by running mas install, mas upgrade, and mas list --json (with text fallback). ADAM ID validation is enforced at both parse-time (parse_use_spec) and config-load-time (validate_package_name), rejecting bundle IDs and version pins before any subprocess is invoked.
  • parse_use_spec treats mas as an opaque manager (like brew/brew-cask) and strips a trailing @latest suffix, so mas:497799835@latest is normalized to mas:497799835 consistently with the use UX.
  • CLI flags, man page, usage KDL, Fig completions, and docs are all updated; e2e tests cover status, use (valid/invalid specs), and conditional install dry-run.

Confidence Score: 5/5

Safe 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 mas update subcommand, silent empty-list result, bundle IDs silently accepted for install) are addressed in this revision. The driver in driver.rs (lines 129–131) has an explicit targets.is_empty() → continue guard, so mas upgrade can never be called with an empty args list. Pinned-version filtering is handled by the driver for both install and upgrade before the manager is invoked. The ADAM ID validation is applied consistently across both CLI-explicit and config-loaded paths. No correctness issues found.

No files require special attention.

Important Files Changed

Filename Overview
src/system/packages/mas.rs New MasManager: install/upgrade/status via mas CLI; JSON+text list fallback; ADAM ID validation; well-structured, previous-thread issues resolved
src/system/mod.rs Adds mas to parse_use_spec (opaque manager, @latest stripping, ADAM ID validation) and config loading; validate_package_name correctly warns-and-skips in config loading, bails in CLI specs
src/system/packages/mod.rs Registers MasManager in all_managers(); straightforward addition
e2e/cli/test_system_status Adds mas entries to status test; correctly gates install --dry-run on Darwin+mas PATH availability
e2e/cli/test_system_use Adds mas spec validation tests: numeric ADAM ID accepted, @latest stripped, bundle IDs and version pins rejected
docs/bootstrap/packages/mas.md New docs page; correctly states numeric-only IDs, macOS+PATH requirement, and sign-in caveats

Reviews (7): Last reviewed commit: "chore: merge main into mas bootstrap bra..." | Re-trigger Greptile

Comment thread src/system/packages/mas.rs
Comment thread src/system/packages/mas.rs Outdated

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
src/system/packages/mas.rs (1)

208-228: 💤 Low value

Install 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 sets stdin to 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

📥 Commits

Reviewing files that changed from the base of the PR and between db6bd8f and 95e2fe3.

📒 Files selected for processing (13)
  • docs/bootstrap/packages/index.md
  • docs/bootstrap/packages/mas.md
  • docs/cli/bootstrap/packages/install.md
  • docs/cli/bootstrap/packages/upgrade.md
  • docs/cli/bootstrap/packages/use.md
  • e2e/cli/test_system_status
  • e2e/cli/test_system_use
  • src/cli/system/install.rs
  • src/cli/system/upgrade.rs
  • src/cli/system/use.rs
  • src/system/mod.rs
  • src/system/packages/mas.rs
  • src/system/packages/mod.rs

@github-actions

github-actions Bot commented Jun 13, 2026

Copy link
Copy Markdown

Hyperfine Performance

mise x -- echo

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%

Comment thread src/system/mod.rs
Comment thread src/system/packages/mas.rs Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ 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.

Comment thread src/system/packages/mas.rs Outdated
@jdx jdx merged commit 4085a1d into main Jun 13, 2026
35 checks passed
@jdx jdx deleted the codex/add-mas-bootstrap-packages branch June 13, 2026 15:48
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.

1 participant