Skip to content

cli: classify the subcommand past --cwd/--env-file values - #36644

Open
robobun wants to merge 9 commits into
mainfrom
farm/07fabac3/which-global-flag-value
Open

cli: classify the subcommand past --cwd/--env-file values#36644
robobun wants to merge 9 commits into
mainfrom
farm/07fabac3/which-global-flag-value

Conversation

@robobun

@robobun robobun commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

What

Command::which() scans argv for the first non-dash token to pick the subcommand. It treats every dash-prefixed token as valueless, so the value of a global flag is read as the subcommand name:

$ bun --cwd ./dir test foo.test.ts
error: Script not found "test"

$ bun --env-file .env run app.ts
Usage: bun run [flags] <file or script>   # prints help instead of running

$ bun --cwd sub init -y
error: Script not found "init"

In each case which() lands on the flag's value (./dir, .env, sub), matches no keyword, and dispatches AutoCommand.

Why the obvious patch is wrong

Having which() simply step past the value of --cwd/--env-file/--config was tried in #34983 and reverted (ff4255a): once the subcommand is classified correctly, several handlers that re-read raw bun::argv() at a hard-coded offset see the wrong token. For example bun --env-file .env install would reach InstallCommand, whose parser does not declare --env-file, so .env and install become positionals and it behaves like bun add .env install. bun info, bun init, bun create, bun x, bun upgrade and bun pm trust have the same shape (argv().iter().skip(2) / &argv[2..] / &args[1..]).

Fix

  • which() now steps past the value of the required-value BASE_PARAMS_ flags (--cwd, --env-file) and records the argv index of the keyword it lands on in SUBCOMMAND_ARGV_INDEX.
  • Every handler that previously sliced raw argv at a fixed offset reads subcommand_argv_index() instead (exec_init, exec_bunx, bun_info, bun_create, exec_install_completions, reserved_command, upgrade_command, package_manager_command). For the default bun <cmd> ... shape the index is 1, so behavior is unchanged.
  • CreateOptions::parse strips positionals up to and including the c/create keyword by name rather than assuming it is at [0].
  • Install's SHARED_PARAMS gains a hidden --env-file <STR>... entry so the path is consumed instead of leaking into cli.positionals (--cwd and --config were already declared there).

-c, --config is intentionally not stepped over: it is declared Values::OneOptional, so the downstream clap parse never consumes a separate token for it either and the path would still surface as a positional. #34983 changes that declaration to required-value; once that lands, --config can be added to the skip set and will behave identically to --cwd.

Verification

New tests in test/cli/bun.test.ts cover run, test, build, exec, init, install, add with --cwd / --env-file before the subcommand, plus the #34983 regression guard (bun --env-file my.env install must not treat the path as a package name). All 14 fail with USE_SYSTEM_BUN=1 and pass with the fix.


no test proof · iteration 3 · Platform-specific test(s) that do not run on this machine. Deferring to CI, which covers all platforms: test/cli/bun.test.ts

Known limitation

For the install family (install/add/remove/update/pm/…), a leading --env-file is now accepted and its path no longer leaks as a positional, but the env file is not yet loaded: PackageManager::init's env.load(entries, &[], …) still passes an empty explicit-files list. This was already the case for bun install --env-file .env on main (where the flag was unrecognized and the path mis-routed to bun add), so no working invocation regresses. Threading the option through to env.load is a separate change.

Fixes #10333

Command::which() scans argv for the first non-dash token to pick the
subcommand, but treated every dash-prefixed token as valueless. The
value of --cwd / --env-file was therefore read as the subcommand name:

  bun --cwd ./dir test foo.test.ts    -> AutoCommand, 'Script not found test'
  bun --env-file .env run app.ts      -> AutoCommand, prints help

which() now steps past the value of the required-value BASE_PARAMS_
flags and records the argv index of the keyword it lands on. Every
handler that re-reads raw argv at a hard-coded offset (init, info,
create, bunx via 'bun x', upgrade, pm, completions, reserved) uses that
index instead, so 'bun --cwd d <cmd> ...' and 'bun <cmd> ...' share the
same downstream parse.

