{"_id":"@clawpilot-app/clawpilot-media-bridge","_rev":"14-627b357961d4b50542bb40f7bce66137","name":"@clawpilot-app/clawpilot-media-bridge","dist-tags":{"latest":"1.3.2"},"versions":{"1.0.0":{"name":"@clawpilot-app/clawpilot-media-bridge","version":"1.0.0","keywords":["openclaw","clawpilot","plugin","media","r2"],"license":"MIT","_id":"@clawpilot-app/clawpilot-media-bridge@1.0.0","maintainers":[{"name":"yanghangbin","email":"yanghangbin@gmail.com"}],"dist":{"shasum":"54868c752310f9657d250c5575c444e2e5caaae6","tarball":"https://registry.npmjs.org/@clawpilot-app/clawpilot-media-bridge/-/clawpilot-media-bridge-1.0.0.tgz","fileCount":16,"integrity":"sha512-yZpPtJsqq2eP/tCJ0eN1qHq9KzilZ4LUdYWRj+BS4XKN+nMRIjT1XWPdsyoynRkH7eMfESi6uZl/uYPgUU8oxA==","signatures":[{"sig":"MEUCIQCZjlKO+fAXFcq7pkhMnjk2r+8sMAlSMCFl4Wx9wQGLRwIgTWamNs6tDNgahXmNlcaSlKmt4+jXND63/A6edWxgL+w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":38008},"type":"module","gitHead":"caa6d9f622a1ad98685a913241b20fd42cf2c414","scripts":{"check":"node --check index.js && node --check src/*.js","pack:dry-run":"npm pack --dry-run"},"_npmUser":{"name":"yanghangbin","email":"yanghangbin@gmail.com"},"openclaw":{"extensions":["./index.js"]},"_npmVersion":"11.6.0","description":"ClawPilot media bridge plugin for OpenClaw","directories":{},"_nodeVersion":"22.17.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/clawpilot-media-bridge_1.0.0_1773891631194_0.44401255143694174","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@clawpilot-app/clawpilot-media-bridge","version":"1.0.1","keywords":["openclaw","clawpilot","plugin","media","r2"],"license":"MIT","_id":"@clawpilot-app/clawpilot-media-bridge@1.0.1","maintainers":[{"name":"yanghangbin","email":"yanghangbin@gmail.com"}],"dist":{"shasum":"e29390d33f145aa5f75f7e4424416fbafb66d5d1","tarball":"https://registry.npmjs.org/@clawpilot-app/clawpilot-media-bridge/-/clawpilot-media-bridge-1.0.1.tgz","fileCount":16,"integrity":"sha512-WmxsZwOa/BWoDxfQYTenPBredkok8jjd9IRaTmHVOKRNnqMqx/sXqRn3X6AlaPQrcKks0x3YoI514kMpWukd7Q==","signatures":[{"sig":"MEUCIHSr9f998tlEuNhLDzZ1z1sEc7/xnnZUc5IW+WrMHJdrAiEAyALBWyANVpnO0c8l+zAXdrsJnt+CfAcH2641yADpVaQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":41065},"type":"module","gitHead":"caa6d9f622a1ad98685a913241b20fd42cf2c414","scripts":{"check":"node --check index.js && node --check src/*.js","pack:dry-run":"npm pack --dry-run"},"_npmUser":{"name":"yanghangbin","email":"yanghangbin@gmail.com"},"openclaw":{"extensions":["./index.js"]},"_npmVersion":"11.6.0","description":"ClawPilot media bridge plugin for OpenClaw","directories":{},"_nodeVersion":"22.17.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/clawpilot-media-bridge_1.0.1_1773901727847_0.26652265273001685","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@clawpilot-app/clawpilot-media-bridge","version":"1.0.2","keywords":["openclaw","clawpilot","plugin","media","r2"],"license":"MIT","_id":"@clawpilot-app/clawpilot-media-bridge@1.0.2","maintainers":[{"name":"yanghangbin","email":"yanghangbin@gmail.com"}],"dist":{"shasum":"cec714f07c0f6957c289c0d69ec912e0db4af483","tarball":"https://registry.npmjs.org/@clawpilot-app/clawpilot-media-bridge/-/clawpilot-media-bridge-1.0.2.tgz","fileCount":16,"integrity":"sha512-8vzWCCp6h3fZYJCIKOX418v8eJV8Ba0ywpYHea0N2iy2zs5VHysbW47tLNWw66aFw5KFxhnqnLuH3Pkr0wa2fA==","signatures":[{"sig":"MEYCIQDh3IcT9u6DP2uGTXNfYueuWDuzrsxZQlw7hN+v1BvoagIhALFmy7GE6TK9lYKZo4PKpae7WfsLNSLr70R/S/xtHrol","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":41043},"type":"module","gitHead":"caa6d9f622a1ad98685a913241b20fd42cf2c414","scripts":{"check":"node --check index.js && node --check src/*.js","pack:dry-run":"npm pack --dry-run"},"_npmUser":{"name":"yanghangbin","email":"yanghangbin@gmail.com"},"openclaw":{"extensions":["./index.js"]},"_npmVersion":"11.6.0","description":"ClawPilot media bridge plugin for OpenClaw","directories":{},"_nodeVersion":"22.17.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/clawpilot-media-bridge_1.0.2_1773905096732_0.5800969271006671","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@clawpilot-app/clawpilot-media-bridge","version":"1.0.3","keywords":["openclaw","clawpilot","plugin","media","r2"],"license":"MIT","_id":"@clawpilot-app/clawpilot-media-bridge@1.0.3","maintainers":[{"name":"yanghangbin","email":"yanghangbin@gmail.com"}],"dist":{"shasum":"6a776161aca98986d0bc9c6f83989b75dac13bf0","tarball":"https://registry.npmjs.org/@clawpilot-app/clawpilot-media-bridge/-/clawpilot-media-bridge-1.0.3.tgz","fileCount":16,"integrity":"sha512-L2kWpPXAd2mcdt19qsiqZZqGoUdD8wWXq83uK9m/OFHml5lu5Y0u1gyb2Yyq9i36+f8h9zLLf1ydUAwqssrb7w==","signatures":[{"sig":"MEYCIQDjpd3DCFRuNLOFf1lroVGhjfkDecsmDaJfVibaJpMr/AIhAPTa2YTtaMLaVuMU4InV32qD1a+rC6VsZPNV4SnpwEoU","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":41065},"type":"module","gitHead":"caa6d9f622a1ad98685a913241b20fd42cf2c414","scripts":{"check":"node --check index.js && node --check src/*.js","pack:dry-run":"npm pack --dry-run"},"_npmUser":{"name":"yanghangbin","email":"yanghangbin@gmail.com"},"openclaw":{"extensions":["./index.js"]},"_npmVersion":"11.6.0","description":"ClawPilot media bridge plugin for OpenClaw","directories":{},"_nodeVersion":"22.17.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/clawpilot-media-bridge_1.0.3_1773907906806_0.10783023530443914","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@clawpilot-app/clawpilot-media-bridge","version":"1.0.4","keywords":["openclaw","clawpilot","plugin","media","r2"],"license":"MIT","_id":"@clawpilot-app/clawpilot-media-bridge@1.0.4","maintainers":[{"name":"yanghangbin","email":"yanghangbin@gmail.com"}],"dist":{"shasum":"80881dc75ec8e71fb2af2867692c3960a5e60220","tarball":"https://registry.npmjs.org/@clawpilot-app/clawpilot-media-bridge/-/clawpilot-media-bridge-1.0.4.tgz","fileCount":16,"integrity":"sha512-okr3xG8R+8ZB5Y0QHeUFBR7tLlTu9Tf9PoeKhJdttzv+DQzIh0IBANeK+BnVPd6aSWYeAyxevZz3pHIW6AoBsg==","signatures":[{"sig":"MEYCIQDGfv5wfSmc3nNvufs3Djcnu0gukufNk2+gXPkKA63t9wIhAO0fL1z5Fk3BA/lj1TNZ7rlqUf4zOs4zk6cjYDJg1ijf","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":41140},"type":"module","gitHead":"caa6d9f622a1ad98685a913241b20fd42cf2c414","scripts":{"check":"node --check index.js && node --check src/*.js && node --check scripts/*.mjs","release":"node ./scripts/release.mjs","pack:dry-run":"npm pack --dry-run"},"_npmUser":{"name":"yanghangbin","email":"yanghangbin@gmail.com"},"openclaw":{"extensions":["./index.js"]},"_npmVersion":"11.6.0","description":"ClawPilot media bridge plugin for OpenClaw","directories":{},"_nodeVersion":"22.17.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/clawpilot-media-bridge_1.0.4_1773909199331_0.48112571031758966","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@clawpilot-app/clawpilot-media-bridge","version":"1.0.5","keywords":["openclaw","clawpilot","plugin","media","r2"],"license":"MIT","_id":"@clawpilot-app/clawpilot-media-bridge@1.0.5","maintainers":[{"name":"yanghangbin","email":"yanghangbin@gmail.com"}],"dist":{"shasum":"11c9443de918e16a4db57e017a6c9c631ae19013","tarball":"https://registry.npmjs.org/@clawpilot-app/clawpilot-media-bridge/-/clawpilot-media-bridge-1.0.5.tgz","fileCount":16,"integrity":"sha512-r5Hj8SuGKonznSyFglLsQit/6zT4vUrQTbmUz6UFo8fxs4rzPXjTftYucows9g+/XgqLskO/gci9C7QKOOgq6Q==","signatures":[{"sig":"MEQCIBZ7pxya4KqaPXMxpDPR2IkervqJXMZqJ/vcuhjLtqpCAiAEgFIVJ7s7Hf7lpbWpgGjXSkZOXtdE61NcBvRGYtrh3g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":41585},"type":"module","gitHead":"caa6d9f622a1ad98685a913241b20fd42cf2c414","scripts":{"check":"node --check index.js && node --check src/*.js && node --check scripts/*.mjs","release":"node ./scripts/release.mjs","pack:dry-run":"npm pack --dry-run"},"_npmUser":{"name":"yanghangbin","email":"yanghangbin@gmail.com"},"openclaw":{"extensions":["./index.js"]},"_npmVersion":"11.6.0","description":"ClawPilot media bridge plugin for OpenClaw","directories":{},"_nodeVersion":"22.17.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/clawpilot-media-bridge_1.0.5_1773911647941_0.904631376862006","host":"s3://npm-registry-packages-npm-production"}},"1.0.6":{"name":"@clawpilot-app/clawpilot-media-bridge","version":"1.0.6","keywords":["openclaw","clawpilot","plugin","media","r2"],"license":"MIT","_id":"@clawpilot-app/clawpilot-media-bridge@1.0.6","maintainers":[{"name":"yanghangbin","email":"yanghangbin@gmail.com"}],"dist":{"shasum":"71b44cd519bd7614f76fa9e8abf4fbd4b75b8e13","tarball":"https://registry.npmjs.org/@clawpilot-app/clawpilot-media-bridge/-/clawpilot-media-bridge-1.0.6.tgz","fileCount":16,"integrity":"sha512-hFzAVcFGbzWalM5QvchkXsnvsibp/IDhsVIqV6tvbPLxp7JJLR3NyJjGOKru92VCpol60IigFYidvJK7/A/YBA==","signatures":[{"sig":"MEUCIQDnSLLyCkU0h8S+VEfKgy+NeLHNNeXZp4zF+djpjro39QIgerC8uYue78ikfAxMXQ/njAcEHHHNeKdm4fNvtro9/N8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":41619},"type":"module","gitHead":"9c5554fc49a725f5432f21d4cc5ad702ba7b2d86","scripts":{"check":"node --check index.js && node --check src/*.js && node --check scripts/*.mjs","release":"node ./scripts/release.mjs","pack:dry-run":"npm pack --dry-run"},"_npmUser":{"name":"yanghangbin","email":"yanghangbin@gmail.com"},"openclaw":{"extensions":["./index.js"]},"_npmVersion":"11.6.0","description":"ClawPilot media bridge plugin for OpenClaw","directories":{},"_nodeVersion":"22.17.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/clawpilot-media-bridge_1.0.6_1773932514679_0.7863861885440089","host":"s3://npm-registry-packages-npm-production"}},"1.0.7":{"name":"@clawpilot-app/clawpilot-media-bridge","version":"1.0.7","keywords":["openclaw","clawpilot","plugin","media","r2"],"license":"MIT","_id":"@clawpilot-app/clawpilot-media-bridge@1.0.7","maintainers":[{"name":"yanghangbin","email":"yanghangbin@gmail.com"}],"dist":{"shasum":"9770527b19f8bf2b1f8896315ce59db46a46d0a7","tarball":"https://registry.npmjs.org/@clawpilot-app/clawpilot-media-bridge/-/clawpilot-media-bridge-1.0.7.tgz","fileCount":16,"integrity":"sha512-+kXTcNF0VWtxoBVsI1kHnxR/ZA2L0cvj0JE6DgSoM1xD786iCsQCCvT56gx13v7by3sGIeFtweZdzOjj6yFHfw==","signatures":[{"sig":"MEYCIQCOfLL55kq5lRCcvrAxtih7ci6BBVPsfx1Kpn3wklojwwIhAN6vzalz1OcjTsmECt38Jui7wNx4M44k/QkeVU1ZqKmH","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":42135},"type":"module","gitHead":"9e10465871c9e976255379a5d4324b97a364b710","scripts":{"check":"node --check index.js && node --check src/*.js && node --check scripts/*.mjs","release":"node ./scripts/release.mjs","pack:dry-run":"npm pack --dry-run"},"_npmUser":{"name":"yanghangbin","email":"yanghangbin@gmail.com"},"openclaw":{"extensions":["./index.js"]},"_npmVersion":"11.6.0","description":"ClawPilot media bridge plugin for OpenClaw","directories":{},"_nodeVersion":"22.17.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/clawpilot-media-bridge_1.0.7_1773936054571_0.6795662127022779","host":"s3://npm-registry-packages-npm-production"}},"1.0.8":{"name":"@clawpilot-app/clawpilot-media-bridge","version":"1.0.8","keywords":["openclaw","clawpilot","plugin","media","r2"],"license":"MIT","_id":"@clawpilot-app/clawpilot-media-bridge@1.0.8","maintainers":[{"name":"yanghangbin","email":"yanghangbin@gmail.com"}],"dist":{"shasum":"89fca7d7c7016ca927543ccf5e0f44c88fd5e057","tarball":"https://registry.npmjs.org/@clawpilot-app/clawpilot-media-bridge/-/clawpilot-media-bridge-1.0.8.tgz","fileCount":16,"integrity":"sha512-VKZhAD763Q2ZUszEv/gb6IIfQzABJ+56jFoxC4LwcUCrCFHrW24AskZWfrdYGIxoBx4ngE2YPaRKY8EzFRa6+A==","signatures":[{"sig":"MEYCIQDOOugs3Faz00axP9Hu30Z3bG5jQBWh7qetqVaal6c2SwIhAKlG7gu5dpapIzA2atnH92a0veZ8fCtiO41XCJE458be","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":42124},"type":"module","gitHead":"9e10465871c9e976255379a5d4324b97a364b710","scripts":{"check":"node --check index.js && node --check src/*.js && node --check scripts/*.mjs","release":"node ./scripts/release.mjs","pack:dry-run":"npm pack --dry-run"},"_npmUser":{"name":"yanghangbin","email":"yanghangbin@gmail.com"},"openclaw":{"extensions":["./index.js"]},"_npmVersion":"11.6.0","description":"ClawPilot media bridge plugin for OpenClaw","directories":{},"_nodeVersion":"22.17.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/clawpilot-media-bridge_1.0.8_1773936122233_0.9006662184280434","host":"s3://npm-registry-packages-npm-production"}},"1.0.9":{"name":"@clawpilot-app/clawpilot-media-bridge","version":"1.0.9","keywords":["openclaw","clawpilot","plugin","media","r2"],"license":"MIT","_id":"@clawpilot-app/clawpilot-media-bridge@1.0.9","maintainers":[{"name":"yanghangbin","email":"yanghangbin@gmail.com"}],"dist":{"shasum":"11469095e703fb44c6e63976ad23196810494489","tarball":"https://registry.npmjs.org/@clawpilot-app/clawpilot-media-bridge/-/clawpilot-media-bridge-1.0.9.tgz","fileCount":16,"integrity":"sha512-UFHhxDzH5OhuFcwftSpWfkLGe6r/jQ0Pfvxnv8EBZVptNS+Z6+RpEbT6K/MmOVEtR5oQFMCpFiehtkkezeixvQ==","signatures":[{"sig":"MEUCIQCzMv6PqNVWd6nkCZqSRqaLzV1ePzYifOmHSMjRhDFLDgIgXnqC3Fb+tl5ZMJvtZrX/FwVBvG2K9q2SvYyMojVP+9c=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":43356},"type":"module","gitHead":"b3cc240c18f0dd94ddaca4f26d6dd7d6251b34ad","scripts":{"check":"node --check index.js && node --check src/*.js && node --check scripts/*.mjs","release":"node ./scripts/release.mjs","pack:dry-run":"npm pack --dry-run"},"_npmUser":{"name":"yanghangbin","email":"yanghangbin@gmail.com"},"openclaw":{"extensions":["./index.js"]},"_npmVersion":"11.6.0","description":"ClawPilot media bridge plugin for OpenClaw","directories":{},"_nodeVersion":"22.17.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/clawpilot-media-bridge_1.0.9_1773992508308_0.1686496124801451","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@clawpilot-app/clawpilot-media-bridge","version":"1.1.0","keywords":["openclaw","clawpilot","plugin","media","r2"],"license":"MIT","_id":"@clawpilot-app/clawpilot-media-bridge@1.1.0","maintainers":[{"name":"yanghangbin","email":"yanghangbin@gmail.com"}],"dist":{"shasum":"5f746f427c5b7a319922cca5b97ceeb9fb0e2b01","tarball":"https://registry.npmjs.org/@clawpilot-app/clawpilot-media-bridge/-/clawpilot-media-bridge-1.1.0.tgz","fileCount":16,"integrity":"sha512-TufnQawuThVzqoBZHzHJ95cf3V8n302dz1mDH/4MBGoJcG7wRukN0NBsJCWbK9iDCdk1AL5iaGtN5O5tFdfU6w==","signatures":[{"sig":"MEUCIQDCW21M2Ld5NA81RL7YAQuFVLztl/BjXS6mhL8OVb+tYAIgPVIK3XzNMuJorWuIjoQBXPMN15OH+PNgN4xh8X3HRuA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":43225},"type":"module","gitHead":"c95f28c16420d5125c84df60a5ad0f4e7305cf84","scripts":{"check":"node --check index.js && node --check src/*.js && node --check scripts/*.mjs","release":"node ./scripts/release.mjs","pack:dry-run":"npm pack --dry-run"},"_npmUser":{"name":"yanghangbin","email":"yanghangbin@gmail.com"},"openclaw":{"extensions":["./index.js"]},"_npmVersion":"11.6.0","description":"ClawPilot media bridge plugin for OpenClaw","directories":{},"_nodeVersion":"22.17.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/clawpilot-media-bridge_1.1.0_1774793335666_0.8727782171362588","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"@clawpilot-app/clawpilot-media-bridge","version":"1.3.0","keywords":["openclaw","clawpilot","plugin","media","r2"],"license":"MIT","_id":"@clawpilot-app/clawpilot-media-bridge@1.3.0","maintainers":[{"name":"yanghangbin","email":"yanghangbin@gmail.com"}],"dist":{"shasum":"8a97c886928803ea69780012988d69012d5c599b","tarball":"https://registry.npmjs.org/@clawpilot-app/clawpilot-media-bridge/-/clawpilot-media-bridge-1.3.0.tgz","fileCount":22,"integrity":"sha512-Q1uDU3354VSeRE730OF9EWbI628UXCifptklSEP5tT1OuB+x9E4nBiKmQ/P0SyV69bcgeNm5AUEyzF/EJWn7mw==","signatures":[{"sig":"MEUCIQCZLCX4+SUTzxBYdUhf9vSp3vQdQUZ1E27HY+TmtLdB0AIgWpV+NoA3DR73fVgxxaFRW7eP7r3dzczVMVj0YCrbO9I=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":140214},"type":"module","gitHead":"f27cc7f0a902006827688273229dea689d3d4d6e","scripts":{"check":"node --check index.js && node --check src/*.js && node --check scripts/*.mjs","release":"node ./scripts/release.mjs","pack:dry-run":"npm pack --dry-run"},"_npmUser":{"name":"yanghangbin","email":"yanghangbin@gmail.com"},"openclaw":{"extensions":["./index.js"]},"_npmVersion":"11.6.0","description":"ClawPilot media bridge plugin for OpenClaw","directories":{},"_nodeVersion":"22.17.1","dependencies":{"music-metadata":"^11.12.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/clawpilot-media-bridge_1.3.0_1775635950042_0.21424913719047867","host":"s3://npm-registry-packages-npm-production"}},"1.3.1":{"name":"@clawpilot-app/clawpilot-media-bridge","version":"1.3.1","keywords":["openclaw","clawpilot","plugin","media","r2"],"license":"MIT","_id":"@clawpilot-app/clawpilot-media-bridge@1.3.1","maintainers":[{"name":"yanghangbin","email":"yanghangbin@gmail.com"}],"dist":{"shasum":"c70a332fea15add1377d342cc6bc6ee1217a801e","tarball":"https://registry.npmjs.org/@clawpilot-app/clawpilot-media-bridge/-/clawpilot-media-bridge-1.3.1.tgz","fileCount":22,"integrity":"sha512-Jb4sSHddjQYiOdnKON4wZ3jr+be5K+P0fkS0AGm9Az9L7nn2PeFjRWizwOvmG5wLlkMfIkMUiXwyk8w80Hak9A==","signatures":[{"sig":"MEQCIDenATdj6ceETZs2Xf0zbVm9e65Ozo5F7yV6w35HW1E5AiAI95gm0GHrYL6Ej9XvId/DB2D/HlhchPJEMa18tCQKUQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":140437},"type":"module","gitHead":"3ee8e9e8336ba9c26cd8bc52e29a8bb1518334a3","scripts":{"check":"node --check index.js && node --check src/*.js && node --check scripts/*.mjs","release":"node ./scripts/release.mjs","pack:dry-run":"npm pack --dry-run"},"_npmUser":{"name":"yanghangbin","email":"yanghangbin@gmail.com"},"openclaw":{"extensions":["./index.js"]},"_npmVersion":"11.6.0","description":"ClawPilot media bridge plugin for OpenClaw","directories":{},"_nodeVersion":"22.17.1","dependencies":{"music-metadata":"^11.12.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/clawpilot-media-bridge_1.3.1_1777990478195_0.8442245639845589","host":"s3://npm-registry-packages-npm-production"}},"1.3.2":{"name":"@clawpilot-app/clawpilot-media-bridge","version":"1.3.2","description":"ClawPilot media bridge plugin for OpenClaw","license":"MIT","type":"module","keywords":["openclaw","clawpilot","plugin","media","r2"],"dependencies":{"music-metadata":"^11.12.3"},"scripts":{"check":"node --check index.js && node --check src/*.js && node --check scripts/*.mjs && node scripts/check-registration.mjs","pack:dry-run":"npm pack --dry-run","release":"node ./scripts/release.mjs"},"publishConfig":{"access":"public"},"openclaw":{"extensions":["./index.js"]},"_id":"@clawpilot-app/clawpilot-media-bridge@1.3.2","gitHead":"41b40860aaabed95ed68d089fb5543c926a43d75","_nodeVersion":"22.17.1","_npmVersion":"11.6.0","dist":{"integrity":"sha512-i7AUA82uiERH1piQc6/P9tBzTMy8jvGKu1dPqDwAfIG4vWrlOkuqzvKtUVT/7FRQ5BczvYCSqij9CRevr0tbXw==","shasum":"02b39c6531661a253a6e1f32796243c30aa99396","tarball":"https://registry.npmjs.org/@clawpilot-app/clawpilot-media-bridge/-/clawpilot-media-bridge-1.3.2.tgz","fileCount":22,"unpackedSize":140951,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDcHmstXa9Y/yLcIj4x3TI8dMbsiihTUTcFXY3zeXhLjQIhAKWziv6mWat0UsQFlgpDLFjqZKWTA2APLqQMFQhZ1WDo"}]},"_npmUser":{"name":"yanghangbin","email":"yanghangbin@gmail.com"},"directories":{},"maintainers":[{"name":"yanghangbin","email":"yanghangbin@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/clawpilot-media-bridge_1.3.2_1779430234760_0.5414127729630609"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-19T03:40:31.092Z","modified":"2026-05-22T06:10:35.103Z","1.0.0":"2026-03-19T03:40:31.357Z","1.0.1":"2026-03-19T06:28:47.985Z","1.0.2":"2026-03-19T07:24:56.887Z","1.0.3":"2026-03-19T08:11:46.973Z","1.0.4":"2026-03-19T08:33:19.496Z","1.0.5":"2026-03-19T09:14:08.094Z","1.0.6":"2026-03-19T15:01:54.855Z","1.0.7":"2026-03-19T16:00:54.748Z","1.0.8":"2026-03-19T16:02:02.370Z","1.0.9":"2026-03-20T07:41:48.460Z","1.1.0":"2026-03-29T14:08:55.832Z","1.3.0":"2026-04-08T08:12:30.208Z","1.3.1":"2026-05-05T14:14:38.366Z","1.3.2":"2026-05-22T06:10:34.949Z"},"license":"MIT","keywords":["openclaw","clawpilot","plugin","media","r2"],"description":"ClawPilot media bridge plugin for OpenClaw","maintainers":[{"name":"yanghangbin","email":"yanghangbin@gmail.com"}],"readme":"# @clawpilot-app/clawpilot-media-bridge\n\nClawPilot media bridge plugin for **OpenClaw**.\n\nIt lets an OpenClaw agent:\n\n- upload a gateway-local image or file to ClawPilot R2-backed media storage\n- get back a stable capability URL\n- return structured upload metadata that ClawPilot App can render as attachment cards\n- generate a voice reply, upload it automatically, and return a real ClawPilot voice bubble payload\n- fetch a ClawPilot capability URL back to a local temp file when the agent needs bytes\n- transcribe a ClawPilot voice attachment with OpenClaw's native audio runtime\n\nThe plugin is intentionally **tool-first**. It does **not** hijack Feishu, Discord, Telegram, or any other channel send path.\n\n## What This Plugin Registers\n\n- Tool: `clawpilot_media_upload`\n- Tool: `clawpilot_media_reply_voice`\n- Tool: `clawpilot_media_fetch`\n- Tool: `clawpilot_media_transcribe`\n- Gateway RPC: `clawpilot_media.status`\n- Skill: `clawpilot-media-bridge`\n\n## Install\n\nCanonical npm install command:\n\n```bash\nopenclaw plugins install @clawpilot-app/clawpilot-media-bridge\n```\n\nLocal archive install is also supported:\n\n```bash\nopenclaw plugins install ./clawpilot-media-bridge.tgz\n```\n\nAfter installation, restart the gateway.\n\n## Config\n\nAdd or update the plugin entry in `~/.openclaw/openclaw.json`:\n\n```json5\n{\n  plugins: {\n    allow: [\"clawpilot-media-bridge\"],\n    entries: {\n      \"clawpilot-media-bridge\": {\n        enabled: true,\n        hooks: {\n          allowConversationAccess: true,\n        },\n        config: {\n          serverBaseUrl: \"https://api.clawpilot.me\",\n          gatewayClientId: \"YOUR_GATEWAY_CLIENT_ID\",\n          mediaBridgeToken: \"mbt_xxx\",\n          uploadMaxBytes: 104857600,\n          downloadHostAllowlist: [\"api.clawpilot.me\", \"media.clawpilot.me\"],\n          allowedMessageChannels: [\"webchat\"],\n          openclawPackageRoot: \"/absolute/path/to/openclaw\"\n        },\n      },\n    },\n  },\n}\n```\n\nField notes:\n\n- `plugins.allow`: if you maintain an explicit plugin allowlist, include `clawpilot-media-bridge` here. If you already trust other plugins, append this id instead of replacing the list.\n- `hooks.allowConversationAccess`: required by recent OpenClaw versions so this non-bundled plugin can read the current ClawPilot turn, authorize its scoped tools, and inject the media guidance only for matching App sessions.\n- `serverBaseUrl`: ClawPilot server origin or origin+base-path.\n- `gatewayClientId`: the gateway client id bound in ClawPilot server.\n- `mediaBridgeToken`: bearer token issued by ClawPilot server for this gateway.\n- `uploadMaxBytes`: hard transport cap. Default `104857600` (100 MB).\n- `downloadHostAllowlist`: hosts that `clawpilot_media_fetch` may download from.\n- `allowedMessageChannels`: defaults to `[\"webchat\"]` so the plugin stays scoped to ClawPilot App style sessions.\n- `allowedAgentIds`: optional extra guard if you only want this plugin available to a dedicated app agent.\n- `openclawPackageRoot`: optional absolute path to the installed OpenClaw package root. Leave this empty unless isolated TTS runtime auto-detection fails in your environment.\n\n### Voice Reply Runtime Notes\n\n`clawpilot_media_reply_voice` now runs TTS inside an **isolated child process** instead of reusing the OpenClaw main process state.\n\nWhy this matters:\n\n- voice-message turns can warm up OpenClaw's media-understanding runtime before TTS runs\n- in some OpenClaw environments that can leave the main process with a stale active speech-provider registry\n- the result is a false failure like `microsoft: no provider registered; openai: not configured`\n- isolating TTS in a clean subprocess avoids that polluted state without requiring any OpenClaw core patch\n\nHow the plugin finds OpenClaw for isolated TTS:\n\n1. `plugins.entries.clawpilot-media-bridge.config.openclawPackageRoot`\n2. `CLAWPILOT_MEDIA_OPENCLAW_PACKAGE_ROOT`\n3. automatic discovery from the current OpenClaw process / executable / global install path\n\nOpenClaw compatibility note:\n\n- Some OpenClaw `2026.4.5` npm installs expose the needed TTS functions through `dist/plugin-sdk/agent-runtime.js`.\n- OpenClaw `2026.4.1` exposed the TTS facade as `plugin-sdk/speech-runtime`.\n- OpenClaw `2026.4.5` removed that export and moved the isolated TTS facade to `dist/plugin-sdk/tts-runtime.js`.\n- This plugin now probes all known layouts so upgrades and packaging differences do not break isolated voice replies.\n\nRecommended rule:\n\n- do nothing first\n- only set `openclawPackageRoot` when the plugin tells you it could not auto-detect the OpenClaw runtime\n- if you use an explicit `plugins.allow` list, keep the active TTS provider plugin in that allowlist too, for example `microsoft`\n\nThis design works with normal macOS, Linux, Windows, and Docker installs as long as the path points to the OpenClaw package **inside the environment where OpenClaw is actually running**.\n\nWaveform note:\n\n- For the most accurate ClawPilot voice-bubble waveform on generated voice replies, install `ffmpeg` on the gateway host.\n- When `ffmpeg` is available, the plugin decodes the synthesized audio to real PCM before sampling waveform bars, so speech pauses and emphasis show up much more naturally.\n- Without `ffmpeg`, voice replies still upload and play, but the waveform preview falls back to rough file-byte estimation and can look flatter than the actual speech.\n\n## App Onboarding Flow\n\nRecommended product flow:\n\n1. User installs the plugin with `openclaw plugins install @clawpilot-app/clawpilot-media-bridge`\n2. User restarts the gateway\n3. ClawPilot App calls `clawpilot_media.status`\n4. If `hasMediaBridgeToken` is false, the app requests a token from ClawPilot server\n5. The app writes `plugins.entries.clawpilot-media-bridge.config`\n6. User restarts the gateway again so the new config takes effect\n\n## Model-Facing Usage\n\nThis section is written so both humans and agents can understand the intended usage.\n\n### Sending a generated image or file back to the user\n\n1. Generate or locate a local file path on the gateway host.\n2. Call `clawpilot_media_upload`.\n3. In normal ClawPilot App replies, return a short natural sentence and let the app render attachment cards from tool events.\n\nDo not hand-write capability URLs.\nDo not hand-write `CP_MEDIA_V1` payloads.\n\nThe plugin returns:\n\n- `CP_MEDIA_V1:<base64url-json>` for images and generic files\n- Voice/file directives may also include `fileKind` and `durationMs` metadata when available so ClawPilot App can restore voice bubbles from history.\n\nOnly when the user explicitly asks for the raw link/directive line should the agent return `assistantDirective` verbatim.\n\n### Sending a voice reply back to the user\n\nIf the reply should appear as a ClawPilot voice bubble, call `clawpilot_media_reply_voice`.\n\nWhy this exists:\n\n- OpenClaw's built-in `tts` tool only returns a gateway-local file path.\n- That local path is not reachable from the ClawPilot App on the user's phone.\n- `clawpilot_media_reply_voice` fixes this by generating speech and then uploading it through ClawPilot media storage in the same tool call.\n\nImportant:\n\n- In ClawPilot App sessions, do not use bare `tts` for outbound voice replies.\n- Only use `clawpilot_media_upload` for audio when some other tool already created the local audio file.\n- After `clawpilot_media_reply_voice` succeeds, do not add extra assistant-visible text unless the user explicitly asked for a written version too.\n- In normal voice-reply turns, let the voice bubble speak for itself instead of replying with a follow-up sentence like \"uploaded\" or \"voice sent\".\n\n### Reading a file that came from ClawPilot App\n\nIf the user message already contains a ClawPilot capability URL or a `CP_MEDIA_V1` block and the agent needs the local bytes, call `clawpilot_media_fetch`.\n\nThat tool downloads the file to a local temp path and returns:\n\n- `localPath`\n- `fileName`\n- `mimeType`\n- `sizeBytes`\n\n## Tool Reference\n\n### `clawpilot_media_upload`\n\nPurpose:\n\n- Upload a gateway-local file to ClawPilot media storage.\n- Return structured media metadata and a backward-compatible directive line.\n\nInput:\n\n```json\n{\n  \"path\": \"/tmp/report.pdf\",\n  \"kind\": \"auto\",\n  \"fileName\": \"report.pdf\",\n  \"mimeType\": \"application/pdf\"\n}\n```\n\nKey output fields:\n\n```json\n{\n  \"ok\": true,\n  \"mediaId\": \"med_xxx\",\n  \"publicId\": \"mpub_xxx\",\n  \"kind\": \"file\",\n  \"capabilityUrl\": \"https://media.clawpilot.me/openclaw-media/2026/03/19/med_xxx/report.pdf\",\n  \"assistantDirective\": \"CP_MEDIA_V1:...\",\n  \"markdownLink\": \"[report.pdf](https://media.clawpilot.me/openclaw-media/2026/03/19/med_xxx/report.pdf)\"\n}\n```\n\n### `clawpilot_media_reply_voice`\n\nPurpose:\n\n- Generate speech on the gateway.\n- Upload the generated audio to ClawPilot media storage.\n- Return structured metadata that ClawPilot App can render as a voice bubble.\n\nInput:\n\n```json\n{\n  \"text\": \"这是给用户的语音回复\",\n  \"fileName\": \"voice-reply\"\n}\n```\n\nKey output fields:\n\n```json\n{\n  \"ok\": true,\n  \"kind\": \"file\",\n  \"fileKind\": \"voice\",\n  \"fileName\": \"voice-reply.ogg\",\n  \"capabilityUrl\": \"https://media.clawpilot.me/openclaw-media/2026/04/05/med_xxx/voice-reply.ogg\",\n  \"assistantDirective\": \"CP_MEDIA_V1:...\"\n}\n```\n\nFailure payloads are structured too:\n\n```json\n{\n  \"ok\": false,\n  \"channel\": \"webchat\",\n  \"ttsRuntime\": \"isolated_subprocess\",\n  \"configuredTtsProviders\": [\"microsoft\"],\n  \"error\": {\n    \"code\": \"tts_provider_not_configured\",\n    \"stage\": \"tts\",\n    \"retryable\": false,\n    \"userMessage\": \"This gateway can see TTS providers, but none of them are configured well enough to synthesize speech.\",\n    \"userAction\": \"Configure any working TTS provider on the gateway, such as Microsoft, OpenAI, or another OpenClaw speech provider, then retry.\"\n  }\n}\n```\n\nFailure-handling guidance:\n\n- If `ok` is `true`, render the returned voice bubble metadata as usual.\n- If `ok` is `false`, do not pretend the voice reply was sent.\n- Use `error.userMessage` and `error.userAction` to explain the problem to the user in plain language.\n- When `error.code` is `tts_runtime_not_found` or `tts_runtime_path_invalid`, fix the OpenClaw runtime path before retrying.\n\n### `clawpilot_media_fetch`\n\nPurpose:\n\n- Download an allowed ClawPilot capability URL to a temp file on the gateway host.\n\nInput:\n\n```json\n{\n  \"capabilityUrl\": \"https://media.clawpilot.me/openclaw-media/2026/03/19/med_xxx/report.pdf\",\n  \"expectedFileName\": \"report.pdf\",\n  \"expectedMimeType\": \"application/pdf\"\n}\n```\n\n### `clawpilot_media_transcribe`\n\nPurpose:\n\n- Download a ClawPilot voice capability URL to a temp file.\n- Reuse OpenClaw's native audio runtime and return either transcript text or a structured failure payload.\n- The plugin now passes a best-effort agent/default model hint into OpenClaw when that config is available, so the gateway can prefer an already configured model before falling back to auto-detected STT routes.\n\nInput:\n\n```json\n{\n  \"capabilityUrl\": \"https://media.clawpilot.me/openclaw-media/2026/03/19/med_xxx/voice.ogg\",\n  \"expectedFileName\": \"voice.ogg\",\n  \"expectedMimeType\": \"audio/ogg\"\n}\n```\n\nKey output fields:\n\n```json\n{\n  \"ok\": true,\n  \"transcript\": \"帮我总结一下今天的会议重点\",\n  \"mimeType\": \"audio/ogg\",\n  \"transcriptionProvider\": \"openai\",\n  \"transcriptionModel\": \"gpt-4o-mini-transcribe\"\n}\n```\n\nFailure payloads are also structured:\n\n```json\n{\n  \"ok\": false,\n  \"mimeType\": \"audio/ogg\",\n  \"error\": {\n    \"code\": \"transcription_unavailable\",\n    \"stage\": \"transcribe\",\n    \"retryable\": false,\n    \"userMessage\": \"The gateway could not find a usable audio transcription path for this voice message.\",\n    \"userAction\": \"Configure any one working audio path on the gateway, such as local Whisper/Sherpa or a provider like OpenAI, Groq, Deepgram, Google, or Mistral, then retry.\"\n  }\n}\n```\n\nModel-handling guidance:\n\n- If `ok` is `true`, use `transcript` as the user's actual voice content.\n- If `ok` is `false`, do not pretend the audio was understood.\n- Use the returned structured error fields to explain what happened in the user's language.\n- If the same turn also includes typed text, still handle the typed text normally and only mention the audio failure when it matters.\n\n### `clawpilot_media.status`\n\nPurpose:\n\n- Let ClawPilot App detect whether the plugin is installed, enabled, and configured.\n\nExample success payload:\n\n```json\n{\n  \"ok\": true,\n  \"pluginId\": \"clawpilot-media-bridge\",\n  \"version\": \"1.3.2\",\n  \"enabled\": true,\n  \"configured\": false,\n  \"hasMediaBridgeToken\": false,\n  \"serverBaseUrl\": \"https://api.clawpilot.me\",\n  \"gatewayClientId\": null,\n  \"needsRestart\": false\n}\n```\n\n## Safety Boundaries\n\n- This plugin does **not** register a global outbound hook.\n- This plugin does **not** rewrite every `MEDIA:` line in every channel.\n- Runtime checks still require a valid session context and allowed message channel.\n- Default scope is `webchat`, which is the OpenClaw path most aligned with ClawPilot App usage.\n\n## Recommended Agent Policy\n\nFor strongest isolation, enable these tools only for your ClawPilot App agent:\n\n- `clawpilot_media_upload`\n- `clawpilot_media_reply_voice`\n- `clawpilot_media_fetch`\n- `clawpilot_media_transcribe`\n\nDo not enable them globally for every channel-facing agent unless that is explicitly what you want.\n","readmeFilename":"README.md"}