@ondeinference / cli / commits / 9a86127

Add Dart pub package for Onde CLI with CI and release workflow

keypair34 committed May 3, 2026 at 10:51 UTC 9a86127729464365628c3998302f969ad4ed9dc6
16 files changed +669 -3
.agents/skills/distribution/SKILL.md
.github/workflows/ci.yml
+23 -3
@@ -123,6 +123,24 @@ jobs:
123 - name: Build .NET tool launcher
124 run: dotnet build nuget/onde-cli/Onde.Cli.csproj --configuration Release
125
126 + dart-package:
127 + name: Dart pub package check
128 + runs-on: ubuntu-latest
129 + steps:
130 + - name: Checkout
131 + uses: actions/checkout@v6
132 +
133 + - name: Setup Dart SDK
134 + uses: dart-lang/setup-dart@v1
135 +
136 + - name: Get package dependencies
137 + working-directory: pub/onde_cli
138 + run: dart pub get
139 +
140 + - name: Analyze Dart package
141 + working-directory: pub/onde_cli
142 + run: dart analyze
143 +
144 build:
145 name: Build (aarch64-apple-darwin)
146 runs-on: macos-26
@@ -156,6 +174,7 @@ jobs:
174 - test
175 - check
176 - dotnet-tool
177 + - dart-package
178 - build
179 if: always()
180 steps:
@@ -164,6 +183,7 @@ jobs:
183 test "${{ needs.fmt.result }}" = "success"
184 test "${{ needs.clippy.result }}" = "success"
185 test "${{ needs.test.result }}" = "success"
167 - test "${{ needs.check.result }}" = "success"
168 - test "${{ needs.dotnet-tool.result }}" = "success"
169 - test "${{ needs.build.result }}" = "success"
186 + test "${{ needs.check.result }}" = "success"
187 + test "${{ needs.dotnet-tool.result }}" = "success"
188 + test "${{ needs.dart-package.result }}" = "success"
189 + test "${{ needs.build.result }}" = "success"
.github/workflows/release-pub.yml new
+241
@@ -0,0 +1,241 @@
1 +name: pub.dev 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 + PUB_PACKAGE_NAME: onde_cli
19 + ONDE_APP_ID: ${{ secrets.ONDE_APP_ID }}
20 + ONDE_APP_SECRET: ${{ secrets.ONDE_APP_SECRET }}
21 + GRESIQ_API_KEY: ${{ secrets.GRESIQ_API_KEY }}
22 + GRESIQ_API_SECRET: ${{ secrets.GRESIQ_API_SECRET }}
23 + HF_TOKEN: ${{ secrets.HF_TOKEN }}
24 +
25 +jobs:
26 + build-native-binaries:
27 + name: Build native binary (${{ matrix.build.NAME }})
28 + runs-on: ${{ matrix.build.OS }}
29 + strategy:
30 + fail-fast: false
31 + matrix:
32 + build:
33 + - {
34 + NAME: linux-x64,
35 + OS: ubuntu-latest,
36 + TARGET: x86_64-unknown-linux-gnu,
37 + }
38 + - {
39 + NAME: linux-arm64,
40 + OS: ubuntu-24.04-arm,
41 + TARGET: aarch64-unknown-linux-gnu,
42 + }
43 + - {
44 + NAME: windows-x64,
45 + OS: windows-2022,
46 + TARGET: x86_64-pc-windows-msvc,
47 + }
48 + - {
49 + NAME: windows-arm64,
50 + OS: windows-2022,
51 + TARGET: aarch64-pc-windows-msvc,
52 + }
53 + - {
54 + NAME: darwin-x64,
55 + OS: macos-26-intel,
56 + TARGET: x86_64-apple-darwin,
57 + }
58 + - { NAME: darwin-arm64, OS: macos-26, TARGET: aarch64-apple-darwin }
59 + steps:
60 + - name: Checkout
61 + uses: actions/checkout@v6
62 + with:
63 + ref: ${{ github.event.inputs.tag || github.ref }}
64 +
65 + - name: Read Rust toolchain
66 + shell: bash
67 + run: |
68 + rust_toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml | head -n 1)"
69 + if [ -z "$rust_toolchain" ]; then
70 + echo "Failed to read Rust toolchain from rust-toolchain.toml" >&2
71 + exit 1
72 + fi
73 + echo "RUST_TOOLCHAIN=${rust_toolchain}" >> "$GITHUB_ENV"
74 +
75 + - name: Install Rust toolchain
76 + uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
77 + with:
78 + toolchain: ${{ env.RUST_TOOLCHAIN }}
79 + targets: ${{ matrix.build.TARGET }}
80 +
81 + - name: Setup Rust cache
82 + uses: Swatinem/rust-cache@v2
83 + with:
84 + key: pub-${{ matrix.build.TARGET }}
85 +
86 + - name: Build binary
87 + shell: bash
88 + run: cargo build --locked --release --target ${{ matrix.build.TARGET }}
89 +
90 + - name: Prepare artifact
91 + shell: bash
92 + run: |
93 + executable_name="onde"
94 + if [[ "${{ matrix.build.OS }}" == "windows-2022" ]]; then
95 + executable_name="onde.exe"
96 + fi
97 +
98 + mkdir -p "pub-artifacts/native/${{ matrix.build.NAME }}"
99 + cp "target/${{ matrix.build.TARGET }}/release/${executable_name}" "pub-artifacts/native/${{ matrix.build.NAME }}/${executable_name}"
100 +
101 + - name: Upload native artifact
102 + uses: actions/upload-artifact@v4
103 + with:
104 + name: pub-native-${{ matrix.build.NAME }}
105 + path: pub-artifacts/native
106 +
107 + verify-package:
108 + name: Verify Dart package
109 + runs-on: ubuntu-latest
110 + needs: build-native-binaries
111 + steps:
112 + - name: Checkout
113 + uses: actions/checkout@v6
114 + with:
115 + ref: ${{ github.event.inputs.tag || github.ref }}
116 +
117 + - name: Set the release version
118 + shell: bash
119 + run: |
120 + if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
121 + release_version="${GITHUB_REF_NAME#v}"
122 + else
123 + release_version="${{ github.event.inputs.tag }}"
124 + release_version="${release_version#v}"
125 + fi
126 + echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
127 +
128 + - name: Download native artifacts
129 + uses: actions/download-artifact@v4
130 + with:
131 + pattern: pub-native-*
132 + path: pub/onde_cli/native
133 + merge-multiple: true
134 +
135 + - name: Stage generated native binaries
136 + shell: bash
137 + run: git add -f pub/onde_cli/native
138 +
139 + - name: Setup Dart SDK
140 + uses: dart-lang/setup-dart@v1
141 +
142 + - name: Sync package version
143 + shell: bash
144 + run: |
145 + python3 - <<'PY'
146 + from pathlib import Path
147 + import os
148 + release_version = os.environ['RELEASE_VERSION']
149 + pubspec = Path('pub/onde_cli/pubspec.yaml')
150 + lines = pubspec.read_text().splitlines()
151 + for index, line in enumerate(lines):
152 + if line.startswith('version: '):
153 + lines[index] = f'version: {release_version}'
154 + pubspec.write_text('\n'.join(lines) + '\n')
155 + PY
156 +
157 + - name: Get package dependencies
158 + working-directory: pub/onde_cli
159 + run: dart pub get
160 +
161 + - name: Analyze Dart package
162 + working-directory: pub/onde_cli
163 + run: dart analyze
164 +
165 + - name: Dry-run publish
166 + working-directory: pub/onde_cli
167 + run: dart pub publish --dry-run
168 +
169 + publish-pub:
170 + name: Publish to pub.dev
171 + runs-on: ubuntu-latest
172 + needs: verify-package
173 + steps:
174 + - name: Checkout
175 + uses: actions/checkout@v6
176 + with:
177 + ref: ${{ github.event.inputs.tag || github.ref }}
178 +
179 + - name: Set the release version
180 + shell: bash
181 + run: |
182 + if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
183 + release_version="${GITHUB_REF_NAME#v}"
184 + else
185 + release_version="${{ github.event.inputs.tag }}"
186 + release_version="${release_version#v}"
187 + fi
188 + echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
189 +
190 + - name: Download native artifacts
191 + uses: actions/download-artifact@v4
192 + with:
193 + pattern: pub-native-*
194 + path: pub/onde_cli/native
195 + merge-multiple: true
196 +
197 + - name: Stage generated native binaries
198 + shell: bash
199 + run: git add -f pub/onde_cli/native
200 +
201 + - name: Setup Dart SDK
202 + uses: dart-lang/setup-dart@v1
203 +
204 + - name: Sync package version
205 + shell: bash
206 + run: |
207 + python3 - <<'PY'
208 + from pathlib import Path
209 + import os
210 + release_version = os.environ['RELEASE_VERSION']
211 + pubspec = Path('pub/onde_cli/pubspec.yaml')
212 + lines = pubspec.read_text().splitlines()
213 + for index, line in enumerate(lines):
214 + if line.startswith('version: '):
215 + lines[index] = f'version: {release_version}'
216 + pubspec.write_text('\n'.join(lines) + '\n')
217 + PY
218 +
219 + - name: Check whether release already exists on pub.dev
220 + id: pub-check
221 + shell: bash
222 + run: |
223 + package_url="https://pub.dev/api/packages/${PUB_PACKAGE_NAME}"
224 + if curl -fsS "${package_url}" | grep -F '"version":"'"${RELEASE_VERSION}"'"' >/dev/null; then
225 + echo "${PUB_PACKAGE_NAME} ${RELEASE_VERSION} already exists on pub.dev, skipping publish"
226 + echo "exists=true" >> "$GITHUB_OUTPUT"
227 + else
228 + echo "exists=false" >> "$GITHUB_OUTPUT"
229 + fi
230 +
231 + - name: Configure pub.dev token
232 + if: steps.pub-check.outputs.exists != 'true'
233 + shell: bash
234 + env:
235 + PUB_DEV_PUBLISH_ACCESS_TOKEN: ${{ secrets.PUB_DEV_PUBLISH_ACCESS_TOKEN }}
236 + run: dart pub token add https://pub.dev --env-var PUB_DEV_PUBLISH_ACCESS_TOKEN
237 +
238 + - name: Publish package
239 + if: steps.pub-check.outputs.exists != 'true'
240 + working-directory: pub/onde_cli
241 + run: dart pub publish --force
.gitignore
+4
@@ -10,4 +10,8 @@
10 /nuget/onde-cli/obj/
11 /nuget/onde-cli/native/
12
13 +# Generated Dart pub package artifacts
14 +/pub/onde_cli/.dart_tool/
15 +/pub/onde_cli/pubspec.lock
16 +
17 .env
README.md
+7
@@ -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://pub.dev/packages/onde_cli"><img src="https://img.shields.io/pub/v/onde_cli?style=flat-square&labelColor=17211D&color=235843" alt="pub.dev"></a>
17 <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>
18 <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>
19 </p>
@@ -59,6 +60,12 @@ uvx --from onde-cli onde
60 dotnet tool install --global Onde.Cli
61 ```
62
63 +### Dart pub global
64 +
65 +```sh
66 +dart pub global activate onde_cli
67 +```
68 +
69 ### Pre-built binary
70
71 Download a release from [GitHub Releases](https://github.com/ondeinference/onde-cli/releases):
npm/onde-cli/README.md
+2
@@ -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://pub.dev/packages/onde_cli"><img src="https://img.shields.io/pub/v/onde_cli?style=flat-square&labelColor=17211D&color=235843" alt="pub.dev"></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://ondeinference.com"><img src="https://img.shields.io/badge/ondeinference.com-235843?style=flat-square&labelColor=17211D" alt="Website"></a>
18 </p>
@@ -39,6 +40,7 @@ It works on:
40 | Homebrew | `brew install ondeinference/homebrew-tap/onde` |
41 | pip | `pip install onde-cli` |
42 | uv | `uv tool install onde-cli` |
43 +| Dart pub | `dart pub global activate onde_cli` |
44 | .NET tool | `dotnet tool install --global Onde.Cli` |
45 | Cargo | `cargo install onde-cli` |
46
nuget/onde-cli/README.md
+1
@@ -36,6 +36,7 @@ This .NET tool bundles native `onde` binaries for:
36
37 - npm: `npm install -g @ondeinference/cli`
38 - pip: `pip install onde-cli`
39 +- Dart pub: `dart pub global activate onde_cli`
40 - Homebrew: `brew install ondeinference/homebrew-tap/onde`
41 - GitHub Releases: <https://github.com/ondeinference/onde-cli/releases>
42
pub/onde_cli/.gitignore new
+2
@@ -0,0 +1,2 @@
1 +.dart_tool/
2 +pubspec.lock
pub/onde_cli/.pubignore new
+2
@@ -0,0 +1,2 @@
1 +.dart_tool/
2 +pubspec.lock
pub/onde_cli/CHANGELOG.md new
+3
@@ -0,0 +1,3 @@
1 +## 0.3.0
2 +
3 +- Initial pub.dev wrapper for the Onde Inference CLI.
pub/onde_cli/LICENSE new
+201
@@ -0,0 +1,201 @@
1 + Apache License
2 + Version 2.0, January 2004
3 + http://www.apache.org/licenses/
4 +
5 + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 +
7 + 1. Definitions.
8 +
9 + "License" shall mean the terms and conditions for use, reproduction,
10 + and distribution as defined by Sections 1 through 9 of this document.
11 +
12 + "Licensor" shall mean the copyright owner or entity authorized by
13 + the copyright owner that is granting the License.
14 +
15 + "Legal Entity" shall mean the union of the acting entity and all
16 + other entities that control, are controlled by, or are under common
17 + control with that entity. For the purposes of this definition,
18 + "control" means (i) the power, direct or indirect, to cause the
19 + direction or management of such entity, whether by contract or
20 + otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 + outstanding shares, or (iii) beneficial ownership of such entity.
22 +
23 + "You" (or "Your") shall mean an individual or Legal Entity
24 + exercising permissions granted by this License.
25 +
26 + "Source" form shall mean the preferred form for making modifications,
27 + including but not limited to software source code, documentation
28 + source, and configuration files.
29 +
30 + "Object" form shall mean any form resulting from mechanical
31 + transformation or translation of a Source form, including but
32 + not limited to compiled object code, generated documentation,
33 + and conversions to other media types.
34 +
35 + "Work" shall mean the work of authorship, whether in Source or
36 + Object form, made available under the License, as indicated by a
37 + copyright notice that is included in or attached to the work
38 + (an example is provided in the Appendix below).
39 +
40 + "Derivative Works" shall mean any work, whether in Source or Object
41 + form, that is based on (or derived from) the Work and for which the
42 + editorial revisions, annotations, elaborations, or other modifications
43 + represent, as a whole, an original work of authorship. For the purposes
44 + of this License, Derivative Works shall not include works that remain
45 + separable from, or merely link (or bind by name) to the interfaces of,
46 + the Work and Derivative Works thereof.
47 +
48 + "Contribution" shall mean any work of authorship, including
49 + the original version of the Work and any modifications or additions
50 + to that Work or Derivative Works thereof, that is intentionally
51 + submitted to Licensor for inclusion in the Work by the copyright owner
52 + or by an individual or Legal Entity authorized to submit on behalf of
53 + the copyright owner. For the purposes of this definition, "submitted"
54 + means any form of electronic, verbal, or written communication sent
55 + to the Licensor or its representatives, including but not limited to
56 + communication on electronic mailing lists, source code control systems,
57 + and issue tracking systems that are managed by, or on behalf of, the
58 + Licensor for the purpose of discussing and improving the Work, but
59 + excluding communication that is conspicuously marked or otherwise
60 + designated in writing by the copyright owner as "Not a Contribution."
61 +
62 + "Contributor" shall mean Licensor and any individual or Legal Entity
63 + on behalf of whom a Contribution has been received by Licensor and
64 + subsequently incorporated within the Work.
65 +
66 + 2. Grant of Copyright License. Subject to the terms and conditions of
67 + this License, each Contributor hereby grants to You a perpetual,
68 + worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 + copyright license to reproduce, prepare Derivative Works of,
70 + publicly display, publicly perform, sublicense, and distribute the
71 + Work and such Derivative Works in Source or Object form.
72 +
73 + 3. Grant of Patent License. Subject to the terms and conditions of
74 + this License, each Contributor hereby grants to You a perpetual,
75 + worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 + (except as stated in this section) patent license to make, have made,
77 + use, offer to sell, sell, import, and otherwise transfer the Work,
78 + where such license applies only to those patent claims licensable
79 + by such Contributor that are necessarily infringed by their
80 + Contribution(s) alone or by combination of their Contribution(s)
81 + with the Work to which such Contribution(s) was submitted. If You
82 + institute patent litigation against any entity (including a
83 + cross-claim or counterclaim in a lawsuit) alleging that the Work
84 + or a Contribution incorporated within the Work constitutes direct
85 + or contributory patent infringement, then any patent licenses
86 + granted to You under this License for that Work shall terminate
87 + as of the date such litigation is filed.
88 +
89 + 4. Redistribution. You may reproduce and distribute copies of the
90 + Work or Derivative Works thereof in any medium, with or without
91 + modifications, and in Source or Object form, provided that You
92 + meet the following conditions:
93 +
94 + (a) You must give any other recipients of the Work or
95 + Derivative Works a copy of this License; and
96 +
97 + (b) You must cause any modified files to carry prominent notices
98 + stating that You changed the files; and
99 +
100 + (c) You must retain, in the Source form of any Derivative Works
101 + that You distribute, all copyright, patent, trademark, and
102 + attribution notices from the Source form of the Work,
103 + excluding those notices that do not pertain to any part of
104 + the Derivative Works; and
105 +
106 + (d) If the Work includes a "NOTICE" text file as part of its
107 + distribution, then any Derivative Works that You distribute must
108 + include a readable copy of the attribution notices contained
109 + within such NOTICE file, excluding those notices that do not
110 + pertain to any part of the Derivative Works, in at least one
111 + of the following places: within a NOTICE text file distributed
112 + as part of the Derivative Works; within the Source form or
113 + documentation, if provided along with the Derivative Works; or,
114 + within a display generated by the Derivative Works, if and
115 + wherever such third-party notices normally appear. The contents
116 + of the NOTICE file are for informational purposes only and
117 + do not modify the License. You may add Your own attribution
118 + notices within Derivative Works that You distribute, alongside
119 + or as an addendum to the NOTICE text from the Work, provided
120 + that such additional attribution notices cannot be construed
121 + as modifying the License.
122 +
123 + You may add Your own copyright statement to Your modifications and
124 + may provide additional or different license terms and conditions
125 + for use, reproduction, or distribution of Your modifications, or
126 + for any such Derivative Works as a whole, provided Your use,
127 + reproduction, and distribution of the Work otherwise complies with
128 + the conditions stated in this License.
129 +
130 + 5. Submission of Contributions. Unless You explicitly state otherwise,
131 + any Contribution intentionally submitted for inclusion in the Work
132 + by You to the Licensor shall be under the terms and conditions of
133 + this License, without any additional terms or conditions.
134 + Notwithstanding the above, nothing herein shall supersede or modify
135 + the terms of any separate license agreement you may have executed
136 + with Licensor regarding such Contributions.
137 +
138 + 6. Trademarks. This License does not grant permission to use the trade
139 + names, trademarks, service marks, or product names of the Licensor,
140 + except as required for reasonable and customary use in describing the
141 + origin of the Work and reproducing the content of the NOTICE file.
142 +
143 + 7. Disclaimer of Warranty. Unless required by applicable law or
144 + agreed to in writing, Licensor provides the Work (and each
145 + Contributor provides its Contributions) on an "AS IS" BASIS,
146 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 + implied, including, without limitation, any warranties or conditions
148 + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 + PARTICULAR PURPOSE. You are solely responsible for determining the
150 + appropriateness of using or redistributing the Work and assume any
151 + risks associated with Your exercise of permissions under this License.
152 +
153 + 8. Limitation of Liability. In no event and under no legal theory,
154 + whether in tort (including negligence), contract, or otherwise,
155 + unless required by applicable law (such as deliberate and grossly
156 + negligent acts) or agreed to in writing, shall any Contributor be
157 + liable to You for damages, including any direct, indirect, special,
158 + incidental, or consequential damages of any character arising as a
159 + result of this License or out of the use or inability to use the
160 + Work (including but not limited to damages for loss of goodwill,
161 + work stoppage, computer failure or malfunction, or any and all
162 + other commercial damages or losses), even if such Contributor
163 + has been advised of the possibility of such damages.
164 +
165 + 9. Accepting Warranty or Additional Liability. While redistributing
166 + the Work or Derivative Works thereof, You may choose to offer,
167 + and charge a fee for, acceptance of support, warranty, indemnity,
168 + or other liability obligations and/or rights consistent with this
169 + License. However, in accepting such obligations, You may act only
170 + on Your own behalf and on Your sole responsibility, not on behalf
171 + of any other Contributor, and only if You agree to indemnify,
172 + defend, and hold each Contributor harmless for any liability
173 + incurred by, or claims asserted against, such Contributor by reason
174 + of your accepting any such warranty or additional liability.
175 +
176 + END OF TERMS AND CONDITIONS
177 +
178 + APPENDIX: How to apply the Apache License to your work.
179 +
180 + To apply the Apache License to your work, attach the following
181 + boilerplate notice, with the fields enclosed by brackets "[]"
182 + replaced with your own identifying information. (Don't include
183 + the brackets!) The text should be enclosed in the appropriate
184 + comment syntax for the file format. We also recommend that a
185 + file or class name and description of purpose be included on the
186 + same "printed page" as the copyright notice for easier
187 + identification within third-party archives.
188 +
189 + Copyright 2026 Onde Inference (Splitfire AB)
190 +
191 + Licensed under the Apache License, Version 2.0 (the "License");
192 + you may not use this file except in compliance with the License.
193 + You may obtain a copy of the License at
194 +
195 + http://www.apache.org/licenses/LICENSE-2.0
196 +
197 + Unless required by applicable law or agreed to in writing, software
198 + distributed under the License is distributed on an "AS IS" BASIS,
199 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 + See the License for the specific language governing permissions and
201 + limitations under the License.
pub/onde_cli/README.md new
+48
@@ -0,0 +1,48 @@
1 +# onde_cli
2 +
3 +Dart wrapper for the official [Onde Inference](https://ondeinference.com) CLI.
4 +
5 +## Install
6 +
7 +```sh
8 +dart pub global activate onde_cli
9 +```
10 +
11 +## Run
12 +
13 +```sh
14 +onde
15 +```
16 +
17 +That opens the Onde terminal UI for account management, app setup, and local model fine-tuning.
18 +
19 +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).
20 +
21 +## Platform support
22 +
23 +This package bundles native `onde` binaries for:
24 +
25 +- macOS `arm64`, `x64`
26 +- Linux `arm64`, `x64` (glibc)
27 +- Windows `arm64`, `x64`
28 +
29 +## Other installation methods
30 +
31 +- npm: `npm install -g @ondeinference/cli`
32 +- pip: `pip install onde-cli`
33 +- .NET tool: `dotnet tool install --global Onde.Cli`
34 +- Homebrew: `brew install ondeinference/homebrew-tap/onde`
35 +
36 +## Source
37 +
38 +- Repository: <https://github.com/ondeinference/onde-cli>
39 +- Website: <https://ondeinference.com>
40 +- Issues: <https://github.com/ondeinference/onde-cli/issues>
41 +
42 +## License
43 +
44 +Dual-licensed under MIT and Apache 2.0.
45 +
46 +## Copyright
47 +
48 +© 2026 [Onde Inference](https://ondeinference.com) (Splitfire AB).
pub/onde_cli/bin/onde.dart new
+13
@@ -0,0 +1,13 @@
1 +import 'dart:io';
2 +
3 +import 'package:onde_cli/onde_cli.dart';
4 +
5 +Future<void> main(List<String> arguments) async {
6 + try {
7 + final exitCode = await runOndeCli(arguments);
8 + exit(exitCode);
9 + } on OndeCliException catch (error) {
10 + stderr.writeln('onde: ${error.message}');
11 + exit(1);
12 + }
13 +}
pub/onde_cli/lib/onde_cli.dart new
+99
@@ -0,0 +1,99 @@
1 +import 'dart:ffi';
2 +import 'dart:io';
3 +import 'dart:isolate';
4 +
5 +class OndeCliException implements Exception {
6 + OndeCliException(this.message);
7 +
8 + final String message;
9 +
10 + @override
11 + String toString() => message;
12 +}
13 +
14 +Future<int> runOndeCli(List<String> arguments) async {
15 + final executablePath = await resolveExecutablePath();
16 + await ensureExecutablePermissions(executablePath);
17 +
18 + final process = await Process.start(
19 + executablePath,
20 + arguments,
21 + mode: ProcessStartMode.inheritStdio,
22 + workingDirectory: Directory.current.path,
23 + );
24 +
25 + return process.exitCode;
26 +}
27 +
28 +Future<String> resolveExecutablePath() async {
29 + final packageUri = await Isolate.resolvePackageUri(
30 + Uri.parse('package:onde_cli/onde_cli.dart'),
31 + );
32 +
33 + if (packageUri == null) {
34 + throw OndeCliException(
35 + 'Failed to resolve the installed Dart package path.',
36 + );
37 + }
38 +
39 + final packageRootUri = packageUri.resolve('../');
40 + final executableUri = packageRootUri.resolve(
41 + 'native/${runtimeIdentifier()}/${executableName()}',
42 + );
43 + final executablePath = executableUri.toFilePath();
44 +
45 + if (!await File(executablePath).exists()) {
46 + throw OndeCliException(
47 + "The native onde executable for '${runtimeIdentifier()}' is not bundled in this package.",
48 + );
49 + }
50 +
51 + return executablePath;
52 +}
53 +
54 +String runtimeIdentifier() {
55 + final architecture = architectureName();
56 +
57 + if (Platform.isMacOS) {
58 + return 'darwin-$architecture';
59 + }
60 + if (Platform.isWindows) {
61 + return 'windows-$architecture';
62 + }
63 + if (Platform.isLinux) {
64 + return 'linux-$architecture';
65 + }
66 +
67 + throw OndeCliException(
68 + 'onde does not support this operating system through the Dart package.',
69 + );
70 +}
71 +
72 +String architectureName() {
73 + final abi = Abi.current().toString().toLowerCase();
74 + if (abi.contains('arm64')) {
75 + return 'arm64';
76 + }
77 + if (abi.contains('x64')) {
78 + return 'x64';
79 + }
80 +
81 + throw OndeCliException(
82 + 'onde does not support the current architecture through the Dart package.',
83 + );
84 +}
85 +
86 +String executableName() => Platform.isWindows ? 'onde.exe' : 'onde';
87 +
88 +Future<void> ensureExecutablePermissions(String executablePath) async {
89 + if (Platform.isWindows) {
90 + return;
91 + }
92 +
93 + final result = await Process.run('chmod', ['755', executablePath]);
94 + if (result.exitCode != 0) {
95 + throw OndeCliException(
96 + 'Failed to mark the native onde binary as executable.',
97 + );
98 + }
99 +}
pub/onde_cli/pubspec.yaml new
+21
@@ -0,0 +1,21 @@
1 +name: onde_cli
2 +description: Dart wrapper for the Onde Inference CLI with bundled native binaries for macOS, Linux, and Windows.
3 +version: 0.3.0
4 +homepage: https://ondeinference.com
5 +repository: https://github.com/ondeinference/onde-cli
6 +issue_tracker: https://github.com/ondeinference/onde-cli/issues
7 +documentation: https://ondeinference.com
8 +publish_to: https://pub.dev
9 +
10 +environment:
11 + sdk: '>=3.8.0 <4.0.0'
12 +
13 +executables:
14 + onde: onde
15 +
16 +topics:
17 + - cli
18 + - ai
19 + - llm
20 + - on-device
21 + - inference
pypi/README.md
+2
@@ -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://pub.dev/packages/onde_cli"><img src="https://img.shields.io/pub/v/onde_cli?style=flat-square&labelColor=17211D&color=235843" alt="pub.dev"></a>
17 <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>
18 <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>
19 <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>
@@ -165,6 +166,7 @@ The exported file loads directly in the [Onde SDK](https://ondeinference.com) fo
166 | npm | `npm install -g @ondeinference/cli` |
167 | Homebrew | `brew install ondeinference/homebrew-tap/onde` |
168 | uv | `uv tool install onde-cli` |
169 +| Dart pub | `dart pub global activate onde_cli` |
170 | .NET tool | `dotnet tool install --global Onde.Cli` |
171 | Cargo | `cargo install onde-cli` |
172