Metadata-Version: 2.4
Name: zeno-cli
Version: 0.3.8
Summary: Zeno CLI - measure the supervision cost of AI-assisted work
Project-URL: Homepage, https://zeno.center
Project-URL: Repository, https://github.com/Marwan01/zeno
Author-email: Mar Helali <mar@1dev.space>
License-Expression: Apache-2.0
Keywords: ai,claude-code,cognitive-load,rtlx-s,session-analytics,supervision
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development
Requires-Python: >=3.12
Requires-Dist: aiosqlite>=0.20.0
Requires-Dist: alembic>=1.13.2
Requires-Dist: keyring>=25.3.0
Requires-Dist: matplotlib>=3.9.2
Requires-Dist: numpy>=2.0
Requires-Dist: pydantic>=2.9.0
Requires-Dist: rich>=13.8.1
Requires-Dist: scipy>=1.14.1
Requires-Dist: textual>=0.86.1
Description-Content-Type: text/markdown

# zeno-cli

Measure the supervision cost of AI-assisted work, from your terminal. `zeno`
records RTLX-S load probes + session activity, fits your personal "babysitting
tax" curve, and surfaces where your optimal number of parallel agents sits.

## Install

Install the `zeno` CLI straight from the monorepo over SSH. It is one
self-contained package: the SDK, core, adapters, session-intelligence engine,
and SQLite migrations all ship inside it. Requires **Python >= 3.12** and GitHub
SSH access to the repo.

```sh
uv tool install \
  --from "git+ssh://git@github.com/Marwan01/zeno.git@cli-v0.3.3#subdirectory=apps/cli" \
  zeno-cli
```

`pipx install "git+ssh://git@github.com/Marwan01/zeno.git@cli-v0.3.3#subdirectory=apps/cli"`
works the same way. The git clone runs an in-tree build, so the hatchling build
hook (`apps/cli/hatch_build.py`) vendors the workspace packages into the wheel.
**Update** by bumping the tag: re-run with `@cli-v0.3.3` (uv) or
`pipx install --force ...@<newtag>`.