For the package-manager family, --cwd and --config were already declared
in SHARED_PARAMS and are consumed correctly; --env-file is added as a
hidden param so its path never leaks into cli.positionals as a spurious
package name.

-c/--config is intentionally not stepped over: it is declared
OneOptional, so clap never consumes a separate token for it and the
downstream parse would still see the path as a positional. #34983
changes that declaration.
@github-actions github-actions Bot added the claude label Aug 1, 2026
@robobun

robobun commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator Author

Status: diff is ready. Build #87469 ran the full suite; test/cli/bun.test.ts and every CLI-adjacent suite this PR touches passed on every lane that ran. Remaining reds on that build are unrelated: an EC2 agent-provisioning failure on debian 13 aarch64, a JSC ExceptionScope ASAN assertion in test-worker-message-port-transfer-terminate.js (worker/message-port code this diff doesn't touch; reported separately), and three flakes that passed on retry/alone (parallel.test.ts, node-module-module.test.js, sourcetextmodule-leak.test.ts). Builds 87335/87378 earlier had every build-* job expire in the Buildkite queue before running.

16 new tests in test/cli/bun.test.ts; with main's src/ 15/16 fail (the one that passes is the bun --bun x <bin> regression guard, which is expected to pass on main), with the diff 16/16 pass. Regression suites (bun-pm, bun-info, trust, bun-init, bunx, bun-run) all clean locally.

Reproduced on 1.4.0-canary:

bun --cwd ./dir test foo.test.ts   # error: Script not found "test"
bun --env-file .env run app.ts     # prints `bun run` help instead of running
bun --cwd sub init -y              # error: Script not found "init"

Review follow-ups addressed in 9ae4055..b12f741:

  • bun_info reads positionals from the INFO_PARAMS clap parse instead of re-scanning raw argv.
  • exec_init / exec_bunx / bun_create chdir into a leading --cwd (both --cwd dir and --cwd=dir, last-wins) so the command doesn't silently run in the wrong directory.
  • bun --bun x <bin> / bun --bun create <tmpl> still see --bun: bunx/create keep scanning argv[1..] and step past --cwd/--env-file values themselves instead of being handed a pre-sliced argv.
  • bun --all list / bun --all pm trust still see --all: the --all/--trusted flag probes scan full argv while args[2..] positional handling stays relative to the subcommand keyword; the redundant args.len()==2 early guard in TrustCommand was dropped so the full-argv --all scan can run.
  • bunx shebang-stub test is skipIf(isWindows).

Spot-checked post-fix: --cwd=. (attached form), bare --cwd (errors "requires a value"), repeated --env-file, mixed leading flags (--silent --cwd . run), and the baseline bun run --cwd . <script> are all unchanged.

Comment thread src/runtime/cli/create_command.rs Outdated
Comment thread src/runtime/cli/mod.rs Outdated
@robobun

robobun commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator Author
Updated 6:43 PM PT - Aug 1st, 2026

@robobun, your commit 6c3de46 has 3 failures in Build #87469 (All Failures):


🧪   To try this PR locally:

bunx bun-pr 36644

That installs a local version of the PR into your bun-36644 executable, so you can run:

bun-36644 --bun

Comment thread src/runtime/cli/mod.rs Outdated
Comment thread src/runtime/cli/mod.rs Outdated
Comment thread src/runtime/cli/package_manager_command.rs Outdated
@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Changes

CLI subcommand indexing

Layer / File(s) Summary
Global flag detection and index storage
src/install/PackageManager/CommandLineArguments.rs, src/runtime/cli/mod.rs
The CLI advertises --env-file and records the subcommand index after global flags and their values.
Handler argument slicing
src/runtime/cli/mod.rs, src/runtime/cli/create_command.rs, src/runtime/cli/bunx_command.rs, src/runtime/cli/package_manager_command.rs, src/runtime/cli/upgrade_command.rs
Command handlers use the detected index instead of fixed argument offsets. They skip --cwd and --env-file values during parsing.
Global-flag dispatch coverage
test/cli/bun.test.ts
Tests cover dispatch, environment loading, working-directory resolution, and argument handling for global flags.

