#!/usr/bin/env bash set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "$ROOT" ts="$(date -u +"%Y-%m-%dT%H:%M:%SZ")" safe_ts="$(date -u +"%Y-%m-%dT%H-%M-%SZ")" note="${1:-}" mkdir -p out/checkpoints echo "== running ci ==" >&2 ci_json="$(./scripts/ci.sh)" echo "$ci_json" > "out/checkpoints/ci_${safe_ts}.json" echo "== writing session state ==" >&2 ./scripts/state.sh >/dev/null git_branch="(unknown)" git_head_short="" dirty_count="0" modified_count="0" untracked_count="0" diffstat="" diffstat_lines="0" diffstat_note="" if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then git_branch="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "(unknown)")" git_head_short="$(git rev-parse --short HEAD 2>/dev/null || echo "")" porcelain="$(git status --porcelain=v1 2>/dev/null || true)" if [ -n "${porcelain}" ]; then dirty_count="$(printf "%s\n" "${porcelain}" | wc -l | awk '{print $1}')" untracked_count="$(printf "%s\n" "${porcelain}" | grep -c '^??' || true)" modified_count="$(printf "%s\n" "${porcelain}" | grep -vc '^??' || true)" fi diffstat="$(git diff --stat 2>/dev/null || true)" if [ -n "${diffstat}" ]; then diffstat_lines="$(printf "%s\n" "${diffstat}" | wc -l | awk '{print $1}')" if [ "${diffstat_lines}" -gt 200 ]; then diffstat="$(printf "%s\n" "${diffstat}" | head -n 200)" diffstat_note="(diffstat truncated to first 200 lines)" fi fi fi tar_path="out/checkpoints/iftypeset_checkpoint_${safe_ts}.tar.gz" details_path="out/checkpoints/checkpoint_${safe_ts}.md" echo "== creating snapshot ${tar_path} ==" >&2 snapshot_paths=(.forgejo .gitignore README.md STATUS.md app docs fixtures forgejo pyproject.toml requirements.txt scripts spec src tests tools) if [ -f AGENTS.md ]; then snapshot_paths+=(AGENTS.md) fi tar \ --exclude=".git" \ --exclude=".venv" \ --exclude="out" \ -czf "$tar_path" \ "${snapshot_paths[@]}" sha="$(sha256sum "$tar_path" | awk '{print $1}')" cat > "${details_path}" < docs/CHECKPOINTS.md <<'EOF' # Checkpoints Durable restore points for this repo (useful when chat context resets). How to create a checkpoint: - `./scripts/checkpoint.sh "short note about what changed"` Each entry records the snapshot tarball path + sha256 and the CI JSON for that moment. EOF fi cat >> docs/CHECKPOINTS.md <&2