feat: installable protostar CLI (PROT-6)#1
Merged
Conversation
Introduce the protostar CLI so a harness can invoke it. Built with Spectre.Console.Cli; `protostar` prints a styled status, `--version` and `--help` work out of the box. Commands (auth, sync, hooks) land in later tickets. - src/Protostar.Cli: Spectre.Console.Cli CommandApp; binary named `protostar`, InvariantGlobalization for a smaller self-contained build. - install.ps1: publishes a self-contained, single-file executable (no .NET runtime needed to run), installs to %LOCALAPPDATA%\Programs\protostar, and puts it on PATH. Verified: installed binary runs standalone (36.6 MB, ~218 ms cold start). Lean/fast optimization (trimming/AOT) is deferred to a separate performance-tuning ticket, since Spectre.Console.Cli's reflection-based binding is not trim/AOT-safe. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Make the CLI install itself, and provide one-line installers that fetch the latest GitHub release. - `protostar install` / `protostar uninstall`: the running binary copies itself into a per-user dir (%LOCALAPPDATA%\Programs\protostar on Windows, ~/.local/bin on Unix) and manages PATH. Options: --dir, --no-modify-path. Cross-platform. - scripts/install.ps1 + scripts/install.sh: detect OS/arch, download the matching asset from releases/latest/download, and run `protostar install`. Curl-able and surfaced in the README. - Remove the source-build install.ps1 (superseded; dev flow documented in README). Release assets are expected as protostar-<rid>(.exe) (e.g. protostar-win-x64.exe, protostar-linux-x64); the CI to publish them is upcoming work. Verified the install/uninstall cycle end-to-end and both bootstrap scripts' arch/URL resolution. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Guarantees scripts/install.sh stays LF-terminated regardless of core.autocrlf, so the Linux/macOS curl installer's shebang never breaks; PowerShell scripts pinned CRLF. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Version is derived from git tags by MinVer and read from the assembly at runtime, replacing the hardcoded CliInfo constant. release-please manages the release flow: a Release PR bumps version.txt + CHANGELOG, and merging it tags main and triggers a build that attaches self-contained binaries (win-x64, win-arm64, linux-x64, osx-arm64) to the GitHub Release. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ljones491
approved these changes
Jun 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Lands the first
protostarcomponent — an installable CLI (Jira PROT-6) — and the versioning + release automation that ships it. After this merges, releasing is "merge a Release PR"; the version flows from a git tag into the binary with no manual edits.This PR bundles two logically distinct parts; they are described separately below.
Part 1 — The
protostarCLI (PROT-6)A self-contained, single-file binary (no .NET runtime required on the target machine), built on
Spectre.Console.Cli.protostar installandprotostar uninstall— the binary installs itself into a per-user directory and manages PATH.src/Protostar.Cli/Commands/{DefaultCommand,InstallCommand,UninstallCommand}.cssrc/Protostar.Cli/Install/InstallEnvironment.csprotostar install:scripts/install.ps1(Windows),scripts/install.sh(Linux/macOS)src/Protostar.Cli/Protostar.Cli.csproj(net10.0,AssemblyName=protostar),Program.cs,.gitattributes.Part 2 — Versioning + automated releases
Directory.Build.propsadds MinVer (build-time only). The version is no longer hardcoded —CliInfo.csnow readsAssemblyInformationalVersionAttributeat runtime (trim/AOT-safe) and strips the+<sha>metadata. This removes the oldconst Version = "0.1.0"and its duplication in the README..github/workflows/release-please.ymlplusrelease-please-config.json,.release-please-manifest.json, andversion.txt. release-please maintains a Release PR (version + changelog) from Conventional Commits; merging it tagsmain, creates the GitHub Release, and a build job attaches binaries forwin-x64,win-arm64,linux-x64,osx-arm64.Design decisions worth a reviewer's eye
main; MinVer reads that tag at build time and stamps the binary. One source of truth (the tag).include-component-in-tag: falsemakes tagsv0.1.0(notprotostar-v0.1.0) so MinVer'svprefix matches. This is load-bearing.release_created), so the "GITHUB_TOKEN does not trigger downstream workflows" limitation does not apply.protostar-<rid>[.exe], matching exactly whatscripts/install.*fetch fromreleases/latest/download/.What this changes about our workflow (after merge)
feat:,fix:,feat!:for breaking) and squash-merge — the squash subject is what release-please reads.feat:PR takes the baseline0.0.0to 0.1.0, which release-please will propose in the first Release PR.Verify locally
Tagging a commit
v0.1.0and rebuilding makes--versionreport a clean0.1.0(verified locally), which is exactly what release-please will produce onmain.🤖 Generated with Claude Code