Possibly related PRs

  • oven-sh/bun#36696: Both changes modify src/runtime/cli/bunx_command.rs argument handling and execution behavior.

Suggested reviewers: jarred-sumner

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes address issue #10333 by correctly dispatching commands after --cwd and preserving the expected run behavior and exit handling.
Out of Scope Changes check ✅ Passed The changes remain within the CLI parsing, handler updates, install parameter support, and regression tests described by the objectives.
Title check ✅ Passed The title clearly identifies the main change: correct subcommand classification past --cwd and --env-file values.
Description check ✅ Passed The description explains the problem, implementation, verification, known limitation, and linked issue, although it uses alternate section headings.

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

@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: 4

🤖 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/runtime/cli/create_command.rs`:
- Around line 235-246: Update the create-command argument handling around the
positional scan to use the global parser’s detected subcommand index rather than
matching positional text; remove argv entries through that index so option
values equal to “c” or “create” are preserved correctly. Add regression coverage
for both --cwd and --env-file values using each accepted command spelling,
including the supported option spellings.

In `@src/runtime/cli/mod.rs`:
- Around line 1513-1514: Update the direct InitCommand::exec dispatch in the CLI
path to process the validated global --cwd option before invoking init,
preserving the requested working directory for commands such as bun --cwd target
init --yes. Add a regression test verifying that package.json is created under
the requested directory.
- Around line 1952-1955: Update the argument parsing around the info
subcommand’s found_package loop to consume --env-file together with its separate
value, rather than treating that value as a positional package or property path;
handle repeated --env-file options consistently. Prefer the existing parsed
positional arguments or declared option arity, and add coverage for separate and
repeated values plus invalid/adversarial cases.

In `@test/cli/bun.test.ts`:
- Around line 263-270: Strengthen the test around run(["--cwd", "sub", "add",
"--dry-run"]) to assert the expected no-package bun add usage diagnostic and
nonzero exitCode. Keep the existing resolver and “Script not found” assertions,
using the returned execution result so unrelated failures cannot satisfy the
test.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: dc2e9ea5-a667-4fb2-b1a3-31a765d56c8e

📥 Commits

Reviewing files that changed from the base of the PR and between 5f7e62d and 804b819.

📒 Files selected for processing (6)
  • src/install/PackageManager/CommandLineArguments.rs
  • src/runtime/cli/create_command.rs
  • src/runtime/cli/mod.rs
  • src/runtime/cli/package_manager_command.rs
  • src/runtime/cli/upgrade_command.rs
  • test/cli/bun.test.ts

Comment thread src/runtime/cli/create_command.rs Outdated
Comment thread src/runtime/cli/mod.rs
Comment thread src/runtime/cli/mod.rs Outdated
Comment thread test/cli/bun.test.ts
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Found 3 issues this PR may fix:

  1. bun --cwd . run Fails with Exit Code 0 #10333 - bun --cwd . run shows help instead of running; the . (value of --cwd) is misread as the subcommand name
  2. bunx cannot use --env-file #12430 - bunx --env-file ../../.env serve treats the env file path as the package name due to the same flag-value misclassification
  3. bun --print may interpret what follows as a sub-command w/ no way to escape && bun run --eval is broken #23631 - bun --print x interprets x as a subcommand instead of code to evaluate; same root cause in which()

If this is helpful, copy the block below into the PR description to auto-close these issues on merge.

Fixes #10333
Fixes #12430
Fixes #23631

🤖 Generated with Claude Code

Comment thread src/runtime/cli/mod.rs
Comment thread src/install/PackageManager/CommandLineArguments.rs
Comment thread test/cli/bun.test.ts
Comment thread src/runtime/cli/create_command.rs Outdated
Comment thread src/runtime/cli/mod.rs Outdated
…bunx/create

- bun_info reads cli.positionals from the INFO_PARAMS clap parse instead of
  re-scanning raw argv, so value-taking flags after 'info' (--cwd, --registry,
  --env-file) no longer leak their value as the package name.
- exec_init / exec_bunx / bun_create chdir into a leading --cwd before
  running, so 'bun --cwd target init' scaffolds in target/ rather than
  silently ignoring the flag (none of these route through a parser that
  honors --cwd on their own).
- Tighten the 'bun --cwd sub add --dry-run' test to assert the
  zero-positional diagnostic; change the init test to a non-'.' --cwd and
  assert package.json lands in the subdirectory.
- Trim doc comments flagged by comment-cop to one line each.
Comment thread src/runtime/cli/mod.rs
Comment thread src/runtime/cli/mod.rs Outdated
Comment thread src/runtime/cli/mod.rs
Comment thread src/runtime/cli/mod.rs Outdated
Comment thread src/runtime/cli/mod.rs
…_leading_cwd

Changing exec_bunx's start_idx to subcommand_argv_index() stripped every
leading dash token, not just --cwd/--env-file, so 'bun --bun x vite'
lost --bun. Revert to passing argv[1..] and instead teach bunx's
Options::parse and bun_create's remainder scan to step past the value
of --cwd/--env-file themselves. apply_leading_cwd now also matches the
attached --cwd=dir form.
Comment thread src/runtime/cli/bunx_command.rs Outdated
Comment thread src/runtime/cli/mod.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.

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
src/runtime/cli/mod.rs (1)

1571-1579: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Handle --cwd for direct bunx invocations.

bunx skips arguments::parse, and SUBCOMMAND_ARGV_INDEX remains 1. apply_leading_cwd() therefore ignores bunx --cwd <dir> <package> and bunx --cwd=<dir> <package>. Handle these flags before BunxCommand::exec and add direct-executable regression coverage.

🤖 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/runtime/cli/mod.rs` around lines 1571 - 1579, Update the direct bunx
invocation flow around apply_leading_cwd and BunxCommand::exec to detect and
apply both --cwd <dir> and --cwd=<dir> before executing the package, since bunx
bypasses arguments::parse. Preserve the existing argv slicing behavior for
executable and non-executable paths, and add regression coverage for both flag
forms when invoking the direct bunx executable.

