Skip to content

Skip plain-forge install when Node.js is unavailable - #266

Open
pedjaradenkovic wants to merge 2 commits into
mainfrom
fix/skip-plain-forge-install-without-node
Open

Skip plain-forge install when Node.js is unavailable#266
pedjaradenkovic wants to merge 2 commits into
mainfrom
fix/skip-plain-forge-install-without-node

Conversation

@pedjaradenkovic

Copy link
Copy Markdown
Contributor

Problem

The installers already checked command -v npx / Get-Command npx, but that check passes when a version-manager shim (nvm, volta, asdf) is on PATH without a working Node.js behind it. When the shim then fails:

  • bash: set -euo pipefail aborts the entire installer mid-flow — the plyn extension, examples, and final verification steps never run.
  • PowerShell: $ErrorActionPreference = 'Stop' has the same exposure, and $plainForgeInstalled was set to $true even when the npx command failed.

Fix

  • Verify Node actually runs (node --version succeeds) instead of only checking that an npx shim resolves. When it doesn't, skip the step with a clear "Node.js not found. Skipping plain-forge…" message plus the manual npx plain-forge install hint.
  • Wrap the npx plain-forge install call so a failure prints a retry hint and the installer continues with the remaining steps instead of aborting.
  • Only mark plain-forge as installed on a zero exit code, so the existing "Next steps" screen reminds the user to install it manually whenever the step was skipped or failed.

Testing

  • bash -n passes on the bash installer.
  • Simulated all three scenarios under set -e (npx missing entirely, broken shim, npx plain-forge install exiting non-zero) — the installer skips or continues correctly in each case and reaches the end.
  • pwsh isn't available locally, so the PowerShell file was not syntax-checked — worth a quick run on a Windows box.

The npx presence check passes when a version-manager shim (nvm, volta,
asdf) is on PATH without a working Node.js behind it. The npx call then
fails and aborts the whole installer: set -euo pipefail in bash,
ErrorActionPreference=Stop in PowerShell. The PowerShell installer also
marked plain-forge as installed even when the npx command failed.

Verify node actually runs before invoking npx, skip the step with a
clear message when it doesn't, and let a failed plain-forge install
print a retry hint instead of aborting the remaining setup steps. The
final next-steps screen already reminds the user to install plain-forge
manually whenever the step was skipped or failed.
The bare "Node.js not found" line read like a status report and did
not say what plain-forge is or why Node.js matters. Explain that
plain-forge brings codeplain's agentic skills to the user's coding
agent, that installing it requires Node.js, and how to add it later.
@pedjaradenkovic
pedjaradenkovic requested a review from zanjonke July 30, 2026 09:20
@pedjaradenkovic pedjaradenkovic self-assigned this Jul 30, 2026
@sunasrd-byte

Copy link
Copy Markdown
Contributor

Tested this on macOS (Darwin 24.6.0, bash 3.2, Node v24.18.0) — bash installer

Confirmed the fix does what it claims. Four things I'd still flag:

  1. "Already installed" is reported as a failure, with unfollowable advice. plain-forge install
    exits 1 when it's already present (bin/cli.mjs:781-787
    (https://github.com/Codeplain-ai/plain-forge/blob/main/bin/cli.mjs#L781)), printing plain-forge is
    already installed in . / run "plain-forge update" to refresh it. The new if npx ... treats
    that as a failure, so a returning user sees:

plain-forge is already installed in /Users/you/.claude.
run "plain-forge update" to refresh it.
plain-forge installation failed. You can retry later with:
npx plain-forge install

They're told installation failed and told to retry with the one command guaranteed to fail again —
while the correct command (update) was on screen two lines above. PLAIN_FORGE_INSTALLED=false also
puts "Let your agent work in specs, not code" in Next steps for someone who already has it. This is
pre-existing on main, but the fix makes it newly visible (previously it just killed the
installer). Worth capturing the exit code and treating already-installed as success — plain-forge
uses exit 2 for usage errors, so 1 vs 2 is distinguishable.

  1. The guard checks that Node runs, not that it's new enough. plain-forge declares "engines":
    {"node": ">=18"}. node --version &> /dev/null succeeds on Node 14/16, so npx runs, fails on the
    engine mismatch, and the user lands in "installation failed — retry with npx plain-forge install" —
    same dead end as requirements.txt is missing #1. Parsing the major version and routing old Node to the skip message would be
    more honest.

  2. The skip message misdiagnoses a missing npm. On distros that package nodejs without npm, node
    works and npx doesn't. Verified the guard correctly skips, but it reports that Node.js "was not
    found on this machine" when Node is right there. Cosmetic, and the suggested next step still works.

  3. npx can prompt inside the prompt flow. On a cold cache npx plain-forge install asks Ok to
    proceed? (y) before running. It survives because stdin is /dev/tty, but npx --yes
    plain-forge@latest install removes a prompt nested inside the installer's own prompt and pins the
    version.

Smaller nit: unlike ✓ uv detected / ✓ codeplain installed successfully! / ✓ plyn installed, the
success path here prints no confirmation of its own — just plain-forge's output and a blank line.

@pedjaradenkovic

Copy link
Copy Markdown
Contributor Author

@sunasrd-byte

I couldn't reproduce 1. Can you tell me how did you reproduce it? I think it just reinstalls the plain-forge and continues - which is good enough for this use case (rarely will anyone install codeplain after they have plain-forge already installed).

Regarding 2, 3 and 4, I don't think they are relevant (IMO it's a nitpicking for this change).

@sunasrd-byte

Copy link
Copy Markdown
Contributor

@pedjaradenkovic

The check applies to the resolved target directory, which is derived from the agent and scope. I reproduced it by running the install command twice against the same target:

bash
mkdir /tmp/pf-repro && cd /tmp/pf-repro
npx plain-forge install --agent claude --scope project; echo "exit: $?" # 0
npx plain-forge install --agent claude --scope project; echo "exit: $?" # 1

Anything that resolves to a different directory exits successfully.

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

🚀

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.

3 participants