{
  "schemaVersion": "1.0",
  "item": {
    "slug": "localsend",
    "name": "Localsend",
    "source": "tencent",
    "type": "skill",
    "category": "通讯协作",
    "sourceUrl": "https://clawhub.ai/Chordlini/localsend",
    "canonicalUrl": "https://clawhub.ai/Chordlini/localsend",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/localsend",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=localsend",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md",
      "references/protocol.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-04-23T16:43:11.935Z",
      "expiresAt": "2026-04-30T16:43:11.935Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=4claw-imageboard",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=4claw-imageboard",
        "contentDisposition": "attachment; filename=\"4claw-imageboard-1.0.1.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/localsend"
    },
    "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/localsend",
    "agentPageUrl": "https://openagent3.xyz/skills/localsend/agent",
    "manifestUrl": "https://openagent3.xyz/skills/localsend/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/localsend/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": "LocalSend",
        "body": "Interactive file transfer between devices on the local network using real Telegram inline keyboard buttons. Works with any device running the LocalSend app (Android, iOS, Windows, macOS, Linux)."
      },
      {
        "title": "Install",
        "body": "The localsend-cli is a zero-dependency Python CLI. Install from GitHub:\n\ncurl -fsSL https://raw.githubusercontent.com/Chordlini/localsend-cli/master/localsend-cli -o ~/.local/bin/localsend-cli\nchmod +x ~/.local/bin/localsend-cli\n\nFull docs: https://github.com/Chordlini/localsend-cli\n\nRequires Python 3.8+ and openssl (for TLS)."
      },
      {
        "title": "Telegram Button Format",
        "body": "All menus MUST use OpenClaw's inline button format. Send buttons alongside your message using this structure:\n\nbuttons: [\n  [{ \"text\": \"Label\", \"callback_data\": \"ls:action\" }],\n  [{ \"text\": \"Row 2\", \"callback_data\": \"ls:other\" }]\n]\n\nOuter array = rows of buttons\nInner array = buttons per row (max 3 per row for readability)\nPrefix all callback_data with ls: to namespace this skill\nWhen user taps a button, you receive: callback_data: ls:action"
      },
      {
        "title": "State Awareness (CRITICAL)",
        "body": "This skill uses conversational state. Track where you are in the flow:\n\nStateMeaningNext user input should be treated as...idleNo active flowNormal message — respond normallyawaiting_fileAsked user to drop/specify a file to sendThe file to send — do NOT comment on it, describe it, or react to it. Immediately use it as the send payload.awaiting_textAsked user to type text to sendThe text payload — send it, don't discuss itawaiting_confirmWaiting for send confirmationExpect ls:confirm-send or ls:menureceivingReceiver is activeMonitor for incoming files\n\nRULES:\n\nWhen in awaiting_file state and user sends an image/file/path → treat it as the file to send. Show confirmation buttons immediately.\nWhen in awaiting_text state and user types anything → treat it as the text to send.\nNEVER comment on, describe, or react to a file/image when you're in awaiting_file state.\nState resets to idle when user taps ls:menu or the flow completes."
      },
      {
        "title": "On Trigger: Main Menu",
        "body": "When the user types /localsend or mentions sending/receiving files locally, send this message with real inline buttons:\n\nMessage:\n\n📡 LocalSend — File Transfer\n\nButtons:\n\nbuttons: [\n  [\n    { \"text\": \"📤 Send\", \"callback_data\": \"ls:send\" },\n    { \"text\": \"📥 Receive\", \"callback_data\": \"ls:receive\" }\n  ],\n  [\n    { \"text\": \"🔍 Scan Devices\", \"callback_data\": \"ls:devices\" }\n  ]\n]\n\nDo NOT run any commands yet. Wait for the button tap."
      },
      {
        "title": "Flow: Scan Devices",
        "body": "Trigger: callback_data: ls:devices or user says \"scan\", \"discover\", \"find devices\"\n\nRun:\nlocalsend-cli discover --json -t 2\n\n\n\nDevices found — create one button per device, plus Refresh and Back:\nMessage:\n📡 Found 3 devices:\n\nButtons (one device per row):\nbuttons: [\n  [{ \"text\": \"📱 Fast Potato — 192.168.0.148\", \"callback_data\": \"ls:dev:Fast Potato\" }],\n  [{ \"text\": \"💻 Rami-Desktop — 192.168.0.100\", \"callback_data\": \"ls:dev:Rami-Desktop\" }],\n  [{ \"text\": \"🖥️ Living Room PC — 192.168.0.105\", \"callback_data\": \"ls:dev:Living Room PC\" }],\n  [\n    { \"text\": \"🔄 Refresh\", \"callback_data\": \"ls:devices\" },\n    { \"text\": \"⬅️ Back\", \"callback_data\": \"ls:menu\" }\n  ]\n]\n\n\n\nNo devices found:\nMessage:\n📡 No devices found.\nMake sure LocalSend is open on the other device and both are on the same WiFi.\n\nButtons:\nbuttons: [\n  [\n    { \"text\": \"🔄 Try Again\", \"callback_data\": \"ls:devices\" },\n    { \"text\": \"⬅️ Back\", \"callback_data\": \"ls:menu\" }\n  ]\n]\n\n\n\nUser taps a device (callback_data: ls:dev:DEVICENAME) — store it as the selected target. Show action menu:\nMessage:\n✅ Selected: Fast Potato (192.168.0.148)\nWhat do you want to do?\n\nButtons:\nbuttons: [\n  [\n    { \"text\": \"📄 Send File\", \"callback_data\": \"ls:sendfile\" },\n    { \"text\": \"📝 Send Text\", \"callback_data\": \"ls:sendtext\" }\n  ],\n  [\n    { \"text\": \"📦 Send Multiple\", \"callback_data\": \"ls:sendmulti\" },\n    { \"text\": \"⬅️ Back\", \"callback_data\": \"ls:devices\" }\n  ]\n]"
      },
      {
        "title": "Flow: Send",
        "body": "Trigger: callback_data: ls:send"
      },
      {
        "title": "Step 1 — Pick target device (if not already selected)",
        "body": "Run discover and show device picker (see Scan Devices flow above)."
      },
      {
        "title": "Step 2 — Choose what to send",
        "body": "Message:\n\nSend to Fast Potato:\n\nButtons:\n\nbuttons: [\n  [\n    { \"text\": \"📄 Send File\", \"callback_data\": \"ls:sendfile\" },\n    { \"text\": \"📝 Send Text\", \"callback_data\": \"ls:sendtext\" }\n  ],\n  [\n    { \"text\": \"📦 Send Multiple\", \"callback_data\": \"ls:sendmulti\" },\n    { \"text\": \"⬅️ Back\", \"callback_data\": \"ls:menu\" }\n  ]\n]"
      },
      {
        "title": "Send File (callback_data: ls:sendfile)",
        "body": "Ask: \"Send me the file, drop a path, or tell me which file to send\"\n\n\nUser provides file path or sends a file via chat\n\n\nGet file size with stat or ls -lh\n\n\nConfirm with buttons:\nMessage:\n📤 Send to Fast Potato?\n📄 project.zip — 4.2 MB\n\nButtons:\nbuttons: [\n  [\n    { \"text\": \"✅ Send\", \"callback_data\": \"ls:confirm-send\" },\n    { \"text\": \"❌ Cancel\", \"callback_data\": \"ls:menu\" }\n  ]\n]\n\n\n\nOn confirm, run:\nlocalsend-cli send --to \"Fast Potato\" /path/to/project.zip\n\n\n\nReport result:\nMessage:\n✅ Sent project.zip (4.2 MB) to Fast Potato\n\nButtons:\nbuttons: [\n  [\n    { \"text\": \"📤 Send Another\", \"callback_data\": \"ls:send\" },\n    { \"text\": \"⬅️ Menu\", \"callback_data\": \"ls:menu\" }\n  ]\n]"
      },
      {
        "title": "Send Text (callback_data: ls:sendtext)",
        "body": "Ask: \"Type the text you want to send:\"\n\n\nUser types their message\n\n\nWrite text to temp file, send:\necho \"user's text\" > /tmp/localsend-text.txt\nlocalsend-cli send --to \"Fast Potato\" /tmp/localsend-text.txt\nrm /tmp/localsend-text.txt\n\n\n\nConfirm:\nMessage:\n✅ Text sent to Fast Potato\n\nButtons:\nbuttons: [\n  [\n    { \"text\": \"📝 Send More Text\", \"callback_data\": \"ls:sendtext\" },\n    { \"text\": \"📤 Send File\", \"callback_data\": \"ls:sendfile\" }\n  ],\n  [{ \"text\": \"⬅️ Menu\", \"callback_data\": \"ls:menu\" }]\n]"
      },
      {
        "title": "Send Multiple (callback_data: ls:sendmulti)",
        "body": "Ask: \"List the files or give me a glob pattern (e.g. ~/Screenshots/*.png)\"\n\n\nUser provides paths or pattern\n\n\nExpand glob, list files with sizes:\nMessage:\n📦 Send 5 files to Fast Potato?\n📄 photo1.jpg — 2.1 MB\n📄 photo2.jpg — 1.8 MB\n📄 photo3.jpg — 3.2 MB\n📄 photo4.jpg — 2.5 MB\n📄 photo5.jpg — 1.9 MB\n📊 Total: 11.5 MB\n\nButtons:\nbuttons: [\n  [\n    { \"text\": \"✅ Send All\", \"callback_data\": \"ls:confirm-send\" },\n    { \"text\": \"❌ Cancel\", \"callback_data\": \"ls:menu\" }\n  ]\n]\n\n\n\nOn confirm, run:\nlocalsend-cli send --to \"Fast Potato\" photo1.jpg photo2.jpg photo3.jpg photo4.jpg photo5.jpg\n\n\n\nReport:\nMessage:\n✅ Sent 5 files (11.5 MB) to Fast Potato\n\nButtons:\nbuttons: [\n  [\n    { \"text\": \"📤 Send More\", \"callback_data\": \"ls:send\" },\n    { \"text\": \"⬅️ Menu\", \"callback_data\": \"ls:menu\" }\n  ]\n]"
      },
      {
        "title": "Flow: Receive",
        "body": "Trigger: callback_data: ls:receive or user says \"receive\", \"start receiving\", \"listen\""
      },
      {
        "title": "Step 1 — Snapshot current files",
        "body": "ls -1 /home/rami/.openclaw/workspace/_incoming/ > /tmp/localsend-before.txt"
      },
      {
        "title": "Step 2 — Start receiver in background",
        "body": "localsend-cli --alias openclaw-workspace receive --save-dir /home/rami/.openclaw/workspace/_incoming/ -y\n\nRun with run_in_background: true. Store the task ID.\n\nCRITICAL: --alias MUST come BEFORE receive (global flag)."
      },
      {
        "title": "Step 3 — Confirm ready with buttons",
        "body": "Message:\n\n📡 Receiver active — \"openclaw-workspace\"\n📁 Saving to: ~/incoming/\n✅ Auto-accept: ON\n\nSend files from your device whenever ready.\n\nButtons:\n\nbuttons: [\n  [\n    { \"text\": \"🛑 Stop\", \"callback_data\": \"ls:stop\" },\n    { \"text\": \"🔄 Status\", \"callback_data\": \"ls:status\" }\n  ]\n]"
      },
      {
        "title": "Step 4 — Monitor for incoming files",
        "body": "Poll every 3 seconds for new files:\n\nls -1 /home/rami/.openclaw/workspace/_incoming/ > /tmp/localsend-after.txt\ndiff /tmp/localsend-before.txt /tmp/localsend-after.txt"
      },
      {
        "title": "Step 5 — Post-receive confirmation (MANDATORY)",
        "body": "When file(s) arrive, immediately present in chat with inline buttons.\n\nSingle file:\n\nMessage:\n\n✅ Received from Fast Potato:\n📄 portfolio.zip — 240 MB\n📁 Saved to: ~/incoming/portfolio.zip\n\nButtons (contextual by file type):\n\nbuttons: [\n  [\n    { \"text\": \"📂 Extract\", \"callback_data\": \"ls:extract\" },\n    { \"text\": \"🚀 Deploy\", \"callback_data\": \"ls:deploy\" }\n  ],\n  [\n    { \"text\": \"📥 Receive More\", \"callback_data\": \"ls:receive\" },\n    { \"text\": \"🛑 Stop\", \"callback_data\": \"ls:stop\" }\n  ]\n]\n\nImage file — show inline preview:\n\nMessage:\n\n✅ Received from Fast Potato:\n🖼️ screenshot.png — 2.1 MB\n\nInclude MEDIA:~/incoming/screenshot.png for inline preview.\n\nButtons:\n\nbuttons: [\n  [\n    { \"text\": \"📂 Open Folder\", \"callback_data\": \"ls:openfolder\" },\n    { \"text\": \"📥 Receive More\", \"callback_data\": \"ls:receive\" }\n  ],\n  [{ \"text\": \"🛑 Stop\", \"callback_data\": \"ls:stop\" }]\n]\n\nMultiple files:\n\nMessage:\n\n✅ Received 3 files from Fast Potato:\n📄 app.apk — 45 MB\n📄 README.md — 2 KB\n🖼️ icon.png — 128 KB\n📊 Total: 45.1 MB\n\nButtons:\n\nbuttons: [\n  [\n    { \"text\": \"📂 Show All\", \"callback_data\": \"ls:showall\" },\n    { \"text\": \"📥 Receive More\", \"callback_data\": \"ls:receive\" }\n  ],\n  [{ \"text\": \"🛑 Stop\", \"callback_data\": \"ls:stop\" }]\n]\n\nContextual button rules by file type:\n\n.zip, .tar.gz → add 📂 Extract button\n.png, .jpg, .gif, .webp → show MEDIA: inline + 📂 Open Folder\n.apk → add 📱 Install button\n.html, .js, .py → add 👁️ Preview button\nwebsite archives → add 🚀 Deploy button"
      },
      {
        "title": "Step 6 — Stop receiver",
        "body": "Trigger: callback_data: ls:stop\n\nKill the background task using stored task ID\n\n\nConfirm:\nMessage:\n🛑 Receiver stopped.\n\nButtons:\nbuttons: [\n  [\n    { \"text\": \"📡 Restart\", \"callback_data\": \"ls:receive\" },\n    { \"text\": \"⬅️ Menu\", \"callback_data\": \"ls:menu\" }\n  ]\n]"
      },
      {
        "title": "Flow: Status Check",
        "body": "Trigger: callback_data: ls:status\n\nCheck if receiver is running and count new files:\n\nls -1 /home/rami/.openclaw/workspace/_incoming/ > /tmp/localsend-after.txt\ndiff /tmp/localsend-before.txt /tmp/localsend-after.txt | grep \"^>\" | wc -l\n\nMessage:\n\n📡 Receiver: Running (12 min)\n📁 Files received: 2\n📊 Total: 242 MB\n\nButtons:\n\nbuttons: [\n  [\n    { \"text\": \"🛑 Stop\", \"callback_data\": \"ls:stop\" },\n    { \"text\": \"📂 Show Files\", \"callback_data\": \"ls:showall\" }\n  ]\n]"
      },
      {
        "title": "Callback Data Reference",
        "body": "callback_dataActionls:menuShow main menuls:sendStart send flowls:receiveStart receive flowls:devicesDiscover devicesls:dev:DEVICENAMESelect a specific devicels:sendfileSend single filels:sendtextSend text messagels:sendmultiSend multiple filesls:confirm-sendConfirm and execute sendls:stopStop receiverls:statusCheck receiver statusls:extractExtract received archivels:deployDeploy received websitels:openfolderOpen save directoryls:showallList all received files"
      },
      {
        "title": "CLI Reference",
        "body": "CommandUsageDiscoverlocalsend-cli discover --json -t 2Sendlocalsend-cli send --to \"DEVICE\" file1 file2 ...Receivelocalsend-cli --alias NAME receive --save-dir DIR -y\n\nFlagScopeDescription--alias NAMEGlobal (before subcommand)Device name to advertise--to NAMEsendTarget device (case-insensitive substring)-t NdiscoverScan duration in seconds (use 2 for speed)--jsondiscoverMachine-readable output--save-dir DIRreceiveSave location (default: ~/Downloads)-yreceiveAuto-accept transfers"
      },
      {
        "title": "Troubleshooting",
        "body": "ProblemFixunrecognized arguments: --aliasMove --alias BEFORE the subcommandNo devices foundOpen LocalSend on target, same WiFi, screen onPort 53317 in useNormal — CLI auto-falls back to 53318/53319Transfer declined (403)Use -y on receiver sideTransfer hangsLarge file on slow WiFi — be patient"
      },
      {
        "title": "Reference",
        "body": "CLI repo & docs: https://github.com/Chordlini/localsend-cli\nLocalSend protocol: references/protocol.md or https://github.com/localsend/protocol"
      }
    ],
    "body": "LocalSend\n\nInteractive file transfer between devices on the local network using real Telegram inline keyboard buttons. Works with any device running the LocalSend app (Android, iOS, Windows, macOS, Linux).\n\nInstall\n\nThe localsend-cli is a zero-dependency Python CLI. Install from GitHub:\n\ncurl -fsSL https://raw.githubusercontent.com/Chordlini/localsend-cli/master/localsend-cli -o ~/.local/bin/localsend-cli\nchmod +x ~/.local/bin/localsend-cli\n\n\nFull docs: https://github.com/Chordlini/localsend-cli\n\nRequires Python 3.8+ and openssl (for TLS).\n\nTelegram Button Format\n\nAll menus MUST use OpenClaw's inline button format. Send buttons alongside your message using this structure:\n\nbuttons: [\n  [{ \"text\": \"Label\", \"callback_data\": \"ls:action\" }],\n  [{ \"text\": \"Row 2\", \"callback_data\": \"ls:other\" }]\n]\n\nOuter array = rows of buttons\nInner array = buttons per row (max 3 per row for readability)\nPrefix all callback_data with ls: to namespace this skill\nWhen user taps a button, you receive: callback_data: ls:action\nState Awareness (CRITICAL)\n\nThis skill uses conversational state. Track where you are in the flow:\n\nState\tMeaning\tNext user input should be treated as...\nidle\tNo active flow\tNormal message — respond normally\nawaiting_file\tAsked user to drop/specify a file to send\tThe file to send — do NOT comment on it, describe it, or react to it. Immediately use it as the send payload.\nawaiting_text\tAsked user to type text to send\tThe text payload — send it, don't discuss it\nawaiting_confirm\tWaiting for send confirmation\tExpect ls:confirm-send or ls:menu\nreceiving\tReceiver is active\tMonitor for incoming files\n\nRULES:\n\nWhen in awaiting_file state and user sends an image/file/path → treat it as the file to send. Show confirmation buttons immediately.\nWhen in awaiting_text state and user types anything → treat it as the text to send.\nNEVER comment on, describe, or react to a file/image when you're in awaiting_file state.\nState resets to idle when user taps ls:menu or the flow completes.\nOn Trigger: Main Menu\n\nWhen the user types /localsend or mentions sending/receiving files locally, send this message with real inline buttons:\n\nMessage:\n\n📡 LocalSend — File Transfer\n\n\nButtons:\n\nbuttons: [\n  [\n    { \"text\": \"📤 Send\", \"callback_data\": \"ls:send\" },\n    { \"text\": \"📥 Receive\", \"callback_data\": \"ls:receive\" }\n  ],\n  [\n    { \"text\": \"🔍 Scan Devices\", \"callback_data\": \"ls:devices\" }\n  ]\n]\n\n\nDo NOT run any commands yet. Wait for the button tap.\n\nFlow: Scan Devices\n\nTrigger: callback_data: ls:devices or user says \"scan\", \"discover\", \"find devices\"\n\nRun:\n\nlocalsend-cli discover --json -t 2\n\n\nDevices found — create one button per device, plus Refresh and Back:\n\nMessage:\n\n📡 Found 3 devices:\n\n\nButtons (one device per row):\n\nbuttons: [\n  [{ \"text\": \"📱 Fast Potato — 192.168.0.148\", \"callback_data\": \"ls:dev:Fast Potato\" }],\n  [{ \"text\": \"💻 Rami-Desktop — 192.168.0.100\", \"callback_data\": \"ls:dev:Rami-Desktop\" }],\n  [{ \"text\": \"🖥️ Living Room PC — 192.168.0.105\", \"callback_data\": \"ls:dev:Living Room PC\" }],\n  [\n    { \"text\": \"🔄 Refresh\", \"callback_data\": \"ls:devices\" },\n    { \"text\": \"⬅️ Back\", \"callback_data\": \"ls:menu\" }\n  ]\n]\n\n\nNo devices found:\n\nMessage:\n\n📡 No devices found.\nMake sure LocalSend is open on the other device and both are on the same WiFi.\n\n\nButtons:\n\nbuttons: [\n  [\n    { \"text\": \"🔄 Try Again\", \"callback_data\": \"ls:devices\" },\n    { \"text\": \"⬅️ Back\", \"callback_data\": \"ls:menu\" }\n  ]\n]\n\n\nUser taps a device (callback_data: ls:dev:DEVICENAME) — store it as the selected target. Show action menu:\n\nMessage:\n\n✅ Selected: Fast Potato (192.168.0.148)\nWhat do you want to do?\n\n\nButtons:\n\nbuttons: [\n  [\n    { \"text\": \"📄 Send File\", \"callback_data\": \"ls:sendfile\" },\n    { \"text\": \"📝 Send Text\", \"callback_data\": \"ls:sendtext\" }\n  ],\n  [\n    { \"text\": \"📦 Send Multiple\", \"callback_data\": \"ls:sendmulti\" },\n    { \"text\": \"⬅️ Back\", \"callback_data\": \"ls:devices\" }\n  ]\n]\n\nFlow: Send\n\nTrigger: callback_data: ls:send\n\nStep 1 — Pick target device (if not already selected)\n\nRun discover and show device picker (see Scan Devices flow above).\n\nStep 2 — Choose what to send\n\nMessage:\n\nSend to Fast Potato:\n\n\nButtons:\n\nbuttons: [\n  [\n    { \"text\": \"📄 Send File\", \"callback_data\": \"ls:sendfile\" },\n    { \"text\": \"📝 Send Text\", \"callback_data\": \"ls:sendtext\" }\n  ],\n  [\n    { \"text\": \"📦 Send Multiple\", \"callback_data\": \"ls:sendmulti\" },\n    { \"text\": \"⬅️ Back\", \"callback_data\": \"ls:menu\" }\n  ]\n]\n\nSend File (callback_data: ls:sendfile)\n\nAsk: \"Send me the file, drop a path, or tell me which file to send\"\n\nUser provides file path or sends a file via chat\n\nGet file size with stat or ls -lh\n\nConfirm with buttons:\n\nMessage:\n\n📤 Send to Fast Potato?\n📄 project.zip — 4.2 MB\n\n\nButtons:\n\nbuttons: [\n  [\n    { \"text\": \"✅ Send\", \"callback_data\": \"ls:confirm-send\" },\n    { \"text\": \"❌ Cancel\", \"callback_data\": \"ls:menu\" }\n  ]\n]\n\n\nOn confirm, run:\n\nlocalsend-cli send --to \"Fast Potato\" /path/to/project.zip\n\n\nReport result:\n\nMessage:\n\n✅ Sent project.zip (4.2 MB) to Fast Potato\n\n\nButtons:\n\nbuttons: [\n  [\n    { \"text\": \"📤 Send Another\", \"callback_data\": \"ls:send\" },\n    { \"text\": \"⬅️ Menu\", \"callback_data\": \"ls:menu\" }\n  ]\n]\n\nSend Text (callback_data: ls:sendtext)\n\nAsk: \"Type the text you want to send:\"\n\nUser types their message\n\nWrite text to temp file, send:\n\necho \"user's text\" > /tmp/localsend-text.txt\nlocalsend-cli send --to \"Fast Potato\" /tmp/localsend-text.txt\nrm /tmp/localsend-text.txt\n\n\nConfirm:\n\nMessage:\n\n✅ Text sent to Fast Potato\n\n\nButtons:\n\nbuttons: [\n  [\n    { \"text\": \"📝 Send More Text\", \"callback_data\": \"ls:sendtext\" },\n    { \"text\": \"📤 Send File\", \"callback_data\": \"ls:sendfile\" }\n  ],\n  [{ \"text\": \"⬅️ Menu\", \"callback_data\": \"ls:menu\" }]\n]\n\nSend Multiple (callback_data: ls:sendmulti)\n\nAsk: \"List the files or give me a glob pattern (e.g. ~/Screenshots/*.png)\"\n\nUser provides paths or pattern\n\nExpand glob, list files with sizes:\n\nMessage:\n\n📦 Send 5 files to Fast Potato?\n📄 photo1.jpg — 2.1 MB\n📄 photo2.jpg — 1.8 MB\n📄 photo3.jpg — 3.2 MB\n📄 photo4.jpg — 2.5 MB\n📄 photo5.jpg — 1.9 MB\n📊 Total: 11.5 MB\n\n\nButtons:\n\nbuttons: [\n  [\n    { \"text\": \"✅ Send All\", \"callback_data\": \"ls:confirm-send\" },\n    { \"text\": \"❌ Cancel\", \"callback_data\": \"ls:menu\" }\n  ]\n]\n\n\nOn confirm, run:\n\nlocalsend-cli send --to \"Fast Potato\" photo1.jpg photo2.jpg photo3.jpg photo4.jpg photo5.jpg\n\n\nReport:\n\nMessage:\n\n✅ Sent 5 files (11.5 MB) to Fast Potato\n\n\nButtons:\n\nbuttons: [\n  [\n    { \"text\": \"📤 Send More\", \"callback_data\": \"ls:send\" },\n    { \"text\": \"⬅️ Menu\", \"callback_data\": \"ls:menu\" }\n  ]\n]\n\nFlow: Receive\n\nTrigger: callback_data: ls:receive or user says \"receive\", \"start receiving\", \"listen\"\n\nStep 1 — Snapshot current files\nls -1 /home/rami/.openclaw/workspace/_incoming/ > /tmp/localsend-before.txt\n\nStep 2 — Start receiver in background\nlocalsend-cli --alias openclaw-workspace receive --save-dir /home/rami/.openclaw/workspace/_incoming/ -y\n\n\nRun with run_in_background: true. Store the task ID.\n\nCRITICAL: --alias MUST come BEFORE receive (global flag).\n\nStep 3 — Confirm ready with buttons\n\nMessage:\n\n📡 Receiver active — \"openclaw-workspace\"\n📁 Saving to: ~/incoming/\n✅ Auto-accept: ON\n\nSend files from your device whenever ready.\n\n\nButtons:\n\nbuttons: [\n  [\n    { \"text\": \"🛑 Stop\", \"callback_data\": \"ls:stop\" },\n    { \"text\": \"🔄 Status\", \"callback_data\": \"ls:status\" }\n  ]\n]\n\nStep 4 — Monitor for incoming files\n\nPoll every 3 seconds for new files:\n\nls -1 /home/rami/.openclaw/workspace/_incoming/ > /tmp/localsend-after.txt\ndiff /tmp/localsend-before.txt /tmp/localsend-after.txt\n\nStep 5 — Post-receive confirmation (MANDATORY)\n\nWhen file(s) arrive, immediately present in chat with inline buttons.\n\nSingle file:\n\nMessage:\n\n✅ Received from Fast Potato:\n📄 portfolio.zip — 240 MB\n📁 Saved to: ~/incoming/portfolio.zip\n\n\nButtons (contextual by file type):\n\nbuttons: [\n  [\n    { \"text\": \"📂 Extract\", \"callback_data\": \"ls:extract\" },\n    { \"text\": \"🚀 Deploy\", \"callback_data\": \"ls:deploy\" }\n  ],\n  [\n    { \"text\": \"📥 Receive More\", \"callback_data\": \"ls:receive\" },\n    { \"text\": \"🛑 Stop\", \"callback_data\": \"ls:stop\" }\n  ]\n]\n\n\nImage file — show inline preview:\n\nMessage:\n\n✅ Received from Fast Potato:\n🖼️ screenshot.png — 2.1 MB\n\n\nInclude MEDIA:~/incoming/screenshot.png for inline preview.\n\nButtons:\n\nbuttons: [\n  [\n    { \"text\": \"📂 Open Folder\", \"callback_data\": \"ls:openfolder\" },\n    { \"text\": \"📥 Receive More\", \"callback_data\": \"ls:receive\" }\n  ],\n  [{ \"text\": \"🛑 Stop\", \"callback_data\": \"ls:stop\" }]\n]\n\n\nMultiple files:\n\nMessage:\n\n✅ Received 3 files from Fast Potato:\n📄 app.apk — 45 MB\n📄 README.md — 2 KB\n🖼️ icon.png — 128 KB\n📊 Total: 45.1 MB\n\n\nButtons:\n\nbuttons: [\n  [\n    { \"text\": \"📂 Show All\", \"callback_data\": \"ls:showall\" },\n    { \"text\": \"📥 Receive More\", \"callback_data\": \"ls:receive\" }\n  ],\n  [{ \"text\": \"🛑 Stop\", \"callback_data\": \"ls:stop\" }]\n]\n\n\nContextual button rules by file type:\n\n.zip, .tar.gz → add 📂 Extract button\n.png, .jpg, .gif, .webp → show MEDIA: inline + 📂 Open Folder\n.apk → add 📱 Install button\n.html, .js, .py → add 👁️ Preview button\nwebsite archives → add 🚀 Deploy button\nStep 6 — Stop receiver\n\nTrigger: callback_data: ls:stop\n\nKill the background task using stored task ID\n\nConfirm:\n\nMessage:\n\n🛑 Receiver stopped.\n\n\nButtons:\n\nbuttons: [\n  [\n    { \"text\": \"📡 Restart\", \"callback_data\": \"ls:receive\" },\n    { \"text\": \"⬅️ Menu\", \"callback_data\": \"ls:menu\" }\n  ]\n]\n\nFlow: Status Check\n\nTrigger: callback_data: ls:status\n\nCheck if receiver is running and count new files:\n\nls -1 /home/rami/.openclaw/workspace/_incoming/ > /tmp/localsend-after.txt\ndiff /tmp/localsend-before.txt /tmp/localsend-after.txt | grep \"^>\" | wc -l\n\n\nMessage:\n\n📡 Receiver: Running (12 min)\n📁 Files received: 2\n📊 Total: 242 MB\n\n\nButtons:\n\nbuttons: [\n  [\n    { \"text\": \"🛑 Stop\", \"callback_data\": \"ls:stop\" },\n    { \"text\": \"📂 Show Files\", \"callback_data\": \"ls:showall\" }\n  ]\n]\n\nCallback Data Reference\ncallback_data\tAction\nls:menu\tShow main menu\nls:send\tStart send flow\nls:receive\tStart receive flow\nls:devices\tDiscover devices\nls:dev:DEVICENAME\tSelect a specific device\nls:sendfile\tSend single file\nls:sendtext\tSend text message\nls:sendmulti\tSend multiple files\nls:confirm-send\tConfirm and execute send\nls:stop\tStop receiver\nls:status\tCheck receiver status\nls:extract\tExtract received archive\nls:deploy\tDeploy received website\nls:openfolder\tOpen save directory\nls:showall\tList all received files\nCLI Reference\nCommand\tUsage\nDiscover\tlocalsend-cli discover --json -t 2\nSend\tlocalsend-cli send --to \"DEVICE\" file1 file2 ...\nReceive\tlocalsend-cli --alias NAME receive --save-dir DIR -y\nFlag\tScope\tDescription\n--alias NAME\tGlobal (before subcommand)\tDevice name to advertise\n--to NAME\tsend\tTarget device (case-insensitive substring)\n-t N\tdiscover\tScan duration in seconds (use 2 for speed)\n--json\tdiscover\tMachine-readable output\n--save-dir DIR\treceive\tSave location (default: ~/Downloads)\n-y\treceive\tAuto-accept transfers\nTroubleshooting\nProblem\tFix\nunrecognized arguments: --alias\tMove --alias BEFORE the subcommand\nNo devices found\tOpen LocalSend on target, same WiFi, screen on\nPort 53317 in use\tNormal — CLI auto-falls back to 53318/53319\nTransfer declined (403)\tUse -y on receiver side\nTransfer hangs\tLarge file on slow WiFi — be patient\nReference\nCLI repo & docs: https://github.com/Chordlini/localsend-cli\nLocalSend protocol: references/protocol.md or https://github.com/localsend/protocol"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/Chordlini/localsend",
    "publisherUrl": "https://clawhub.ai/Chordlini/localsend",
    "owner": "Chordlini",
    "version": "3.4.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/localsend",
    "downloadUrl": "https://openagent3.xyz/downloads/localsend",
    "agentUrl": "https://openagent3.xyz/skills/localsend/agent",
    "manifestUrl": "https://openagent3.xyz/skills/localsend/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/localsend/agent.md"
  }
}