Metadata-Version: 2.4
Name: blankstate-cli
Version: 0.1.1
Summary: Blankstate CLI — bks terminal commands for interaction measurement
Project-URL: Homepage, https://blankstate.ai
Project-URL: Documentation, https://api.blankstate.ai/docs
Project-URL: Repository, https://github.com/blankstate-ai/blankstate-py
Project-URL: Issues, https://github.com/blankstate-ai/blankstate-py/issues
Author-email: Blankstate <hello@blankstate.ai>
License-Expression: MIT
Keywords: blankstate,cli,protocol,sgm
Requires-Python: >=3.10
Requires-Dist: blankstate-sdk<0.2.0,>=0.1.1
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Requires-Dist: textual<2.0.0,>=0.74.0; extra == 'dev'
Provides-Extra: tui
Requires-Dist: textual<2.0.0,>=0.74.0; extra == 'tui'
Description-Content-Type: text/markdown

# blankstate-cli

Terminal interface for Blankstate (Python). Measure interactions, inspect protocols, and monitor your AI agents in real time — from the command line. This package provides the `bks` command and uses the [`blankstate-sdk`](https://pypi.org/project/blankstate-sdk/) library (`import blankstate_sdk`).

---

## Install

**Requirements:** Python **3.10+** and [`pip`](https://pip.pypa.io/).

### From PyPI (when published)

```bash
python3 -m venv .venv
source .venv/bin/activate          # Windows: .venv\Scripts\activate
python3 -m pip install --upgrade pip
python3 -m pip install blankstate-cli
bks --help
```

Install as a standalone tool (isolated environment, recommended for daily use):

```bash
pipx install blankstate-cli
bks --help
```

### From this monorepo (development)

From the **repository root** (`blankstate-py`), install the SDK and CLI in editable mode so imports resolve:

```bash
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install -e "./packages/sdk" -e "./packages/cli"
bks --help
```

If you only have the `packages/cli` tree, install the SDK path explicitly:

```bash
python3 -m pip install -e /path/to/blankstate-py/packages/sdk
python3 -m pip install -e /path/to/blankstate-py/packages/cli
```

Run without the `bks` script on `PATH`:

```bash
python3 -m blankstate_cli --help
```

---

## Authentication

```bash
# Interactive login — stores token in ~/.blankstate/config.json
bks auth login

# Check current auth and ICS balance
bks auth status

# Logout
bks auth logout

# Or set via environment variable (takes priority over saved config)
export BLANKSTATE_API_TOKEN=bks_your_token_here
```

Get a token at [atlas.blankstate.ai](https://atlas.blankstate.ai).

---

## Commands

### `bks status`

API health, engine versions, and ICS balance.

```
$ bks status

  API:           healthy
  Authenticated: true
  SGM versions:  1.0 · 1.5

  ICS cap:       40
  ICS used:      4
  ICS remaining: 36
  Period:        2026-03
```

---

### `bks protocol list`

List protocols in your account.

```
$ bks protocol list

  50 protocol(s):

  Customer Support Quality [SGM 1.0]
    ID:       proto-6d28a7b8-a905-45f3-81f5-2cd574813450
    Versions: 0.1, 0.2

  Agent Safety Monitor [SGM 1.5]
    ID:       proto-f302e022-1ed2-4546-abcb-e942239d5c79
    Versions: 1.0
```

---

### `bks protocol inspect <id>`

Full protocol definition with metamarkers.

```bash
bks protocol inspect proto-6d28a7b8-a905-45f3-81f5-2cd574813450

# Save a local YAML snapshot
bks protocol inspect proto-6d28a7b8-a905-45f3-81f5-2cd574813450 --save

# Alternate ID flag
bks protocol inspect --id proto-6d28a7b8-a905-45f3-81f5-2cd574813450
```

```
  Customer Support Quality
  ────────────────────────
  ID:          proto-6d28a7b8-a905-45f3-81f5-2cd574813450
  Version:     0.2
  SGM version: 1.0

  Metamarkers (9):
    - Solution-Oriented
    - Empathy
    - Professional Tone
    - Acknowledgment
    - Clarity
    ...
```

`--save` writes a `.yaml` file to `~/.blankstate/protocols/`.

---

### `bks sense <protocol> <content>`

Measure content against a protocol.

```bash
# Inline text
bks sense proto-xxx:1.0 "The agent resolved the customer's issue with clear steps."

# From a file
bks sense proto-xxx:1.0 --file transcript.txt

# Options
bks sense proto-xxx:1.0 "..." --profile discovery
bks sense proto-xxx:1.0 "..." --depth full
bks sense proto-xxx:1.0 "..." --save md         # save trace to ~/.blankstate/measurements/
bks sense proto-xxx:1.0 "..." --save yaml
bks sense proto-xxx:1.0 "..." --save both
```

The Python CLI prints a framed summary (spectral waveform, fidelity line, optional C×B×I bars, resonance dots, ICS/timing). Example layout (values illustrative):

```
  ┌─ SENSE ─ ... ─ SGM 1.0 ── 0.8200 ─┐
  │  proto-xxx:1.0                    │
  ├───────────────────────────────────┤
  │  ▁▂▃▄▅▆▇█ ... (waveform)          │
  │  ──────────────── fid 0.74 ─      │
  ...
```

| Flag | Description |
|------|-------------|
| `--file <path>` | Read content from file |
| `--language <code>` | Language code (default: `en`) |
| `--profile <type>` | `raw` \| `detailed` \| `discovery` |
| `--depth <level>` | `measure` (scores only) \| `full` (+ entities, evidence) |
| `--detail` | Show full resonance decomposition inline |
| `--save <format>` | `md` \| `yaml` \| `both` — save artifact to `~/.blankstate/measurements/` |
| `--trace` | Alias for `--save md` (also writes legacy `~/.blankstate/traces/`) |

---

### `bks session <protocol> [protocol...]`

Interactive sensing session. Type content, get a measurement. **Ctrl+C** to exit.

```bash
# Inline session — single protocol, stays in your terminal
bks session proto-xxx:1.0

# Pipe agent output
my-agent | bks session proto-xxx:1.0 --pipe

# Watch a log file for new lines (polled; appends are detected)
bks session proto-xxx:1.0 --watch ./agent-output.log

# Save session log (markdown under ~/.blankstate/sessions/)
bks session proto-xxx:1.0 --log

# Full-screen dashboard (Textual; optional extra)
pip install 'blankstate-cli[tui]'
bks session proto-xxx:1.0 --tui

# Optional: fake sparkline motion every second (demos only)
bks session proto-xxx:1.0 --tui --demo-spark

# Same dashboard with stdin lines (must be a pipe/redirect, not an interactive TTY)
my-agent | bks session proto-xxx:1.0 --tui --pipe

# Same dashboard while tailing a file (you can still type in the TUI)
bks session proto-xxx:1.0 --tui --watch ./agent-output.log

# Multi-protocol TUI — Tab picks ECG detail; each line is sensed against every pane (Node parity)
bks session proto-a:1.0 proto-b:1.0 --tui

# Verbose MCP / watch tracing (default TUI log is quiet)
bks session proto-xxx:1.0 --tui -v

# Replay entire events.jsonl from the beginning once (can be slow if the file is large)
bks session proto-xxx:1.0 --tui --mcp-replay
```

The **`--tui`** flag launches a Python [Textual](https://textual.textualize.io/) dashboard:

- **Overview:** one **sparkline row per protocol**. **`Tab`** selects which pane drives the **ECG detail** panel (wave, actants, last, timeline). **Typed lines, `--pipe`, and `--watch`** each run **`sense` in parallel on every loaded protocol** (same as Node `senseAll`).
- **Slash commands (TUI):** **`/list`**, **`/protocols`**, **`/browse`** — **interactive API browser** (Space toggles, Enter adds selected, Esc cancels); **`/add`**, **`/remove`** (max **9** panes; duplicate **base** protocol ids rejected; failed API lookup still adds raw id); **`/chronicle`**, **`/chr`**, **`/tail [n]`**; **`/mini`**, **`/compact`**, **`/full`**, **`/expand`**; **`/sessions`**, **`/history`** — **split-pane** file list + markdown preview under `~/.blankstate/sessions/`; **`/clear`**, **`/help`**, **`/quit`**. **`F1`** / **`Ctrl+H`** toggle help. After each **`sense`**, a **background `depth: full`** call merges richer **entities** into actants (Node phase 2).
- **MCP:** **`sense`** rows in **`~/.blankstate/live/events.jsonl`** merge into the pane whose `protocolId` matches. Default MCP log is **quiet**; **`-v`** adds detail. **`--mcp-replay`** replays the JSONL from the start. MCP polling is **~1s**.
- **Resize:** spark + ECG reflow. **`--pipe`** needs redirected stdin. **`--demo-spark`** only in interactive TUI. **`--log`** writes all panes to one append-style markdown file with `## [protocol-id]` sections. **Without `--log`**, quitting after any measurements still writes a **Node-style snapshot** to `~/.blankstate/sessions/session-<iso>.md` (scores, chronicle, activity tail).

#### Parity vs `@blankstate/cli` monitor (`packages/cli/src/commands/monitor.tsx`)

| Node (Ink) | Python (`--tui`) |
|------------|------------------|
| Plain text → **all** protocols in parallel (`senseAll`) | Same (`_sense_all_protocols`) |
| **`Tab`** = highlighted / ECG-focused cell | Same (ECG = active pane) |
| **`/list`** interactive API browser, multi-select, Enter adds | **Textual modal** — `ListView`, Space, Enter (`ProtocolBrowseScreen`) |
| **`/chronicle`** cycles **entity context types** (C×B×I chronicle column) | Cycles **`entityType`** filter on **ECG actants** + **CHRONICLE** strip; falls back to **`/tail`** when empty |
| **`/sessions`**, **`/history`** split-pane file browser | **List + scrollable preview** (`SessionFilesScreen`) |
| **`/mini`**, **`/full`** compact layout | **`/mini`/`/compact`** hide ECG + activity/chronicle strips, slim MCP log; **`/full`/`/expand`** restores |
| **`/clear`** resets scores + activity log + entities **for all panes** | Same (all panes + MCP + activity/chronicle log views) |
| **`/help`** toggles help | Same (**F1** / **Ctrl+H** / **`/help`**) |
| Phase-2 **`depth: 'full'`** sense for richer entities (background) | **`run_worker`** + **`depth="full"`** after each **`measure`** pass (`_entity_depth_worker`) |
| Auto-save session on exit when measured > 0 | **`session-<ts>.md`** when **not** `--log`; **`--log`** still writes the detailed `session-<id>.md` |

Source of truth for Node UX: local clone **`blankstate-node/packages/cli/src/commands/monitor.tsx`**.

In **inline (test) mode**, the non-TUI Python session accepts:

| Command | Description |
|---------|-------------|
| `/clear` | Reset measurements and actant map in the session |
| `/quit`, `/exit`, `/q` | End the session |
| `/list` | Show the current protocol id, name, SGM, and measurement count |
| `/tail [n]`, `/chronicle [n]` | Print the last *n* measurements (default 15, max 100) |
| `/sessions`, `/history` | List recent `~/.blankstate/sessions/*.md` |
| `/help`, `/?` | Print commands; points to **`--tui`** for `/add` / `/remove` |

| Flag | Description |
|------|-------------|
| `--tui` | Full-screen Textual dashboard (`pip install 'blankstate-cli[tui]'`; optional `--pipe` / `--watch`) |
| `--demo-spark` | With `--tui`: append a fake score every second (demos only) |
| `-v`, `--verbose` | With `--tui`: verbose MCP / watch log lines |
| `--mcp-replay` | With `--tui`: replay `~/.blankstate/live/events.jsonl` from the start |
| `--pipe` | Read interactions from stdin |
| `--watch <file>` | Poll a file for new lines |
| `--log` | Save session to `~/.blankstate/sessions/` |
| `--language <code>` | Language code (default: `en`) |

In **TUI** mode use **q** or **Ctrl+C** to quit, **Tab** for ECG focus, **F1** / **Ctrl+H** to toggle help. **`--pipe`** / **`--watch`** lines are sensed against **all** panes. **`/clear`** clears **every** pane and the MCP log **view** (not `events.jsonl` on disk).

### Phase 4 (session TUI) — status

**In place:** Textual dashboard; **parallel multi-protocol sense**; **Tab** + ECG; **ACTIVITY** + **CHRONICLE** strips; **`/mini`/`/full`**; **auto-save snapshot** on quit (no `--log`); **interactive `/list`** browser; **`/sessions`** preview modal; **background `depth: full`** entity merge; **`/tail`**, chronicle filter, MCP tail, **`--mcp-replay`**; batched MCP refresh; **~1s** poll; **`--pipe`** / **`--watch`**; **`-v`**; idle shimmer; TTY cleanup; tests in `tests/test_tui_dashboard.py` and `tests/test_session_slash_inline.py`.

**Remaining stretch:** Ink **per-entity C×B×I history** (we use aggregate + per-measurement scores), mouse layout, huge JSONL perf, real Windows terminal E2E.

---

## Environment Variables

| Variable | Description | Default |
|----------|-------------|---------|
| `BLANKSTATE_API_TOKEN` | API token (overrides saved config) | — |
| `BLANKSTATE_API_URL` | API base URL | `https://ibf.blankstate.ai` |

---

## Local Files

The CLI stores config and artifacts in `~/.blankstate/`:

| Path | Description |
|------|-------------|
| `~/.blankstate/config.json` | Auth token and API URL |
| `~/.blankstate/protocols/` | Protocol snapshots (`.yaml`, via `inspect --save`) |
| `~/.blankstate/measurements/` | Measurement traces (`.md` / `.yaml`, via `sense --save`) |
| `~/.blankstate/traces/` | Legacy mirror of markdown traces (via `sense --trace` / `--save md`) |
| `~/.blankstate/sessions/` | Session logs (`.md`, via `session --log`) |
| `~/.blankstate/live/events.jsonl` | MCP live events (`bks_sense` / `bks_validate`); TUI `--tui` tails this file |

---

## Requirements

- **Python ≥ 3.10**
- API token from [atlas.blankstate.ai](https://atlas.blankstate.ai)
- A terminal that supports **ANSI** escape codes for session redraws and formatting (Windows Terminal, iTerm2, most modern terminals)

---

## Issues

- Python CLI / SDK: [github.com/blankstate-ai/blankstate-py](https://github.com/blankstate-ai/blankstate-py) (if applicable)
- Node CLI: [github.com/blankstate-ai/blankstate-node/issues](https://github.com/blankstate-ai/blankstate-node/issues)

## License

MIT — [blankstate.ai](https://blankstate.ai)
