CLI Reference
Backup, restore, verify, and migrate your AI identity from the command line.
$ savestate --help
Time Machine for AI. Backup, restore, and migrate your AI identity.
Commands:
init Initialize encryption & storage config
snapshot Capture current AI state to encrypted archive
restore [snapshot-id] Restore from snapshot (default: latest)
list List all snapshots with metadata
stats Show usage statistics about your snapshots
doctor Health-check snapshots: decrypt, unpack, verify chains
inspect <id> Decrypt and summarize a snapshot without restoring
diff <a> <b> Compare two snapshots side-by-side
search <query> Search across all snapshots
export Export an encrypted agent container
import <file> Import an encrypted agent container
container Manage encrypted agent state containers (export, import)
verify <file> Verify a .savestate container and list metadata
prune Drop old snapshots by retention policy (dry-run)
antibodies Manage failure antibodies (list, add, preflight, stats)
schedule Configure automatic backup schedule (Pro/Team)
migrate Migration wizard between platforms
trust Inspect Trust Kernel state, audit trail, and denylist
team Team management: members, invites, audit log (Team)
eval Memory quality evaluation (quality, report)
login Authenticate with SaveState cloud
logout Remove the saved cloud API key
cloud Cloud storage commands (Pro/Team)
mcp MCP server: serve, status, export, import
context Preflight context compilation for agent runs
memory Manage multi-tier memory (L1/L2/L3) for long-running agents
slo Memory freshness SLO monitoring (status, report, config)
acl Manage active commitments (propose, verify, gate, list)
identity Manage agent identity (show, init, set, schema)
integrity Memory Integrity Grid (status, seed, incidents)
trace Inspect Askable Echoes trace runs (list, show, export)
config View or edit configuration
adapters List available platform adapters
savestate init
Initialize SaveState in the current directory. Creates a .savestate/ directory containing your encryption configuration and storage settings. Optionally cap status field rows with --limit.
$ savestate init [options]
This command:
- Prompts for a passphrase (used to derive your encryption key via scrypt)
- Creates
.savestate/config.jsonwith default local storage - Sets up the snapshot index file
| Flag | Description |
|---|---|
--limit <n> | Maximum number of status field rows to show. Must be a positive integer up to 1000. |
--offset <n> | Skip the first status field rows before applying --limit. Must be a non-negative integer up to 1000. |
--json | Emit init status as JSON. Skips the spinner and passphrase prompt. Cannot be combined with --limit or --offset. Useful for scripting. |
$ savestate init --limit 5
$ savestate init --offset 1 --limit 5
$ savestate init --json
~/.savestate/config.json — local project config takes priority.
savestate snapshot
Capture the current AI state and save it as an encrypted archive. Optionally cap status field rows with --limit. --offset skips status field rows before --limit.
$ savestate snapshot [options]
| Flag | Description |
|---|---|
-l, --label <label> | Human-readable label for this snapshot (e.g., "Before migration"). Must be a single non-empty snapshot label (no commas). |
-t, --tags <tags> | Comma-separated tags for organization (e.g., "backup,weekly"). Must be one or more non-empty snapshot tags (comma-separated). |
--tag <entry...> | Record a structured state entry as type:key=value (repeatable). Types: decision, preference, error, api_response, custom. Distinct from -t, --tags. Must be type:key=value with type one of: decision, preference, error, api_response, custom. |
--meta <entry...> | Additional metadata for --tag entries as key=value (repeatable). Applied to every state entry on this snapshot. Must be key=value with a non-empty key and value. |
-a, --adapter <adapter> | Force a specific adapter instead of auto-detection. Must be one of: clawdbot, claude-code, claude-web, openai-assistants, chatgpt, gemini, cursor, windsurf. |
-s, --schedule <interval> | Set up auto-snapshot schedule (e.g., 6h, 1d). Must be a duration like 1h, 6h, 12h, or 1d up to 7 days. (Pro) |
--full | Force a full snapshot, skipping incremental delta detection |
--limit <n> | Maximum number of status field rows to show. Must be a positive integer up to 1000. Combines with --offset. |
--offset <n> | Skip the first N status field rows. Must be a non-negative integer up to 1000. Applied before --limit. |
--json | Emit the snapshot result as JSON. Encrypts the archive. Skips the spinner. When SaveState is not initialized, emits a missing summary (found, adapter, snapshotId, timestamp, platform; omits extra fields). When no adapter can be detected, emits a missing summary (found, adapter, snapshotId, timestamp, platform; omits extra fields). Useful for scripting. |
Examples
# Basic snapshot with auto-detection
$ savestate snapshot
# Cap status field rows
$ savestate snapshot --limit 5
# Page status field rows
$ savestate snapshot --offset 10 --limit 5
# Labeled + tagged
$ savestate snapshot --label "Pre-update backup" --tags "important,v2"
# Force the Claude Code adapter
$ savestate snapshot --adapter claude-code
# Force full snapshot (ignore incrementals)
$ savestate snapshot --full
# Record structured state entries
$ savestate snapshot --tag decision:api_provider=openai --tag preference:theme=dark --meta confidence=high
# Schedule auto-backups every 6 hours (Pro)
$ savestate snapshot --schedule 6h
# Scriptable snapshot metadata
$ savestate snapshot --json --full
# Scriptable JSON when no adapter can be detected
$ savestate snapshot --json
By default, snapshots are incremental — only changes since the last snapshot are stored. Use --full to force a complete capture. See Incremental Snapshots for details.
savestate restore
Restore your AI state from a snapshot. Defaults to the latest if no ID is specified.
$ savestate restore [snapshot-id] [options]
| Flag | Description |
|---|---|
[snapshot-id] | Snapshot to restore. Optional; defaults to latest. Must be a single non-empty snapshot id (or latest). |
--to <platform> | Restore to a different platform (cross-platform migration). Must be one of: clawdbot, claude-code, claude-web, openai-assistants, chatgpt, gemini, cursor, windsurf. |
--dry-run | Show what would be restored without making any changes |
--include <categories> | Only restore specific categories: identity, memory, conversations (comma-separated). Must be one or more of: identity, memory, conversations. |
--exclude <categories> | Skip restore categories: identity, memory, conversations (comma-separated). Must be one or more of: identity, memory, conversations. |
--adapter <id> | Restore the newest snapshot from this adapter. Must be one of: clawdbot, claude-code, claude-web, openai-assistants, chatgpt, gemini, cursor, windsurf. |
--since <date> | Restore the newest snapshot taken after this date. Must be an ISO 8601 date. |
--until <date> | Restore the newest snapshot taken on or before this date. Must be an ISO 8601 date. |
--tag <tag> | Restore the newest snapshot with this tag. Must be a single non-empty snapshot tag (no commas). |
--label <label> | Restore the newest snapshot with this human-readable label. Must be a single non-empty snapshot label (no commas). |
--limit <n> | Only consider the N most recent matching snapshots. Must be a positive integer up to 1000. Pass latest as the snapshot id to restore the newest matching snapshot. |
--offset <n> | Skip the first N snapshots after filters before applying --limit. Must be a non-negative integer up to 1000. Pass latest as the snapshot id to restore the newest remaining snapshot. |
--json | Emit the restore result as JSON. Decrypts the archive. Skips the spinner. When SaveState is not initialized, emits a missing summary (found, snapshotId, timestamp, platform, hasIdentity; omits extra fields). When the snapshot is missing, emits a missing summary (found, snapshotId, timestamp, platform, hasIdentity; omits extra fields). Useful for scripting. |
Examples
# Restore latest snapshot
$ savestate restore latest
# Restore a specific snapshot
$ savestate restore ss-2026-01-26T09-30-00-b7c1m4
# Migrate to Claude Code
$ savestate restore latest --to claude-code
# Restore only memory files
$ savestate restore latest --include memory
# Restore everything except conversations
$ savestate restore latest --exclude conversations
# Restore the newest snapshot from one adapter
$ savestate restore --adapter chatgpt
# Restore the newest snapshot since a date
$ savestate restore --since 2026-04-01
# Restore the newest snapshot on or before a date
$ savestate restore --until 2026-06-01
# Restore the newest tagged snapshot
$ savestate restore --tag work
# Restore the newest labeled snapshot
$ savestate restore --label backup
# Restrict to the N most recent matching snapshots
$ savestate restore --limit 5
# Skip the newest snapshots, then restore the next match
$ savestate restore --offset 10 --limit 5
# Preview without changing anything
$ savestate restore latest --dry-run
# Scriptable JSON result
$ savestate restore latest --json --dry-run
.bak extension before being overwritten.
savestate list
List all snapshots with metadata. Alias: savestate ls. Reads the snapshot index only — it does not decrypt archives. Requires savestate init.
$ savestate list [options]
| Flag | Description |
|---|---|
--json | Emit snapshot records as JSON, newest first, with found for whether the current page contains an entry, total/shown counts, page/pageSize/totalPages navigation metadata, emptyReason, and suggestedOffset for recovering from a stale page. emptyReason is collection when no snapshots match, page when the offset is past the filtered collection, or null when entries are shown. suggestedOffset is the nearest page offset when the requested page is empty, or null when the collection is empty or the page has entries. Does not decrypt archives. When SaveState is not initialized, emits a page-compatible missing summary (found, total, shown, emptyReason, entries, storage). Useful for scripting. |
--oldest-first | Show snapshots from oldest to newest. Applies to table and JSON output. |
--reverse | Alias for --oldest-first; show snapshots from oldest to newest. |
--limit <n> | Maximum number of snapshots to show (default 50). Must be a positive integer up to 1000. |
--offset <n> | Skip the first N snapshots after filters. Must be a non-negative integer up to 1000. |
--since <date> | Only snapshots taken after this date (ISO 8601, e.g. 2026-04-01) |
--until <date> | Only snapshots taken on or before this date. Date-only values include the full UTC day. Must be an ISO 8601 date. |
--adapter <id> | Only snapshots from this adapter. Must be one of: clawdbot, claude-code, claude-web, openai-assistants, chatgpt, gemini, cursor, windsurf. |
--exclude <ids> | Skip snapshots from these adapters. Must be one or more of: clawdbot, claude-code, claude-web, openai-assistants, chatgpt, gemini, cursor, windsurf. |
--snapshot <id> | Only this snapshot. Must be a single non-empty snapshot id. |
--tag <tag> | Only snapshots with this tag. Must be a single non-empty snapshot tag (no commas). |
--label <label> | Only snapshots with this human-readable label. Must be a single non-empty snapshot label (no commas). |
# Recent snapshots
$ savestate list --limit 5
# Review snapshots from oldest to newest
$ savestate list --oldest-first --limit 5
# Skip the newest 10, then show 5
$ savestate list --offset 10 --limit 5
# Claude Code snapshots since April
$ savestate list --adapter claude-code --since 2026-04-01
# Skip ChatGPT snapshots
$ savestate list --exclude chatgpt
# One snapshot
$ savestate list --snapshot ss-2026-09-13T12-00-00-ab12cd
# Tagged backups as JSON
$ savestate ls --tag weekly --json | jq '.entries[0]'
# Labeled snapshots
$ savestate list --label "Pre-update backup"
# Scripting
$ savestate list --json
savestate stats
Show usage statistics about your snapshots: total count, storage size, adapter mix, cadence, and top tags. Reads the snapshot index only — it does not decrypt archives.
$ savestate stats [options]
| Flag | Description |
|---|---|
--json | Emit usage statistics as JSON, including found plus pagination metadata (total matching snapshots, shown, remaining, offset, limit, page, pageSize, totalPages, emptyReason, suggestedOffset for an exhausted page, and next/previous page offsets). Does not decrypt archives. When SaveState is not initialized, emits a missing summary (found, total, totalBytes, first, latest, storage; omits extra fields). Useful for scripting. |
--platform <id> | Only snapshots recorded from this platform. Matching is case-insensitive and ignores surrounding whitespace. Must be a single non-empty platform id (no spaces or commas). |
--adapter <id> | Only snapshots from this adapter. Must be one of: clawdbot, claude-code, claude-web, openai-assistants, chatgpt, gemini, cursor, windsurf. |
--exclude <ids> | Skip snapshots from these adapters. Must be one or more of: clawdbot, claude-code, claude-web, openai-assistants, chatgpt, gemini, cursor, windsurf. |
--snapshot <id> | Only this snapshot. Must be a single non-empty snapshot id. |
--since <date> | Only snapshots taken on or after this date. Date-only values start at 00:00 UTC. Must be an ISO 8601 date. |
--until <date> | Only snapshots taken on or before this date. Date-only values include the full UTC day. Must be an ISO 8601 date. |
--tag <tag> | Only snapshots tagged with this label. Must be a single non-empty snapshot tag (no commas). |
--label <label> | Only snapshots with this label. Must be a single non-empty snapshot label (no commas). |
--limit <n> | Only aggregate the N most recent snapshots. Must be a positive integer up to 1000. Human-readable output includes the next page offset when more matches remain. |
--offset <n> | Skip the first N snapshots after filters. Must be a non-negative integer up to 1000. Human-readable output includes the previous page offset when this is a later page. |
# Human-readable summary
$ savestate stats
# ChatGPT snapshots only
$ savestate stats --adapter chatgpt
# Snapshots recorded from Claude
$ savestate stats --platform claude
# Skip ChatGPT snapshots
$ savestate stats --exclude chatgpt
# One snapshot
$ savestate stats --snapshot ss-2026-09-13T12-00-00-ab12cd
# Snapshots since April
$ savestate stats --since 2026-04-01
# Snapshots until April
$ savestate stats --until 2026-04-01
# Tagged backups
$ savestate stats --tag work
# Labeled snapshots
$ savestate stats --label "Pre-update backup"
# Most recent snapshots only
$ savestate stats --limit 5
# Skip the newest 10, then aggregate 5
$ savestate stats --offset 10 --limit 5
# Scripting
$ savestate stats --json
# Scriptable JSON when SaveState is not initialized
$ savestate stats --json
savestate doctor
Health-check every snapshot in the index. Decrypts each archive, unpacks the manifest, verifies content checksums, and walks incremental chains end-to-end. Reports a per-snapshot status table and a summary. Exits non-zero if any snapshot is unhealthy, so it can be wired into cron.
$ savestate doctor [options]
| Flag | Description |
|---|---|
--json | Emit per-snapshot diagnosis as JSON. Decrypts archives. When SaveState is not initialized, emits a missing summary (found, total, healthy, unhealthy; omits extra fields). Useful for scripting. |
--adapter <id> | Only check snapshots from this adapter. Must be one of: clawdbot, claude-code, claude-web, openai-assistants, chatgpt, gemini, cursor, windsurf. |
--exclude <ids> | Skip snapshots from these adapters. Must be one or more of: clawdbot, claude-code, claude-web, openai-assistants, chatgpt, gemini, cursor, windsurf. |
--snapshot <id> | Only check this snapshot. Must be a single non-empty snapshot id. |
--since <date> | Only check snapshots taken after this date. Must be an ISO 8601 date. |
--until <date> | Only check snapshots taken before this date. Must be an ISO 8601 date. |
--tag <tag> | Only check snapshots tagged with this label. Must be a single non-empty snapshot tag (no commas). |
--label <label> | Only check snapshots with this human-readable label. Must be a single non-empty snapshot label (no commas). |
--limit <n> | Only check the N most recent snapshots. Must be a positive integer up to 1000. |
--offset <n> | Skip the first N snapshots after filters. Must be a non-negative integer up to 1000. |
# Check every snapshot
$ savestate doctor
# Scripting
$ savestate doctor --json
# Scriptable JSON when SaveState is not initialized
$ savestate doctor --json
# Restrict to recent Claude Code snapshots
$ savestate doctor --adapter claude-code --limit 5 --json
# Skip the newest 10, then check 5
$ savestate doctor --offset 10 --limit 5
# Skip ChatGPT snapshots
$ savestate doctor --exclude chatgpt
# Check one snapshot
$ savestate doctor --snapshot ss-2026-09-13T12-00-00-ab12cd
# Skip snapshots older than a cutoff
$ savestate doctor --since 2026-04-01
# Skip snapshots newer than a cutoff
$ savestate doctor --until 2026-04-01
# Restrict to tagged snapshots
$ savestate doctor --tag work --json
# Restrict to labeled snapshots
$ savestate doctor --label backup --json
savestate inspect
Decrypt and summarize a snapshot without restoring it. Use this to browse history and confirm what a backup contains before running savestate restore. Requires a single non-empty snapshot id, savestate init, and a passphrase.
$ savestate inspect <snapshot-id> [options]
| Flag | Description |
|---|---|
<snapshot-id> | Snapshot to decrypt and summarize. Must be a single non-empty snapshot id (or latest). |
--adapter <id> | Inspect the newest snapshot from this adapter. Must be one of: clawdbot, claude-code, claude-web, openai-assistants, chatgpt, gemini, cursor, windsurf. Pass latest as the snapshot id to inspect the newest matching snapshot. |
--exclude <ids> | Skip snapshots from these adapters. Must be one or more of: clawdbot, claude-code, claude-web, openai-assistants, chatgpt, gemini, cursor, windsurf. Pass latest as the snapshot id to inspect the newest matching snapshot. |
--since <date> | Inspect the newest snapshot taken after this date. Must be an ISO 8601 date. Pass latest as the snapshot id to inspect the newest matching snapshot. |
--until <date> | Inspect the newest snapshot taken on or before this date. Must be an ISO 8601 date. Pass latest as the snapshot id to inspect the newest matching snapshot. |
--tag <tag> | Only inspect a snapshot tagged with this label. Must be a single non-empty snapshot tag (no commas). Pass latest as the snapshot id to inspect the newest matching snapshot. |
--label <label> | Only inspect a snapshot with this human-readable label. Must be a single non-empty snapshot label (no commas). Pass latest as the snapshot id to inspect the newest matching snapshot. |
--limit <n> | Only consider the N most recent matching snapshots. Must be a positive integer up to 1000. Pass latest as the snapshot id to inspect the newest matching snapshot. |
--offset <n> | Skip the first N matching snapshots after filters. Must be a non-negative integer up to 1000. Pass latest as the snapshot id to inspect the newest remaining snapshot. |
--json | Emit the snapshot summary as JSON. Decrypts the archive. When SaveState is not initialized, emits a missing summary (found, id, timestamp, platform, hasIdentity; omits extra fields). When the snapshot is missing, emits a missing summary (found, id, timestamp, platform, hasIdentity; omits extra fields). Useful for scripting. |
Pass latest to inspect the most recent snapshot. Output includes id, timestamp, platform, adapter, size, optional label/tags, and content counts (memories, conversations, knowledge, tools, skills, identity).
# Summarize the latest snapshot
$ savestate inspect latest
# Restrict to snapshots from one adapter
$ savestate inspect latest --adapter chatgpt
# Skip ChatGPT snapshots
$ savestate inspect latest --exclude chatgpt
# Restrict to snapshots taken after a date
$ savestate inspect latest --since 2026-04-01
# Restrict to snapshots taken on or before a date
$ savestate inspect latest --until 2026-06-01
# Restrict to tagged snapshots
$ savestate inspect latest --tag work
# Summarize the newest labeled snapshot
$ savestate inspect latest --label backup
# Restrict to the N most recent matching snapshots
$ savestate inspect latest --limit 5
# Skip the newest 10, then inspect within the next 5
$ savestate inspect latest --offset 10 --limit 5
# Scripting
$ savestate inspect latest --json
# Scriptable JSON summary
$ savestate inspect ss-2026-01-26T09-30-00-b7c1m4 --json
savestate diff
Compare two snapshots and see what changed across identity, memory, conversations, and tools. Requires two single non-empty snapshot ids, savestate init, and a passphrase. Decrypts both archives.
$ savestate diff <snapshot-a> <snapshot-b> [options]
| Flag | Description |
|---|---|
<snapshot-a> | First snapshot to compare. Must be a single non-empty snapshot id. |
<snapshot-b> | Second snapshot to compare. Must be a single non-empty snapshot id. |
--adapter <id> | Only compare snapshots from this adapter. Must be one of: clawdbot, claude-code, claude-web, openai-assistants, chatgpt, gemini, cursor, windsurf. Combines with --exclude, --since, --until, --tag, --label, --limit, and --offset. Pass latest as a snapshot id to use the newest matching snapshot. |
--exclude <ids> | Skip snapshots from these adapters. Must be one or more of: clawdbot, claude-code, claude-web, openai-assistants, chatgpt, gemini, cursor, windsurf. Combines with --adapter, --since, --until, --tag, --label, --limit, and --offset. Pass latest as a snapshot id to use the newest matching snapshot. |
--since <date> | Compare the newest snapshots taken after this date. Must be an ISO 8601 date. Combines with --adapter, --exclude, --until, --tag, --label, --limit, and --offset. Pass latest as a snapshot id to use the newest matching snapshot. |
--until <date> | Compare the newest snapshots taken on or before this date. Must be an ISO 8601 date. Combines with --adapter, --exclude, --since, --tag, --label, --limit, and --offset. Pass latest as a snapshot id to use the newest matching snapshot. |
--tag <tag> | Only compare snapshots tagged with this label. Must be a single non-empty snapshot tag (no commas). Combines with --adapter, --exclude, --since, --until, --label, --limit, and --offset. Pass latest as a snapshot id to use the newest matching snapshot. |
--label <label> | Only compare snapshots with this human-readable label. Must be a single non-empty snapshot label (no commas). Combines with --adapter, --exclude, --since, --until, --tag, --limit, and --offset. Pass latest as a snapshot id to use the newest matching snapshot. |
--limit <n> | Only consider the N most recent matching snapshots. Must be a positive integer up to 1000. Combines with --adapter, --exclude, --since, --until, --tag, --label, and --offset. Pass latest as a snapshot id to use the newest matching snapshot. |
--offset <n> | Skip the first N matching snapshots after filters. Must be a non-negative integer up to 1000. Pass latest as a snapshot id to use the newest remaining snapshot. |
--json | Emit identity and state diffs as JSON. Decrypts both archives. When SaveState is not initialized, emits a missing summary (found, snapshotA, snapshotB, hasChanges; omits extra fields). When a snapshot is missing, emits a missing summary (found, snapshotA, snapshotB, hasChanges; omits extra fields). Useful for scripting. |
# Newest ChatGPT snapshot vs an earlier id
$ savestate diff latest ss-2026-01-25 --adapter chatgpt
# Newest snapshot that is not from ChatGPT vs an earlier id
$ savestate diff latest ss-2026-01-25 --exclude chatgpt
# Newest snapshot after a date vs an earlier id
$ savestate diff latest ss-2026-01-25 --since 2026-04-01
# Newest tagged snapshot vs an earlier id
$ savestate diff latest ss-2026-01-25 --tag work
# Newest labeled snapshot vs an earlier id
$ savestate diff latest ss-2026-01-25 --label backup
# Newest snapshot on or before a date vs an earlier id
$ savestate diff latest ss-2026-01-25 --until 2026-06-01
# Newest of the 2 most recent snapshots vs an earlier id in that window
$ savestate diff latest ss-2026-01-25 --limit 2
# Skip the newest 10, then compare within the next 5
$ savestate diff latest ss-2026-01-25 --offset 10 --limit 5
# Human-readable summary
$ savestate diff ss-2026-01-25 ss-2026-01-27
Changes between ss-2026-01-25 and ss-2026-01-27:
+ 3 files added
~ 5 files modified
- 1 file removed
# Scripting
$ savestate diff ss-2026-01-25 ss-2026-01-27 --json
savestate search
Search across all snapshots without restoring them. Find that conversation from months ago. Searches memory entries, conversations, identity files, and knowledge documents. Returns results ranked by relevance with context snippets. Interactive output suggests the next offset when a page is full, identifies a partial page as the final page, offers the previous page for later partial pages, and provides a nearby recovery offset when a requested page is empty. Use --json-summary for a machine-readable result envelope with page navigation metadata. Requires a non-empty query, savestate init, and a passphrase.
$ savestate search <query> [options]
| Flag | Description |
|---|---|
<query> | Search text. Must be a non-empty query. |
--type <type> | Filter by type: memory, conversation, identity, or knowledge (comma-separated). Must be one or more of: memory, conversation, identity, knowledge. |
--exclude <types> | Skip search types: memory, conversation, identity, knowledge (comma-separated). Must be one or more of: memory, conversation, identity, knowledge. |
--since <date> | Only search snapshots taken after this date. Must be an ISO 8601 date. |
--until <date> | Only search snapshots taken before this date. Must be an ISO 8601 date. |
--limit <n> | Maximum number of results (default 20). Must be a positive integer up to 1000. |
--offset <n> | Skip the first N ranked results after filters before applying --limit. Must be a non-negative integer up to 1000. |
--snapshot <id> | Search within a specific snapshot instead of every archive |
--adapter <id> | Only search snapshots from this adapter (matching is case-insensitive). Must be one of: clawdbot, claude-code, claude-web, openai-assistants, chatgpt, gemini, cursor, windsurf. |
--tag <tag> | Only search snapshots with this tag (matching is case-insensitive and trims legacy surrounding whitespace; filter output is normalized to lowercase). Must be a single non-empty snapshot tag (no commas). |
--label <label> | Only search snapshots with this human-readable label (matching is case-insensitive and trims legacy surrounding whitespace; filter output is normalized to lowercase). Must be a single non-empty snapshot label (no commas). |
--json | Output ranked results as JSON. When SaveState is not initialized, emits a missing summary (found, query, snapshot, count; omits extra fields). When the snapshot is missing, emits a missing summary (found, query, snapshot, count; omits extra fields). Useful for scripting. |
--json-summary | Output an object with found, query, normalized filters (type, exclude, ISO since/until boundaries, snapshot, adapter, tag, and label), results, and pagination metadata (offset, limit, shown, emptyReason, suggestedOffset, hasMore, nextOffset, hasPrevious, and previousOffset). Date-only inputs are emitted as UTC boundaries, with --until including the full day. When a later page is empty, suggestedOffset identifies the nearest earlier page to retry; otherwise it is null. An empty first page reports emptyReason: collection; any empty later page—including a missing snapshot or uninitialized state—reports emptyReason: page, helping scripts distinguish no matches from an exhausted offset. Preserves the selected page size and is useful for paginated scripts; unlike --json, it does not emit a bare array. |
# Search every snapshot
$ savestate search "cocktail recommendations"
# Conversations only, cap results
$ savestate search "cocktail recommendations" --type conversation --limit 5
# Page past the first 10 ranked results
$ savestate search "cocktail recommendations" --offset 10 --limit 5
# Skip conversations
$ savestate search "cocktail recommendations" --exclude conversation
# Snapshots since April
$ savestate search "cocktail recommendations" --since 2026-04-01
# Snapshots before a cutoff
$ savestate search "cocktail recommendations" --until 2026-04-01
# One snapshot
$ savestate search "system prompt" --snapshot ss-2026-01-26T09-30-00-b7c1m4
# ChatGPT snapshots only
$ savestate search "cocktail recommendations" --adapter chatgpt
# Tagged snapshots only
$ savestate search "cocktail recommendations" --tag work
# Labeled snapshots only
$ savestate search "cocktail recommendations" --label backup
# Scriptable JSON results
$ savestate search "cocktail recommendations" --json
# Scriptable JSON with page navigation
$ savestate search "cocktail recommendations" --offset 10 --limit 5 --json-summary
# Scriptable JSON when the snapshot is missing
$ savestate search "cocktail recommendations" --snapshot missing --json
savestate config
View or edit your SaveState configuration.
$ savestate config [options]
| Flag | Description |
|---|---|
--set <key=value> | Set a configuration value (e.g., storage.type=s3). Must be a non-empty key=value pair. |
--limit <n> | Maximum number of adapters to show. Must be a positive integer up to 1000. |
--offset <n> | Skip the first N adapters. Must be a non-negative integer up to 1000. Applied before --limit. |
--json | Emit the current config as JSON. Omits the saved cloud API key. When SaveState is not initialized, emits a missing summary (found, version, storage, defaultAdapter; omits extra fields). Useful for scripting. |
# View current config
$ savestate config
# Cap the adapter list
$ savestate config --limit 5
# Page the adapter list
$ savestate config --offset 10 --limit 5
# Set storage to S3
$ savestate config --set "storage.type=s3"
# Scriptable config (API key omitted)
$ savestate config --json
# Scriptable JSON when SaveState is not initialized
$ savestate config --json
savestate adapters
List all available platform adapters and their detection status. When --platform, --limit, or --offset is used, the human-readable output includes the visible count and page settings so filters and stale offsets are easy to correct.
$ savestate adapters [options]
| Flag | Description |
|---|---|
--json | Output adapter records as JSON. When SaveState is not initialized, emits a missing summary (found, total; omits extra fields). Useful for scripting. |
--platform <id> | Show only adapters reported by the specified platform. Combines with --offset and --limit. |
--limit <n> | Maximum number of adapters to show. Must be a positive integer up to 1000. |
--offset <n> | Skip the first N adapters. Must be a non-negative integer up to 1000. Applied before --limit. |
$ savestate adapters
ID NAME PLATFORM DETECTED
clawdbot Clawdbot openclaw ✓
claude-code Claude Code claude-code ✗
claude-web Claude Web (claude.ai) claude-web ✗
openai-assistants OpenAI Assistants openai-assistants ✗
chatgpt ChatGPT chatgpt ✗
gemini Google Gemini gemini ✗
# Cap the adapter list
$ savestate adapters --limit 5
# Show adapters for one platform
$ savestate adapters --platform claude-code
# Page the adapter list
$ savestate adapters --offset 10 --limit 5
# Scriptable JSON records
$ savestate adapters --json
# Scriptable JSON when SaveState is not initialized
$ savestate adapters --json
Detection is automatic based on the current directory and environment. See Platform Adapters for details on what each adapter captures.
savestate export
Export agent state to an encrypted .savestate container. Loads and encrypts the selected components, then writes the archive. Prints packed components, optionally capped with --limit. --offset skips packed components before --limit. A missing output directory is rejected before encrypting. An existing output file is refused unless --force is set.
$ savestate export -a <id> -o <file> [options]
| Flag | Description |
|---|---|
-a, --agent <id> | Agent ID to export. Must be a single non-empty agent id. |
-o, --output <file> | Output file path (default: agent.savestate). Must be a single non-empty path. A missing parent directory, directory path, or empty path is rejected before writing. |
--dry-run | Encrypt and print export metadata without writing. An existing output file can still be previewed without --force. |
--force | Overwrite an existing output file |
--include <paths> | Only pack named state paths. Must be one or more of: personality, memory, tools, preferences, conversation_history. |
--include-conversation-history | Include conversation history when packing with boolean include flags. Other --include-* flags omit conversation history unless this is also set. |
--exclude <paths> | Skip named state paths from the packed set. Must be one or more of: personality, memory, tools, preferences, conversation_history. |
-p, --passphrase <pass> | Passphrase for encryption, or SAVESTATE_PASSPHRASE / prompt. An empty value is rejected before encrypting. |
-k, --keyfile <path> | Keyfile instead of a passphrase. Must be a single non-empty path. An empty path, missing file, directory, or file with no contents is rejected before encrypting. |
--description <text> | Optional human-readable description stored in the manifest. Must be a non-empty description. |
--limit <n> | Maximum number of packed components to show. Must be a positive integer up to 1000. Combines with --offset. |
--offset <n> | Skip the first N packed components before applying --limit. Must be a non-negative integer up to 1000. |
--json | Emit the export result as JSON. Encrypts the archive. Skips progress output. When the output directory is missing, emits a missing summary (found, output, written, agent; omits extra fields). Useful for scripting. |
# Preview without writing
$ savestate export -a my-agent -o agent.savestate --dry-run
# Overwrite an existing archive
$ savestate export -a my-agent -o agent.savestate --force
# Scriptable export metadata
$ savestate export -a my-agent -o agent.savestate --json --dry-run
# Cap packed component rows
$ savestate export -a my-agent -o agent.savestate --limit 5
# Skip then cap packed components
$ savestate export -a my-agent -o agent.savestate --offset 10 --limit 5
# Missing output directory
$ savestate export -a my-agent -o missing-dir/agent.savestate --json
savestate import
Import agent state from an encrypted .savestate container. Decrypts, verifies, and restores. Prints packed components, optionally capped with --limit. --offset skips packed components before --limit. The input file must be a single non-empty path. A missing input path is rejected before decrypting. A missing --target parent directory is rejected before restoring. An existing target file is refused unless --force is set.
$ savestate import <file> [options]
| Flag | Description |
|---|---|
--dry-run | Decrypt and print import metadata without restoring. An existing target file can still be previewed without --force. |
-p, --passphrase <pass> | Passphrase for decryption, or SAVESTATE_PASSPHRASE / prompt. An empty value is rejected before decrypting. |
-k, --keyfile <path> | Keyfile instead of a passphrase. Must be a single non-empty path. An empty path, missing file, directory, or file with no contents is rejected before decrypting. |
--target <dir> | Write restored agent state to this directory. Must be a single non-empty path. A missing parent directory is rejected before restoring. |
--force | Overwrite an existing target file |
--include <paths> | Only restore named state paths. Must be one or more of: personality, memory, tools, preferences, conversation_history. |
--exclude <paths> | Skip named state paths while restoring. Must be one or more of: personality, memory, tools, preferences, conversation_history. |
--merge | Merge with existing state (default: replace) |
--limit <n> | Maximum number of packed components to show. Must be a positive integer up to 1000. Combines with --offset. |
--offset <n> | Skip the first N packed components before applying --limit. Must be a non-negative integer up to 1000. |
--json | Emit the import result as JSON. Decrypts the archive. Skips progress output. When the input file is missing, emits a missing summary (found, input, restored, agent; omits extra fields). Useful for scripting. |
# Preview without restoring
$ savestate import agent.savestate --dry-run
# Restore into a directory, replacing an existing target file
$ savestate import agent.savestate --target ./restored --force
# Scriptable import metadata
$ savestate import agent.savestate --json --dry-run
# Cap packed component rows
$ savestate import agent.savestate --limit 5
# Skip then cap packed components
$ savestate import agent.savestate --offset 10 --limit 5
# Missing input file
$ savestate import missing.savestate --json
savestate verify
Verify integrity of a .savestate container. Checks the magic header, manifest, checksum, and (when a key is provided) decryptability. Prints packed components and payload metadata, optionally capped with --limit. --offset skips packed components before --limit. An empty, whitespace-only, comma-separated, missing, or directory file path is rejected before reading.
$ savestate verify <file> [options]
| Flag | Description |
|---|---|
<file> | Container to verify. Must be a single non-empty path. |
-p, --passphrase <pass> | Passphrase used to decrypt the container. An empty or whitespace-only value is rejected before decrypting. |
-k, --keyfile <path> | Keyfile instead of a passphrase. Must be a single non-empty path. An empty path, missing file, directory, or file with no contents is rejected before decrypting. |
--limit <n> | Maximum number of packed components to show. Must be a positive integer up to 1000. Combines with --offset. |
--offset <n> | Skip the first N packed components before applying --limit. Must be a non-negative integer up to 1000. |
--json | Emit the full verify result as JSON. Decrypts the archive when a key is provided. When packed components are present, includes pagination metadata (offset, limit, total, shown, hasMore, nextOffset, previousOffset, emptyReason, and suggestedOffset) so scripts can page through component lists and recover from stale offsets. When the input file is missing, emits a missing summary (found, input, valid, agent; omits extra fields). Useful for scripting. |
On a valid file, output includes agent id, created timestamp, format version, optional description, components, excluded paths, checksum, size, content type, payload name, encryption algorithm, and key derivation.
If the container decrypts but has no agent_state payload, verify still prints the metadata it can read from the manifest — including Content-Type, checksum, size, components, and encryption details — then reports the file as corrupted.
# Verify with a passphrase
$ savestate verify agent.savestate --passphrase "secret"
# Cap packed components
$ savestate verify agent.savestate --limit 5
# Skip then cap packed components
$ savestate verify agent.savestate --offset 10 --limit 5
# Scripting
$ savestate verify agent.savestate --json
# Missing input file
$ savestate verify missing.savestate --json
# Verify with a keyfile and JSON
$ savestate verify agent.savestate --keyfile ./key.bin --json
savestate prune
Drop old snapshots according to a retention policy. Dry-run is the default: nothing is deleted unless --apply is set. Specify --keep-last, --older-than, or both.
$ savestate prune [options]
| Flag | Description |
|---|---|
--keep-last <n> | Keep the N most recent snapshots. Must be a positive integer up to 1000. |
--older-than <date> | Drop snapshots older than this date. Must be an ISO 8601 date. |
--adapter <id> | Only prune snapshots from this adapter. Must be one of: clawdbot, claude-code, claude-web, openai-assistants, chatgpt, gemini, cursor, windsurf. Combines with --keep-last and --older-than. |
--exclude <ids> | Skip snapshots from these adapters. Must be one or more of: clawdbot, claude-code, claude-web, openai-assistants, chatgpt, gemini, cursor, windsurf. Combines with --adapter, --keep-last, and --older-than. |
--since <date> | Only prune snapshots taken after this date. Must be an ISO 8601 date. Combines with --adapter, --keep-last, and --older-than. |
--until <date> | Only prune snapshots taken before this date. Must be an ISO 8601 date. Combines with --adapter, --keep-last, and --older-than. |
--snapshot <id> | Only prune this snapshot. Must be a single non-empty snapshot id. Combines with --adapter, --keep-last, and --older-than. |
--tag <tag> | Only prune snapshots with this tag. Must be a single non-empty snapshot tag (no commas). Combines with --adapter, --keep-last, and --older-than. |
--label <label> | Only prune snapshots with this human-readable label. Must be a single non-empty snapshot label (no commas). Combines with --adapter, --keep-last, and --older-than. |
--limit <n> | Only consider the N most recent snapshots. Must be a positive integer up to 1000. Combines with --adapter, --keep-last, and --older-than. |
--offset <n> | Skip the first N snapshots after filters before applying --limit. Must be a non-negative integer up to 1000. Combines with --adapter, --keep-last, and --older-than. |
--apply | Actually delete. Without this flag, prune only prints the plan |
--json | Emit the prune plan as JSON. Useful for scripting. Dry-run is the default unless --apply is set. When SaveState is not initialized, emits a missing summary (found, dryRun, keepCount, dropCount; omits extra fields). |
The newest snapshot is never pruned. A snapshot that is the only one for its adapter is held back for chain safety.
# Preview which snapshots would be dropped
$ savestate prune --keep-last 10
# Only prune snapshots from one adapter
$ savestate prune --keep-last 10 --adapter chatgpt
# Skip snapshots from excluded adapters
$ savestate prune --keep-last 10 --exclude chatgpt
# Only prune snapshots taken after a cutoff
$ savestate prune --keep-last 10 --since 2026-04-01
# Only prune snapshots taken before a cutoff
$ savestate prune --keep-last 10 --until 2026-06-01
# Only prune one snapshot
$ savestate prune --keep-last 10 --snapshot ss-2026-09-13T12-00-00-ab12cd
# Only prune snapshots with one tag
$ savestate prune --keep-last 10 --tag work
# Only prune labeled snapshots
$ savestate prune --keep-last 10 --label backup
# Only consider the N most recent snapshots
$ savestate prune --keep-last 1 --limit 5
# Skip the first N snapshots after filters
$ savestate prune --keep-last 1 --offset 10 --limit 5
# Delete snapshots older than a cutoff
$ savestate prune --older-than 2026-01-01 --apply
# Scripting
$ savestate prune --keep-last 10 --json
# Scriptable JSON when SaveState is not initialized
$ savestate prune --json
savestate antibodies
Manage failure antibodies: reusable rules that match a tool, error, or path and suggest a safe action. Subcommands: list, add, preflight, stats. Must be a single non-empty subcommand (list, add, preflight, or stats). list, stats, preflight, and add can cap per-rule or status-field output with --limit. list, stats, and preflight can skip rules or warnings with --offset before --limit.
$ savestate antibodies <subcommand> [options]
| Flag | Description |
|---|---|
--json | Emit antibody list, preflight, stats, and an add summary (id, risk, safe action, and confidence) as JSON. List output is a stable rule summary (id, risk, intervention, active, confidence, hits, overrides, and safe action). When SaveState is not initialized, list --json emits a missing summary (found, total, shown; omits extra fields) and add --json emits a missing summary (found, added, id; omits extra fields). Preflight output is a stable summary (blocked, elapsed, semantic, all matched rule IDs, and warnings with rule id, risk, intervention, confidence, safe action, and reasons). Matched rule IDs include warnings hidden by --offset or --limit. When SaveState is not initialized, preflight --json emits a missing summary (found, blocked, elapsedMs, semanticUsed; omits extra fields). Stats output is a stable summary (counts plus per-rule hits and overrides). When SaveState is not initialized, stats --json emits a missing summary (found, totalRules, activeRules, retiredRules, totalHits, totalOverrides; omits extra fields). Omits extra fields. Useful for scripting. |
--all | Include retired rules in list. Combines with --limit and --offset. |
--limit <n> | Maximum number of antibody rules to show on list or stats, or preflight warnings, or add status field rows. Must be a positive integer up to 1000. Combines with --all and --offset on list, and with --offset on stats. |
--offset <n> | Skip the first N antibody rules on list or stats, or warnings on preflight, before applying --limit. Must be a non-negative integer up to 1000. |
--tool <name> | Tool name for add / preflight. Must be a single non-empty tool name. |
--error-code <code> | Error code in the rule trigger or preflight context. Must be a single non-empty error code. |
--path-prefix <prefix> | Path prefix in the rule trigger. Must be a single non-empty path prefix. |
--path <path> | Path in preflight context. Must be a single non-empty path. |
--tags <tags> | Comma-separated tags for add / preflight. Must be one or more non-empty antibody tags (comma-separated). |
--risk <level> | Risk level: low, medium, high, or critical |
--safe-action <type> | Safe action for a manual rule |
--confidence <0..1> | Rule confidence |
--id <id> | Rule ID when adding manually. Must be a single non-empty rule id. |
--semantic | Enable the semantic matcher stub on preflight |
# List active rules
$ savestate antibodies list
# Cap the antibody list
$ savestate antibodies list --limit 5
# Skip the first 10, then show the next 5
$ savestate antibodies list --offset 10 --limit 5
# Scripting
$ savestate antibodies list --json
# Add a rule for a tool/error pair
$ savestate antibodies add --tool write --error-code EACCES --risk high --safe-action check_permissions --json
# Cap add status field rows
$ savestate antibodies add --tool write --error-code EACCES --limit 5
# Scriptable JSON when SaveState is not initialized
$ savestate antibodies add --json
# Check whether a planned action matches a rule
$ savestate antibodies preflight --tool write --path ./secret.env --json
$ savestate antibodies preflight --limit 5
$ savestate antibodies preflight --offset 10 --limit 5
# Scriptable JSON when SaveState is not initialized
$ savestate antibodies preflight --json
# Hit counts and overrides
$ savestate antibodies stats --json
$ savestate antibodies stats --limit 5
# Skip the first 10 stats rules, then show the next 5
$ savestate antibodies stats --offset 10 --limit 5
savestate schedule
Configure automatic backup schedule. Enabling a schedule requires Pro or Team and a logged-in API key. Status and disable work without a subscription. Uses launchd on macOS and systemd user timers on Linux. With no flags, prints the current status.
$ savestate schedule [options]
| Flag | Description |
|---|---|
-e, --every <interval> | Backup interval (e.g., 1h, 6h, 12h, 1d). Must be a duration like 1h, 6h, 12h, or 1d up to 7 days. Requires Pro or Team |
-d, --disable | Disable scheduled backups |
-s, --status | Show schedule status (default when no other flag is set) |
--limit <n> | Maximum number of status field rows to show. Must be a positive integer up to 1000. Combines with --offset. |
--offset <n> | Skip the first N status field rows. Must be a non-negative integer up to 1000. Applied before --limit. |
--json | Emit schedule status as JSON. Skips progress output. When SaveState is not initialized, emits a missing summary (found, enabled, running, supported; omits extra fields). Useful for scripting. |
Run savestate login first. The job runs savestate snapshot --label auto on the interval.
# Show whether scheduled backups are enabled
$ savestate schedule
# Cap status field rows
$ savestate schedule --limit 5
# Page status field rows
$ savestate schedule --offset 10 --limit 5
# Scriptable schedule status
$ savestate schedule --json
# Enable a 6-hour backup schedule
$ savestate schedule --every 6h
# Turn scheduled backups off
$ savestate schedule --disable
savestate migrate
Move AI identity between platforms (ChatGPT → Claude, Claude → Gemini, and so on). Requires savestate init first. With no flags, prompts for source and target. Source and target cannot be the same platform.
$ savestate migrate [options]
| Flag | Description |
|---|---|
-f, --from <platform> | Source platform to migrate from. Must be one of: chatgpt, claude, gemini, copilot. |
-t, --to <platform> | Target platform to migrate to. Must be one of: chatgpt, claude, gemini, copilot. |
-s, --snapshot <id> | Use an existing snapshot instead of creating a new one. Must be a single non-empty snapshot id. |
--label <label> | Use the newest existing snapshot with this label instead of creating a new one. Must be a single non-empty snapshot label (no commas). ANDs with --snapshot when both are set. |
--tag <tag> | Use the newest snapshot with this tag instead of creating a new one. Must be a single non-empty snapshot tag (no commas). ANDs with --snapshot and --label when those flags are set. |
--until <date> | Use the newest existing snapshot taken on or before this date instead of creating a new one. Must be an ISO 8601 date. ANDs with --snapshot, --label, --tag, --since, and --adapter when those flags are set. |
--adapter <id> | Use the newest snapshot from this adapter instead of creating a new one. Must be one of: clawdbot, claude-code, claude-web, openai-assistants, chatgpt, gemini, cursor, windsurf. ANDs with --snapshot, --label, --tag, --since, --until, --limit, and --offset when those flags are set. |
--limit <n> | Use the newest of the N most recent matching snapshots instead of creating a new one. Must be a positive integer up to 1000. ANDs with --snapshot, --label, --tag, --since, --until, --adapter, and --offset when those flags are set. |
--offset <n> | Skip the first N matching snapshots after filters before applying --limit. Must be a non-negative integer up to 1000. ANDs with --snapshot, --label, --tag, --since, --until, --adapter, and --limit when those flags are set. |
-l, --list | List available platforms and their capabilities |
--json | Emit the platform catalog as JSON with --list, or a compatibility report as JSON with --dry-run (source, target, feasibility, summary, items, and recommendations; omits source refs). When SaveState is not initialized, emits a missing summary (found, source, target, feasibility; omits extra fields). Skips the wizard banner. Useful for scripting. |
--dry-run | Show a compatibility report without making changes |
--review | Inspect items needing manual attention without migrating |
--resume | Resume an interrupted migration |
-i, --include <types> | Only migrate specific types: instructions, memories, conversations, files, customBots (comma-separated). Must be one or more of: instructions, memories, conversations, files, customBots. |
--exclude <types> | Skip migrate types: instructions, memories, conversations, files, customBots (comma-separated). Must be one or more of: instructions, memories, conversations, files, customBots. |
--force | Skip the confirmation prompt before writing |
-v, --verbose | Show detailed progress |
--no-color | Disable colorized output |
# List platforms the wizard can migrate between
$ savestate migrate --list
# Scriptable platform catalog
$ savestate migrate --list --json
# Preview ChatGPT → Claude without writing anything
$ savestate migrate --from chatgpt --to claude --dry-run
# Scriptable compatibility report
$ savestate migrate --from chatgpt --to claude --dry-run --json
# Missing summary when SaveState is not initialized
$ savestate migrate --json
# Inspect items that need manual attention
$ savestate migrate --from chatgpt --to claude --review
# Memories only, skip confirmation
$ savestate migrate --from chatgpt --to claude --include memories --force
# Skip conversations
$ savestate migrate --from chatgpt --to claude --exclude conversations --force
# Resume an interrupted migration
$ savestate migrate --resume
# Run the migration
$ savestate migrate --from chatgpt --to claude
# Reuse an existing snapshot instead of creating a new one
$ savestate migrate --from chatgpt --to claude --snapshot ss-2026-01-26T09-30-00-b7c1m4
# Reuse the newest snapshot with this label
$ savestate migrate --from chatgpt --to claude --label backup
# Reuse the newest tagged snapshot instead of creating a new one
$ savestate migrate --from chatgpt --to claude --tag work
# Reuse the newest snapshot taken after this date
$ savestate migrate --from chatgpt --to claude --since 2026-04-01
# Reuse the newest snapshot taken on or before this date
$ savestate migrate --from chatgpt --to claude --until 2026-06-01
# Reuse the newest snapshot from this adapter
$ savestate migrate --from chatgpt --to claude --adapter chatgpt
# Reuse the newest of the N most recent matching snapshots
$ savestate migrate --from chatgpt --to claude --limit 5
# Skip the newest 10, then reuse the newest of the next 5
$ savestate migrate --from chatgpt --to claude --offset 10 --limit 5
savestate trust
Inspect Trust Kernel state, the promotion audit trail, and the WriteGate denylist. Subcommands: status, audit, and deny (add, remove, list). See the Trust Kernel docs for the state machine.
$ savestate trust <subcommand> [options]
| Flag | Description |
|---|---|
--json | Emit Trust Kernel metrics as JSON on status, audit events as JSON (entry id, states, actor, and reason) on audit, denylist entries as JSON (pattern, reason, actor, and epoch) on deny list, a deny-remove summary (pattern and removed count) on deny remove, or a deny-add summary (pattern, reason, and actor) on deny add. The paged status, audit, and deny list responses include a pagination object with offset, limit, total, shown, hasMore, and nextOffset (status reports these fields separately for state and scope). Pass nextOffset back with --offset while hasMore is true. When no denylist entry matches, deny remove emits a missing summary (found, pattern, removed; omits extra fields). Omits event metadata. Useful for scripting. |
<pattern> | Denylist pattern for deny add and deny remove. Must be a single non-empty denylist pattern. |
--limit <n> | Number of recent events for audit (default 50), maximum denylist entries to show on deny list, or maximum state or scope metric rows on status, or maximum status field rows on deny add or deny remove. Must be a positive integer up to 1000. Combines with --offset on status, audit, deny list, deny add, and deny remove. |
--offset <n> | Skip the first N state or scope metric rows on status, audit events on audit, denylist entries on deny list, or status field rows on deny add and deny remove, before applying --limit. Must be a non-negative integer up to 1000. |
-r, --reason <reason> | Why a pattern is denylisted on deny add. Must be a non-empty reason. |
-b, --by <actor> | Who is adding the denylist entry (defaults to cli). Must be a single non-empty actor id. |
# Entries by state/scope and denylist size
$ savestate trust status --json
# Cap status metric rows
$ savestate trust status --limit 5
# Skip the first 10, then show the next 5
$ savestate trust status --offset 10 --limit 5
# Recent promotion and rejection events
$ savestate trust audit --limit 20 --json
# Skip the newest 10, then show the next 5
$ savestate trust audit --offset 10 --limit 5
# Scripting
$ savestate trust audit --json
# Block a pattern at the WriteGate
$ savestate trust deny add secret.env --reason "contains credentials" --json
# Cap deny-add status field rows
$ savestate trust deny add secret.env --reason "contains credentials" --limit 5
# Page deny-add status field rows
$ savestate trust deny add secret.env --offset 1 --limit 2
# Unblock a pattern
$ savestate trust deny remove secret.env --json
# Cap deny-remove status field rows
$ savestate trust deny remove secret.env --limit 5
# Page deny-remove status field rows
$ savestate trust deny remove secret.env --offset 1 --limit 2
# List denylist entries
$ savestate trust deny list --json
# Cap denylist output
$ savestate trust deny list --limit 5
# Page denylist entries
$ savestate trust deny list --offset 10 --limit 5
savestate team
Team management for the Team tier: membership, invites, and the audit log. Subcommands: status, members, invite, and audit. Must be a single non-empty subcommand (status, members, invite, or audit). Requires savestate login. A 402 response means the account is not on Team — upgrade at savestate.dev/#pricing.
$ savestate team <subcommand> [options]
| Flag | Description |
|---|---|
<subcommand> | Team action. Must be a single non-empty subcommand (status, members, invite, or audit). |
<email> | Invite address for invite. Must be a single non-empty email address. |
-r, --role <role> | Invite role: admin, member, or viewer (default member). Must be one of: admin, member, viewer. |
--json | Emit team status as JSON (id, name, and role), members as JSON (email, role, and invite timestamps), invite as JSON (invited email, role, and invite timestamps), or audit as JSON (id, action, actor, resource, and timestamp). Omits event metadata. When team status is missing, emits a missing summary (found, id, name, role; omits extra fields). When team members are missing, emits a missing summary (found, name, total, shown; omits extra fields). When a team invite is missing, emits a missing summary (found, email, role; omits extra fields). When the team or audit log is missing, audit --json emits a missing summary (found, teamId, count, nextCursor; omits extra fields). Useful for scripting. |
--since <date> | Audit entries after this date. Must be an ISO 8601 date. |
--until <date> | Audit entries before this date. Must be an ISO 8601 date. |
--limit <n> | Maximum number of team members to show on members, audit entries on audit, or status field rows on status or invite. Must be a positive integer up to 1000. On audit, ANDs with --since and --until when those flags are set. Combines with --offset on status, members, and audit. |
--offset <n> | Skip the first N status field rows on status, team members on members, or audit entries on audit before applying --limit. Must be a non-negative integer up to 1000. |
--format <format> | Audit output: csv or json (default json). Must be one of: csv, json. |
# Your team name, id, and role
$ savestate team status --json
# Cap status field rows
$ savestate team status --limit 5
# Skip then cap status field rows
$ savestate team status --offset 1 --limit 2
# Members and pending invites
$ savestate team members --json
# Cap the member list
$ savestate team members --limit 5
# Skip then cap the member list
$ savestate team members --offset 10 --limit 5
# Invite a viewer
$ savestate team invite user@example.com --role viewer --json
# Cap invite status field rows
$ savestate team invite user@example.com --limit 5
# Stream the audit log as CSV
$ savestate team audit --since 2026-01-01 --format csv
# Cap the audit log
$ savestate team audit --limit 20 --json
# Skip then cap the audit log
$ savestate team audit --offset 10 --limit 5
# Scripting
$ savestate team audit --json
savestate eval
Run memory quality benchmarks and print the last report. Subcommands: quality and report. Must be a single non-empty subcommand (quality or report). Requires savestate init. Suites load from .savestate/benchmarks/ (JSON files). Results are saved to .savestate/eval-results.json. Reports precision, recall, F1, stale-hit rate, constraint retention, and confidence.
$ savestate eval <subcommand> [options]
| Flag | Description |
|---|---|
--threshold <0..1> | Confidence threshold for pass/fail on quality (default 0.7). Must be a number between 0 and 1. |
--suite <name> | Run only a specific benchmark suite. Must be a single non-empty name (no commas or spaces). |
--limit <n> | Maximum number of benchmark suites to run on quality or show on report. Must be a positive integer up to 1000. Combines with --offset on quality and report. |
--offset <n> | Skip the first N benchmark suites on quality or report before applying --limit. Must be a non-negative integer up to 1000. |
-v, --verbose | Show per-test metrics |
--json | Emit quality and report results as JSON. A paged report response includes pagination metadata (offset, limit, total, shown, emptyReason, suggestedOffset, hasMore, nextOffset, hasPrevious, and previousOffset) so scripts can navigate or recover from stale offsets; this metadata is also retained when the report is missing. Human-readable paged reports print matching next, previous, and stale-page hints. When SaveState is not initialized, quality emits a missing summary (found, suite, suiteCount, passed, total, passRate; omits extra fields). When the named suite is missing, quality emits a missing summary (found, suite, suiteCount, passed, total, passRate; omits extra fields). When SaveState is not initialized, report emits a missing summary (found, suiteCount, passed, total, passRate; omits extra fields unless pagination was requested). When no report exists, report emits a missing summary (found, suiteCount, passed, total, passRate; omits extra fields unless pagination was requested). Useful for scripting. |
# Run every benchmark suite
$ savestate eval quality
# Cap suites to run
$ savestate eval quality --limit 5
# Skip then cap suites to run
$ savestate eval quality --offset 10 --limit 5
# One suite, stricter threshold, JSON
$ savestate eval quality --suite recall --threshold 0.9 --json
# Cap suites in the last report
$ savestate eval report --limit 5
# Skip then cap suites in the last report
$ savestate eval report --offset 10 --limit 5
# Last saved report with per-test metrics
$ savestate eval report --verbose
# Scripting
$ savestate eval report --json
savestate login
Authenticate with SaveState cloud. Requires savestate init first. Prompts for an API key unless you pass --key. Keys start with ss_live_ — get yours at savestate.dev/account. The key is validated against the API and saved locally so cloud features (schedule, cloud push/pull, team) unlock.
$ savestate login [options]
| Flag | Description |
|---|---|
-k, --key <api-key> | API key (or enter interactively). Must be a single non-empty API key. |
--limit <n> | Maximum number of status field rows to show. Must be a positive integer up to 1000. |
--offset <n> | Skip the first N status field rows. Must be a non-negative integer up to 1000. |
--json | Emit the login result as JSON. Skips the spinner. When SaveState is not initialized, emits a missing summary (found, authenticated, email, tier; omits extra fields). Useful for scripting. |
# Prompt for the key
$ savestate login
# Pass the key on the command line
$ savestate login --key ss_live_...
# Cap status field rows
$ savestate login --limit 5
# Page status field rows
$ savestate login --offset 1 --limit 2
# Scriptable login
$ savestate login --key ss_live_... --json
# Scriptable JSON when SaveState is not initialized
$ savestate login --json
savestate logout
Remove the saved cloud API key from local config. Does not revoke the key on the server. Reports if you were not logged in.
$ savestate logout [options]
| Flag | Description |
|---|---|
--limit <n> | Maximum number of status field rows to show. Must be a positive integer up to 1000. |
--offset <n> | Skip the first N status field rows. Must be a non-negative integer up to 1000. |
--json | Emit logout status as JSON. Skips progress output. When SaveState is not initialized, emits a missing summary (found, loggedOut, hadKey; omits extra fields). Useful for scripting. |
# Remove the saved cloud API key
$ savestate logout
# Cap status field rows
$ savestate logout --limit 5
# Page status field rows
$ savestate logout --offset 1 --limit 2
# Scriptable logout status
$ savestate logout --json
savestate cloud
Push, pull, list, and delete encrypted snapshots in SaveState cloud storage. Requires Pro or Team and a logged-in API key (savestate login). Snapshots stay encrypted; the CLI uploads .saf.enc files through the API. Default push/pull is the latest snapshot unless you pass --id, --adapter, --exclude, --since, --until, --label, --tag, --limit, --offset, or --all. Subcommand must be a single non-empty value: push, pull, list, or delete.
$ savestate cloud <subcommand> [options]
| Flag | Description |
|---|---|
<subcommand> | Cloud action. Must be a single non-empty subcommand: push, pull, list, or delete. |
--id <id> | Specific snapshot ID (prefix match allowed). Must be a single non-empty snapshot id. |
--adapter <id> | Push the newest local snapshot from this adapter. Must be one of: clawdbot, claude-code, claude-web, openai-assistants, chatgpt, gemini, cursor, windsurf. Combines with --id, --exclude, --since, --until, --label, --tag, --limit, and --all. |
--exclude <ids> | Skip snapshots from these adapters. Must be one or more of: clawdbot, claude-code, claude-web, openai-assistants, chatgpt, gemini, cursor, windsurf. Combines with --id, --adapter, --since, --until, --label, --tag, --limit, and --all. |
--since <date> | Push the newest local snapshot taken after this date. Must be an ISO 8601 date; a date-only value starts at 00:00:00 UTC. Combines with --id, --adapter, --exclude, --until, --label, --tag, --limit, and --all. |
--until <date> | Push the newest local snapshot taken on or before this date. Must be an ISO 8601 date; a date-only value ends at 23:59:59.999 UTC. Combines with --id, --adapter, --exclude, --since, --label, --tag, --limit, and --all. |
--label <label> | Push the newest local snapshot with this label. Must be a single non-empty snapshot label (no commas). Combines with --id, --adapter, --exclude, --since, --until, --tag, --limit, and --all. |
--tag <tag> | Push the newest local snapshot with this tag. Must be a single non-empty snapshot tag (no commas). Combines with --id, --adapter, --exclude, --since, --until, --label, --limit, and --all. |
--limit <n> | Push the N newest matching local snapshots, or show at most N cloud list rows, or pull at most N cloud snapshots, or delete at most N cloud snapshots. Must be a positive integer up to 1000. Combines with --id, --adapter, --exclude, --since, --until, --label, --tag, --offset, and --all. |
--offset <n> | After filters, skip the first N newest matching local snapshots; for cloud pagination, skip the first N cloud list rows and skip the first N cloud list/pull rows; or skip matching cloud snapshots before applying --limit on delete. Must be a non-negative integer up to 1000. Combines with --id, --adapter, --exclude, --since, --until, --label, --tag, --limit, and --all. |
--all | Process all snapshots instead of the latest |
-f, --force | Overwrite existing local files on pull, or skip delete confirmation |
--json | Emit the cloud list as JSON with found, total, shown, remaining, offset, limit, page navigation, emptyReason, and suggestedOffset for stale pages, plus tier, storage usage, and snapshot rows; interactive paged output also prints next, previous, or recovery commands. A push summary with found, uploaded count, and snapshot ids on push; pull results with found on pull; or delete results with found on delete. When SaveState is not initialized, push emits a missing summary (found, id, pushed, failed; omits extra fields). When SaveState is not initialized, list emits a missing summary (found, total, shown; omits extra fields). When SaveState is not initialized, pull emits a missing summary (found, id, pulled, failed, skipped; omits extra fields). When SaveState is not initialized, delete emits a missing summary (found, id, deleted, failed; omits extra fields). When the snapshot ID is missing, push emits a missing summary (found, id, pushed, failed; omits extra fields), pull emits a missing summary (found, id, pulled, failed, skipped; omits extra fields), and delete emits a missing summary (found, id, deleted, failed; omits extra fields). Skips the spinner and delete confirmation. Useful for scripting. |
# List snapshots in cloud storage
$ savestate cloud list
# Cap the cloud inventory
$ savestate cloud list --limit 5
# Page through the cloud inventory
$ savestate cloud list --offset 10 --limit 5
# Scriptable cloud inventory
$ savestate cloud list --json
# Push the latest local snapshot
$ savestate cloud push
# Push the newest ChatGPT snapshot
$ savestate cloud push --adapter chatgpt
# Scriptable cloud push
$ savestate cloud push --json
# Push the newest snapshot taken after a date
$ savestate cloud push --since 2026-04-01
# Push the newest snapshot taken on or before a date
$ savestate cloud push --until 2026-06-01
# Push the newest snapshot that is not from ChatGPT
$ savestate cloud push --exclude chatgpt
# Push the newest snapshot with a label
$ savestate cloud push --label backup
# Push the newest snapshot with a tag
$ savestate cloud push --tag work
# Push the 5 newest matching local snapshots
$ savestate cloud push --limit 5
# Skip the newest matching snapshots before --limit
$ savestate cloud push --offset 10 --limit 5
# Pull a specific snapshot, overwriting the local file
$ savestate cloud pull --id ss-2026-01-26 --force
# Cap how many cloud snapshots to pull
$ savestate cloud pull --limit 5
# Page through cloud snapshots before pulling
$ savestate cloud pull --offset 10 --limit 5
# Scriptable pull summary
$ savestate cloud pull --json
# Delete one cloud snapshot without the confirm prompt
$ savestate cloud delete --id ss-2026-01-26 --force
# Cap how many matching cloud snapshots to delete
$ savestate cloud delete --id ss-2026-01-26 --limit 5
# Skip matching snapshots before deleting a page
$ savestate cloud delete --offset 10 --limit 5 --all
# Scriptable cloud delete
$ savestate cloud delete --id ss-2026-01-26 --json
savestate mcp
MCP server commands for Claude Code, Cursor, Codex, and other MCP clients. Subcommands: serve, status, export, and import. Must be a single non-empty subcommand (serve, status, export, or import). Omitting the subcommand starts the server (serve). Stdio is the default transport. Client JSON snippets are on the MCP Server guide. export and import require savestate init.
$ savestate mcp <subcommand> [options]
| Flag | Description |
|---|---|
<subcommand> | MCP action. Must be a single non-empty subcommand: serve, status, export, or import. Omitting the subcommand starts the server. |
-p, --port <port> | HTTP port for serve (default 3333; HTTP mode is not implemented yet). Must be an integer from 1 to 65535. |
--stdio | Use stdio transport (default, recommended for MCP clients) |
--no-stdio | Request HTTP transport instead of stdio (not implemented yet) |
-a, --agent <id> | Agent ID for export (default default) or target agent for import. Must be a single non-empty agent id. |
-o, --output <path> | Passport output path for export. Must be a single non-empty path. |
--include-snapshots | Include snapshot metadata in the exported passport |
--limit <n> | Maximum number of MCP tools and resources to show on status, memories and snapshot metadata rows to include on export, memories to import on import, or serve status field rows on serve. Must be a positive integer up to 1000. Combines with --offset. |
--offset <n> | Skip the first N MCP tools and resources on status, snapshot metadata rows on export, or memories on import before applying --limit. Must be a non-negative integer up to 1000. |
-i, --input <path> | Passport file to import (required for import). Must be a single non-empty path. |
--merge | Merge imported memories with existing ones instead of replacing |
--json | Emit MCP status as JSON on status, including pagination.tools and pagination.resources objects with offset, limit, total, shown, hasMore, nextOffset, hasPrevious, previousOffset, and suggestedOffset when a page is empty; human-readable status headings show the visible/total count (for example, Available MCP Tools (5/14 shown):) and point empty pages to the nearest populated offset; export summary (agent, output path, memory/snapshot counts, requested offset and limit) on export; or import summary (input path, source/target agents, memory/snapshot counts, requested offset and limit) on import. Pass a returned nextOffset back with --offset while hasMore is true, or previousOffset while hasPrevious is true to move backward. When a page is empty, pass suggestedOffset to recover the nearest populated page. When SaveState is not initialized, status --json emits a missing summary (found, initialized, enabled; omits extra fields). When SaveState is not initialized, export emits a missing summary (found, agent, output, memories, snapshots, written; omits extra fields). When the agent has no memories or snapshots, export emits a missing summary (found, agent, output, memories, snapshots, written; omits extra fields). When SaveState is not initialized, import emits a missing summary (found, input, importedMemories, totalMemories, snapshots; omits extra fields). When the passport file is missing, import emits a missing summary (found, input, importedMemories, totalMemories, snapshots; omits extra fields). Skips progress output. Useful for scripting. |
# Start the MCP server (stdio)
$ savestate mcp serve
# Cap serve status field rows
$ savestate mcp serve --limit 5
# Config, tools, and client snippet
$ savestate mcp status
# Cap listed MCP tools and resources
$ savestate mcp status --limit 5
# Skip listed MCP tools and resources before --limit
$ savestate mcp status --offset 10 --limit 5
# An exhausted page prints a nearby offset to retry
# Paginated output includes previous/next commands for each page
# Scriptable MCP status
$ savestate mcp status --json
# Export a memory passport
$ savestate mcp export --agent my-agent --include-snapshots
# Cap exported memories and snapshot metadata
$ savestate mcp export --limit 5
# Skip exported snapshot metadata before --limit
$ savestate mcp export --offset 10 --limit 5
# Scriptable export summary
$ savestate mcp export --agent my-agent --json
# Import a passport into another agent
$ savestate mcp import --input passport.json --agent other-agent --merge
# Cap imported memories
$ savestate mcp import --input passport.json --limit 5
# Resume importing after the first page
$ savestate mcp import --input passport.json --offset 10 --limit 5
# Scriptable import summary
$ savestate mcp import --input passport.json --json
savestate context
Preflight context compilation for agent runs. Subcommands: compile, explain, validate, and config. compile builds a RunBrief for an agent and task within a token budget (default 4000), including unknowns alongside the other context sections. compile --limit caps the RunBrief section list. explain prints the inclusion trace for a compiled run and requires a single non-empty run id. explain --limit caps the candidate list (default 10). validate checks a RunBrief JSON file, optionally capping errors and warnings with --limit. config shows scoring weights and budget allocation, with --offset skipping rows before --limit.
$ savestate context <subcommand> [options]
| Flag | Description |
|---|---|
<run-id> | Run ID for explain. Must be a single non-empty run id. |
-a, --agent <id> | Agent ID for compile (required). Must be a single non-empty agent id. |
-t, --task <intent> | Task intent for compile (required). Must be a non-empty task intent. |
-b, --budget <tokens> | Token budget for compile (default 4000). Must be a positive integer up to 1000000. |
-f, --file <path> | Path to a RunBrief JSON file for validate. Must be a single non-empty path. |
--weights | Show scoring weights on config |
--budget | Show budget allocation on config |
--limit <n> | Maximum number of explain candidates to show on explain (default 10), or scoring weight or budget allocation rows on config, or RunBrief section rows on compile, or validation errors and warnings on validate. Must be a positive integer up to 1000. |
--offset <n> | Skip the first N explain candidates, RunBrief section rows, validation errors and warnings, or scoring weight and budget allocation rows. Must be a non-negative integer up to 1000. |
--json | Emit compile, explain, validate, and config results as JSON. Compile includes section counts plus paged sections, a shown count for the returned section rows, and pagination metadata (offset, limit, pageSize, totalSections, hasMore, nextOffset, previousOffset, and suggestedOffset); human-readable compile output prints the same page hints. Explain omits score breakdowns and includes emptyReason plus pagination metadata (offset, limit, total, pageSize, hasMore, nextOffset, previousOffset, and suggestedOffset) so consumers can distinguish an empty run from an exhausted page, recover from a stale offset, and return to the prior page; human-readable explain output prints the same next, previous, and stale-page hints. Validate includes valid flag, errors, warnings, coverage, and pagination metadata (offset, limit, total issue counts, hasMore, nextOffset, previousOffset, and suggestedOffset). Config includes shown counts and next, previous, and stale-offset recovery metadata for both weights and budget rows. When hasMore is true, pass nextOffset back with --offset to read the next issue or config page; pass previousOffset to return to the prior page. If an offset is past the available issues or config rows, use suggestedOffset to recover the last page; human-readable validation output prints the same recovery hint. When the RunBrief file is missing, validate emits a missing summary (found, file, valid, errors, warnings; omits extra fields). Skips progress output. Useful for scripting. |
# Compile a RunBrief
$ savestate context compile --agent my-agent --task "summarize inbox"
$ savestate context compile --agent my-agent --task "summarize inbox" --limit 5
$ savestate context compile --agent my-agent --task "summarize inbox" --offset 2 --limit 3
# Explain why candidates were included
$ savestate context explain run_abc123 --json
$ savestate context explain run_abc123 --limit 5
$ savestate context explain run_abc123 --offset 5 --limit 5
# Validate a saved brief
$ savestate context validate --file brief.json
$ savestate context validate --file brief.json --limit 5
$ savestate context validate --file brief.json --offset 5 --limit 5
# Show scoring weights and budget split
$ savestate context config --weights --budget
$ savestate context config --limit 5
$ savestate context config --offset 2 --limit 5
# Scripting
$ savestate context compile --agent my-agent --task "summarize inbox" --json
$ savestate context explain run_abc123 --json
$ savestate context validate --file brief.json --json
$ savestate context config --json
savestate memory
For memory explain --json, use --offset with --limit to page through ranked matches, and pass --snapshot to inspect a historical archive. Filters are applied before pagination, so each result keeps its stable 1-based rank, while pagination.remaining reports how many matching results follow the visible page, including 0 for an empty or exhausted page. The explain pagination object also includes suggestedOffset when a later page is empty, so clients can retry the nearest available page. For memory log --json, the response includes pagination metadata with offset, limit, total, shown, hasMore, nextOffset, previousOffset, emptyReason, and suggestedOffset; an exhausted page is reported as emptyReason: page, while a missing memory remains the compact found: false summary.
Manage multi-tier memory (L1/L2/L3) for long-running agents. Subcommands: list, promote, demote, pin, unpin, apply-policies, config, explain, edit, delete, rollback, expire, and log. promote, demote, pin, unpin, edit, delete, rollback, and log require a single non-empty memory id. explain requires a non-empty query, can inspect a historical archive with --snapshot, and can scope retrievals by tier with --tier, source with --source, content with --content, tags with --tags, pin state with --pinned or --unpinned, freshness with --freshness, creation date with --since and --until, importance with --min-importance and --max-importance, task criticality with --min-criticality and --max-criticality, and optionally cap results with --limit. Importance and criticality default to 0.5 when metadata is missing or invalid; when both bounds of either score are provided, the minimum must be at or below the maximum. config --limit and config --offset accept decimal integers only (surrounding whitespace is allowed), bounded to 1-1000 and 0-1000 respectively. Requires savestate init. Prompts for the archive passphrase unless SAVESTATE_PASSPHRASE is set.
Memory explain shows each result's current freshness state, creation date, profile, and last verified date. Use --tier to scope the explanation to L1, L2, or L3 memories. With --json, results also include effective importance and criticality scores, normalized source, non-empty normalized tags, pinned state, and tier, plus createdAt and machine-readable freshness, freshnessClass, lastVerifiedAt, and optional verificationSource fields.
Explain output includes the resolved archive snapshot ID, including when no memories match, so scripts and human readers can verify which archive was inspected.
$ savestate memory <subcommand> [options]
| Flag | Description |
|---|---|
<memory-id> | Memory to promote, demote, pin, unpin, edit, delete, rollback, or log. Must be a single non-empty memory id. |
<query> | Search text for explain. Must be a non-empty query. |
-t, --tier <tier> | Filter list or explain by tier (L1, L2, L3) |
-p, --pinned | Show only pinned memories on list, or scope retrieval explanations to pinned memories on explain |
--unpinned | Show only unpinned memories on list, or scope retrieval explanations to unpinned memories on explain; mutually exclusive with --pinned |
--source <id> | Show only memories captured from this source id on list or use it to scope retrieval explanations on explain; matching is case-insensitive |
--until <date> | Show only memories created on or before this ISO-8601 date or timestamp on list or explain; date-only values include the full UTC day |
--since <date> | Show only memories created on or after this ISO-8601 date or timestamp on list or explain. Date-only values start at 00:00 UTC. |
--freshness <state> | Show only memories in the requested freshness state: active, stale, or needs_confirmation. |
--min-importance <n> | Show only list or explain memories with an importance score at least n (0-1, inclusive). Missing importance metadata uses the default score of 0.5. |
--max-importance <n> | Show only list or explain memories with an importance score at most n (0-1, inclusive). Missing importance metadata uses the default score of 0.5. |
--min-criticality <n> | Show only explain memories with task criticality at least n (0-1, inclusive). Missing or invalid criticality metadata uses the default score of 0.5. |
--max-criticality <n> | Show only explain memories with task criticality at most n (0-1, inclusive). Missing or invalid criticality metadata uses the default score of 0.5. |
-n, --namespace <ns> | Show only memories whose metadata namespace matches org:app:agent[:user] on list, explain, and expire. Must be a single non-empty namespace. |
--content <text> | Show only memories whose content includes this text, case-insensitively. Must be non-empty. |
--tags <tags> | Show only memories containing every requested metadata tag. Matching is case-insensitive. Provide one or more non-empty tags separated by commas; surrounding whitespace and duplicate tags are normalized. |
--oldest-first | Show memories from oldest to newest on list (default: newest first) |
--reverse | Alias for --oldest-first on list |
-l, --limit <n> | Maximum number of memories to show on list (default 20), maximum audit events to show on log, maximum expirable memories to show on expire, maximum tier changes to show on apply-policies, or maximum configuration setting rows to show on config, or maximum status field rows to show on promote, or maximum status field rows to show on demote, or maximum status field rows to show on pin, or maximum status field rows to show on unpin, or maximum status field rows to show on edit, or maximum status field rows to show on delete, or maximum status field rows to show on rollback, or maximum retrieval results to show on explain (default 5). Must be a positive integer up to 1000. Combines with --offset on list, log, expire, config, promote, demote, pin, unpin, apply-policies, edit, delete, rollback, and explain. |
--offset <n> | Skip the first N memories on list, audit events on log, expirable memories on expire, configuration setting rows on config, status field rows on promote, demote, pin, unpin, edit, delete, or rollback, tier changes on apply-policies, or retrieval results on explain, before applying --limit. Must be a non-negative integer up to 1000. |
-s, --snapshot <id> | Snapshot to inspect or modify (default: latest), including the archive used by explain. Must be a single non-empty snapshot id. |
--json | Emit list, explain, log, config, promote, demote, pin, unpin, apply-policies, edit, delete, rollback, and expire results as JSON. A successful memory list response includes found: true, the resolved snapshot ID, empty, emptyReason, total, shown, remaining matching entries after the current page, offset, limit, pageSize, tier/freshness/pinned counts, active filters, hasPrevious/previousOffset, and hasMore/nextOffset. The byFreshness and shownByFreshness objects count active, stale, and needs_confirmation entries across the filtered collection and current page. Table output also adds a freshness summary with active, stale, and confirmation-needed totals; paginated tables add a labeled page freshness summary for the visible rows. An empty page also includes suggestedOffset, the nearest page offset containing entries; it is null when the collection is empty or the page has entries. empty: true means the snapshot exists but the current filters/page returned no entries. emptyReason is collection when no memories match the filters, page when the offset is beyond the filtered collection, and null otherwise. pass the returned offset back with --offset to recover from a stale page cursor. Table output adds a compact page summary when pagination hides rows, including next and previous offsets so an interactive user can move through pages in either direction. Each entry includes its id, tier, pin state, source, namespace (a string or null), normalized tags when present, created timestamp, optional updated and last-accessed timestamps, and content. The active tag filter is returned as filters.tags with whitespace removed, empty values omitted, and case-insensitive duplicates collapsed. Omits previous content. Config includes tier limits and policy names. When the snapshot is missing, list emits a missing summary (found, snapshot, total, shown; omits extra fields), config emits a missing summary (found, snapshot, version, defaultTier; omits extra fields), and apply-policies emits a missing summary (found, snapshot, applied, changeCount; omits extra fields). Promote, demote, and apply-policies include from/to tiers. When the memory is missing, promote emits a missing summary (found, id, from, to; omits extra fields) and demote emits a missing summary (found, id, from, to; omits extra fields). Pin and unpin include pinned status. When the memory is missing, pin emits a missing summary (found, id, pinned; omits extra fields) and unpin emits a missing summary (found, id, pinned; omits extra fields). When the memory is missing, log emits a missing summary (found, id, events; omits extra fields). Edit includes edited version. When the memory is missing, edit emits a missing summary (found, id, version; omits extra fields). Delete includes deleted status. When the memory is missing, delete emits a missing summary (found, id, deleted; omits extra fields). Rollback includes rolled-back status. When the memory is missing, rollback emits a missing summary (found, id, rolledBack; omits extra fields). Expire includes expired count and IDs. When the namespace is missing, expire emits a missing summary (found, namespace, applied, expiredCount; omits extra fields). Explain success envelopes include found: true and an empty boolean, and include retrieval scores, summaries, each result's pinned state, effective tier, importance, and criticality, active filters (including tier, pinned/unpinned, importance, criticality, and creation-date scope), emptyReason (collection, page, or null when results are shown), and a pagination object with offset, limit, total, remaining, pageSize, hasPrevious/previousOffset, hasMore, and nextOffset. When no memories match, explain emits a missing summary (found: false, query, shown: 0, emptyReason: collection, and results: null); when an offset returns an empty page, it emits a normal paginated result (found: true, shown: 0, empty: true, emptyReason: page, and results: []). Human-readable explain output includes previous-page guidance when the offset is non-zero. Skips table output. Useful for scripting. |
memory explain --json | Each returned result includes a stable 1-based rank across pages. When a paged explain request returns no rows, suggestedOffset identifies the nearest page containing matches; it is null when the collection is empty or the page has entries. |
--dry-run | Preview apply-policies and expire without writing |
-t, --to <tier> | Target tier on promote (default L1) and demote (default L3). Promote must be one of: L1, L2; demote target (Must be one of: L2, L3). |
-r, --reason <reason> | Required reason on delete; optional on edit. Must be a non-empty reason. |
-c, --content <content> | New content on edit. Must be non-empty memory content. |
-t, --tags <tags> | Comma-separated tags on explain (filter) and edit (replace). Must be one or more non-empty memory tags (comma-separated). |
-i, --importance <n> | New importance score (0-1, inclusive) on edit. Must be a number between 0 and 1. |
--actor <id> | Actor ID for the audit trail on edit, delete, and rollback (default cli-user). Must be a single non-empty actor id. |
-v, --version <n> | Required version to restore on rollback. Must be a positive integer up to 1000. |
# List memories in L1
$ savestate memory list --tier L1
# Pinned memories only
$ savestate memory list --pinned --limit 5
$ savestate memory list --unpinned --limit 5
$ savestate memory list --content "preferred editor"
$ savestate memory list --tags work,urgent
$ savestate memory list --until 2026-10-01
$ savestate memory list --since 2026-10-01
$ savestate memory list --min-importance 0.8 --json
$ savestate memory list --max-importance 0.5 --json
$ savestate memory list --offset 10 --limit 5
$ savestate memory list --oldest-first --limit 5
$ savestate memory list --reverse --limit 5
# Promote a memory to faster access
$ savestate memory promote mem-123 --to L1 --json
# Cap status field rows
$ savestate memory promote mem-123 --limit 5
$ savestate memory promote mem-123 --offset 10 --limit 5
# Demote a memory to archival
$ savestate memory demote mem-123 --to L3 --json
# Cap status field rows
$ savestate memory demote mem-123 --limit 5
$ savestate memory demote mem-123 --offset 10 --limit 5
# Pin a memory
$ savestate memory pin mem-123 --json
# Cap pin status field rows
$ savestate memory pin mem-123 --limit 5
$ savestate memory pin mem-123 --offset 10 --limit 5
# Unpin a memory
$ savestate memory unpin mem-123 --json
# Cap unpin status field rows
$ savestate memory unpin mem-123 --limit 5
$ savestate memory unpin mem-123 --offset 10 --limit 5
# Preview policy demotions as JSON
$ savestate memory apply-policies --json --dry-run
# Cap policy change rows
$ savestate memory apply-policies --limit 5
$ savestate memory apply-policies --offset 10 --limit 5
# Edit content and importance
$ savestate memory edit mem-123 --content "Updated preference" --importance 0.9 --reason "correction" --json
# Cap status field rows
$ savestate memory edit mem-123 --content "Updated preference" --limit 5
$ savestate memory edit mem-123 --content "Updated preference" --offset 10 --limit 5
# Soft-delete a memory
$ savestate memory delete mem-123 --reason "stale" --json
# Cap delete status field rows
$ savestate memory delete mem-123 --reason "stale" --limit 5
# Skip delete status field rows before applying the cap
$ savestate memory delete mem-123 --reason "stale" --offset 1 --limit 5
# Rollback to a previous version
$ savestate memory rollback mem-123 --version 2 --json
# Cap rollback status field rows
$ savestate memory rollback mem-123 --version 2 --limit 5
$ savestate memory rollback mem-123 --version 2 --offset 1 --limit 5
# Preview TTL expiry without applying
$ savestate memory expire --namespace org:app:agent --json --dry-run
$ savestate memory expire --namespace org:app:agent --limit 5
$ savestate memory expire --namespace org:app:agent --offset 10 --limit 5
# Audit history for one memory
$ savestate memory log mem-123 --json
$ savestate memory log mem-123 --limit 5
$ savestate memory log mem-123 --offset 10 --limit 5
# Scripting
$ savestate memory list --json
$ savestate memory list --snapshot ss-missing --json
$ savestate memory config --json
$ savestate memory config --snapshot ss-missing --json
$ savestate memory config --limit 5
$ savestate memory config --offset 10 --limit 5
$ savestate memory apply-policies --json
$ savestate memory apply-policies --snapshot ss-missing --json
$ savestate memory edit mem-123 --content "Updated preference" --json
$ savestate memory delete mem-123 --reason "stale" --json
$ savestate memory rollback mem-123 --version 2 --json
$ savestate memory expire --namespace org:app:agent --json
$ savestate memory expire --namespace org:missing --json
$ savestate memory explain "inbox preference" --json
$ savestate memory explain "inbox preference" --tier L1 --json
$ savestate memory explain "inbox preference" --snapshot ss-2026-10-18 --json
$ savestate memory explain "inbox preference" --limit 5
$ savestate memory explain "inbox preference" --offset 10 --limit 5
$ savestate memory explain "inbox preference" --min-importance 0.8 --max-importance 1 --json
$ savestate memory explain "inbox preference" --min-criticality 0.8 --json
$ savestate memory explain "inbox preference" --since 2026-10-01 --until 2026-10-18
savestate slo
Memory freshness SLO monitoring. Subcommands: status, report, and config. Must be a single non-empty subcommand (status, report, or config). status evaluates namespace compliance against freshness, relevance, recall, and cross-session targets, optionally paging and capping violations with --offset and --limit. report prints a period summary (default 7 days), optionally paging and capping namespace rows with --offset and --limit. config shows or updates SLO thresholds, optionally paging and capping configuration setting rows with --offset and --limit. Enable monitoring with savestate slo config --set enabled=true.
$ savestate slo <subcommand> [options]
| Flag | Description |
|---|---|
-n, --namespace <ns> | Namespace (org:app:agent[:user]) for status (default default:default:default). Must be a single non-empty namespace. |
-p, --period <duration> | Report window for report (e.g. 7d, 30d; default 7 days). Must be a duration like 24h, 7d, or 1w up to 365 days. |
--limit <n> | Maximum number of namespace compliance rows to show on report, or status violations, or configuration setting rows on config. Must be a positive integer up to 1000. |
--offset <n> | Skip the first N namespace compliance rows on report, status violations, or configuration setting rows on config before applying --limit. Must be a non-negative integer up to 1000. |
--set <key=value> | Set a config value on config (e.g. enabled=true). Must be a non-empty key=value pair. |
--json | Emit status, report, and config as JSON. When monitoring is disabled, status emits a missing summary (found, enabled, namespace, compliant, violations; omits extra fields) and report emits a missing summary (found, enabled, reportId, totalQueries, namespaces; omits extra fields). Useful for scripting. |
# Check compliance for a namespace
$ savestate slo status --namespace org:app:agent
# Period report as JSON
$ savestate slo report --period 7d --json
$ savestate slo status --limit 5
$ savestate slo report --limit 5
$ savestate slo config --limit 5
$ savestate slo report --offset 10 --limit 5
# Enable monitoring and raise max age
$ savestate slo config --set enabled=true
$ savestate slo config --set freshness.max_age_hours=720
# Scripting
$ savestate slo status --json
$ savestate slo status --namespace org:missing --json
$ savestate slo report --period 7d --json
$ savestate slo report --json
$ savestate slo config --json
savestate acl
Manage Active Commitment Layer (ACL) commitments that gate high-impact agent actions. Subcommands: propose, verify, gate, and list. Must be a single non-empty subcommand (propose, verify, gate, or list). propose records a commitment with type, criticality, description, and proposer, optionally capped with --limit. verify approves or rejects a proposed commitment, optionally capped with --limit. gate checks whether an action type is allowed, optionally capped with --limit. list prints commitments, optionally paged with --offset and capped with --limit.
$ savestate acl <subcommand> [options]
| Flag | Description |
|---|---|
<subcommand> | ACL action. Must be a single non-empty subcommand (propose, verify, gate, or list). |
-t, --type <type> | Commitment type for propose: customer_promise, ticket_status_change, escalation_closure, or account_tool_write. Must be one of: customer_promise, ticket_status_change, escalation_closure, account_tool_write. |
-c, --criticality <level> | Criticality for propose: c1, c2, or c3. Must be one of: c1, c2, c3. |
-d, --description <text> | Description of the commitment for propose. Must be a non-empty commitment description. |
-p, --proposer <id> | ID of the proposing agent for propose. Must be a single non-empty proposer id. |
-e, --expires-in <minutes> | Minutes until expiration on propose (positive integer up to 10080) |
-i, --id <id> | Commitment ID for verify. Must be a single non-empty commitment id. |
-v, --verifier <id> | ID of the verifier for verify. Must be a single non-empty verifier id. |
--approve | Approve the commitment on verify (default is reject) |
-a, --action <type> | Action type to check on gate. Must be one of: customer_promise, ticket_status_change, escalation_closure, account_tool_write. |
--limit <n> | Maximum number of commitments to show on list, or status field rows on verify, gate, or propose. Must be a positive integer up to 1000. |
--offset <n> | Skip the first N commitments on list before applying --limit. Must be a non-negative integer up to 1000. |
--json | Emit commitments or gate status as JSON. Omits the audit trail. When no commitment exists, verify emits a missing summary (found, id, state, verifier; omits extra fields). Useful for scripting. |
# Propose a customer promise
$ savestate acl propose --type customer_promise --criticality c3 --description "Refund within 24h" --proposer agent-1
$ savestate acl propose --type customer_promise --criticality c3 --description "Refund within 24h" --proposer agent-1 --limit 5
# Approve a proposed commitment
$ savestate acl verify --id <commitment-id> --verifier reviewer-1 --approve
$ savestate acl verify --id <commitment-id> --verifier reviewer-1 --approve --limit 5
# Check whether an action is allowed
$ savestate acl gate --action customer_promise
$ savestate acl gate --action customer_promise --limit 5
# List all commitments
$ savestate acl list
# Cap the commitment list
$ savestate acl list --limit 5
# Page through the commitment list
$ savestate acl list --offset 10 --limit 5
# Scripting
$ savestate acl list --json
$ savestate acl verify --id cmt-missing --verifier reviewer-1 --json
savestate identity
Manage the workspace agent identity document at .savestate/identity.json. Subcommands: show, init, set, and schema. Must be a single non-empty subcommand (show, init, set, or schema). show prints the current identity, optionally paged with --offset and capped with --limit. init <name> creates one if missing, optionally paged with --offset and capped with --limit. set <field> <value> updates a core field or metadata.<key>, optionally paged with --offset and capped with --limit. schema prints the JSON schema, optionally paged with --offset and capped with --limit. Requires savestate init.
$ savestate identity <subcommand> [args...] [options]
| Flag | Description |
|---|---|
<name> | Agent name for init. Must be a single non-empty identity name. |
<field> | Field name for set. Must be a single non-empty identity field (core field or metadata.<key>). |
<value> | Field value for set. Must be a non-empty identity value. |
--limit <n> | Maximum number of identity tools to show on show, identity schema properties to show on schema, or status field rows on init, or field rows to show on set. Must be a positive integer up to 1000. |
--offset <n> | Skip the first N identity tools on show, status field rows on init, field rows on set, or schema properties on schema. Must be a non-negative integer up to 1000. Applied before --limit. |
--json | Emit an init summary as JSON on init (created, alreadyExists, path, name, version; omits tool config). When SaveState is not initialized, init emits a missing summary (found, created, alreadyExists, path, name, version; omits extra fields). Emit a set summary as JSON on set (updated, field, name, version; omits tool config). When SaveState is not initialized, set emits a missing summary (found, updated, field, name, version; omits extra fields). Emit identity as JSON on show (omits tool config). When SaveState is not initialized, show emits a missing summary (found, name, version, schemaVersion; omits extra fields). When no identity exists, show emits a missing summary (found, name, version, schemaVersion; omits extra fields). When no identity exists, set emits a missing summary (found, updated, field, name, version; omits extra fields). Emit a schema summary as JSON on schema (id, title, type, required fields, property names/types, additionalProperties; omits descriptions and nested tool config). When SaveState is not initialized, schema emits a missing summary (found, id, title, type; omits extra fields). Skips the spinner. Useful for scripting. |
# Create a local identity
$ savestate identity init MyAgent
$ savestate identity init MyAgent --limit 5
$ savestate identity init MyAgent --offset 1 --limit 2
# Show the current identity
$ savestate identity show
$ savestate identity show --limit 5
$ savestate identity show --offset 5 --limit 5
# Update a core field or nested metadata key
$ savestate identity set tone professional
$ savestate identity set goals '["Help users"]'
$ savestate identity set metadata.customKey "custom value"
$ savestate identity set tone professional --limit 5
$ savestate identity set tone professional --offset 1 --limit 2
# Print the identity JSON schema
$ savestate identity schema --json
# Cap schema properties
$ savestate identity schema --limit 5
$ savestate identity schema --offset 5 --limit 5
# Scripting
$ savestate identity show --json
$ savestate identity set tone professional --json
$ savestate identity schema --json
$ savestate identity init MyAgent --json
savestate integrity
Memory Integrity Grid: detect and contain memory poisoning with honeyfact seeding, tripwire monitoring, and quarantine. Subcommands: status, seed, rotate, incidents, incident, quarantine, release, config, test, and clear. Must be a single non-empty subcommand (status, seed, rotate, incidents, incident, quarantine, release, config, test, or clear). incidents, config, status, quarantine, release, incident, test, seed, rotate, and clear can cap output with --limit; incidents supports bounded --offset pagination and reports next/previous offsets in human-readable output, while test can skip event rows with --offset before applying --limit. It defaults offset-only pages to 20 incidents. Requires savestate init.
$ savestate integrity <subcommand> [args...] [options]
| Flag | Description |
|---|---|
--json | Emit a rotation summary as JSON on rotate (rotated, valid, created/retired counts, tenant, TTL, rotatedAt; omits honeyfact contents). When SaveState is not initialized, rotate emits a missing summary (found, rotated, valid, createdCount, retiredCount; omits extra fields). Emit a seed summary as JSON on seed (count, tenant, TTL, seededAt; omits honeyfact contents). When SaveState is not initialized, seed emits a missing summary (found, count; omits extra fields). Emit a quarantine summary as JSON on quarantine (success, approval, target, action, reason, eventId, error; omits event metadata). When SaveState is not initialized, quarantine emits a missing summary (found, success, eventId; omits extra fields). Emit a release summary as JSON on release (success, approval, target, action, reason, eventId, error; omits event metadata). When no quarantine entry exists, release emits a missing summary (found, targetId, success, eventId; omits extra fields). Emit a config summary as JSON on config (enabled, honeyfact count/TTL, tripwire threshold/fuzzy, containment policy/auto-escalate; omits nested objects). When SaveState is not initialized, config emits a missing summary (found, enabled; omits extra fields). Emit a clear summary as JSON on clear (cleared count, tenant; omits honeyfact contents). When SaveState is not initialized, clear emits a missing summary (found, cleared; omits extra fields). Emit a test summary as JSON on test (triggered, duration, event count/ids/confidence/source, incident id/severity; omits matched content). When SaveState is not initialized, test emits a missing summary (found, triggered, eventCount, incidentId; omits extra fields). Emit incident records as JSON on incidents and incident (omits event match context). When --offset or --limit is supplied to incidents, the response is an object with found, incidents, and pagination (offset, limit, total, shown, emptyReason, suggestedOffset, hasMore, nextOffset, hasPrevious, and previousOffset); without pagination flags it remains the legacy incident array. When SaveState is not initialized, incidents emits a missing summary (found, total, shown; omits extra fields). When SaveState is not initialized, incident emits a missing summary (found, id, status, eventCount; omits extra fields). When no incident exists, incident emits a missing summary (found, id, status, eventCount; omits extra fields). Status output is a stable summary (enabled, policy, honeyfact counts, incident counts, and containment counts). When SaveState is not initialized, status emits a missing summary (found, enabled, policy, honeyfacts, incidents; omits extra fields). Omits extra fields. Skips the banner. Useful for scripting. |
--tenant <id> | Tenant ID (default: default). Must be a single non-empty tenant id. |
--count <n> | Number of honeyfacts to seed. Must be a positive integer up to 1000. |
honeyfact.ttl_days | Honeyfact TTL in days on config. Must be a positive integer up to 365. |
honeyfact.count | Honeyfact seed count on config. Must be a positive integer up to 1000. |
tripwire.threshold | Tripwire fuzzy match threshold on config. Must be a number between 0 and 1. |
--status <status> | Filter incidents by status. Must be one of: open, investigating, contained, resolved, false_positive. |
--limit <n> | Maximum number of incidents to show on incidents, configuration setting rows on config, or honeyfact, incident, and containment metric rows on status, or quarantine status field rows on quarantine, or release status field rows on release, or event rows on incident, or event rows on test, or category rows on seed, or rotate status field rows on rotate, or clear status field rows on clear. Must be a positive integer up to 1000. Combines with --status on incidents. |
--offset <n> | Skip the first N incidents on incidents, or test event rows on test, before applying --limit. Must be a non-negative integer up to 1000. Incident pages default to 20 rows when --limit is omitted. Combines with --status on incidents. |
<id> | Incident ID for incident. Must be a single non-empty incident id. |
--policy <policy> | Containment policy. Must be one of: observe, approve, auto. |
<key>=<value> | Setting for config. Must be a non-empty key=value pair. |
enabled | Enable the Memory Integrity Grid on config. Must be true or false. |
tripwire.fuzzy_enabled | Tripwire fuzzy matching on config. Must be true or false. |
containment.auto_escalate | Auto-escalate critical incidents on config. Must be true or false. |
--status <status> | Filter incidents by status. Must be one of: open, investigating, contained, resolved, false_positive. |
--force | Required on clear |
<memory_id|agent_id> | Memory or agent ID for quarantine and release. Must be a single non-empty memory or agent id. |
<text> | Text to check on test. Must be a non-empty text to check. |
--reason <text> | Reason for quarantine or release. Must be a non-empty reason. |
--user <id> | Actor for quarantine and release (default cli). Must be a single non-empty user id (no commas). |
When SaveState is not initialized, release emits a missing summary (found, targetId, success, eventId; omits extra fields). | |
# Show honeyfact, incident, and containment status
$ savestate integrity status
$ savestate integrity status --limit 5
# Plant honeyfact memories
$ savestate integrity seed --count 10
# Cap seed category rows
$ savestate integrity seed --count 10 --limit 5
# List detected incidents
$ savestate integrity incidents
$ savestate integrity incidents --limit 5
$ savestate integrity incidents --offset 5 --limit 5
# Cap configuration setting rows
$ savestate integrity config --limit 5
# Cap release status field rows
$ savestate integrity release mem-123 --limit 5
# Cap incident event rows
$ savestate integrity incident inc-123 --limit 5
# Cap test event rows
$ savestate integrity test "canary text" --limit 5
$ savestate integrity test "canary text" --offset 5 --limit 5
# Cap rotate status field rows
$ savestate integrity rotate --limit 5
# Cap clear status field rows
$ savestate integrity clear --force --limit 5
# Scripting
$ savestate integrity status --json
$ savestate integrity rotate --json
$ savestate integrity seed --count 10 --json
$ savestate integrity quarantine mem-123 --json
$ savestate integrity release mem-123 --json
$ savestate integrity clear --force --json
$ savestate integrity test "canary text" --json
$ savestate integrity incidents --json
$ savestate integrity incident inc-123 --json
$ savestate integrity config --json
# Quarantine a memory or agent
$ savestate integrity quarantine mem-123 --limit 5
$ savestate integrity quarantine mem-123 --reason "tripwire hit" --user reviewer-1 --policy observe
savestate trace
Inspect Askable Echoes trace runs: an append-only ledger of tool calls, results, checkpoints, and errors. Subcommands: list, show, and export. Must be a single non-empty subcommand (list, show, or export). list, show, and export can page through runs or events with --offset and cap output with --limit. Human-readable list and show output reports the current page, next/previous offsets, and the nearest valid offset when a page is stale. Requires savestate init. Runs are stored under .savestate/traces.
$ savestate trace <subcommand> [options]
| Flag | Description |
|---|---|
<subcommand> | Trace action. Must be a single non-empty subcommand (list, show, or export). |
--json | Emit run and event summaries as JSON on list and show. When SaveState is not initialized, list emits a missing summary (found, total, shown; omits extra fields and event payloads). When SaveState is not initialized, show emits a missing summary (found, runId, adapter, eventCount; omits extra fields and event payloads). When no run exists, show emits a missing summary (found, runId, adapter, eventCount; omits extra fields and event payloads). Emit an export summary as JSON on export (found, format, run, run/event counts, run ids/adapters/timestamps/tags, and pagination metadata with total/shown/emptyReason/hasMore/nextOffset/hasPrevious/previousOffset/suggestedOffset; emptyReason is collection when no trace runs exist, page when the offset is past the available runs, and null when runs are shown; omits event payloads and on-disk file paths). When SaveState is not initialized, export emits a missing summary (found, format, run, runCount, eventCount, pagination metadata; omits extra fields, run lists, event payloads, and on-disk file paths). When --run names a missing run, export emits a missing summary (found, format, run, runCount, eventCount, pagination metadata; omits extra fields, run lists, event payloads, and on-disk file paths). Useful for scripting. |
--json-summary | Emit an opt-in JSON envelope for list or show with runs/events plus pagination metadata (offset, limit, total, shown, emptyReason, hasMore, nextOffset, hasPrevious, previousOffset, and suggestedOffset). On export, it aliases the export summary produced by --json. This preserves the array shape of --json for existing list/show scripts, and missing or uninitialized results retain the same pagination envelope with an empty collection. |
<run_id> | Run ID for show. Must be a single non-empty run id. |
--format <format> | Export format on export (only jsonl is supported). Must be one of: jsonl. |
--run <id> | Export only a specific run ID (default: all runs). Must be a single non-empty run id. |
--limit <n> | Maximum number of trace runs to show on list, events to show on show, or runs to export on export. Must be a positive integer up to 1000. Human-readable paged exports keep JSONL on stdout and print next/previous page guidance to stderr. |
--offset <n> | Skip the first N trace runs on list or export, or events on show, before applying --limit. Must be a non-negative integer up to 1000. |
# List trace runs
$ savestate trace list
# Cap the trace run list
$ savestate trace list --limit 5
# Page through the trace run list
$ savestate trace list --offset 5 --limit 5
# Get machine-readable trace run page navigation
$ savestate trace list --json-summary --offset 5 --limit 5
# Show events for one run
$ savestate trace show run-123 --json
# Cap events for one run
$ savestate trace show run-123 --limit 5
# Page through events for one run
$ savestate trace show run-123 --offset 5 --limit 5
# Get machine-readable event page navigation
$ savestate trace show run-123 --json-summary --offset 5 --limit 5
# Export every run as JSONL
$ savestate trace export --format jsonl
# Cap the export run list
$ savestate trace export --limit 5
# Page through the export run list
$ savestate trace export --offset 5 --limit 5
# Export one run
$ savestate trace export --run run-123
# Scripting
$ savestate trace list --json
$ savestate trace list --json-summary --offset 5 --limit 5
$ savestate trace export --json
$ savestate trace export --json-summary
$ savestate trace export --run run-123 --json
savestate container
Manage encrypted agent state containers. Subcommands: export and import. Same encryption, path selection, and dry-run behavior as the top-level savestate export / savestate import commands, with required --out / --in flags instead of optional --output or a positional file.
$ savestate container <subcommand> [options]
| Flag | Description |
|---|---|
-a, --agent <id> | Required on export. Agent ID to pack. Must be a single non-empty agent id. |
-o, --out <file> | Required on export. Output .savestate path. Must be a single non-empty path. |
-i, --in <file> | Required on import. Input .savestate path. Must be a single non-empty path. |
--dry-run | Preview without writing or restoring |
--force | Overwrite an existing export file or import target file |
--include <paths> | Only pack or restore named state paths. Must be one or more of: personality, memory, tools, preferences, conversation_history. |
--include-conversation-history | Include conversation history when packing with boolean include flags. Other --include-* flags omit conversation history unless this is also set. |
--exclude <paths> | Skip named state paths. Must be one or more of: personality, memory, tools, preferences, conversation_history. |
-p, --passphrase <pass> | Passphrase, or SAVESTATE_PASSPHRASE / prompt. An empty or whitespace-only value is rejected before encrypting or decrypting. |
-k, --keyfile <path> | Keyfile instead of a passphrase. Must be a single non-empty path. |
--description <text> | Optional manifest description on export. Must be a non-empty description. |
--target <dir> | Write restored agent state to this directory on import |
--merge | Merge with existing state on import (default: replace) |
--replace | Replace existing state on import |
--limit <n> | Maximum number of packed components to show on export or import. Must be a positive integer up to 1000. Combines with --offset. |
--offset <n> | Skip the first N packed components on export or import before applying --limit. Must be a non-negative integer up to 1000. |
--json | Emit export or import results as JSON. Encrypts on export, decrypts on import. Skips progress output. Useful for scripting. |
# Preview an export without writing
$ savestate container export -a my-agent -o agent.savestate --dry-run
# Cap packed components shown
$ savestate container export -a my-agent -o agent.savestate --limit 5
# Skip then cap packed components shown
$ savestate container export -a my-agent -o agent.savestate --offset 10 --limit 5
# Restore into a directory, replacing an existing target file
$ savestate container import --in agent.savestate --target ./restored --force
# Cap packed components shown
$ savestate container import --in agent.savestate --limit 5
# Skip then cap packed components shown
$ savestate container import --in agent.savestate --offset 10 --limit 5
# Scripting
$ savestate container export -a my-agent -o agent.savestate --json --dry-run
Subscribe
Pro is $9/month. Encrypted portable memory you can snapshot, restore, search, and migrate from the CLI. Card today. No waitlist.
Subscribe to Pro — $9/mo Team is $29/month
After you pay, your API key is emailed. Then savestate login. Card today — no waitlist.