**Why git+ssh and not an index:** TestPyPI is not a durable distribution channel
and a private index is overkill at team scale. A public PyPI wheel comes only
when non-repo-access users do. The packaging blocker for it is now resolved - the
build is sdist-clean (`uv build --sdist` -> a wheel built from that sdist installs
and runs every verb; see the build-hook note under [Packaging](#packaging-notes)),
so the remaining gate is purely "do public users exist yet", not a broken build.

### Install channels (staged)

The distribution channel widens as the audience does. Use the one that matches
where the project is, not the most convenient:

| Stage | Channel | Command | Status |
| :--- | :--- | :--- | :--- |
| Now | git+ssh tag | `uv tool install --from "git+ssh://git@github.com/Marwan01/zeno.git@cli-v0.3.3#subdirectory=apps/cli" zeno-cli` | Live (needs repo SSH access) |
| Next | PyPI | `uv tool install zeno-cli` (or `pipx install zeno-cli`) | Lands when `.github/workflows/publish.yml` runs on the first GitHub release; the packaging metadata is ready |
| Later | Homebrew | `brew install zeno-cli` | Formula not written yet |

The PyPI publish is OIDC Trusted-Publishing gated and fires only on a published
GitHub release - see `.github/workflows/publish.yml`. Until that first release,
the git+ssh tag is the supported path.

**From a built wheel** (offline / air-gapped; the wheel is fully self-contained):

```sh
uv build --wheel --package zeno-cli          # -> dist/zeno_cli-*.whl
uv tool install ./dist/zeno_cli-0.3.3-py3-none-any.whl
```

**From source** (development inside the monorepo, no install):

```sh
uv run --project /path/to/zeno zeno <cmd>
```

New here? Follow `docs/ADOPT.md` for the 10-minute install -> capture -> survey loop.

## Use

```sh
zeno survey        # log how a session felt (~6s, RTLX-S 5-item probe)
zeno status        # tier, streak, tax curve, cognitive state, today's survey
zeno curve         # render the babysitting-tax curve (needs ~10 sessions of data)
zeno weekly        # 7-day rollup
zeno doctor        # health check: API reachability + identity
zeno login         # browser sign-in; stores a Clerk JWT in the OS keyring
zeno whoami        # show the identity + tier the API sees for your token
zeno logout        # clear the stored token
```

### Authentication

`zeno login` runs a browser + loopback sign-in and stores the resulting Clerk
JWT in your OS keyring; the CLI sends it as a `Bearer` token so the API
attributes requests to your user. Token resolution order, used by every
command: `ZENO_API_TOKEN` env override first, then the keyring token from
`zeno login`, then none (local-only). Use `zeno login --no-browser` for SSH /
headless (prints the URL), and `--authorize-url` / `ZENO_LOGIN_AUTHORIZE_URL`
to target a non-default bridge.

> The dashboard `/cli/authorize` bridge page + the Clerk `zeno-api` JWT template
> that mint the token are a documented follow-up (not yet shipped). See
> `src/zeno_cli/login.py` for the callback contract.

Full daily-loop guide: `docs/CLI_QUICKSTART.md`. Requires Python >= 3.12.

## Cognition HUD add-on

`zeno-hud-bar` is the single differentiated cognition line (`att / eff / drv`) that
stacks UNDER whatever popular HUD you already run, instead of replacing it. Claude Code
has one statusLine slot, so zeno rides the HUD you have:

```sh
zeno hud install            # auto-detect: ccstatusline (native widget) or claude-hud (wrapper)
zeno hud install --dry-run  # print what would change, write nothing
zeno hud status             # what is detected + whether the line is wired in
zeno hud uninstall          # remove from both adapters (idempotent; --restore for byte-for-byte)
```

`--target {auto,ccstatusline,claude-hud}` forces an adapter (auto prefers ccstatusline
when both are present). Every edit is backed up and reversible. The bar is crash-safe: on
any error it prints an empty line and exits 0, so it never breaks the host HUD. Full model
and both recipes: `docs/HUD_ADDON.md`.

## Packaging notes

- **sdist-clean via a build hook.** `apps/cli/hatch_build.py` (a custom hatchling
  build hook, enabled on BOTH the `wheel` and `sdist` targets) vendors the four
  workspace packages (`zeno_core` / `zeno_sdk` / `zeno_adapters` /
  `zeno_session_intel`) plus the SDK alembic tree into an in-root, gitignored
  `_vendor_build/` stage at build time. The wheel target flattens them to the
  archive top level (the exact layout the old static `force-include` produced, so
  absolute imports resolve unchanged); the sdist target ships the whole
  `_vendor_build/` stage inside the tarball so a wheel built FROM the sdist finds
  the sources locally. This replaced the static `[tool.hatch...force-include]` of
  `../../packages/...` relative-parent paths, whose `..` escaped the sdist root and
  were silently dropped - a wheel from that sdist died with "Forced include not
  found". Repo source under `packages/*` is never moved, so the uv workspace, the
  API, and the test suite keep importing the editable members unchanged; the
  vendored copy is purely a build artifact.
- `zeno ingest` / `zeno usage` are backed by `zeno_session_intel`, vendored
  alongside the other internal packages by the build hook. It is stdlib-only with
  relative-only internal imports, so it flattens into the wheel with zero import
  rewrites. Omit it and both subcommands abort with a "not bundled" hint at runtime
  (the regression fixed in 0.3.3); `scripts/install-smoke.sh` now exercises every
  advertised subcommand so this cannot ship silently again.
- Agent-framework adapters (`zeno_sdk.adapters` -> crewai / openai / anthropic /
  langgraph) are off the CLI path and pull heavy framework deps; they are kept
  optional and will be exposed as extras (e.g. `zeno-cli[crewai]`) in a later stage.
