Product shape
NuvyntraLabs.Nuvyn.Cli is a global dotnet tool (PackAsTool, command nuvyn) on net10.0. Version 1.2.0. MIT. The CLI is a standalone product — it must not ProjectReference MauiEssentials hub modules. Runtime dependencies are System.CommandLine and Spectre.Console only.
nuvyn init adds Nuvyntra packages to the user's app from nuget.org, unpinned (latest stable). Do not dotnet add package NuvyntraLabs.Nuvyn.Cli into an app. Publishing is pipeline-only — never dotnet nuget push from a local clone. nuget.org uses the Actions secret NUGET_KEY_NUVYN; GitHub Packages uses GITHUB_TOKEN.
nuvyn init <folder>— create a new project only.nuvyn adopt— attach the slash chain to an existing MAUI app (workflow files only).nuvyn update— refresh templates, reference, and slash files on an existing Nuvyn app.nuvyn version— print the tool version.nuvyn check— confirmdotnetand the payload; greenfield HostProof; adopt prints inventory and skips HostProof; then composemaui-dev doctor.nuvyn --no-update-check— skip the 4-hour nuget.org update prompt (or setNUVYNTRA_NO_UPDATE_CHECK=1).nuvyn --help— usage.
Repository layout
Nuvyn/
├── payload/
│ ├── host/ # Three-project MAUI host (MauiApp1 token)
│ ├── commands/ # constitution.md … converge.md
│ └── nuvyn/ # constitution, templates, reference
├── src/NuvyntraLabs.Nuvyn.Cli/
│ ├── Commands/ # Init, Version, Check
│ ├── Scaffolding/ # Host, packages, agent files
│ ├── Agents/ # Spec Kit coding-agent set
│ ├── Workflow/ # Slash ids + handoffs
│ └── Infrastructure/ # PayloadRoot
└── tests/NuvyntraLabs.Nuvyn.Cli.Tests/The tool copies payload/ into the new folder. Command bodies stay in payload/commands/. Standing law and templates stay in payload/nuvyn/. The MAUI host stays in payload/host/ — not stock dotnet new maui pages.
Init pipeline
InitCommand is the only write path. It always creates a new directory. There is no --here / --force. If the name exists as a file or folder, init prints an error and exits 1 without touching the tree.
- Validate
project_name: starts with a letter; letters, digits,.,_,-; max 64 characters. - Resolve
--agentfrom the Spec Kit set (cursor,copilot,claude,gemini,codex,windsurf, …). Searchable picker when omitted; default Cursor when non-interactive. - Create the folder. Resolve
PayloadRoot(embedded payload next to the tool). HostScaffolder.Scaffold— copypayload/host/, thendotnet adddefault packages, then patchMauiProgram.PayloadInstaller— write.nuvyn/(constitution, templates, reference,init-options.json).AgentInstaller— wrap each command body for the selected agent.ProjectReadme.Write— print the slash chain.
Host fallback if the embedded copy is missing: dotnet new mvvmexpress and overlay the same UIKit MainPage; then stock dotnet new maui; then write HOST.md and still install workflow files. --skip-host is hidden and used in tests.
Host and default packages
The host is a three-project tree. MainPage is Lumina UIKit: Nuvyntra hexagon logo (nuvyntra.png, also app icon and splash), NVHeading counter, NVButton Increase / Decrease. No stock Entry / Button / Label. No Login / Items / Edit seed pages.
ClinicApp/
├── ClinicApp.sln
├── ClinicApp/ # MAUI app — MauiProgram, Pages/MainPage.xaml
├── ClinicApp.Core/ # ViewModels
└── ClinicApp.Tests/DefaultHostPackages splits by project. The MAUI app gets MVVMExpress + Dialogs + Navigation, UIKit, HttpForge, FormValidation, and KeyboardManager. Core gets Plugin.Maui.MVVMExpress.Core and the source generators. Tests get Plugin.Maui.MVVMExpress.Testing. Versions are never pinned — dotnet add package without --version.
builder
.UseMauiApp<App>()
.UseMvvmExpress(o => o
.UseNavigationPage((nav, _) => nav
.Map<MainPageViewModel, MainPage>("main"))
.UseDialogs())
.UseNuvyntraUIKit()
.UseHttpForge()
.UseMauiFormValidation()
.UseKeyboardManager();
builder.Services.AddTransient<MainPageViewModel>();
builder.Services.AddTransient<MainPage>();Agent installers
AgentInstaller reads payload/commands/<id>.md and writes one file per slash command into the folder that agent already reads (same destinations Spec Kit uses). Cursor, Copilot, and Codex-style agents use skill folders (nuvyn-constitution — a folder name cannot contain .). Claude writes .claude/commands/nuvyn.<id>.md. Gemini writes .gemini/commands/nuvyn.<id>.toml. Goose writes .goose/recipes/nuvyn.<id>.yaml.
| Agent | --agent | On disk |
|---|---|---|
| Cursor | cursor | .cursor/skills/nuvyn-*/ |
| GitHub Copilot | copilot | .github/skills/ |
| Claude Code | claude | .claude/commands/ |
| Gemini CLI | gemini | .gemini/commands/ |
| Codex CLI | codex | .agents/skills/ |
| Goose | goose | .goose/recipes/ |
| Windsurf | windsurf | .windsurf/workflows/ |
| Generic | generic | .agents/commands/ |
Also: agy, alquimia, amp, auggie, bob, cline, codebuddy, command-code, cursor-agent, devin, docker-agent, droid, dsh, firebender, forge, grok, hermes, iflow, junie, kilocode, kimi, kiro-cli (kiro), lingma, muse, omp, opencode, pi, qodercli, qwen, roo, rovodev, shai, tabnine, trae, vibe, zcode, zed. Pass --agent cursor-agent if you already use that Spec Kit key.
Wrappers add YAML front matter (name, description, handoffs), a Gemini TOML prompt, or Goose YAML. Handoffs come from NuvynCommands.Handoffs: constitution → specify → clarify / plan → checklist / task → analysis / implement → converge → implement again.
Later: --vertical only after one Lumina Playground head regenerates without hand-edits; GitHub issue export. Coding agents already match Spec Kit.
CI and safety rails
Publishing order on the Nuvyn repository: version alignment → NuGet key + unpublished version → unit tests → pack (net10.0, PackAsTool nupkg only) → nuget.org and GitHub Packages.
- Never overlay an existing app with
init.adoptwrites workflow files only. - Never add LocalStore, NuvexaDB, AppLock, or other catalog packages until the user asks.
- Never restore fail-open DeepLinks / PushRouter / SmartUpload / FeatureFlags defaults.
- Never
dotnet nuget pushfrom a local clone. init/adopt/checkcompose maui-dev doctor--pathwhen MauiDev is on PATH — they do not forward--no-update-check.
Implementation lives in Source on GitHub