smriti/cli
Himanshu Dongre 73c71b4c9d Add delete endpoints for spaces, checkpoints, and sessions
Two rounds of agent-handoff dogfood testing surfaced that Smriti had no
way to delete spaces, sessions, or checkpoints via any surface. This
adds DELETE endpoints to the V2/V4 API, new CLI commands, and UI
affordances on the workspace overview and chat history panel so the
daily cleanup path does not require opening a Python shell.

Checkpoint delete refuses with 409 Conflict when child commits or
forked sessions reference the target, because silently orphaning them
would cause walk_ancestors to collapse lineage and forked sessions to
lose isolation. The refusal is escaped via ?cascade=true on the API,
--cascade on the CLI, and a two-step confirm with a dependents list
plus checkbox in the UI modal.

Space delete relies on the existing DB-level cascade chain from the
earlier commit/session/turn migrations — no new Alembic migration is
needed. Session delete cascades turn events but preserves commits
authored by the session, since commits are space-owned artifacts.

14 integration tests cover cascade correctness, 409 refusal, the
cascade escape hatch, cross-user 404s, subtree ordering, and
idempotency. Existing tests pass unchanged (143/143).
2026-04-11 17:25:36 +05:30
..
smriti_cli Add delete endpoints for spaces, checkpoints, and sessions 2026-04-11 17:25:36 +05:30
pyproject.toml Add CLI for agent and programmatic access 2026-04-11 11:10:01 +05:30
README.md Add CLI for agent and programmatic access 2026-04-11 11:10:01 +05:30

smriti-cli

Command-line access to Smriti's reasoning-state backend. Built for coding agents and scripts — pipe JSON in, get readable markdown out.

Install

From the repo root:

cd cli
pip install -e .

This installs a smriti command on your PATH.

Configuration

Set the backend URL via env var (defaults to http://localhost:8000):

export SMRITI_API_URL=http://localhost:8000

Or pass --api-url on any command.

Commands

smriti space list
smriti space create <name> [--description "..."]

smriti state <space>                                     # continuation brief
smriti state <space> --full-artifacts                    # include full artifacts
smriti state <space> --json                              # structured output

smriti checkpoint create <space>                         # reads JSON from stdin
smriti checkpoint create <space> --from-json <path>      # from file
smriti checkpoint show <checkpoint-id>
smriti checkpoint list <space>
smriti checkpoint review <checkpoint-id>

Every command supports --json for structured output.

Typical agent workflow

Read current project state:

smriti state my-project

Write a checkpoint from a JSON object piped on stdin:

cat <<'JSON' | smriti checkpoint create my-project
{
  "message": "Decided to use Pydantic for state validation",
  "objective": "Build runtime-enforced state layer",
  "summary": "...",
  "decisions": ["Use Pydantic BaseModel for state", "extra=forbid blocks injection"],
  "assumptions": ["Latency cost is acceptable"],
  "tasks": ["Benchmark validation overhead"],
  "open_questions": ["How to handle shared state across agents"],
  "entities": ["Pydantic", "BaseModel"],
  "artifacts": [
    {"id": "a1", "type": "text", "label": "Draft implementation", "content": "..."}
  ]
}
JSON

Review a specific checkpoint for consistency issues:

smriti checkpoint review <checkpoint-id>

Checkpoint payload schema

Only message is required. Every other field defaults to empty.

Field Type Notes
message string Short title (required)
objective string What you are working toward
summary string Narrative of what was figured out
decisions string[] Explicit choices made
assumptions string[] Things taken for granted
tasks string[] Concrete action items
open_questions string[] Unresolved issues
entities string[] Key concepts, tools, names
artifacts object[] {id, type, label, content} entries

Space resolution

<space> arguments accept either the space name or the UUID. Names are matched exactly first, then case-insensitively. If multiple spaces match, the CLI asks you to use a UUID.

Exit codes

  • 0 success
  • 1 API error, invalid input, or backend unreachable
  • 130 interrupted (Ctrl+C)