Production service containers for rtw.run
readme.nix
{ pkgs }:

pkgs.writeShellApplication {
  name = "readme";
  runtimeInputs = [ pkgs.atproto-goat pkgs.jq ];
  text = ''
    # Usage: readme <service> [file] [-y]
    #
    # Publishes docs/registry/<service>.md (or [file]) as the README shown on
    # the repo's atcr.io page: https://atcr.io/r/rtw.run/<service>
    #
    # atcr.io stores repo page content as an io.atcr.repo.page record in the
    # owner's PDS (rkey = repository name), synced to the appview via
    # Jetstream. The web UI is just one writer of that record — this script
    # writes it directly via goat. userEdited:true prevents push-time
    # auto-population from manifest annotations overwriting the content, and
    # updates preserve any avatar previously set via the UI.
    #
    # Dry-run by default (prints the record JSON); pass -y to write. Writing
    # requires a goat session, one-time:
    #   goat account login -u rtw.run -p '<ATProto app password>'

    account="''${RTW_ACCOUNT:-rtw.run}"
    repo_root="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"

    svc=""; file=""; yes=0
    for a in "$@"; do
      case "$a" in
        -y|--yes) yes=1 ;;
        *) if [ -z "$svc" ]; then svc="$a"
           elif [ -z "$file" ]; then file="$a"
           else echo "usage: readme <service> [file] [-y]" >&2; exit 1
           fi ;;
      esac
    done
    if [ -z "$svc" ]; then echo "usage: readme <service> [file] [-y]" >&2; exit 1; fi
    file="''${file:-$repo_root/docs/registry/$svc.md}"
    if [ ! -f "$file" ]; then
      echo "[readme] ERROR: file not found: $file" >&2
      exit 1
    fi

    # Create or update? Preserve createdAt and avatar from an existing record.
    now="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
    created="$now"
    avatar=null
    op=create
    if existing="$(goat get "at://$account/io.atcr.repo.page/$svc" 2>/dev/null)"; then
      op=update
      created="$(printf '%s' "$existing" | jq -r '.createdAt // empty')"
      created="''${created:-$now}"
      avatar="$(printf '%s' "$existing" | jq -c '.avatar // null')"
    fi

    record="$(jq -n \
      --arg repo "$svc" \
      --rawfile desc "$file" \
      --arg created "$created" \
      --arg updated "$now" \
      --argjson avatar "$avatar" \
      '{ "$type": "io.atcr.repo.page",
         repository: $repo,
         description: $desc,
         userEdited: true,
         createdAt: $created,
         updatedAt: $updated }
       + (if $avatar != null then {avatar: $avatar} else {} end)')"

    if [ "$yes" != 1 ]; then
      echo "[readme] dry-run — would $op io.atcr.repo.page/$svc from $file:"
      printf '%s\n' "$record"
      echo "[readme] re-run with -y to write"
      exit 0
    fi

    # --no-validate: the PDS doesn't know the io.atcr.repo.page lexicon and
    # rejects validated writes with "Unknown lexicon type".
    tmp="$(mktemp)"
    trap 'rm -f "$tmp"' EXIT
    printf '%s\n' "$record" > "$tmp"
    goat record "$op" -n -r "$svc" "$tmp"
    echo "[readme] done ($op) — live at https://atcr.io/r/$account/$svc"
  '';
}