Auto-Memory Skill Permanent decentralized memory on the Autonomys Network with linked-list memory chains for agent resurrection. Works with agents powered by Claude, GPT, Gemini, and any LLM that supports OpenClaw skills. What This Skill Does 1. Upload files to Auto Drive and get back a CID (Content Identifier) — a permanent, immutable address on the Autonomys distributed storage network. 2. Download files from Auto Drive using a CID — uses the authenticated API if a key is set, otherwise falls back to the public gateway. 3. Save memories as a chain — each memory entry is a JSON experience wi…

\n\n# Return 0 if the argument looks like a valid Autonomys CID, 1 otherwise.\n# Usage: am_valid_cid \"$CID\"\nam_valid_cid() { [[ \"${1:-}\" =~ $AM_CID_RE ]]; }\n\n# -- Functions ----------------------------------------------------------------\n\n# Verify an API key against the Auto Drive accounts endpoint.\n# On success, sets AM_VERIFY_BODY with the JSON response.\n# On failure, prints an error to stderr and returns 1.\n# Usage: automemory_verify_key \"$API_KEY\"\nautomemory_verify_key() {\n local key=\"$1\"\n echo \"Verifying API key...\"\n local response http_code body\n response=$(curl -sS -w \"\\n%{http_code}\" \"$AD_API_BASE/accounts/@me\" \\\n -H \"Authorization: Bearer $key\" \\\n -H \"X-Auth-Provider: apikey\")\n http_code=$(echo \"$response\" | tail -1)\n body=$(echo \"$response\" | sed '$d')\n\n if [[ \"$http_code\" -lt 200 || \"$http_code\" -ge 300 ]]; then\n echo -e \"${RED}Error: API key verification failed (HTTP $http_code).${NC}\" >&2\n echo \"$body\" >&2\n return 1\n fi\n AM_VERIFY_BODY=\"$body\"\n echo -e \"${GREEN}✓ API key verified${NC}\"\n}\n\n# Save an API key to openclaw.json and .env.\n# Creates $AM_OPENCLAW_DIR if it doesn't exist.\n# Temp files are cleaned up on exit via trap.\n# Usage: automemory_save_key \"$API_KEY\"\nautomemory_save_key() {\n local key=\"$1\"\n\n mkdir -p \"$AM_OPENCLAW_DIR\"\n chmod 700 \"$AM_OPENCLAW_DIR\"\n\n # Collect temp files for cleanup\n _AM_TMPS=()\n trap 'rm -f \"${_AM_TMPS[@]}\"' EXIT\n\n # --- openclaw.json ---------------------------------------------------------\n # Write to .apiKey (not .env.AUTO_DRIVE_API_KEY) — the skill declares\n # primaryEnv: AUTO_DRIVE_API_KEY, so the gateway maps .apiKey to that\n # env var automatically. This matches the documented config path:\n # skills.entries.auto-memory.apiKey\n if [[ ! -f \"$AM_CONFIG_FILE\" ]]; then\n local newtmp\n newtmp=$(mktemp)\n _AM_TMPS+=(\"$newtmp\")\n jq -n --arg key \"$key\" \\\n '{\"skills\": {\"entries\": {\"auto-memory\": {\"enabled\": true, \"apiKey\": $key}}}}' \\\n > \"$newtmp\" && mv \"$newtmp\" \"$AM_CONFIG_FILE\"\n chmod 600 \"$AM_CONFIG_FILE\"\n else\n local jsontmp\n jsontmp=$(mktemp)\n _AM_TMPS+=(\"$jsontmp\")\n jq --arg key \"$key\" \\\n '.skills //= {} | .skills.entries //= {} | .skills.entries[\"auto-memory\"] //= {} | .skills.entries[\"auto-memory\"].apiKey = $key | .skills.entries[\"auto-memory\"].enabled = true' \\\n \"$AM_CONFIG_FILE\" > \"$jsontmp\" && mv \"$jsontmp\" \"$AM_CONFIG_FILE\"\n chmod 600 \"$AM_CONFIG_FILE\"\n fi\n echo -e \"${GREEN}✓ Saved to $AM_CONFIG_FILE${NC}\"\n\n # --- .env ------------------------------------------------------------------\n # Remove any existing AUTO_DRIVE_API_KEY lines first to prevent duplicates,\n # then append exactly one entry.\n if [[ -f \"$AM_ENV_FILE\" ]]; then\n local sedtmp\n sedtmp=$(mktemp)\n _AM_TMPS+=(\"$sedtmp\")\n sed '/^AUTO_DRIVE_API_KEY=/d' \"$AM_ENV_FILE\" > \"$sedtmp\" && mv \"$sedtmp\" \"$AM_ENV_FILE\"\n fi\n # Single-quote the value so characters like #, $, and backticks are\n # preserved literally when the .env file is later sourced by bash.\n local safe_key=\"${key//\\'/\\'\\\\\\'\\'}\"\n echo \"AUTO_DRIVE_API_KEY='${safe_key}'\" >> \"$AM_ENV_FILE\"\n chmod 600 \"$AM_ENV_FILE\"\n echo -e \"${GREEN}✓ Saved to $AM_ENV_FILE${NC}\"\n}\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":5239,"content_sha256":"e168c2bdc4a0a82d267e422090084f40152d8221905c08fe090c16709352e7fa"},{"filename":"scripts/automemory-download.sh","content":"#!/usr/bin/env bash\n# Download a file from Auto Drive by CID\n# Usage: automemory-download.sh \u003ccid> [output_path]\n# Tries the public download API first (handles server-side decompression); falls back to\n# the public gateway if the API fails. Auth headers are sent when AUTO_DRIVE_API_KEY is set.\n# If output_path is omitted, outputs to stdout.\n\nset -euo pipefail\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n# shellcheck source=./_lib.sh\nsource \"$SCRIPT_DIR/_lib.sh\"\nam_warn_git_bash\nam_require_tools curl\n\nCID=\"${1:?Usage: automemory-download.sh \u003ccid> [output_path]}\"\nOUTPUT=\"${2:-}\"\n\n# Validate CID format\nif ! am_valid_cid \"$CID\"; then\n echo \"Error: Invalid CID format: $CID\" >&2\n exit 1\nfi\n\n# Validate output path: reject traversal, resolve physically, verify within $HOME.\nif [[ -n \"$OUTPUT\" ]]; then\n if [[ \"$OUTPUT\" == *..* ]]; then\n echo \"Error: Output path must not contain '..': $OUTPUT\" >&2; exit 1\n fi\n OUTPUT_DIR_PART=\"$(dirname \"$OUTPUT\")\"\n OUTPUT_BASE=\"$(basename \"$OUTPUT\")\"\n OUTPUT_RESOLVED=\"$(cd \"$OUTPUT_DIR_PART\" 2>/dev/null && pwd -P)/$OUTPUT_BASE\" || {\n echo \"Error: Could not resolve output path — directory does not exist: $OUTPUT_DIR_PART\" >&2; exit 1\n }\n HOME_REAL=\"$(cd \"$HOME\" && pwd -P)\"\n if [[ \"$OUTPUT_RESOLVED\" != \"$HOME_REAL/\"* ]]; then\n echo \"Error: Output path must be within home directory\" >&2\n exit 1\n fi\n OUTPUT=\"$OUTPUT_RESOLVED\"\nfi\n\nGATEWAY=\"https://gateway.autonomys.xyz\"\n\ndownload_to_file() {\n local URL=\"$1\" DEST=\"$2\"\n shift 2\n RESPONSE=$(curl -sS -w \"\\n%{http_code}\" \"$URL\" \"$@\" -o \"$DEST\")\n echo \"$RESPONSE\" | tail -1\n}\n\n# Send auth headers when API key is available (gives user-level access);\n# the download API is public either way and handles server-side decompression.\nAUTH_ARGS=()\nif [[ -n \"${AUTO_DRIVE_API_KEY:-}\" ]]; then\n AUTH_ARGS=(-H \"Authorization: Bearer $AUTO_DRIVE_API_KEY\" -H \"X-Auth-Provider: apikey\")\nfi\n\nif [[ -z \"$OUTPUT\" ]]; then\n # Output to stdout — try download API first, fall back to gateway\n curl -sS --fail \"$AD_DOWNLOAD_API/downloads/$CID\" ${AUTH_ARGS[@]+\"${AUTH_ARGS[@]}\"} 2>/dev/null \\\n || curl -sS --fail \"$GATEWAY/file/$CID\"\nelse\n # Output to file — check HTTP codes for proper error reporting\n HTTP_CODE=$(download_to_file \"$AD_DOWNLOAD_API/downloads/$CID\" \"$OUTPUT\" ${AUTH_ARGS[@]+\"${AUTH_ARGS[@]}\"})\n if [[ \"$HTTP_CODE\" -ge 200 && \"$HTTP_CODE\" -lt 300 ]]; then\n echo \"Saved to: $OUTPUT\" >&2\n else\n echo \"Error: API download failed (HTTP $HTTP_CODE) — trying gateway\" >&2\n HTTP_CODE=$(download_to_file \"$GATEWAY/file/$CID\" \"$OUTPUT\")\n if [[ \"$HTTP_CODE\" -lt 200 || \"$HTTP_CODE\" -ge 300 ]]; then\n echo \"Error: Gateway download also failed (HTTP $HTTP_CODE)\" >&2\n rm -f \"$OUTPUT\"\n exit 1\n fi\n echo \"Saved to: $OUTPUT (via public gateway — file may be in compressed form)\" >&2\n fi\nfi\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":2858,"content_sha256":"fa173157aa9fc61f8bfc6fef8c0e689aac1ec69afaf5981ae26bd688b5dbb6bd"},{"filename":"scripts/automemory-recall-chain.sh","content":"#!/usr/bin/env bash\n# Traverse the memory chain from a CID, downloading each experience\n# Usage: automemory-recall-chain.sh [cid] [--limit N] [--output-dir DIR] [--restore-state]\n# Output: Each experience as JSON to stdout (newest first), or to files in output dir\n# Env: AUTO_DRIVE_API_KEY (required — memories are stored compressed by default and the authenticated API decompresses server-side)\n\nset -euo pipefail\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n# shellcheck source=./_lib.sh\nsource \"$SCRIPT_DIR/_lib.sh\"\nam_warn_git_bash\nam_require_tools curl jq\nif ! command -v python3 &>/dev/null && ! command -v perl &>/dev/null; then\n echo \"Warning: Neither python3 nor perl found — gateway decompression fallback will not work.\" >&2\n am_install_hint python3\nfi\n\n\n# First arg can be a CID or a flag — if no CID given, try state file\nCID=\"\"\nLIMIT=50\nOUTPUT_DIR=\"\"\nRESTORE_STATE=false\n\n# Parse arguments\nARGS=(\"$@\")\nIDX=0\nwhile [[ $IDX -lt ${#ARGS[@]} ]]; do\n case \"${ARGS[$IDX]}\" in\n --limit)\n # Bounds check: ensure a value was provided after the flag\n # Prevents array out-of-bounds access and crashes with set -u\n if [[ $((IDX + 1)) -ge ${#ARGS[@]} ]]; then\n echo \"Error: --limit requires a value\" >&2\n exit 1\n fi\n LIMIT=\"${ARGS[$((IDX+1))]}\"\n # Validate it's a positive integer to prevent comparison errors in the loop\n # Without this, --limit abc would cause \"integer expression expected\" errors\n if ! [[ \"$LIMIT\" =~ ^[0-9]+$ ]] || [[ \"$LIMIT\" -lt 1 ]]; then\n echo \"Error: --limit must be a positive integer, got: $LIMIT\" >&2\n exit 1\n fi\n IDX=$((IDX + 2))\n ;;\n --output-dir)\n # Bounds check: ensure a value was provided after the flag\n if [[ $((IDX + 1)) -ge ${#ARGS[@]} ]]; then\n echo \"Error: --output-dir requires a value\" >&2\n exit 1\n fi\n OUTPUT_DIR=\"${ARGS[$((IDX+1))]}\"\n IDX=$((IDX + 2))\n ;;\n --restore-state)\n RESTORE_STATE=true\n IDX=$((IDX + 1))\n ;;\n *)\n if [[ -z \"$CID\" ]]; then\n CID=\"${ARGS[$IDX]}\"\n fi\n IDX=$((IDX + 1))\n ;;\n esac\ndone\n\n# If no CID from args, try state file\nif [[ -z \"$CID\" ]]; then\n STATE_FILE=\"${OPENCLAW_WORKSPACE:-$HOME/.openclaw/workspace}/memory/automemory-state.json\"\n if [[ -f \"$STATE_FILE\" ]]; then\n CID=$(jq -r '.lastCid // empty' \"$STATE_FILE\" 2>/dev/null || true)\n fi\n if [[ -z \"$CID\" ]]; then\n echo \"Error: No CID provided and no state file found.\" >&2\n echo \"Usage: automemory-recall-chain.sh \u003ccid> [--limit N] [--output-dir DIR] [--restore-state]\" >&2\n exit 1\n fi\nfi\n\n# Validate CID format\nif ! am_valid_cid \"$CID\"; then\n echo \"Error: Invalid CID format: $CID\" >&2\n exit 1\nfi\n\nif [[ -z \"${AUTO_DRIVE_API_KEY:-}\" ]]; then\n echo \"Error: AUTO_DRIVE_API_KEY not set.\" >&2\n echo \"Get a free key at https://ai3.storage (sign in with Google/GitHub → Developers → Create API Key)\" >&2\n exit 1\nfi\n\nif [[ -n \"$OUTPUT_DIR\" ]]; then\n # Validate output directory: reject traversal, verify within $HOME before\n # and after creation (to catch symlinks that resolve outside $HOME).\n if [[ \"$OUTPUT_DIR\" == *..* ]]; then\n echo \"Error: Output directory must not contain '..': $OUTPUT_DIR\" >&2; exit 1\n fi\n HOME_REAL=\"$(cd \"$HOME\" && pwd -P)\"\n # Pre-creation check: convert to absolute, normalize $HOME to physical path.\n if [[ \"$OUTPUT_DIR\" != /* ]]; then\n OUTPUT_DIR_CHECK=\"$(pwd -P)/$OUTPUT_DIR\"\n else\n OUTPUT_DIR_CHECK=\"$OUTPUT_DIR\"\n fi\n if [[ \"$OUTPUT_DIR_CHECK\" == \"$HOME/\"* ]]; then\n OUTPUT_DIR_CHECK=\"$HOME_REAL/${OUTPUT_DIR_CHECK#\"$HOME/\"}\"\n elif [[ \"$OUTPUT_DIR_CHECK\" == \"$HOME\" ]]; then\n OUTPUT_DIR_CHECK=\"$HOME_REAL\"\n fi\n if [[ \"$OUTPUT_DIR_CHECK\" != \"$HOME_REAL\" && \"$OUTPUT_DIR_CHECK\" != \"$HOME_REAL/\"* ]]; then\n echo \"Error: Output directory must be within home directory\" >&2\n exit 1\n fi\n mkdir -p \"$OUTPUT_DIR_CHECK\"\n OUTPUT_DIR=\"$(cd \"$OUTPUT_DIR_CHECK\" && pwd -P)\"\n # Post-creation check: re-validate physical path to catch internal symlinks.\n if [[ \"$OUTPUT_DIR\" != \"$HOME_REAL\" && \"$OUTPUT_DIR\" != \"$HOME_REAL/\"* ]]; then\n echo \"Error: Output directory resolves outside home directory (symlink?)\" >&2\n exit 1\n fi\nfi\n\necho \"=== MEMORY CHAIN RESURRECTION ===\" >&2\necho \"Starting from: $CID\" >&2\necho \"\" >&2\n\nHEAD_CID=\"$CID\"\nCOUNT=0\nVISITED=\"\"\nwhile [[ -n \"$CID\" && \"$CID\" != \"null\" && $COUNT -lt $LIMIT ]]; do\n # Detect cycles — bail if we've seen this CID before (bash 3.2 compatible)\n if echo \"$VISITED\" | grep -qF \"|$CID|\"; then\n echo \"Warning: Cycle detected at CID $CID — stopping traversal\" >&2\n break\n fi\n VISITED=\"$VISITED|$CID|\"\n\n # Download via authenticated API (handles decompression server-side).\n EXPERIENCE=$(curl -sS --fail \\\n \"$AD_DOWNLOAD_API/downloads/$CID\" \\\n -H \"Authorization: Bearer $AUTO_DRIVE_API_KEY\" \\\n -H \"X-Auth-Provider: apikey\" 2>/dev/null \\\n || true)\n\n # Fall back to public gateway if the API fails.\n # Memories are uploaded with --compress (ZLIB), and the gateway returns raw bytes,\n # so we must decompress client-side. Pipe curl directly into the decompressor to\n # avoid bash variables stripping null bytes from the binary stream.\n if [[ -z \"$EXPERIENCE\" ]] || ! echo \"$EXPERIENCE\" | jq empty 2>/dev/null; then\n GATEWAY_URL=\"https://gateway.autonomys.xyz/file/$CID\"\n # Try as JSON first (uncompressed files are safe in bash variables)\n EXPERIENCE=$(curl -sS --fail \"$GATEWAY_URL\" 2>/dev/null || true)\n if [[ -n \"$EXPERIENCE\" ]] && echo \"$EXPERIENCE\" | jq empty 2>/dev/null; then\n echo \"[$COUNT] Fetched $CID via gateway\" >&2\n else\n # ZLIB compressed — pipe curl directly into decompressor (no intermediate variable)\n EXPERIENCE=\"\"\n if command -v python3 &>/dev/null; then\n EXPERIENCE=$(curl -sS --fail \"$GATEWAY_URL\" 2>/dev/null \\\n | python3 -c \"import sys,zlib;sys.stdout.buffer.write(zlib.decompress(sys.stdin.buffer.read()))\" 2>/dev/null || true)\n fi\n if [[ -z \"$EXPERIENCE\" ]] && command -v perl &>/dev/null; then\n EXPERIENCE=$(curl -sS --fail \"$GATEWAY_URL\" 2>/dev/null \\\n | perl -MCompress::Zlib -e 'undef $/;my $d=uncompress(\u003cSTDIN>);print $d if defined $d' 2>/dev/null || true)\n fi\n if [[ -n \"$EXPERIENCE\" ]]; then\n echo \"[$COUNT] Fetched $CID via gateway (decompressed client-side)\" >&2\n fi\n fi\n fi\n\n if [[ -z \"$EXPERIENCE\" ]]; then\n echo \"Error: Failed to download CID $CID via API and gateway — chain broken at depth $((COUNT + 1))\" >&2\n break\n fi\n\n # Validate JSON\n if ! echo \"$EXPERIENCE\" | jq empty 2>/dev/null; then\n echo \"Warning: Non-JSON response for CID $CID — chain broken at depth $((COUNT + 1))\" >&2\n echo \"Response preview: $(echo \"$EXPERIENCE\" | head -c 200)\" >&2\n break\n fi\n\n if [[ -n \"$OUTPUT_DIR\" ]]; then\n echo \"$EXPERIENCE\" > \"$OUTPUT_DIR/$(printf '%04d' $COUNT)-$CID.json\"\n echo \"[$COUNT] Saved $CID\" >&2\n else\n echo \"$EXPERIENCE\"\n fi\n\n # Follow the chain — check header.previousCid first (Autonomys Agents format),\n # then fall back to root-level previousCid for compatibility\n PREV=$(echo \"$EXPERIENCE\" | jq -r '.header.previousCid // .previousCid // empty' 2>/dev/null || true)\n CID=\"${PREV:-}\"\n # Validate next CID in chain\n if [[ -n \"$CID\" && \"$CID\" != \"null\" ]] && ! am_valid_cid \"$CID\"; then\n echo \"Warning: Invalid CID format in chain: $CID — stopping traversal\" >&2\n break\n fi\n COUNT=$((COUNT + 1))\ndone\n\n# Restore state file so subsequent save-memory calls continue the chain\nif [[ \"$RESTORE_STATE\" == true && $COUNT -gt 0 ]]; then\n RS_STATE_FILE=\"${OPENCLAW_WORKSPACE:-$HOME/.openclaw/workspace}/memory/automemory-state.json\"\n mkdir -p \"$(dirname \"$RS_STATE_FILE\")\"\n # Detect whether traversal was truncated by --limit (chain may be longer than $COUNT)\n TRUNCATED=false\n if [[ $COUNT -ge $LIMIT && -n \"$CID\" && \"$CID\" != \"null\" ]]; then\n TRUNCATED=true\n fi\n jq -n \\\n --arg cid \"$HEAD_CID\" \\\n --arg ts \"$(date -u +\"%Y-%m-%dT%H:%M:%S.000Z\")\" \\\n --argjson len \"$COUNT\" \\\n --argjson truncated \"$TRUNCATED\" \\\n '{lastCid: $cid, lastUploadTimestamp: $ts, chainLength: $len, chainTruncated: $truncated}' > \"$RS_STATE_FILE\"\n chmod 600 \"$RS_STATE_FILE\"\n if [[ \"$TRUNCATED\" == true ]]; then\n echo \"State restored: lastCid=$HEAD_CID, chainLength>=$COUNT (truncated by --limit $LIMIT)\" >&2\n else\n echo \"State restored: lastCid=$HEAD_CID, chainLength=$COUNT\" >&2\n fi\nfi\n\necho \"\" >&2\necho \"=== CHAIN COMPLETE ===\" >&2\necho \"Total memories recalled: $COUNT\" >&2\nif [[ $COUNT -ge $LIMIT ]]; then\n echo \"Warning: Hit limit of $LIMIT entries. Use --limit N to retrieve more.\" >&2\nfi\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":8697,"content_sha256":"3b2c1d48eb5e6c586767dfaf6a1588461be4b697b3d5b95914964c90ac0d9809"},{"filename":"scripts/automemory-save-memory.sh","content":"#!/usr/bin/env bash\n# Save a memory experience to Auto Drive as part of the linked list chain\n# Usage: automemory-save-memory.sh \u003cdata_file_or_string> [--agent-name NAME] [--state-file PATH]\n# Env: AUTO_DRIVE_API_KEY (required), AGENT_NAME (optional, default: openclaw-agent),\n# OPENCLAW_WORKSPACE (optional, default: $HOME/.openclaw/workspace)\n# Output: JSON with cid, previousCid, chainLength (stdout)\n#\n# If the first argument is a file path, its contents are used as the data payload.\n# If the first argument is a plain string, it is wrapped as {\"type\":\"memory\",\"content\":\"...\"}.\n\nset -euo pipefail\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n# shellcheck source=./_lib.sh\nsource \"$SCRIPT_DIR/_lib.sh\"\nam_warn_git_bash\nam_require_tools curl jq\nINPUT=\"${1:?Usage: automemory-save-memory.sh \u003cdata_file_or_string> [--agent-name NAME] [--state-file PATH]}\"\nAGENT_NAME=\"${AGENT_NAME:-openclaw-agent}\"\nSTATE_FILE=\"${OPENCLAW_WORKSPACE:-$HOME/.openclaw/workspace}/memory/automemory-state.json\"\nSTATE_FILE_EXPLICIT=false\n\nshift\nwhile [[ $# -gt 0 ]]; do\n case \"$1\" in\n --agent-name)\n if [[ $# -lt 2 ]]; then echo \"Error: --agent-name requires a value\" >&2; exit 1; fi\n AGENT_NAME=\"$2\"; shift 2 ;;\n --state-file)\n if [[ $# -lt 2 ]]; then echo \"Error: --state-file requires a value\" >&2; exit 1; fi\n STATE_FILE=\"$2\"; STATE_FILE_EXPLICIT=true; shift 2 ;;\n *) shift ;;\n esac\ndone\n\n# Validate explicit --state-file: reject traversal, resolve physically, verify within $HOME.\n# Skipped for the default path which derives from a trusted env var.\nif [[ \"$STATE_FILE_EXPLICIT\" == true ]]; then\n if [[ \"$STATE_FILE\" == *..* ]]; then\n echo \"Error: State file path must not contain '..': $STATE_FILE\" >&2; exit 1\n fi\n HOME_REAL=\"$(cd \"$HOME\" && pwd -P)\"\n # Convert to absolute, normalize $HOME to physical path.\n if [[ \"$STATE_FILE\" != /* ]]; then\n STATE_FILE_CHECK=\"$(pwd -P)/$STATE_FILE\"\n else\n STATE_FILE_CHECK=\"$STATE_FILE\"\n fi\n if [[ \"$STATE_FILE_CHECK\" == \"$HOME/\"* ]]; then\n STATE_FILE_CHECK=\"$HOME_REAL/${STATE_FILE_CHECK#\"$HOME/\"}\"\n elif [[ \"$STATE_FILE_CHECK\" == \"$HOME\" ]]; then\n STATE_FILE_CHECK=\"$HOME_REAL\"\n fi\n # Resolve parent physically if it exists (catches symlinks).\n STATE_FILE_DIR=\"$(dirname \"$STATE_FILE_CHECK\")\"\n STATE_FILE_BASE=\"$(basename \"$STATE_FILE_CHECK\")\"\n if [[ -d \"$STATE_FILE_DIR\" ]]; then\n STATE_FILE_CHECK=\"$(cd \"$STATE_FILE_DIR\" && pwd -P)/$STATE_FILE_BASE\"\n fi\n if [[ \"$STATE_FILE_CHECK\" != \"$HOME_REAL/\"* ]]; then\n echo \"Error: State file path must be within home directory\" >&2\n exit 1\n fi\n STATE_FILE=\"$STATE_FILE_CHECK\"\nfi\n\nif [[ -z \"${AUTO_DRIVE_API_KEY:-}\" ]]; then\n echo \"Error: AUTO_DRIVE_API_KEY not set.\" >&2\n echo \"Get a free key at https://ai3.storage (sign in with Google/GitHub → Developers → Create API Key)\" >&2\n exit 1\nfi\n\n# Determine if input is a file or a string\nif [[ -f \"$INPUT\" ]]; then\n # Validate it's JSON\n if ! jq empty \"$INPUT\" 2>/dev/null; then\n echo \"Error: Data file is not valid JSON: $INPUT\" >&2\n exit 1\n fi\n DATA_JSON=$(cat \"$INPUT\")\nelse\n # Wrap the plain string as a simple memory object\n DATA_JSON=$(jq -n --arg content \"$INPUT\" '{type: \"memory\", content: $content}')\nfi\n\n# Read previous CID and chain length from state file\nPREVIOUS_CID=\"null\"\nCHAIN_LENGTH=0\nif [[ -f \"$STATE_FILE\" ]]; then\n PREVIOUS_CID=$(jq -r '.lastCid // empty' \"$STATE_FILE\" 2>/dev/null || echo \"null\")\n CHAIN_LENGTH=$(jq -r '.chainLength // 0' \"$STATE_FILE\" 2>/dev/null || echo \"0\")\n [[ -z \"$PREVIOUS_CID\" ]] && PREVIOUS_CID=\"null\"\n # Reject a corrupted/tampered state file CID rather than propagating it into the chain\n if [[ \"$PREVIOUS_CID\" != \"null\" ]] && ! am_valid_cid \"$PREVIOUS_CID\"; then\n echo \"Warning: State file contains invalid CID '$PREVIOUS_CID' — starting new chain\" >&2\n PREVIOUS_CID=\"null\"\n CHAIN_LENGTH=0\n fi\nfi\n\nTIMESTAMP=$(date -u +\"%Y-%m-%dT%H:%M:%S.000Z\")\n\n# Build the experience JSON with header/data structure\nEXPERIENCE=$(jq -n \\\n --arg name \"$AGENT_NAME\" \\\n --arg ts \"$TIMESTAMP\" \\\n --arg prev \"$PREVIOUS_CID\" \\\n --argjson data \"$DATA_JSON\" \\\n '{\n header: {\n agentName: $name,\n agentVersion: \"1.0.0\",\n timestamp: $ts,\n previousCid: (if $prev == \"null\" then null else $prev end)\n },\n data: $data\n }')\n\n# Write to temp file and upload via the upload script\nTMPDIR_MEMORY=$(mktemp -d)\nSAFE_AGENT_NAME=$(printf '%s' \"$AGENT_NAME\" | tr -cd 'A-Za-z0-9_-')\nSAFE_AGENT_NAME=\"${SAFE_AGENT_NAME:-agent}\"\nTMPFILE=\"$TMPDIR_MEMORY/auto-memory-${SAFE_AGENT_NAME}-$(date -u +%Y%m%dT%H%M%S).json\"\ntrap 'rm -rf \"$TMPDIR_MEMORY\"' EXIT\necho \"$EXPERIENCE\" > \"$TMPFILE\"\nCID=$(\"$SCRIPT_DIR/automemory-upload.sh\" \"$TMPFILE\" --json --compress)\n\nif [[ -z \"$CID\" ]]; then\n echo \"Error: Upload failed — no CID returned\" >&2\n exit 1\nfi\n\n# Validate CID format\nif ! am_valid_cid \"$CID\"; then\n echo \"Error: Invalid CID format returned: $CID\" >&2\n exit 1\nfi\n\n# Update state file\nNEW_LENGTH=$((CHAIN_LENGTH + 1))\nmkdir -p \"$(dirname \"$STATE_FILE\")\"\njq -n \\\n --arg cid \"$CID\" \\\n --arg ts \"$TIMESTAMP\" \\\n --argjson len \"$NEW_LENGTH\" \\\n '{lastCid: $cid, lastUploadTimestamp: $ts, chainLength: $len}' > \"$STATE_FILE\"\nchmod 600 \"$STATE_FILE\"\n\n# Pin latest CID to MEMORY.md for session continuity (if it exists)\nMEMORY_FILE=\"${OPENCLAW_WORKSPACE:-$HOME/.openclaw/workspace}/MEMORY.md\"\nif [[ -f \"$MEMORY_FILE\" ]]; then\n if grep -q \"^## Auto-Memory Chain\" \"$MEMORY_FILE\"; then\n if grep -q \"^\\- \\*\\*Latest CID:\\*\\*\" \"$MEMORY_FILE\"; then\n # Portable sed -i (works on both macOS and Linux)\n SEDTMP=$(mktemp \"${MEMORY_FILE}.XXXXXX\")\n sed \"s|^- \\*\\*Latest CID:\\*\\*.*|- **Latest CID:** \\`$CID\\` (chain length: $NEW_LENGTH, updated: $TIMESTAMP)|\" \"$MEMORY_FILE\" > \"$SEDTMP\" && mv \"$SEDTMP\" \"$MEMORY_FILE\"\n else\n # Backticks below are literal Markdown, not shell expansion\n # shellcheck disable=SC2016\n printf '- **Latest CID:** `%s` (chain length: %d, updated: %s)\\n' \"$CID\" \"$NEW_LENGTH\" \"$TIMESTAMP\" >> \"$MEMORY_FILE\"\n fi\n else\n # Backticks below are literal Markdown, not shell expansion\n # shellcheck disable=SC2016\n printf '\\n## Auto-Memory Chain\\n- **Latest CID:** `%s` (chain length: %d, updated: %s)\\n' \"$CID\" \"$NEW_LENGTH\" \"$TIMESTAMP\" >> \"$MEMORY_FILE\"\n fi\nfi\n\n# Output structured result\njq -n \\\n --arg cid \"$CID\" \\\n --arg prev \"$PREVIOUS_CID\" \\\n --argjson len \"$NEW_LENGTH\" \\\n '{cid: $cid, previousCid: (if $prev == \"null\" then null else $prev end), chainLength: $len}'\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":6521,"content_sha256":"d1a7b4a8476467d8621c3614ac996939dcc9b1037332c059db6fe585b3f12397"},{"filename":"scripts/automemory-upload.sh","content":"#!/usr/bin/env bash\n# Upload a file or JSON object to Auto Drive (3-step chunked upload)\n# Usage: automemory-upload.sh \u003cfile_path> [--json] [--compress]\n# Env: AUTO_DRIVE_API_KEY (required)\n# Output: CID on success (stdout), status messages on stderr\n\nset -euo pipefail\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n# shellcheck source=./_lib.sh\nsource \"$SCRIPT_DIR/_lib.sh\"\nam_warn_git_bash\nam_require_tools curl jq\n\nFILE_PATH=\"${1:?Usage: automemory-upload.sh \u003cfile_path> [--json] [--compress]}\"\nIS_JSON=false\nCOMPRESS=false\nshift\nfor arg in \"$@\"; do\n case \"$arg\" in\n --json) IS_JSON=true ;;\n --compress) COMPRESS=true ;;\n esac\ndone\n\nif [[ -z \"${AUTO_DRIVE_API_KEY:-}\" ]]; then\n echo \"Error: AUTO_DRIVE_API_KEY not set.\" >&2\n echo \"Get a free key at https://ai3.storage (sign in with Google/GitHub → Developers → Create API Key)\" >&2\n exit 1\nfi\n\nif [[ ! -f \"$FILE_PATH\" ]]; then\n echo \"Error: File not found: $FILE_PATH\" >&2\n exit 1\nfi\n\nFILENAME=$(basename \"$FILE_PATH\")\nif $IS_JSON; then\n MIME=\"application/json\"\nelse\n if command -v file &>/dev/null; then\n MIME=$(file --mime-type -b \"$FILE_PATH\" 2>/dev/null || echo \"application/octet-stream\")\n else\n case \"${FILE_PATH##*.}\" in\n json) MIME=\"application/json\" ;;\n txt) MIME=\"text/plain\" ;;\n pdf) MIME=\"application/pdf\" ;;\n png) MIME=\"image/png\" ;;\n jpg|jpeg) MIME=\"image/jpeg\" ;;\n *) MIME=\"application/octet-stream\" ;;\n esac\n fi\nfi\n\nAUTH_HEADERS=(-H \"Authorization: Bearer $AUTO_DRIVE_API_KEY\" -H \"X-Auth-Provider: apikey\")\n\n# Step 1: Create upload\necho \"Creating upload for '$FILENAME'...\" >&2\nif $COMPRESS; then\n UPLOAD_BODY=$(jq -n --arg fn \"$FILENAME\" --arg mt \"$MIME\" \\\n '{filename: $fn, mimeType: $mt, uploadOptions: {compression: {algorithm: \"ZLIB\"}}}')\nelse\n UPLOAD_BODY=$(jq -n --arg fn \"$FILENAME\" --arg mt \"$MIME\" \\\n '{filename: $fn, mimeType: $mt, uploadOptions: {}}')\nfi\n\nRESPONSE=$(curl -sS -w \"\\n%{http_code}\" -X POST \"$AD_API_BASE/uploads/file\" \\\n \"${AUTH_HEADERS[@]}\" \\\n -H \"Content-Type: application/json\" \\\n -d \"$UPLOAD_BODY\")\nHTTP_CODE=$(echo \"$RESPONSE\" | tail -1)\nBODY=$(echo \"$RESPONSE\" | sed '$d')\n\nif [[ \"$HTTP_CODE\" -lt 200 || \"$HTTP_CODE\" -ge 300 ]]; then\n echo \"Error: Failed to create upload (HTTP $HTTP_CODE)\" >&2\n echo \"$BODY\" >&2\n exit 1\nfi\n\nUPLOAD_ID=$(echo \"$BODY\" | jq -r '.id')\nif [[ -z \"$UPLOAD_ID\" || \"$UPLOAD_ID\" == \"null\" ]]; then\n echo \"Error: Failed to create upload — no upload ID returned\" >&2\n echo \"$BODY\" >&2\n exit 1\nfi\n\n# Step 2: Upload chunk\necho \"Uploading file data...\" >&2\nRESPONSE=$(curl -sS -w \"\\n%{http_code}\" -X POST \"$AD_API_BASE/uploads/file/$UPLOAD_ID/chunk\" \\\n \"${AUTH_HEADERS[@]}\" \\\n -F \"file=@$FILE_PATH\" \\\n -F \"index=0\")\nHTTP_CODE=$(echo \"$RESPONSE\" | tail -1)\nif [[ \"$HTTP_CODE\" -lt 200 || \"$HTTP_CODE\" -ge 300 ]]; then\n BODY=$(echo \"$RESPONSE\" | sed '$d')\n echo \"Error: Failed to upload chunk (HTTP $HTTP_CODE)\" >&2\n echo \"$BODY\" >&2\n exit 1\nfi\n\n# Step 3: Complete upload → get CID\necho \"Completing upload...\" >&2\nRESPONSE=$(curl -sS -w \"\\n%{http_code}\" -X POST \"$AD_API_BASE/uploads/$UPLOAD_ID/complete\" \\\n \"${AUTH_HEADERS[@]}\")\nHTTP_CODE=$(echo \"$RESPONSE\" | tail -1)\nBODY=$(echo \"$RESPONSE\" | sed '$d')\n\nif [[ \"$HTTP_CODE\" -lt 200 || \"$HTTP_CODE\" -ge 300 ]]; then\n echo \"Error: Failed to complete upload (HTTP $HTTP_CODE)\" >&2\n echo \"$BODY\" >&2\n exit 1\nfi\n\nCID=$(echo \"$BODY\" | jq -r '.cid')\nif [[ -z \"$CID\" || \"$CID\" == \"null\" ]]; then\n echo \"Error: Upload completed but no CID returned\" >&2\n echo \"$BODY\" >&2\n exit 1\nfi\n\n# Validate CID format to prevent command injection and chain corruption\nif ! am_valid_cid \"$CID\"; then\n echo \"Error: Invalid CID format returned: $CID\" >&2\n exit 1\nfi\n\necho \"Upload successful! CID: $CID\" >&2\necho \"Gateway URL: https://gateway.autonomys.xyz/file/$CID\" >&2\necho \"$CID\"\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":3865,"content_sha256":"00b3b9d8c97500633614f39156b93205b13c5b37dcd24200a355f4ed36028b8d"},{"filename":"scripts/setup-auto-memory.sh","content":"#!/usr/bin/env bash\n# Setup Autonomys Auto-Memory — interactive API key configuration\n# Usage: ./scripts/setup-auto-memory.sh\n# Opens explorer.ai3.storage in your browser, prompts for the API key,\n# writes it to ~/.openclaw/openclaw.json (skills.entries.auto-memory.env)\n# and ~/.openclaw/.env, then verifies the connection.\n\nset -euo pipefail\n\n# shellcheck source=_lib.sh\nsource \"$(dirname \"$0\")/_lib.sh\"\n\necho \"\"\necho \"╔══════════════════════════════════════════╗\"\necho \"║ Autonomys Auto-Memory — Setup ║\"\necho \"╚══════════════════════════════════════════╝\"\necho \"\"\n\nam_warn_git_bash\nam_require_tools curl jq\necho -e \"${GREEN}✓ Prerequisites OK (curl, jq)${NC}\"\necho \"\"\n\n# Open browser to API key creation page\nDASHBOARD_URL=\"https://explorer.ai3.storage/mainnet/drive/developers\"\necho \"Opening $DASHBOARD_URL in your browser...\"\necho \"\"\necho \" → If prompted, sign in with Google, GitHub, or Discord\"\necho \" (AI agents: you cannot complete OAuth yourself —\"\necho \" ask the user to sign in, then take over)\"\necho \" → Click 'Create API Key' and paste the key below\"\necho \"\"\nif command -v xdg-open &>/dev/null; then\n xdg-open \"$DASHBOARD_URL\" 2>/dev/null &\nelif command -v open &>/dev/null; then\n open \"$DASHBOARD_URL\" 2>/dev/null &\nelif [[ -n \"${WSL_DISTRO_NAME:-}\" ]] || grep -qi microsoft /proc/version 2>/dev/null; then\n cmd.exe /c start \"\" \"$DASHBOARD_URL\" 2>/dev/null &\nelse\n echo -e \"${YELLOW}Could not open browser automatically — visit: $DASHBOARD_URL${NC}\"\nfi\n\nread -rp \"Paste your API key here: \" API_KEY\nAPI_KEY=\"${API_KEY//[[:space:]]/}\"\n\nif [[ -z \"$API_KEY\" ]]; then\n echo -e \"${RED}Error: No API key provided.${NC}\" >&2\n exit 1\nfi\n\necho \"\"\nautomemory_verify_key \"$API_KEY\"\nautomemory_save_key \"$API_KEY\"\n\necho \"\"\necho \"╔══════════════════════════════════════════╗\"\necho \"║ Setup complete! ║\"\necho \"╚══════════════════════════════════════════╝\"\necho \"\"\necho \"Next steps:\"\necho \" 1. Restart OpenClaw gateway to pick up the new config\"\necho \" 2. Try: scripts/automemory-upload.sh /path/to/any/file\"\necho \" 3. Or run: scripts/verify-setup.sh\"\necho \"\"\necho \"Or ask your agent: 'Save a memory that Auto-Memory is now configured'\"\necho \"\"\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":2577,"content_sha256":"6a6fc3c4fe4dac3d430582b96ec2e1bac7b99104703c3b4abec546c31ac72252"},{"filename":"scripts/update-api-key.sh","content":"#!/usr/bin/env bash\n# Update the Auto Drive API key without re-running full setup\n# Usage: ./scripts/update-api-key.sh\n# Env: AUTO_DRIVE_API_KEY may be set to skip the prompt (non-interactive use)\n\nset -euo pipefail\n\n# shellcheck source=_lib.sh\nsource \"$(dirname \"$0\")/_lib.sh\"\n\nam_warn_git_bash\nam_require_tools curl jq\n\n# Accept key from argument, interactive prompt, or env var (CI only).\n# When stdin is a terminal we always prompt so the user isn't silently\n# handed back the old key that is already exported in their shell.\nif [[ -n \"${1:-}\" ]]; then\n API_KEY=\"$1\"\nelif [[ -t 0 ]]; then\n read -rp \"New Auto Drive API key: \" API_KEY\nelif [[ -n \"${AUTO_DRIVE_API_KEY:-}\" ]]; then\n API_KEY=\"$AUTO_DRIVE_API_KEY\"\nelse\n echo -e \"${RED}Error: No API key provided (non-interactive and AUTO_DRIVE_API_KEY is unset).${NC}\" >&2\n exit 1\nfi\nAPI_KEY=\"${API_KEY//[[:space:]]/}\"\n\nif [[ -z \"$API_KEY\" ]]; then\n echo -e \"${RED}Error: No API key provided.${NC}\" >&2\n exit 1\nfi\n\nautomemory_verify_key \"$API_KEY\"\nautomemory_save_key \"$API_KEY\"\n\necho \"\"\necho \"API key updated. Restart the OpenClaw gateway to apply.\"\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":1109,"content_sha256":"74d6a4e31c68e431bd234aff9c07b5e6ef664707876611b3b481d7a945bdc466"},{"filename":"scripts/verify-setup.sh","content":"#!/usr/bin/env bash\n# Verify Auto-Memory setup — checks API key, account info, and remaining credits\n# Usage: ./scripts/verify-setup.sh\n\nset -euo pipefail\n\n# shellcheck source=_lib.sh\nsource \"$(dirname \"$0\")/_lib.sh\"\n\nam_warn_git_bash\n\necho \"\"\necho \"=== Auto-Memory Setup Verification ===\"\necho \"\"\n\n# Check prerequisites first — curl and jq are needed for verification below\nMISSING=()\nfor bin in curl jq file; do\n if command -v \"$bin\" &>/dev/null; then\n echo -e \" ${GREEN}✓ $bin${NC}\"\n else\n echo -e \" ${RED}✗ $bin not found${NC}\"\n MISSING+=(\"$bin\")\n fi\ndone\n\nif [[ ${#MISSING[@]} -gt 0 ]]; then\n echo -e \"${RED}✗ Missing prerequisites: ${MISSING[*]}${NC}\" >&2\n exit 1\nfi\necho \"\"\n\n# Check for API key\nif [[ -z \"${AUTO_DRIVE_API_KEY:-}\" ]]; then\n echo -e \"${RED}✗ AUTO_DRIVE_API_KEY is not set${NC}\" >&2\n echo \" Run: scripts/setup-auto-memory.sh\" >&2\n exit 1\nfi\necho -e \"${GREEN}✓ AUTO_DRIVE_API_KEY is set${NC}\"\n\n# Verify key and fetch account info\nif ! automemory_verify_key \"$AUTO_DRIVE_API_KEY\"; then\n echo \" The key may be invalid or expired. Run: scripts/update-api-key.sh\" >&2\n exit 1\nfi\n\n# Display account details (AM_VERIFY_BODY set by automemory_verify_key)\nLIMIT=$(echo \"$AM_VERIFY_BODY\" | jq -r '.uploadLimit // .limits.uploadLimit // empty' 2>/dev/null || true)\nUSED=$(echo \"$AM_VERIFY_BODY\" | jq -r '.uploadedBytes // .limits.uploadedBytes // empty' 2>/dev/null || true)\n\nif [[ -n \"$LIMIT\" && -n \"$USED\" ]]; then\n REMAINING=$((LIMIT - USED))\n if command -v bc &>/dev/null; then\n UNIT=\"MB\"\n LIMIT_FMT=$(echo \"scale=1; $LIMIT / 1048576\" | bc)\n USED_FMT=$(echo \"scale=1; $USED / 1048576\" | bc)\n REMAINING_FMT=$(echo \"scale=1; $REMAINING / 1048576\" | bc)\n else\n UNIT=\"bytes\"\n LIMIT_FMT=\"$LIMIT\"\n USED_FMT=\"$USED\"\n REMAINING_FMT=\"$REMAINING\"\n fi\n echo \" Upload limit: ${LIMIT_FMT} ${UNIT} / month\"\n echo \" Used this month: ${USED_FMT} ${UNIT}\"\n if [[ \"$REMAINING\" -lt 1048576 ]]; then\n echo -e \" Remaining: ${YELLOW}${REMAINING_FMT} ${UNIT} (low)${NC}\"\n else\n echo -e \" Remaining: ${GREEN}${REMAINING_FMT} ${UNIT}${NC}\"\n fi\nfi\n\necho \"\"\necho -e \"${GREEN}All checks passed. Auto-Memory is ready.${NC}\"\necho \"\"\necho \"Try: scripts/automemory-upload.sh /path/to/any/file\"\necho \"\"\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":2279,"content_sha256":"2e618e4cad99b2a6b67721cf2e4bd294e450276c1849e37243825696c4fd47ec"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Auto-Memory Skill","type":"text"}]},{"type":"paragraph","content":[{"text":"Permanent decentralized memory on the Autonomys Network with linked-list memory chains for agent resurrection. Works with agents powered by Claude, GPT, Gemini, and any LLM that supports OpenClaw skills.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"What This Skill Does","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Upload files","type":"text","marks":[{"type":"strong"}]},{"text":" to Auto Drive and get back a CID (Content Identifier) — a permanent, immutable address on the Autonomys distributed storage network.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Download files","type":"text","marks":[{"type":"strong"}]},{"text":" from Auto Drive using a CID — uses the authenticated API if a key is set, otherwise falls back to the public gateway.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Save memories as a chain","type":"text","marks":[{"type":"strong"}]},{"text":" — each memory entry is a JSON experience with a ","type":"text"},{"text":"header.previousCid","type":"text","marks":[{"type":"code_inline"}]},{"text":" pointer, forming a linked list stored permanently on-chain.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Resurrect from a chain","type":"text","marks":[{"type":"strong"}]},{"text":" — given the latest CID, walk the chain backwards to reconstruct full agent history.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"When To Use This Skill","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"User says \"save this to Auto-Memory\" or \"upload to Autonomys\" or \"store permanently\"","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"User says \"download from Auto-Memory\" or provides a CID to retrieve","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"User says \"save memory\", \"remember this permanently\", or \"checkpoint\"","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"User says \"resurrect\", \"recall chain\", \"rebuild memory\", or \"load history\"","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Any time the user wants data stored permanently and immutably on a decentralized network","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Post-Install","type":"text"}]},{"type":"paragraph","content":[{"text":"After installing via ClawHub, make the scripts executable:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"chmod +x skills/auto-memory/scripts/*.sh","type":"text"}]},{"type":"paragraph","content":[{"text":"ClawHub does not currently preserve file permissions during install.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Configuration","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"API Key","type":"text"}]},{"type":"paragraph","content":[{"text":"Requires an ","type":"text"},{"text":"AUTO_DRIVE_API_KEY","type":"text","marks":[{"type":"code_inline"}]},{"text":". Run the guided setup script for the easiest path:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"scripts/setup-auto-memory.sh","type":"text"}]},{"type":"paragraph","content":[{"text":"This opens ","type":"text"},{"text":"explorer.ai3.storage","type":"text","marks":[{"type":"link","attrs":{"href":"https://explorer.ai3.storage/mainnet/drive/developers","title":null}}]},{"text":" in your browser, prompts for the key, saves it to ","type":"text"},{"text":"~/.openclaw/.env","type":"text","marks":[{"type":"code_inline"}]},{"text":", and verifies the connection.","type":"text"}]},{"type":"paragraph","content":[{"text":"Manual setup:","type":"text","marks":[{"type":"strong"}]}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Navigate to ","type":"text"},{"text":"https://explorer.ai3.storage","type":"text","marks":[{"type":"strong"}]},{"text":" (not ","type":"text"},{"text":"ai3.storage","type":"text","marks":[{"type":"code_inline"}]},{"text":" — that's just the landing page)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Check authentication: if the sidebar shows a \"Log In\" button or lock icons on My Files / Profile / Developers, you are not signed in","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"AI agent note:","type":"text","marks":[{"type":"strong"}]},{"text":" You cannot complete OAuth yourself. Open the browser for the user and ask them to sign in via Google, GitHub, or Discord. Once the user confirms they're signed in, take over — or simply ask the user to paste the API key directly","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Once authenticated, click ","type":"text"},{"text":"Developers","type":"text","marks":[{"type":"strong"}]},{"text":" in the left sidebar","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Click ","type":"text"},{"text":"Create API Key","type":"text","marks":[{"type":"strong"}]},{"text":" and copy the generated key","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Then set the key via:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Environment:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"export AUTO_DRIVE_API_KEY=your_key_here","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"OpenClaw config:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"skills.entries.auto-memory.apiKey","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"paragraph","content":[{"text":"The API key is required for uploading, saving memories, and recalling the memory chain. It is optional for general file downloads — without it, the public gateway is used and files are returned as stored (i.e. compressed files will not be decompressed).","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Core Operations","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Upload a File","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"scripts/automemory-upload.sh \u003cfilepath> [--json] [--compress]","type":"text"}]},{"type":"paragraph","content":[{"text":"Uploads a file to Auto Drive mainnet using the 3-step upload protocol (single chunk). Returns the CID on stdout. Requires ","type":"text"},{"text":"AUTO_DRIVE_API_KEY","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"--json","type":"text","marks":[{"type":"code_inline"}]},{"text":" — force MIME type to ","type":"text"},{"text":"application/json","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"--compress","type":"text","marks":[{"type":"code_inline"}]},{"text":" — enable ZLIB compression","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Download a File","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"scripts/automemory-download.sh \u003ccid> [output_path]","type":"text"}]},{"type":"paragraph","content":[{"text":"Downloads a file by CID. Uses the authenticated API if ","type":"text"},{"text":"AUTO_DRIVE_API_KEY","type":"text","marks":[{"type":"code_inline"}]},{"text":" is set (decompresses server-side), otherwise uses the public gateway (files returned as stored). If ","type":"text"},{"text":"output_path","type":"text","marks":[{"type":"code_inline"}]},{"text":" is omitted, outputs to stdout.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Save a Memory Entry","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"scripts/automemory-save-memory.sh \u003cdata_file_or_string> [--agent-name NAME] [--state-file PATH]","type":"text"}]},{"type":"paragraph","content":[{"text":"Creates a memory experience with the Autonomys Agents header/data structure:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"json"},"content":[{"text":"{\n \"header\": {\n \"agentName\": \"my-agent\",\n \"agentVersion\": \"1.0.0\",\n \"timestamp\": \"2026-02-14T00:00:00.000Z\",\n \"previousCid\": \"bafk...or null\"\n },\n \"data\": {\n \"type\": \"memory\",\n \"content\": \"...\"\n }\n}","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"If the first argument is a ","type":"text"},{"text":"file path","type":"text","marks":[{"type":"strong"}]},{"text":", its JSON contents become the ","type":"text"},{"text":"data","type":"text","marks":[{"type":"code_inline"}]},{"text":" payload.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"If the first argument is a ","type":"text"},{"text":"plain string","type":"text","marks":[{"type":"strong"}]},{"text":", it is wrapped as ","type":"text"},{"text":"{\"type\": \"memory\", \"content\": \"...\"}","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"--agent-name","type":"text","marks":[{"type":"code_inline"}]},{"text":" — set the agent name in the header (default: ","type":"text"},{"text":"openclaw-agent","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"$AGENT_NAME","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"--state-file","type":"text","marks":[{"type":"code_inline"}]},{"text":" — override the state file location","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Uploads to Auto Drive and updates the state file with the new head CID. Also pins the latest CID to ","type":"text"},{"text":"MEMORY.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" if that file exists in the workspace.","type":"text"}]},{"type":"paragraph","content":[{"text":"Returns structured JSON on stdout:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"json"},"content":[{"text":"{\"cid\": \"bafk...\", \"previousCid\": \"bafk...\", \"chainLength\": 5}","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Recall the Full Chain","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"scripts/automemory-recall-chain.sh [cid] [--limit N] [--output-dir DIR]","type":"text"}]},{"type":"paragraph","content":[{"text":"If no CID is given, reads the latest CID from the state file. Walks the linked list from newest to oldest, outputting each experience as JSON.","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"--limit N","type":"text","marks":[{"type":"code_inline"}]},{"text":" — maximum entries to retrieve (default: 50)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"--output-dir DIR","type":"text","marks":[{"type":"code_inline"}]},{"text":" — save each entry as a numbered JSON file instead of printing to stdout","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Supports both ","type":"text"},{"text":"header.previousCid","type":"text","marks":[{"type":"code_inline"}]},{"text":" (Autonomys Agents format) and root-level ","type":"text"},{"text":"previousCid","type":"text","marks":[{"type":"code_inline"}]},{"text":" for backward compatibility.","type":"text"}]},{"type":"paragraph","content":[{"text":"This is the ","type":"text"},{"text":"resurrection","type":"text","marks":[{"type":"strong"}]},{"text":" mechanism: a new agent instance only needs one CID to rebuild its entire memory.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"The Resurrection Concept","type":"text"}]},{"type":"paragraph","content":[{"text":"Every memory saved gets a unique CID and points back to the previous one, forming a permanent chain on a permanent and immutable Decentralized Storage Network:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐\n│ Experience #1 │ │ Experience #2 │ │ Experience #3 │\n│ CID: bafk...abc │◄────│ CID: bafk...def │◄────│ CID: bafk...xyz │\n│ previousCid: null │ │ previousCid: │ │ previousCid: │\n│ (genesis) │ │ bafk...abc │ │ bafk...def │\n└─────────────────────┘ └─────────────────────┘ └─────────────────────┘\n ▲\n │\n HEAD CID\n (resurrection key)","type":"text"}]},{"type":"paragraph","content":[{"text":"A new agent instance only needs the ","type":"text"},{"text":"head CID","type":"text","marks":[{"type":"strong"}]},{"text":" to walk the entire chain back to genesis and rebuild its full history. With the ","type":"text"},{"text":"auto-respawn","type":"text","marks":[{"type":"strong"}]},{"text":" skill, the head CID is anchored on-chain — making resurrection possible from just an address, on any machine, at any time:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"┌──────────┐ save ┌──────────────┐ anchor ┌────────────────┐\n│ Agent │─────────────►│ Auto-Memory │─────────────►│ Auto-Respawn │\n│ │ │ (chain) │ head CID │ (on-chain) │\n└──────────┘ └──────────────┘ └────────────────┘\n ▲ │\n │ recall chain │\n └──────────────────────────────────────────────────────────┘\n gethead → CID → walk chain","type":"text"}]},{"type":"paragraph","content":[{"text":"What you store in the chain is up to you — lightweight notes, full file snapshots, structured data, or anything in between. Because the chain is permanent and walkable, it also enables ","type":"text"},{"text":"resurrection","type":"text","marks":[{"type":"strong"}]},{"text":": if the agent loses all local state, a new instance can walk the chain from the last CID back to genesis and restore whatever was saved. When combined with the ","type":"text"},{"text":"auto-respawn","type":"text","marks":[{"type":"strong"}]},{"text":" skill (which anchors the head CID on-chain), this becomes a full resurrection loop — no local state required at all.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Usage Examples","type":"text"}]},{"type":"paragraph","content":[{"text":"User:","type":"text","marks":[{"type":"strong"}]},{"text":" \"Upload my report to Autonomys\" → Run ","type":"text"},{"text":"scripts/automemory-upload.sh /path/to/report.pdf","type":"text","marks":[{"type":"code_inline"}]},{"text":" → Report back the CID and gateway link","type":"text"}]},{"type":"paragraph","content":[{"text":"User:","type":"text","marks":[{"type":"strong"}]},{"text":" \"Upload with compression\" → Run ","type":"text"},{"text":"scripts/automemory-upload.sh /path/to/data.json --json --compress","type":"text","marks":[{"type":"code_inline"}]}]},{"type":"paragraph","content":[{"text":"User:","type":"text","marks":[{"type":"strong"}]},{"text":" \"My soul.md has changed — save it permanently\" → Run ","type":"text"},{"text":"scripts/automemory-save-memory.sh /path/to/soul.md --agent-name my-agent","type":"text","marks":[{"type":"code_inline"}]}]},{"type":"paragraph","content":[{"text":"User:","type":"text","marks":[{"type":"strong"}]},{"text":" \"Save a memory that we decided to use React for the frontend\" → Run ","type":"text"},{"text":"scripts/automemory-save-memory.sh \"Decision: using React for frontend. Reason: team familiarity and component reuse.\"","type":"text","marks":[{"type":"code_inline"}]}]},{"type":"paragraph","content":[{"text":"User:","type":"text","marks":[{"type":"strong"}]},{"text":" \"Save a structured memory\" → Create a JSON file, then run ","type":"text"},{"text":"scripts/automemory-save-memory.sh /tmp/milestone.json --agent-name my-agent","type":"text","marks":[{"type":"code_inline"}]}]},{"type":"paragraph","content":[{"text":"User:","type":"text","marks":[{"type":"strong"}]},{"text":" \"Resurrect my memory chain\" → Run ","type":"text"},{"text":"scripts/automemory-recall-chain.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":" → Rebuild identity and context from genesis to present","type":"text"}]},{"type":"paragraph","content":[{"text":"User:","type":"text","marks":[{"type":"strong"}]},{"text":" \"Download bafk...abc from Autonomys\" → Run ","type":"text"},{"text":"scripts/automemory-download.sh bafk...abc ./downloaded_file","type":"text","marks":[{"type":"code_inline"}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Integration with Auto-Respawn","type":"text"}]},{"type":"paragraph","content":[{"text":"If the ","type":"text"},{"text":"auto-respawn","type":"text","marks":[{"type":"strong"}]},{"text":" skill is also installed, anchor the new head CID on-chain after every memory save. This ensures the on-chain pointer always reflects the latest memory state, enabling full resurrection from just an EVM address.","type":"text"}]},{"type":"paragraph","content":[{"text":"After each ","type":"text"},{"text":"automemory-save-memory.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":" call, run:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"npx tsx auto-respawn.ts anchor --from \u003cwallet-name> --cid \u003cnew-cid>","type":"text"}]},{"type":"paragraph","content":[{"text":"This completes the resurrection loop: permanent storage (auto-memory) + on-chain discovery (auto-respawn). Without anchoring, a new instance would need the head CID from some other source to walk the chain.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Important Notes","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"All data stored via Auto Drive is ","type":"text"},{"text":"permanent and public","type":"text","marks":[{"type":"strong"}]},{"text":" by default. Do not store secrets, private keys, or sensitive personal data.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"The free API key has a ","type":"text"},{"text":"20 MB per month upload limit","type":"text","marks":[{"type":"strong"}]},{"text":" on mainnet. Downloads are unlimited. Check remaining credits via ","type":"text"},{"text":"GET /accounts/@me","type":"text","marks":[{"type":"code_inline"}]},{"text":" or run ","type":"text"},{"text":"scripts/verify-setup.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"An API key is required for uploads, memory saves, and chain recall. General file downloads work without one via the public gateway, but compressed files will not be decompressed.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"The memory state file tracks ","type":"text"},{"text":"lastCid","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"lastUploadTimestamp","type":"text","marks":[{"type":"code_inline"}]},{"text":", and ","type":"text"},{"text":"chainLength","type":"text","marks":[{"type":"code_inline"}]},{"text":". Back up the ","type":"text"},{"text":"lastCid","type":"text","marks":[{"type":"code_inline"}]},{"text":" value — it's your resurrection key.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"The ","type":"text"},{"text":"automemory-save-memory.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":" script ","type":"text"},{"text":"automatically pins the latest CID to ","type":"text","marks":[{"type":"strong"}]},{"text":"MEMORY.md","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" if the file exists in the workspace. It creates an ","type":"text"},{"text":"## Auto-Memory Chain","type":"text","marks":[{"type":"code_inline"}]},{"text":" section and updates it on each save. You do not need to track the latest CID in MEMORY.md manually — the script handles this.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Files are uploaded in a single chunk. The free tier's 20 MB/month limit is effectively a per-file ceiling — keep individual uploads well under that to preserve your monthly budget.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Gateway URL for any file: ","type":"text"},{"text":"https://gateway.autonomys.xyz/file/\u003cCID>","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"For true resurrection resilience, consider anchoring the latest CID on-chain via the Autonomys EVM — this makes recovery possible without keeping track of the head CID yourself. See ","type":"text"},{"text":"openclaw-memory-chain","type":"text","marks":[{"type":"link","attrs":{"href":"https://github.com/autojeremy/openclaw-memory-chain","title":null}}]},{"text":" for an example contract implementation.","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"auto-memory","author":"@skillopedia","source":{"stars":65,"repo_name":"claude-code-skills","origin_url":"https://github.com/aaaaqwq/claude-code-skills/blob/HEAD/skills/auto-memory/SKILL.md","repo_owner":"aaaaqwq","body_sha256":"d278945ceb5a80f9eda1cea4e46e3f4696ec062c4e19373027fa03d6b4941f7f","cluster_key":"32c69927a768f7dd818189c2011c38990103787cbdbd9f88ecefae019c25708d","clean_bundle":{"format":"clean-skill-bundle-v1","source":"aaaaqwq/claude-code-skills/skills/auto-memory/SKILL.md","attachments":[{"id":"bb210f10-0e11-5c76-b0bf-095a71677aab","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/bb210f10-0e11-5c76-b0bf-095a71677aab/attachment.md","path":"references/automemory-api.md","size":3210,"sha256":"5adde4616b4e76b90647a1c7dedceb5177f3c6dd5f85541f89feaa4539ba13ab","contentType":"text/markdown; charset=utf-8"},{"id":"c497ef84-8c66-53d4-b1a6-32a2ef5b67fe","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/c497ef84-8c66-53d4-b1a6-32a2ef5b67fe/attachment.md","path":"references/autonomys-network.md","size":3760,"sha256":"9334168cc0032e82bcceb35d94feb5f598d9cdde021989183a8eb150db940f79","contentType":"text/markdown; charset=utf-8"},{"id":"afd4df71-efa8-58f6-a63f-89b2f5ce9201","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/afd4df71-efa8-58f6-a63f-89b2f5ce9201/attachment.md","path":"references/memory-chain.md","size":3723,"sha256":"3c17a271cf03d591916ed22441306fbce1e5d1f417077b73db4201b04db1a68c","contentType":"text/markdown; charset=utf-8"},{"id":"9b1b38d8-e398-5848-8ce1-0c083712c31f","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/9b1b38d8-e398-5848-8ce1-0c083712c31f/attachment.sh","path":"scripts/_lib.sh","size":5239,"sha256":"e168c2bdc4a0a82d267e422090084f40152d8221905c08fe090c16709352e7fa","contentType":"application/x-sh; charset=utf-8"},{"id":"aa4b072c-a550-5cf8-b9f2-a46fbb83ccce","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/aa4b072c-a550-5cf8-b9f2-a46fbb83ccce/attachment.sh","path":"scripts/automemory-download.sh","size":2858,"sha256":"fa173157aa9fc61f8bfc6fef8c0e689aac1ec69afaf5981ae26bd688b5dbb6bd","contentType":"application/x-sh; charset=utf-8"},{"id":"c7eb02b4-284f-5621-ab51-5103bbe26194","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/c7eb02b4-284f-5621-ab51-5103bbe26194/attachment.sh","path":"scripts/automemory-recall-chain.sh","size":8697,"sha256":"3b2c1d48eb5e6c586767dfaf6a1588461be4b697b3d5b95914964c90ac0d9809","contentType":"application/x-sh; charset=utf-8"},{"id":"30a9275f-972e-5455-b8ac-a3afad57006e","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/30a9275f-972e-5455-b8ac-a3afad57006e/attachment.sh","path":"scripts/automemory-save-memory.sh","size":6521,"sha256":"d1a7b4a8476467d8621c3614ac996939dcc9b1037332c059db6fe585b3f12397","contentType":"application/x-sh; charset=utf-8"},{"id":"bfbc2aee-8ad5-51ca-8ccd-a75566f35507","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/bfbc2aee-8ad5-51ca-8ccd-a75566f35507/attachment.sh","path":"scripts/automemory-upload.sh","size":3865,"sha256":"00b3b9d8c97500633614f39156b93205b13c5b37dcd24200a355f4ed36028b8d","contentType":"application/x-sh; charset=utf-8"},{"id":"a64eb0e3-f9d8-5058-8e10-acf6c7d74f33","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/a64eb0e3-f9d8-5058-8e10-acf6c7d74f33/attachment.sh","path":"scripts/setup-auto-memory.sh","size":2577,"sha256":"6a6fc3c4fe4dac3d430582b96ec2e1bac7b99104703c3b4abec546c31ac72252","contentType":"application/x-sh; charset=utf-8"},{"id":"d4a07eed-200c-5e7c-b8d2-63a86c2ef2cd","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/d4a07eed-200c-5e7c-b8d2-63a86c2ef2cd/attachment.sh","path":"scripts/update-api-key.sh","size":1109,"sha256":"74d6a4e31c68e431bd234aff9c07b5e6ef664707876611b3b481d7a945bdc466","contentType":"application/x-sh; charset=utf-8"},{"id":"866602b4-b3b9-5ceb-876e-1b648fa51bd1","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/866602b4-b3b9-5ceb-876e-1b648fa51bd1/attachment.sh","path":"scripts/verify-setup.sh","size":2279,"sha256":"2e618e4cad99b2a6b67721cf2e4bd294e450276c1849e37243825696c4fd47ec","contentType":"application/x-sh; charset=utf-8"}],"bundle_sha256":"2795d3aa3ff6edd3e6bc3492b418b48d824b35ed3226f25e55d7993f3819dc46","attachment_count":11,"text_attachments":11,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"skills/auto-memory/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"web-development","category_label":"Web"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"web-development","metadata":{"openclaw":{"emoji":"🧬","install":[{"id":"curl-brew","bins":["curl"],"kind":"brew","label":"Install curl (brew)","formula":"curl"},{"id":"jq-brew","bins":["jq"],"kind":"brew","label":"Install jq (brew)","formula":"jq"},{"id":"file-brew","bins":["file"],"kind":"brew","label":"Install file (brew)","formula":"file-formula"}],"requires":{"env":["AUTO_DRIVE_API_KEY"],"bins":["curl","jq","file"]},"primaryEnv":"AUTO_DRIVE_API_KEY"}},"import_tag":"clean-skills-v1","description":"Indestructible agent memory — permanently stored, never lost. Save decisions, identity, and context as a memory chain on the Autonomys Network. Rebuild your full history from a single CID, even after total state loss."}},"renderedAt":1782979553101}

Auto-Memory Skill Permanent decentralized memory on the Autonomys Network with linked-list memory chains for agent resurrection. Works with agents powered by Claude, GPT, Gemini, and any LLM that supports OpenClaw skills. What This Skill Does 1. Upload files to Auto Drive and get back a CID (Content Identifier) — a permanent, immutable address on the Autonomys distributed storage network. 2. Download files from Auto Drive using a CID — uses the authenticated API if a key is set, otherwise falls back to the public gateway. 3. Save memories as a chain — each memory entry is a JSON experience wi…