{
  "schemaVersion": "1.0",
  "item": {
    "slug": "node-transfer",
    "name": "Node Transfer",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/EisonMe/node-transfer",
    "canonicalUrl": "https://clawhub.ai/EisonMe/node-transfer",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/node-transfer",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=node-transfer",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "CONTRIBUTING_PROPOSAL.md",
      "deploy.js",
      "ensure-installed.js",
      "example.js",
      "INVESTIGATION_REPORT.md",
      "package.json"
    ],
    "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",
      "slug": "node-transfer",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-05-06T04:23:08.779Z",
      "expiresAt": "2026-05-13T04:23:08.779Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=node-transfer",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=node-transfer",
        "contentDisposition": "attachment; filename=\"node-transfer-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null,
        "slug": "node-transfer"
      },
      "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/node-transfer"
    },
    "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/node-transfer",
    "agentPageUrl": "https://openagent3.xyz/skills/node-transfer/agent",
    "manifestUrl": "https://openagent3.xyz/skills/node-transfer/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/node-transfer/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": "node-transfer",
        "body": "High-speed, memory-efficient file transfer between OpenClaw nodes using native Node.js streams."
      },
      {
        "title": "📋 Table of Contents",
        "body": "Problem Solved\nArchitecture\nRequirements\nInstallation\nUsage\nAPI Reference\nTroubleshooting"
      },
      {
        "title": "The Original Problem",
        "body": "When transferring large files between OpenClaw nodes using the standard nodes.invoke mechanism, we encountered several critical issues:\n\nIssueImpactBase64 Encoding Overhead33% larger payload, slower transfersMemory Exhaustion (OOM)Loading multi-GB files into memory crashes the processTransfer LatencyJSON serialization/deserialization adds significant delay9-Minute DeploymentsRe-deploying scripts on every transfer"
      },
      {
        "title": "The Solution",
        "body": "node-transfer uses native HTTP streaming with Node.js streams, providing:\n\n✅ Zero memory overhead - Files stream directly from disk to network\n✅ No Base64 encoding - Raw binary transfer\n✅ Speed - Line-speed limited only by network bandwidth\n✅ Install Once, Run Many - Scripts persist on nodes after first deployment"
      },
      {
        "title": "Performance Comparison",
        "body": "MetricBase64 Transfernode-transferImprovement1GB file transfer time~15-30 min~8 sec~150x fasterMemory usage1GB+<10MB99% reductionFirst transfer overheadN/A~30 sec (one-time install)-Subsequent transfers~15-30 min<1 sec check + ~8 sec transfer~200x faster"
      },
      {
        "title": "How It Works",
        "body": "┌──────────────┐     HTTP Stream      ┌──────────────┐\n│  send.js     │ ◄──────────────────► │ receive.js   │\n│  (Source)    │   (Token-protected)  │ (Destination)│\n└──────────────┘                      └──────────────┘\n       │                                     │\n       ▼                                     ▼\n┌──────────────┐                      ┌──────────────┐\n│  Read Stream │                      │ Write Stream │\n│  (fs.create  │                      │ (fs.create   │\n│   ReadStream)│                      │  WriteStream)│\n└──────────────┘                      └──────────────┘\n       │                                     │\n       ▼                                     ▼\n┌──────────────┐                      ┌──────────────┐\n│  File on     │                      │  File on     │\n│  Disk        │                      │  Disk        │\n└──────────────┘                      └──────────────┘"
      },
      {
        "title": "Security Model",
        "body": "One-time Token: 256-bit cryptographically random token (64 hex chars)\nSingle Connection: Only one download allowed per token\nAuto-shutdown: Server closes after transfer completes or disconnects\nToken Validation: Every request must include the correct token"
      },
      {
        "title": "Data Flow",
        "body": "Sender (send.js):\n\nGenerates random port and security token\nStarts HTTP server on ephemeral port\nStreams file directly from disk to HTTP response\nAuto-shutdown after transfer or timeout (5 min default)\n\n\n\nReceiver (receive.js):\n\nConnects to sender URL with token\nStreams HTTP response directly to disk\nReports progress, speed, and completion status\nValidates received bytes match expected size"
      },
      {
        "title": "📦 Requirements",
        "body": "Node.js: 14.0.0 or higher\nNetwork: TCP connectivity between nodes (any port 1024-65535)\nFirewall: Must allow outbound connections and inbound on ephemeral ports\nDisk Space: Sufficient space on destination for received files"
      },
      {
        "title": "The \"Install Once\" Pattern",
        "body": "Instead of deploying scripts on every transfer, we deploy them once per node and use a fast version check for subsequent transfers."
      },
      {
        "title": "Method 1: Using deploy.js (Recommended)",
        "body": "# Generate deployment script for a target node\nnode deploy.js E3V3\n\n# This outputs a PowerShell script that you can execute via nodes.invoke()"
      },
      {
        "title": "Method 2: Manual Deployment",
        "body": "On each target node, create the directory and copy files:\n\n# Create directory\nmkdir C:/openclaw/skills/node-transfer/scripts -Force\n\n# Copy these files (ensure UTF-8 without BOM encoding):\n# - send.js\n# - receive.js\n# - ensure-installed.js\n# - version.js"
      },
      {
        "title": "Method 3: Via OpenClaw Agent",
        "body": "// 1. Check if already installed (< 100ms)\nconst check = await nodes.invoke({\n    node: 'E3V3',\n    command: ['node', 'C:/openclaw/skills/node-transfer/scripts/ensure-installed.js', \n              'C:/openclaw/skills/node-transfer/scripts']\n});\n\nconst checkResult = JSON.parse(check.output);\n\nif (!checkResult.installed) {\n    // 2. Deploy if needed (one-time, ~30 seconds)\n    // Use the deploy.js output or manually copy files\n    console.log('Deploying node-transfer to E3V3...');\n    // ... deployment code ...\n}"
      },
      {
        "title": "Basic Transfer Workflow",
        "body": "const INSTALL_DIR = 'C:/openclaw/skills/node-transfer/scripts';\nconst SOURCE_NODE = 'E3V3';\nconst DEST_NODE = 'E3V3-Docker';\n\n// Step 1: Check installation on both nodes (fast!)\nconst [sourceCheck, destCheck] = await Promise.all([\n    nodes.invoke({\n        node: SOURCE_NODE,\n        command: ['node', `${INSTALL_DIR}/ensure-installed.js`, INSTALL_DIR]\n    }),\n    nodes.invoke({\n        node: DEST_NODE,\n        command: ['node', `${INSTALL_DIR}/ensure-installed.js`, INSTALL_DIR]\n    })\n]);\n\n// Deploy if needed (usually only once per node ever)\n// ... deployment code if not installed ...\n\n// Step 2: Start sender on source node\nconst sendResult = await nodes.invoke({\n    node: SOURCE_NODE,\n    command: ['node', `${INSTALL_DIR}/send.js`, 'C:/data/large-file.zip']\n});\n\nconst { url, token, fileSize, fileName } = JSON.parse(sendResult.output);\n\n// Step 3: Start receiver on destination node\nconst receiveResult = await nodes.invoke({\n    node: DEST_NODE,\n    command: ['node', `${INSTALL_DIR}/receive.js`, url, token, '/incoming/file.zip']\n});\n\nconst result = JSON.parse(receiveResult.output);\nconsole.log(`Transferred ${result.bytesReceived} bytes in ${result.duration}s at ${result.speedMBps} MB/s`);"
      },
      {
        "title": "Using the Command Line",
        "body": "Sender\n\nnode send.js /path/to/file.zip\n\nOutput:\n\n{\n  \"url\": \"http://192.168.1.10:54321/transfer\",\n  \"token\": \"a1b2c3d4e5f6789...\",\n  \"fileSize\": 1073741824,\n  \"fileName\": \"file.zip\",\n  \"sourceIp\": \"192.168.1.10\",\n  \"port\": 54321,\n  \"version\": \"1.0.0\"\n}\n\nOptions:\n\nnode send.js /path/to/file.zip --port 8080 --timeout 10\nnode send.js --help\nnode send.js --version\n\nReceiver\n\nnode receive.js \"http://192.168.1.10:54321/transfer\" \"token-here...\" /path/to/save.zip\n\nOutput:\n\n{\n  \"success\": true,\n  \"bytesReceived\": 1073741824,\n  \"totalBytes\": 1073741824,\n  \"duration\": 8.42,\n  \"speedMBps\": 121.5,\n  \"outputPath\": \"/path/to/save.zip\"\n}\n\nOptions:\n\nnode receive.js <url> <token> <output> --timeout 60 --no-progress\nnode receive.js --help\nnode receive.js --version"
      },
      {
        "title": "send.js",
        "body": "Starts an HTTP server to stream a file.\n\nUsage: node send.js <filePath> [options]\n\nArguments:\n\nfilePath (required): Path to the file to send\n\nOptions:\n\n--port <n>: Use specific port (default: random ephemeral)\n--timeout <n>: Timeout in minutes (default: 5)\n\nOutput (JSON):\n\nFieldTypeDescriptionurlstringHTTP URL for receiver to connect totokenstringSecurity token (64 hex chars)fileSizenumberFile size in bytesfileNamestringOriginal filenamesourceIpstringIP address of senderportnumberTCP port usedversionstringVersion of send.js\n\nExit Codes:\n\n0: Success (transfer completed or info displayed)\n1: Error (check stderr for JSON error details)\n\nError Output (JSON):\n\n{\n  \"error\": \"ERROR_CODE\",\n  \"message\": \"Human-readable description\"\n}\n\nError codes: FILE_NOT_FOUND, NOT_A_FILE, SERVER_ERROR, TIMEOUT, READ_ERROR, RESPONSE_ERROR"
      },
      {
        "title": "receive.js",
        "body": "Connects to a sender and downloads a file.\n\nUsage: node receive.js <url> <token> <outputPath> [options]\n\nArguments:\n\nurl (required): URL from send.js output\ntoken (required): Security token from send.js output\noutputPath (required): Path to save the received file\n\nOptions:\n\n--timeout <n>: Connection timeout in seconds (default: 30)\n--no-progress: Suppress progress updates\n\nOutput (JSON):\n\nFieldTypeDescriptionsuccessbooleanAlways true on successbytesReceivednumberActual bytes receivedtotalBytesnumberExpected bytes (from Content-Length)durationnumberTransfer time in secondsspeedMBpsnumberAverage speed in MB/soutputPathstringAbsolute path to saved file\n\nProgress Updates (when not using --no-progress):\n\n{\n  \"progress\": true,\n  \"receivedBytes\": 536870912,\n  \"totalBytes\": 1073741824,\n  \"percent\": 50,\n  \"speedMBps\": 125.4\n}\n\nExit Codes:\n\n0: Success\n1: Error (check stderr for JSON error details)\n\nError codes: INVALID_ARGS, INVALID_URL, CONNECTION_ERROR, HTTP_ERROR, TIMEOUT, WRITE_ERROR, SIZE_MISMATCH, FILE_EXISTS, NO_DATA"
      },
      {
        "title": "ensure-installed.js",
        "body": "Fast check if node-transfer is installed on a node.\n\nUsage: node ensure-installed.js <targetDir>\n\nArguments:\n\ntargetDir (required): Directory to check\n\nOutput (JSON):\n\nInstalled:\n\n{\n  \"installed\": true,\n  \"version\": \"1.0.0\",\n  \"message\": \"node-transfer is installed and up-to-date\"\n}\n\nNeeds installation:\n\n{\n  \"installed\": false,\n  \"missing\": [\"send.js\"],\n  \"mismatched\": [],\n  \"currentVersion\": null,\n  \"requiredVersion\": \"1.0.0\",\n  \"action\": \"DEPLOY\",\n  \"message\": \"Installation needed: 1 missing, 0 outdated\"\n}\n\nExit Codes:\n\n0: Already installed and up-to-date\n1: Needs installation/update\n2: Error (invalid directory, etc.)"
      },
      {
        "title": "deploy.js",
        "body": "Generates deployment scripts for the main agent.\n\nUsage: node deploy.js <nodeId> [targetDir]\n\nOutput: JSON with:\n\nscript: PowerShell script to deploy files\nescapedScript: Escaped version for command-line use\nusage: Example code for JavaScript and CLI usage"
      },
      {
        "title": "\"Connection timeout\"",
        "body": "Cause: Network connectivity issue or firewall blocking connection.\n\nSolutions:\n\nVerify both nodes can reach each other\nCheck firewall rules allow outbound connections\nTry specifying a specific port with --port\nIncrease timeout with --timeout"
      },
      {
        "title": "\"403 Forbidden: Invalid or missing token\"",
        "body": "Cause: Token mismatch or URL manipulation.\n\nSolutions:\n\nUse the exact token from send.js output\nDon't modify the URL\nEnsure the token hasn't expired (sender times out after 5 minutes)"
      },
      {
        "title": "\"409 Conflict: Transfer already in progress\"",
        "body": "Cause: Multiple connections attempted with same token.\n\nSolutions:\n\nEach sender URL/token can only be used once\nStart a new sender if you need to retry"
      },
      {
        "title": "\"FILE_NOT_FOUND\" or \"NOT_A_FILE\"",
        "body": "Cause: Invalid file path on sender.\n\nSolutions:\n\nUse absolute paths\nVerify file exists\nCheck file permissions"
      },
      {
        "title": "\"SIZE_MISMATCH\"",
        "body": "Cause: Connection interrupted or network error.\n\nSolutions:\n\nRetry the transfer\nCheck network stability\nThe partial file is automatically cleaned up"
      },
      {
        "title": "\"Hash mismatch\" during ensure-installed",
        "body": "Cause: Files were modified or corrupted.\n\nSolutions:\n\nRe-deploy scripts using deploy.js\nEnsure files are copied without modification\nCheck encoding (must be UTF-8 without BOM)"
      },
      {
        "title": "Slow transfers on subsequent runs",
        "body": "Cause: Not using ensure-installed.js check pattern.\n\nSolutions:\n\nAlways check installation first (< 100ms)\nOnly deploy if installed: false\nFollow the \"Install Once, Run Many\" pattern"
      },
      {
        "title": "📄 Files",
        "body": "FilePurposesend.jsHTTP server that streams files to receiversreceive.jsHTTP client that downloads files from sendersensure-installed.jsFast version/integrity check for deploymentversion.jsVersion manifest for update detectiondeploy.jsGenerates deployment scripts for agents"
      },
      {
        "title": "🤝 Contributing",
        "body": "See CONTRIBUTING_PROPOSAL.md for information on how this could be integrated into OpenClaw core.\n\nBuilt for OpenClaw - No Base64, No OOM, No Waiting."
      }
    ],
    "body": "node-transfer\n\nHigh-speed, memory-efficient file transfer between OpenClaw nodes using native Node.js streams.\n\n📋 Table of Contents\nProblem Solved\nArchitecture\nRequirements\nInstallation\nUsage\nAPI Reference\nTroubleshooting\n🎯 Problem Solved\nThe Original Problem\n\nWhen transferring large files between OpenClaw nodes using the standard nodes.invoke mechanism, we encountered several critical issues:\n\nIssue\tImpact\nBase64 Encoding Overhead\t33% larger payload, slower transfers\nMemory Exhaustion (OOM)\tLoading multi-GB files into memory crashes the process\nTransfer Latency\tJSON serialization/deserialization adds significant delay\n9-Minute Deployments\tRe-deploying scripts on every transfer\nThe Solution\n\nnode-transfer uses native HTTP streaming with Node.js streams, providing:\n\n✅ Zero memory overhead - Files stream directly from disk to network\n✅ No Base64 encoding - Raw binary transfer\n✅ Speed - Line-speed limited only by network bandwidth\n✅ Install Once, Run Many - Scripts persist on nodes after first deployment\nPerformance Comparison\nMetric\tBase64 Transfer\tnode-transfer\tImprovement\n1GB file transfer time\t~15-30 min\t~8 sec\t~150x faster\nMemory usage\t1GB+\t<10MB\t99% reduction\nFirst transfer overhead\tN/A\t~30 sec (one-time install)\t-\nSubsequent transfers\t~15-30 min\t<1 sec check + ~8 sec transfer\t~200x faster\n🏗️ Architecture\nHow It Works\n┌──────────────┐     HTTP Stream      ┌──────────────┐\n│  send.js     │ ◄──────────────────► │ receive.js   │\n│  (Source)    │   (Token-protected)  │ (Destination)│\n└──────────────┘                      └──────────────┘\n       │                                     │\n       ▼                                     ▼\n┌──────────────┐                      ┌──────────────┐\n│  Read Stream │                      │ Write Stream │\n│  (fs.create  │                      │ (fs.create   │\n│   ReadStream)│                      │  WriteStream)│\n└──────────────┘                      └──────────────┘\n       │                                     │\n       ▼                                     ▼\n┌──────────────┐                      ┌──────────────┐\n│  File on     │                      │  File on     │\n│  Disk        │                      │  Disk        │\n└──────────────┘                      └──────────────┘\n\nSecurity Model\nOne-time Token: 256-bit cryptographically random token (64 hex chars)\nSingle Connection: Only one download allowed per token\nAuto-shutdown: Server closes after transfer completes or disconnects\nToken Validation: Every request must include the correct token\nData Flow\n\nSender (send.js):\n\nGenerates random port and security token\nStarts HTTP server on ephemeral port\nStreams file directly from disk to HTTP response\nAuto-shutdown after transfer or timeout (5 min default)\n\nReceiver (receive.js):\n\nConnects to sender URL with token\nStreams HTTP response directly to disk\nReports progress, speed, and completion status\nValidates received bytes match expected size\n📦 Requirements\nNode.js: 14.0.0 or higher\nNetwork: TCP connectivity between nodes (any port 1024-65535)\nFirewall: Must allow outbound connections and inbound on ephemeral ports\nDisk Space: Sufficient space on destination for received files\n🚀 Installation\nThe \"Install Once\" Pattern\n\nInstead of deploying scripts on every transfer, we deploy them once per node and use a fast version check for subsequent transfers.\n\nMethod 1: Using deploy.js (Recommended)\n# Generate deployment script for a target node\nnode deploy.js E3V3\n\n# This outputs a PowerShell script that you can execute via nodes.invoke()\n\nMethod 2: Manual Deployment\n\nOn each target node, create the directory and copy files:\n\n# Create directory\nmkdir C:/openclaw/skills/node-transfer/scripts -Force\n\n# Copy these files (ensure UTF-8 without BOM encoding):\n# - send.js\n# - receive.js\n# - ensure-installed.js\n# - version.js\n\nMethod 3: Via OpenClaw Agent\n// 1. Check if already installed (< 100ms)\nconst check = await nodes.invoke({\n    node: 'E3V3',\n    command: ['node', 'C:/openclaw/skills/node-transfer/scripts/ensure-installed.js', \n              'C:/openclaw/skills/node-transfer/scripts']\n});\n\nconst checkResult = JSON.parse(check.output);\n\nif (!checkResult.installed) {\n    // 2. Deploy if needed (one-time, ~30 seconds)\n    // Use the deploy.js output or manually copy files\n    console.log('Deploying node-transfer to E3V3...');\n    // ... deployment code ...\n}\n\n💡 Usage\nBasic Transfer Workflow\nconst INSTALL_DIR = 'C:/openclaw/skills/node-transfer/scripts';\nconst SOURCE_NODE = 'E3V3';\nconst DEST_NODE = 'E3V3-Docker';\n\n// Step 1: Check installation on both nodes (fast!)\nconst [sourceCheck, destCheck] = await Promise.all([\n    nodes.invoke({\n        node: SOURCE_NODE,\n        command: ['node', `${INSTALL_DIR}/ensure-installed.js`, INSTALL_DIR]\n    }),\n    nodes.invoke({\n        node: DEST_NODE,\n        command: ['node', `${INSTALL_DIR}/ensure-installed.js`, INSTALL_DIR]\n    })\n]);\n\n// Deploy if needed (usually only once per node ever)\n// ... deployment code if not installed ...\n\n// Step 2: Start sender on source node\nconst sendResult = await nodes.invoke({\n    node: SOURCE_NODE,\n    command: ['node', `${INSTALL_DIR}/send.js`, 'C:/data/large-file.zip']\n});\n\nconst { url, token, fileSize, fileName } = JSON.parse(sendResult.output);\n\n// Step 3: Start receiver on destination node\nconst receiveResult = await nodes.invoke({\n    node: DEST_NODE,\n    command: ['node', `${INSTALL_DIR}/receive.js`, url, token, '/incoming/file.zip']\n});\n\nconst result = JSON.parse(receiveResult.output);\nconsole.log(`Transferred ${result.bytesReceived} bytes in ${result.duration}s at ${result.speedMBps} MB/s`);\n\nUsing the Command Line\nSender\nnode send.js /path/to/file.zip\n\n\nOutput:\n\n{\n  \"url\": \"http://192.168.1.10:54321/transfer\",\n  \"token\": \"a1b2c3d4e5f6789...\",\n  \"fileSize\": 1073741824,\n  \"fileName\": \"file.zip\",\n  \"sourceIp\": \"192.168.1.10\",\n  \"port\": 54321,\n  \"version\": \"1.0.0\"\n}\n\n\nOptions:\n\nnode send.js /path/to/file.zip --port 8080 --timeout 10\nnode send.js --help\nnode send.js --version\n\nReceiver\nnode receive.js \"http://192.168.1.10:54321/transfer\" \"token-here...\" /path/to/save.zip\n\n\nOutput:\n\n{\n  \"success\": true,\n  \"bytesReceived\": 1073741824,\n  \"totalBytes\": 1073741824,\n  \"duration\": 8.42,\n  \"speedMBps\": 121.5,\n  \"outputPath\": \"/path/to/save.zip\"\n}\n\n\nOptions:\n\nnode receive.js <url> <token> <output> --timeout 60 --no-progress\nnode receive.js --help\nnode receive.js --version\n\n📚 API Reference\nsend.js\n\nStarts an HTTP server to stream a file.\n\nUsage: node send.js <filePath> [options]\n\nArguments:\n\nfilePath (required): Path to the file to send\n\nOptions:\n\n--port <n>: Use specific port (default: random ephemeral)\n--timeout <n>: Timeout in minutes (default: 5)\n\nOutput (JSON):\n\nField\tType\tDescription\nurl\tstring\tHTTP URL for receiver to connect to\ntoken\tstring\tSecurity token (64 hex chars)\nfileSize\tnumber\tFile size in bytes\nfileName\tstring\tOriginal filename\nsourceIp\tstring\tIP address of sender\nport\tnumber\tTCP port used\nversion\tstring\tVersion of send.js\n\nExit Codes:\n\n0: Success (transfer completed or info displayed)\n1: Error (check stderr for JSON error details)\n\nError Output (JSON):\n\n{\n  \"error\": \"ERROR_CODE\",\n  \"message\": \"Human-readable description\"\n}\n\n\nError codes: FILE_NOT_FOUND, NOT_A_FILE, SERVER_ERROR, TIMEOUT, READ_ERROR, RESPONSE_ERROR\n\nreceive.js\n\nConnects to a sender and downloads a file.\n\nUsage: node receive.js <url> <token> <outputPath> [options]\n\nArguments:\n\nurl (required): URL from send.js output\ntoken (required): Security token from send.js output\noutputPath (required): Path to save the received file\n\nOptions:\n\n--timeout <n>: Connection timeout in seconds (default: 30)\n--no-progress: Suppress progress updates\n\nOutput (JSON):\n\nField\tType\tDescription\nsuccess\tboolean\tAlways true on success\nbytesReceived\tnumber\tActual bytes received\ntotalBytes\tnumber\tExpected bytes (from Content-Length)\nduration\tnumber\tTransfer time in seconds\nspeedMBps\tnumber\tAverage speed in MB/s\noutputPath\tstring\tAbsolute path to saved file\n\nProgress Updates (when not using --no-progress):\n\n{\n  \"progress\": true,\n  \"receivedBytes\": 536870912,\n  \"totalBytes\": 1073741824,\n  \"percent\": 50,\n  \"speedMBps\": 125.4\n}\n\n\nExit Codes:\n\n0: Success\n1: Error (check stderr for JSON error details)\n\nError codes: INVALID_ARGS, INVALID_URL, CONNECTION_ERROR, HTTP_ERROR, TIMEOUT, WRITE_ERROR, SIZE_MISMATCH, FILE_EXISTS, NO_DATA\n\nensure-installed.js\n\nFast check if node-transfer is installed on a node.\n\nUsage: node ensure-installed.js <targetDir>\n\nArguments:\n\ntargetDir (required): Directory to check\n\nOutput (JSON):\n\nInstalled:\n\n{\n  \"installed\": true,\n  \"version\": \"1.0.0\",\n  \"message\": \"node-transfer is installed and up-to-date\"\n}\n\n\nNeeds installation:\n\n{\n  \"installed\": false,\n  \"missing\": [\"send.js\"],\n  \"mismatched\": [],\n  \"currentVersion\": null,\n  \"requiredVersion\": \"1.0.0\",\n  \"action\": \"DEPLOY\",\n  \"message\": \"Installation needed: 1 missing, 0 outdated\"\n}\n\n\nExit Codes:\n\n0: Already installed and up-to-date\n1: Needs installation/update\n2: Error (invalid directory, etc.)\ndeploy.js\n\nGenerates deployment scripts for the main agent.\n\nUsage: node deploy.js <nodeId> [targetDir]\n\nOutput: JSON with:\n\nscript: PowerShell script to deploy files\nescapedScript: Escaped version for command-line use\nusage: Example code for JavaScript and CLI usage\n🔧 Troubleshooting\n\"Connection timeout\"\n\nCause: Network connectivity issue or firewall blocking connection.\n\nSolutions:\n\nVerify both nodes can reach each other\nCheck firewall rules allow outbound connections\nTry specifying a specific port with --port\nIncrease timeout with --timeout\n\"403 Forbidden: Invalid or missing token\"\n\nCause: Token mismatch or URL manipulation.\n\nSolutions:\n\nUse the exact token from send.js output\nDon't modify the URL\nEnsure the token hasn't expired (sender times out after 5 minutes)\n\"409 Conflict: Transfer already in progress\"\n\nCause: Multiple connections attempted with same token.\n\nSolutions:\n\nEach sender URL/token can only be used once\nStart a new sender if you need to retry\n\"FILE_NOT_FOUND\" or \"NOT_A_FILE\"\n\nCause: Invalid file path on sender.\n\nSolutions:\n\nUse absolute paths\nVerify file exists\nCheck file permissions\n\"SIZE_MISMATCH\"\n\nCause: Connection interrupted or network error.\n\nSolutions:\n\nRetry the transfer\nCheck network stability\nThe partial file is automatically cleaned up\n\"Hash mismatch\" during ensure-installed\n\nCause: Files were modified or corrupted.\n\nSolutions:\n\nRe-deploy scripts using deploy.js\nEnsure files are copied without modification\nCheck encoding (must be UTF-8 without BOM)\nSlow transfers on subsequent runs\n\nCause: Not using ensure-installed.js check pattern.\n\nSolutions:\n\nAlways check installation first (< 100ms)\nOnly deploy if installed: false\nFollow the \"Install Once, Run Many\" pattern\n📄 Files\nFile\tPurpose\nsend.js\tHTTP server that streams files to receivers\nreceive.js\tHTTP client that downloads files from senders\nensure-installed.js\tFast version/integrity check for deployment\nversion.js\tVersion manifest for update detection\ndeploy.js\tGenerates deployment scripts for agents\n🤝 Contributing\n\nSee CONTRIBUTING_PROPOSAL.md for information on how this could be integrated into OpenClaw core.\n\nBuilt for OpenClaw - No Base64, No OOM, No Waiting."
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/EisonMe/node-transfer",
    "publisherUrl": "https://clawhub.ai/EisonMe/node-transfer",
    "owner": "EisonMe",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/node-transfer",
    "downloadUrl": "https://openagent3.xyz/downloads/node-transfer",
    "agentUrl": "https://openagent3.xyz/skills/node-transfer/agent",
    "manifestUrl": "https://openagent3.xyz/skills/node-transfer/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/node-transfer/agent.md"
  }
}