opentine-tui
Terminal management console for opentine agent runs.
Built with Textual.
Install
pip install opentine-tui
That pulls in opentine
>=0.4,<0.5. Portable .tine files are format v2 (migration, tags + search,
cost + budget, autosave/drafts, signing, field-level diff); 0.3 added the
git-shaped v3 repository (content-addressed objects, refs, fsck, semantic
diff, attestations) and 0.4 made a fork id identify the fork act — the
dashboard manages all of it.
Ed25519 signing and keygen work out of the box: opentine 0.4 depends on
cryptography directly. The crypto extra is kept as a no-op so
opentine-tui[crypto] keeps resolving, and so the requirement stays explicit if
opentine ever makes it optional again.
Usage
tine-dashboard
opentine-tui
By default the TUI reads .tine artifacts from .tine_runs, and looks upward from
the working directory for a v3 .tine/ repository the way tine itself does.
Override either with:
tine-dashboard --runs-dir path/to/.tine_runs
tine-dashboard --repo path/inside/a/repository
OPENTINE_RUNS_DIR=path/to/.tine_runs tine-dashboard
tine-dashboard --version
The left panel has two tabs — Files (portable .tine artifacts) and
Repository (run objects in a .tine/ repository) — and [ / ] switches
between them. Both feed the same step tree and detail panels, because
repo.load_run() returns the same run the file reader does.
Layout
┌─ Runs ─────────────────┐ ┌── Steps ───────────────┐ ┌── Details ─────────┐
│ Files │ Repository │ │ * think "I'll search" │ │ Run: a3f8 │
│ a3f8 done 4m ✓ │ │ > tool search(q="...") │ │ Model: claude │
│ b7c1 fail 1h │ │ * think "The mass..." │ │ Steps: 4 │
│ c9d2 corrupt │ │ + done │ │ Cost: $0.003 │
│ │ │ │ │ Duration: 12.3s │
└────────────────────────┘ └────────────────────────┘ └────────────────────┘
Files lists portable artifacts with Cost, Age, Tags, and a compact
Flags column that marks on-disk state at a glance: 1/L = a v1/legacy file a
re-save would upgrade, D = an autosave draft checkpoint, and a signature glyph
(✓ verified, ~ verified-tofu, ? signed-but-no-key, x mismatch). Corrupt
.tine files remain visible with their load or integrity error in the details
panel, which also surfaces tags, token usage, a cost/budget breakdown, pricing
provenance, the integrity digest, and an authenticity (signature) block.
Repository lists run objects with their event count, cost, evaluation score
and ref, flagged Y for a fork and ~ when a shallow clone boundary cut some of
its events. There is no integrity or signature column there: v3 objects are
content-addressed and opentine verifies them on every read.
Keybindings
Press ? for the full list inside the app — every binding carries a tooltip.
| Key | Action |
|---|---|
q |
Quit |
? |
Help panel (every binding, including the hidden ones) |
r |
Refresh — drop the scan cache and rescan |
/ |
Search / filter runs (tag: model: status:completed cost:>0.01 after: + free text) |
[ ] |
Switch the run list between Files and Repository |
1 2 3 |
Focus runs / steps / details panel |
↑ ↓ |
Browse runs — the step and detail panels follow the highlight |
v |
Files: verify integrity + signature. Repository: deep fsck |
t |
Edit tags on the selected run (kept outside the digest) |
m |
Migrate a v1/legacy .tine to v2 (one-way; in place or to a new path) |
b |
Set a budget (max_cost/max_usage/max_steps/max_duration, breach mode, strict cost) |
s |
Sign the selected run (HMAC-SHA256 or Ed25519, via env var / key file) |
k |
Generate an Ed25519 keypair (refuses to replace an existing key) |
f |
Fork — from the selected step (file) or the selected event (repository) |
c |
Write a cached replay from the selected step |
d |
Files: field-level diff. Repository: semantic diff between two runs |
x |
Resume selected run when manifest.resume is true |
h |
Launch a new external harness run |
Ctrl+F |
Fork selected step and launch a harness |
Ctrl+R |
Replay from selected step with a harness |
i |
Import a .tine file into the repository (tine migrate-v3) |
p |
Promote a repository run to promotions/<name> |
e |
Record an evaluation attestation (scores) on a repository run |
l |
Walk a ref's event ancestry |
o |
Inspect a verified v3 object by id |
Write operations and external harness launches require an explicit confirmation modal before they run.
What's new for opentine 0.4.0
- Fork provenance. 0.4.0 derives a v2 fork id from the fork act — source
lineage, retained slice, branch, declared intent and a 128-bit nonce — and
records that basis in the artifact. The details panel shows it and reports
whether the id re-derives from the record:
verified,MISMATCH(the record was edited), or no verdict at all for a pre-0.4.0 fork, which is never presented as tampering. - Forking the same point twice now works. It used to produce one id and one filename, so the second fork silently destroyed the first. The dashboard no longer needs its own guard against that, and the run list shows both.
- Cached replay stays reproducible. A replay reuses recorded steps and produces nothing new, so it forks with an empty nonce and lands on one id; replaying twice is still refused rather than duplicated, and the panel labels it "reproducible fork — a replay, not a divergence".
What's new for opentine 0.3.0
- v3 repository browser — a second source tab lists the run objects in a
.tine/repository with their refs, event counts, cost, evaluation score, fork and shallow-boundary markers. Selecting one materializes it through the same step tree and detail panels the file list uses. - Repository actions — deep
fsck(v), event log (l), object inspection (o), semantic diff (d), fork from an event (f), promotion with the compare-and-swap opentine actually enforces (p), evaluation attestations (e), andmigrate-v3import of a portable artifact (i), which stays fail-closed on a source that does not verify. - Honest accounting — token counts include cache reads, 5m/1h cache writes and
reasoning tokens rather than input+output alone; per-step cost reads
billing.known_subtotal_usdthe wayRun.total_costdoes; and a step opentine could not price is marked unpriced instead of rendering as$0.0000. The run summary shows pricing provenance and the newby_refcost attribution. - Budgets —
strict_cost(an unpriced step counts as a breach) is editable and displayed, and a breach recorded in the run is surfaced alongside the re-derived one, sincecost_completenesscannot be recomputed from the artifact.
Non-goals for this release
Remote sync (fetch / push / clone / serve) and the live trace Recorder
are deliberately not wired up: the transfer path is fully blocking with no
progress reporting, and the recorder mints a new run object per appended event.
Both need a design of their own rather than a keybinding.
What's new for opentine 0.2.0
The dashboard now manages the full .tine format v2 surface:
- Migration — detects each file's on-disk version from raw JSON (not the loaded
run, which always reports v2) and upgrades v1/legacy
0.1.0artifacts to v2. - Tags + search — per-run tags and a live filter bar backed by the opentine search DSL.
- Cost + budget — per-step token usage, a
cost_breakdown(by model/kind), and budgets with a re-derived breach state. - Autosave / drafts — draft checkpoints are badged and never treated as final or signed.
- Signing (
tine-sig/1) — sign, verify, and generate keys; the details panel distinguishesverified/verified-tofu/no-key/mismatch, and labelssigneras display-only. - Field-level diff — per-field before/after across aligned steps, including cost/usage drift on otherwise-identical steps.
Development
pip install -e ".[dev]" # resolves opentine>=0.4,<0.5 from PyPI
ruff check .
ruff format --check .
pytest
Tests run against the installed opentine, so a green suite says something
about what users get. To test against a source checkout instead — a worktree at a
release tag, say — point OPENTINE_SRC at it:
git -C ../opentine worktree add /tmp/opentine-v040 v0.4.0
OPENTINE_SRC=/tmp/opentine-v040 pytest
CI runs lint, format, the test suite, a packaging build, and a twine metadata
check across Linux/macOS/Windows on Python 3.11–3.14, resolving opentine from
PyPI through the pin in pyproject.toml — so CI tests what users install.
Pushing a v* tag builds release artifacts, attests their provenance, and
attaches them to a GitHub release.
Contributing
See CONTRIBUTING.md for setup, the gates CI runs, and the conventions that keep a malformed artifact from taking the dashboard down. Security issues go to SECURITY.md, not the issue tracker.
License
Apache 2.0
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file opentine_tui-0.4.0.tar.gz.
File metadata
- Download URL: opentine_tui-0.4.0.tar.gz
- Upload date:
- Size: 78.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
081aa08fe2925c597c099a29035eff59ccec34eb7b6db6892cf9452518956e80
|
|
| MD5 |
69cf4bbeedc9828335150799adeb1a34
|
|
| BLAKE2b-256 |
ef72bb4c4b4129f4560e452c31d52773ebc5508ee00d58c97fae3e56b2bd91b7
|
Provenance
The following attestation bundles were made for opentine_tui-0.4.0.tar.gz:
Publisher:
publish.yml on 0xcircuitbreaker/opentine-tui
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
opentine_tui-0.4.0.tar.gz -
Subject digest:
081aa08fe2925c597c099a29035eff59ccec34eb7b6db6892cf9452518956e80 - Sigstore transparency entry: 2312944411
- Sigstore integration time:
-
Permalink:
0xcircuitbreaker/opentine-tui@f1344c1a2bb081204cd115031ba2a7694a19b6e8 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/0xcircuitbreaker
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f1344c1a2bb081204cd115031ba2a7694a19b6e8 -
Trigger Event:
push
-
Statement type:
File details
Details for the file opentine_tui-0.4.0-py3-none-any.whl.
File metadata
- Download URL: opentine_tui-0.4.0-py3-none-any.whl
- Upload date:
- Size: 63.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0576b1ad32a409437b414075210f5e363788ea8a3a276a6bcfdf4a24885d9bcd
|
|
| MD5 |
058b7de53c7a8c65d728984b3c4840c4
|
|
| BLAKE2b-256 |
4b902c4c926b695240c3009455c109fccabfce2a1221ae25e74fbc906328d59c
|
Provenance
The following attestation bundles were made for opentine_tui-0.4.0-py3-none-any.whl:
Publisher:
publish.yml on 0xcircuitbreaker/opentine-tui
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
opentine_tui-0.4.0-py3-none-any.whl -
Subject digest:
0576b1ad32a409437b414075210f5e363788ea8a3a276a6bcfdf4a24885d9bcd - Sigstore transparency entry: 2312944491
- Sigstore integration time:
-
Permalink:
0xcircuitbreaker/opentine-tui@f1344c1a2bb081204cd115031ba2a7694a19b6e8 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/0xcircuitbreaker
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f1344c1a2bb081204cd115031ba2a7694a19b6e8 -
Trigger Event:
push
-
Statement type: