RosaCli 0.8.1

dotnet tool install --global RosaCli --version 0.8.1
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local RosaCli --version 0.8.1
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=RosaCli&version=0.8.1
                    
nuke :add-package RosaCli --version 0.8.1
                    

rosa CLI

Scaffolds and maintains Godot + rosa game projects. Published publicly as RosaCli on nuget.org (the rosa libs themselves stay on the private GitHub feed).

dnx rosacli                     # run once, no install
dotnet tool install -g RosaCli  # or install as `rosa`

Commands

  • dnx rosacli init [Name] — scaffold a project in the current directory (empty or Godot-created). Name is the RosaRootNamespace; defaults to the PascalCased directory name (my_game → MyGame).
  • dnx rosacli lib <name> [--fs] — seed a C# (or F#) lib subproject wired to the machinery: namespace GameNs.LibName, its own RosaModules menu, added to the sln; paste the printed ProjectReference into the game csproj.
  • dnx rosacli sync [version] — rewrite the rosa-owned files to the current tool's templates and stamp RosaVersion (default: latest stable on the feed; offline keeps the currently stamped version). Run after updating the tool.
  • dnx rosacli local [on|off] [path] — build against a local rosa checkout (default ../rosa) instead of the feed. Writes the gitignored Directory.Build.local.props (no file means off) and maintains .vscode/{name}.local.sln — pick that solution in the IDE while local is on and rosa loads as source (live cross-repo IntelliSense, go-to-def, find-refs). Both commands finish with a restore + project-file touch so language servers re-crack without a window reload.

The contract

Owned (rewritten by every init/sync — never edit): rosa.godot.props, rosa.godot.targets, Directory.Build.props, Directory.Build.targets, .editorconfig, nuget.config, .gitattributes, .gitignore, .vscode/*, .config/dotnet-tools.json, .config/mise/config.toml.

Seeded (written once, then yours): {name}.csproj, {name}.sln, Directory.Packages.props, project.godot, src/*, and everything rosa lib creates.

Versions are centrally managed (CPM): projects hold versionless PackageReferences; game package versions live in the seeded Directory.Packages.props, while the single rosa pin is the RosaVersion stamped into owned rosa.godot.props by sync.

Tools (mise)

mise is the per-repo tool manager: it pins the tools and exports the env. The owned .config/mise/config.toml holds the pins — the .NET SDK, bud (the content build, installed straight from rosa-rs's private release assets), this tool, the Godot version, GODOT for .vscode/launch.json, and the private feed's credential built from gh — plus a postinstall hook that runs dotnet tool restore for csharpier and fantomas. Sync rewrites it, so put your own tools and env in mise.toml at the repo root and per-machine values (a different Godot path) in the gitignored mise.local.toml; both load after the owned file and win. init runs mise trust && mise install itself; sync says when the pins moved so you can rerun it.

direnv and .envrc are gone — mise's [env] replaces them, and sync no longer writes the file (delete a leftover .envrc by hand).

Fresh machine, in order:

  1. Install Godot (mono/.NET build) into /Applications — it stays a hand-installed app, and GODOT_VERSION in the mise config says which one the repo expects.
  2. Install mise and activate it in your shell.
  3. gh auth login — one login covers the private NuGet feed and bud's release assets. Then, once per machine, mise settings set github.credential_command "gh auth token" — mise reads that login for bud's private release; a project config may not set it, and gh keeps the token in the keychain where mise's own lookup does not find it.
  4. rosa init in a new directory, or clone the repo and rosa sync; then mise trust && mise install.
  5. dotnet build.

Modules

Each project file holds only decisions:

<Project Sdk="Godot.NET.Sdk/4.7.0">
  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <RosaRootNamespace>Poplar</RosaRootNamespace>
    <RosaModules>
      Utils
      
      ...commented menu, uncomment to opt in...
    </RosaModules>
  </PropertyGroup>
</Project>

rosa.godot.targets expands RosaModules by convention — Godot.Grove → Rosa.Cs.Godot.Grove (feed) or $(RosaLocalPath)/cs/godot/grove/grove.csproj (local), Fs.Utils → Rosa.Fs.Utils / fs/utils/utils.fsproj — so new rosa modules need no CLI release, and a typo'd module fails the build instead of silently doing nothing. In local mode every sibling project of a module (<name>.gen, <name>.fix, …, <name>.tests excepted) is picked up as a Roslyn analyzer; the packages bundle the same assemblies themselves.

Current menu: Utils, Grove, Star, Random, Godot.Clock, Godot.R3, Godot.Grove, Godot.Star, Godot.Input, Godot.Validation, Fs.Utils, Fs.Random, Fs.Interop. C# and F# modules mix freely.

Conventions (enforced at build)

  • Code lives under src/; folders are snake_case; files are snake_case (C# may also be PascalCase). Folders never start with _ or +.
  • Namespace = RosaRootNamespace + ._Pascal per path segment: src/game/enemy_ai/brain.cs → Game._Game._EnemyAi._Brain.
  • A _-prefixed file is the folder's own module — its final bit is the literal _Mod (src/core/_def.fs → Game._Core._Mod); mod/_mod names are reserved.
  • C# is checked by the Godot.Validation analyzer, F# by an inline task in rosa.godot.targets — same RGV0008–0013 codes (escape hatch: <RosaSkipFsNamespaceCheck>true</RosaSkipFsNamespaceCheck>).
  • F# compile order comes from +order manifests (root src/+order): one name per line, @folder recurses into folder/+order, # comments; _def.fs is auto-included first and _api.fs last in every folder — never list them. Builds write the expansion to the gitignored obj/order.g.props and bump the fsproj mtime when it changed, so IDEs re-crack automatically: edit +order, build, done — no window reloads, no committed-file churn. The running build always compiles the fresh list, so the generated file is never load-bearing.

Libs

Libs are ordinary subprojects riding the same game-root machinery, with their own RosaRootNamespace (e.g. Poplar.Engine) and RosaModules. F# libs get a seeded src/+order instead of a hand-kept <Compile> list, and reference FSharp.Core explicitly — CPM suppresses the F# SDK's implicit reference, and without it C# consumers can't see F# types. GodotSharp is referenced versionless; the version is centrally pinned for non-Godot-Sdk projects.

Releasing

Tag vX.Y.Z + publish a GitHub release → CI packs and pushes to nuget.org via trusted publishing (OIDC — no stored API key). Requires a trusted publishing policy on nuget.org (username → Trusted Publishing: repo owner orcharddweller, repo rosa-cli, workflow file publish.yml) and the correct user: in the workflow's NuGet login step. Bump Feed.DefaultRosaVersion when rosa releases and Feed.DefaultBudVersion when bud does, so the offline fallbacks stay fresh — both versions are otherwise resolved live (the feed for rosa, rosa-rs's latest release for bud). Feed.DefaultCliVersion is the same fallback for this tool's own pin, used only by unpacked dev builds, whose assembly carries the SDK's placeholder version.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated
0.8.1 98 9/12/2026
0.8.0 85 9/12/2026
0.7.0 92 9/2/2026
0.6.1 104 8/25/2026
0.6.0 104 8/22/2026
0.5.1 133 7/22/2026
0.5.0 111 7/21/2026
0.4.1 112 7/21/2026
0.4.0 106 7/18/2026
0.3.0 114 7/16/2026
0.2.0 106 7/16/2026
0.1.5 115 7/14/2026
0.1.4 108 7/14/2026
0.1.3 119 7/14/2026
0.1.2 111 7/14/2026