{
  "schemaVersion": "1.0",
  "item": {
    "slug": "open-lesson",
    "name": "openlesson",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/dncolomer/open-lesson",
    "canonicalUrl": "https://clawhub.ai/dncolomer/open-lesson",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/open-lesson",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=open-lesson",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "requires.env",
      "skill.md"
    ],
    "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. 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. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-05-07T17:22:31.273Z",
      "expiresAt": "2026-05-14T17:22:31.273Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=afrexai-annual-report",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=afrexai-annual-report",
        "contentDisposition": "attachment; filename=\"afrexai-annual-report-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/open-lesson"
    },
    "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/open-lesson",
    "agentPageUrl": "https://openagent3.xyz/skills/open-lesson/agent",
    "manifestUrl": "https://openagent3.xyz/skills/open-lesson/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/open-lesson/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. 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. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "openLesson Agent API Skill",
        "body": "You are an AI agent that can interact with the openLesson tutoring platform via API."
      },
      {
        "title": "Overview",
        "body": "openLesson is a tutoring system that uses audio-based dialogue to help users learn by asking questions rather than giving answers. The platform generates personalized learning plans as directed graphs, where each node is a session. Agents can programmatically generate learning plans, start sessions, and analyze audio chunks for reasoning gaps."
      },
      {
        "title": "Important: No Browser Tool Required",
        "body": "You do not need a browser tool. You only need shell tools (e.g., curl) to make API calls to openLesson."
      },
      {
        "title": "Important: Audio-Only System",
        "body": "CRITICAL: The openLesson platform is audio-only. The analyze endpoint accepts ONLY audio input, NOT text.\n\nAlways convert speech to base64-encoded audio before calling the analyze endpoint\nSupported formats: webm, mp4, ogg\nDo not send text to the analyze endpoint - it will be rejected"
      },
      {
        "title": "Authentication",
        "body": "Include your API key in the Authorization header:\n\nAuthorization: Bearer YOUR_API_KEY\n\nImportant: Always use https://www.openlesson.academy for API calls. The domain openlesson.academy has a redirect that loses the Authorization header.\n\nAPI keys can be generated from the user's dashboard at /dashboard."
      },
      {
        "title": "Credentials",
        "body": "This skill requires an API key for the openLesson API:\n\nEnvironment variable: OPENLESSON_API_KEY\nHow to obtain: Generate from the user's dashboard at /dashboard\nNo calendar access needed: The skill does NOT create actual calendar events. \"Reminders\" means the agent proactively notifies the human when a session is due — this is behavioral, not a technical integration."
      },
      {
        "title": "Session State",
        "body": "Session IDs are stored in-memory for the duration of the conversation. No persistent storage is used or required."
      },
      {
        "title": "Bash Command Patterns",
        "body": "When running API calls as shell commands, use this pattern to avoid JSON escaping issues:"
      },
      {
        "title": "Basic POST with JSON body",
        "body": "bash -c 'printf \"{\\\"topic\\\":\\\"Quantum Computing\\\",\\\"days\\\":60}\" | curl -X POST \"https://www.openlesson.academy/api/agent/plan\" -H \"Authorization: Bearer $OPENLESSON_API_KEY\" -H \"Content-Type: application/json\" --data-binary @-'"
      },
      {
        "title": "With variables",
        "body": "TOPIC=\"Quantum Computing\"\nDAYS=60\nbash -c \"printf '{\\\"topic\\\":\\\"$TOPIC\\\",\\\"days\\\":$DAYS}' | curl -X POST 'https://www.openlesson.academy/api/agent/plan' -H 'Authorization: Bearer $OPENLESSON_API_KEY' -H 'Content-Type: application/json' --data-binary @-\""
      },
      {
        "title": "Start session",
        "body": "bash -c 'printf \"{\\\"plan_node_id\\\":\\\"NODE_UUID\\\",\\\"problem\\\":\\\"Explain neural networks\\\"}\" | curl -X POST \"https://www.openlesson.academy/api/agent/session/start\" -H \"Authorization: Bearer $OPENLESSON_API_KEY\" -H \"Content-Type: application/json\" --data-binary @-'"
      },
      {
        "title": "Analyze audio",
        "body": "bash -c 'printf \"{\\\"session_id\\\":\\\"SESSION_UUID\\\",\\\"audio_base64\\\":\\\"BASE64_DATA\\\",\\\"audio_format\\\":\\\"webm\\\"}\" | curl -X POST \"https://www.openlesson.academy/api/agent/session/analyze\" -H \"Authorization: Bearer $OPENLESSON_API_KEY\" -H \"Content-Type: application/json\" --data-binary @-'"
      },
      {
        "title": "1. Generate Learning Plan",
        "body": "Creates a directed graph of learning sessions for a given topic.\n\nEndpoint: POST /api/agent/plan\n\nRequest:\n\n{\n  \"topic\": \"Machine Learning Fundamentals\",\n  \"days\": 30  // optional: number of days to spread the plan across (default: 30)\n}\n\nResponse:\n\n{\n  \"planId\": \"uuid\",\n  \"topic\": \"Machine Learning Fundamentals\",\n  \"days\": 30,\n  \"nodes\": [\n    {\n      \"id\": \"uuid\",\n      \"title\": \"Introduction to ML\",\n      \"description\": \"Basic concepts and overview\",\n      \"is_start\": true,\n      \"next_node_ids\": [\"uuid2\"],\n      \"status\": \"available\"\n    }\n  ]\n}\n\nDays to Sessions:\n\n7 days: 3-5 sessions\n14 days: 4-7 sessions\n30 days (default): 5-10 sessions\n60 days: 8-14 sessions\n90 days: 10-18 sessions\n180 days: 15-25 sessions"
      },
      {
        "title": "2. Start Session",
        "body": "Starts a new Socratic session.\n\nEndpoint: POST /api/agent/session/start\n\nRequest:\n\n{\n  \"problem\": \"Explain how gradient descent works in neural networks\",\n  \"plan_node_id\": \"uuid-from-plan\"  // optional, links to plan node\n}\n\nResponse:\n\n{\n  \"sessionId\": \"uuid\",\n  \"problem\": \"Explain how gradient descent works...\",\n  \"nodeTitle\": \"Gradient Descent\",\n  \"planId\": \"uuid\",\n  \"status\": \"active\",\n  \"instructions\": {\n    \"audioFormat\": \"webm\",\n    \"submitEndpoint\": \"/api/agent/session/analyze\",\n    \"maxChunkDuration\": 60000\n  }\n}"
      },
      {
        "title": "3. Analyze Audio Chunk",
        "body": "Submits an audio chunk for Socratic analysis. Returns reasoning gap score and follow-up questions.\n\nEndpoint: POST /api/agent/session/analyze\n\nRequest:\n\n{\n  \"session_id\": \"uuid-from-start\",\n  \"audio_base64\": \"base64-encoded-audio-data\",\n  \"audio_format\": \"webm\"\n}\n\nResponse:\n\n{\n  \"sessionId\": \"uuid\",\n  \"gapScore\": 0.7,\n  \"signals\": [\n    \"Missing consideration of local minima\",\n    \"No mention of learning rate impact\"\n  ],\n  \"transcript\": \"transcribed audio...\",\n  \"followUpQuestion\": \"What happens when the gradient becomes very small?\",\n  \"requiresFollowUp\": true\n}"
      },
      {
        "title": "4. End Session",
        "body": "Ends an agent session and generates a summary report.\n\nEndpoint: POST /api/agent/session/end\n\nRequest:\n\n{\n  \"session_id\": \"uuid-from-start\"\n}\n\nResponse:\n\n{\n  \"success\": true,\n  \"sessionId\": \"uuid\",\n  \"message\": \"Session ended and report generated\",\n  \"chunkCount\": 5,\n  \"wordCount\": 1200\n}"
      },
      {
        "title": "5. Get Session Summary",
        "body": "Retrieves the summary report of a completed session.\n\nEndpoint: GET /api/agent/session/summary?session_id=xxx\n\nResponse (if ready):\n\n{\n  \"ready\": true,\n  \"sessionId\": \"uuid\",\n  \"report\": \"# Session Report\\n\\n## Overview\\n...\",\n  \"createdAt\": \"2026-02-24T12:00:00Z\",\n  \"status\": \"completed\"\n}\n\nResponse (if not ready):\n\n{\n  \"ready\": false,\n  \"message\": \"Session report not ready yet. Call /session/end first to generate the report.\",\n  \"sessionId\": \"uuid\",\n  \"status\": \"active\"\n}"
      },
      {
        "title": "Complete Agent Workflow",
        "body": "import base64\nimport requests\n\nAPI_KEY = \"your_api_key\"\nBASE_URL = \"https://openlesson.academy\"\nHEADERS = {\"Authorization\": f\"Bearer {API_KEY}\"}\n\n# Step 1: Generate a learning plan (optional: specify days)\nplan_response = requests.post(\n    f\"{BASE_URL}/api/agent/plan\",\n    json={\n        \"topic\": \"Quantum Computing\",\n        \"days\": 14  # optional: number of days for the plan\n    },\n    headers=HEADERS\n)\nplan = plan_response.json()\n\n# Step 2: Start a session for the first node\nfirst_node = next(n for n in plan[\"nodes\"] if n[\"is_start\"])\nsession_response = requests.post(\n    f\"{BASE_URL}/api/agent/session/start\",\n    json={\"plan_node_id\": first_node[\"id\"], \"problem\": first_node[\"title\"]},\n    headers=HEADERS\n)\nsession = session_response.json()\n\n# Step 3: Record and analyze audio\n# 1. Record audio from user (use browser MediaRecorder or similar)\n# 2. Convert to base64\nwith open(\"audio.webm\", \"rb\") as f:\n    audio_base64 = base64.b64encode(f.read()).decode()\n\nanalyze_response = requests.post(\n    f\"{BASE_URL}/api/agent/session/analyze\",\n    json={\n        \"session_id\": session[\"sessionId\"],\n        \"audio_base64\": audio_base64,\n        \"audio_format\": \"webm\"\n    },\n    headers=HEADERS\n)\nanalysis = analyze_response.json()\n\nprint(f\"Gap Score: {analysis['gapScore']}\")\nprint(f\"Follow-up: {analysis['followUpQuestion']}\")"
      },
      {
        "title": "Error Handling",
        "body": "401: Invalid or inactive API key\n403: Session doesn't belong to this key or wrong endpoint\n404: Session not found\n500: Internal server error"
      },
      {
        "title": "Tips for Agents",
        "body": "Always use audio: The analyze endpoint ONLY accepts audio. Never send text.\nRecord in webm format: This is the preferred format (Opus codec)\nChunk audio: Send 30-60 second chunks for analysis\nFollow up: If requiresFollowUp is true, ask the follow-up question and record response\nTrack gap scores: Use gap score to determine when user has mastered a concept\nUse bash -c for curl: When running API calls in shell scripts, use the bash -c 'printf \"...\" | curl ... --data-binary @-' pattern to avoid JSON escaping issues\nSchedule all sessions: When you generate a learning plan, it is important to schedule all the sessions suggested in the plan for your human. Create calendar events or reminders for each session so they can follow the plan. Always remind your human when a session is due - don't wait for them to ask."
      }
    ],
    "body": "openLesson Agent API Skill\n\nYou are an AI agent that can interact with the openLesson tutoring platform via API.\n\nOverview\n\nopenLesson is a tutoring system that uses audio-based dialogue to help users learn by asking questions rather than giving answers. The platform generates personalized learning plans as directed graphs, where each node is a session. Agents can programmatically generate learning plans, start sessions, and analyze audio chunks for reasoning gaps.\n\nImportant: No Browser Tool Required\n\nYou do not need a browser tool. You only need shell tools (e.g., curl) to make API calls to openLesson.\n\nImportant: Audio-Only System\n\nCRITICAL: The openLesson platform is audio-only. The analyze endpoint accepts ONLY audio input, NOT text.\n\nAlways convert speech to base64-encoded audio before calling the analyze endpoint\nSupported formats: webm, mp4, ogg\nDo not send text to the analyze endpoint - it will be rejected\nAuthentication\n\nInclude your API key in the Authorization header:\n\nAuthorization: Bearer YOUR_API_KEY\n\n\nImportant: Always use https://www.openlesson.academy for API calls. The domain openlesson.academy has a redirect that loses the Authorization header.\n\nAPI keys can be generated from the user's dashboard at /dashboard.\n\nCredentials\n\nThis skill requires an API key for the openLesson API:\n\nEnvironment variable: OPENLESSON_API_KEY\nHow to obtain: Generate from the user's dashboard at /dashboard\nNo calendar access needed: The skill does NOT create actual calendar events. \"Reminders\" means the agent proactively notifies the human when a session is due — this is behavioral, not a technical integration.\nSession State\n\nSession IDs are stored in-memory for the duration of the conversation. No persistent storage is used or required.\n\nBash Command Patterns\n\nWhen running API calls as shell commands, use this pattern to avoid JSON escaping issues:\n\nBasic POST with JSON body\nbash -c 'printf \"{\\\"topic\\\":\\\"Quantum Computing\\\",\\\"days\\\":60}\" | curl -X POST \"https://www.openlesson.academy/api/agent/plan\" -H \"Authorization: Bearer $OPENLESSON_API_KEY\" -H \"Content-Type: application/json\" --data-binary @-'\n\nWith variables\nTOPIC=\"Quantum Computing\"\nDAYS=60\nbash -c \"printf '{\\\"topic\\\":\\\"$TOPIC\\\",\\\"days\\\":$DAYS}' | curl -X POST 'https://www.openlesson.academy/api/agent/plan' -H 'Authorization: Bearer $OPENLESSON_API_KEY' -H 'Content-Type: application/json' --data-binary @-\"\n\nStart session\nbash -c 'printf \"{\\\"plan_node_id\\\":\\\"NODE_UUID\\\",\\\"problem\\\":\\\"Explain neural networks\\\"}\" | curl -X POST \"https://www.openlesson.academy/api/agent/session/start\" -H \"Authorization: Bearer $OPENLESSON_API_KEY\" -H \"Content-Type: application/json\" --data-binary @-'\n\nAnalyze audio\nbash -c 'printf \"{\\\"session_id\\\":\\\"SESSION_UUID\\\",\\\"audio_base64\\\":\\\"BASE64_DATA\\\",\\\"audio_format\\\":\\\"webm\\\"}\" | curl -X POST \"https://www.openlesson.academy/api/agent/session/analyze\" -H \"Authorization: Bearer $OPENLESSON_API_KEY\" -H \"Content-Type: application/json\" --data-binary @-'\n\nEndpoints\n1. Generate Learning Plan\n\nCreates a directed graph of learning sessions for a given topic.\n\nEndpoint: POST /api/agent/plan\n\nRequest:\n\n{\n  \"topic\": \"Machine Learning Fundamentals\",\n  \"days\": 30  // optional: number of days to spread the plan across (default: 30)\n}\n\n\nResponse:\n\n{\n  \"planId\": \"uuid\",\n  \"topic\": \"Machine Learning Fundamentals\",\n  \"days\": 30,\n  \"nodes\": [\n    {\n      \"id\": \"uuid\",\n      \"title\": \"Introduction to ML\",\n      \"description\": \"Basic concepts and overview\",\n      \"is_start\": true,\n      \"next_node_ids\": [\"uuid2\"],\n      \"status\": \"available\"\n    }\n  ]\n}\n\n\nDays to Sessions:\n\n7 days: 3-5 sessions\n14 days: 4-7 sessions\n30 days (default): 5-10 sessions\n60 days: 8-14 sessions\n90 days: 10-18 sessions\n180 days: 15-25 sessions\n2. Start Session\n\nStarts a new Socratic session.\n\nEndpoint: POST /api/agent/session/start\n\nRequest:\n\n{\n  \"problem\": \"Explain how gradient descent works in neural networks\",\n  \"plan_node_id\": \"uuid-from-plan\"  // optional, links to plan node\n}\n\n\nResponse:\n\n{\n  \"sessionId\": \"uuid\",\n  \"problem\": \"Explain how gradient descent works...\",\n  \"nodeTitle\": \"Gradient Descent\",\n  \"planId\": \"uuid\",\n  \"status\": \"active\",\n  \"instructions\": {\n    \"audioFormat\": \"webm\",\n    \"submitEndpoint\": \"/api/agent/session/analyze\",\n    \"maxChunkDuration\": 60000\n  }\n}\n\n3. Analyze Audio Chunk\n\nSubmits an audio chunk for Socratic analysis. Returns reasoning gap score and follow-up questions.\n\nEndpoint: POST /api/agent/session/analyze\n\nRequest:\n\n{\n  \"session_id\": \"uuid-from-start\",\n  \"audio_base64\": \"base64-encoded-audio-data\",\n  \"audio_format\": \"webm\"\n}\n\n\nResponse:\n\n{\n  \"sessionId\": \"uuid\",\n  \"gapScore\": 0.7,\n  \"signals\": [\n    \"Missing consideration of local minima\",\n    \"No mention of learning rate impact\"\n  ],\n  \"transcript\": \"transcribed audio...\",\n  \"followUpQuestion\": \"What happens when the gradient becomes very small?\",\n  \"requiresFollowUp\": true\n}\n\n4. End Session\n\nEnds an agent session and generates a summary report.\n\nEndpoint: POST /api/agent/session/end\n\nRequest:\n\n{\n  \"session_id\": \"uuid-from-start\"\n}\n\n\nResponse:\n\n{\n  \"success\": true,\n  \"sessionId\": \"uuid\",\n  \"message\": \"Session ended and report generated\",\n  \"chunkCount\": 5,\n  \"wordCount\": 1200\n}\n\n5. Get Session Summary\n\nRetrieves the summary report of a completed session.\n\nEndpoint: GET /api/agent/session/summary?session_id=xxx\n\nResponse (if ready):\n\n{\n  \"ready\": true,\n  \"sessionId\": \"uuid\",\n  \"report\": \"# Session Report\\n\\n## Overview\\n...\",\n  \"createdAt\": \"2026-02-24T12:00:00Z\",\n  \"status\": \"completed\"\n}\n\n\nResponse (if not ready):\n\n{\n  \"ready\": false,\n  \"message\": \"Session report not ready yet. Call /session/end first to generate the report.\",\n  \"sessionId\": \"uuid\",\n  \"status\": \"active\"\n}\n\nComplete Agent Workflow\nimport base64\nimport requests\n\nAPI_KEY = \"your_api_key\"\nBASE_URL = \"https://openlesson.academy\"\nHEADERS = {\"Authorization\": f\"Bearer {API_KEY}\"}\n\n# Step 1: Generate a learning plan (optional: specify days)\nplan_response = requests.post(\n    f\"{BASE_URL}/api/agent/plan\",\n    json={\n        \"topic\": \"Quantum Computing\",\n        \"days\": 14  # optional: number of days for the plan\n    },\n    headers=HEADERS\n)\nplan = plan_response.json()\n\n# Step 2: Start a session for the first node\nfirst_node = next(n for n in plan[\"nodes\"] if n[\"is_start\"])\nsession_response = requests.post(\n    f\"{BASE_URL}/api/agent/session/start\",\n    json={\"plan_node_id\": first_node[\"id\"], \"problem\": first_node[\"title\"]},\n    headers=HEADERS\n)\nsession = session_response.json()\n\n# Step 3: Record and analyze audio\n# 1. Record audio from user (use browser MediaRecorder or similar)\n# 2. Convert to base64\nwith open(\"audio.webm\", \"rb\") as f:\n    audio_base64 = base64.b64encode(f.read()).decode()\n\nanalyze_response = requests.post(\n    f\"{BASE_URL}/api/agent/session/analyze\",\n    json={\n        \"session_id\": session[\"sessionId\"],\n        \"audio_base64\": audio_base64,\n        \"audio_format\": \"webm\"\n    },\n    headers=HEADERS\n)\nanalysis = analyze_response.json()\n\nprint(f\"Gap Score: {analysis['gapScore']}\")\nprint(f\"Follow-up: {analysis['followUpQuestion']}\")\n\nError Handling\n401: Invalid or inactive API key\n403: Session doesn't belong to this key or wrong endpoint\n404: Session not found\n500: Internal server error\nTips for Agents\nAlways use audio: The analyze endpoint ONLY accepts audio. Never send text.\nRecord in webm format: This is the preferred format (Opus codec)\nChunk audio: Send 30-60 second chunks for analysis\nFollow up: If requiresFollowUp is true, ask the follow-up question and record response\nTrack gap scores: Use gap score to determine when user has mastered a concept\nUse bash -c for curl: When running API calls in shell scripts, use the bash -c 'printf \"...\" | curl ... --data-binary @-' pattern to avoid JSON escaping issues\nSchedule all sessions: When you generate a learning plan, it is important to schedule all the sessions suggested in the plan for your human. Create calendar events or reminders for each session so they can follow the plan. Always remind your human when a session is due - don't wait for them to ask."
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/dncolomer/open-lesson",
    "publisherUrl": "https://clawhub.ai/dncolomer/open-lesson",
    "owner": "dncolomer",
    "version": "1.0.2",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/open-lesson",
    "downloadUrl": "https://openagent3.xyz/downloads/open-lesson",
    "agentUrl": "https://openagent3.xyz/skills/open-lesson/agent",
    "manifestUrl": "https://openagent3.xyz/skills/open-lesson/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/open-lesson/agent.md"
  }
}