{
  "schemaVersion": "1.0",
  "item": {
    "slug": "overleaf",
    "name": "Overleaf",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/EasonC13/overleaf",
    "canonicalUrl": "https://clawhub.ai/EasonC13/overleaf",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/overleaf",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=overleaf",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "README.md",
      "SKILL.md",
      "_meta.json",
      "scripts/sync-to-overleaf.sh"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "slug": "overleaf",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-05-06T19:23:01.359Z",
      "expiresAt": "2026-05-13T19:23:01.359Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=overleaf",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=overleaf",
        "contentDisposition": "attachment; filename=\"overleaf-1.2.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null,
        "slug": "overleaf"
      },
      "scope": "item",
      "summary": "Item download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this item.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/overleaf"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/overleaf",
    "agentPageUrl": "https://openagent3.xyz/skills/overleaf/agent",
    "manifestUrl": "https://openagent3.xyz/skills/overleaf/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/overleaf/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Overleaf",
        "body": "CLI tool to interact with Overleaf projects using browser cookies for authentication.\n\nGitHub: https://github.com/jkulhanek/pyoverleaf"
      },
      {
        "title": "Requirements",
        "body": "Python 3.8+\npyoverleaf (pipx install pyoverleaf)\nUser logged into Overleaf in Chrome/Firefox"
      },
      {
        "title": "Security Considerations",
        "body": "⚠️ Keychain Access Required: pyoverleaf needs \"Always Allow\" keychain access to read browser cookies. This grants the tool access to your browser's cookie storage.\n\nSecurity audit: We have audited pyoverleaf v0.1.7 and found it safe. The codebase is small and readable. Before installing, agents can self-audit the latest version at the GitHub repo above."
      },
      {
        "title": "Authentication Setup",
        "body": "pyoverleaf authenticates by reading cookies from your browser. The user must:\n\nLog into Overleaf in Chrome or Firefox (visit overleaf.com and sign in)\nGrant keychain access on first run (macOS will prompt for \"Always Allow\")\n\n# Test auth - user should run this in their terminal first\npyoverleaf ls\n\nIf you get auth errors:\n\nAsk user: \"Are you logged into Overleaf in your browser?\"\nIf on macOS: \"Did you approve the keychain access prompt with 'Always Allow'?\"\nUser may need to run pyoverleaf ls manually in terminal to trigger the keychain prompt\n\nNote: The agent cannot log in for the user. Browser authentication must be done by the user directly."
      },
      {
        "title": "CLI Commands",
        "body": "# List all projects\npyoverleaf ls\n\n# List files in project\npyoverleaf ls \"Project Name\"\n\n# Read file content\npyoverleaf read \"Project Name/main.tex\"\n\n# Write file (stdin → Overleaf)\ncat local.tex | pyoverleaf write \"Project Name/main.tex\"\n\n# Create directory\npyoverleaf mkdir \"Project Name/figures\"\n\n# Remove file/folder\npyoverleaf rm \"Project Name/old-draft.tex\"\n\n# Download project as zip\npyoverleaf download-project \"Project Name\" output.zip"
      },
      {
        "title": "Download from Overleaf",
        "body": "pyoverleaf download-project \"Project Name\" /tmp/latest.zip\nunzip -o /tmp/latest.zip -d /tmp/latest\ncp /tmp/latest/main.tex /path/to/local/main.tex"
      },
      {
        "title": "Upload to Overleaf (Python API recommended)",
        "body": "The CLI write command has websocket issues. Use Python API for reliable uploads:\n\nimport pyoverleaf\n\napi = pyoverleaf.Api()\napi.login_from_browser()\n\n# List projects to get project ID\nfor proj in api.get_projects():\n    print(proj.name, proj.id)\n\n# Upload file (direct overwrite)\nproject_id = \"your_project_id_here\"\nwith open('main.tex', 'rb') as f:\n    content = f.read()\nroot = api.project_get_files(project_id)\napi.project_upload_file(project_id, root.id, \"main.tex\", content)\n\nWhy direct overwrite? This method preserves Overleaf's version history. Users can see exactly what changed via Overleaf's History feature, making it easy to review agent edits and revert if needed."
      },
      {
        "title": "Accept Project Invites",
        "body": "The agent can accept Overleaf project invitations programmatically using browser cookies — no manual clicking required."
      },
      {
        "title": "How it works",
        "body": "Fetch pending invite notifications from Overleaf's /notifications API\nExtract the invite token from the notification\nFetch the invite page to get a CSRF token\nPOST to the accept endpoint with the CSRF token"
      },
      {
        "title": "Python snippet",
        "body": "import pyoverleaf\nimport re\n\napi = pyoverleaf.Api()\napi.login_from_browser()\nsession = api._get_session()\n\n# Step 1: Get pending invites\nr = session.get('https://www.overleaf.com/notifications',\n                headers={'Accept': 'application/json'})\nnotifications = r.json()\n\n# Filter for project invites\ninvites = [n for n in notifications\n           if n.get('templateKey') == 'notification_project_invite']\n\nfor invite in invites:\n    opts = invite['messageOpts']\n    project_id = opts['projectId']\n    token = opts['token']\n    project_name = opts['projectName']\n    inviter = opts['userName']\n    print(f\"Invite: '{project_name}' from {inviter}\")\n\n    # Step 2: Get CSRF token from invite page\n    r_page = session.get(\n        f'https://www.overleaf.com/project/{project_id}/invite/token/{token}')\n    csrf_match = re.search(\n        r'name=\"ol-csrfToken\" content=\"([^\"]+)\"', r_page.text)\n    if not csrf_match:\n        print(f\"  Could not find CSRF token, skipping\")\n        continue\n    csrf = csrf_match.group(1)\n\n    # Step 3: Accept the invite\n    r_accept = session.post(\n        f'https://www.overleaf.com/project/{project_id}/invite/token/{token}/accept',\n        headers={\n            'Accept': 'application/json',\n            'Content-Type': 'application/json',\n            'x-csrf-token': csrf,\n        },\n        json={})\n    if r_accept.status_code == 200:\n        print(f\"  ✅ Accepted '{project_name}'\")\n    else:\n        print(f\"  ❌ Failed ({r_accept.status_code})\")"
      },
      {
        "title": "Accept a specific invite by project URL",
        "body": "# Given: https://www.overleaf.com/project/XXXXXXXXXXXXXXXXXXXXXXXX\ntarget_project_id = \"XXXXXXXXXXXXXXXXXXXXXXXX\"\nmatching = [n for n in invites\n            if n['messageOpts']['projectId'] == target_project_id]\n# Then follow steps 2-3 above for the matching invite"
      },
      {
        "title": "Notes",
        "body": "Only works if the user is logged into Overleaf in their browser (cookie auth)\nInvites expire (check the expires field in the notification)\nAfter accepting, the project appears in pyoverleaf ls / api.get_projects()\nFor self-hosted Overleaf, replace www.overleaf.com with your host"
      },
      {
        "title": "Self-hosted Overleaf",
        "body": "# Via env var\nexport PYOVERLEAF_HOST=overleaf.mycompany.com\npyoverleaf ls\n\n# Via flag\npyoverleaf --host overleaf.mycompany.com ls"
      },
      {
        "title": "Troubleshooting",
        "body": "Auth error / websocket error: Open Overleaf in Chrome browser first (open -a \"Google Chrome\" \"https://www.overleaf.com/project\" then wait 5s) to refresh cookies, then retry\n\"scheme https is invalid\" (websocket redirect bug): The default host overleaf.com causes a 301→www.overleaf.com redirect that breaks websocket. Fix: set PYOVERLEAF_HOST=www.overleaf.com:\ncat main.tex | PYOVERLEAF_HOST=www.overleaf.com pyoverleaf write \"Project/main.tex\"\n\n\nKeychain Access Denied (macOS): pyoverleaf needs keychain access to read browser cookies. User must run pyoverleaf ls in their terminal and click \"Always Allow\" on the keychain prompt\nProject not found: Use exact project name (case-sensitive), check with pyoverleaf ls\nPermission denied: User may not have edit access to the project"
      }
    ],
    "body": "Overleaf\n\nCLI tool to interact with Overleaf projects using browser cookies for authentication.\n\nGitHub: https://github.com/jkulhanek/pyoverleaf\n\nRequirements\nPython 3.8+\npyoverleaf (pipx install pyoverleaf)\nUser logged into Overleaf in Chrome/Firefox\nSecurity Considerations\n\n⚠️ Keychain Access Required: pyoverleaf needs \"Always Allow\" keychain access to read browser cookies. This grants the tool access to your browser's cookie storage.\n\nSecurity audit: We have audited pyoverleaf v0.1.7 and found it safe. The codebase is small and readable. Before installing, agents can self-audit the latest version at the GitHub repo above.\n\nAuthentication Setup\n\npyoverleaf authenticates by reading cookies from your browser. The user must:\n\nLog into Overleaf in Chrome or Firefox (visit overleaf.com and sign in)\nGrant keychain access on first run (macOS will prompt for \"Always Allow\")\n# Test auth - user should run this in their terminal first\npyoverleaf ls\n\n\nIf you get auth errors:\n\nAsk user: \"Are you logged into Overleaf in your browser?\"\nIf on macOS: \"Did you approve the keychain access prompt with 'Always Allow'?\"\nUser may need to run pyoverleaf ls manually in terminal to trigger the keychain prompt\n\nNote: The agent cannot log in for the user. Browser authentication must be done by the user directly.\n\nCLI Commands\n# List all projects\npyoverleaf ls\n\n# List files in project\npyoverleaf ls \"Project Name\"\n\n# Read file content\npyoverleaf read \"Project Name/main.tex\"\n\n# Write file (stdin → Overleaf)\ncat local.tex | pyoverleaf write \"Project Name/main.tex\"\n\n# Create directory\npyoverleaf mkdir \"Project Name/figures\"\n\n# Remove file/folder\npyoverleaf rm \"Project Name/old-draft.tex\"\n\n# Download project as zip\npyoverleaf download-project \"Project Name\" output.zip\n\nCommon Workflows\nDownload from Overleaf\npyoverleaf download-project \"Project Name\" /tmp/latest.zip\nunzip -o /tmp/latest.zip -d /tmp/latest\ncp /tmp/latest/main.tex /path/to/local/main.tex\n\nUpload to Overleaf (Python API recommended)\n\nThe CLI write command has websocket issues. Use Python API for reliable uploads:\n\nimport pyoverleaf\n\napi = pyoverleaf.Api()\napi.login_from_browser()\n\n# List projects to get project ID\nfor proj in api.get_projects():\n    print(proj.name, proj.id)\n\n# Upload file (direct overwrite)\nproject_id = \"your_project_id_here\"\nwith open('main.tex', 'rb') as f:\n    content = f.read()\nroot = api.project_get_files(project_id)\napi.project_upload_file(project_id, root.id, \"main.tex\", content)\n\n\nWhy direct overwrite? This method preserves Overleaf's version history. Users can see exactly what changed via Overleaf's History feature, making it easy to review agent edits and revert if needed.\n\nAccept Project Invites\n\nThe agent can accept Overleaf project invitations programmatically using browser cookies — no manual clicking required.\n\nHow it works\nFetch pending invite notifications from Overleaf's /notifications API\nExtract the invite token from the notification\nFetch the invite page to get a CSRF token\nPOST to the accept endpoint with the CSRF token\nPython snippet\nimport pyoverleaf\nimport re\n\napi = pyoverleaf.Api()\napi.login_from_browser()\nsession = api._get_session()\n\n# Step 1: Get pending invites\nr = session.get('https://www.overleaf.com/notifications',\n                headers={'Accept': 'application/json'})\nnotifications = r.json()\n\n# Filter for project invites\ninvites = [n for n in notifications\n           if n.get('templateKey') == 'notification_project_invite']\n\nfor invite in invites:\n    opts = invite['messageOpts']\n    project_id = opts['projectId']\n    token = opts['token']\n    project_name = opts['projectName']\n    inviter = opts['userName']\n    print(f\"Invite: '{project_name}' from {inviter}\")\n\n    # Step 2: Get CSRF token from invite page\n    r_page = session.get(\n        f'https://www.overleaf.com/project/{project_id}/invite/token/{token}')\n    csrf_match = re.search(\n        r'name=\"ol-csrfToken\" content=\"([^\"]+)\"', r_page.text)\n    if not csrf_match:\n        print(f\"  Could not find CSRF token, skipping\")\n        continue\n    csrf = csrf_match.group(1)\n\n    # Step 3: Accept the invite\n    r_accept = session.post(\n        f'https://www.overleaf.com/project/{project_id}/invite/token/{token}/accept',\n        headers={\n            'Accept': 'application/json',\n            'Content-Type': 'application/json',\n            'x-csrf-token': csrf,\n        },\n        json={})\n    if r_accept.status_code == 200:\n        print(f\"  ✅ Accepted '{project_name}'\")\n    else:\n        print(f\"  ❌ Failed ({r_accept.status_code})\")\n\nAccept a specific invite by project URL\n# Given: https://www.overleaf.com/project/XXXXXXXXXXXXXXXXXXXXXXXX\ntarget_project_id = \"XXXXXXXXXXXXXXXXXXXXXXXX\"\nmatching = [n for n in invites\n            if n['messageOpts']['projectId'] == target_project_id]\n# Then follow steps 2-3 above for the matching invite\n\nNotes\nOnly works if the user is logged into Overleaf in their browser (cookie auth)\nInvites expire (check the expires field in the notification)\nAfter accepting, the project appears in pyoverleaf ls / api.get_projects()\nFor self-hosted Overleaf, replace www.overleaf.com with your host\nSelf-hosted Overleaf\n# Via env var\nexport PYOVERLEAF_HOST=overleaf.mycompany.com\npyoverleaf ls\n\n# Via flag\npyoverleaf --host overleaf.mycompany.com ls\n\nTroubleshooting\nAuth error / websocket error: Open Overleaf in Chrome browser first (open -a \"Google Chrome\" \"https://www.overleaf.com/project\" then wait 5s) to refresh cookies, then retry\n\"scheme https is invalid\" (websocket redirect bug): The default host overleaf.com causes a 301→www.overleaf.com redirect that breaks websocket. Fix: set PYOVERLEAF_HOST=www.overleaf.com:\ncat main.tex | PYOVERLEAF_HOST=www.overleaf.com pyoverleaf write \"Project/main.tex\"\n\nKeychain Access Denied (macOS): pyoverleaf needs keychain access to read browser cookies. User must run pyoverleaf ls in their terminal and click \"Always Allow\" on the keychain prompt\nProject not found: Use exact project name (case-sensitive), check with pyoverleaf ls\nPermission denied: User may not have edit access to the project"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/EasonC13/overleaf",
    "publisherUrl": "https://clawhub.ai/EasonC13/overleaf",
    "owner": "EasonC13",
    "version": "1.2.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/overleaf",
    "downloadUrl": "https://openagent3.xyz/downloads/overleaf",
    "agentUrl": "https://openagent3.xyz/skills/overleaf/agent",
    "manifestUrl": "https://openagent3.xyz/skills/overleaf/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/overleaf/agent.md"
  }
}