Skip to content
Nuvyntra Labs

Technical documentation

Technical implementation

PackAsTool CLI, payload host, init pipeline, default packages, agent wrappers, and pipeline-only publish.

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 — confirm dotnet and the payload; greenfield HostProof; adopt prints inventory and skips HostProof; then compose maui-dev doctor.
  • nuvyn --no-update-check — skip the 4-hour nuget.org update prompt (or set NUVYNTRA_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.

  1. Validate project_name: starts with a letter; letters, digits, ., _, -; max 64 characters.
  2. Resolve --agent from the Spec Kit set (cursor, copilot, claude, gemini, codex, windsurf, …). Searchable picker when omitted; default Cursor when non-interactive.
  3. Create the folder. Resolve PayloadRoot (embedded payload next to the tool).
  4. HostScaffolder.Scaffold — copy payload/host/, then dotnet add default packages, then patch MauiProgram.
  5. PayloadInstaller — write .nuvyn/ (constitution, templates, reference, init-options.json).
  6. AgentInstaller — wrap each command body for the selected agent.
  7. 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 pinneddotnet 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--agentOn disk
Cursorcursor.cursor/skills/nuvyn-*/
GitHub Copilotcopilot.github/skills/
Claude Codeclaude.claude/commands/
Gemini CLIgemini.gemini/commands/
Codex CLIcodex.agents/skills/
Goosegoose.goose/recipes/
Windsurfwindsurf.windsurf/workflows/
Genericgeneric.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. adopt writes 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 push from a local clone.
  • init / adopt / check compose maui-dev doctor --path when MauiDev is on PATH — they do not forward --no-update-check.

Implementation lives in Source on GitHub

Discussion

Comment on Nuvyn. The thread lives on this component's GitHub repository (nuvyntralabs/Nuvyn). Sign in with GitHub — Giscus uses Discussions, Utterances uses Issues.