"""muse plumbing read-snapshot — emit full snapshot metadata as JSON. Reads a snapshot record by its SHA-256 ID and emits the complete JSON representation including the file manifest. Output:: { "snapshot_id": "", "created_at": "2026-03-18T12:00:00+00:00", "file_count": 3, "manifest": { "tracks/drums.mid": "", "tracks/bass.mid": "", "tracks/piano.mid": "" } } Plumbing contract ----------------- - Exit 0: snapshot found and printed. - Exit 1: snapshot not found or invalid snapshot ID format. Agent use --------- Skip the manifest when you only need metadata:: muse plumbing read-snapshot --no-manifest # → {"snapshot_id": "...", "created_at": "...", "file_count": 3} Filter to a path prefix to avoid pulling the full manifest:: muse plumbing read-snapshot --path-prefix src/ """ from __future__ import annotations import argparse import json import logging import sys from typing import TypedDict from muse.core.errors import ExitCode from muse.core.repo import require_repo from muse.core.store import read_snapshot from muse.core.validation import validate_object_id from muse.core._types import Manifest logger = logging.getLogger(__name__) _FORMAT_CHOICES = ("json", "text") class _SnapshotOutput(TypedDict, total=False): snapshot_id: str created_at: str file_count: int manifest: Manifest def register(subparsers: "argparse._SubParsersAction[argparse.ArgumentParser]") -> None: """Register the read-snapshot subcommand.""" parser = subparsers.add_parser( "read-snapshot", help="Emit full snapshot metadata and manifest as JSON.", description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, ) parser.add_argument( "snapshot_id", help="SHA-256 snapshot ID (64 hex chars).", ) parser.add_argument( "--no-manifest", action="store_true", dest="no_manifest", help=( "Omit the file manifest from JSON output. " "Returns only snapshot_id, created_at, and file_count — " "ideal for agents doing metadata-only queries." ), ) parser.add_argument( "--path-prefix", "-p", default=None, dest="path_prefix", metavar="PREFIX", help="Filter manifest to paths starting with PREFIX.", ) parser.add_argument( "--format", "-f", dest="fmt", default="json", metavar="FORMAT", help="Output format: json (default) or text.", ) parser.add_argument( "--json", action="store_const", const="json", dest="fmt", help="Shorthand for --format json.", ) parser.set_defaults(func=run) def run(args: argparse.Namespace) -> None: """Emit full snapshot metadata as JSON (default) or a compact text summary. A snapshot holds the complete file manifest (path → object_id mapping) for a point in time. Every commit references exactly one snapshot. Use ``muse plumbing ls-files --commit `` if you want to look up a snapshot from a commit ID rather than the snapshot ID directly. Use ``--no-manifest`` for lightweight metadata queries. Use ``--path-prefix`` to scope the manifest to a subtree. Text format (``--format text``):: files """ fmt: str = args.fmt snapshot_id: str = args.snapshot_id no_manifest: bool = args.no_manifest path_prefix: str | None = args.path_prefix if fmt not in _FORMAT_CHOICES: print( json.dumps({"error": f"Unknown format {fmt!r}. Valid: {', '.join(_FORMAT_CHOICES)}"}), file=sys.stderr, ) raise SystemExit(ExitCode.USER_ERROR) if no_manifest and fmt == "text": print( json.dumps({"error": "--no-manifest is only valid with --format json"}), file=sys.stderr, ) raise SystemExit(ExitCode.USER_ERROR) if path_prefix is not None and fmt == "text": print( json.dumps({"error": "--path-prefix is only valid with --format json"}), file=sys.stderr, ) raise SystemExit(ExitCode.USER_ERROR) try: validate_object_id(snapshot_id) except ValueError as exc: print(json.dumps({"error": f"Invalid snapshot ID: {exc}"}), file=sys.stderr) raise SystemExit(ExitCode.USER_ERROR) root = require_repo() record = read_snapshot(root, snapshot_id) if record is None: print(json.dumps({"error": f"Snapshot not found: {snapshot_id}"}), file=sys.stderr) raise SystemExit(ExitCode.USER_ERROR) if fmt == "text": print( f"{record.snapshot_id[:12]} {len(record.manifest)} files " f"{record.created_at.isoformat()}" ) return manifest = record.manifest if path_prefix is not None: manifest = {p: oid for p, oid in manifest.items() if p.startswith(path_prefix)} output: _SnapshotOutput = { "snapshot_id": record.snapshot_id, "created_at": record.created_at.isoformat(), "file_count": len(manifest), } if not no_manifest: output["manifest"] = manifest print(json.dumps(output, indent=2))