Skip to content

fix(steppage): provision StepPage safely on Windows - #305

Open
li-xiu-qi wants to merge 4 commits into
stepfun-ai:mainfrom
li-xiu-qi:fix/steppage-windows-provisioning-final
Open

li-xiu-qi wants to merge 4 commits into
stepfun-ai:mainfrom
li-xiu-qi:fix/steppage-windows-provisioning-final

Conversation

@li-xiu-qi

@li-xiu-qi li-xiu-qi commented Oct 26, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #304
Refs #219

Problem

#219 identified the missing automatic StepPage provisioning path on Windows. The candidate implementation adds that path, but bare cmd and curl.exe can still resolve through the working directory, and the wrapper health probe can still pass special path text through cmd parsing. URL forms containing single quotes can bypass redaction, while Windows ENOENT guidance still points to POSIX curl | sh.

This PR retains Hylouis233's three original commits and adds focused hardening plus native Windows acceptance coverage.

Changes

Windows provisioning installs the published StepPage bundle and writes ~/.local/bin/steppage-mcp.cmd. It resolves node.exe, cmd.exe, and curl.exe only from absolute PATH entries. Missing cmd.exe or curl.exe fails before any download begins.

The health probe sets cwd to the wrapper directory and invokes the wrapper by a fixed basename through an absolute cmd.exe. Spaces, &, and % in that directory stay out of the cmd command line.

Error reporting redacts userinfo and sensitive query/fragment values in both raw and shell-escaped URLs, and also redacts environment-variable values. Windows ENOENT now points users to step mcp prepare. Documentation and regression tests are updated with the implementation.

Behavior and compatibility

On Windows, step mcp prepare can automatically install StepPage and reuse a healthy installation. Custom commands, disabled configurations, and explicit uninstall behavior are unchanged. StepPage still requires Node >=20.

The POSIX installation flow is unchanged apart from broader redaction. Step itself does not gain a separate Node dependency.

Validation

Final HEAD is e37e8d44ac5cc1a290e0599466237968e781f6a5.

The focused regression command is

cd packages/coding-agent && pnpm exec vitest --run test/steppage-provision-windows.test.ts src/step/mcp.test.ts

Against unfixed d77b1efe, the final tests report 5 failed / 29 passed. With the fix, the two focused test files pass 34/34.

From packages/coding-agent, the related four-file command is

pnpm exec vitest --run test/steppage-provision-windows.test.ts src/step/mcp.test.ts test/step-plugins.test.ts src/step/mcp-startup.test.ts

The candidate reports 86 passed / 3 failed / 1 skipped, while unmodified d77b1efe reports 82 passed / 3 failed / 1 skipped. Both runs fail the same three tests: uses the Step namespace for default storage and withholds project plugin resources unless the project is trusted in test/step-plugins.test.ts, and a plugin stdio server runs from the plugin root unless it names an absolute cwd in src/step/mcp-startup.test.ts.

On native Windows with Node v24.21.0, repository-root pnpm run check passes.

./test.sh stops at the pre-existing Windows failure install.sh persists inherited PATH and preserves malformed user blocks in scripts/release-bundle.test.mjs. It does not reach the workspace packages.

The isolated pnpm -r --no-bail --if-present test workspace run is not green on either tree. It contains 5,062 coding-agent tests on the candidate and 5,058 on unmodified d77b1efe, with 266 skipped in both. After normalizing duration suffixes in test names, there are 0 candidate-only failures and 7 baseline-only failures. The same five packages have pre-existing Windows failures in both runs.

From packages/coding-agent, this command uses the repository entry points to build dist/step-bin.exe successfully.

bun build --compile --no-compile-autoload-bunfig --env=STEPCODE_BUILD_* ../../apps/cli/src/bun/stepcode.ts ./src/utils/image-resize-worker.ts ./src/step/usage/activity-worker.ts ./src/core/session-index/session-index-worker.ts --outfile dist/step-bin

The old binary reports the StepPage version-check failure with isolated HOME native&%PATH%probe. The new binary installs successfully when HOME contains spaces, &, and %PATH%, with node.cmd, cmd.exe, and curl.exe decoys in cwd. The wrapper returns 1.0.0, MCP initialize reports server steppage version 0.0.1, and tools/list returns 13 tools.

