From a Fresh Clone
Reproducing Tidemark starts from an empty directory and what the repository cannot supply, meaning mise, the tool that installs everything else, and a free NASA Earthdata account for the satellite data, beside an optional AVISO+ account for the Level 3 products. This page covers the path from a clone to a machine ready to fetch, in the order a new reader takes it.
Install the Toolchain
mise reads .mise/config.toml and installs every tool it pins, meaning the Python interpreter, uv, the Bun and Node.js this site builds with, and the gh, lychee, and zizmor that the tasks reaching GitHub, checking the site's links, and auditing the workflows run, each at the version whose download address and checksum .mise/mise.lock records. A Mac runs macOS 15 or later, the oldest release netCDF4's wheels install on, since on an older macOS its source build needs the netCDF-C and HDF5 libraries. mise's installer for each shell installs mise and appends a line running mise activate to that shell's startup file. On macOS, whose default shell is zsh, run:
bash
curl -fsSL https://mise.run/zsh | shOn Linux, WSL included, whose default shell is bash, run:
bash
curl -fsSL https://mise.run/bash | shWhere mise is already installed, such as through Homebrew, append the activation alone instead, each line reaching only the shell whose startup file it names:
bash
echo 'eval "$(mise activate zsh)"' >> ~/.zshrc
echo 'eval "$(mise activate bash)"' >> ~/.bashrcClone and Install
Once the activation line above is written, open a new terminal, since activation reaches only a shell started after it, then clone the repository (which needs access to nucapstone/tidemark while the repository is private), and install the rest:
bash
git clone https://github.com/nucapstone/tidemark.git
mise trust tidemark
mise -C tidemark install
cd tidemark
tidemarkmise trust tidemarkmarks the clone's own configuration as onemisemay read, which mise 2026.10.9'smise installalso does on its own, as mise's account of implicit trust sets outmise -C tidemark installtakes each pinned tool from the address the lockfile records for the machine's platform, and stops where the lockfile has none, rather than finding the tool some other waycd tidemarkenters the clone once its tools are in place, so the shell's path gains each tool's folder and.mise/binas the directory changes, and a block pasted whole runstidemarkon its last linetidemarkruns.mise/bin/tidemark, which builds.venvfromuv.lockthroughuv run --exact --lockedon the interpretermiseinstalled, before the command prints its help, so the package needs no install step of its own
A bare tidemark is found only in a shell running mise activate, since activation is what puts .mise/bin on the path. A shell relying on mise's shims alone or an editor's terminal that mise does not activate runs mise x -- tidemark instead, which applies the same configuration to that one command.
uv is held to the same standard as mise, in that it never downloads an interpreter of its own and refuses a uv.lock that lags pyproject.toml, rather than rewriting it, while --exact removes any package the lockfile no longer names. A clone therefore runs on the versions the lockfiles name, or stops with an error that says which file is behind.
On Windows
Tidemark runs on macOS and Linux, and on Windows, it runs in the Linux that WSL 2 provides, so a Windows machine first sets that Linux up:
- Open PowerShell as an administrator, run
wsl --install, and restart, which installs WSL 2 with Ubuntu - Open Ubuntu from the Start menu and choose the Linux username and password it asks for on its first launch
- Inside Ubuntu, run the Linux line under Install the Toolchain,
curl -fsSL https://mise.run/bash | sh, which installsmiseand activates it in bash, then open a new Ubuntu terminal - Run
sudo apt install -y jq, which installs thejqthat the Claude Code hooks read each payload through, since a fresh Ubuntu does not carry it
Every command on this page then runs from Ubuntu, with the clone in the Linux home directory, rather than under /mnt/c, since Microsoft advises keeping files in the WSL file system when working from a Linux command line. An editor installed on Windows opens the clone through its WSL support, such as VS Code's WSL extension, which code . starts from inside the clone.
Check the Machine
mise doctor project runs one check for each thing a clone needs beyond the tools and prints whether each passed. The checks only read the machine, so on a fresh clone, the venv check fails until the first tidemark has built .venv, and the earthdata check fails until the login below is saved, whereas the aviso check, once .venv exists, passes until an AVISO+ login is saved and then fails where AVISO turns that login down or cannot be reached. A failing check prints the hint in the last column, which names the command that supplies what is missing or the status page to read when a service is down.
| Check | What It Confirms | When It Fails |
|---|---|---|
activated | mise is activated in the shell, which is what puts .mise/bin on the path | Run curl -fsSL https://mise.run/zsh | sh on macOS or curl -fsSL https://mise.run/bash | sh on Linux, WSL included, then open a new terminal, since activation reaches only a shell started after it. Where mise came from elsewhere, such as Homebrew, run echo 'eval "$(mise activate zsh)"' >> ~/.zshrc, or the bash form with ~/.bashrc, instead |
aviso | An AVISO+ login, where one is saved, opens a SWOT Level 3 file on AVISO's THREDDS server, and a clone saving none passes while the login is optional | Once the venv check passes, run mise run data:login:aviso to save the login again, or check that the account lists the SWOT Level 3 products under My products on https://www.aviso.altimetry.fr/ |
clone | The clone carries its full history rather than a shallow copy of it | Run git fetch --unshallow origin to download the rest of the history |
coops | The host serving NOAA's CO-OPS Data API and metadata API answers, so a fetch can read each NOAA station's water levels and a catalog rebuild its metadata | Check https://tidesandcurrents.noaa.gov/ for an outage before rerunning mise run data:fetch:gauges or mise run data:catalog |
earthdata | A NASA Earthdata login is available and has not expired | Once the urs and venv checks pass, run mise run data:login:earthdata to save a login to ~/.netrc, since a failure in either of those checks fails this one as well |
erddap | The NERACOOS ERDDAP answers, so a fetch can read the low-cost gauges' series | Check https://data.neracoos.org/ |
jq | jq is installed, which .claude/hooks/hook.sh reads each hook payload's cwd through | On Ubuntu, WSL included, run sudo apt install -y jq, and elsewhere install it through the system's package manager |
lockfile | uv.lock, .mise/mise.lock, docs/bun.lock, and each task script's own lockfile resolve what their manifests declare, and no published advisory names a package version uv.lock, a script's lockfile, or docs/bun.lock pins | Run mise run lock:sync to re-resolve every lockfile against its manifest, or move a package a published advisory names to the version the advisory gives as fixed. Where uv audit or bun audit could not reach its advisory database, rerun once the network is back |
opendap | PO.DAAC's OPeNDAP service answers, so a fetch can request the lines of each SWOT pass near the gauges | Check https://status.earthdata.nasa.gov/ for an outage before rerunning the fetch |
podaac | PO.DAAC's archive answers, so a fetch can download the whole of each SWOT pass the OPeNDAP service does not serve | Check https://podaac.jpl.nasa.gov/ for an outage notice before rerunning the fetch |
urs | Earthdata Login answers, so a fetch can get the token it needs | Check https://status.earthdata.nasa.gov/ for an outage before rerunning the fetch |
usgs | The USGS Water Data API answers, so a fetch can read each USGS gauge's water levels and a catalog rebuild its monitoring location | Check https://api.waterdata.usgs.gov/ for an outage before rerunning mise run data:fetch:gauges or mise run data:catalog, and where a fetch names the hourly limit on requests, rerun once the seconds it names have passed, or save an API key with mise run data:login:usgs, which raises that limit |
venv | .venv was built on the interpreter .mise/config.toml pins | Run mise x -- uv venv --clear and then mise x -- uv sync, which rebuild .venv on the interpreter mise pins, since uv sync alone keeps a .venv whose interpreter still meets requires-python |
workspace | The directory holding every worktree carries a .claude whose links still reach a worktree, which is what a session started there reads its agents, settings, hooks, and skills from | Run mise run workspace:link from an up-to-date worktree, which links what a session reads from its .claude/ into that directory |
The table above is written from the [doctor.checks] tables in .mise/config.toml, so a check added there reaches this page through mise run docs:render.
Save the Earthdata Login
Fetching SWOT passes needs a NASA Earthdata login, which earthaccess looks for in three places, in this order:
- The
EARTHDATA_TOKENvariable - The
EARTHDATA_USERNAMEandEARTHDATA_PASSWORDpair - The
urs.earthdata.nasa.goventry in~/.netrc
A token in EARTHDATA_TOKEN lasts 60 days from when Earthdata Login issues it, whereas a username and password never expire this way, since every login asks Earthdata for a token again.
Everyone working on the project registers their own account, because Earthdata allows two valid tokens at a time and answers a request for another by returning one it already issued, so a team sharing one account would hand the same two tokens back and forth. No workflow holds a login, so no CI row runs a check that needs one. Neither accepting a EULA nor authorizing an application, the other consents Earthdata keeps, stands between a new account and the SWOT product.
After creating the account, log in once:
bash
mise run data:login:earthdataWhen none of the three is set, the task prompts for a username and password, offering the username the urs.earthdata.nasa.gov entry already holds, so a changed password is the one field left to fill, and refusing an entry holding nothing but whitespace. It checks what was typed against Earthdata before anything reaches disk, then writes that entry, changing no other line of ~/.netrc, and creates ~/.urs_cookies and ~/.dodsrc wherever either is missing, so every later fetch authenticates without a prompt.
A new entry goes ahead of a default entry, which the GNU Inetutils manual's description of the file places after every machine entry. The task closes by printing the account, the day its token expires, and how many days remain, adding what to do once a week or less is left, a threshold this project sets rather than Earthdata. tidemark login earthdata, the subcommand behind the task, lists each way the login can fail.
Save a USGS Key
The USGS Water Data API answers without a key up to an hourly limit on each address, which one whole fetch of every USGS gauge can spend, whereas a free API key raises that limit. Its signup form asks for a first name, a last name, and an email address, beside an optional description of the use and the terms, then shows the key and emails it, usable at once. Each request to the API sends the key in its X-Api-Key header, read from the first of these holding one:
- The
API_USGS_PATvariable, which USGS's own Python and R clients read, so oneexport API_USGS_PAT=...serves all three - The
api.waterdata.usgs.goventry in~/.netrc
After signing up, log in once:
bash
mise run data:login:usgsThe task prompts for the key without showing it, asks the API for one monitoring location with it, and only then writes that entry. tidemark login usgs, the subcommand behind the task, lists each way the login can fail.
Save the AVISO+ Login
AVISO publishes the SWOT Level 3 products through its THREDDS server, whose catalog lists every file without a login, whereas each download and each OPeNDAP request takes the username and password of a free AVISO+ account. mise run data:fetch:swot l3 is the one command that fetches a Level 3 file, and it seeds every Level 3 pass the newest release carrying them holds without a login, so the login is optional, needed only for a pass the release lacks, and a clone without it fetches every Level 2 pass. A teammate fetching the Level 3 products registers an account of their own, as for Earthdata. On an older account, add the SWOT Level 3 products on the My products page of MY AVISO+, since a new account holds every product from the start. Once AVISO's emails with the login details arrive, log in with the account's email address as the username:
bash
mise run data:login:avisoThe task prompts for a username and password, asks the server for the first file of the reprocessed Level 3 Expert product with them, since an account holding the SWOT Level 3 products opens its Unsmoothed files the same way, and only then writes the tds-odatis.aviso.altimetry.fr entry beside the Earthdata entry in ~/.netrc, which requests reads on every later request, so each Level 3 file arrives without a prompt. The aviso check above runs tidemark login aviso --check, which asks for the same file with the saved entry and passes a clone holding none, and tidemark login aviso, the subcommand behind the task, lists each way the login can fail.