ivy-deploy-to-desktop
Deploy an Ivy project as a standalone desktop application using Ivy.Desktop.
Pre-flight: Read Learnings
If the file .ivy/learnings/ivy-deploy-to-desktop.md exists in the project directory, read it first and apply any lessons learned from previous runs of this skill.
Reference Files
Read before implementing:
- references/AGENTS.md -- Ivy framework API reference (widgets, hooks, layouts, inputs, colors)
Workflow
Verify the project -- Confirm the working directory is a valid Ivy project and that it builds successfully with dotnet build. If it does not build, stop and ask the user to fix build errors first.
Determine the project namespace -- Find the root namespace from the .csproj file or existing source files.
Scaffold the desktop project -- Create a desktop wrapper project under .ivy/publish/[Namespace].Desktop/. This is a separate .NET project that references the main Ivy project and adds the Ivy.Desktop package.
Generate Program.cs -- Write a Program.cs for the desktop wrapper following the rules in the generation guide below.
Publish the application -- Run dotnet publish -c Release on the desktop project to produce a self-contained executable.
Copy to desktop -- Place the published executable on the user's desktop so it is ready to run.
Step 4: Generating Program.cs
Write a Program.cs for the desktop project ([Namespace].Desktop) at .ivy/publish/[Namespace].Desktop/Program.cs.
Before generating, read the original web project's Program.cs and list the files in the project's Apps/ directory.
The generated Program.cs must:
- Use
Ivy and Ivy.Desktop namespaces.
- Create a
new Server(new ServerArgs { Silent = true }).
- Assembly references -- For
AddAppsFromAssembly and AddConnectionsFromAssembly, you MUST pass an explicit assembly reference because the entry assembly in the desktop project is different from the main app assembly. Find a class from the original project (e.g., an [App] class) and use typeof(ThatClass).Assembly as the argument:var targetAssembly = typeof(MyNamespace.Apps.SomeAppClass).Assembly;
server.AddAppsFromAssembly(targetAssembly);
server.AddConnectionsFromAssembly(targetAssembly);
- Preserve any other service registrations from the original (e.g.
server.UseCulture(...), any server.Add* calls).
- Chrome handling:
- Count the number of apps in the
Apps/ directory.
- If there are multiple apps, preserve the chrome configuration (e.g.
UseAppShell) in the desktop version so users can navigate between apps via the sidebar.
- If there is only a single app, do NOT add
UseAppShell. Use server.UseDefaultApp(typeof(TheApp)) instead. Single-app desktop applications should not have a sidebar.
- Window sizing -- Choose appropriate
.Size(width, height) values for the DesktopWindow based on the apps found in Apps/:
- Multi-app projects with chrome/sidebar:
1280, 800 or larger
- Single-app dashboards or data-heavy apps:
1200, 800
- Single-app form/tool apps (calculators, converters, simple utilities):
800, 600
- Single-app narrow/focused apps (chat, single-column):
500, 700
- When unsure, default to
1024, 768
- Replace the web server startup with:
return new DesktopWindow(server)
.Title("[AppTitle]")
.Size(WIDTH, HEIGHT) // Use the dimensions chosen in step 6
.Run();
- Do NOT include any web host building,
app.Run(), builder.Build(), Kestrel, or HTTP pipeline code.
CRITICAL: Write ONLY to .ivy/publish/[Namespace].Desktop/Program.cs. Do NOT create any files in the main project directory. Do NOT create a .Desktop subfolder in the main project. The desktop project lives under .ivy/publish/[Namespace].Desktop/ -- all desktop files must go there.
Output ONLY raw C# code, no markdown fences or explanation.
Troubleshooting
If the publish step fails:
- Ensure the project builds successfully with
dotnet build.
- Check that the Ivy.Desktop NuGet package is available.
- Verify you have the .NET 10 SDK installed.
- If the error mentions "Ambiguous project name", create a
Directory.Build.props in the desktop project directory with content <Project></Project> to isolate the project from the parent directory tree.
Recovery Steps
Diagnose using the troubleshooting steps above to identify the root cause.
After fixing the underlying issue, choose ONE of these approaches:
Option A: Retry from scratch (recommended for transient failures like NuGet package issues or temporary build failures) -- re-run the full workflow from step 1.
Option B: Manual desktop publish (recommended for persistent workflow failures):
- Run
dotnet publish -c Release -r <rid> (e.g., -r win-x64, -r osx-arm64, -r linux-x64)
- Locate the published executable in
bin/Release/net10.0/{rid}/publish/
- Copy the executable to the user's desktop (see "Desktop Copy" below)
Use ivy docs to find deployment patterns: "How do I publish an Ivy app as a desktop application?"
Do NOT skip the desktop copy step -- the executable must be accessible on the desktop for the user.
Desktop Copy
If you recover manually, you MUST copy the published executable to the user's desktop:
- Publish location:
bin/Release/net10.0/{rid}/publish/
- Desktop folder: Use the system desktop path (e.g.,
C:\Users\{user}\Desktop\)
- Copy the
.exe file (Windows) or the binary (macOS/Linux) to the desktop
Completion
When the publish succeeds, inform the user:
- The application name
- The output location (on their desktop)
- That it is ready to run
Post-run: Evaluate and Improve
After completing the task:
- Evaluate: Did the build succeed? Were there compilation errors, unexpected behavior, or manual corrections needed during this run?
- Update learnings: If anything required correction or was surprising, append a concise entry to
.ivy/learnings/ivy-deploy-to-desktop.md (create the file and .ivy/learnings/ directory if they don't exist). Each entry should note: the date, what went wrong, why, and what to do differently next time.
- Skip if clean: If everything succeeded without issues, do not update the learnings file.
1---2name: ivy-deploy-to-desktop3description: Deploy an Ivy project as a standalone desktop application. Use when the user asks to publish, deploy, package, or export their Ivy app as a desktop app, native app, executable, or .exe. Scaffolds a desktop wrapper project using Ivy.Desktop, generates a Program.cs, publishes with dotnet, and copies the executable to the user's desktop.4---56# ivy-deploy-to-desktop78Deploy an Ivy project as a standalone desktop application using Ivy.Desktop.910## Pre-flight: Read Learnings1112If the file `.ivy/learnings/ivy-deploy-to-desktop.md` exists in the project directory, read it first and apply any lessons learned from previous runs of this skill.1314## Reference Files1516Read before implementing:17- [references/AGENTS.md](references/AGENTS.md) -- Ivy framework API reference (widgets, hooks, layouts, inputs, colors)1819## Workflow20211. **Verify the project** -- Confirm the working directory is a valid Ivy project and that it builds successfully with `dotnet build`. If it does not build, stop and ask the user to fix build errors first.22232. **Determine the project namespace** -- Find the root namespace from the `.csproj` file or existing source files.24253. **Scaffold the desktop project** -- Create a desktop wrapper project under `.ivy/publish/[Namespace].Desktop/`. This is a separate .NET project that references the main Ivy project and adds the Ivy.Desktop package.26274. **Generate Program.cs** -- Write a `Program.cs` for the desktop wrapper following the rules in the generation guide below.28295. **Publish the application** -- Run `dotnet publish -c Release` on the desktop project to produce a self-contained executable.30316. **Copy to desktop** -- Place the published executable on the user's desktop so it is ready to run.3233## Step 4: Generating Program.cs3435Write a `Program.cs` for the desktop project (`[Namespace].Desktop`) at `.ivy/publish/[Namespace].Desktop/Program.cs`.3637Before generating, read the original web project's `Program.cs` and list the files in the project's `Apps/` directory.3839The generated Program.cs must:40411. Use `Ivy` and `Ivy.Desktop` namespaces.422. Create a `new Server(new ServerArgs { Silent = true })`.433. **Assembly references** -- For `AddAppsFromAssembly` and `AddConnectionsFromAssembly`, you MUST pass an explicit assembly reference because the entry assembly in the desktop project is different from the main app assembly. Find a class from the original project (e.g., an `[App]` class) and use `typeof(ThatClass).Assembly` as the argument:44 ```csharp45 var targetAssembly = typeof(MyNamespace.Apps.SomeAppClass).Assembly;46 server.AddAppsFromAssembly(targetAssembly);47 server.AddConnectionsFromAssembly(targetAssembly);48 ```494. Preserve any other service registrations from the original (e.g. `server.UseCulture(...)`, any `server.Add*` calls).505. **Chrome handling:**51 - Count the number of apps in the `Apps/` directory.52 - If there are **multiple apps**, preserve the chrome configuration (e.g. `UseAppShell`) in the desktop version so users can navigate between apps via the sidebar.53 - If there is only a **single app**, do NOT add `UseAppShell`. Use `server.UseDefaultApp(typeof(TheApp))` instead. Single-app desktop applications should not have a sidebar.546. **Window sizing** -- Choose appropriate `.Size(width, height)` values for the `DesktopWindow` based on the apps found in `Apps/`:55 - Multi-app projects with chrome/sidebar: `1280, 800` or larger56 - Single-app dashboards or data-heavy apps: `1200, 800`57 - Single-app form/tool apps (calculators, converters, simple utilities): `800, 600`58 - Single-app narrow/focused apps (chat, single-column): `500, 700`59 - When unsure, default to `1024, 768`607. Replace the web server startup with:61 ```csharp62 return new DesktopWindow(server)63 .Title("[AppTitle]")64 .Size(WIDTH, HEIGHT) // Use the dimensions chosen in step 665 .Run();66 ```678. Do NOT include any web host building, `app.Run()`, `builder.Build()`, Kestrel, or HTTP pipeline code.6869**CRITICAL:** Write ONLY to `.ivy/publish/[Namespace].Desktop/Program.cs`. Do NOT create any files in the main project directory. Do NOT create a `.Desktop` subfolder in the main project. The desktop project lives under `.ivy/publish/[Namespace].Desktop/` -- all desktop files must go there.7071Output ONLY raw C# code, no markdown fences or explanation.7273## Troubleshooting7475If the publish step fails:76771. Ensure the project builds successfully with `dotnet build`.782. Check that the Ivy.Desktop NuGet package is available.793. Verify you have the .NET 10 SDK installed.804. If the error mentions "Ambiguous project name", create a `Directory.Build.props` in the desktop project directory with content `<Project></Project>` to isolate the project from the parent directory tree.8182### Recovery Steps83841. Diagnose using the troubleshooting steps above to identify the root cause.85862. After fixing the underlying issue, choose ONE of these approaches:8788 **Option A: Retry from scratch** (recommended for transient failures like NuGet package issues or temporary build failures) -- re-run the full workflow from step 1.8990 **Option B: Manual desktop publish** (recommended for persistent workflow failures):91 - Run `dotnet publish -c Release -r <rid>` (e.g., `-r win-x64`, `-r osx-arm64`, `-r linux-x64`)92 - Locate the published executable in `bin/Release/net10.0/{rid}/publish/`93 - Copy the executable to the user's desktop (see "Desktop Copy" below)9495 Use `ivy docs` to find deployment patterns: "How do I publish an Ivy app as a desktop application?"96973. Do NOT skip the desktop copy step -- the executable must be accessible on the desktop for the user.9899### Desktop Copy100101If you recover manually, you MUST copy the published executable to the user's desktop:102- Publish location: `bin/Release/net10.0/{rid}/publish/`103- Desktop folder: Use the system desktop path (e.g., `C:\Users\{user}\Desktop\`)104- Copy the `.exe` file (Windows) or the binary (macOS/Linux) to the desktop105106## Completion107108When the publish succeeds, inform the user:109- The application name110- The output location (on their desktop)111- That it is ready to run112113## Post-run: Evaluate and Improve114115After completing the task:1161171. **Evaluate**: Did the build succeed? Were there compilation errors, unexpected behavior, or manual corrections needed during this run?1182. **Update learnings**: If anything required correction or was surprising, append a concise entry to `.ivy/learnings/ivy-deploy-to-desktop.md` (create the file and `.ivy/learnings/` directory if they don't exist). Each entry should note: the date, what went wrong, why, and what to do differently next time.1193. **Skip if clean**: If everything succeeded without issues, do not update the learnings file.