Skip to content

[6.12.1] install --yes without --directory stops at the "Installation directory:" prompt, exits 0, and installs nothing #3064

Description

@arcaven

The headless install command in the install guide stops at an interactive prompt on 6.12.1 and exits 0 without installing anything, so a CI step that runs it as written succeeds with no _bmad/ in the project. Adding --directory makes the same command install.

This looks like the directory half of #1962. That issue reported both this prompt and a literal {output_folder} folder, and was closed as a duplicate of #1917; the closing note and the later v6.6.0 comment there are both about output_folder, so the prompt half may not have been tracked since.

Expected. The guide's "Headless CI installs" section (install-bmad.md L100-L106) gives, "For a typical fresh headless install of BMM configured for Claude Code":

npx bmad-method install --yes --modules bmm --tools claude-code

and the install command describes --directory <path> as "Installation directory (default: current directory)". So I expected an install into the current directory with no prompt, as #1962 also expected ("--yes without --directory should default to process.cwd()").

Actual. The installer shows Installation directory: and the process ends there with exit 0. No _bmad/ is created. With --directory added, the same command installs and exits 0.

Repro script and one full run

Clean HOME, Node.js from the nodejs.org tarball, temp project directories, cleanup trap. stdin is /dev/null, as in CI.

#!/usr/bin/env bash
# bmad-method 6.12.1: the documented headless install, with and without --directory.
# Clean HOME, Node.js from the nodejs.org tarball, temp project dirs, cleanup trap.
set -euo pipefail

NODE_V=v24.18.0
BMAD_V=6.12.1
ROOT="$(mktemp -d "${TMPDIR:-/tmp}/bmad-dir.XXXXXX")"
trap 'rm -rf -- "$ROOT"' EXIT

export HOME="$ROOT/home"; mkdir -p "$HOME"
export PATH="$ROOT/node/bin:/opt/homebrew/bin:/usr/bin:/bin"   # /opt/homebrew/bin for uv only; it has no node

echo "== host: $(sw_vers -productName) $(sw_vers -productVersion) $(uname -m)"
cd "$ROOT"
tgz="node-$NODE_V-darwin-arm64.tar.gz"
curl -fsSLO "https://nodejs.org/dist/$NODE_V/$tgz"
curl -fsSLO "https://nodejs.org/dist/$NODE_V/SHASUMS256.txt"
grep " $tgz\$" SHASUMS256.txt | shasum -a 256 -c -
mkdir node && tar -xzf "$tgz" -C node --strip-components 1
echo "node $(node --version), uv $(uv --version | cut -d' ' -f2)"

try() {  # label, then extra install args
  local label="$1"; shift
  local P="$ROOT/$label"; mkdir -p "$P" && cd "$P" && git init -q .
  echo
  echo "== $label: npx -y bmad-method@$BMAD_V install --yes --modules bmm --tools claude-code $*"
  set +e
  npx -y "bmad-method@$BMAD_V" install --yes --modules bmm --tools claude-code "$@" < /dev/null > "$P.log" 2>&1
  local rc=$?
  set -e
  echo "exit $rc; _bmad present: $([[ -d _bmad ]] && echo yes || echo no)"
  echo "last 3 log lines, escapes removed:"
  python3 -c 'import re,sys; t=open(sys.argv[1],encoding="utf-8",errors="replace").read(); t=re.sub(r"\x1b\[[0-9;?]*[A-Za-z]","",t); print("\n".join(l.rstrip() for l in t.splitlines()[-3:]))' "$P.log"
  cd "$ROOT"
}

# Positive control: the same command with --directory installs.
try with-directory --directory "$ROOT/with-directory"
# The command as documented in docs/start/install-bmad.md, "Headless CI installs".
try as-documented
== host: macOS 26.5.2 arm64
node-v24.18.0-darwin-arm64.tar.gz: OK
node v24.18.0, uv 0.12.1

== with-directory: npx -y bmad-method@6.12.1 install --yes --modules bmm --tools claude-code --directory $TMPDIR/bmad-dir.vaXmtK/with-directory
exit 0; _bmad present: yes
last 3 log lines, escapes removed:
npm notice Changelog: https://github.com/npm/cli/releases/tag/v12.2.0
npm notice To update run: npm install -g npm@12.2.0
npm notice

== as-documented: npx -y bmad-method@6.12.1 install --yes --modules bmm --tools claude-code 
exit 0; _bmad present: no
last 3 log lines, escapes removed:
◆  Installation directory:
│  $TMPDIR/bmad-dir.vaXmtK/as-documented█
└

Mechanism. When options.directory is unset, promptInstall goes to getConfirmedDirectory(), which prompts for the directory and asks for confirmation, and nothing on that path (getConfirmedDirectory, promptForDirectory, confirmDirectory) checks options.yes. Later steps in the same function do check it, for example the module selection at L511. I have not traced the exit code: the log ends at the prompt with no "Operation cancelled" line, so the process seems to end when stdin closes, not through handleCancel.

Relevant paths: tools/installer/ui.js L283-L296, tools/installer/ui.js L840, tools/installer/commands/install.js L14

Could --yes without --directory use process.cwd(), as that option text says?

No activity

Activity on this issue will appear here.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions