OceanCode
Distribution and updates
oceancode ships as two self-contained binaries: the engine oceancode and the terminal UI
ocean-pager it launches, installed side by side. This page covers installing it, keeping it
current, verifying a download, and removing it. Every download is checksummed, and every install
channel agrees on one set of release-asset names.
Installing
| Channel | Command |
|---|---|
| macOS / Linux (script) | curl -fsSL https://raw.githubusercontent.com/OWNER/ocean-coding-agent/main/packaging/install/install.sh | sh |
| Windows (PowerShell) | irm https://raw.githubusercontent.com/OWNER/ocean-coding-agent/main/packaging/install/install.ps1 | iex |
| Homebrew (macOS / Linux) | brew install OWNER/oceancode/oceancode |
| Cargo (Rust-native, npm-free) | cargo install --locked --path crates/ocean-cli (from a clone today; cargo install --locked oceancode once published) |
The script installer downloads the release asset for your platform, verifies it (see
Verifying a download), and installs oceancode and ocean-pager into
${OC_INSTALL_DIR:-$HOME/.local/bin} (Windows %USERPROFILE%\.oceancode\bin). If that directory
is not on your PATH, the installer prints the line to add. See
02 · Configuration for OC_INSTALL_DIR and the other install knobs.
cargo install is npm-free by design — the whole toolchain is Rust; no Node package is pulled at
build or install time. See packaging/homebrew/cargo-install.md.
Keeping current — oceancode update
oceancode update # update to the newest release for your channel
oceancode update --self-test # prove the swap + rollback offline (no network)update fetches the newest release for the configured channel, never downgrades, verifies the
release signatures, swaps oceancode and ocean-pager atomically, and rolls both back if either
new binary fails a health check — so a failed update leaves the working pair exactly as it was.
--self-test prints UPDATE_SELF_TEST_OK binaries=2 as its last line.
Channels and opt-out:
| Setting | Where | Effect |
|---|---|---|
update.channel | config (oceancode.json) | stable (default) or beta (sees pre-releases). |
OC_UPDATE_CHANNEL | env | Overrides update.channel for one run. |
update.auto_check | config | true (default) checks for a newer release on boot. |
OC_NO_UPDATE_CHECK | env | Any value suppresses the boot-time check. |
update.endpoint | config | Overrides the release-metadata source (default: GitHub Releases). |
Telemetry-free first run. The boot-time update check is always skipped on the very first run
(and whenever update.auto_check is false or OC_NO_UPDATE_CHECK is set): a fresh install never
phones home before you ask it to.
Verifying a download
Every release ships a single SHA256SUMS manifest and a detached minisign signature
(<asset>.minisig) per asset. Verify a download before trusting it — the same check on macOS,
Linux and Windows, with no external tool:
oceancode verify-release oceancode-macos-aarch64.tar.gz \
--sha256sums SHA256SUMSIt prints VERIFY_RELEASE_OK file=<name> on success and refuses (non-zero exit) on any mismatch.
--pubkey <base64> overrides the embedded release public key.
Signing tiers. Releases are signed with minisign on every platform. When an Apple Developer ID
(macOS) or an Authenticode certificate (Windows) is available, the release also carries OS-native
codesigning / notarization. When no such certificate is present, the release ships unsigned at the
OS level but with SHA256SUMS + minisign — the portable trust root above still applies, and the
installer stays fail-closed (it refuses to install an unverifiable artifact unless you pass
--insecure-skip-verify / OCEANCODE_INSECURE_SKIP_VERIFY=1).
Test key notice. The public key embedded in
oceancode verify-release(verify_release::EMBEDDED_PUBKEY) and in the installers is a deterministic test key. The release owner must replace it with the real minisign public key before shipping a signed release.
Uninstalling
oceancode uninstall # remove the binary only
oceancode uninstall --purge # also remove ~/.config/oceancode and the data dir
oceancode uninstall --dry-run # print the plan, remove nothinguninstall removes only what the installer placed. --purge additionally removes the app's config
and data directories (the data dir holds auth.json, TUI state and the default global session
store) — never your per-project .oceancode/oceancode.db. It requires a typed oceancode
confirmation unless --yes, never follows a symlink out of its own tree, and prints
UNINSTALL_OK removed=<n>.
Windows notes
On Windows the bash tool spawns the shell selected by the shell.kind config key (default
auto → PowerShell). Tool output is normalized for cross-OS stability: \r\n and stray \r
become \n, and backslash paths are shown POSIX-style (C:/Users/...) for display only. ConPTY is
the PTY backend, and the console has ANSI/VT processing enabled so escape sequences render.
Release-asset naming contract
Every channel — the script installer, Homebrew, oceancode update, oceancode verify-release, the
download page and the release CI job — agrees on one naming scheme. This is the single source of
truth; a producer or consumer that disagrees is a bug to reconcile against it.
Per target, the release publishes BOTH:
oceancode-<os>-<arch>.tar.gz— a gzipped tar containing exactlyoceancodeandocean-pager. The script installer (macOS/Linux) and Homebrew download this and install both side by side.oceancode-<os>-<arch>— the bare binary (Windows:oceancode-<os>-<arch>.exe).oceancode updatedownloads this and stages it directly asoceancode.newfor the atomic swap, so it must NOT be an archive. On Windows the PowerShell installer also consumes this bare.exe.ocean-pager-<os>-<arch>— the bare TUI binary;oceancode updateswaps it together withoceancode(the engine runs inside the pager process, so the pair must match). If either fails its--versionhealth check after the swap, both are rolled back to their<name>.bak. A release without this asset updatesoceancodealone and warns that the TUI was not updated.
Plus, for every asset (the tarball and both bare binaries):
<asset>.minisig— a detached minisign signature, and- one
SHA256SUMS— a single manifest hashing every asset (no per-target manifest).
No version appears in any filename — the version lives in the release tag path and the download
manifest's version field.
rustc triple ↔ <os>-<arch> token
The <os>-<arch> token is oceancode update's platform_suffix() (std::env::consts::OS +
std::env::consts::ARCH), matched as a substring of the asset name — so the Linux -musl suffix
is tolerated. The installer's detect_asset (packaging/install/install.sh) names match the tarball
column.
| rustc triple | <os>-<arch> token | tarball (installer / Homebrew) | bare binary (oceancode update) | bare TUI (oceancode update) |
|---|---|---|---|---|
aarch64-apple-darwin | macos-aarch64 | oceancode-macos-aarch64.tar.gz | oceancode-macos-aarch64 | ocean-pager-macos-aarch64 |
x86_64-apple-darwin | macos-x86_64 | oceancode-macos-x86_64.tar.gz | oceancode-macos-x86_64 | ocean-pager-macos-x86_64 |
x86_64-unknown-linux-musl | linux-x86_64 | oceancode-linux-x86_64-musl.tar.gz | oceancode-linux-x86_64-musl | ocean-pager-linux-x86_64-musl |
aarch64-unknown-linux-musl | linux-aarch64 | oceancode-linux-aarch64-musl.tar.gz | oceancode-linux-aarch64-musl | ocean-pager-linux-aarch64-musl |
x86_64-pc-windows-msvc | windows-x86_64 | oceancode-windows-x86_64.tar.gz | oceancode-windows-x86_64.exe | ocean-pager-windows-x86_64.exe |
Because the .tar.gz and the bare binaries carry the same <os>-<arch> token, the update path
must select the bare binaries specifically (skip .tar.gz) and tells them apart by the
ocean-pager- prefix; the installer/Homebrew select the tarball.
Platform download-page contract
When update.endpoint is set, oceancode update fetches release metadata from the platform's
release endpoint (Track P / S11-T03; the canonical schema lives in
docs/platform-download-contract.md). The endpoint returns JSON of this shape — the platform and
the binary agree on the artifact list here:
{
"version": "0.8.8.01",
"channel": "stable",
"artifacts": [
{
"target": "aarch64-apple-darwin",
"url": "https://…/oceancode-macos-aarch64",
"sha256": "…",
"minisig": "https://…/oceancode-macos-aarch64.minisig"
}
]
}version and channel are strings; artifacts is one object per shipped target. url is the
bare binary oceancode update downloads and stages as oceancode.new (not the .tar.gz — that
is the installer's), sha256 matches its SHA256SUMS entry, and minisig is its detached
signature. This page documents the shape only; the endpoint itself is the platform's (Track P,
docs/platform-download-contract.md), not the binary's.
Release checklist
An ordered, mostly-automated release. Agents never publish or tag — the owner does the final GitHub Release and tap steps.
- Bump the version.
bash scripts/release/bump-version.sh <X.Y.Z.B>— moves the## UnreleasedCHANGELOG section under the new dated heading and updatesVERSION. The number isMAJOR.MINOR.PATCH.BUILD: the first three name the release (a human sets them with the explicit argument), the fourth is the build counter — everyscripts/release/build-release.shrun adds one to it on its own (0.8.8.01,0.8.8.02, …0.8.8.99,0.8.8.100; two digits minimum, never capped), so a build number is never reused and self-update treats a newer build of the same release as an update. The check.sh lanes build withNO_BUMP=1. Re-baselined to0.8.8.00on 2026-10-22 (the2.6.NNnumbers before it carried the build counter in the patch field). - CHANGELOG dated. Confirm the moved section reads correctly under
## 0.8.8.01 — <date>. - User-guide tables current.
node scripts/gates/check-user-guide.mjs→USER_GUIDE_OK … missing=0(everyOC_*var and subcommand has a row) andnode scripts/gates/check-changelog.mjs→CHANGELOG_OK. - Whole-tree green on three OSes.
./check.sh→ALL CHECKS PASSEDon macOS, Linux and Windows in CI. - Build the five targets.
bash scripts/release/build-all.sh(or the CIreleasejob's matrix) →BUILD_RELEASE_OK targets=5. Per target publish both the bareoceancode-<os>-<arch>(Windows.exe) and theoceancode-<os>-<arch>.tar.gz, using the<os>-<arch>tokens in the mapping table above — no version in any filename. - Per-artifact budgets.
RELEASE=1 ./check.sh(or the CI native legs) runssize-gate.shper artifact (≤ 40 MiB →SIZE_GATE_OK) andboot-bench.sh(< 36 ms →BOOT_BENCH_OK). - Sign.
bash scripts/sign/sign-artifacts.sh(minisign →SIGN_OK artifacts=<n>); where certificates exist,scripts/sign/codesign-macos.sh(Apple notarization) andscripts/sign/authenticode-windows.ps1(Windows Authenticode). - Checksums.
bash scripts/release/gen-sha256sums.sh dist→SHA256SUMS_OK count=<n>over the packaged assets. - Draft the GitHub Release (owner): upload the assets,
SHA256SUMSand each.minisig. - Homebrew tap (owner): mirror
packaging/homebrew/oceancode.rbto the tap with the realsha256s / bottle digests.
Owner-only steps (agents never do these)
- Replace
verify_release::EMBEDDED_PUBKEYand the installers' embedded minisign pubkey with the real release key. - Provision the CI secret
MINISIGN_SECRET_KEYand installminisignon the release runners. - Relocate
docs/plans/ci/oceancode.yml→.github/workflows/oceancode.yml. git tag/ publish the GitHub Release; push the Homebrew tap;cargo publish.
Release-notes template
# oceancode v<X.Y.Z>
## Highlights
- <the one or two changes users will notice first>
## Install
- macOS/Linux: `curl -fsSL <install.sh> | sh`
- Windows: `irm <install.ps1> | iex`
- Homebrew: `brew install OWNER/oceancode/oceancode`
- Cargo: `cargo install --locked oceancode`
## Verify
Download the asset for your platform and run:
`oceancode verify-release <asset> --sha256sums SHA256SUMS`
## Changed
- <user-visible changes from the CHANGELOG's dated section>
## Fixed
- <fixes from the CHANGELOG>
## Checksums
See `SHA256SUMS` and the per-asset `<asset>.minisig` attached to this release.See also
- 01 · Getting started — the install one-liners and first run.
- 02 · Configuration —
update.*,shell.kind,OC_UPDATE_CHANNEL,OC_NO_UPDATE_CHECK,OC_INSTALL_DIR. - 07 · Headless and server —
update/verify-release/uninstallas management subcommands.