Skip to content

Let the standalone installers start stacktape init [skip ci] - #318

Merged
matuscongrady merged 2 commits into
mainfrom
feat/installer-run-init
Oct 24, 2026
Merged

matuscongrady merged 2 commits into
mainfrom
feat/installer-run-init

Conversation

@matuscongrady

@matuscongrady matuscongrady commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

The standalone installers can now start stacktape init right after installing, so a machine without Node.js needs one command:

curl -fsSL https://installs.stacktape.com/macos-arm.sh | sh -s -- init
iex "& { $(irm https://installs.stacktape.com/windows.ps1) } init"

Anything after the installer's own arguments is passed to the installed CLI, run by its full path because the new PATH entry only applies to new shells. With curl | sh, the CLI's input comes from the terminal (/dev/tty), because stdin is the rest of the piped script. Without a terminal (CI, Docker builds, a coding agent's shell), the CLI gets empty input instead of failing, so sh -s -- init --headless works there too. The shell installers exec the CLI, so its exit code is the installer's. Run as a file (powershell -File windows.ps1 init), the Windows installer exits with the CLI's code; under iex it never calls exit, which would close the user's PowerShell window. Without extra arguments nothing changes. The docs homepage's standalone-install tabs now use these commands.

Testing the real flow found a separate bug: released binaries never found the init wizard beside them, so stacktape init said "The wizard interface has not been built" and served a blank page. This affects 4.0.0-preview.10. findWizardBundle looked next to process.argv[1], which is a virtual /$bunfs/... path in a Bun-compiled binary. It now uses process.execPath.

How it was checked:

  • installers.spec.ts pipes each shell installer into sh -s -- init --projectDirectory "my app" with no terminal (setsid) and inside a pseudo-terminal (script). It checks the exact arguments, the CLI's stdin and the exit code. windows.spec.ts runs both Windows installers under pwsh as a file and through the iex form. The new cases fail against main's installers.
  • End to end on Linux: I built a release archive from this branch and installed it through the piped linux.sh in a pseudo-terminal. init started; headless Chromium rendered the wizard; Ctrl+C ended it. init --headless wrote stacktape.yml.
  • End to end on Windows 11: I installed the branch's windows.zip with windows.ps1 run as a file in Windows PowerShell 5.1 and pwsh 7, using temporary home folders. init --headless --projectDirectory "C:\…\my app" wrote stacktape.yml, and the installed stacktape.exe served the wizard page. I did not run the irm | iex download form on Windows: Windows Defender flags a powershell.exe command line that downloads and runs a script as Trojan:Win32/Commando.A!ml. That form was checked with pwsh on Linux instead.
  • pnpm check:public passes except two failures that origin/main has too: scripts/perf/packaging-harness.spec.ts ("measures a shape and reports which artifacts each edit changes") and the test registry, which finds no owner for apps/cli/src/domain/packaging-manager/dependency-installer.spec.ts from Reuse the runner's dependency install on Git push deploys [skip ci] #316. Also shellcheck (no new findings), and independent reviews by Fable 5.1 and GPT-6.1 Sol. Sol found that the file-run Windows installer hid the CLI's exit code, which is now fixed.

Nothing is published. The release workflow's publish-installers job uploads the installers to installs.stacktape.com on the next stable release. Until then the live 3.7.1 installers ignore init and only install. Console PR stacktape/console-app#142 records that the docs should be published after that release.

Two unverified notes from review. In Windows PowerShell 5.1 with $ErrorActionPreference = 'Stop', a CI step that redirects stderr could show an error after the CLI has finished. A coding-agent shell on macOS or Windows that runs init without --headless waits for the browser wizard, as plain stacktape init does there.

matuscongrady and others added 2 commits October 24, 2026 02:12
Arguments after the installer's own now run the installed CLI by its full path:
curl -fsSL https://installs.stacktape.com/macos.sh | sh -s -- init, or
iex "& { $(irm https://installs.stacktape.com/windows.ps1) } init" on Windows.
With curl | sh the CLI reads from the terminal instead of the piped script, and
gets empty input when there is no terminal. Run as a file, windows.ps1 exits
with the CLI's code; under iex it never exits, so the user's window stays open.
Without arguments nothing changes. The docs homepage shows the new commands.

Released binaries never found the init wizard beside them: argv[1] is a
virtual /$bunfs path in a compiled binary, so the wizard served nothing. The
lookup now uses execPath.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@matuscongrady
matuscongrady force-pushed the feat/installer-run-init branch from eef421d to c9f7f2f Compare October 24, 2026 00:12
@matuscongrady
matuscongrady merged commit b41c13c into main Oct 24, 2026
@matuscongrady
matuscongrady deleted the feat/installer-run-init branch October 24, 2026 00:14
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.

1 participant