git diff --check passes, and the final diff contains 6 target files.

Limitations

None known.

Hylouis233 and others added 4 commits October 25, 2026 06:38
provisionBuiltinPlugin() skipped win32 entirely and ensureStepPageReady()
refused to install without a healthy executable, so the built-in steppage
plugin could never set up steppage-mcp on Windows and every launch reported
"automatic installation is currently supported on macOS and Linux" (stepfun-ai#219).

Windows cannot run the POSIX installer script, so install the published
bundle directly: download steppage-mcp.mjs, write a steppage-mcp.cmd wrapper
next to it under ~/.local/bin, and verify the result. Executable probes run
through `cmd /d /c` on Windows so both bare PATHEXT lookups and explicit
.cmd files resolve on every Node runtime.

The lock, Node.js >= 20 check, credential handling and failure reporting
stay shared with the POSIX path; only the download-and-execute step is
platform-specific. The Windows failure hint points at `step mcp prepare`
instead of the POSIX-only `curl | sh` pipeline.
On Windows, `cmd` searches the current working directory before PATH, so
probing the bare `steppage-mcp` name could execute a project-controlled
`steppage-mcp.cmd`. Windows candidates are now resolved to absolute files
from absolute PATH entries only (`.cmd`, `.exe`, `.bat`), followed by the
managed `~/.local/bin/steppage-mcp.cmd` wrapper; relative PATH entries,
including `.`, are skipped.

The bundle URL is now derived from STEPCODE_STEPPAGE_INSTALLER_URL with URL
parsing, so a mirror's credentials, query parameters, percent-encoding and
fragment are preserved when switching to `latest/steppage-mcp.mjs`.

Tests cover absolute-only Windows probes, a PATH that contains the working
directory, and mirror URL preservation.
Native Windows validation showed the generated `steppage-mcp.cmd` wrapper
invoked a bare `node`, which `cmd` resolves from the working directory
before PATH: a project-controlled `node.cmd` ran in its place. Windows now
resolves `node.exe` from absolute PATH entries only, runs the Node.js >= 20
check with that absolute path, and writes the same path into the wrapper.
Setup fails closed when no such `node.exe` exists. `process.execPath` is not
used because in the standalone binary it is Step itself.

Mirror URLs could also carry a password or token into the final error text
on both the Windows and POSIX paths, either from a curl failure or from the
manual install hint. The complete message is now redacted: URL userinfo,
token-like query or fragment parameters, and secret-named environment
values. Detail is redacted before truncation so a cut cannot strip the
scheme that marks a URL. The missing-executable hint in the MCP startup
message uses the same redaction.

Tests cover node.exe resolution that skips relative entries and the
working directory, the runtime check and wrapper sharing one absolute
path, failing closed without node.exe, and credential-free failure text
for Windows, Linux and the MCP startup hint.
Resolve Windows provisioning executables from absolute PATH entries and probe wrappers by basename from their own directory.

Redact quoted mirror URLs and use the native preparation hint on Windows.
@Hylouis233

Copy link
Copy Markdown
Contributor

@li-xiu-qi thank you for opening this from our branch and for the extra hardening commit on top of our three commits — that matches what we wanted for the Windows path.

CI looks green on our side of the story too. Maintainers: this closes the Windows provisioning gap from #219 (already Refs #219 in the body); please associate #219 when reviewing/merging.

@Hylouis233

Copy link
Copy Markdown
Contributor

Follow-up after local re-check of head e37e8d44:

  • Our three commits (878ff8f, 9ea8904, d77b1ef) are unchanged; e37e8d44 is a clean fast-forward on top.
  • The extra hardening looks right to us: absolute-PATH resolution for cmd.exe/curl.exe, fail-closed preflight, basename+cwd probe (safe with &/% in HOME), quote-aware credential redaction, and the Windows step mcp prepare hint.
  • On Linux with mocked win32: steppage-provision-windows 18/18, related suites 106/106; biome / tsgo / no-secret-leak clean.
  • We have not re-run on native Windows ourselves — happy to defer to @li-xiu-qi’s earlier Windows validation / maintainer CI.

No further code changes from our side. Please associate #219 when reviewing.

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.

[Bug] Windows StepPage provisioning can resolve executables from the working directory

2 participants