Metadata-Version: 2.4
Name: mooring
Version: 0.4.7
Summary: Git-free marimo notebook sharing via GitHub
Requires-Python: >=3.12
Requires-Dist: keyring
Requires-Dist: marimo>=0.23.9
Requires-Dist: platformdirs
Requires-Dist: pyyaml>=6
Requires-Dist: requests
Requires-Dist: starlette
Requires-Dist: tomli-w>=1.2.0
Requires-Dist: truststore
Requires-Dist: uvicorn
Provides-Extra: copilot
Requires-Dist: github-copilot-sdk>=1.0.1; extra == 'copilot'
Provides-Extra: pii
Requires-Dist: gliner>=0.2.13; extra == 'pii'
Provides-Extra: pii-spacy
Requires-Dist: mooring-spacy-en-md; extra == 'pii-spacy'
Requires-Dist: spacy<3.9,>=3.8; extra == 'pii-spacy'
Description-Content-Type: text/markdown

# ⚓ mooring

Git-free [marimo](https://marimo.io) notebook sharing via GitHub.

Mooring is a single-file app (`mooring.pyz` / `mooring.exe`) that lets a team
of data analysts pull, edit, and push marimo notebooks stored in a shared
GitHub repo — **without git installed on their machines**. All sync happens
over the GitHub REST API; the only requirement on an analyst's machine is
Python 3.12 or newer.

Double-clicking the app opens a local browser **hub**: log in to GitHub with
a one-time device code, see every team notebook with its sync status, pull
the latest, open notebooks in the bundled marimo editor, and push your
changes back — one commit per file, with conflicts detected and resolved
per file (never silently overwritten).

## How it works

- **One shared team repo** (e.g. `your-org/notebooks`) holds `notebooks/`,
  `data/`, and `reports/` folders. Everyone pulls from and pushes to it.
- **No git anywhere.** Pull walks the repo tree via the GitHub Git Data API
  and downloads only changed blobs; push uses the Contents API with the
  file's last-known SHA, so GitHub itself rejects writes that would clobber
  someone else's change.
- **Conflicts are explicit.** Pull never overwrites local edits; push blocks
  conflicted files, offering per-file resolution.
- **Push or propose.** Push commits straight to the shared branch; **propose**
  sends changes to a personal review branch so they can land via a pull
  request — protect the branch and propose becomes the only way in.
- **Dependencies live with the repo.** A repo declares its notebook packages in
  a `pyproject.toml` + `uv.lock` at its root (run `mooring init`, then
  `mooring deps add <pkg>`), version-controlled alongside the notebooks. With uv,
  notebooks run in that locked environment automatically; mooring itself ships
  lean (no opinionated analyst stack baked in). For machines with no uv, an admin
  builds a frozen `.pyz` whose bundle is generated from that same `pyproject.toml`
  — one source of truth, two delivery modes (see
  [build & distribute](docs/admins/build-and-distribute.md)).
- **Works on corporate GitHub.** GitHub Enterprise instances are supported
  (`mooring login --host ghe.example.com`), and TLS is verified against the
  OS trust store, so SSL-intercepting proxies with an IT-installed root CA
  just work.

## Install from PyPI

With **Python 3.12+** and [uv](https://docs.astral.sh/uv/), run Mooring straight
from PyPI — no frozen build needed:

```
uvx mooring                  # run it as a one-off tool
uv tool install mooring      # …or install it as a persistent CLI
pip install mooring          # …or into the active environment
```

### Optional extras

Mooring ships lean; opt-in features live behind extras. **Quote the brackets** —
`[...]` is a shell glob, so an unquoted `mooring[copilot]` can expand to nothing:

| Extra | Enables |
|-------|---------|
| `copilot` | the AI copilot |
| `pii` | NER name detection for the PII guard |
| `pii-spacy` | offline name detection (air-gapped teams) |

```
uvx "mooring[copilot]"               # one-off tool run
uv tool install "mooring[copilot]"   # persistent CLI tool
uv add "mooring[copilot]"            # add to your own uv project
pip install "mooring[copilot]"       # plain pip
```

Combine with a comma (`"mooring[copilot,pii]"`). Full reference:
[optional extras](docs/admins/build-and-distribute.md#optional-extras).

## Documentation

Full docs live in [`docs/`](docs/) and build into a searchable site with
[zensical](https://zensical.org):

- **[For users](docs/users/index.md)** — install Python, run the app, and
  pull / edit / push notebooks ([daily workflow](docs/users/daily-workflow.md),
  [conflicts](docs/users/conflicts.md), [CLI](docs/users/cli.md)).
- **[For admins](docs/admins/index.md)** — set up a team:
  [GitHub setup](docs/admins/github-setup.md) (the repo, OAuth app, client id,
  scopes), [configuration](docs/admins/configuration.md), and
  [build & distribute](docs/admins/build-and-distribute.md).
- **[For developers](docs/developers/index.md)** —
  [architecture](docs/developers/index.md) and
  [contributing](docs/developers/contributing.md).

### Build & preview the docs

```
uv sync
uv run zensical serve     # live-reloading preview at a local URL
uv run zensical build     # static site into ./site
```

`.github/workflows/docs.yml` publishes the site to GitHub Pages on every push
to the default branch.

## Develop

```
uv sync                                  # install everything
uv run pytest                            # unit tests (no network needed)
uv run ruff check src tests              # lint
uv run mooring hub                       # run the hub from source
```

See [contributing](docs/developers/contributing.md) for the architecture,
integration testing, and project conventions.

---

Built with [moonlit](https://github.com/openafterhours/moonlit).
