Add .NET tool support and update docs and CI
keypair34 committed
May 3, 2026 at 10:38 UTC
2466ccfdd517df4ed9ece35919fae664bcdf9d7a
11 files changed
+553
-5
.github/workflows/ci.yml
+22
-5
@@ -108,6 +108,21 @@ jobs:
108
GRESIQ_API_SECRET: ${{ secrets.GRESIQ_API_SECRET }}
109
HF_TOKEN: ${{ secrets.HF_TOKEN }}
110
111
+ dotnet-tool:
112
+ name: .NET tool launcher build
113
+ runs-on: ubuntu-latest
114
+ steps:
115
+ - name: Checkout
116
+ uses: actions/checkout@v6
117
+
118
+ - name: Setup .NET SDK
119
+ uses: actions/setup-dotnet@v4
120
+ with:
121
+ dotnet-version: 8.0.x
122
+
123
+ - name: Build .NET tool launcher
124
+ run: dotnet build nuget/onde-cli/Onde.Cli.csproj --configuration Release
125
+
126
build:
127
name: Build (aarch64-apple-darwin)
128
runs-on: macos-26
@@ -140,13 +155,15 @@ jobs:
155
- clippy
156
- test
157
- check
158
+ - dotnet-tool
159
- build
160
if: always()
161
steps:
162
- name: Verify all required jobs succeeded
163
run: |
148
- test "${{ needs.fmt.result }}" = "success"
149
- test "${{ needs.clippy.result }}" = "success"
150
- test "${{ needs.test.result }}" = "success"
151
- test "${{ needs.check.result }}" = "success"
152
- test "${{ needs.build.result }}" = "success"
164
+ test "${{ needs.fmt.result }}" = "success"
165
+ test "${{ needs.clippy.result }}" = "success"
166
+ test "${{ needs.test.result }}" = "success"
167
+ test "${{ needs.check.result }}" = "success"
168
+ test "${{ needs.dotnet-tool.result }}" = "success"
169
+ test "${{ needs.build.result }}" = "success"
.github/workflows/release-nuget.yml
new
+305
@@ -0,0 +1,305 @@
1
+name: NuGet Release
2
+
3
+on:
4
+ push:
5
+ tags:
6
+ - "v*.*.*"
7
+ workflow_dispatch:
8
+ inputs:
9
+ tag:
10
+ description: "Release tag (e.g. v0.3.0)"
11
+ required: true
12
+
13
+permissions:
14
+ contents: read
15
+
16
+env:
17
+ CARGO_TERM_COLOR: always
18
+ DOTNET_VERSION: 8.0.x
19
+ NUGET_PACKAGE_ID: Onde.Cli
20
+ ONDE_APP_ID: ${{ secrets.ONDE_APP_ID }}
21
+ ONDE_APP_SECRET: ${{ secrets.ONDE_APP_SECRET }}
22
+ GRESIQ_API_KEY: ${{ secrets.GRESIQ_API_KEY }}
23
+ GRESIQ_API_SECRET: ${{ secrets.GRESIQ_API_SECRET }}
24
+ HF_TOKEN: ${{ secrets.HF_TOKEN }}
25
+
26
+jobs:
27
+ build-native-binaries:
28
+ name: Build native binary (${{ matrix.build.NAME }})
29
+ runs-on: ${{ matrix.build.OS }}
30
+ strategy:
31
+ fail-fast: false
32
+ matrix:
33
+ build:
34
+ - {
35
+ NAME: linux-x64,
36
+ OS: ubuntu-latest,
37
+ TARGET: x86_64-unknown-linux-gnu,
38
+ }
39
+ - {
40
+ NAME: linux-arm64,
41
+ OS: ubuntu-24.04-arm,
42
+ TARGET: aarch64-unknown-linux-gnu,
43
+ }
44
+ - {
45
+ NAME: windows-x64,
46
+ OS: windows-2022,
47
+ TARGET: x86_64-pc-windows-msvc,
48
+ }
49
+ - {
50
+ NAME: windows-arm64,
51
+ OS: windows-2022,
52
+ TARGET: aarch64-pc-windows-msvc,
53
+ }
54
+ - {
55
+ NAME: darwin-x64,
56
+ OS: macos-26-intel,
57
+ TARGET: x86_64-apple-darwin,
58
+ }
59
+ - { NAME: darwin-arm64, OS: macos-26, TARGET: aarch64-apple-darwin }
60
+ steps:
61
+ - name: Checkout
62
+ uses: actions/checkout@v6
63
+ with:
64
+ ref: ${{ github.event.inputs.tag || github.ref }}
65
+
66
+ - name: Set the release version
67
+ shell: bash
68
+ run: |
69
+ if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
70
+ release_version="${GITHUB_REF_NAME#v}"
71
+ else
72
+ release_version="${{ github.event.inputs.tag }}"
73
+ release_version="${release_version#v}"
74
+ fi
75
+
76
+ echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
77
+
78
+ - name: Read Rust toolchain
79
+ shell: bash
80
+ run: |
81
+ rust_toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml | head -n 1)"
82
+ if [ -z "$rust_toolchain" ]; then
83
+ echo "Failed to read Rust toolchain from rust-toolchain.toml" >&2
84
+ exit 1
85
+ fi
86
+
87
+ echo "RUST_TOOLCHAIN=${rust_toolchain}" >> "$GITHUB_ENV"
88
+
89
+ - name: Install Rust toolchain
90
+ uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
91
+ with:
92
+ toolchain: ${{ env.RUST_TOOLCHAIN }}
93
+ targets: ${{ matrix.build.TARGET }}
94
+
95
+ - name: Setup Rust cache
96
+ uses: Swatinem/rust-cache@v2
97
+ with:
98
+ key: nuget-${{ matrix.build.TARGET }}
99
+
100
+ - name: Build binary
101
+ shell: bash
102
+ run: cargo build --locked --release --target ${{ matrix.build.TARGET }}
103
+
104
+ - name: Prepare artifact
105
+ shell: bash
106
+ run: |
107
+ executable_name="onde"
108
+ if [[ "${{ matrix.build.OS }}" == "windows-2022" ]]; then
109
+ executable_name="onde.exe"
110
+ fi
111
+
112
+ mkdir -p "nuget-artifacts/native/${{ matrix.build.NAME }}"
113
+ cp "target/${{ matrix.build.TARGET }}/release/${executable_name}" "nuget-artifacts/native/${{ matrix.build.NAME }}/${executable_name}"
114
+
115
+ - name: Upload native artifact
116
+ uses: actions/upload-artifact@v4
117
+ with:
118
+ name: nuget-native-${{ matrix.build.NAME }}
119
+ path: nuget-artifacts/native
120
+
121
+ pack-nuget:
122
+ name: Pack NuGet .NET tool
123
+ runs-on: ubuntu-latest
124
+ needs: build-native-binaries
125
+ steps:
126
+ - name: Checkout
127
+ uses: actions/checkout@v6
128
+ with:
129
+ ref: ${{ github.event.inputs.tag || github.ref }}
130
+
131
+ - name: Set the release version
132
+ shell: bash
133
+ run: |
134
+ if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
135
+ release_version="${GITHUB_REF_NAME#v}"
136
+ else
137
+ release_version="${{ github.event.inputs.tag }}"
138
+ release_version="${release_version#v}"
139
+ fi
140
+
141
+ echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
142
+
143
+ - name: Download native artifacts
144
+ uses: actions/download-artifact@v4
145
+ with:
146
+ pattern: nuget-native-*
147
+ path: nuget/onde-cli/native
148
+ merge-multiple: true
149
+
150
+ - name: Setup .NET SDK
151
+ uses: actions/setup-dotnet@v4
152
+ with:
153
+ dotnet-version: ${{ env.DOTNET_VERSION }}
154
+
155
+ - name: Pack .NET tool
156
+ shell: bash
157
+ run: |
158
+ dotnet pack nuget/onde-cli/Onde.Cli.csproj \
159
+ --configuration Release \
160
+ --output nuget/dist \
161
+ -p:PackageVersion=${RELEASE_VERSION}
162
+
163
+ - name: Upload package artifact
164
+ uses: actions/upload-artifact@v4
165
+ with:
166
+ name: nuget-package
167
+ path: nuget/dist/*.nupkg
168
+
169
+ smoke-test:
170
+ name: Smoke test (${{ matrix.os }})
171
+ runs-on: ${{ matrix.os }}
172
+ needs: pack-nuget
173
+ strategy:
174
+ fail-fast: false
175
+ matrix:
176
+ os:
177
+ - ubuntu-latest
178
+ - windows-2022
179
+ - macos-26
180
+ steps:
181
+ - name: Checkout
182
+ uses: actions/checkout@v6
183
+ with:
184
+ ref: ${{ github.event.inputs.tag || github.ref }}
185
+
186
+ - name: Set the release version
187
+ shell: bash
188
+ run: |
189
+ if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
190
+ release_version="${GITHUB_REF_NAME#v}"
191
+ else
192
+ release_version="${{ github.event.inputs.tag }}"
193
+ release_version="${release_version#v}"
194
+ fi
195
+
196
+ echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
197
+
198
+ - name: Download package artifact
199
+ uses: actions/download-artifact@v4
200
+ with:
201
+ name: nuget-package
202
+ path: nuget/dist
203
+
204
+ - name: Setup .NET SDK
205
+ uses: actions/setup-dotnet@v4
206
+ with:
207
+ dotnet-version: ${{ env.DOTNET_VERSION }}
208
+
209
+ - name: Install tool from local package
210
+ shell: pwsh
211
+ run: |
212
+ $packageSource = (Resolve-Path "nuget/dist").Path
213
+ @"
214
+ <?xml version="1.0" encoding="utf-8"?>
215
+ <configuration>
216
+ <packageSources>
217
+ <clear />
218
+ <add key="local" value="$packageSource" />
219
+ </packageSources>
220
+ </configuration>
221
+ "@ | Set-Content -Path "nuget/NuGet.Config"
222
+
223
+ dotnet tool install `
224
+ --tool-path ".tool" `
225
+ --configfile "nuget/NuGet.Config" `
226
+ --version "$env:RELEASE_VERSION" `
227
+ "$env:NUGET_PACKAGE_ID"
228
+
229
+ - name: Verify bundled native binary
230
+ shell: pwsh
231
+ run: |
232
+ $runtimeIdentifier = if ($IsWindows) {
233
+ if ([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture -eq [System.Runtime.InteropServices.Architecture]::Arm64) { "windows-arm64" } else { "windows-x64" }
234
+ } elseif ($IsMacOS) {
235
+ if ([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture -eq [System.Runtime.InteropServices.Architecture]::Arm64) { "darwin-arm64" } else { "darwin-x64" }
236
+ } else {
237
+ if ([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture -eq [System.Runtime.InteropServices.Architecture]::Arm64) { "linux-arm64" } else { "linux-x64" }
238
+ }
239
+
240
+ $binaryName = if ($IsWindows) { "onde.exe" } else { "onde" }
241
+ $nativeBinary = Get-ChildItem ".tool/.store" -Recurse -File | Where-Object {
242
+ $_.FullName -like "*native*${runtimeIdentifier}*${binaryName}"
243
+ } | Select-Object -First 1
244
+
245
+ if (-not $nativeBinary) {
246
+ Write-Error "Onde native binary for ${runtimeIdentifier} was not bundled in the installed .NET tool package."
247
+ }
248
+
249
+ Write-Host "Found bundled native binary at $($nativeBinary.FullName)"
250
+
251
+ publish-nuget:
252
+ name: Publish to NuGet
253
+ runs-on: ubuntu-latest
254
+ needs: smoke-test
255
+ steps:
256
+ - name: Checkout
257
+ uses: actions/checkout@v6
258
+ with:
259
+ ref: ${{ github.event.inputs.tag || github.ref }}
260
+
261
+ - name: Set the release version
262
+ shell: bash
263
+ run: |
264
+ if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
265
+ release_version="${GITHUB_REF_NAME#v}"
266
+ else
267
+ release_version="${{ github.event.inputs.tag }}"
268
+ release_version="${release_version#v}"
269
+ fi
270
+
271
+ echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
272
+
273
+ - name: Download package artifact
274
+ uses: actions/download-artifact@v4
275
+ with:
276
+ name: nuget-package
277
+ path: nuget/dist
278
+
279
+ - name: Setup .NET SDK
280
+ uses: actions/setup-dotnet@v4
281
+ with:
282
+ dotnet-version: ${{ env.DOTNET_VERSION }}
283
+
284
+ - name: Check whether release already exists on NuGet
285
+ id: nuget-check
286
+ shell: bash
287
+ run: |
288
+ package_index_url="https://api.nuget.org/v3-flatcontainer/onde.cli/index.json"
289
+ if curl -fsS "${package_index_url}" | grep -F "\"${RELEASE_VERSION}\"" >/dev/null; then
290
+ echo "${NUGET_PACKAGE_ID} ${RELEASE_VERSION} already exists on NuGet, skipping publish"
291
+ echo "exists=true" >> "$GITHUB_OUTPUT"
292
+ else
293
+ echo "exists=false" >> "$GITHUB_OUTPUT"
294
+ fi
295
+
296
+ - name: Publish package
297
+ if: steps.nuget-check.outputs.exists != 'true'
298
+ env:
299
+ NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
300
+ shell: bash
301
+ run: |
302
+ dotnet nuget push nuget/dist/*.nupkg \
303
+ --api-key "${NUGET_API_KEY}" \
304
+ --source https://api.nuget.org/v3/index.json \
305
+ --skip-duplicate
.gitignore
+10
@@ -1,3 +1,13 @@
1
/target
2
/pypi/dist
3
+
4
+# Local .NET CLI state
5
+/.dotnet/
6
+
7
+# Generated NuGet release artifacts
8
+/nuget/dist/
9
+/nuget/onde-cli/bin/
10
+/nuget/onde-cli/obj/
11
+/nuget/onde-cli/native/
12
+
13
.env
.nuget/NuGet/NuGet.Config
new
+6
@@ -0,0 +1,6 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<configuration>
3
+ <packageSources>
4
+ <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
5
+ </packageSources>
6
+</configuration>
\ No newline at end of file
README.md
+9
@@ -13,6 +13,7 @@
13
<a href="https://apps.apple.com/se/developer/splitfire-ab/id1831430993"><img src="https://img.shields.io/badge/App%20Store-live-235843?style=flat-square&labelColor=17211D" alt="App Store"></a>
14
<a href="https://www.npmjs.com/package/@ondeinference/cli"><img src="https://img.shields.io/npm/v/@ondeinference/cli?style=flat-square&labelColor=17211D&color=235843" alt="npm"></a>
15
<a href="https://pypi.org/project/onde-cli/"><img src="https://img.shields.io/pypi/v/onde-cli?style=flat-square&labelColor=17211D&color=235843" alt="PyPI"></a>
16
+ <a href="https://www.nuget.org/packages/Onde.Cli"><img src="https://img.shields.io/nuget/v/Onde.Cli?style=flat-square&labelColor=17211D&color=235843" alt="NuGet"></a>
17
<a href="https://crates.io/crates/onde-cli"><img src="https://img.shields.io/crates/v/onde-cli?style=flat-square&labelColor=17211D&color=235843" alt="Crates.io"></a>
18
</p>
19
@@ -52,6 +53,12 @@ uv run onde
53
uvx --from onde-cli onde
54
```
55
56
+### .NET tool
57
+
58
+```sh
59
+dotnet tool install --global Onde.Cli
60
+```
61
+
62
### Pre-built binary
63
64
Download a release from [GitHub Releases](https://github.com/ondeinference/onde-cli/releases):
@@ -97,6 +104,8 @@ This opens the TUI. You can sign up or sign in right there.
104
105
The flow is straightforward: download a safetensors base model, fine-tune it with LoRA, merge the adapter back into the base weights, then export to GGUF for use in the Onde SDK.
106
107
+If you want a quick refresher on what the model is actually doing at inference time, Onde has a short note on the [forward pass](https://ondeinference.com/forward-pass).
108
+
109
### Training data format
110
111
Each line should be one complete conversation in Qwen's chat template:
npm/onde-cli/README.md
+4
@@ -12,6 +12,7 @@
12
<a href="https://www.npmjs.com/package/@ondeinference/cli"><img src="https://img.shields.io/npm/v/@ondeinference/cli?style=flat-square&labelColor=17211D&color=235843" alt="npm"></a>
13
<a href="https://crates.io/crates/onde-cli"><img src="https://img.shields.io/crates/v/onde-cli?style=flat-square&labelColor=17211D&color=235843" alt="crates.io"></a>
14
<a href="https://pypi.org/project/onde-cli/"><img src="https://img.shields.io/pypi/v/onde-cli?style=flat-square&labelColor=17211D&color=235843" alt="PyPI"></a>
15
+ <a href="https://www.nuget.org/packages/Onde.Cli"><img src="https://img.shields.io/nuget/v/Onde.Cli?style=flat-square&labelColor=17211D&color=235843" alt="NuGet"></a>
16
<a href="https://ondeinference.com"><img src="https://img.shields.io/badge/ondeinference.com-235843?style=flat-square&labelColor=17211D" alt="Website"></a>
17
</p>
18
@@ -38,6 +39,7 @@ It works on:
39
| Homebrew | `brew install ondeinference/homebrew-tap/onde` |
40
| pip | `pip install onde-cli` |
41
| uv | `uv tool install onde-cli` |
42
+| .NET tool | `dotnet tool install --global Onde.Cli` |
43
| Cargo | `cargo install onde-cli` |
44
45
---
@@ -82,6 +84,8 @@ Training runs locally:
84
85
So yes, no cloud training setup and no Python environment to babysit.
86
87
+If you want a quick mental model for what the network is doing once it starts running, Onde has a short write-up on the [forward pass](https://ondeinference.com/forward-pass).
88
+
89
### Supported base models
90
91
| Model | Size |
nuget/.gitignore
new
+4
@@ -0,0 +1,4 @@
1
+dist/
2
+onde-cli/bin/
3
+onde-cli/obj/
4
+onde-cli/native/
nuget/onde-cli/Onde.Cli.csproj
new
+26
@@ -0,0 +1,26 @@
1
+<Project Sdk="Microsoft.NET.Sdk">
2
+ <PropertyGroup>
3
+ <OutputType>Exe</OutputType>
4
+ <TargetFramework>net8.0</TargetFramework>
5
+ <ImplicitUsings>enable</ImplicitUsings>
6
+ <Nullable>enable</Nullable>
7
+ <PackAsTool>true</PackAsTool>
8
+ <ToolCommandName>onde</ToolCommandName>
9
+ <PackageId>Onde.Cli</PackageId>
10
+ <PackageVersion>0.0.0-local</PackageVersion>
11
+ <Version>$(PackageVersion)</Version>
12
+ <Authors>Seto Elkahfi</Authors>
13
+ <Description>Onde Inference command line interface.</Description>
14
+ <PackageReadmeFile>README.md</PackageReadmeFile>
15
+ <PackageLicenseExpression>MIT OR Apache-2.0</PackageLicenseExpression>
16
+ <PackageProjectUrl>https://ondeinference.com</PackageProjectUrl>
17
+ <RepositoryUrl>https://github.com/ondeinference/onde-cli</RepositoryUrl>
18
+ <PackageTags>onde;onde-inference;cli;llm;ai;developer-tools;dotnet-tool</PackageTags>
19
+ <PublishRepositoryUrl>true</PublishRepositoryUrl>
20
+ </PropertyGroup>
21
+
22
+ <ItemGroup>
23
+ <None Include="README.md" Pack="true" PackagePath="" />
24
+ <Content Include="native/**/*" CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="PreserveNewest" Pack="false" Visible="false" />
25
+ </ItemGroup>
26
+</Project>
nuget/onde-cli/Program.cs
new
+109
@@ -0,0 +1,109 @@
1
+using System.ComponentModel;
2
+using System.Diagnostics;
3
+using System.Runtime.InteropServices;
4
+
5
+internal static class Program
6
+{
7
+ private const string CommandName = "onde";
8
+
9
+ public static async Task<int> Main(string[] arguments)
10
+ {
11
+ try
12
+ {
13
+ string executablePath = ResolveExecutablePath();
14
+ EnsureExecutablePermissions(executablePath);
15
+ return await RunAsync(executablePath, arguments);
16
+ }
17
+ catch (Exception exception) when (
18
+ exception is FileNotFoundException or
19
+ PlatformNotSupportedException or
20
+ Win32Exception)
21
+ {
22
+ Console.Error.WriteLine($"{CommandName}: {exception.Message}");
23
+ return 1;
24
+ }
25
+ }
26
+
27
+ private static string ResolveExecutablePath()
28
+ {
29
+ string runtimeIdentifier = GetRuntimeIdentifier();
30
+ string executableName = OperatingSystem.IsWindows() ? $"{CommandName}.exe" : CommandName;
31
+ string executablePath = Path.GetFullPath(
32
+ Path.Combine(AppContext.BaseDirectory, "native", runtimeIdentifier, executableName));
33
+
34
+ if (!File.Exists(executablePath))
35
+ {
36
+ throw new FileNotFoundException(
37
+ $"The native {CommandName} executable for '{runtimeIdentifier}' is not bundled in this package.",
38
+ executablePath);
39
+ }
40
+
41
+ return executablePath;
42
+ }
43
+
44
+ private static string GetRuntimeIdentifier()
45
+ {
46
+ string operatingSystem = OperatingSystem.IsWindows()
47
+ ? "windows"
48
+ : OperatingSystem.IsMacOS()
49
+ ? "darwin"
50
+ : OperatingSystem.IsLinux()
51
+ ? "linux"
52
+ : throw new PlatformNotSupportedException(
53
+ $"{CommandName} does not support this operating system through the .NET tool package.");
54
+
55
+ string architecture = RuntimeInformation.ProcessArchitecture switch
56
+ {
57
+ Architecture.X64 => "x64",
58
+ Architecture.Arm64 => "arm64",
59
+ _ => throw new PlatformNotSupportedException(
60
+ $"{CommandName} does not support the '{RuntimeInformation.ProcessArchitecture}' architecture through the .NET tool package."),
61
+ };
62
+
63
+ return $"{operatingSystem}-{architecture}";
64
+ }
65
+
66
+ private static void EnsureExecutablePermissions(string executablePath)
67
+ {
68
+ if (OperatingSystem.IsWindows())
69
+ {
70
+ return;
71
+ }
72
+
73
+ UnixFileMode currentMode = File.GetUnixFileMode(executablePath);
74
+ UnixFileMode requiredMode = UnixFileMode.UserRead |
75
+ UnixFileMode.UserWrite |
76
+ UnixFileMode.UserExecute |
77
+ UnixFileMode.GroupRead |
78
+ UnixFileMode.GroupExecute |
79
+ UnixFileMode.OtherRead |
80
+ UnixFileMode.OtherExecute;
81
+
82
+ if ((currentMode & requiredMode) == requiredMode)
83
+ {
84
+ return;
85
+ }
86
+
87
+ File.SetUnixFileMode(executablePath, currentMode | requiredMode);
88
+ }
89
+
90
+ private static async Task<int> RunAsync(string executablePath, IReadOnlyList<string> arguments)
91
+ {
92
+ ProcessStartInfo startInfo = new(executablePath)
93
+ {
94
+ UseShellExecute = false,
95
+ WorkingDirectory = Environment.CurrentDirectory,
96
+ };
97
+
98
+ foreach (string argument in arguments)
99
+ {
100
+ startInfo.ArgumentList.Add(argument);
101
+ }
102
+
103
+ using Process process = Process.Start(startInfo)
104
+ ?? throw new Win32Exception($"Failed to start '{CommandName}'.");
105
+
106
+ await process.WaitForExitAsync();
107
+ return process.ExitCode;
108
+ }
109
+}
nuget/onde-cli/README.md
new
+54
@@ -0,0 +1,54 @@
1
+# Onde CLI for .NET
2
+
3
+`onde` is the official command-line interface for [Onde Inference](https://ondeinference.com).
4
+
5
+## Install
6
+
7
+```sh
8
+dotnet tool install --global Onde.Cli
9
+```
10
+
11
+## Update
12
+
13
+```sh
14
+dotnet tool update --global Onde.Cli
15
+```
16
+
17
+## Run
18
+
19
+```sh
20
+onde
21
+```
22
+
23
+That opens the terminal UI for account management, app setup, and local model fine-tuning.
24
+
25
+If you want a quick background read on the inference side, Onde has a short note on the [forward pass](https://ondeinference.com/forward-pass).
26
+
27
+## Platform support
28
+
29
+This .NET tool bundles native `onde` binaries for:
30
+
31
+- macOS `arm64`, `x64`
32
+- Linux `arm64`, `x64` (glibc)
33
+- Windows `arm64`, `x64`
34
+
35
+## Other installation methods
36
+
37
+- npm: `npm install -g @ondeinference/cli`
38
+- pip: `pip install onde-cli`
39
+- Homebrew: `brew install ondeinference/homebrew-tap/onde`
40
+- GitHub Releases: <https://github.com/ondeinference/onde-cli/releases>
41
+
42
+## Source
43
+
44
+- Repository: <https://github.com/ondeinference/onde-cli>
45
+- Website: <https://ondeinference.com>
46
+- Issues: <https://github.com/ondeinference/onde-cli/issues>
47
+
48
+## License
49
+
50
+Dual-licensed under MIT and Apache 2.0.
51
+
52
+## Copyright
53
+
54
+© 2026 [Onde Inference](https://ondeinference.com) (Splitfire AB).
pypi/README.md
+4
@@ -13,6 +13,7 @@
13
<a href="https://ondeinference.com"><img src="https://img.shields.io/badge/ondeinference.com-235843?style=flat-square&labelColor=17211D" alt="Website"></a>
14
<a href="https://pypi.org/project/onde-cli/"><img src="https://img.shields.io/pypi/v/onde-cli?style=flat-square&labelColor=17211D&color=235843" alt="PyPI"></a>
15
<a href="https://www.npmjs.com/package/@ondeinference/cli"><img src="https://img.shields.io/npm/v/@ondeinference/cli?style=flat-square&labelColor=17211D&color=235843" alt="npm"></a>
16
+ <a href="https://www.nuget.org/packages/Onde.Cli"><img src="https://img.shields.io/nuget/v/Onde.Cli?style=flat-square&labelColor=17211D&color=235843" alt="NuGet"></a>
17
<a href="https://crates.io/crates/onde-cli"><img src="https://img.shields.io/crates/v/onde-cli?style=flat-square&labelColor=17211D&color=235843" alt="Crates.io"></a>
18
<a href="https://github.com/ondeinference/onde-cli/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT%20%2F%20Apache--2.0-235843?style=flat-square&labelColor=17211D" alt="License"></a>
19
</p>
@@ -111,6 +112,8 @@ Training runs locally:
112
113
No cloud training job. No Python environment. No notebook setup spiral.
114
115
+If you want the short version of what happens inside the model at inference time, Onde also has a plain-English note on the [forward pass](https://ondeinference.com/forward-pass).
116
+
117
### Supported base models
118
119
| Model | Size |
@@ -162,6 +165,7 @@ The exported file loads directly in the [Onde SDK](https://ondeinference.com) fo
165
| npm | `npm install -g @ondeinference/cli` |
166
| Homebrew | `brew install ondeinference/homebrew-tap/onde` |
167
| uv | `uv tool install onde-cli` |
168
+| .NET tool | `dotnet tool install --global Onde.Cli` |
169
| Cargo | `cargo install onde-cli` |
170
171
### Build from source