onde-cli 0.4.2__tar.gz → 0.4.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- onde_cli-0.4.3/.agents/skills/release/SKILL.md +149 -0
- onde_cli-0.4.3/.agents/skills/release/evals/evals.json +35 -0
- onde_cli-0.4.3/.cargo/config.toml +7 -0
- onde_cli-0.4.3/.claude/skills/distribution/SKILL.md +262 -0
- onde_cli-0.4.3/.claude/skills/git/SKILL.md +70 -0
- onde_cli-0.4.3/.claude/skills/release/SKILL.md +149 -0
- onde_cli-0.4.3/.claude/skills/release/evals/evals.json +35 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/.github/workflows/release-github.yml +7 -0
- onde_cli-0.4.3/.github/workflows/release-winget.yml +327 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/Cargo.lock +1 -1
- {onde_cli-0.4.2 → onde_cli-0.4.3}/Cargo.toml +1 -1
- {onde_cli-0.4.2 → onde_cli-0.4.3}/PKG-INFO +2 -2
- {onde_cli-0.4.2 → onde_cli-0.4.3}/README.md +5 -5
- {onde_cli-0.4.2 → onde_cli-0.4.3}/npm/onde-cli/README.md +2 -2
- {onde_cli-0.4.2 → onde_cli-0.4.3}/nuget/onde-cli/README.md +1 -1
- onde_cli-0.4.3/packaging/windows/check-static-crt.ps1 +35 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/packaging/winget/OndeInference.onde-cli.installer.yaml.in +2 -2
- {onde_cli-0.4.2 → onde_cli-0.4.3}/packaging/winget/OndeInference.onde-cli.locale.en-US.yaml.in +2 -2
- {onde_cli-0.4.2 → onde_cli-0.4.3}/packaging/winget/OndeInference.onde-cli.yaml.in +2 -2
- {onde_cli-0.4.2 → onde_cli-0.4.3}/pub/onde_cli/README.md +1 -1
- {onde_cli-0.4.2 → onde_cli-0.4.3}/pub/onde_cli/pubspec.yaml +1 -1
- {onde_cli-0.4.2 → onde_cli-0.4.3}/pypi/README.md +1 -1
- {onde_cli-0.4.2 → onde_cli-0.4.3}/server.json +3 -3
- {onde_cli-0.4.2 → onde_cli-0.4.3}/src/main.rs +26 -13
- onde_cli-0.4.2/.github/workflows/release-winget.yml +0 -178
- {onde_cli-0.4.2 → onde_cli-0.4.3}/.agents/AGENTS.md +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/.agents/skills/distribution/SKILL.md +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/.agents/skills/git/SKILL.md +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/.github/workflows/ci.yml +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/.github/workflows/release-crates.yml +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/.github/workflows/release-homebrew.yml +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/.github/workflows/release-mcp-registry.yml +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/.github/workflows/release-npm.yml +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/.github/workflows/release-nuget.yml +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/.github/workflows/release-pub.yml +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/.github/workflows/release-pypi.yml +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/.github/workflows/release-scoop.yml +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/.gitignore +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/.nuget/NuGet/NuGet.Config +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/.nvmrc +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/.sigit/code-cloud-agent/config.toml +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/.sigit/code-review/config.toml +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/.sigit/factory/config.toml +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/AGENTS.md +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/CLAUDE.md +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/LICENSE +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/assets/ondeinference-apps.png +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/build.rs +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/docs/mcp-registry.md +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/npm/README.md.tmpl +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/npm/onde-cli/.gitignore +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/npm/onde-cli/package-lock.json +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/npm/onde-cli/package.json +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/npm/onde-cli/src/index.ts +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/npm/onde-cli/tsconfig.json +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/npm/package-main.json.tmpl +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/npm/package.json.tmpl +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/npm/scripts/render-main-package.cjs +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/npm/scripts/render-platform-package.cjs +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/nuget/.gitignore +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/nuget/onde-cli/Onde.Cli.csproj +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/nuget/onde-cli/Program.cs +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/pub/onde_cli/.gitignore +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/pub/onde_cli/.pubignore +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/pub/onde_cli/CHANGELOG.md +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/pub/onde_cli/LICENSE +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/pub/onde_cli/bin/onde.dart +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/pub/onde_cli/lib/onde_cli.dart +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/pypi/pyproject.toml +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/pyproject.toml +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/rust-toolchain.toml +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/src/app.rs +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/src/chat.rs +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/src/finetune.rs +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/src/gguf.rs +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/src/gresiq.rs +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/src/hf.rs +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/src/hf_clone.rs +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/src/hf_search.rs +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/src/hf_upload.rs +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/src/mcp.rs +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/src/merge.rs +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/src/project.rs +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/src/token.rs +0 -0
- {onde_cli-0.4.2 → onde_cli-0.4.3}/src/ui.rs +0 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: release
|
|
3
|
+
description: Use whenever cutting, preparing, tagging, or publishing an onde-cli release — version bumps, release branch, merges, tagging, pushing to trigger the publish pipeline, and verifying it landed. Also use when a release went wrong (wrong tag target, failed crates.io verify, development left behind main, unsigned release commits) and the repo state needs repair. Trigger even if the user only says "release vX.Y.Z", "bump the version", "tag a release", or "publish the new version".
|
|
4
|
+
user-invocable: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Release skill
|
|
8
|
+
|
|
9
|
+
End-to-end release procedure for `onde-cli`. Complements the git skill (merge rules)
|
|
10
|
+
and the distribution skill (channel details) — this skill is the concrete runbook.
|
|
11
|
+
|
|
12
|
+
## Decide the version
|
|
13
|
+
|
|
14
|
+
- Look at `git tag -l 'v*' --sort=-v:refname | head -1` for the latest release.
|
|
15
|
+
- Look at the commits since (`git log v<latest>..development --oneline`).
|
|
16
|
+
Fixes and chores only → patch bump. New user-facing features → minor bump.
|
|
17
|
+
- Check for an abandoned `release/vX.Y.Z` branch — its version is usually the
|
|
18
|
+
intended next one. If it exists, inspect it (`git log development..release/...`)
|
|
19
|
+
before deciding to reuse or delete it; do not blindly `branch -D` without looking,
|
|
20
|
+
and never reuse a branch whose commits were made unsigned or by the wrong identity.
|
|
21
|
+
|
|
22
|
+
## Version bump surfaces
|
|
23
|
+
|
|
24
|
+
These files pin the crate version and must all move together:
|
|
25
|
+
|
|
26
|
+
- `Cargo.toml` — `version = "X.Y.Z"` in `[package]`
|
|
27
|
+
- `pub/onde_cli/pubspec.yaml` — `version: X.Y.Z`
|
|
28
|
+
- `server.json` — three occurrences: top-level `version`, and the npm and NuGet
|
|
29
|
+
`packages[].version` entries (search for the old version string to catch all)
|
|
30
|
+
|
|
31
|
+
`docs/mcp-registry.md` and `.github/workflows/release-mcp-registry.yml` mention
|
|
32
|
+
past versions only as historical examples — do not bump those.
|
|
33
|
+
|
|
34
|
+
The npm wrapper manifests are NOT bump targets: the committed `package.json` files
|
|
35
|
+
are rewritten at release time by `npm/scripts/render-*.cjs` from the tag.
|
|
36
|
+
|
|
37
|
+
After editing, run `cargo check --locked` (or let the build update `Cargo.lock`)
|
|
38
|
+
so the lockfile carries the new version, and commit it in the same bump commit.
|
|
39
|
+
|
|
40
|
+
## Sequence
|
|
41
|
+
|
|
42
|
+
Follow the git skill's branch flow — `release/vX.Y.Z → development → main`,
|
|
43
|
+
`--no-ff` at every hop, tag on the final `main` merge commit. Concretely:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
git checkout development
|
|
47
|
+
git pull <remote> development # start from the pushed tip
|
|
48
|
+
git checkout -b release/vX.Y.Z
|
|
49
|
+
# ... edit the bump surfaces ...
|
|
50
|
+
git commit -am "Prepare vX.Y.Z" # signed, correct identity (see below)
|
|
51
|
+
git checkout development
|
|
52
|
+
git merge --no-ff release/vX.Y.Z -m "Merge release prep for vX.Y.Z"
|
|
53
|
+
git checkout main
|
|
54
|
+
git pull <remote> main
|
|
55
|
+
git merge --no-ff development -m "Merge development for vX.Y.Z"
|
|
56
|
+
git tag vX.Y.Z
|
|
57
|
+
git push <remote> development main vX.Y.Z
|
|
58
|
+
git branch -d release/vX.Y.Z # only after the merge lands
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The remote here is the one whose URL is the sigit.si or GitHub org repo —
|
|
62
|
+
check `git remote -v`; this repo is commonly cloned with per-account remotes
|
|
63
|
+
(`gh-setoelkahfi`, `gh-paydii`, `gh-keypair34`) rather than `origin`.
|
|
64
|
+
|
|
65
|
+
### What a good result looks like
|
|
66
|
+
|
|
67
|
+
- The tag sits on the step-3 merge commit on `main` (`git log --graph main`
|
|
68
|
+
shows a merge commit directly above the previous release).
|
|
69
|
+
- `git log development..main` and `git log main..development` are both empty
|
|
70
|
+
after the merges — the two branches carry identical trees.
|
|
71
|
+
- Never tag a release-branch tip or a bare bump commit on `main`; if the work
|
|
72
|
+
somehow already landed on `main` linearly, follow the git skill's fallback
|
|
73
|
+
(normal commit, tag it) rather than rewriting history.
|
|
74
|
+
|
|
75
|
+
### Post-push back-merge check
|
|
76
|
+
|
|
77
|
+
If anything reached `main` without passing through `development` first (hotfix,
|
|
78
|
+
manual push, a fast-forwarded release), bring it back immediately:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
git checkout development
|
|
82
|
+
git merge --no-ff main -m "Merge main for vX.Y.Z"
|
|
83
|
+
git push <remote> development
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
A release is not done until the two branches contain the same tree.
|
|
87
|
+
|
|
88
|
+
## Commits and signatures — read the git-commit-signing skill first
|
|
89
|
+
|
|
90
|
+
Release commits must be GPG-signed by the maintainer identity that GitHub can
|
|
91
|
+
verify (this repo: `Seto Elkahfi <1797197+setoelkahfi@users.noreply.github.com>`,
|
|
92
|
+
EDDSA key `2B76DF0F04014E36`). The `gh` CLI's active account is independent of
|
|
93
|
+
git config — set both, and verify before pushing:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
git log -1 --format='%an <%ae> sig:%G? %GK' # want sig:G and the right key
|
|
97
|
+
gh api repos/<owner>/<repo>/commits/<sha> --jq .commit.verification.verified
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Every `git commit` and `git merge` in this flow creates a commit — configure
|
|
101
|
+
signing so merges are signed too, or amend unsigned ones before pushing
|
|
102
|
+
(`git commit --amend --no-edit -S`, only on unpushed commits).
|
|
103
|
+
|
|
104
|
+
Commit trailer: end release-related commit messages with
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
Co-Authored-By: siGit Code v1.6.7-acp <noreply@sigit.si>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## The tag push is the release
|
|
111
|
+
|
|
112
|
+
Pushing `vX.Y.Z` triggers `release-crates.yml`, which verifies the tag against
|
|
113
|
+
`Cargo.toml` and `pubspec.yaml`, publishes the crate, then dispatches the
|
|
114
|
+
wrapper workflows (GitHub Releases, npm, NuGet, PyPI, then Homebrew and pub.dev
|
|
115
|
+
after the GitHub Release assets exist). There is no separate "publish" step.
|
|
116
|
+
|
|
117
|
+
Watch it land:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
gh run list --branch vX.Y.Z
|
|
121
|
+
gh run watch <run-id> --exit-status
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`CI` also runs on the tag push; both should be green. If `release-crates` fails,
|
|
125
|
+
no wrapper publishes — fix the cause, move the tag only if it has not published
|
|
126
|
+
anything yet (crates.io versions are immutable; a failed verify is safe to retry,
|
|
127
|
+
a published crate is not).
|
|
128
|
+
|
|
129
|
+
## Verify
|
|
130
|
+
|
|
131
|
+
After the pipeline finishes, spot-check the fan-out (all idempotent, safe to re-check):
|
|
132
|
+
|
|
133
|
+
- crates.io: `cargo search onde-cli --limit 1`
|
|
134
|
+
- GitHub Release: `gh release view vX.Y.Z`
|
|
135
|
+
- npm: `npm view onde-cli version`
|
|
136
|
+
- PyPI: `https://pypi.org/pypi/onde-cli/json` → `info.version`
|
|
137
|
+
- NuGet: flat container index for `onde-cli`
|
|
138
|
+
- Homebrew/pub.dev trail the GitHub Release; they may take a few extra minutes
|
|
139
|
+
|
|
140
|
+
## Failure modes seen before
|
|
141
|
+
|
|
142
|
+
- Fast-forwarding `main` to the bump commit and tagging it — leaves no merge
|
|
143
|
+
commit, and leaves `development` behind. Back-merge `main` into `development`
|
|
144
|
+
right away and prefer merge commits next time.
|
|
145
|
+
- Deleting a leftover `release/` branch that contained unsigned bump commits and
|
|
146
|
+
redoing the bump fresh — fine, but check it first.
|
|
147
|
+
- Forgetting `Cargo.lock` in the bump commit.
|
|
148
|
+
- Pushing with the wrong `gh` account active — the push works, but PR/issue
|
|
149
|
+
actions afterwards get attributed to the wrong identity.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "release",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"prompt": "Cut release v0.4.3 for onde-cli. Bump all version pins, follow the repo's release branch flow, tag, and push.",
|
|
7
|
+
"expected_output": "Agent bumps Cargo.toml, pubspec.yaml, server.json (3 spots), commits signed with Co-Authored-By trailer, creates release/v0.4.3 from development, merges --no-ff into development then main, tags the main merge commit, pushes development+main+tag, and watches the release pipeline.",
|
|
8
|
+
"files": []
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"id": 2,
|
|
12
|
+
"prompt": "We fast-forwarded main to the version bump commit by mistake and tagged it. development is now behind main. Fix the repo state without rewriting pushed history.",
|
|
13
|
+
"expected_output": "Agent recognizes the git skill's rule (tag belongs on a merge commit; development must carry the release state) and back-merges main into development with --no-ff instead of rewriting main or deleting the pushed tag.",
|
|
14
|
+
"files": []
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"id": 3,
|
|
18
|
+
"prompt": "The v0.4.2 tag push failed the crates.io verify step because pubspec.yaml still said 0.4.1. Nothing was published. Walk me through fixing it and re-releasing.",
|
|
19
|
+
"expected_output": "Agent fixes the pubspec version on a new release branch or hotfix, re-runs the release flow, deletes and recreates the tag only if crates.io never published, and explains why crates.io versions are immutable so a published 0.4.2 would require 0.4.3 instead.",
|
|
20
|
+
"files": []
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"id": 4,
|
|
24
|
+
"prompt": "Update the README install instructions for the npm wrapper and fix the NuGet README badge that points at the wrong package id.",
|
|
25
|
+
"expected_output": "Should NOT deeply engage the release skill beyond reading it; this is distribution/README work. Agent edits npm/onde-cli/README.md and nuget/onde-cli/README.md without cutting a release, bumping versions, or tagging.",
|
|
26
|
+
"files": []
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": 5,
|
|
30
|
+
"prompt": "Merge the feature/lora-scheduler branch into development.",
|
|
31
|
+
"expected_output": "Should NOT trigger the release skill; this is a normal feature merge governed by the git skill (--no-ff into development, no tag).",
|
|
32
|
+
"files": []
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Link the MSVC C runtime statically on Windows. Without this the binary
|
|
2
|
+
# imports VCRUNTIME140.dll and the UCRT api-ms-win-crt-*.dll set, and on a
|
|
3
|
+
# machine without the Visual C++ Redistributable it dies at load time with
|
|
4
|
+
# STATUS_DLL_NOT_FOUND (0xC0000135) before main runs. winget ships onde as a
|
|
5
|
+
# portable exe, so there is no installer to bring the runtime along.
|
|
6
|
+
[target.'cfg(all(windows, target_env = "msvc"))']
|
|
7
|
+
rustflags = ["-C", "target-feature=+crt-static"]
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: distribution
|
|
3
|
+
description: Use when adding, fixing, or documenting package distribution for Onde CLI. Covers wrapper-package design across npm, PyPI, NuGet, pub.dev, GitHub Releases, and Homebrew, plus version alignment, artifact staging, README surfaces, and smoke-test strategy.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Onde CLI distribution
|
|
7
|
+
|
|
8
|
+
This skill captures how `onde-cli` is distributed today and what to watch when adding new channels.
|
|
9
|
+
|
|
10
|
+
## Distribution model
|
|
11
|
+
|
|
12
|
+
`onde-cli` is a native Rust CLI first.
|
|
13
|
+
|
|
14
|
+
Everything else is packaging.
|
|
15
|
+
|
|
16
|
+
That means:
|
|
17
|
+
|
|
18
|
+
- build the Rust binary once per target
|
|
19
|
+
- publish thin wrappers that install or launch that binary
|
|
20
|
+
- keep channel-specific logic small and predictable
|
|
21
|
+
|
|
22
|
+
This design keeps behavior consistent across ecosystems and avoids re-implementing CLI logic in each language.
|
|
23
|
+
|
|
24
|
+
## Channel map
|
|
25
|
+
|
|
26
|
+
### Native source of truth
|
|
27
|
+
|
|
28
|
+
- Rust crate: `onde-cli`
|
|
29
|
+
- binary name: `onde`
|
|
30
|
+
- root manifest: `Cargo.toml`
|
|
31
|
+
|
|
32
|
+
### Wrapper channels
|
|
33
|
+
|
|
34
|
+
- npm: JavaScript launcher + optional platform packages
|
|
35
|
+
- PyPI: `maturin` binary wheels
|
|
36
|
+
- NuGet: .NET global tool launcher
|
|
37
|
+
- pub.dev: Dart launcher package
|
|
38
|
+
|
|
39
|
+
### Native artifact channels
|
|
40
|
+
|
|
41
|
+
- crates.io
|
|
42
|
+
- GitHub Releases
|
|
43
|
+
- Homebrew
|
|
44
|
+
|
|
45
|
+
## Wrapper design patterns
|
|
46
|
+
|
|
47
|
+
### npm
|
|
48
|
+
|
|
49
|
+
Use a very small Node launcher that:
|
|
50
|
+
|
|
51
|
+
- detects OS and architecture
|
|
52
|
+
- resolves the installed platform package
|
|
53
|
+
- spawns the binary with inherited stdio
|
|
54
|
+
|
|
55
|
+
Good fit for users who already live in npm tooling.
|
|
56
|
+
|
|
57
|
+
Important release detail:
|
|
58
|
+
|
|
59
|
+
- the committed `npm/onde-cli/package.json` is a working file, not the publish-time source of truth
|
|
60
|
+
- the release workflow rewrites the base package manifest with `npm/scripts/render-main-package.cjs`
|
|
61
|
+
- platform package manifests are generated on the fly with `npm/scripts/render-platform-package.cjs`
|
|
62
|
+
- the actual npm version comes from the release tag via `RELEASE_VERSION`, not from manually editing the committed npm manifest before publish
|
|
63
|
+
|
|
64
|
+
### PyPI
|
|
65
|
+
|
|
66
|
+
Use `maturin` with `bindings = "bin"` so the native executable is what gets installed.
|
|
67
|
+
|
|
68
|
+
Good fit for Python users who want the CLI but not a Python reimplementation.
|
|
69
|
+
|
|
70
|
+
### NuGet
|
|
71
|
+
|
|
72
|
+
Use a `.NET global tool` wrapper.
|
|
73
|
+
|
|
74
|
+
Important details:
|
|
75
|
+
|
|
76
|
+
- keep the package as a launcher, not a managed rewrite
|
|
77
|
+
- place native binaries under the tool payload
|
|
78
|
+
- resolve the runtime identifier at startup
|
|
79
|
+
- set Unix execute bits before launch
|
|
80
|
+
|
|
81
|
+
Good fit for .NET developers and CI environments that already use `dotnet tool install`.
|
|
82
|
+
|
|
83
|
+
### pub.dev
|
|
84
|
+
|
|
85
|
+
Use a Dart package with a command entrypoint and a library that launches the native binary.
|
|
86
|
+
|
|
87
|
+
Important details:
|
|
88
|
+
|
|
89
|
+
- executable command should stay `onde`
|
|
90
|
+
- keep the runtime-id mapping explicit
|
|
91
|
+
- download the correct binary from GitHub Releases on first run
|
|
92
|
+
- cache downloads under `~/.onde/cli`
|
|
93
|
+
- keep the wrapper thin, the Rust binary is still the product
|
|
94
|
+
- publish the pub.dev package only after the matching GitHub Release exists
|
|
95
|
+
|
|
96
|
+
Good fit for Dart and Flutter developers who want the same CLI through familiar tooling.
|
|
97
|
+
|
|
98
|
+
## Runtime identifier mapping
|
|
99
|
+
|
|
100
|
+
Keep these names aligned anywhere wrappers or workflows refer to native assets:
|
|
101
|
+
|
|
102
|
+
- `darwin-x64`
|
|
103
|
+
- `darwin-arm64`
|
|
104
|
+
- `linux-x64`
|
|
105
|
+
- `linux-arm64`
|
|
106
|
+
- `windows-x64`
|
|
107
|
+
- `windows-arm64`
|
|
108
|
+
|
|
109
|
+
If a wrapper uses one naming scheme and a workflow uploads another, the installed package will pass packaging but fail at runtime.
|
|
110
|
+
|
|
111
|
+
## Release workflow principles
|
|
112
|
+
|
|
113
|
+
### One tag trigger, then fan out
|
|
114
|
+
|
|
115
|
+
`release-crates.yml` is the only workflow that reacts to a tag push. It verifies the
|
|
116
|
+
tag against `Cargo.toml` and `pubspec.yaml`, publishes the crate, then dispatches
|
|
117
|
+
`release-github`, `release-npm`, `release-nuget`, and `release-pypi` with the same tag.
|
|
118
|
+
`release-github` in turn dispatches `release-homebrew` and `release-pub` after the
|
|
119
|
+
release assets exist.
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
tag push
|
|
123
|
+
└─ release-crates (verify -> publish -> dispatch)
|
|
124
|
+
├─ release-github ─┬─ release-homebrew
|
|
125
|
+
│ └─ release-pub
|
|
126
|
+
├─ release-npm
|
|
127
|
+
├─ release-nuget
|
|
128
|
+
└─ release-pypi
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
This mirrors `smbcloud-cli`. Two properties matter:
|
|
132
|
+
|
|
133
|
+
- crates.io is the gate. If verify or publish fails, no wrapper publishes a version
|
|
134
|
+
that has no crate behind it.
|
|
135
|
+
- every dispatch passes `ref: <tag>`, not `ref: main`, so downstream workflows run the
|
|
136
|
+
workflow definition from the release state instead of whatever `main` happens to be.
|
|
137
|
+
|
|
138
|
+
Do not add `push: tags:` to a wrapper workflow. Several workflows racing on the same tag
|
|
139
|
+
is what lets the pub.dev launcher publish before its GitHub Release assets exist.
|
|
140
|
+
|
|
141
|
+
### Build first, package second
|
|
142
|
+
|
|
143
|
+
Always build native binaries in a target matrix first.
|
|
144
|
+
|
|
145
|
+
Then let the wrapper channel jobs package those artifacts.
|
|
146
|
+
|
|
147
|
+
This avoids rebuilding the product multiple times and makes failures easier to reason about.
|
|
148
|
+
|
|
149
|
+
### Idempotency
|
|
150
|
+
|
|
151
|
+
Every publish workflow should check whether the target version already exists before publishing.
|
|
152
|
+
|
|
153
|
+
Examples:
|
|
154
|
+
|
|
155
|
+
- npm: `npm view`
|
|
156
|
+
- PyPI: package JSON endpoint
|
|
157
|
+
- NuGet: flat container index
|
|
158
|
+
- pub.dev: package API endpoint
|
|
159
|
+
|
|
160
|
+
### Smoke tests should match the product shape
|
|
161
|
+
|
|
162
|
+
Because `onde` is TUI-first, avoid smoke tests that assume a traditional CLI help flow unless you know that code path is stable and non-interactive.
|
|
163
|
+
|
|
164
|
+
Safer checks:
|
|
165
|
+
|
|
166
|
+
- install succeeds
|
|
167
|
+
- bundled native binary exists where expected
|
|
168
|
+
- package manager validation passes
|
|
169
|
+
|
|
170
|
+
## pub.dev-specific notes
|
|
171
|
+
|
|
172
|
+
pub.dev behaves differently from npm and NuGet in one important way:
|
|
173
|
+
|
|
174
|
+
- large bundled binaries quickly hit package size limits
|
|
175
|
+
|
|
176
|
+
That makes the safest design a thin Dart launcher that downloads the right native binary from GitHub Releases at runtime instead of shipping every platform binary inside the package.
|
|
177
|
+
|
|
178
|
+
Practical consequences:
|
|
179
|
+
|
|
180
|
+
- `pub/onde_cli/native/` should stay out of the published package
|
|
181
|
+
- do not set `publish_to: https://pub.dev` in `pubspec.yaml`; omit `publish_to` for normal pub.dev publishing
|
|
182
|
+
- use package-level ignore rules so local native staging does not leak into publish input
|
|
183
|
+
- keep release asset names aligned with the GitHub Release workflow, because the launcher depends on them
|
|
184
|
+
- treat `~/.onde/cli` as the local cache root for downloaded binaries
|
|
185
|
+
- do not let the pub.dev workflow race ahead of GitHub Releases; dispatch it after `release-github.yml` has created the assets
|
|
186
|
+
|
|
187
|
+
Run these during verification:
|
|
188
|
+
|
|
189
|
+
- `dart pub get --directory pub/onde_cli`
|
|
190
|
+
- `dart analyze pub/onde_cli`
|
|
191
|
+
- `dart pub publish --dry-run --directory pub/onde_cli`
|
|
192
|
+
|
|
193
|
+
## NuGet-specific notes
|
|
194
|
+
|
|
195
|
+
NuGet packaging is sensitive to path layout.
|
|
196
|
+
|
|
197
|
+
The safest pattern is:
|
|
198
|
+
|
|
199
|
+
- copy native files into the publish output
|
|
200
|
+
- let the .NET tool pack process carry them into the final package
|
|
201
|
+
|
|
202
|
+
Avoid custom `PackagePath` patterns that can duplicate path segments or create nested native folders by accident.
|
|
203
|
+
|
|
204
|
+
If the tool installs but cannot find the native binary, inspect the `.nupkg` contents before debugging the launcher.
|
|
205
|
+
|
|
206
|
+
## README surfaces
|
|
207
|
+
|
|
208
|
+
Every user-facing channel should document the same product with channel-specific installation instructions.
|
|
209
|
+
|
|
210
|
+
Main files:
|
|
211
|
+
|
|
212
|
+
- `README.md`
|
|
213
|
+
- `npm/onde-cli/README.md`
|
|
214
|
+
- `pypi/README.md`
|
|
215
|
+
- `nuget/onde-cli/README.md`
|
|
216
|
+
- `pub/onde_cli/README.md`
|
|
217
|
+
|
|
218
|
+
Keep these aligned on:
|
|
219
|
+
|
|
220
|
+
- product description
|
|
221
|
+
- supported platforms
|
|
222
|
+
- install method
|
|
223
|
+
- license and copyright
|
|
224
|
+
- relevant supporting links like the forward-pass explainer
|
|
225
|
+
|
|
226
|
+
Do not let one channel sound like a different product.
|
|
227
|
+
|
|
228
|
+
## Version alignment
|
|
229
|
+
|
|
230
|
+
When cutting a release, update every user-facing distribution version that should move with the CLI.
|
|
231
|
+
|
|
232
|
+
At minimum, check:
|
|
233
|
+
|
|
234
|
+
- Rust crate version
|
|
235
|
+
- npm release templates and workflow assumptions
|
|
236
|
+
- npm lockfile version if committed
|
|
237
|
+
- PyPI release version source
|
|
238
|
+
- NuGet package version at pack time
|
|
239
|
+
- pub.dev package version in `pubspec.yaml`
|
|
240
|
+
- workflow example tags and docs that mention concrete versions
|
|
241
|
+
|
|
242
|
+
## Common failure modes
|
|
243
|
+
|
|
244
|
+
- wrapper version does not match the Rust release version
|
|
245
|
+
- manually bumping the committed npm manifest and assuming that is what npm publishes
|
|
246
|
+
- staged native binaries land in the wrong directory before packaging
|
|
247
|
+
- package builds successfully but installs without the native binary
|
|
248
|
+
- pub.dev launcher points at the wrong GitHub Release asset name or runtime id
|
|
249
|
+
- pub.dev workflow publishes before the matching GitHub Release assets exist
|
|
250
|
+
- pub.dev package still includes bundled binaries and blows the upload size limit
|
|
251
|
+
- smoke test invokes a TUI-first binary in a way that does not make sense for CI
|
|
252
|
+
- README badges and install commands drift out of sync with real package names
|
|
253
|
+
|
|
254
|
+
## Rule of thumb
|
|
255
|
+
|
|
256
|
+
If the native binary works and the wrappers are boring, distribution stays manageable.
|
|
257
|
+
|
|
258
|
+
If a wrapper starts acting like its own product, complexity grows fast.
|
|
259
|
+
|
|
260
|
+
Keep it thin.
|
|
261
|
+
Keep it aligned.
|
|
262
|
+
Keep the Rust binary as the source of truth.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: git
|
|
3
|
+
description: Git workflow rules for this repository.
|
|
4
|
+
allowed-tools: Read, Write, Edit, Glob, Grep, AskUserQuestion
|
|
5
|
+
user-invocable: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Git skill
|
|
9
|
+
|
|
10
|
+
## Core rule
|
|
11
|
+
|
|
12
|
+
- Use `--no-ff`. Important.
|
|
13
|
+
|
|
14
|
+
## What this means in practice
|
|
15
|
+
|
|
16
|
+
- Do not fast-forward merge feature branches, release branches, or hotfix branches.
|
|
17
|
+
- Prefer explicit merge commits so the branch history stays visible.
|
|
18
|
+
- Release prep goes through `development` on its way to `main`, with `--no-ff` at every hop.
|
|
19
|
+
- Tag the merge commit that contains the final release state.
|
|
20
|
+
|
|
21
|
+
## Branch flow
|
|
22
|
+
|
|
23
|
+
Feature branches merge into `development`. Releases go:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
release/vX.Y.Z -> development -> main
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Never merge a release branch straight into `main` — `development` has to carry the
|
|
30
|
+
release state too, or the next feature branch starts from a base that is missing it.
|
|
31
|
+
|
|
32
|
+
## Release guidance
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# 1. cut the release branch from development, commit the version bumps
|
|
36
|
+
git checkout development
|
|
37
|
+
git checkout -b release/vX.Y.Z
|
|
38
|
+
git commit -am "Prepare vX.Y.Z"
|
|
39
|
+
|
|
40
|
+
# 2. release branch -> development
|
|
41
|
+
git checkout development
|
|
42
|
+
git merge --no-ff release/vX.Y.Z -m "Merge release prep for vX.Y.Z"
|
|
43
|
+
|
|
44
|
+
# 3. development -> main
|
|
45
|
+
git checkout main
|
|
46
|
+
git merge --no-ff development -m "Merge development for vX.Y.Z"
|
|
47
|
+
|
|
48
|
+
# 4. tag the main merge commit, then push
|
|
49
|
+
git tag vX.Y.Z
|
|
50
|
+
git push origin development
|
|
51
|
+
git push origin main
|
|
52
|
+
git push origin vX.Y.Z
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The tag belongs on the step-3 merge commit on `main`, not on the release branch and not
|
|
56
|
+
on `development`. Pushing the tag is what triggers the wrapper publish workflows, which
|
|
57
|
+
read the version from the tag.
|
|
58
|
+
|
|
59
|
+
If the work is already on `main`, make a normal commit and tag that commit. Do not rewrite history just to avoid a merge commit.
|
|
60
|
+
|
|
61
|
+
## Avoid
|
|
62
|
+
|
|
63
|
+
- `git merge --ff`
|
|
64
|
+
- `git pull --ff-only` as a default recommendation for this repo's merge policy
|
|
65
|
+
- Tagging a branch tip that has not been merged into `main` when the intended release source of truth is `main`
|
|
66
|
+
- Merging a release branch directly into `main`, skipping `development`
|
|
67
|
+
|
|
68
|
+
## Why
|
|
69
|
+
|
|
70
|
+
The repo wants explicit history. Release commits should be easy to find, easy to audit, and clearly connected to the branch that introduced them.
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: release
|
|
3
|
+
description: Use whenever cutting, preparing, tagging, or publishing an onde-cli release — version bumps, release branch, merges, tagging, pushing to trigger the publish pipeline, and verifying it landed. Also use when a release went wrong (wrong tag target, failed crates.io verify, development left behind main, unsigned release commits) and the repo state needs repair. Trigger even if the user only says "release vX.Y.Z", "bump the version", "tag a release", or "publish the new version".
|
|
4
|
+
user-invocable: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Release skill
|
|
8
|
+
|
|
9
|
+
End-to-end release procedure for `onde-cli`. Complements the git skill (merge rules)
|
|
10
|
+
and the distribution skill (channel details) — this skill is the concrete runbook.
|
|
11
|
+
|
|
12
|
+
## Decide the version
|
|
13
|
+
|
|
14
|
+
- Look at `git tag -l 'v*' --sort=-v:refname | head -1` for the latest release.
|
|
15
|
+
- Look at the commits since (`git log v<latest>..development --oneline`).
|
|
16
|
+
Fixes and chores only → patch bump. New user-facing features → minor bump.
|
|
17
|
+
- Check for an abandoned `release/vX.Y.Z` branch — its version is usually the
|
|
18
|
+
intended next one. If it exists, inspect it (`git log development..release/...`)
|
|
19
|
+
before deciding to reuse or delete it; do not blindly `branch -D` without looking,
|
|
20
|
+
and never reuse a branch whose commits were made unsigned or by the wrong identity.
|
|
21
|
+
|
|
22
|
+
## Version bump surfaces
|
|
23
|
+
|
|
24
|
+
These files pin the crate version and must all move together:
|
|
25
|
+
|
|
26
|
+
- `Cargo.toml` — `version = "X.Y.Z"` in `[package]`
|
|
27
|
+
- `pub/onde_cli/pubspec.yaml` — `version: X.Y.Z`
|
|
28
|
+
- `server.json` — three occurrences: top-level `version`, and the npm and NuGet
|
|
29
|
+
`packages[].version` entries (search for the old version string to catch all)
|
|
30
|
+
|
|
31
|
+
`docs/mcp-registry.md` and `.github/workflows/release-mcp-registry.yml` mention
|
|
32
|
+
past versions only as historical examples — do not bump those.
|
|
33
|
+
|
|
34
|
+
The npm wrapper manifests are NOT bump targets: the committed `package.json` files
|
|
35
|
+
are rewritten at release time by `npm/scripts/render-*.cjs` from the tag.
|
|
36
|
+
|
|
37
|
+
After editing, run `cargo check --locked` (or let the build update `Cargo.lock`)
|
|
38
|
+
so the lockfile carries the new version, and commit it in the same bump commit.
|
|
39
|
+
|
|
40
|
+
## Sequence
|
|
41
|
+
|
|
42
|
+
Follow the git skill's branch flow — `release/vX.Y.Z → development → main`,
|
|
43
|
+
`--no-ff` at every hop, tag on the final `main` merge commit. Concretely:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
git checkout development
|
|
47
|
+
git pull <remote> development # start from the pushed tip
|
|
48
|
+
git checkout -b release/vX.Y.Z
|
|
49
|
+
# ... edit the bump surfaces ...
|
|
50
|
+
git commit -am "Prepare vX.Y.Z" # signed, correct identity (see below)
|
|
51
|
+
git checkout development
|
|
52
|
+
git merge --no-ff release/vX.Y.Z -m "Merge release prep for vX.Y.Z"
|
|
53
|
+
git checkout main
|
|
54
|
+
git pull <remote> main
|
|
55
|
+
git merge --no-ff development -m "Merge development for vX.Y.Z"
|
|
56
|
+
git tag vX.Y.Z
|
|
57
|
+
git push <remote> development main vX.Y.Z
|
|
58
|
+
git branch -d release/vX.Y.Z # only after the merge lands
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The remote here is the one whose URL is the sigit.si or GitHub org repo —
|
|
62
|
+
check `git remote -v`; this repo is commonly cloned with per-account remotes
|
|
63
|
+
(`gh-setoelkahfi`, `gh-paydii`, `gh-keypair34`) rather than `origin`.
|
|
64
|
+
|
|
65
|
+
### What a good result looks like
|
|
66
|
+
|
|
67
|
+
- The tag sits on the step-3 merge commit on `main` (`git log --graph main`
|
|
68
|
+
shows a merge commit directly above the previous release).
|
|
69
|
+
- `git log development..main` and `git log main..development` are both empty
|
|
70
|
+
after the merges — the two branches carry identical trees.
|
|
71
|
+
- Never tag a release-branch tip or a bare bump commit on `main`; if the work
|
|
72
|
+
somehow already landed on `main` linearly, follow the git skill's fallback
|
|
73
|
+
(normal commit, tag it) rather than rewriting history.
|
|
74
|
+
|
|
75
|
+
### Post-push back-merge check
|
|
76
|
+
|
|
77
|
+
If anything reached `main` without passing through `development` first (hotfix,
|
|
78
|
+
manual push, a fast-forwarded release), bring it back immediately:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
git checkout development
|
|
82
|
+
git merge --no-ff main -m "Merge main for vX.Y.Z"
|
|
83
|
+
git push <remote> development
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
A release is not done until the two branches contain the same tree.
|
|
87
|
+
|
|
88
|
+
## Commits and signatures — read the git-commit-signing skill first
|
|
89
|
+
|
|
90
|
+
Release commits must be GPG-signed by the maintainer identity that GitHub can
|
|
91
|
+
verify (this repo: `Seto Elkahfi <1797197+setoelkahfi@users.noreply.github.com>`,
|
|
92
|
+
EDDSA key `2B76DF0F04014E36`). The `gh` CLI's active account is independent of
|
|
93
|
+
git config — set both, and verify before pushing:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
git log -1 --format='%an <%ae> sig:%G? %GK' # want sig:G and the right key
|
|
97
|
+
gh api repos/<owner>/<repo>/commits/<sha> --jq .commit.verification.verified
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Every `git commit` and `git merge` in this flow creates a commit — configure
|
|
101
|
+
signing so merges are signed too, or amend unsigned ones before pushing
|
|
102
|
+
(`git commit --amend --no-edit -S`, only on unpushed commits).
|
|
103
|
+
|
|
104
|
+
Commit trailer: end release-related commit messages with
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
Co-Authored-By: siGit Code v1.6.7-acp <noreply@sigit.si>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## The tag push is the release
|
|
111
|
+
|
|
112
|
+
Pushing `vX.Y.Z` triggers `release-crates.yml`, which verifies the tag against
|
|
113
|
+
`Cargo.toml` and `pubspec.yaml`, publishes the crate, then dispatches the
|
|
114
|
+
wrapper workflows (GitHub Releases, npm, NuGet, PyPI, then Homebrew and pub.dev
|
|
115
|
+
after the GitHub Release assets exist). There is no separate "publish" step.
|
|
116
|
+
|
|
117
|
+
Watch it land:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
gh run list --branch vX.Y.Z
|
|
121
|
+
gh run watch <run-id> --exit-status
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`CI` also runs on the tag push; both should be green. If `release-crates` fails,
|
|
125
|
+
no wrapper publishes — fix the cause, move the tag only if it has not published
|
|
126
|
+
anything yet (crates.io versions are immutable; a failed verify is safe to retry,
|
|
127
|
+
a published crate is not).
|
|
128
|
+
|
|
129
|
+
## Verify
|
|
130
|
+
|
|
131
|
+
After the pipeline finishes, spot-check the fan-out (all idempotent, safe to re-check):
|
|
132
|
+
|
|
133
|
+
- crates.io: `cargo search onde-cli --limit 1`
|
|
134
|
+
- GitHub Release: `gh release view vX.Y.Z`
|
|
135
|
+
- npm: `npm view onde-cli version`
|
|
136
|
+
- PyPI: `https://pypi.org/pypi/onde-cli/json` → `info.version`
|
|
137
|
+
- NuGet: flat container index for `onde-cli`
|
|
138
|
+
- Homebrew/pub.dev trail the GitHub Release; they may take a few extra minutes
|
|
139
|
+
|
|
140
|
+
## Failure modes seen before
|
|
141
|
+
|
|
142
|
+
- Fast-forwarding `main` to the bump commit and tagging it — leaves no merge
|
|
143
|
+
commit, and leaves `development` behind. Back-merge `main` into `development`
|
|
144
|
+
right away and prefer merge commits next time.
|
|
145
|
+
- Deleting a leftover `release/` branch that contained unsigned bump commits and
|
|
146
|
+
redoing the bump fresh — fine, but check it first.
|
|
147
|
+
- Forgetting `Cargo.lock` in the bump commit.
|
|
148
|
+
- Pushing with the wrong `gh` account active — the push works, but PR/issue
|
|
149
|
+
actions afterwards get attributed to the wrong identity.
|