Skip to content

fix: launch native package bins directly - #1141

Merged
jdx merged 4 commits into
aubepkg:mainfrom
benjaminwestern:fix/native-package-bins
Jul 27, 2026
Merged

jdx merged 4 commits into
aubepkg:mainfrom
benjaminwestern:fix/native-package-bins

Conversation

@benjaminwestern

@benjaminwestern benjaminwestern commented Jul 27, 2026 •

Copy link
Copy Markdown
Contributor

I do not normally write Rust. This change is largely the work of GPT-5.6 Sol on XHigh, with multiple rounds of my poking and review to align it with the existing architectural patterns in mise and aube.

Context

I encountered this issue while using aube with OpenCode on my work Windows machine. That machine cannot push to public Git repositories, so I used my personal macOS device to develop and test the fix. The original Windows failure motivated the Windows-specific implementation and tests, but those gated tests were not run locally on macOS.

Summary

Package bins can point directly to compiled executables, but generated wrappers may pass those executables to Node. This change resolves aube-generated wrappers and symlinks before non-shell execution, then launches recognised native targets directly.

This applies to non-shell aube exec, the local-bin fallback from aube run, and non-shell aube dlx. Existing JavaScript and interpreter-backed behaviour remains unchanged.

What changed

  • The linker now provides a bounded decoder for aube-generated POSIX and cmd wrappers. It resolves their target and preserves NODE_PATH.
  • Direct execution recognises ELF, Mach-O, FAT, FAT64, and validated PE executables. Windows command suffixes are also recognised, with shebangs taking precedence.
  • dlx now uses the same command construction as exec and run.
  • Native launches preserve the switched runtime path, wrapper environment, arguments, and Unix argv[0].
  • Unit and BATS coverage now exercises native exec, run, and scratch dlx launches.

Deliberately out of scope

  • This change does not alter generated shim formats or make shims native-aware.
  • Shell-routed commands, lifecycle scripts, global bins, and direct .bin invocation continue through their installed wrappers.
  • I considered migrating global unlink parsing to the new decoder, but did not include it because global unlink is unrelated to direct execution and would increase the regression surface.
  • I considered re-exporting the decoder from the linker root, but kept it within the sys module because it currently has one internal consumer.
  • I considered applying the switched runtime PATH to every non-shell command, but retained the established direct-Node behaviour and limited the change to wrapper and native launch paths.

Validation

  • cargo test passed.
  • cargo clippy --all-targets -- -D warnings passed.
  • cargo fmt --check passed.
  • mise run test:bats test/exec.bats passed.
  • mise run test:bats test/dlx.bats passed.

Windows-specific tests are gated by cfg(windows) and were not run locally on the macOS development host.

Summary by CodeRabbit

  • New Features
    • Native package binaries can now launch directly via non-shell aube exec, aube run, and aube dlx.
  • Bug Fixes
    • Improved wrapper/shim resolution, including safer handling to avoid unwrapping JavaScript shims when node args aren’t needed.
    • More robust Windows .cmd shim detection and resolution (including dotted names), with stricter rejection of malformed/oversized wrappers.
  • Documentation
    • Clarified how local/native targets are launched versus wrapper-based execution, including Unix executable requirements.
  • Tests
    • Added end-to-end coverage for direct native-bin launching, plus expanded wrapper-parsing tests (including aube dlx on supported Unix-like systems).

@coderabbitai

coderabbitai Bot commented Jul 27, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds typed POSIX and Windows bin-shim decoding, centralizes command construction, detects native executables for direct launching, and updates exec, run, and dlx tests and documentation.

Changes

Native bin execution

Layer / File(s) Summary
Shim metadata decoding
crates/aube-linker/src/sys.rs
Adds ResolvedBinShim and resolve_bin_shim, validating POSIX and CMD wrappers while extracting targets and NODE_PATH values.
Command construction and target selection
crates/aube/src/commands/exec.rs, crates/aube/src/commands/dlx.rs
Shares command construction across execution paths, detects native binaries, preserves Node-backed shims when needed, and prefers Windows .cmd siblings.
Behavioral coverage and documentation
crates/aube/src/commands/exec.rs, docs/package-manager/scripts.md, test/dlx.bats, test/exec.bats
Adds unit, integration, Bats, and documentation coverage for native execution and shim resolution.

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

Sequence Diagram(s)

sequenceDiagram
  participant ExecOrDlx
  participant build_bin_command
  participant resolve_bin_target
  participant NativeExecutable
  participant NodeShim
  ExecOrDlx->>build_bin_command: pass bin path and arguments
  build_bin_command->>resolve_bin_target: resolve target metadata
  resolve_bin_target->>NativeExecutable: detect native target
  resolve_bin_target->>NodeShim: retain wrapper when required
  NativeExecutable-->>build_bin_command: direct executable
  NodeShim-->>build_bin_command: Node-backed command
  build_bin_command-->>ExecOrDlx: run configured command
Loading

Possibly related PRs

  • jdx/aube#1067: Modifies the same exec and dlx non-shell execution wiring.

Poem

A rabbit found a wrapper bright,
With paths tucked in, both day and night.
Native hops straight through the gate,
Node shims wait when args dictate.
Exec and dlx now share the trail—
Tiny paws make launchers sail.

🚥 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 is concise and accurately summarizes the main change: launching native package bins directly.

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.

@greptile-apps