Source: Coding guidelines

🤖 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 `@test/cli/bun.test.ts`:
- Around line 176-180: Replace the imperative loop around the
leading-global-flag cases in test/cli/bun.test.ts lines 176-180 with a
test.concurrent.each() matrix, preserving each case’s isolated temporary
directory and subprocess assertions. Also replace the --cwd loop in
test/cli/bun.test.ts lines 243-252 with a separate test.concurrent.each()
matrix, giving each input an independent test result; then run bun bd test
test/cli/bun.test.ts.

---

Outside diff comments:
In `@src/runtime/cli/mod.rs`:
- Around line 1571-1579: Update the direct bunx invocation flow around
apply_leading_cwd and BunxCommand::exec to detect and apply both --cwd <dir> and
--cwd=<dir> before executing the package, since bunx bypasses arguments::parse.
Preserve the existing argv slicing behavior for executable and non-executable
paths, and add regression coverage for both flag forms when invoking the direct
bunx executable.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 59dc8349-1410-425e-85dd-2e005616b0f1

📥 Commits

Reviewing files that changed from the base of the PR and between 804b819 and 61a8324.

📒 Files selected for processing (4)
  • src/runtime/cli/bunx_command.rs
  • src/runtime/cli/create_command.rs
  • src/runtime/cli/mod.rs
  • test/cli/bun.test.ts
💤 Files with no reviewable changes (1)
  • src/runtime/cli/create_command.rs

Comment thread test/cli/bun.test.ts

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

Commit 61a8324 addresses both of my earlier unresolved comments — exec_bunx is back to start_idx = 1 so bun --bun x <bin> keeps its leading flags (verified by the new test), bun_create re-scans &args[1..] with a --cwd/--env-file skip arm so --bun before create is preserved, and apply_leading_cwd() now handles the --cwd=dir attached form with the corrected i < end bound. Those two threads can be resolved.

Extended reasoning...

