agent-first-data 0.24.0

A naming convention that lets AI agents understand your data without being told what it means, plus a CLI and library for reading and safely editing structured JSON, TOML, YAML, dotenv, and INI documents.
Documentation
#!/usr/bin/env python3
"""Sync or validate offline AFDATA assets bundled by release packages."""

from __future__ import annotations

import argparse
import shutil
import sys
from pathlib import Path


ROOT = Path(__file__).resolve().parents[1]

# Keep exact machine-readable contracts byte-identical in every language
# package and in the installed skill. Narrative skill references stay focused
# and are maintained separately.
CANONICAL_FILES = (
    Path("spec/registry.json"),
    Path("spec/protocol-v1.schema.json"),
    Path("spec/cli-help-v1.schema.json"),
)

PACKAGE_ASSET_ROOTS = (
    Path("go/assets"),
    Path("python/agent_first_data/assets"),
    Path("typescript/assets"),
    Path("skills/agent-first-data/references"),
)


def package_relative_path(canonical: Path) -> Path:
    if canonical.parts[0] == "spec":
        return Path(*canonical.parts[1:])
    return canonical


def sync(check: bool) -> list[str]:
    failures: list[str] = []
    for asset_root in PACKAGE_ASSET_ROOTS:
        for canonical in CANONICAL_FILES:
            source = ROOT / canonical
            target = ROOT / asset_root / package_relative_path(canonical)
            if check:
                if not target.exists():
                    failures.append(f"missing {target.relative_to(ROOT)}")
                    continue
                if source.read_bytes() != target.read_bytes():
                    failures.append(
                        f"stale {target.relative_to(ROOT)}; run scripts/sync_offline_assets.py"
                    )
                continue
            target.parent.mkdir(parents=True, exist_ok=True)
            shutil.copyfile(source, target)
    return failures


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("--check", action="store_true", help="validate without writing")
    args = parser.parse_args()
    failures = sync(args.check)
    if failures:
        for failure in failures:
            print(failure, file=sys.stderr)
        return 1
    return 0


if __name__ == "__main__":
    raise SystemExit(main())