greptile-apps Bot commented Jul 27, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR launches recognized native package binaries directly while retaining wrapper behavior for JavaScript and interpreter-backed targets.

  • Adds bounded decoding of aube-generated POSIX and Windows command wrappers, including preserved NODE_PATH.
  • Shares command construction across non-shell exec, local-bin run, and dlx execution.
  • Detects ELF, Mach-O, FAT, FAT64, and validated PE targets and preserves runtime environment, arguments, and Unix argv[0].
  • Adds unit and BATS coverage and documents the native-launch behavior.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
crates/aube-linker/src/sys.rs Adds bounded, format-aware decoding of generated bin wrappers and reconstructs wrapper targets and NODE_PATH.
crates/aube/src/commands/exec.rs Resolves wrapper or symlink targets, detects native executable formats, and constructs direct native launches for non-shell execution.
crates/aube/src/commands/dlx.rs Reuses the shared bin-command builder for non-shell scratch-package execution.
docs/package-manager/scripts.md Documents which command paths directly launch native targets and which continue through wrappers.
test/exec.bats Adds Unix integration coverage for native execution through both exec and run fallback.
test/dlx.bats Adds Unix integration coverage for launching a native binary from a scratch dlx installation.

Reviews (4): Last reviewed commit: "test(linker): use native separators in s..." | Re-trigger Greptile

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/aube/src/commands/exec.rs (1)

799-823: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

This Windows fixture won't parse — the @SET PATHEXT line is missing.

parse_cmd_shim_target requires the line immediately after ) ELSE ( to be exactly @set PATHEXT=%PATHEXT:;.JS;=;% (crates/aube-linker/src/sys.rs Line 893). The fixture here jumps straight to the node ... fallback, so resolve_bin_shim returns None and all three assertions below will fail. Windows CI hasn't exercised this yet per the PR notes.

🐛 Proposed fix for the fixture
               `@IF` EXIST \"%~dp0\\node.exe\" (\r\n\
               \x20 \"%~dp0\\node.exe\" \"%~dp0\\pkg\\bin.js\" %*\r\n\
               ) ELSE (\r\n\
+              \x20 `@SET` PATHEXT=%PATHEXT:;.JS;=;%\r\n\
               \x20 node \"%~dp0\\pkg\\bin.js\" %*\r\n\
               )\r\n",
#!/bin/bash
# Confirm the generated cmd shim shape the parser expects
ast-grep run --pattern 'fn generate_cmd_shim($$$) { $$$ }' --lang rust crates/aube-linker/src/sys.rs
🤖 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 `@crates/aube/src/commands/exec.rs` around lines 799 - 823, Update the Windows
cmd shim fixture written in the resolve_bin_target test to include the exact
`@SET PATHEXT=%PATHEXT:;.JS;=;%` line immediately after `) ELSE (` and before
the fallback node command. Keep the existing assertions and fixture behavior
unchanged.
🧹 Nitpick comments (1)
crates/aube-linker/src/sys.rs (1)

931-944: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Reject POSIX-style decoding for Windows .sh shims.

parse_posix_shim_target accepts any file containing the marker, but Windows-generated extensionless shims are produced by generate_sh_shim and can carry NODE_PATH entries joined with ;. Splitting those lines on POSIX : produces a bogus single entry. Gate the POSIX branch with an additional marker/shape check or validate that resolved entries contain no ;.

🤖 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 `@crates/aube-linker/src/sys.rs` around lines 931 - 944, Update
resolve_shim_node_path so the BinShimStyle::Posix path rejects Windows-generated
extensionless shims before splitting NODE_PATH on ':'. Add a marker/shape
validation that excludes values containing ';' (or otherwise confirms POSIX
format), while preserving valid POSIX resolution and the existing Cmd handling.
🤖 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.

Outside diff comments:
In `@crates/aube/src/commands/exec.rs`:
- Around line 799-823: Update the Windows cmd shim fixture written in the
resolve_bin_target test to include the exact `@SET PATHEXT=%PATHEXT:;.JS;=;%`
line immediately after `) ELSE (` and before the fallback node command. Keep the
existing assertions and fixture behavior unchanged.

---

Nitpick comments:
In `@crates/aube-linker/src/sys.rs`:
- Around line 931-944: Update resolve_shim_node_path so the BinShimStyle::Posix
path rejects Windows-generated extensionless shims before splitting NODE_PATH on
':'. Add a marker/shape validation that excludes values containing ';' (or
otherwise confirms POSIX format), while preserving valid POSIX resolution and
the existing Cmd handling.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro Plus

Run ID: 4f8244f6-107c-49d5-9260-b3072da9e994

📥 Commits

Reviewing files that changed from the base of the PR and between f354e33 and 818698c.

📒 Files selected for processing (6)
  • crates/aube-linker/src/sys.rs
  • crates/aube/src/commands/dlx.rs
  • crates/aube/src/commands/exec.rs
  • docs/package-manager/scripts.md
  • test/dlx.bats
  • test/exec.bats

@benjaminwestern
benjaminwestern marked this pull request as ready for review July 27, 2026 05:38
@jdx
jdx merged commit a96bcbd into aubepkg:main Jul 27, 2026
18 checks passed
@cursor cursor Bot mentioned this pull request Jul 27, 2026
@benjaminwestern
benjaminwestern deleted the fix/native-package-bins branch July 27, 2026 22:05
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.

2 participants