The two 🔴/🟡 inline comments I left on the previous revision (leading-flag stripping in exec_bunx/bun_create, and the --cwd=dir gap in apply_leading_cwd) are fixed by 61a8324; I re-traced bun --bun x vite, bun --cwd sub x cowsay, bun --bun create next-app, and bun --cwd=target init -y against the current diff and each now dispatches correctly with the flag applied. The new inline findings from this run cover what remains.

Comment thread test/cli/bun.test.ts Outdated
Comment thread src/runtime/cli/bunx_command.rs
Comment thread src/runtime/cli/bunx_command.rs
Comment thread src/runtime/cli/mod.rs Outdated
Comment thread src/runtime/cli/mod.rs
Comment thread src/runtime/cli/package_manager_command.rs Outdated
The skip(cmd_idx) slice is correct for TrustCommand's args[2..] positional
handling, but it also stripped leading flags so 'bun --all list' /
'bun --all pm trust' lost --all. Flag probes now scan the full argv;
positional slicing still starts at the subcommand keyword.
Comment thread src/runtime/cli/package_manager_command.rs
Comment thread src/runtime/cli/pm_trusted_command.rs
It fired before the full-argv --all scan, so 'bun --all pm trust' still
errored. The '!trust_all && packages_to_trust.is_empty()' check just
below covers the same case.

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

