Skip to content

CLI: upsert, metadata, table info, persistent mode, and open transactions - #14

Open
sethrojas21 wants to merge 6 commits into
mitdbg:mainfrom
sethrojas21:cli-v2
Open

sethrojas21 wants to merge 6 commits into
mitdbg:mainfrom
sethrojas21:cli-v2

Conversation

@sethrojas21

Copy link
Copy Markdown
Collaborator

Extends the chronos CLI for HeavenBase. Commands stay thin wrappers over the
Python API.

  • upsert, transaction, branch and checkpoint --metadata,
    branch list --store, branch update-metadata, checkpoint list --store
  • table info, backed by the new ChronosBranchContext.describe_table()
  • chronos --persistent: one workspace, one JSON line per command
  • In persistent mode, begin/commit/rollback keep a transaction open
    across lines; only rollback is accepted after a failure, and closing stdin
    rolls back
  • Fixes: DuckDB table_defs returns empty for a missing table; no direct
    click import (typer 0.29 no longer installs it); OverlayFS mounts are
    released after each persistent command
  • Integration tests use persistent mode (CLI suite drops from about 4 minutes
    to about 1); CI now runs the new test classes

sethrojas21 and others added 6 commits November 12, 2026 09:42
Wrap existing Python APIs needed by HeavenBase:
- upsert: BranchSession.upsert_rows on a store branch
- transaction: execute/upsert operations inside BranchSession.transaction()
- branch create --metadata, branch list --store, branch update-metadata
- checkpoint create --metadata, checkpoint list --store

Move JSON input parsing into the shared terminal module.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`chronos --persistent` opens the workspace once, reads one command per
stdin line, and prints one JSON line per command wrapping the one-shot
result, exit code, and error. connect_workspace reuses the held
workspace, so every existing command works unchanged.

Integration tests send their commands through one persistent process per
config file, restarting it when a test edits chronos.toml and releasing it
before other processes or in-process API access open the stores. Commands
that pipe stdin and the one-shot comparison test still run as separate
processes. The CLI suite drops from about 4 minutes to about 1 minute.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ChronosBranchContext.describe_table() reports whether a table exists and is
registered, its primary key, and its columns as name/type pairs. Registered
tables are read from a fresh read of Chronos's table registry, so a table
registered by another process is reported; unregistered tables are read
from the database with no primary key. `chronos table info --store NAME
TABLE` prints the result in one-shot and persistent mode.

DuckDB's table_defs now returns empty for a missing table, like the SQLite
and PostgreSQL adapters, instead of raising a catalog error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In persistent mode, `begin --store NAME [--branch B]` enters the branch
session's transaction() and keeps it open; `commit` exits it normally and
`rollback` exits it with an error, so the Python API commits or rolls back.
Until then query/execute/upsert on that store and branch run inside it.

- Every other command is refused while a transaction is open.
- After a command fails inside it, only rollback is accepted.
- Closing stdin with a transaction open rolls it back.
- One-shot begin/commit/rollback exit 2; `transaction` still groups
  statements in one call.

connect_workspace now lets typer.Exit through instead of reporting it as an
error (Exit subclasses RuntimeError). Docs cover the SQLite write lock held
from a transaction's first write until it ends.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
typer 0.29 no longer depends on click and bundles its own copy, so
`import click` failed in CI's fresh install. Use typer's public names
instead: ctx.fail() for "Missing command", the parameter source's name for
the --config check, typer.Exit/typer.Abort, and the usage-error base class
looked up through typer.BadParameter. Behavior is unchanged on typer 0.25
and 0.29.

Add TestPersistentMode and TestPersistentTransactions to the CLI test list
in the relational-package workflow so CI runs them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The OverlayFS store keeps a checked-out branch mounted until unmount() or
close(). One-shot commands released mounts when their process closed the
store, but a persistent process kept the branch mounted between commands,
breaking the documented guarantee that each invocation releases its mounts
(TestWorkspaceFilesystemWorkflows on Linux). Call the store's unmount() for
the branch whenever a command releases its sessions, including when an open
transaction ends.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant