Skip to content

fix(brew): support cask command wrappers and run steps - #11472

Merged
jdx merged 3 commits into
mainfrom
agent/brew-cask-command-wrappers
Jul 29, 2026
Merged

jdx merged 3 commits into
mainfrom
agent/brew-cask-command-wrappers

Conversation

@jdx

@jdx jdx commented Jul 29, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • support Homebrew cask command_wrapper artifacts using executable/args/env or literal content
  • execute structured run lifecycle steps with serialized command bases, template expansion, guards, environment variables, and mise's sudo policy
  • track generated wrapper links in cask receipts and reconcile wrappers introduced for an already-installed cask
  • document the expanded cask artifact and lifecycle-step coverage

Context

Homebrew recently introduced command_wrapper artifacts and migrated cask flight commands to structured run steps. mise parsed cask metadata before its installed-state check and intentionally rejected unknown artifacts and step types, so affected casks began failing even when they were already installed.

This addresses the regression reported in discussion #11462, including the Firefox command_wrapper and OrbStack postflight_steps examples.

Generated wrappers use the existing transactional binary-link and receipt paths. Structured commands support the command bases and fields currently emitted by Homebrew while unsupported lifecycle operations continue to fail explicitly.

Validation

  • mise run lint-fix
  • cargo test --bin mise system::packages::brew::cask::tests -- --test-threads=1 (94 passed)
  • git diff --check

AI-assisted — Tool: Codex; model: OpenAI/GPT-5; version: unavailable.


Note

Medium Risk
Touches cask install/linking and can run arbitrary commands (including sudo) from cask metadata, but behavior is scoped to Homebrew’s serialized formats with explicit unsupported-feature errors.

Overview
Fixes regressions where casks such as Firefox (command_wrapper) and OrbStack (structured postflight_steps run) failed because mise rejected newer Homebrew artifact metadata.

command_wrapper artifacts are parsed, staged under .homebrew-command-wrappers (literal content or generated bash from executable / args / env with template expansion), symlinked into the prefix like binaries, and included in install verification and receipt reconciliation when wrappers are added to an already-installed cask.

Structured lifecycle run steps execute serialized commands with staged_path, appdir, homebrew_prefix, and absolute bases; expand Homebrew-style templates; honor platform/path guards; and use mise’s normal or sudo execution path. Preflight structured steps now receive appdir and run before app install, matching Homebrew’s phase ordering.

Docs in brew.md describe command-wrapper and run step support.

Reviewed by Cursor Bugbot for commit 232f5d8. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • New Features

    • Added support for Homebrew cask command wrappers, including installation, activation, version tracking, and dry-run handling.
    • Added structured command execution steps with environment settings, arguments, conditional guards, and optional elevated permissions.
    • Expanded path and template handling for cask lifecycle actions.
  • Bug Fixes

    • Improved installed-version reconciliation when command wrappers are introduced to existing installations.
  • Documentation

    • Clarified supported cask artifact types and lifecycle behavior, including command wrappers and structured execution steps.

@coderabbitai

coderabbitai Bot commented Jul 29, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Homebrew cask lifecycle

Layer / File(s) Summary
Artifact and flight-step contracts
src/system/packages/brew/cask.rs
Adds command-wrapper and structured run step models, guards, contextual path bases, strict metadata parsing, and supported-artifact validation.
Wrapper staging and installed-state integration
src/system/packages/brew/cask.rs
Generates executable wrappers, stages and links them, includes them in dry-runs and target tracking, reconciles receipts, and adds wrapper tests.
Context-aware run-step execution
src/system/packages/brew/cask.rs, docs/bootstrap/packages/brew.md
Resolves paths and templates, evaluates guards, executes direct or sudo commands, and documents the expanded lifecycle behavior.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CaskMetadata
  participant execute_flight_steps
  participant CmdLineRunner
  participant sudo_run
  CaskMetadata->>execute_flight_steps: structured run step
  execute_flight_steps->>execute_flight_steps: evaluate guards and expand templates
  execute_flight_steps->>CmdLineRunner: execute expanded argv
  execute_flight_steps->>sudo_run: execute with sudo when configured
Loading

Possibly related PRs

Suggested reviewers: casparbreloh, roele

Poem

I’m a rabbit with wrappers to stage,
And run steps that leap from the page.
Guards check the way,
Sudo joins the play,
While cask scripts hop into place.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Title check ✅ Passed The title clearly summarizes the main change: Homebrew cask command-wrapper support and new run steps.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Comment thread src/system/packages/brew/cask.rs Resolved
@greptile-apps

greptile-apps Bot commented Jul 29, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR expands Homebrew cask compatibility.

  • Adds generated command_wrapper artifact parsing, staging, linking, receipt reconciliation, and installed-state checks.
  • Executes structured lifecycle run steps with command bases, template expansion, guards, environment variables, and sudo policy.
  • Preserves runtime variables and staged-path placeholders in literal wrapper content while expanding Homebrew prefix and application-directory variables.
  • Documents the expanded artifact and lifecycle-step support.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains; the prior literal-wrapper issue is resolved because $HOME and {{staged_path}} are preserved in literal content and the behavior is covered by a focused regression test.

Important Files Changed

Filename Overview
src/system/packages/brew/cask.rs Adds command-wrapper and structured-run support; the latest implementation and regression test establish that the previously reported literal-content expansion defect is fixed.
docs/bootstrap/packages/brew.md Documents command-wrapper artifacts and structured lifecycle run operations consistently with the implementation.

Reviews (3): Last reviewed commit: "fix(brew): harden cask lifecycle metadat..." | Re-trigger Greptile

@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 3 potential issues.

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 ff0d21b. Configure here.

Comment thread src/system/packages/brew/cask.rs Resolved
Comment thread src/system/packages/brew/cask.rs Resolved
Comment thread src/system/packages/brew/cask.rs Resolved

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

Actionable comments posted: 1

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

1949-1982: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Prefer failing fast over panicking for wrapper shape/env validation.

Two small hardening points:

  • Line 1981: the content/executable invariant is only enforced by the parser, not the type, so unreachable! turns an internal misuse into a panic mid-install. bail! keeps it a normal error.
  • Line 1963: is_shell_env_name rejects bad env names only after the archive is downloaded and extracted; validating in parse_command_wrapper_artifact surfaces bad metadata before any work is done.
♻️ Proposed change for the unreachable arm
-        _ => unreachable!("command wrapper shape is validated while parsing"),
+        _ => bail!(
+            "brew-cask: command_wrapper '{}' must set exactly one of content or executable",
+            wrapper.name
+        ),
🤖 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/brew/cask.rs` around lines 1949 - 1982, Replace the
unreachable! fallback in the command-wrapper content/executable match with bail!
so invalid wrapper shapes return a normal installation error instead of
panicking. Also move the is_shell_env_name validation from the
executable-building branch into parse_command_wrapper_artifact, ensuring every
wrapper environment key is validated before archive download or extraction while
preserving the existing invalid-name error.
🤖 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.

Inline comments:
In `@src/system/packages/brew/cask.rs`:
- Around line 2729-2753: Update the run-command path validation after the base
mapping so FlightPathBase::Absolute also rejects relative paths containing
separators or parent-directory components, while continuing to allow bare names
for PATH resolution and absolute paths. Ensure invalid baseless paths fail
during parsing with the existing invalid run-command path error.

---

Nitpick comments:
In `@src/system/packages/brew/cask.rs`:
- Around line 1949-1982: Replace the unreachable! fallback in the
command-wrapper content/executable match with bail! so invalid wrapper shapes
return a normal installation error instead of panicking. Also move the
is_shell_env_name validation from the executable-building branch into
parse_command_wrapper_artifact, ensuring every wrapper environment key is
validated before archive download or extraction while preserving the existing
invalid-name error.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: d9be23f0-1fbf-482c-912d-e44f85e16876

📥 Commits

Reviewing files that changed from the base of the PR and between e237f7b and ff0d21b.

📒 Files selected for processing (2)
  • docs/bootstrap/packages/brew.md
  • src/system/packages/brew/cask.rs

Comment thread src/system/packages/brew/cask.rs Resolved
@github-actions

github-actions Bot commented Jul 29, 2026 •

Copy link
Copy Markdown
Contributor

Instruction counts

benchmark trend instructions Δ wall (min) Δ
env ▁▁▂▃▃▄▄▃▄▃▃▃▄▆▇█▇█▇▆▆ 84,737,744 → 84,751,830 +0.02% 19.20 → 22.07ms +14.95%
hook-env █▅▁▅▃▁▅▆▄▆▇▃▆▆▇▇▇▇▃▄▆ 87,235,341 → 87,283,515 +0.06% 19.81 → 21.91ms +10.59%
ls ▁▂▄▆▆▅▆▇▇▅▆▆█▇██▇▇▆▅▇ 76,668,275 → 76,742,994 +0.10% 16.05 → 19.23ms +19.78%
registry ▁▁▄▄▄▄▅▅▄▄▄▄▄▅▅▅▅▅▅▅█ 50,193,293 → 50,274,490 +0.16% 10.78 → 13.61ms +26.26%
startup ▁▁▇▇▇▆▇▇▇▇▇▇▇▇▇▇▇▇▇▇█ 16,065,947 → 16,091,037 +0.16% 8.18 → 9.37ms +14.63%

No instruction-count regression above 1%.

Only instruction counts gate. Wall clock is shown for context — on identical hardware it moves 4-20% run to run.

Measured by tak — instruction-counted CLI benchmarks, stored in this repository's git notes.

232f5d85e8f6 vs e237f7b1e8eb · measured on the runner, not pushed to the history.

@jdx
jdx enabled auto-merge (squash) July 29, 2026 17:07
@jdx
jdx merged commit 12c933f into main Jul 29, 2026
37 checks passed
@jdx
jdx deleted the agent/brew-cask-command-wrappers branch July 29, 2026 17:20
This was referenced Jul 29, 2026
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