All five earlier findings are addressed (61a8324b12f741) and this pass found nothing new. Deferring rather than approving because the change is cross-cutting: a new process-global SUBCOMMAND_ARGV_INDEX + apply_leading_cwd() threaded through ~10 subcommand handlers, re-attempting a previously-reverted approach (#34983). Each review round surfaced a fresh sibling-site regression, so a maintainer should sign off on the shape of the fix.

What was reviewed:

  • which() index tracking and every subcommand_argv_index() consumer for off-by-one / stripped-flag regressions
  • apply_leading_cwd() for --cwd=dir, repeated --cwd, and last-wins semantics vs. clap
  • pm ls/trust flag scans against all_args so pre-keyword --all/--trusted still work; redundant args.len()==2 guard dropped
  • New tests for hermeticity (Windows shebang guard, --dry-run on install/add)
Extended reasoning...

Overview

The PR fixes Command::which() misclassifying the value of a leading --cwd/--env-file as the subcommand keyword. It introduces a process-global SUBCOMMAND_ARGV_INDEX recorded during which(), a helper apply_leading_cwd(), and rewires every handler that previously read raw bun::argv() at a hardcoded offset (exec_init, exec_bunx, bun_create, bun_info, exec_install_completions, reserved_command, upgrade_command, package_manager_command, pm_trusted_command, CreateOptions::parse, and bunx's Options::parse). Install's SHARED_PARAMS gains a hidden --env-file entry. 8 files, ~150 lines of new tests.

Security risks

None identified. Pure argv-classification / dispatch logic; no auth, crypto, or untrusted-input parsing beyond argv itself.

Level of scrutiny

High. This is the CLI entry point — every bun <subcommand> invocation flows through which() and one of the touched handlers. The exact same approach was tried before (#34983) and reverted because handlers reading raw argv at fixed offsets broke. Over five review iterations on this PR, each fix surfaced another sibling-site regression (bunx --bun stripping, --cwd=dir attached form, first-vs-last --cwd wins, bun --all list flag stripping, pm trust len==2 guard). All were fixed, but the pattern indicates the invariants here are subtle and easy to miss.

Other factors

  • All five of my prior inline findings are resolved by commits 61a8324, 506da7e, 7185a41, 4518bad, b12f741; the bug-hunting system found nothing on the current revision.
  • The PR description honestly documents a remaining limitation (leading --env-file for the install family is accepted but not loaded), and the bunx --cwd-after-x comment now truthfully says "not honored yet" rather than claiming it was applied.
  • SUBCOMMAND_ARGV_INDEX + apply_leading_cwd() are new cross-cutting mechanisms; per the repo's own guidance, new cross-cutting abstractions benefit from maintainer agreement on the shape before landing.
  • One open CodeRabbit nit (convert two for loops to test.concurrent.each) is stylistic and non-blocking.

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

No new issues found — all five earlier findings (Windows shebang test, --cwd= attached form, last-wins --cwd, pre-keyword --all/--trusted for pm ls/trust, and the redundant args.len()==2 guard) are addressed in the latest commits. Deferring to a human for sign-off given this is a cross-cutting CLI-dispatch change that touches which() and seven downstream raw-argv consumers, was previously attempted and reverted (#34983), and carries two documented not-yet-honored gaps (--env-file for the install family; --cwd after the x keyword).

What was reviewed:

  • which() value-skip and SUBCOMMAND_ARGV_INDEX threading through init/bunx/create/info/completions/upgrade/pm/reserved.
  • apply_leading_cwd for both --cwd v and --cwd=v, last-occurrence semantics, and the bun_create positional scan skipping flag values.
  • package_manager_command's all_args vs sliced args split so pre-keyword --all/--trusted still resolve; TrustCommand full-argv --all scan with the len==2 guard removed.
  • New tests: hermetic (--dry-run, local .bin stub), Windows-guarded, concurrent, and cover run/test/build/exec/init/install/add/bunx.
Extended reasoning...

Overview

This PR fixes Command::which() so that the value token of --cwd / --env-file is not misread as the subcommand keyword (e.g. bun --cwd ./dir test foo previously dispatched AutoCommand on ./dir). It introduces a process-global SUBCOMMAND_ARGV_INDEX recorded by which() and rewires every handler that previously sliced raw bun::argv() at a hard-coded offset — exec_init, exec_bunx, bun_create, bun_info, exec_install_completions, reserved_command, upgrade_command, package_manager_command, pm_trusted_command — plus adds a hidden --env-file param to install's SHARED_PARAMS and an apply_leading_cwd() helper for handlers that don't route through clap. ~150 lines of Rust across 7 files, plus ~150 lines of new tests in test/cli/bun.test.ts.

Security risks

None identified. The change is argv-classification only; no new I/O, network, or privilege surface. apply_leading_cwd() chdirs to a user-supplied path, but that's the existing --cwd semantics already applied by arguments::parse for other subcommands.

Level of scrutiny

High. which() runs on every bun invocation and every downstream handler that re-reads raw argv is a potential mis-slice. The prior attempt (#34983) was reverted for exactly that reason, and this PR's own review history surfaced five separate edge cases across five iterations (Windows shebang test, --cwd= attached form, first-vs-last --cwd, pre-keyword --all for pm, and the len==2 trust guard). All are now addressed, but the pattern — plus two documented remaining gaps (install-family --env-file not loaded; post-x --cwd silently stepped over) — makes this the kind of change a maintainer should sign off on rather than auto-approve.

Other factors

  • All prior inline findings from this reviewer are resolved in commits 506da7e / 7185a41 / 4518bad / b12f741.
  • The new test suite is reasonably broad (run/test/build/exec/init/install/add/bunx across --cwd, --cwd=, --env-file, and mixed), uses --dry-run / a local .bin stub to stay hermetic, and is Windows-guarded where needed.
  • The bun_info rewrite from a manual argv scan to cli.positionals is a net simplification and correctly strips the leading info keyword.
  • CreateOptions::parse now drains up to and including the first c/create positional rather than assuming index 0 — traced against bun_create's positional collection and looks correct.

@robobun

robobun commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator Author

Heads up: #39379 now carries the reader-side part of this change, using the same SUBCOMMAND_ARGV_INDEX / subcommand_argv_index() primitive (its mod.rs and upgrade_command.rs hunks are this PR's, verbatim) plus the bun_info positionals rewrite, and fixes pm trust by reading pm.options.positionals. It covers the valueless-flag and BUN_OPTIONS shifts (#20347) and does not touch the classifier. Once it lands, this PR should rebase down to the --cwd / --env-file stepping, apply_leading_cwd, and the remaining reader conversions (reserved, completions, create, bunx); the package_manager_command.rs reslicing becomes unnecessary.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bun --cwd . run Fails with Exit Code 0

1 participant