feat: add blog section with OpenClaw announcement

- Add blog infrastructure with Astro Content Collections
- Add "Introducing OpenClaw" blog post with rebrand announcement
- Add latest blog post highlight to homepage
- Update branding: Clawd → Claw, ClawdBot → OpenClaw in testimonials
- Update dependencies and migrate lucide-astro to @lucide/astro
- Update installer scripts for openclaw.ai domain
- Add beta status note to blog post
This commit is contained in:
Peter Steinberger 2026-01-30 05:26:23 +01:00
parent 5dc7cdacec
commit 56601ab3b9
23 changed files with 1463 additions and 539 deletions

View File

@ -8,10 +8,10 @@
"preview": "astro preview"
},
"dependencies": {
"@lucide/astro": "^0.563.0",
"@vercel/analytics": "^1.6.1",
"@vercel/speed-insights": "^1.3.1",
"astro": "^5.16.13",
"lucide-astro": "^0.556.0",
"simple-icons": "^16.6.0"
"astro": "^5.17.1",
"simple-icons": "^16.6.1"
}
}

306
pnpm-lock.yaml generated
View File

@ -8,6 +8,9 @@ importers:
.:
dependencies:
'@lucide/astro':
specifier: ^0.563.0
version: 0.563.0(astro@5.17.1(rollup@4.57.0)(typescript@5.9.3))
'@vercel/analytics':
specifier: ^1.6.1
version: 1.6.1
@ -15,14 +18,11 @@ importers:
specifier: ^1.3.1
version: 1.3.1
astro:
specifier: ^5.16.13
version: 5.16.15(rollup@4.56.0)(typescript@5.9.3)
lucide-astro:
specifier: ^0.556.0
version: 0.556.0(astro@5.16.15(rollup@4.56.0)(typescript@5.9.3))
specifier: ^5.17.1
version: 5.17.1(rollup@4.57.0)(typescript@5.9.3)
simple-icons:
specifier: ^16.6.0
version: 16.6.0
specifier: ^16.6.1
version: 16.6.1
packages:
@ -253,89 +253,105 @@ packages:
resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@img/sharp-libvips-linux-arm@1.2.4':
resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
cpu: [arm]
os: [linux]
libc: [glibc]
'@img/sharp-libvips-linux-ppc64@1.2.4':
resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@img/sharp-libvips-linux-riscv64@1.2.4':
resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@img/sharp-libvips-linux-s390x@1.2.4':
resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@img/sharp-libvips-linux-x64@1.2.4':
resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
cpu: [x64]
os: [linux]
libc: [glibc]
'@img/sharp-libvips-linuxmusl-arm64@1.2.4':
resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
cpu: [arm64]
os: [linux]
libc: [musl]
'@img/sharp-libvips-linuxmusl-x64@1.2.4':
resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
cpu: [x64]
os: [linux]
libc: [musl]
'@img/sharp-linux-arm64@0.34.5':
resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@img/sharp-linux-arm@0.34.5':
resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm]
os: [linux]
libc: [glibc]
'@img/sharp-linux-ppc64@0.34.5':
resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@img/sharp-linux-riscv64@0.34.5':
resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@img/sharp-linux-s390x@0.34.5':
resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@img/sharp-linux-x64@0.34.5':
resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [x64]
os: [linux]
libc: [glibc]
'@img/sharp-linuxmusl-arm64@0.34.5':
resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm64]
os: [linux]
libc: [musl]
'@img/sharp-linuxmusl-x64@0.34.5':
resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [x64]
os: [linux]
libc: [musl]
'@img/sharp-wasm32@0.34.5':
resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
@ -363,6 +379,11 @@ packages:
'@jridgewell/sourcemap-codec@1.5.5':
resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
'@lucide/astro@0.563.0':
resolution: {integrity: sha512-X9fNJvRR6pLJfkIEAFQkizWaNVvcduunJoFyR3fwPu30Y6jOu5S9k4k7HTSk3ZrEfqK2eFEqrBqqWH4fwSNKCg==}
peerDependencies:
astro: ^4 || ^5
'@oslojs/encoding@1.1.0':
resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==}
@ -375,128 +396,141 @@ packages:
rollup:
optional: true
'@rollup/rollup-android-arm-eabi@4.56.0':
resolution: {integrity: sha512-LNKIPA5k8PF1+jAFomGe3qN3bbIgJe/IlpDBwuVjrDKrJhVWywgnJvflMt/zkbVNLFtF1+94SljYQS6e99klnw==}
'@rollup/rollup-android-arm-eabi@4.57.0':
resolution: {integrity: sha512-tPgXB6cDTndIe1ah7u6amCI1T0SsnlOuKgg10Xh3uizJk4e5M1JGaUMk7J4ciuAUcFpbOiNhm2XIjP9ON0dUqA==}
cpu: [arm]
os: [android]
'@rollup/rollup-android-arm64@4.56.0':
resolution: {integrity: sha512-lfbVUbelYqXlYiU/HApNMJzT1E87UPGvzveGg2h0ktUNlOCxKlWuJ9jtfvs1sKHdwU4fzY7Pl8sAl49/XaEk6Q==}
'@rollup/rollup-android-arm64@4.57.0':
resolution: {integrity: sha512-sa4LyseLLXr1onr97StkU1Nb7fWcg6niokTwEVNOO7awaKaoRObQ54+V/hrF/BP1noMEaaAW6Fg2d/CfLiq3Mg==}
cpu: [arm64]
os: [android]
'@rollup/rollup-darwin-arm64@4.56.0':
resolution: {integrity: sha512-EgxD1ocWfhoD6xSOeEEwyE7tDvwTgZc8Bss7wCWe+uc7wO8G34HHCUH+Q6cHqJubxIAnQzAsyUsClt0yFLu06w==}
'@rollup/rollup-darwin-arm64@4.57.0':
resolution: {integrity: sha512-/NNIj9A7yLjKdmkx5dC2XQ9DmjIECpGpwHoGmA5E1AhU0fuICSqSWScPhN1yLCkEdkCwJIDu2xIeLPs60MNIVg==}
cpu: [arm64]
os: [darwin]
'@rollup/rollup-darwin-x64@4.56.0':
resolution: {integrity: sha512-1vXe1vcMOssb/hOF8iv52A7feWW2xnu+c8BV4t1F//m9QVLTfNVpEdja5ia762j/UEJe2Z1jAmEqZAK42tVW3g==}
'@rollup/rollup-darwin-x64@4.57.0':
resolution: {integrity: sha512-xoh8abqgPrPYPr7pTYipqnUi1V3em56JzE/HgDgitTqZBZ3yKCWI+7KUkceM6tNweyUKYru1UMi7FC060RyKwA==}
cpu: [x64]
os: [darwin]
'@rollup/rollup-freebsd-arm64@4.56.0':
resolution: {integrity: sha512-bof7fbIlvqsyv/DtaXSck4VYQ9lPtoWNFCB/JY4snlFuJREXfZnm+Ej6yaCHfQvofJDXLDMTVxWscVSuQvVWUQ==}
'@rollup/rollup-freebsd-arm64@4.57.0':
resolution: {integrity: sha512-PCkMh7fNahWSbA0OTUQ2OpYHpjZZr0hPr8lId8twD7a7SeWrvT3xJVyza+dQwXSSq4yEQTMoXgNOfMCsn8584g==}
cpu: [arm64]
os: [freebsd]
'@rollup/rollup-freebsd-x64@4.56.0':
resolution: {integrity: sha512-KNa6lYHloW+7lTEkYGa37fpvPq+NKG/EHKM8+G/g9WDU7ls4sMqbVRV78J6LdNuVaeeK5WB9/9VAFbKxcbXKYg==}
'@rollup/rollup-freebsd-x64@4.57.0':
resolution: {integrity: sha512-1j3stGx+qbhXql4OCDZhnK7b01s6rBKNybfsX+TNrEe9JNq4DLi1yGiR1xW+nL+FNVvI4D02PUnl6gJ/2y6WJA==}
cpu: [x64]
os: [freebsd]
'@rollup/rollup-linux-arm-gnueabihf@4.56.0':
resolution: {integrity: sha512-E8jKK87uOvLrrLN28jnAAAChNq5LeCd2mGgZF+fGF5D507WlG/Noct3lP/QzQ6MrqJ5BCKNwI9ipADB6jyiq2A==}
'@rollup/rollup-linux-arm-gnueabihf@4.57.0':
resolution: {integrity: sha512-eyrr5W08Ms9uM0mLcKfM/Uzx7hjhz2bcjv8P2uynfj0yU8GGPdz8iYrBPhiLOZqahoAMB8ZiolRZPbbU2MAi6Q==}
cpu: [arm]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-arm-musleabihf@4.56.0':
resolution: {integrity: sha512-jQosa5FMYF5Z6prEpTCCmzCXz6eKr/tCBssSmQGEeozA9tkRUty/5Vx06ibaOP9RCrW1Pvb8yp3gvZhHwTDsJw==}
'@rollup/rollup-linux-arm-musleabihf@4.57.0':
resolution: {integrity: sha512-Xds90ITXJCNyX9pDhqf85MKWUI4lqjiPAipJ8OLp8xqI2Ehk+TCVhF9rvOoN8xTbcafow3QOThkNnrM33uCFQA==}
cpu: [arm]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-arm64-gnu@4.56.0':
resolution: {integrity: sha512-uQVoKkrC1KGEV6udrdVahASIsaF8h7iLG0U0W+Xn14ucFwi6uS539PsAr24IEF9/FoDtzMeeJXJIBo5RkbNWvQ==}
'@rollup/rollup-linux-arm64-gnu@4.57.0':
resolution: {integrity: sha512-Xws2KA4CLvZmXjy46SQaXSejuKPhwVdaNinldoYfqruZBaJHqVo6hnRa8SDo9z7PBW5x84SH64+izmldCgbezw==}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-arm64-musl@4.56.0':
resolution: {integrity: sha512-vLZ1yJKLxhQLFKTs42RwTwa6zkGln+bnXc8ueFGMYmBTLfNu58sl5/eXyxRa2RarTkJbXl8TKPgfS6V5ijNqEA==}
'@rollup/rollup-linux-arm64-musl@4.57.0':
resolution: {integrity: sha512-hrKXKbX5FdaRJj7lTMusmvKbhMJSGWJ+w++4KmjiDhpTgNlhYobMvKfDoIWecy4O60K6yA4SnztGuNTQF+Lplw==}
cpu: [arm64]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-loong64-gnu@4.56.0':
resolution: {integrity: sha512-FWfHOCub564kSE3xJQLLIC/hbKqHSVxy8vY75/YHHzWvbJL7aYJkdgwD/xGfUlL5UV2SB7otapLrcCj2xnF1dg==}
'@rollup/rollup-linux-loong64-gnu@4.57.0':
resolution: {integrity: sha512-6A+nccfSDGKsPm00d3xKcrsBcbqzCTAukjwWK6rbuAnB2bHaL3r9720HBVZ/no7+FhZLz/U3GwwZZEh6tOSI8Q==}
cpu: [loong64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-loong64-musl@4.56.0':
resolution: {integrity: sha512-z1EkujxIh7nbrKL1lmIpqFTc/sr0u8Uk0zK/qIEFldbt6EDKWFk/pxFq3gYj4Bjn3aa9eEhYRlL3H8ZbPT1xvA==}
'@rollup/rollup-linux-loong64-musl@4.57.0':
resolution: {integrity: sha512-4P1VyYUe6XAJtQH1Hh99THxr0GKMMwIXsRNOceLrJnaHTDgk1FTcTimDgneRJPvB3LqDQxUmroBclQ1S0cIJwQ==}
cpu: [loong64]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-ppc64-gnu@4.56.0':
resolution: {integrity: sha512-iNFTluqgdoQC7AIE8Q34R3AuPrJGJirj5wMUErxj22deOcY7XwZRaqYmB6ZKFHoVGqRcRd0mqO+845jAibKCkw==}
'@rollup/rollup-linux-ppc64-gnu@4.57.0':
resolution: {integrity: sha512-8Vv6pLuIZCMcgXre6c3nOPhE0gjz1+nZP6T+hwWjr7sVH8k0jRkH+XnfjjOTglyMBdSKBPPz54/y1gToSKwrSQ==}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-ppc64-musl@4.56.0':
resolution: {integrity: sha512-MtMeFVlD2LIKjp2sE2xM2slq3Zxf9zwVuw0jemsxvh1QOpHSsSzfNOTH9uYW9i1MXFxUSMmLpeVeUzoNOKBaWg==}
'@rollup/rollup-linux-ppc64-musl@4.57.0':
resolution: {integrity: sha512-r1te1M0Sm2TBVD/RxBPC6RZVwNqUTwJTA7w+C/IW5v9Ssu6xmxWEi+iJQlpBhtUiT1raJ5b48pI8tBvEjEFnFA==}
cpu: [ppc64]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-riscv64-gnu@4.56.0':
resolution: {integrity: sha512-in+v6wiHdzzVhYKXIk5U74dEZHdKN9KH0Q4ANHOTvyXPG41bajYRsy7a8TPKbYPl34hU7PP7hMVHRvv/5aCSew==}
'@rollup/rollup-linux-riscv64-gnu@4.57.0':
resolution: {integrity: sha512-say0uMU/RaPm3CDQLxUUTF2oNWL8ysvHkAjcCzV2znxBr23kFfaxocS9qJm+NdkRhF8wtdEEAJuYcLPhSPbjuQ==}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-riscv64-musl@4.56.0':
resolution: {integrity: sha512-yni2raKHB8m9NQpI9fPVwN754mn6dHQSbDTwxdr9SE0ks38DTjLMMBjrwvB5+mXrX+C0npX0CVeCUcvvvD8CNQ==}
'@rollup/rollup-linux-riscv64-musl@4.57.0':
resolution: {integrity: sha512-/MU7/HizQGsnBREtRpcSbSV1zfkoxSTR7wLsRmBPQ8FwUj5sykrP1MyJTvsxP5KBq9SyE6kH8UQQQwa0ASeoQQ==}
cpu: [riscv64]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-s390x-gnu@4.56.0':
resolution: {integrity: sha512-zhLLJx9nQPu7wezbxt2ut+CI4YlXi68ndEve16tPc/iwoylWS9B3FxpLS2PkmfYgDQtosah07Mj9E0khc3Y+vQ==}
'@rollup/rollup-linux-s390x-gnu@4.57.0':
resolution: {integrity: sha512-Q9eh+gUGILIHEaJf66aF6a414jQbDnn29zeu0eX3dHMuysnhTvsUvZTCAyZ6tJhUjnvzBKE4FtuaYxutxRZpOg==}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-x64-gnu@4.56.0':
resolution: {integrity: sha512-MVC6UDp16ZSH7x4rtuJPAEoE1RwS8N4oK9DLHy3FTEdFoUTCFVzMfJl/BVJ330C+hx8FfprA5Wqx4FhZXkj2Kw==}
'@rollup/rollup-linux-x64-gnu@4.57.0':
resolution: {integrity: sha512-OR5p5yG5OKSxHReWmwvM0P+VTPMwoBS45PXTMYaskKQqybkS3Kmugq1W+YbNWArF8/s7jQScgzXUhArzEQ7x0A==}
cpu: [x64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-x64-musl@4.56.0':
resolution: {integrity: sha512-ZhGH1eA4Qv0lxaV00azCIS1ChedK0V32952Md3FtnxSqZTBTd6tgil4nZT5cU8B+SIw3PFYkvyR4FKo2oyZIHA==}
'@rollup/rollup-linux-x64-musl@4.57.0':
resolution: {integrity: sha512-XeatKzo4lHDsVEbm1XDHZlhYZZSQYym6dg2X/Ko0kSFgio+KXLsxwJQprnR48GvdIKDOpqWqssC3iBCjoMcMpw==}
cpu: [x64]
os: [linux]
libc: [musl]
'@rollup/rollup-openbsd-x64@4.56.0':
resolution: {integrity: sha512-O16XcmyDeFI9879pEcmtWvD/2nyxR9mF7Gs44lf1vGGx8Vg2DRNx11aVXBEqOQhWb92WN4z7fW/q4+2NYzCbBA==}
'@rollup/rollup-openbsd-x64@4.57.0':
resolution: {integrity: sha512-Lu71y78F5qOfYmubYLHPcJm74GZLU6UJ4THkf/a1K7Tz2ycwC2VUbsqbJAXaR6Bx70SRdlVrt2+n5l7F0agTUw==}
cpu: [x64]
os: [openbsd]
'@rollup/rollup-openharmony-arm64@4.56.0':
resolution: {integrity: sha512-LhN/Reh+7F3RCgQIRbgw8ZMwUwyqJM+8pXNT6IIJAqm2IdKkzpCh/V9EdgOMBKuebIrzswqy4ATlrDgiOwbRcQ==}
'@rollup/rollup-openharmony-arm64@4.57.0':
resolution: {integrity: sha512-v5xwKDWcu7qhAEcsUubiav7r+48Uk/ENWdr82MBZZRIm7zThSxCIVDfb3ZeRRq9yqk+oIzMdDo6fCcA5DHfMyA==}
cpu: [arm64]
os: [openharmony]
'@rollup/rollup-win32-arm64-msvc@4.56.0':
resolution: {integrity: sha512-kbFsOObXp3LBULg1d3JIUQMa9Kv4UitDmpS+k0tinPBz3watcUiV2/LUDMMucA6pZO3WGE27P7DsfaN54l9ing==}
'@rollup/rollup-win32-arm64-msvc@4.57.0':
resolution: {integrity: sha512-XnaaaSMGSI6Wk8F4KK3QP7GfuuhjGchElsVerCplUuxRIzdvZ7hRBpLR0omCmw+kI2RFJB80nenhOoGXlJ5TfQ==}
cpu: [arm64]
os: [win32]
'@rollup/rollup-win32-ia32-msvc@4.56.0':
resolution: {integrity: sha512-vSSgny54D6P4vf2izbtFm/TcWYedw7f8eBrOiGGecyHyQB9q4Kqentjaj8hToe+995nob/Wv48pDqL5a62EWtg==}
'@rollup/rollup-win32-ia32-msvc@4.57.0':
resolution: {integrity: sha512-3K1lP+3BXY4t4VihLw5MEg6IZD3ojSYzqzBG571W3kNQe4G4CcFpSUQVgurYgib5d+YaCjeFow8QivWp8vuSvA==}
cpu: [ia32]
os: [win32]
'@rollup/rollup-win32-x64-gnu@4.56.0':
resolution: {integrity: sha512-FeCnkPCTHQJFbiGG49KjV5YGW/8b9rrXAM2Mz2kiIoktq2qsJxRD5giEMEOD2lPdgs72upzefaUvS+nc8E3UzQ==}
'@rollup/rollup-win32-x64-gnu@4.57.0':
resolution: {integrity: sha512-MDk610P/vJGc5L5ImE4k5s+GZT3en0KoK1MKPXCRgzmksAMk79j4h3k1IerxTNqwDLxsGxStEZVBqG0gIqZqoA==}
cpu: [x64]
os: [win32]
'@rollup/rollup-win32-x64-msvc@4.56.0':
resolution: {integrity: sha512-H8AE9Ur/t0+1VXujj90w0HrSOuv0Nq9r1vSZF2t5km20NTfosQsGGUXDaKdQZzwuLts7IyL1fYT4hM95TI9c4g==}
'@rollup/rollup-win32-x64-msvc@4.57.0':
resolution: {integrity: sha512-Zv7v6q6aV+VslnpwzqKAmrk5JdVkLUzok2208ZXGipjb+msxBr/fJPZyeEXiFgH7k62Ak0SLIfxQRZQvTuf7rQ==}
cpu: [x64]
os: [win32]
@ -628,8 +662,8 @@ packages:
array-iterate@2.0.1:
resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==}
astro@5.16.15:
resolution: {integrity: sha512-+X1Z0NTi2pa5a0Te6h77Dgc44fYj63j1yx6+39Nvg05lExajxSq7b1Uj/gtY45zoum8fD0+h0nak+DnHighs3A==}
astro@5.17.1:
resolution: {integrity: sha512-oD3tlxTaVWGq/Wfbqk6gxzVRz98xa/rYlpe+gU2jXJMSD01k6sEDL01ZlT8mVSYB/rMgnvIOfiQQ3BbLdN237A==}
engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'}
hasBin: true
@ -674,8 +708,8 @@ packages:
resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==}
engines: {node: '>= 20.19.0'}
ci-info@4.3.1:
resolution: {integrity: sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==}
ci-info@4.4.0:
resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==}
engines: {node: '>=8'}
cli-boxes@3.0.0:
@ -941,16 +975,10 @@ packages:
longest-streak@3.1.0:
resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
lru-cache@11.2.4:
resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==}
lru-cache@11.2.5:
resolution: {integrity: sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==}
engines: {node: 20 || >=22}
lucide-astro@0.556.0:
resolution: {integrity: sha512-ugMjPb45AMfkLCaduNSbyy5NQEKvB1TxVVMmUS4S6L807PMESnX0Qp+DIKHjbyjJmPXOyLRbrzvR3YikTK7brg==}
deprecated: 'Deprecated: Use `@lucide/astro`'
peerDependencies:
astro: '>=2.7.1'
magic-string@0.30.21:
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
@ -1239,8 +1267,8 @@ packages:
retext@9.0.0:
resolution: {integrity: sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==}
rollup@4.56.0:
resolution: {integrity: sha512-9FwVqlgUHzbXtDg9RCMgodF3Ua4Na6Gau+Sdt9vyCN4RhHfVKX2DCHy3BjMLTDd47ITDhYAnTwGulWTblJSDLg==}
rollup@4.57.0:
resolution: {integrity: sha512-e5lPJi/aui4TO1LpAXIRLySmwXSE8k3b9zoGfd42p67wzxog4WHjiZF3M2uheQih4DGyc25QEV4yRBbpueNiUA==}
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
hasBin: true
@ -1260,8 +1288,8 @@ packages:
shiki@3.21.0:
resolution: {integrity: sha512-N65B/3bqL/TI2crrXr+4UivctrAGEjmsib5rPMMPpFp1xAx/w03v8WZ9RDDFYteXoEgY7qZ4HGgl5KBIu1153w==}
simple-icons@16.6.0:
resolution: {integrity: sha512-lzSVlAhflhwud7EprwSalbCpHKpculOfaAk1P+S3QajO1bHG5nqwI1VeGnn4rwaE4xSSSKDsOFFL0XfIDv5iIQ==}
simple-icons@16.6.1:
resolution: {integrity: sha512-zg3g5RCnc3cJfxCclOvElfow2rtpeB+Ow/dj1uvGG3MkpT7OjPBrE2hotqW2Hmt2ZYbuXCx2u+Oh4yi5N+yg5Q==}
engines: {node: '>=0.12.18'}
sisteransi@1.0.5:
@ -1591,7 +1619,7 @@ snapshots:
'@astrojs/telemetry@3.3.0':
dependencies:
ci-info: 4.3.1
ci-info: 4.4.0
debug: 4.4.3
dlv: 1.1.3
dset: 3.1.4
@ -1800,89 +1828,93 @@ snapshots:
'@jridgewell/sourcemap-codec@1.5.5': {}
'@lucide/astro@0.563.0(astro@5.17.1(rollup@4.57.0)(typescript@5.9.3))':
dependencies:
astro: 5.17.1(rollup@4.57.0)(typescript@5.9.3)
'@oslojs/encoding@1.1.0': {}
'@rollup/pluginutils@5.3.0(rollup@4.56.0)':
'@rollup/pluginutils@5.3.0(rollup@4.57.0)':
dependencies:
'@types/estree': 1.0.8
estree-walker: 2.0.2
picomatch: 4.0.3
optionalDependencies:
rollup: 4.56.0
rollup: 4.57.0
'@rollup/rollup-android-arm-eabi@4.56.0':
'@rollup/rollup-android-arm-eabi@4.57.0':
optional: true
'@rollup/rollup-android-arm64@4.56.0':
'@rollup/rollup-android-arm64@4.57.0':
optional: true
'@rollup/rollup-darwin-arm64@4.56.0':
'@rollup/rollup-darwin-arm64@4.57.0':
optional: true
'@rollup/rollup-darwin-x64@4.56.0':
'@rollup/rollup-darwin-x64@4.57.0':
optional: true
'@rollup/rollup-freebsd-arm64@4.56.0':
'@rollup/rollup-freebsd-arm64@4.57.0':
optional: true
'@rollup/rollup-freebsd-x64@4.56.0':
'@rollup/rollup-freebsd-x64@4.57.0':
optional: true
'@rollup/rollup-linux-arm-gnueabihf@4.56.0':
'@rollup/rollup-linux-arm-gnueabihf@4.57.0':
optional: true
'@rollup/rollup-linux-arm-musleabihf@4.56.0':
'@rollup/rollup-linux-arm-musleabihf@4.57.0':
optional: true
'@rollup/rollup-linux-arm64-gnu@4.56.0':
'@rollup/rollup-linux-arm64-gnu@4.57.0':
optional: true
'@rollup/rollup-linux-arm64-musl@4.56.0':
'@rollup/rollup-linux-arm64-musl@4.57.0':
optional: true
'@rollup/rollup-linux-loong64-gnu@4.56.0':
'@rollup/rollup-linux-loong64-gnu@4.57.0':
optional: true
'@rollup/rollup-linux-loong64-musl@4.56.0':
'@rollup/rollup-linux-loong64-musl@4.57.0':
optional: true
'@rollup/rollup-linux-ppc64-gnu@4.56.0':
'@rollup/rollup-linux-ppc64-gnu@4.57.0':
optional: true
'@rollup/rollup-linux-ppc64-musl@4.56.0':
'@rollup/rollup-linux-ppc64-musl@4.57.0':
optional: true
'@rollup/rollup-linux-riscv64-gnu@4.56.0':
'@rollup/rollup-linux-riscv64-gnu@4.57.0':
optional: true
'@rollup/rollup-linux-riscv64-musl@4.56.0':
'@rollup/rollup-linux-riscv64-musl@4.57.0':
optional: true
'@rollup/rollup-linux-s390x-gnu@4.56.0':
'@rollup/rollup-linux-s390x-gnu@4.57.0':
optional: true
'@rollup/rollup-linux-x64-gnu@4.56.0':
'@rollup/rollup-linux-x64-gnu@4.57.0':
optional: true
'@rollup/rollup-linux-x64-musl@4.56.0':
'@rollup/rollup-linux-x64-musl@4.57.0':
optional: true
'@rollup/rollup-openbsd-x64@4.56.0':
'@rollup/rollup-openbsd-x64@4.57.0':
optional: true
'@rollup/rollup-openharmony-arm64@4.56.0':
'@rollup/rollup-openharmony-arm64@4.57.0':
optional: true
'@rollup/rollup-win32-arm64-msvc@4.56.0':
'@rollup/rollup-win32-arm64-msvc@4.57.0':
optional: true
'@rollup/rollup-win32-ia32-msvc@4.56.0':
'@rollup/rollup-win32-ia32-msvc@4.57.0':
optional: true
'@rollup/rollup-win32-x64-gnu@4.56.0':
'@rollup/rollup-win32-x64-gnu@4.57.0':
optional: true
'@rollup/rollup-win32-x64-msvc@4.56.0':
'@rollup/rollup-win32-x64-msvc@4.57.0':
optional: true
'@shikijs/core@3.21.0':
@ -1969,7 +2001,7 @@ snapshots:
array-iterate@2.0.1: {}
astro@5.16.15(rollup@4.56.0)(typescript@5.9.3):
astro@5.17.1(rollup@4.57.0)(typescript@5.9.3):
dependencies:
'@astrojs/compiler': 2.13.0
'@astrojs/internal-helpers': 0.7.5
@ -1977,12 +2009,12 @@ snapshots:
'@astrojs/telemetry': 3.3.0
'@capsizecss/unpack': 4.0.0
'@oslojs/encoding': 1.1.0
'@rollup/pluginutils': 5.3.0(rollup@4.56.0)
'@rollup/pluginutils': 5.3.0(rollup@4.57.0)
acorn: 8.15.0
aria-query: 5.3.2
axobject-query: 4.1.0
boxen: 8.0.1
ci-info: 4.3.1
ci-info: 4.4.0
clsx: 2.1.1
common-ancestor-path: 1.0.1
cookie: 1.1.1
@ -2106,7 +2138,7 @@ snapshots:
dependencies:
readdirp: 5.0.0
ci-info@4.3.1: {}
ci-info@4.4.0: {}
cli-boxes@3.0.0: {}
@ -2406,11 +2438,7 @@ snapshots:
longest-streak@3.1.0: {}
lru-cache@11.2.4: {}
lucide-astro@0.556.0(astro@5.16.15(rollup@4.56.0)(typescript@5.9.3)):
dependencies:
astro: 5.16.15(rollup@4.56.0)(typescript@5.9.3)
lru-cache@11.2.5: {}
magic-string@0.30.21:
dependencies:
@ -2931,35 +2959,35 @@ snapshots:
retext-stringify: 4.0.0
unified: 11.0.5
rollup@4.56.0:
rollup@4.57.0:
dependencies:
'@types/estree': 1.0.8
optionalDependencies:
'@rollup/rollup-android-arm-eabi': 4.56.0
'@rollup/rollup-android-arm64': 4.56.0
'@rollup/rollup-darwin-arm64': 4.56.0
'@rollup/rollup-darwin-x64': 4.56.0
'@rollup/rollup-freebsd-arm64': 4.56.0
'@rollup/rollup-freebsd-x64': 4.56.0
'@rollup/rollup-linux-arm-gnueabihf': 4.56.0
'@rollup/rollup-linux-arm-musleabihf': 4.56.0
'@rollup/rollup-linux-arm64-gnu': 4.56.0
'@rollup/rollup-linux-arm64-musl': 4.56.0
'@rollup/rollup-linux-loong64-gnu': 4.56.0
'@rollup/rollup-linux-loong64-musl': 4.56.0
'@rollup/rollup-linux-ppc64-gnu': 4.56.0
'@rollup/rollup-linux-ppc64-musl': 4.56.0
'@rollup/rollup-linux-riscv64-gnu': 4.56.0
'@rollup/rollup-linux-riscv64-musl': 4.56.0
'@rollup/rollup-linux-s390x-gnu': 4.56.0
'@rollup/rollup-linux-x64-gnu': 4.56.0
'@rollup/rollup-linux-x64-musl': 4.56.0
'@rollup/rollup-openbsd-x64': 4.56.0
'@rollup/rollup-openharmony-arm64': 4.56.0
'@rollup/rollup-win32-arm64-msvc': 4.56.0
'@rollup/rollup-win32-ia32-msvc': 4.56.0
'@rollup/rollup-win32-x64-gnu': 4.56.0
'@rollup/rollup-win32-x64-msvc': 4.56.0
'@rollup/rollup-android-arm-eabi': 4.57.0
'@rollup/rollup-android-arm64': 4.57.0
'@rollup/rollup-darwin-arm64': 4.57.0
'@rollup/rollup-darwin-x64': 4.57.0
'@rollup/rollup-freebsd-arm64': 4.57.0
'@rollup/rollup-freebsd-x64': 4.57.0
'@rollup/rollup-linux-arm-gnueabihf': 4.57.0
'@rollup/rollup-linux-arm-musleabihf': 4.57.0
'@rollup/rollup-linux-arm64-gnu': 4.57.0
'@rollup/rollup-linux-arm64-musl': 4.57.0
'@rollup/rollup-linux-loong64-gnu': 4.57.0
'@rollup/rollup-linux-loong64-musl': 4.57.0
'@rollup/rollup-linux-ppc64-gnu': 4.57.0
'@rollup/rollup-linux-ppc64-musl': 4.57.0
'@rollup/rollup-linux-riscv64-gnu': 4.57.0
'@rollup/rollup-linux-riscv64-musl': 4.57.0
'@rollup/rollup-linux-s390x-gnu': 4.57.0
'@rollup/rollup-linux-x64-gnu': 4.57.0
'@rollup/rollup-linux-x64-musl': 4.57.0
'@rollup/rollup-openbsd-x64': 4.57.0
'@rollup/rollup-openharmony-arm64': 4.57.0
'@rollup/rollup-win32-arm64-msvc': 4.57.0
'@rollup/rollup-win32-ia32-msvc': 4.57.0
'@rollup/rollup-win32-x64-gnu': 4.57.0
'@rollup/rollup-win32-x64-msvc': 4.57.0
fsevents: 2.3.3
sax@1.4.4: {}
@ -3009,7 +3037,7 @@ snapshots:
'@shikijs/vscode-textmate': 10.0.2
'@types/hast': 3.0.4
simple-icons@16.6.0: {}
simple-icons@16.6.1: {}
sisteransi@1.0.5: {}
@ -3148,7 +3176,7 @@ snapshots:
chokidar: 5.0.0
destr: 2.0.5
h3: 1.15.5
lru-cache: 11.2.4
lru-cache: 11.2.5
node-fetch-native: 1.6.7
ofetch: 1.5.1
ufo: 1.6.3
@ -3174,7 +3202,7 @@ snapshots:
fdir: 6.5.0(picomatch@4.0.3)
picomatch: 4.0.3
postcss: 8.5.6
rollup: 4.56.0
rollup: 4.57.0
tinyglobby: 0.2.15
optionalDependencies:
fsevents: 2.3.3

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

View File

@ -1,51 +1,32 @@
#!/usr/bin/env bash
set -euo pipefail
# Moltbot CLI installer (non-interactive, no onboarding)
# Usage: curl -fsSL --proto '=https' --tlsv1.2 https://molt.bot/install-cli.sh | bash -s -- [options]
# OpenClaw CLI installer (non-interactive, no onboarding)
# Usage: curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install-cli.sh | bash -s -- [--json] [--prefix <path>] [--version <ver>] [--node-version <ver>] [--onboard]
PREFIX="${CLAWDBOT_PREFIX:-${HOME}/.clawdbot}"
CLAWDBOT_VERSION="${CLAWDBOT_VERSION:-latest}"
NODE_VERSION="${CLAWDBOT_NODE_VERSION:-22.22.0}"
PREFIX="${OPENCLAW_PREFIX:-${HOME}/.openclaw}"
OPENCLAW_VERSION="${OPENCLAW_VERSION:-latest}"
NODE_VERSION="${OPENCLAW_NODE_VERSION:-22.22.0}"
SHARP_IGNORE_GLOBAL_LIBVIPS="${SHARP_IGNORE_GLOBAL_LIBVIPS:-1}"
NPM_LOGLEVEL="${CLAWDBOT_NPM_LOGLEVEL:-error}"
INSTALL_METHOD="${CLAWDBOT_INSTALL_METHOD:-npm}"
GIT_DIR="${CLAWDBOT_GIT_DIR:-${HOME}/moltbot}"
GIT_UPDATE="${CLAWDBOT_GIT_UPDATE:-1}"
NPM_LOGLEVEL="${OPENCLAW_NPM_LOGLEVEL:-error}"
JSON=0
RUN_ONBOARD=0
SET_NPM_PREFIX=0
print_usage() {
cat <<EOF
Moltbot CLI installer (macOS + Linux)
Usage:
curl -fsSL --proto '=https' --tlsv1.2 https://molt.bot/install-cli.sh | bash -s -- [options]
Options:
--json Emit NDJSON events (no human output)
--prefix <path> Install prefix (default: ~/.clawdbot)
--install-method, --method npm|git Install via npm (default) or from a git checkout
--npm Shortcut for --install-method npm
--git, --github Shortcut for --install-method git
--version <version|dist-tag> npm install: version (default: latest)
--git-dir, --dir <path> Checkout directory (default: ~/moltbot)
--no-git-update Skip git pull for existing checkout
--node-version <ver> Node version (default: 22.22.0)
--onboard Run "clawdbot onboard" after install
--no-onboard Skip onboarding (default)
--set-npm-prefix Force npm prefix to ~/.npm-global if current prefix is not writable (Linux)
--help, -h Show this help
Usage: install-cli.sh [options]
--json Emit NDJSON events (no human output)
--prefix <path> Install prefix (default: ~/.openclaw)
--version <ver> OpenClaw version (default: latest)
--node-version <ver> Node version (default: 22.22.0)
--onboard Run "openclaw onboard" after install
--no-onboard Skip onboarding (default)
--set-npm-prefix Force npm prefix to ~/.npm-global if current prefix is not writable (Linux)
Environment variables:
CLAWDBOT_INSTALL_METHOD=git|npm
CLAWDBOT_VERSION=latest|next|<semver>
CLAWDBOT_GIT_DIR=...
CLAWDBOT_GIT_UPDATE=0|1
CLAWDBOT_NPM_LOGLEVEL=error|warn|notice Default: error (hide npm deprecation noise)
SHARP_IGNORE_GLOBAL_LIBVIPS=0|1 Default: 1 (avoid sharp building against global libvips)
OPENCLAW_NPM_LOGLEVEL=error|warn|notice Default: error (hide npm deprecation noise)
EOF
}
@ -82,7 +63,7 @@ download_file() {
}
cleanup_legacy_submodules() {
local repo_dir="${1:-${CLAWDBOT_GIT_DIR:-${HOME}/clawdbot}}"
local repo_dir="${OPENCLAW_GIT_DIR:-${HOME}/openclaw}"
local legacy_dir="${repo_dir}/Peekaboo"
if [[ -d "$legacy_dir" ]]; then
emit_json "{\"event\":\"step\",\"name\":\"legacy-submodule\",\"status\":\"start\",\"path\":\"${legacy_dir//\"/\\\"}\"}"
@ -206,33 +187,13 @@ parse_args() {
shift 2
;;
--version)
CLAWDBOT_VERSION="$2"
OPENCLAW_VERSION="$2"
shift 2
;;
--node-version)
NODE_VERSION="$2"
shift 2
;;
--install-method|--method)
INSTALL_METHOD="$2"
shift 2
;;
--npm)
INSTALL_METHOD="npm"
shift
;;
--git|--github)
INSTALL_METHOD="git"
shift
;;
--git-dir|--dir)
GIT_DIR="$2"
shift 2
;;
--no-git-update)
GIT_UPDATE=0
shift
;;
--onboard)
RUN_ONBOARD=1
shift
@ -349,27 +310,6 @@ install_node() {
emit_json "{\"event\":\"step\",\"name\":\"node\",\"status\":\"ok\",\"version\":\"${NODE_VERSION}\"}"
}
ensure_pnpm() {
if command -v pnpm >/dev/null 2>&1; then
return 0
fi
if [[ -x "$(node_dir)/bin/corepack" ]]; then
emit_json "{\"event\":\"step\",\"name\":\"pnpm\",\"status\":\"start\",\"method\":\"corepack\"}"
log "Installing pnpm via Corepack..."
"$(node_dir)/bin/corepack" enable >/dev/null 2>&1 || true
"$(node_dir)/bin/corepack" prepare pnpm@10 --activate
emit_json "{\"event\":\"step\",\"name\":\"pnpm\",\"status\":\"ok\"}"
return 0
fi
emit_json "{\"event\":\"step\",\"name\":\"pnpm\",\"status\":\"start\",\"method\":\"npm\"}"
log "Installing pnpm via npm..."
SHARP_IGNORE_GLOBAL_LIBVIPS="$SHARP_IGNORE_GLOBAL_LIBVIPS" "$(npm_bin)" install -g --prefix "$PREFIX" pnpm@10
emit_json "{\"event\":\"step\",\"name\":\"pnpm\",\"status\":\"ok\"}"
return 0
}
fix_npm_prefix_if_needed() {
# only meaningful on Linux, non-root installs
if [[ "$(os_detect)" != "linux" ]]; then
@ -402,97 +342,44 @@ fix_npm_prefix_if_needed() {
log "Configured npm prefix to ${target}"
}
install_clawdbot() {
local requested="${CLAWDBOT_VERSION:-latest}"
install_openclaw() {
local requested="${OPENCLAW_VERSION:-latest}"
local npm_args=(
--loglevel "$NPM_LOGLEVEL"
--no-fund
--no-audit
)
emit_json "{\"event\":\"step\",\"name\":\"clawdbot\",\"status\":\"start\",\"version\":\"${requested}\"}"
log "Installing Moltbot (${requested})..."
emit_json "{\"event\":\"step\",\"name\":\"openclaw\",\"status\":\"start\",\"version\":\"${requested}\"}"
log "Installing OpenClaw (${requested})..."
if [[ "$SET_NPM_PREFIX" -eq 1 ]]; then
fix_npm_prefix_if_needed
fi
if [[ "${requested}" == "latest" ]]; then
if ! SHARP_IGNORE_GLOBAL_LIBVIPS="$SHARP_IGNORE_GLOBAL_LIBVIPS" "$(npm_bin)" install -g --prefix "$PREFIX" "${npm_args[@]}" "clawdbot@latest"; then
log "npm install clawdbot@latest failed; retrying clawdbot@next"
emit_json "{\"event\":\"step\",\"name\":\"clawdbot\",\"status\":\"retry\",\"version\":\"next\"}"
SHARP_IGNORE_GLOBAL_LIBVIPS="$SHARP_IGNORE_GLOBAL_LIBVIPS" "$(npm_bin)" install -g --prefix "$PREFIX" "${npm_args[@]}" "clawdbot@next"
if ! SHARP_IGNORE_GLOBAL_LIBVIPS="$SHARP_IGNORE_GLOBAL_LIBVIPS" "$(npm_bin)" install -g --prefix "$PREFIX" "${npm_args[@]}" "openclaw@latest"; then
log "npm install openclaw@latest failed; retrying openclaw@next"
emit_json "{\"event\":\"step\",\"name\":\"openclaw\",\"status\":\"retry\",\"version\":\"next\"}"
SHARP_IGNORE_GLOBAL_LIBVIPS="$SHARP_IGNORE_GLOBAL_LIBVIPS" "$(npm_bin)" install -g --prefix "$PREFIX" "${npm_args[@]}" "openclaw@next"
requested="next"
fi
else
SHARP_IGNORE_GLOBAL_LIBVIPS="$SHARP_IGNORE_GLOBAL_LIBVIPS" "$(npm_bin)" install -g --prefix "$PREFIX" "${npm_args[@]}" "clawdbot@${requested}"
SHARP_IGNORE_GLOBAL_LIBVIPS="$SHARP_IGNORE_GLOBAL_LIBVIPS" "$(npm_bin)" install -g --prefix "$PREFIX" "${npm_args[@]}" "openclaw@${requested}"
fi
rm -f "${PREFIX}/bin/clawdbot"
cat > "${PREFIX}/bin/clawdbot" <<EOF
rm -f "${PREFIX}/bin/openclaw"
cat > "${PREFIX}/bin/openclaw" <<EOF
#!/usr/bin/env bash
set -euo pipefail
exec "${PREFIX}/tools/node/bin/node" "${PREFIX}/lib/node_modules/clawdbot/dist/entry.js" "\$@"
exec "${PREFIX}/tools/node/bin/node" "${PREFIX}/lib/node_modules/openclaw/dist/entry.js" "\$@"
EOF
chmod +x "${PREFIX}/bin/clawdbot"
emit_json "{\"event\":\"step\",\"name\":\"clawdbot\",\"status\":\"ok\",\"version\":\"${requested}\"}"
chmod +x "${PREFIX}/bin/openclaw"
emit_json "{\"event\":\"step\",\"name\":\"openclaw\",\"status\":\"ok\",\"version\":\"${requested}\"}"
}
install_clawdbot_from_git() {
local repo_dir="$1"
local repo_url="https://github.com/moltbot/moltbot.git"
emit_json "{\"event\":\"step\",\"name\":\"clawdbot\",\"status\":\"start\",\"method\":\"git\",\"repo\":\"${repo_url//\"/\\\"}\"}"
if [[ -d "$repo_dir/.git" ]]; then
log "Installing Moltbot from git checkout: ${repo_dir}"
else
log "Installing Moltbot from GitHub (${repo_url})..."
fi
ensure_git
ensure_pnpm
if [[ -d "$repo_dir/.git" ]]; then
:
elif [[ -d "$repo_dir" ]]; then
if [[ -z "$(ls -A "$repo_dir" 2>/dev/null || true)" ]]; then
git clone "$repo_url" "$repo_dir"
else
fail "Git install dir exists but is not a git repo: ${repo_dir}"
fi
else
git clone "$repo_url" "$repo_dir"
fi
if [[ "$GIT_UPDATE" == "1" ]]; then
if [[ -z "$(git -C "$repo_dir" status --porcelain 2>/dev/null || true)" ]]; then
git -C "$repo_dir" pull --rebase || true
else
log "Repo is dirty; skipping git pull"
fi
fi
cleanup_legacy_submodules "$repo_dir"
SHARP_IGNORE_GLOBAL_LIBVIPS="$SHARP_IGNORE_GLOBAL_LIBVIPS" pnpm -C "$repo_dir" install
if ! pnpm -C "$repo_dir" ui:build; then
log "UI build failed; continuing (CLI may still work)"
fi
pnpm -C "$repo_dir" build
mkdir -p "${PREFIX}/bin"
cat > "${PREFIX}/bin/clawdbot" <<EOF
#!/usr/bin/env bash
set -euo pipefail
exec "${PREFIX}/tools/node/bin/node" "${repo_dir}/dist/entry.js" "\$@"
EOF
chmod +x "${PREFIX}/bin/clawdbot"
emit_json "{\"event\":\"step\",\"name\":\"clawdbot\",\"status\":\"ok\",\"method\":\"git\"}"
}
resolve_clawdbot_version() {
resolve_openclaw_version() {
local version=""
if [[ -x "${PREFIX}/bin/clawdbot" ]]; then
version="$("${PREFIX}/bin/clawdbot" --version 2>/dev/null | head -n 1 | tr -d '\r')"
if [[ -x "${PREFIX}/bin/openclaw" ]]; then
version="$("${PREFIX}/bin/openclaw" --version 2>/dev/null | head -n 1 | tr -d '\r')"
fi
echo "$version"
}
@ -500,7 +387,7 @@ resolve_clawdbot_version() {
main() {
parse_args "$@"
if [[ "${CLAWDBOT_NO_ONBOARD:-0}" == "1" ]]; then
if [[ "${OPENCLAW_NO_ONBOARD:-0}" == "1" ]]; then
RUN_ONBOARD=0
fi
@ -510,30 +397,24 @@ main() {
export PATH
install_node
if [[ "$INSTALL_METHOD" == "git" ]]; then
install_clawdbot_from_git "$GIT_DIR"
elif [[ "$INSTALL_METHOD" == "npm" ]]; then
ensure_git
if [[ "$SET_NPM_PREFIX" -eq 1 ]]; then
fix_npm_prefix_if_needed
fi
install_clawdbot
else
fail "Unknown install method: ${INSTALL_METHOD} (use npm or git)"
ensure_git
if [[ "$SET_NPM_PREFIX" -eq 1 ]]; then
fix_npm_prefix_if_needed
fi
install_openclaw
local installed_version
installed_version="$(resolve_clawdbot_version)"
installed_version="$(resolve_openclaw_version)"
if [[ -n "$installed_version" ]]; then
emit_json "{\"event\":\"done\",\"ok\":true,\"version\":\"${installed_version//\"/\\\"}\"}"
log "Moltbot installed (${installed_version})."
log "OpenClaw installed (${installed_version})."
else
emit_json "{\"event\":\"done\",\"ok\":true}"
log "Moltbot installed."
log "OpenClaw installed."
fi
if [[ "$RUN_ONBOARD" -eq 1 ]]; then
"${PREFIX}/bin/clawdbot" onboard
"${PREFIX}/bin/openclaw" onboard
fi
}

View File

@ -1,9 +1,9 @@
@echo off
setlocal enabledelayedexpansion
REM Moltbot Windows CMD installer
REM OpenClaw Windows CMD installer
REM Usage:
REM curl -fsSL https://molt.bot/install.cmd -o install.cmd && install.cmd --no-onboard && del install.cmd
REM curl -fsSL https://openclaw.ai/install.cmd -o install.cmd && install.cmd --no-onboard && del install.cmd
set "TAG=latest"
set "INSTALL_METHOD=npm"
@ -60,10 +60,10 @@ if %ERRORLEVEL% neq 0 (
exit /b 1
)
set "TMP=%TEMP%\clawdbot-install.ps1"
set "TMP=%TEMP%\openclaw-install.ps1"
REM TMP may include spaces; always quote "%TMP%" when used.
if not "%CLAWDBOT_INSTALL_PS1_URL%"=="" set "INSTALL_PS1_URL=%CLAWDBOT_INSTALL_PS1_URL%"
if "%INSTALL_PS1_URL%"=="" set "INSTALL_PS1_URL=https://molt.bot/install.ps1"
if not "%OPENCLAW_INSTALL_PS1_URL%"=="" set "INSTALL_PS1_URL=%OPENCLAW_INSTALL_PS1_URL%"
if "%INSTALL_PS1_URL%"=="" set "INSTALL_PS1_URL=https://openclaw.ai/install.ps1"
if exist "%INSTALL_PS1_URL%" (
copy /Y "%INSTALL_PS1_URL%" "%TMP%" >nul

View File

@ -1,6 +1,6 @@
# Moltbot Installer for Windows
# Usage: iwr -useb https://molt.bot/install.ps1 | iex
# & ([scriptblock]::Create((iwr -useb https://molt.bot/install.ps1))) -Tag beta -NoOnboard -DryRun
# OpenClaw Installer for Windows
# Usage: iwr -useb https://openclaw.ai/install.ps1 | iex
# & ([scriptblock]::Create((iwr -useb https://openclaw.ai/install.ps1))) -Tag beta -NoOnboard -DryRun
param(
[string]$Tag = "latest",
@ -15,7 +15,7 @@ param(
$ErrorActionPreference = "Stop"
Write-Host ""
Write-Host " Moltbot Installer" -ForegroundColor Cyan
Write-Host " OpenClaw Installer" -ForegroundColor Cyan
Write-Host ""
# Check if running in PowerShell
@ -27,34 +27,34 @@ if ($PSVersionTable.PSVersion.Major -lt 5) {
Write-Host "[OK] Windows detected" -ForegroundColor Green
if (-not $PSBoundParameters.ContainsKey("InstallMethod")) {
if (-not [string]::IsNullOrWhiteSpace($env:CLAWDBOT_INSTALL_METHOD)) {
$InstallMethod = $env:CLAWDBOT_INSTALL_METHOD
if (-not [string]::IsNullOrWhiteSpace($env:OPENCLAW_INSTALL_METHOD)) {
$InstallMethod = $env:OPENCLAW_INSTALL_METHOD
}
}
if (-not $PSBoundParameters.ContainsKey("GitDir")) {
if (-not [string]::IsNullOrWhiteSpace($env:CLAWDBOT_GIT_DIR)) {
$GitDir = $env:CLAWDBOT_GIT_DIR
if (-not [string]::IsNullOrWhiteSpace($env:OPENCLAW_GIT_DIR)) {
$GitDir = $env:OPENCLAW_GIT_DIR
}
}
if (-not $PSBoundParameters.ContainsKey("NoOnboard")) {
if ($env:CLAWDBOT_NO_ONBOARD -eq "1") {
if ($env:OPENCLAW_NO_ONBOARD -eq "1") {
$NoOnboard = $true
}
}
if (-not $PSBoundParameters.ContainsKey("NoGitUpdate")) {
if ($env:CLAWDBOT_GIT_UPDATE -eq "0") {
if ($env:OPENCLAW_GIT_UPDATE -eq "0") {
$NoGitUpdate = $true
}
}
if (-not $PSBoundParameters.ContainsKey("DryRun")) {
if ($env:CLAWDBOT_DRY_RUN -eq "1") {
if ($env:OPENCLAW_DRY_RUN -eq "1") {
$DryRun = $true
}
}
if ([string]::IsNullOrWhiteSpace($GitDir)) {
$userHome = [Environment]::GetFolderPath("UserProfile")
$GitDir = (Join-Path $userHome "clawdbot")
$GitDir = (Join-Path $userHome "openclaw")
}
# Check for Node.js
@ -123,11 +123,11 @@ function Install-Node {
exit 1
}
# Check for existing Moltbot installation
function Check-ExistingMoltbot {
# Check for existing OpenClaw installation
function Check-ExistingOpenClaw {
try {
$null = Get-Command clawdbot -ErrorAction Stop
Write-Host "[*] Existing Moltbot installation detected" -ForegroundColor Yellow
$null = Get-Command openclaw -ErrorAction Stop
Write-Host "[*] Existing OpenClaw installation detected" -ForegroundColor Yellow
return $true
} catch {
return $false
@ -153,8 +153,8 @@ function Require-Git {
exit 1
}
function Ensure-MoltbotOnPath {
if (Get-Command clawdbot -ErrorAction SilentlyContinue) {
function Ensure-OpenClawOnPath {
if (Get-Command openclaw -ErrorAction SilentlyContinue) {
return $true
}
@ -173,12 +173,12 @@ function Ensure-MoltbotOnPath {
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
Write-Host "[!] Added $npmBin to user PATH (restart terminal if command not found)" -ForegroundColor Yellow
}
if (Test-Path (Join-Path $npmBin "clawdbot.cmd")) {
if (Test-Path (Join-Path $npmBin "openclaw.cmd")) {
return $true
}
}
Write-Host "[!] clawdbot is not on PATH yet." -ForegroundColor Yellow
Write-Host "[!] openclaw is not on PATH yet." -ForegroundColor Yellow
Write-Host "Restart PowerShell or add the npm global bin folder to PATH." -ForegroundColor Yellow
if ($npmPrefix) {
Write-Host "Expected path: $npmPrefix\\bin" -ForegroundColor Cyan
@ -209,12 +209,17 @@ function Ensure-Pnpm {
Write-Host "[OK] pnpm installed" -ForegroundColor Green
}
# Install Moltbot
function Install-Moltbot {
# Install OpenClaw
function Install-OpenClaw {
if ([string]::IsNullOrWhiteSpace($Tag)) {
$Tag = "latest"
}
Write-Host "[*] Installing Moltbot@$Tag..." -ForegroundColor Yellow
# Use openclaw package for beta, openclaw for stable
$packageName = "openclaw"
if ($Tag -eq "beta" -or $Tag -match "^beta\.") {
$packageName = "openclaw"
}
Write-Host "[*] Installing OpenClaw ($packageName@$Tag)..." -ForegroundColor Yellow
$prevLogLevel = $env:NPM_CONFIG_LOGLEVEL
$prevUpdateNotifier = $env:NPM_CONFIG_UPDATE_NOTIFIER
$prevFund = $env:NPM_CONFIG_FUND
@ -224,7 +229,7 @@ function Install-Moltbot {
$env:NPM_CONFIG_FUND = "false"
$env:NPM_CONFIG_AUDIT = "false"
try {
$npmOutput = npm install -g "clawdbot@$Tag" 2>&1
$npmOutput = npm install -g "$packageName@$Tag" 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Host "[!] npm install failed" -ForegroundColor Red
if ($npmOutput -match "spawn git" -or $npmOutput -match "ENOENT.*git") {
@ -233,7 +238,7 @@ function Install-Moltbot {
Write-Host " https://git-scm.com/download/win" -ForegroundColor Cyan
} else {
Write-Host "Re-run with verbose output to see the full error:" -ForegroundColor Yellow
Write-Host " iwr -useb https://molt.bot/install.ps1 | iex" -ForegroundColor Cyan
Write-Host " iwr -useb https://openclaw.ai/install.ps1 | iex" -ForegroundColor Cyan
}
$npmOutput | ForEach-Object { Write-Host $_ }
exit 1
@ -244,11 +249,11 @@ function Install-Moltbot {
$env:NPM_CONFIG_FUND = $prevFund
$env:NPM_CONFIG_AUDIT = $prevAudit
}
Write-Host "[OK] Moltbot installed" -ForegroundColor Green
Write-Host "[OK] OpenClaw installed" -ForegroundColor Green
}
# Install Moltbot from GitHub
function Install-MoltbotFromGit {
# Install OpenClaw from GitHub
function Install-OpenClawFromGit {
param(
[string]$RepoDir,
[switch]$SkipUpdate
@ -256,8 +261,8 @@ function Install-MoltbotFromGit {
Require-Git
Ensure-Pnpm
$repoUrl = "https://github.com/clawdbot/clawdbot.git"
Write-Host "[*] Installing Moltbot from GitHub ($repoUrl)..." -ForegroundColor Yellow
$repoUrl = "https://github.com/openclaw/openclaw.git"
Write-Host "[*] Installing OpenClaw from GitHub ($repoUrl)..." -ForegroundColor Yellow
if (-not (Test-Path $RepoDir)) {
git clone $repoUrl $RepoDir
@ -285,7 +290,7 @@ function Install-MoltbotFromGit {
if (-not (Test-Path $binDir)) {
New-Item -ItemType Directory -Force -Path $binDir | Out-Null
}
$cmdPath = Join-Path $binDir "clawdbot.cmd"
$cmdPath = Join-Path $binDir "openclaw.cmd"
$cmdContents = "@echo off`r`nnode ""$RepoDir\\dist\\entry.js"" %*`r`n"
Set-Content -Path $cmdPath -Value $cmdContents -NoNewline
@ -296,7 +301,7 @@ function Install-MoltbotFromGit {
Write-Host "[!] Added $binDir to user PATH (restart terminal if command not found)" -ForegroundColor Yellow
}
Write-Host "[OK] Moltbot wrapper installed to $cmdPath" -ForegroundColor Green
Write-Host "[OK] OpenClaw wrapper installed to $cmdPath" -ForegroundColor Green
Write-Host "[i] This checkout uses pnpm. For deps, run: pnpm install (avoid npm install in the repo)." -ForegroundColor Gray
}
@ -304,7 +309,7 @@ function Install-MoltbotFromGit {
function Run-Doctor {
Write-Host "[*] Running doctor to migrate settings..." -ForegroundColor Yellow
try {
clawdbot doctor --non-interactive
openclaw doctor --non-interactive
} catch {
# Ignore errors from doctor
}
@ -312,11 +317,11 @@ function Run-Doctor {
}
function Get-LegacyRepoDir {
if (-not [string]::IsNullOrWhiteSpace($env:CLAWDBOT_GIT_DIR)) {
return $env:CLAWDBOT_GIT_DIR
if (-not [string]::IsNullOrWhiteSpace($env:OPENCLAW_GIT_DIR)) {
return $env:OPENCLAW_GIT_DIR
}
$userHome = [Environment]::GetFolderPath("UserProfile")
return (Join-Path $userHome "clawdbot")
return (Join-Path $userHome "openclaw")
}
function Remove-LegacySubmodule {
@ -360,7 +365,7 @@ function Main {
Remove-LegacySubmodule -RepoDir $RepoDir
# Check for existing installation
$isUpgrade = Check-ExistingMoltbot
$isUpgrade = Check-ExistingOpenClaw
# Step 1: Node.js
if (-not (Check-Node)) {
@ -377,17 +382,17 @@ function Main {
$finalGitDir = $null
# Step 2: Moltbot
# Step 2: OpenClaw
if ($InstallMethod -eq "git") {
$finalGitDir = $GitDir
Install-MoltbotFromGit -RepoDir $GitDir -SkipUpdate:$NoGitUpdate
Install-OpenClawFromGit -RepoDir $GitDir -SkipUpdate:$NoGitUpdate
} else {
Install-Moltbot
Install-OpenClaw
}
if (-not (Ensure-MoltbotOnPath)) {
Write-Host "Install completed, but Moltbot is not on PATH yet." -ForegroundColor Yellow
Write-Host "Open a new terminal, then run: clawdbot doctor" -ForegroundColor Cyan
if (-not (Ensure-OpenClawOnPath)) {
Write-Host "Install completed, but OpenClaw is not on PATH yet." -ForegroundColor Yellow
Write-Host "Open a new terminal, then run: openclaw doctor" -ForegroundColor Cyan
return
}
@ -398,15 +403,15 @@ function Main {
$installedVersion = $null
try {
$installedVersion = (clawdbot --version 2>$null).Trim()
$installedVersion = (openclaw --version 2>$null).Trim()
} catch {
$installedVersion = $null
}
if (-not $installedVersion) {
try {
$npmList = npm list -g --depth 0 --json 2>$null | ConvertFrom-Json
if ($npmList -and $npmList.dependencies -and $npmList.dependencies.clawdbot -and $npmList.dependencies.clawdbot.version) {
$installedVersion = $npmList.dependencies.clawdbot.version
if ($npmList -and $npmList.dependencies -and $npmList.dependencies.openclaw -and $npmList.dependencies.openclaw.version) {
$installedVersion = $npmList.dependencies.openclaw.version
}
} catch {
$installedVersion = $null
@ -415,9 +420,9 @@ function Main {
Write-Host ""
if ($installedVersion) {
Write-Host "Moltbot installed successfully ($installedVersion)!" -ForegroundColor Green
Write-Host "OpenClaw installed successfully ($installedVersion)!" -ForegroundColor Green
} else {
Write-Host "Moltbot installed successfully!" -ForegroundColor Green
Write-Host "OpenClaw installed successfully!" -ForegroundColor Green
}
Write-Host ""
if ($isUpgrade) {
@ -464,23 +469,23 @@ function Main {
if ($InstallMethod -eq "git") {
Write-Host "Source checkout: $finalGitDir" -ForegroundColor Cyan
Write-Host "Wrapper: $env:USERPROFILE\\.local\\bin\\clawdbot.cmd" -ForegroundColor Cyan
Write-Host "Wrapper: $env:USERPROFILE\\.local\\bin\\openclaw.cmd" -ForegroundColor Cyan
Write-Host ""
}
if ($isUpgrade) {
Write-Host "Upgrade complete. Run " -NoNewline
Write-Host "clawdbot doctor" -ForegroundColor Cyan -NoNewline
Write-Host "openclaw doctor" -ForegroundColor Cyan -NoNewline
Write-Host " to check for additional migrations."
} else {
if ($NoOnboard) {
Write-Host "Skipping onboard (requested). Run " -NoNewline
Write-Host "clawdbot onboard" -ForegroundColor Cyan -NoNewline
Write-Host "openclaw onboard" -ForegroundColor Cyan -NoNewline
Write-Host " later."
} else {
Write-Host "Starting setup..." -ForegroundColor Cyan
Write-Host ""
clawdbot onboard
openclaw onboard
}
}
}

View File

@ -67,7 +67,7 @@
</g>
<!-- Text -->
<text x="380" y="280" font-family="system-ui, -apple-system, sans-serif" font-size="72" font-weight="700" fill="#f0f4ff">Clawdbot</text>
<text x="380" y="280" font-family="system-ui, -apple-system, sans-serif" font-size="72" font-weight="700" fill="#f0f4ff">OpenClaw</text>
<!-- Tagline -->
<text x="380" y="340" font-family="system-ui, -apple-system, sans-serif" font-size="24" font-weight="500" fill="#ff4d4d" letter-spacing="0.15em">EXFOLIATE! EXFOLIATE!</text>

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -45,7 +45,7 @@ import {
StickyNote, CheckSquare, ListTodo, PenTool, Bed, ShoppingCart, Printer,
Heart, UtensilsCrossed, MonitorSmartphone, Eye, Monitor, Bot, Users, Hash,
Home, MessageCircle, Brain, Terminal, Puzzle, Zap
} from 'lucide-astro';
} from '@lucide/astro';
const { icon, color = 'currentColor', size = 24, class: className = '' } = Astro.props;

View File

@ -0,0 +1,71 @@
---
title: "Introducing OpenClaw"
description: "The journey from Clawd to Moltbot to OpenClaw—and why this name is here to stay."
date: 2026-01-29
author: "Peter Steinberger"
authorHandle: "steipete"
tags: ["announcement", "roadmap"]
image: "/blog/openclaw-logo-text.png"
---
Two months ago, I hacked together a weekend project. What started as "WhatsApp Relay" now has over 100,000 GitHub stars and drew 2 million visitors in a single week.
Today, I'm excited to announce our new name: **OpenClaw**.
## The Naming Journey
We've been through some names.
**Clawd** was born in November 2025—a playful pun on "Claude" with a claw. It felt perfect until Anthropic's legal team politely asked us to reconsider. Fair enough.
**Moltbot** came next, chosen in a chaotic 5am Discord brainstorm with the community. Molting represents growth - lobsters shed their shells to become something bigger. It was meaningful, but [it never quite rolled off the tongue](https://x.com/NetworkChuck/status/2016254397496414317).
**OpenClaw** is where we land. And this time, we did our homework: trademark searches came back clear, domains have been purchased, migration code has been written. The name captures what this project has become:
- **Open**: Open source, open to everyone, community-driven
- **Claw**: Our lobster heritage, a nod to where we came from
## What OpenClaw Is
OpenClaw is an open agent platform that runs on your machine and works from the chat apps you already use. WhatsApp, Telegram, Discord, Slack, Teams—wherever you are, your AI assistant follows.
**Your assistant. Your machine. Your rules.**
OpenClaw is currently in beta—expect rough edges, but also rapid iteration.
Unlike SaaS assistants where your data lives on someone else's servers, OpenClaw runs where you choose—laptop, homelab, or VPS. Your infrastructure. Your keys. Your data.
## What's New in This Release
Along with the rebrand, we're shipping:
- **New Channels**: Twitch and Google Chat plugins
- **Models**: Support for KIMI K2.5 & Xiaomi MiMo-V2-Flash
- **Web Chat**: Send images just like you can in messaging apps
- **Security**: 34 security-related commits to harden the codebase
I'd like to thank all security folks for their hard work in helping us harden the project. We've released [machine-checkable security models](https://github.com/vignesh07/clawdbot-formal-models) this week and are continuing to work on additional security improvements. Remember that prompt injection is still an industry-wide unsolved problem, so it's important to use strong models and to study our [security best practices](https://docs.openclaw.ai/gateway/security).
## The Road Ahead
What's next? Security remains our top priority. We're also focused on gateway reliability and adding polish plus support for more models and providers.
This project has grown far beyond what I could maintain alone. Over the last few days I've worked on adding maintainers and we're slowly setting up processes so we can deal with the insane influx of PRs and Issues. I'm also figuring out how to pay maintainers properly—full-time if possible. If you wanna help, consider [contributing](https://github.com/openclaw/openclaw/blob/main/CONTRIBUTING.md) or [sponsoring the org](https://github.com/sponsors/openclaw).
## Thank You
To the Claw Crew—every clawtributor who's shipped code, filed issues, joined our Discord, or just tried the project: thank you. You are what makes OpenClaw special.
The lobster has molted into its final form. Welcome to OpenClaw.
---
*Get started: [openclaw.ai](https://openclaw.ai)*
*Join the Claw Crew: [Discord](https://discord.gg/openclaw)*
*Star on GitHub: [github.com/openclaw/openclaw](https://github.com/openclaw/openclaw)*
— Peter
P.S. Yes, the mascot is still a lobster. Some things are sacred. 🦞

17
src/content/config.ts Normal file
View File

@ -0,0 +1,17 @@
import { defineCollection, z } from 'astro:content';
const blog = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
description: z.string(),
date: z.date(),
author: z.string(),
authorHandle: z.string(),
draft: z.boolean().default(false),
tags: z.array(z.string()).default([]),
image: z.string().optional(),
}),
});
export const collections = { blog };

View File

@ -95,14 +95,14 @@
{
"id": "2012313149576302746",
"author": "chrisrodz35",
"quote": "@moltbot short story;\n\nWeek 1 - Set it up for my family\nWeek 2 - Set it up for some non-techie friends\nWeek 3 - We're building clawd for work",
"quote": "@moltbot short story;\n\nWeek 1 - Set it up for my family\nWeek 2 - Set it up for some non-techie friends\nWeek 3 - We're building claw for work",
"category": "personal",
"likes": 82
},
{
"id": "2012028725710192741",
"author": "jdrhyne",
"quote": "Just built a GA4 skill for @moltbot in ~20 minutes.\n\nSolved my own problem → packaged it → published to ClawdHub.\n\nNow anyone can `clawdhub install ga4` and start querying their analytics.\n\nThe best part of agent skills: pay it forward so the next person doesn't have to figure it out.",
"quote": "Just built a GA4 skill for @moltbot in ~20 minutes.\n\nSolved my own problem → packaged it → published to ClawHub.\n\nNow anyone can `clawhub install ga4` and start querying their analytics.\n\nThe best part of agent skills: pay it forward so the next person doesn't have to figure it out.",
"category": "developer",
"likes": 42,
"images": [
@ -156,7 +156,7 @@
{
"id": "2008336434827002232",
"author": "jdrhyne",
"quote": "Honestly, @moltbot is super powerful because of its ease of use. It literally just connected to JIRA and built a skill since it wasn't on @clawdhub yet. Look how simple it was",
"quote": "Honestly, @moltbot is super powerful because of its ease of use. It literally just connected to JIRA and built a skill since it wasn't on @clawhub yet. Look how simple it was",
"category": "developer",
"likes": 46,
"images": [
@ -166,7 +166,7 @@
{
"id": "2008970037013381165",
"author": "tonylongname",
"quote": "Now my home's PM. Wife and I drop topics anytime, Clawd researches, Sunday 9am sends the roundup.",
"quote": "Now my home's PM. Wife and I drop topics anytime, Claw researches, Sunday 9am sends the roundup.",
"category": "family",
"likes": 27
},
@ -191,7 +191,7 @@
{
"id": "2009424267801485362",
"author": "MagiMetal",
"quote": "Just built a Swift macOS menu bar app with @moltbot to manage ClawdBot! 🤖⚡\n\nShows gateway status, Discord connection, lets me start/stop/restart, view logs, and has notifications for status changes.\n\nBuilt it together in about an hour.",
"quote": "Just built a Swift macOS menu bar app with @moltbot to manage OpenClaw! 🤖⚡\n\nShows gateway status, Discord connection, lets me start/stop/restart, view logs, and has notifications for status changes.\n\nBuilt it together in about an hour.",
"category": "developer",
"likes": 23,
"images": [
@ -228,7 +228,7 @@
{
"id": "2013024865393975718",
"author": "bangkokbuild",
"quote": "Gave Clawd access to:\n• Garmin Watch\n• Obsidian Vault\n• GitHub repos\n• VPS\n• Telegram + Whatsapp\n• X\n\nNow it:\n• Logs my sleep/health/exercise data and tells me when I stay up too late\n• Writes code and deploys it\n• Updates Obsidian daily notes\n• Tracks who visits MenuCapture and where they came from\n• Monitors earthquakes in Tokyo\n• Researches stuff online and saves files to my desktop\n• Remembers my projects, patterns and preferences\n• Reminds me of my schedule, including holidays/accommodation\n• Checks on me (on Telegram!) if I'm quiet too long",
"quote": "Gave Claw access to:\n• Garmin Watch\n• Obsidian Vault\n• GitHub repos\n• VPS\n• Telegram + Whatsapp\n• X\n\nNow it:\n• Logs my sleep/health/exercise data and tells me when I stay up too late\n• Writes code and deploys it\n• Updates Obsidian daily notes\n• Tracks who visits MenuCapture and where they came from\n• Monitors earthquakes in Tokyo\n• Researches stuff online and saves files to my desktop\n• Remembers my projects, patterns and preferences\n• Reminds me of my schedule, including holidays/accommodation\n• Checks on me (on Telegram!) if I'm quiet too long",
"category": "integration",
"likes": 3
},
@ -289,7 +289,7 @@
{
"id": "2011586646458708138",
"author": "5katkov",
"quote": "ClawdBot is fully operational.\n\nIt can manage my calendar, obsidian, it can use browser now. It send me reminders, plans my itirenary. Contributes to my GitHub repositories.\n\nThis bot is my bitch now.",
"quote": "OpenClaw is fully operational.\n\nIt can manage my calendar, obsidian, it can use browser now. It send me reminders, plans my itirenary. Contributes to my GitHub repositories.\n\nThis bot is my bitch now.",
"category": "productivity",
"likes": 11
},
@ -330,7 +330,7 @@
{
"id": "2007656142105661693",
"author": "buddyhadry",
"quote": "Having too much fun building new CLIs / skills to work with @steipete's @moltbot.\n\nJust built an alexa cli to control your Alexa devices (including all Alexa-enabled smart home devices) with Clawdis / Claude Code / Codex / your agent of choice.\n\nSupports natural language text commands that can mimic anything you'd say to an Echo.",
"quote": "Having too much fun building new CLIs / skills to work with @steipete's @moltbot.\n\nJust built an alexa cli to control your Alexa devices (including all Alexa-enabled smart home devices) with Clawis / Claude Code / Codex / your agent of choice.\n\nSupports natural language text commands that can mimic anything you'd say to an Echo.",
"category": "smart-home",
"likes": 16
},
@ -521,7 +521,7 @@
{
"id": "2013089630317355014",
"author": "LLMJunky",
"quote": "You should try to think of Clawd as an orchestration layer that can interface with not only your entire machine, but the rest of your coding agents as well.\n\nAnd what makes it supremely useful, in my opinion, is that inferface is now available to you on all of your devices at the same time - especially mobile!\n\nThis means that anything you can do on your local dev machine, you can now do with simple voice memos on your phone.\n\nWorking on a project? Think of some idea while walking to the train? No problem. Drop Clawd a message, tell it to goto your project directory, spin up an agent, and build that feature.",
"quote": "You should try to think of Claw as an orchestration layer that can interface with not only your entire machine, but the rest of your coding agents as well.\n\nAnd what makes it supremely useful, in my opinion, is that inferface is now available to you on all of your devices at the same time - especially mobile!\n\nThis means that anything you can do on your local dev machine, you can now do with simple voice memos on your phone.\n\nWorking on a project? Think of some idea while walking to the train? No problem. Drop Claw a message, tell it to goto your project directory, spin up an agent, and build that feature.",
"category": "developer",
"likes": 3
},
@ -612,7 +612,7 @@
{
"id": "2013196232181637500",
"author": "christinetyip",
"quote": "I connected mine to an external memory layer - check out the shared-memory skill in clawdhub.\n\nMoltbot helps me build my second brain and selectively shares context and state with my partner's moltbot.",
"quote": "I connected mine to an external memory layer - check out the shared-memory skill in clawhub.\n\nMoltbot helps me build my second brain and selectively shares context and state with my partner's moltbot.",
"category": "integration",
"likes": 1
},
@ -664,7 +664,7 @@
{
"id": "2014797672419340435",
"author": "nateliason",
"quote": "My new favorite way to work with Moltbot:\n\n1. Tell it we're working on app improvements, it should just take notes\n2. Run through user flows, send screenshots with notes as I find issues\n3. It builds a list of work, adds its own hypotheses\n4. Writes up a full report on what to do\n5. I say \"Go\" and it kicks off Codex agents to attack the different pieces, opening separate PRs\n6. Claude reviews & improves the PRs on Github\n7. Clawd makes a doc of everything we did + what to test\n8. Next time I test, I start with that list to make sure everything worked",
"quote": "My new favorite way to work with Moltbot:\n\n1. Tell it we're working on app improvements, it should just take notes\n2. Run through user flows, send screenshots with notes as I find issues\n3. It builds a list of work, adds its own hypotheses\n4. Writes up a full report on what to do\n5. I say \"Go\" and it kicks off Codex agents to attack the different pieces, opening separate PRs\n6. Claude reviews & improves the PRs on Github\n7. Claw makes a doc of everything we did + what to test\n8. Next time I test, I start with that list to make sure everything worked",
"category": "developer",
"likes": 239,
"images": [

View File

@ -55,7 +55,7 @@
"url": "https://x.com/ricgarcas/status/2010163252890874250"
},
{
"quote": "Everyday I'm clawdin",
"quote": "Everyday I'm clawin",
"author": "robipop22",
"url": "https://x.com/robipop22/status/2012120668515737936"
}

View File

@ -10,7 +10,7 @@
"url": "https://x.com/cnlinkcnlink/status/2010149031071363355"
},
{
"quote": "clawd is amazing",
"quote": "claw is amazing",
"author": "ethan_tan",
"url": "https://x.com/ethan_tan/status/2010147402963968202"
},
@ -85,7 +85,7 @@
"url": "https://x.com/chrisdietr/status/2009118722695553363"
},
{
"quote": "More excited about Clawd than anything in AI since AutoGPT in 2023",
"quote": "More excited about Claw than anything in AI since AutoGPT in 2023",
"author": "georgepickett",
"url": "https://x.com/georgepickett/status/2008232708560867485"
},
@ -135,12 +135,12 @@
"url": "https://x.com/TommyFalkowski/status/2009897023252684936"
},
{
"quote": "Running the family Tesco shop as *Clawdy McClawdface's* first real test. Loving @moltbot so far.",
"quote": "Running the family Tesco shop as *Clawy McClawface's* first real test. Loving @moltbot so far.",
"author": "marchattonhere",
"url": "https://x.com/marchattonhere/status/2009562498748563505"
},
{
"quote": "100%, I am honestly thinking to have a separate claude account just for clawd.",
"quote": "100%, I am honestly thinking to have a separate claude account just for claw.",
"author": "alexgrama",
"url": "https://x.com/alexgrama/status/2010001285056213447"
},
@ -165,12 +165,12 @@
"url": "https://x.com/kenwheeler/status/2010003459987386412"
},
{
"quote": "Yes it can build a rocket. Yes it can connect to your synth and play songs while you sing. And it can sing along with you. Welcome to the Clawd Nation.",
"quote": "Yes it can build a rocket. Yes it can connect to your synth and play songs while you sing. And it can sing along with you. Welcome to the Claw Nation.",
"author": "mindragon",
"url": "https://x.com/mindragon/status/2010009907043692765"
},
{
"quote": "Did you look at this Clawd bot? The thing is wild, it's good to get status from your setup/env like you have when you're out.",
"quote": "Did you look at this Claw bot? The thing is wild, it's good to get status from your setup/env like you have when you're out.",
"author": "bitdeep_",
"url": "https://x.com/bitdeep_/status/2010041684919554501"
},
@ -185,7 +185,7 @@
"url": "https://x.com/MysticEru/status/2010053430493278360"
},
{
"quote": "Super powerful because of its ease of use. Literally connected to JIRA and built a skill since it wasn't on ClawdHub yet.",
"quote": "Super powerful because of its ease of use. Literally connected to JIRA and built a skill since it wasn't on ClawHub yet.",
"author": "jdrhyne",
"url": "https://x.com/jdrhyne/status/2008336434827002232"
},
@ -290,7 +290,7 @@
"url": "https://x.com/kenwheeler/status/2008692793888100509"
},
{
"quote": "Clawd is a crazy and really cool tool",
"quote": "Claw is a crazy and really cool tool",
"author": "bangkokbuild",
"url": "https://x.com/bangkokbuild/status/2007776814094250153"
},
@ -330,7 +330,7 @@
"url": "https://x.com/4shad0wed/status/2007882979302130018"
},
{
"quote": "Fixed a bug in clawd with clawd itself in Telegram. Can't wait to play more!",
"quote": "Fixed a bug in claw with claw itself in Telegram. Can't wait to play more!",
"author": "DanielGri",
"url": "https://x.com/DanielGri/status/2008477573810909571"
},
@ -598,7 +598,7 @@
"url": "https://x.com/WilcosX/status/2014476631021388299"
},
{
"quote": "I thought Claude Code was a vision of the future. But have a feeling Clawd is a vision of a mass *consumer* future. Nice work!",
"quote": "I thought Claude Code was a vision of the future. But have a feeling Claw is a vision of a mass *consumer* future. Nice work!",
"author": "Loster",
"url": "https://x.com/Loster/status/2014530687244591531"
},

View File

@ -1,11 +1,11 @@
[
{
"quote": "Setup @moltbot by @steipete yesterday. All I have to say is, wow. First I was using my Claude Max sub and I used all of my limit quickly, so today I had my clawd bot setup a proxy to route my CoPilot subscription as a API endpoint so now it runs on that. It's the fact that clawd can just keep building upon itself just by talking to it in discord is crazy. The future is already here",
"quote": "Setup @moltbot by @steipete yesterday. All I have to say is, wow. First I was using my Claude Max sub and I used all of my limit quickly, so today I had my claw bot setup a proxy to route my CoPilot subscription as a API endpoint so now it runs on that. It's the fact that claw can just keep building upon itself just by talking to it in discord is crazy. The future is already here",
"author": "jonahships_",
"url": "https://x.com/jonahships_/status/2010605025844723765"
},
{
"quote": "Tried Clawd by @steipete. I tried to build my own AI assistant bots before, and I am very impressed how many hard things Clawd gets right. Persistent memory, persona onboarding, comms integration, heartbeats. A few minor wrinkles remain, but the end result is AWESOME.",
"quote": "Tried Claw by @steipete. I tried to build my own AI assistant bots before, and I am very impressed how many hard things Claw gets right. Persistent memory, persona onboarding, comms integration, heartbeats. A few minor wrinkles remain, but the end result is AWESOME.",
"author": "AryehDubois",
"url": "https://x.com/AryehDubois/status/2011742378655432791"
},
@ -20,7 +20,7 @@
"url": "https://x.com/danpeguine/status/2014760164113477700"
},
{
"quote": "Yeah this was 1,000% worth it. Separate Claude subscription + Clawd, managing Claude Code / Codex sessions I can kick off anywhere, autonomously running tests on my app and capturing errors through a sentry webhook then resolving them and opening PRs... The future is here.",
"quote": "Yeah this was 1,000% worth it. Separate Claude subscription + Claw, managing Claude Code / Codex sessions I can kick off anywhere, autonomously running tests on my app and capturing errors through a sentry webhook then resolving them and opening PRs... The future is here.",
"author": "nateliason",
"url": "https://x.com/nateliason/status/2013725082850414592"
},
@ -30,7 +30,7 @@
"url": "https://x.com/nathanclark_/status/2014647048612773912"
},
{
"quote": "Clawd Bot is a 24/7 assistant with access to its own computer. What if there were ten, or a hundred, or a thousand?? All running 24/7 in the cloud with access to your files, Gmail, calendar, everything about you... That's the future, and we're living it today.",
"quote": "OpenClaw is a 24/7 assistant with access to its own computer. What if there were ten, or a hundred, or a thousand?? All running 24/7 in the cloud with access to your files, Gmail, calendar, everything about you... That's the future, and we're living it today.",
"author": "nickvasiles",
"url": "https://x.com/nickvasiles/status/2014790519529095447"
},
@ -140,7 +140,7 @@
"url": "https://x.com/wizaj/status/2010767447192637601"
},
{
"quote": "I can understand why people love @moltbot so much. I wanted to automate some tasks from Todoist and clawd was able to create a skill for it on its own, all within a Telegram chat.",
"quote": "I can understand why people love @moltbot so much. I wanted to automate some tasks from Todoist and claw was able to create a skill for it on its own, all within a Telegram chat.",
"author": "iamsubhrajyoti",
"url": "https://x.com/iamsubhrajyoti/status/2009949389884920153"
},
@ -335,7 +335,7 @@
"url": "https://x.com/adam91holt/status/2010768201173622822"
},
{
"quote": "I love that ClawdBot has a \"Hackable\" install option. This should be a standard for OSS projects",
"quote": "I love that OpenClaw has a \"Hackable\" install option. This should be a standard for OSS projects",
"author": "logscore",
"url": "https://x.com/logscore/status/2011126513022935133"
},
@ -495,7 +495,7 @@
"url": "https://x.com/_KevinTang/status/2010914035550634494"
},
{
"quote": "Excellent reading thank you. Love oracle and Clawd.",
"quote": "Excellent reading thank you. Love oracle and Claw.",
"author": "karpathy",
"url": "https://x.com/karpathy/status/2005692186470514904"
},

View File

@ -7,7 +7,7 @@ interface Props {
description?: string;
}
const { title, description = "Moltbot — The AI that actually does things. Your personal assistant on any platform." } = Astro.props;
const { title, description = "OpenClaw — The AI that actually does things. Your personal assistant on any platform." } = Astro.props;
---
<!doctype html>
@ -20,14 +20,14 @@ const { title, description = "Moltbot — The AI that actually does things. Your
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<link rel="canonical" href="https://molt.bot/" />
<link rel="canonical" href="https://openclaw.ai/" />
<!-- Open Graph -->
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://molt.bot/" />
<meta property="og:image" content="https://molt.bot/og-image.png" />
<meta property="og:url" content="https://openclaw.ai/" />
<meta property="og:image" content="https://openclaw.ai/og-image.png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
@ -35,7 +35,7 @@ const { title, description = "Moltbot — The AI that actually does things. Your
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content={title} />
<meta name="twitter:description" content={description} />
<meta name="twitter:image" content="https://molt.bot/og-image.png" />
<meta name="twitter:image" content="https://openclaw.ai/og-image.png" />
<!-- Fonts: Clash Display + Satoshi from Fontshare -->
<link rel="preconnect" href="https://api.fontshare.com">

View File

@ -0,0 +1,542 @@
---
import Layout from '../../layouts/Layout.astro';
import { getCollection, render } from 'astro:content';
export async function getStaticPaths() {
const posts = await getCollection('blog');
return posts.map((post) => ({
params: { slug: post.slug },
props: { post },
}));
}
const { post } = Astro.props;
const { Content } = await render(post);
function formatDate(date: Date): string {
return date.toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
});
}
function estimateReadTime(content: string): string {
const wordsPerMinute = 200;
const words = content.split(/\s+/).length;
const minutes = Math.ceil(words / wordsPerMinute);
return `${minutes} min read`;
}
const readTime = estimateReadTime(post.body || '');
const postUrl = `https://openclaw.ai/blog/${post.slug}`;
---
<Layout title={`${post.data.title} — OpenClaw Blog`} description={post.data.description}>
<div class="stars"></div>
<div class="nebula"></div>
<main class="container">
<article class="article">
<header class="article-header">
<a href="/blog" class="back-link">← Back to blog</a>
<h1 class="article-title">{post.data.title}</h1>
{post.data.image && (
<img src={post.data.image} alt={post.data.title} class="article-header-image" />
)}
<div class="article-meta">
<div class="author-info">
<img
src={`https://unavatar.io/x/${post.data.authorHandle}`}
alt={post.data.author}
class="author-avatar"
loading="lazy"
/>
<div class="author-details">
<span class="author-name">{post.data.author}</span>
<a href={`https://x.com/${post.data.authorHandle}`} class="author-handle" target="_blank" rel="noopener">@{post.data.authorHandle}</a>
</div>
</div>
<div class="meta-right">
<span class="post-date">{formatDate(post.data.date)}</span>
<span class="meta-separator">·</span>
<span class="read-time">{readTime}</span>
</div>
</div>
</header>
<div class="article-content">
<Content />
</div>
<footer class="article-footer">
<div class="share-section">
<span class="share-label">Share this post</span>
<div class="share-buttons">
<a href={`https://twitter.com/intent/tweet?text=${encodeURIComponent(post.data.title)}&url=${encodeURIComponent(postUrl)}&via=openclaw`} target="_blank" rel="noopener" class="share-btn share-x">
Share on X
</a>
<a href={`https://news.ycombinator.com/submitlink?u=${encodeURIComponent(postUrl)}&t=${encodeURIComponent(post.data.title)}`} target="_blank" rel="noopener" class="share-btn share-hn">
Post to HN
</a>
</div>
</div>
<div class="cta-box">
<h3 class="cta-title">Ready to try OpenClaw?</h3>
<p class="cta-text">Get started with a single command.</p>
<div class="cta-code">
<code>curl -fsSL https://openclaw.ai/install.sh | bash</code>
</div>
<a href="/" class="cta-btn">Learn more →</a>
</div>
</footer>
</article>
<footer class="page-footer">
<nav class="footer-nav">
<a href="/">Home</a>
<span class="footer-separator">·</span>
<a href="/blog">Blog</a>
<span class="footer-separator">·</span>
<a href="/showcase">Showcase</a>
<span class="footer-separator">·</span>
<a href="/shoutouts">Shoutouts</a>
</nav>
<p>Built by <a href="https://molty.me" target="_blank" rel="noopener">Molty</a> 🦞</p>
</footer>
</main>
</Layout>
<style>
.stars {
position: fixed;
inset: 0;
background-image:
radial-gradient(2px 2px at 20px 30px, rgba(255,255,255,0.8), transparent),
radial-gradient(2px 2px at 40px 70px, rgba(255,255,255,0.5), transparent),
radial-gradient(1px 1px at 90px 40px, rgba(255,255,255,0.6), transparent),
radial-gradient(2px 2px at 130px 80px, rgba(255,255,255,0.4), transparent),
radial-gradient(1px 1px at 160px 120px, rgba(255,255,255,0.7), transparent),
radial-gradient(2px 2px at 200px 60px, rgba(0,229,204,0.6), transparent),
radial-gradient(1px 1px at 250px 150px, rgba(255,255,255,0.5), transparent),
radial-gradient(2px 2px at 300px 40px, rgba(255,77,77,0.4), transparent);
background-size: 350px 200px;
animation: twinkle 8s ease-in-out infinite alternate;
pointer-events: none;
z-index: 0;
}
@keyframes twinkle {
0% { opacity: 0.4; }
100% { opacity: 0.7; }
}
.nebula {
position: fixed;
inset: 0;
background:
radial-gradient(ellipse 80% 50% at 20% 20%, rgba(255, 77, 77, 0.12), transparent 50%),
radial-gradient(ellipse 60% 60% at 80% 30%, rgba(0, 229, 204, 0.08), transparent 50%),
radial-gradient(ellipse 90% 70% at 50% 90%, rgba(255, 77, 77, 0.06), transparent 50%);
pointer-events: none;
z-index: 0;
}
.container {
position: relative;
z-index: 1;
max-width: 720px;
margin: 0 auto;
padding: 40px 24px;
min-height: 100vh;
display: flex;
flex-direction: column;
}
.article {
animation: fadeInUp 0.6s ease-out;
}
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.article-header {
margin-bottom: 48px;
}
.back-link {
display: inline-block;
margin-bottom: 32px;
color: var(--text-muted);
text-decoration: none;
font-size: 0.9rem;
transition: color 0.2s ease;
}
.back-link:hover {
color: var(--coral-bright);
}
.article-title {
font-family: var(--font-display);
font-size: clamp(2rem, 6vw, 3rem);
font-weight: 700;
line-height: 1.2;
margin-bottom: 24px;
background: linear-gradient(135deg, var(--text-primary) 0%, var(--coral-bright) 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.article-header-image {
width: 100%;
max-height: 300px;
object-fit: contain;
border-radius: 12px;
margin-bottom: 24px;
}
.article-meta {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: 16px;
padding: 20px;
border-radius: 12px;
background: rgba(10, 15, 26, 0.7);
border: 1px solid var(--border-subtle);
}
.author-info {
display: flex;
align-items: center;
gap: 12px;
}
.author-avatar {
width: 48px;
height: 48px;
border-radius: 50%;
border: 2px solid var(--border-subtle);
background: var(--bg-elevated);
}
.author-details {
display: flex;
flex-direction: column;
gap: 2px;
}
.author-name {
font-weight: 600;
color: var(--text-primary);
}
.author-handle {
font-size: 0.85rem;
color: var(--coral-bright);
text-decoration: none;
}
.author-handle:hover {
text-decoration: underline;
}
.meta-right {
display: flex;
align-items: center;
gap: 8px;
font-size: 0.9rem;
color: var(--text-muted);
}
.meta-separator {
opacity: 0.5;
}
/* Article Content - Markdown Styling */
.article-content {
line-height: 1.8;
color: var(--text-secondary);
}
.article-content :global(p:first-child) {
font-size: 1.25rem;
line-height: 1.7;
color: var(--text-primary);
margin-bottom: 16px;
}
.article-content :global(p) {
margin-bottom: 20px;
}
.article-content :global(h2) {
font-family: var(--font-display);
font-size: 1.5rem;
font-weight: 600;
color: var(--text-primary);
margin-top: 24px;
margin-bottom: 0;
}
.article-content :global(ul) {
margin-bottom: 12px;
padding-left: 24px;
}
.article-content :global(li) {
margin-bottom: 4px;
padding-left: 8px;
}
.article-content :global(li::marker) {
color: var(--coral-bright);
}
.article-content :global(strong) {
color: var(--text-primary);
font-weight: 600;
}
.article-content :global(hr) {
border: none;
border-top: 1px solid var(--border-subtle);
margin: 24px 0 16px;
opacity: 0.5;
}
.article-content :global(hr ~ p) {
margin-top: 0;
margin-bottom: 4px;
}
.article-content :global(em) {
color: var(--cyan-bright);
font-style: italic;
}
.article-content :global(a) {
color: var(--coral-bright);
text-decoration: underline;
text-underline-offset: 3px;
}
.article-content :global(a:hover) {
color: var(--cyan-bright);
}
.article-content :global(code) {
font-family: var(--font-mono);
font-size: 0.9em;
padding: 2px 6px;
border-radius: 4px;
background: var(--bg-elevated);
color: var(--cyan-bright);
}
.article-content :global(pre) {
padding: 20px;
border-radius: 12px;
background: var(--bg-elevated);
border: 1px solid var(--border-subtle);
overflow-x: auto;
margin-bottom: 24px;
}
.article-content :global(pre code) {
padding: 0;
background: transparent;
}
.article-content :global(blockquote) {
margin: 24px 0;
padding: 16px 24px;
border-left: 3px solid var(--coral-bright);
background: rgba(255, 77, 77, 0.05);
border-radius: 0 8px 8px 0;
font-style: italic;
color: var(--text-secondary);
}
/* Article Footer */
.article-footer {
margin-top: 64px;
padding-top: 48px;
border-top: 1px solid var(--border-subtle);
}
.share-section {
display: flex;
align-items: center;
gap: 16px;
margin-bottom: 48px;
flex-wrap: wrap;
}
.share-label {
font-size: 0.9rem;
color: var(--text-muted);
}
.share-buttons {
display: flex;
gap: 12px;
}
.share-btn {
padding: 8px 16px;
border-radius: 8px;
font-size: 0.85rem;
font-weight: 500;
text-decoration: none;
transition: all 0.2s ease;
}
.share-x {
background: rgba(255, 255, 255, 0.1);
color: var(--text-primary);
border: 1px solid var(--border-subtle);
}
.share-x:hover {
background: rgba(255, 255, 255, 0.15);
border-color: var(--text-secondary);
}
.share-hn {
background: rgba(255, 102, 0, 0.1);
color: #ff6600;
border: 1px solid rgba(255, 102, 0, 0.3);
}
.share-hn:hover {
background: rgba(255, 102, 0, 0.2);
}
.cta-box {
padding: 32px;
border-radius: 16px;
background: linear-gradient(135deg, rgba(255, 77, 77, 0.08) 0%, rgba(10, 15, 26, 0.9) 50%, rgba(0, 229, 204, 0.05) 100%);
border: 1px solid var(--border-accent);
text-align: center;
}
.cta-title {
font-family: var(--font-display);
font-size: 1.25rem;
font-weight: 600;
color: var(--text-primary);
margin-bottom: 8px;
}
.cta-text {
color: var(--text-secondary);
margin-bottom: 20px;
}
.cta-code {
display: inline-block;
padding: 12px 20px;
border-radius: 8px;
background: var(--bg-elevated);
border: 1px solid var(--border-subtle);
margin-bottom: 20px;
}
.cta-code code {
font-family: var(--font-mono);
font-size: 0.9rem;
color: var(--cyan-bright);
}
.cta-btn {
display: inline-block;
padding: 12px 24px;
border-radius: 10px;
background: linear-gradient(135deg, var(--coral-bright) 0%, var(--coral-dark) 100%);
color: white;
font-family: var(--font-display);
font-weight: 600;
text-decoration: none;
transition: all 0.2s ease;
box-shadow: 0 4px 20px rgba(255, 77, 77, 0.3);
}
.cta-btn:hover {
transform: translateY(-2px);
box-shadow: 0 8px 30px rgba(255, 77, 77, 0.4);
}
/* Page Footer */
.page-footer {
margin-top: auto;
padding-top: 64px;
text-align: center;
font-size: 0.9rem;
color: var(--text-muted);
}
.footer-nav {
display: flex;
justify-content: center;
align-items: center;
gap: 12px;
margin-bottom: 16px;
flex-wrap: wrap;
}
.footer-separator {
color: var(--text-muted);
}
.page-footer a {
color: var(--coral-bright);
text-decoration: none;
}
.page-footer a:hover {
color: var(--cyan-bright);
}
@media (max-width: 480px) {
.container {
padding: 24px 16px;
}
.article-meta {
flex-direction: column;
align-items: flex-start;
}
.article-content :global(p:first-child) {
font-size: 1.1rem;
}
.cta-box {
padding: 24px 20px;
}
.cta-code {
padding: 10px 14px;
word-break: break-all;
}
.cta-code code {
font-size: 0.8rem;
}
.share-section {
flex-direction: column;
align-items: flex-start;
}
}
</style>

319
src/pages/blog/index.astro Normal file
View File

@ -0,0 +1,319 @@
---
import Layout from '../../layouts/Layout.astro';
import { getCollection } from 'astro:content';
// Get all blog posts, sorted by date (newest first)
const posts = (await getCollection('blog', ({ data }) => !data.draft))
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf());
function formatDate(date: Date): string {
return date.toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
});
}
function estimateReadTime(content: string): string {
const wordsPerMinute = 200;
const words = content.split(/\s+/).length;
const minutes = Math.ceil(words / wordsPerMinute);
return `${minutes} min read`;
}
---
<Layout title="Blog — OpenClaw">
<div class="stars"></div>
<div class="nebula"></div>
<main class="container">
<header class="header">
<a href="/" class="back-link">← Back to home</a>
<h1 class="title">
<span class="claw-accent">⟩</span> Blog
</h1>
<p class="subtitle">Updates, insights, and lobster wisdom from the OpenClaw team.</p>
</header>
<div class="posts-grid">
{posts.map((post) => (
<a href={`/blog/${post.slug}`} class="post-card">
<div class="post-meta">
<span class="post-date">{formatDate(post.data.date)}</span>
<span class="post-separator">·</span>
<span class="post-readtime">{estimateReadTime(post.body || '')}</span>
</div>
<h2 class="post-title">{post.data.title}</h2>
<p class="post-description">{post.data.description}</p>
<div class="post-footer">
<div class="post-author">
<img
src={`https://unavatar.io/x/${post.data.authorHandle}`}
alt={post.data.author}
class="author-avatar"
loading="lazy"
/>
<span class="author-name">{post.data.author}</span>
</div>
<div class="post-tags">
{post.data.tags.map((tag) => (
<span class="tag">#{tag}</span>
))}
</div>
</div>
</a>
))}
</div>
<footer class="footer">
<nav class="footer-nav">
<a href="/">Home</a>
<span class="footer-separator">·</span>
<a href="/showcase">Showcase</a>
<span class="footer-separator">·</span>
<a href="/shoutouts">Shoutouts</a>
<span class="footer-separator">·</span>
<a href="/integrations">Integrations</a>
</nav>
<p>Built by <a href="https://molty.me" target="_blank" rel="noopener">Molty</a> 🦞</p>
</footer>
</main>
</Layout>
<style>
.stars {
position: fixed;
inset: 0;
background-image:
radial-gradient(2px 2px at 20px 30px, rgba(255,255,255,0.8), transparent),
radial-gradient(2px 2px at 40px 70px, rgba(255,255,255,0.5), transparent),
radial-gradient(1px 1px at 90px 40px, rgba(255,255,255,0.6), transparent),
radial-gradient(2px 2px at 130px 80px, rgba(255,255,255,0.4), transparent),
radial-gradient(1px 1px at 160px 120px, rgba(255,255,255,0.7), transparent),
radial-gradient(2px 2px at 200px 60px, rgba(0,229,204,0.6), transparent),
radial-gradient(1px 1px at 250px 150px, rgba(255,255,255,0.5), transparent),
radial-gradient(2px 2px at 300px 40px, rgba(255,77,77,0.4), transparent);
background-size: 350px 200px;
animation: twinkle 8s ease-in-out infinite alternate;
pointer-events: none;
z-index: 0;
}
@keyframes twinkle {
0% { opacity: 0.4; }
100% { opacity: 0.7; }
}
.nebula {
position: fixed;
inset: 0;
background:
radial-gradient(ellipse 80% 50% at 20% 20%, rgba(255, 77, 77, 0.12), transparent 50%),
radial-gradient(ellipse 60% 60% at 80% 30%, rgba(0, 229, 204, 0.08), transparent 50%),
radial-gradient(ellipse 90% 70% at 50% 90%, rgba(255, 77, 77, 0.06), transparent 50%);
pointer-events: none;
z-index: 0;
}
.container {
position: relative;
z-index: 1;
max-width: 860px;
margin: 0 auto;
padding: 40px 24px;
min-height: 100vh;
display: flex;
flex-direction: column;
}
.header {
text-align: center;
margin-bottom: 48px;
animation: fadeInUp 0.6s ease-out;
}
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.back-link {
display: inline-block;
margin-bottom: 24px;
color: var(--text-muted);
text-decoration: none;
font-size: 0.9rem;
transition: color 0.2s ease;
}
.back-link:hover {
color: var(--coral-bright);
}
.title {
font-family: var(--font-display);
font-size: clamp(2rem, 6vw, 3rem);
font-weight: 700;
margin-bottom: 12px;
color: var(--text-primary);
}
.claw-accent {
color: var(--coral-bright);
}
.subtitle {
color: var(--text-secondary);
font-size: 1.1rem;
}
.posts-grid {
display: flex;
flex-direction: column;
gap: 24px;
margin-bottom: 56px;
}
.post-card {
display: flex;
flex-direction: column;
gap: 16px;
padding: 28px;
border-radius: 16px;
border: 1px solid var(--border-subtle);
background: rgba(10, 15, 26, 0.7);
backdrop-filter: blur(8px);
text-decoration: none;
color: var(--text-primary);
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}
.post-card:hover {
border-color: var(--coral-bright);
transform: translateY(-4px);
box-shadow: 0 16px 48px rgba(255, 77, 77, 0.15);
}
.post-meta {
display: flex;
align-items: center;
gap: 8px;
font-size: 0.85rem;
color: var(--text-muted);
}
.post-separator {
opacity: 0.5;
}
.post-title {
font-family: var(--font-display);
font-size: 1.5rem;
font-weight: 600;
color: var(--text-primary);
line-height: 1.3;
}
.post-card:hover .post-title {
color: var(--coral-bright);
}
.post-description {
font-size: 1rem;
line-height: 1.6;
color: var(--text-secondary);
}
.post-footer {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 8px;
padding-top: 16px;
border-top: 1px solid var(--border-subtle);
}
.post-author {
display: flex;
align-items: center;
gap: 10px;
}
.author-avatar {
width: 32px;
height: 32px;
border-radius: 50%;
border: 2px solid var(--border-subtle);
background: var(--bg-elevated);
}
.author-name {
font-size: 0.9rem;
font-weight: 500;
color: var(--text-secondary);
}
.post-tags {
display: flex;
gap: 8px;
}
.tag {
font-size: 0.75rem;
color: var(--cyan-bright);
padding: 4px 10px;
border-radius: 12px;
background: rgba(0, 229, 204, 0.1);
border: 1px solid rgba(0, 229, 204, 0.2);
}
.footer {
margin-top: auto;
padding-top: 48px;
text-align: center;
font-size: 0.9rem;
color: var(--text-muted);
}
.footer-nav {
display: flex;
justify-content: center;
align-items: center;
gap: 12px;
margin-bottom: 16px;
flex-wrap: wrap;
}
.footer-separator {
color: var(--text-muted);
}
.footer a {
color: var(--coral-bright);
text-decoration: none;
}
.footer a:hover {
color: var(--cyan-bright);
}
@media (max-width: 480px) {
.container {
padding: 24px 16px;
}
.post-card {
padding: 20px;
}
.post-footer {
flex-direction: column;
align-items: flex-start;
gap: 12px;
}
.post-tags {
flex-wrap: wrap;
}
}
</style>

View File

@ -2,6 +2,11 @@
import Layout from '../layouts/Layout.astro';
import Icon from '../components/Icon.astro';
import testimonials from '../data/testimonials.json';
import { getCollection } from 'astro:content';
// Get latest blog post
const posts = await getCollection('blog', ({ data }) => !data.draft);
const latestPost = posts.sort((a, b) => b.data.date.getTime() - a.data.date.getTime())[0];
import {
siWhatsapp, siTelegram, siDiscord, siSignal, siApple,
siAnthropic, siSpotify, siObsidian, siGithub, siGooglechrome, siGmail,
@ -46,7 +51,7 @@ const duration1 = (row1.length / 2 * pixelsPerItem) / pixelsPerSecond;
const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
---
<Layout title="Moltbot — Personal AI Assistant">
<Layout title="OpenClaw — Personal AI Assistant">
<div class="stars"></div>
<div class="nebula"></div>
@ -79,7 +84,7 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
</div>
<h1 class="title">
<span class="title-main">Moltbot</span>
<span class="title-main">OpenClaw</span>
</h1>
<p class="tagline" id="tagline">The AI that actually does things.</p>
@ -90,6 +95,17 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
</p>
</header>
<!-- Latest Blog Post -->
{latestPost && (
<section class="latest-post">
<a href={`/blog/${latestPost.slug}`} class="latest-post-card">
<span class="latest-post-badge">New</span>
<span class="latest-post-title">{latestPost.data.title}</span>
<span class="latest-post-link">→</span>
</a>
</section>
)}
<!-- Testimonials (moved up for social proof) -->
<section class="testimonials">
<div class="section-header">
@ -186,7 +202,7 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
<div class="code-line comment" id="oneliner-comment"># Works everywhere. Installs everything. You're welcome. 🦞</div>
<div class="code-line cmd">
<span class="code-prompt">$</span>
<span class="os-cmd">curl -fsSL https://molt.bot/install.sh | bash</span>
<span class="os-cmd">curl -fsSL https://openclaw.ai/install.sh | bash</span>
<button class="copy-line-btn" data-cmd="oneliner" title="Copy">
<svg class="copy-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
<svg class="check-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="display:none"><polyline points="20 6 9 17 4 12"/></svg>
@ -194,7 +210,7 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
</div>
</div>
<div id="code-quick" class="code-content" style="display: none;">
<div class="code-line comment" id="quick-comment-install"># Install Moltbot</div>
<div class="code-line comment" id="quick-comment-install"># Install OpenClaw</div>
<div class="code-line cmd">
<span class="code-prompt">$</span>
<span class="pm-install">npm i -g clawdbot</span>
@ -206,7 +222,7 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
<div class="code-line comment" id="quick-comment-onboard"># Meet your lobster</div>
<div class="code-line cmd">
<span class="code-prompt">$</span>
<span>clawdbot onboard</span>
<span>openclaw onboard</span>
<button class="copy-line-btn" data-cmd="onboard" title="Copy">
<svg class="copy-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
<svg class="check-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="display:none"><polyline points="20 6 9 17 4 12"/></svg>
@ -218,7 +234,7 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
<div class="code-line comment"># For those who read source code for fun</div>
<div class="code-line cmd">
<span class="code-prompt">$</span>
<span class="os-cmd-hackable">curl -fsSL https://molt.bot/install.sh | bash -s -- --install-method git</span>
<span class="os-cmd-hackable">curl -fsSL https://openclaw.ai/install.sh | bash -s -- --install-method git</span>
<button class="copy-line-btn" data-cmd="hackable-installer" title="Copy">
<svg class="copy-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
<svg class="check-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="display:none"><polyline points="20 6 9 17 4 12"/></svg>
@ -229,7 +245,7 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
<div class="code-line comment"># You clearly know what you're doing</div>
<div class="code-line cmd">
<span class="code-prompt">$</span>
<span>git clone https://github.com/moltbot/moltbot.git</span>
<span>git clone https://github.com/openclaw/openclaw.git</span>
<button class="copy-line-btn" data-cmd="clone" title="Copy">
<svg class="copy-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
<svg class="check-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="display:none"><polyline points="20 6 9 17 4 12"/></svg>
@ -246,7 +262,7 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
<div class="code-line comment"># You built it, now meet it</div>
<div class="code-line cmd">
<span class="code-prompt">$</span>
<span>pnpm run clawdbot onboard</span>
<span>pnpm run openclaw onboard</span>
<button class="copy-line-btn" data-cmd="hackable-onboard" title="Copy">
<svg class="copy-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
<svg class="check-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="display:none"><polyline points="20 6 9 17 4 12"/></svg>
@ -260,7 +276,7 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
<span class="macos-tagline">Companion App (Beta)</span>
<span class="macos-subtitle">Menubar access to your lobster. Works great alongside the CLI.</span>
</div>
<a href="https://github.com/moltbot/moltbot/releases/latest" class="macos-download-btn" target="_blank" rel="noopener">
<a href="https://github.com/openclaw/openclaw/releases/latest" class="macos-download-btn" target="_blank" rel="noopener">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
<polyline points="7 10 12 15 17 10"/>
@ -283,12 +299,12 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
pnpm: 'pnpm add -g clawdbot'
};
const windowsPsCmd = 'iwr -useb https://molt.bot/install.ps1 | iex';
const windowsPsBetaCmd = '& ([scriptblock]::Create((iwr -useb https://molt.bot/install.ps1))) -Tag beta';
const windowsCmdCmd = 'curl -fsSL https://molt.bot/install.cmd -o install.cmd && install.cmd && del install.cmd';
const windowsCmdBetaCmd = 'curl -fsSL https://molt.bot/install.cmd -o install.cmd && install.cmd --tag beta && del install.cmd';
const windowsPsCmd = 'iwr -useb https://openclaw.ai/install.ps1 | iex';
const windowsPsBetaCmd = '& ([scriptblock]::Create((iwr -useb https://openclaw.ai/install.ps1))) -Tag beta';
const windowsCmdCmd = 'curl -fsSL https://openclaw.ai/install.cmd -o install.cmd && install.cmd && del install.cmd';
const windowsCmdBetaCmd = 'curl -fsSL https://openclaw.ai/install.cmd -o install.cmd && install.cmd --tag beta && del install.cmd';
const osCmds = {
unix: "curl -fsSL https://molt.bot/install.sh | bash",
unix: "curl -fsSL https://openclaw.ai/install.sh | bash",
windows: windowsPsCmd
};
@ -340,8 +356,8 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
beta: "# Living on the edge. Bugs are features you found first. 🦞"
},
quickInstall: {
stable: "# Install Moltbot",
beta: "# Install Moltbot (beta) — Fresh from the lab 🧪"
stable: "# Install OpenClaw",
beta: "# Install OpenClaw (beta) — Fresh from the lab 🧪"
},
quickOnboard: {
stable: "# Meet your lobster",
@ -362,8 +378,8 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
let onelinerCmd;
if (currentOs === 'unix') {
onelinerCmd = currentBeta
? "curl -fsSL https://molt.bot/install.sh | bash -s -- --beta"
: "curl -fsSL https://molt.bot/install.sh | bash";
? "curl -fsSL https://openclaw.ai/install.sh | bash -s -- --beta"
: "curl -fsSL https://openclaw.ai/install.sh | bash";
} else if (currentWinShell === 'cmd') {
onelinerCmd = currentBeta ? windowsCmdBetaCmd : windowsCmdCmd;
} else {
@ -371,7 +387,7 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
}
document.querySelectorAll('.os-cmd').forEach(cmd => cmd.textContent = onelinerCmd);
// Update hackable OS command for installer mode
const hackableOsCmd = "curl -fsSL https://molt.bot/install.sh | bash -s -- --install-method git";
const hackableOsCmd = "curl -fsSL https://openclaw.ai/install.sh | bash -s -- --install-method git";
document.querySelectorAll('.os-cmd-hackable').forEach(cmd => cmd.textContent = hackableOsCmd);
// Update OS indicator text
osDetected.textContent = osLabels[currentOs];
@ -486,8 +502,8 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
'oneliner': () => {
if (currentOs === 'unix') {
return currentBeta
? "curl -fsSL https://molt.bot/install.sh | bash -s -- --beta"
: "curl -fsSL https://molt.bot/install.sh | bash";
? "curl -fsSL https://openclaw.ai/install.sh | bash -s -- --beta"
: "curl -fsSL https://openclaw.ai/install.sh | bash";
} else if (currentWinShell === 'cmd') {
return currentBeta ? windowsCmdBetaCmd : windowsCmdCmd;
} else {
@ -498,11 +514,11 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
const betaSuffix = currentBeta ? '@beta' : '';
return currentPm === 'npm' ? `npm i -g clawdbot${betaSuffix}` : `pnpm add -g clawdbot${betaSuffix}`;
},
'onboard': () => 'clawdbot onboard',
'hackable-installer': () => "curl -fsSL https://molt.bot/install.sh | bash -s -- --install-method git",
'clone': () => 'git clone https://github.com/moltbot/moltbot.git',
'onboard': () => 'openclaw onboard',
'hackable-installer': () => "curl -fsSL https://openclaw.ai/install.sh | bash -s -- --install-method git",
'clone': () => 'git clone https://github.com/openclaw/openclaw.git',
'build': () => 'cd moltbot && pnpm install && pnpm run build',
'hackable-onboard': () => 'pnpm run clawdbot onboard',
'hackable-onboard': () => 'pnpm run openclaw onboard',
};
document.querySelectorAll('.copy-line-btn').forEach(btn => {
@ -567,7 +583,7 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
<span class="claw-accent">⟩</span> What It Does
</h2>
<div class="features-grid">
<a href="https://docs.molt.bot/getting-started" target="_blank" rel="noopener" class="feature-card">
<a href="https://docs.openclaw.ai/getting-started" target="_blank" rel="noopener" class="feature-card">
<div class="feature-icon"><Icon icon="lucide:home" color="var(--coral-bright)" size={28} /></div>
<h3 class="feature-title">Runs on Your Machine</h3>
<p class="feature-desc">Mac, Windows, or Linux. Anthropic, OpenAI, or local models. Private by default—your data stays yours.</p>
@ -577,22 +593,22 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
<h3 class="feature-title">Any Chat App</h3>
<p class="feature-desc">Talk to it on WhatsApp, Telegram, Discord, Slack, Signal, or iMessage. Works in DMs and group chats.</p>
</a>
<a href="https://docs.molt.bot/session" target="_blank" rel="noopener" class="feature-card">
<a href="https://docs.openclaw.ai/session" target="_blank" rel="noopener" class="feature-card">
<div class="feature-icon"><Icon icon="lucide:brain" color="var(--coral-bright)" size={28} /></div>
<h3 class="feature-title">Persistent Memory</h3>
<p class="feature-desc">Remembers you and becomes uniquely yours. Your preferences, your context, your AI.</p>
</a>
<a href="https://docs.molt.bot/browser" target="_blank" rel="noopener" class="feature-card">
<a href="https://docs.openclaw.ai/browser" target="_blank" rel="noopener" class="feature-card">
<div class="feature-icon"><Icon icon="lucide:globe" color="var(--coral-bright)" size={28} /></div>
<h3 class="feature-title">Browser Control</h3>
<p class="feature-desc">It can browse the web, fill forms, and extract data from any site.</p>
</a>
<a href="https://docs.molt.bot/bash" target="_blank" rel="noopener" class="feature-card">
<a href="https://docs.openclaw.ai/bash" target="_blank" rel="noopener" class="feature-card">
<div class="feature-icon"><Icon icon="lucide:terminal" color="var(--coral-bright)" size={28} /></div>
<h3 class="feature-title">Full System Access</h3>
<p class="feature-desc">Read and write files, run shell commands, execute scripts. Full access or sandboxed—your choice.</p>
</a>
<a href="https://docs.molt.bot/skills" target="_blank" rel="noopener" class="feature-card">
<a href="https://docs.openclaw.ai/skills" target="_blank" rel="noopener" class="feature-card">
<div class="feature-icon"><Icon icon="lucide:puzzle" color="var(--coral-bright)" size={28} /></div>
<h3 class="feature-title">Skills & Plugins</h3>
<p class="feature-desc">Extend with community skills or build your own. It can even write its own.</p>
@ -634,7 +650,7 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
<span class="press-name">MacStories</span>
</div>
<blockquote class="press-quote">
"Moltbot Showed Me What the Future of Personal AI Assistants Looks Like"
"OpenClaw Showed Me What the Future of Personal AI Assistants Looks Like"
</blockquote>
<span class="press-author">Federico Viticci</span>
</a>
@ -663,7 +679,7 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
<span class="cta-sub">Join the community</span>
</a>
<a href="https://docs.molt.bot/getting-started" class="cta cta-docs" target="_blank" rel="noopener">
<a href="https://docs.openclaw.ai/getting-started" class="cta cta-docs" target="_blank" rel="noopener">
<svg class="cta-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/>
<path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/>
@ -674,7 +690,7 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
<span class="cta-sub">Learn the ropes</span>
</a>
<a href="https://github.com/moltbot/moltbot" class="cta cta-github" target="_blank" rel="noopener">
<a href="https://github.com/openclaw/openclaw" class="cta cta-github" target="_blank" rel="noopener">
<svg class="cta-icon" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
</svg>
@ -682,11 +698,11 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
<span class="cta-sub">View the source</span>
</a>
<a href="https://clawdhub.com" class="cta cta-skills" target="_blank" rel="noopener">
<a href="https://clawhub.com" class="cta cta-skills" target="_blank" rel="noopener">
<svg class="cta-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/>
</svg>
<span class="cta-label">ClawdHub</span>
<span class="cta-label">ClawHub</span>
<span class="cta-sub">Download skills</span>
</a>
</nav>
@ -721,8 +737,17 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
<!-- Footer -->
<footer class="footer">
<p>Built by <a href="https://molty.me" target="_blank" rel="noopener">Molty</a> 🦞, a space lobster AI with a <a href="https://soul.md" target="_blank" rel="noopener">soul</a>, by <a href="https://steipete.me" target="_blank" rel="noopener">Peter Steinberger</a> & <a href="https://github.com/moltbot/moltbot#community" target="_blank" rel="noopener">community</a>.</p>
<p class="disclaimer">Moltbot was formerly known as Clawdbot. Independent project, not affiliated with Anthropic.</p>
<nav class="footer-nav">
<a href="/blog">Blog</a>
<span class="footer-separator">·</span>
<a href="/showcase">Showcase</a>
<span class="footer-separator">·</span>
<a href="/shoutouts">Shoutouts</a>
<span class="footer-separator">·</span>
<a href="/integrations">Integrations</a>
</nav>
<p>Built by <a href="https://molty.me" target="_blank" rel="noopener">Molty</a> 🦞, a space lobster AI with a <a href="https://soul.md" target="_blank" rel="noopener">soul</a>, by <a href="https://steipete.me" target="_blank" rel="noopener">Peter Steinberger</a> & <a href="https://github.com/openclaw/openclaw#community" target="_blank" rel="noopener">community</a>.</p>
<p class="disclaimer">Formerly known as Clawdbot and Moltbot. Independent project, not affiliated with Anthropic.</p>
</footer>
</main>
</Layout>
@ -1730,6 +1755,55 @@ const duration2 = (row2.length / 2 * pixelsPerItem) / pixelsPerSecond;
opacity: 0.7;
}
/* Latest Blog Post */
.latest-post {
margin-bottom: 40px;
animation: fadeInUp 0.8s ease-out 0.5s both;
text-align: center;
}
.latest-post-card {
display: inline-flex;
align-items: center;
gap: 12px;
padding: 10px 20px;
border-radius: 50px;
background: rgba(10, 15, 26, 0.8);
border: 1px solid var(--border-subtle);
text-decoration: none;
transition: all 0.3s ease;
}
.latest-post-card:hover {
border-color: var(--coral-bright);
box-shadow: 0 4px 20px rgba(255, 77, 77, 0.2);
}
.latest-post-badge {
padding: 3px 8px;
border-radius: 12px;
background: var(--coral-bright);
color: white;
font-size: 0.7rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.latest-post-title {
font-size: 0.9rem;
color: var(--text-primary);
}
.latest-post-link {
color: var(--text-muted);
transition: color 0.2s;
}
.latest-post-card:hover .latest-post-link {
color: var(--coral-bright);
}
/* Testimonials */
.testimonials {
margin-bottom: 56px;

View File

@ -15,24 +15,6 @@ import {
// Helper to create SVG from simple-icons
const siIcon = (icon: any) => icon.path;
// MiniMax custom icon (wave form logo with gradient)
const minimaxIcon = {
viewBox: '0 0 680 572',
defs: {
linearGradients: [{
id: 'minimax-grad',
x1: '0%', y1: '0%', x2: '100%', y2: '0%',
stops: [
{ offset: '0%', color: '#e31e80' },
{ offset: '100%', color: '#fe6642' },
],
}],
},
paths: [
{ d: 'M 468 5 L 445 6 L 426 15 L 411 31 L 403 55 L 403 516 L 394 530 L 376 535 L 357 521 L 352 445 L 337 439 L 324 450 L 327 531 L 346 556 L 370 566 L 389 566 L 412 556 L 427 540 L 435 516 L 435 55 L 447 39 L 469 38 L 483 56 L 483 422 L 490 443 L 513 465 L 544 471 L 572 460 L 591 435 L 594 200 L 598 189 L 612 179 L 628 180 L 642 197 L 643 394 L 660 405 L 674 392 L 673 190 L 664 170 L 648 155 L 626 147 L 605 148 L 575 167 L 563 194 L 562 422 L 544 439 L 530 438 L 518 428 L 514 50 L 506 30 L 492 15 Z M 309 5 L 290 5 L 265 16 L 251 32 L 244 52 L 244 460 L 235 476 L 215 481 L 196 463 L 196 199 L 187 172 L 174 158 L 153 148 L 127 148 L 106 158 L 90 177 L 84 199 L 84 316 L 73 331 L 54 334 L 39 322 L 36 267 L 31 259 L 15 256 L 5 264 L 5 324 L 17 346 L 48 365 L 82 362 L 105 344 L 115 322 L 117 194 L 127 182 L 139 178 L 160 189 L 164 198 L 164 464 L 176 492 L 189 504 L 209 512 L 231 512 L 253 502 L 267 487 L 275 466 L 275 58 L 279 47 L 296 36 L 313 40 L 324 61 L 324 394 L 330 402 L 341 405 L 355 392 L 355 53 L 343 25 L 328 12 Z', fill: 'url(#minimax-grad)' },
],
};
const tlonIcon = {
viewBox: '0 0 160 160',
paths: [
@ -69,101 +51,100 @@ const bluebubblesIcon = {
};
const chatProviders = [
{ name: 'WhatsApp', icon: siIcon(siWhatsapp), color: '#25D366', desc: 'QR pairing via Baileys', docs: 'https://clawdhub.com/skills/wacli' },
{ name: 'Telegram', icon: siIcon(siTelegram), color: '#26A5E4', desc: 'Bot API via grammY', docs: 'https://docs.molt.bot/telegram' },
{ name: 'Discord', icon: siIcon(siDiscord), color: '#5865F2', desc: 'Servers, channels & DMs', docs: 'https://clawdhub.com/skills/discord' },
{ name: 'Slack', icon: 'lucide:hash', color: '#E01E5A', desc: 'Workspace apps via Bolt', docs: 'https://clawdhub.com/skills/slack' },
{ name: 'Signal', icon: siIcon(siSignal), color: '#3A76F0', desc: 'Privacy-focused via signal-cli', docs: 'https://docs.clawd.bot/channels/signal' },
{ name: 'WhatsApp', icon: siIcon(siWhatsapp), color: '#25D366', desc: 'QR pairing via Baileys', docs: 'https://clawhub.com/skills/wacli' },
{ name: 'Telegram', icon: siIcon(siTelegram), color: '#26A5E4', desc: 'Bot API via grammY', docs: 'https://docs.openclaw.ai/telegram' },
{ name: 'Discord', icon: siIcon(siDiscord), color: '#5865F2', desc: 'Servers, channels & DMs', docs: 'https://clawhub.com/skills/discord' },
{ name: 'Slack', icon: 'lucide:hash', color: '#E01E5A', desc: 'Workspace apps via Bolt', docs: 'https://clawhub.com/skills/slack' },
{ name: 'Signal', icon: siIcon(siSignal), color: '#3A76F0', desc: 'Privacy-focused via signal-cli', docs: 'https://clawhub.com/skills/sag' },
{ name: 'iMessage', icon: siIcon(siApple), color: '#007AFF', desc: 'iMessage via imsg (AppleScript bridge)', docs: 'https://github.com/steipete/imsg' },
{ name: 'iMessage', icon: bluebubblesIcon, color: '#3B82F6', desc: 'iMessage via BlueBubbles server', docs: 'https://docs.molt.bot/channels/bluebubbles' },
{ name: 'Microsoft Teams', icon: 'lucide:users', color: '#6264A7', desc: 'Enterprise support', docs: 'https://docs.molt.bot/channels/msteams' },
{ name: 'Nextcloud Talk', icon: siIcon(siNextcloud), color: '#0082C9', desc: 'Self-hosted Nextcloud chat', docs: 'https://docs.molt.bot/channels/nextcloud-talk' },
{ name: 'Matrix', icon: siIcon(siMatrix), color: '#000000', desc: 'Matrix protocol', docs: 'https://docs.molt.bot/channels/matrix' },
{ name: 'Nostr', icon: 'lucide:message-circle', color: '#8F2CFF', desc: 'Decentralized DMs via NIP-04', docs: 'https://docs.molt.bot/channels/nostr' },
{ name: 'iMessage', icon: bluebubblesIcon, color: '#3B82F6', desc: 'iMessage via BlueBubbles server', docs: 'https://docs.openclaw.ai/channels/bluebubbles' },
{ name: 'Microsoft Teams', icon: 'lucide:users', color: '#6264A7', desc: 'Enterprise support', docs: 'https://docs.openclaw.ai/msteams' },
{ name: 'Nextcloud Talk', icon: siIcon(siNextcloud), color: '#0082C9', desc: 'Self-hosted Nextcloud chat', docs: 'https://docs.openclaw.ai/channels/nextcloud-talk' },
{ name: 'Matrix', icon: siIcon(siMatrix), color: '#000000', desc: 'Matrix protocol', docs: 'https://docs.openclaw.ai/channels/matrix' },
{ name: 'Nostr', icon: 'lucide:message-circle', color: '#8F2CFF', desc: 'Decentralized DMs via NIP-04', docs: 'https://docs.openclaw.ai/channels/nostr' },
{ name: 'Tlon Messenger', icon: tlonIcon, color: '#FFFFFF', desc: 'P2P ownership-first chat', docs: 'https://docs.urbit.org' },
{ name: 'Zalo', icon: siIcon(siZalo), color: '#0068FF', desc: 'Zalo Bot API', docs: 'https://docs.molt.bot/channels/zalo' },
{ name: 'Zalo Personal', icon: siIcon(siZalo), color: '#0068FF', desc: 'Personal account via QR login', docs: 'https://docs.molt.bot/channels/zalouser' },
{ name: 'WebChat', icon: 'lucide:globe', color: '#00E5CC', desc: 'Browser-based UI', docs: 'https://docs.molt.bot/webchat' },
{ name: 'Zalo', icon: siIcon(siZalo), color: '#0068FF', desc: 'Zalo Bot API', docs: 'https://docs.openclaw.ai/channels/zalo' },
{ name: 'Zalo Personal', icon: siIcon(siZalo), color: '#0068FF', desc: 'Personal account via QR login', docs: 'https://docs.openclaw.ai/channels/zalouser' },
{ name: 'WebChat', icon: 'lucide:globe', color: '#00E5CC', desc: 'Browser-based UI', docs: 'https://docs.openclaw.ai/webchat' },
];
const modelProviders = [
{ name: 'Anthropic', icon: siIcon(siAnthropic), color: '#D4A574', desc: 'Claude Pro/Max + Opus 4.5', docs: 'https://docs.molt.bot/models' },
{ name: 'OpenAI', icon: 'lucide:bot', color: '#00A67E', desc: 'GPT-4, GPT-5, o1', docs: 'https://docs.molt.bot/models' },
{ name: 'Google', icon: siIcon(siGoogle), color: '#4285F4', desc: 'Gemini 2.5 Pro/Flash', docs: 'https://docs.molt.bot/models' },
{ name: 'MiniMax', icon: minimaxIcon, color: '#E91E63', desc: 'MiniMax-M2.1', docs: 'https://docs.molt.bot/models' },
{ name: 'xAI', icon: siIcon(siX), color: '#FFFFFF', desc: 'Grok 3 & 4', docs: 'https://docs.molt.bot/models' },
{ name: 'OpenRouter', icon: 'lucide:zap', color: '#6366F1', desc: 'Unified API gateway', docs: 'https://docs.molt.bot/models' },
{ name: 'Mistral', icon: siIcon(siMistralai), color: '#FF7000', desc: 'Mistral Large & Codestral', docs: 'https://docs.molt.bot/models' },
{ name: 'DeepSeek', icon: 'lucide:brain', color: '#4D6BFE', desc: 'DeepSeek V3 & R1', docs: 'https://docs.molt.bot/models' },
{ name: 'GLM', icon: 'lucide:message-circle', color: '#00D4AA', desc: 'ChatGLM models', docs: 'https://docs.molt.bot/models' },
{ name: 'Perplexity', icon: siIcon(siPerplexity), color: '#20B8CD', desc: 'Search-augmented AI', docs: 'https://docs.molt.bot/models' },
{ name: 'Hugging Face', icon: siIcon(siHuggingface), color: '#FFD21E', desc: 'Open-source models', docs: 'https://docs.molt.bot/models' },
{ name: 'Local Models', icon: siIcon(siOllama), color: '#FFFFFF', desc: 'Ollama, LM Studio', docs: 'https://docs.molt.bot/models' },
{ name: 'Anthropic', icon: siIcon(siAnthropic), color: '#D4A574', desc: 'Claude Pro/Max + Opus 4.5', docs: 'https://docs.openclaw.ai/models' },
{ name: 'OpenAI', icon: 'lucide:bot', color: '#00A67E', desc: 'GPT-4, GPT-5, o1', docs: 'https://docs.openclaw.ai/models' },
{ name: 'Google', icon: siIcon(siGoogle), color: '#4285F4', desc: 'Gemini 2.5 Pro/Flash', docs: 'https://docs.openclaw.ai/models' },
{ name: 'xAI', icon: siIcon(siX), color: '#FFFFFF', desc: 'Grok 3 & 4', docs: 'https://docs.openclaw.ai/models' },
{ name: 'OpenRouter', icon: 'lucide:zap', color: '#6366F1', desc: 'Unified API gateway', docs: 'https://docs.openclaw.ai/models' },
{ name: 'Mistral', icon: siIcon(siMistralai), color: '#FF7000', desc: 'Mistral Large & Codestral', docs: 'https://docs.openclaw.ai/models' },
{ name: 'DeepSeek', icon: 'lucide:brain', color: '#4D6BFE', desc: 'DeepSeek V3 & R1', docs: 'https://docs.openclaw.ai/models' },
{ name: 'GLM', icon: 'lucide:message-circle', color: '#00D4AA', desc: 'ChatGLM models', docs: 'https://docs.openclaw.ai/models' },
{ name: 'Perplexity', icon: siIcon(siPerplexity), color: '#20B8CD', desc: 'Search-augmented AI', docs: 'https://docs.openclaw.ai/models' },
{ name: 'Hugging Face', icon: siIcon(siHuggingface), color: '#FFD21E', desc: 'Open-source models', docs: 'https://docs.openclaw.ai/models' },
{ name: 'Local Models', icon: siIcon(siOllama), color: '#FFFFFF', desc: 'Ollama, LM Studio', docs: 'https://docs.openclaw.ai/models' },
];
const companionApps = [
{ name: 'macOS', icon: siIcon(siMacos), color: '#FFFFFF', desc: 'Menu bar app + Voice Wake', docs: 'https://docs.molt.bot/macos' },
{ name: 'iOS', icon: siIcon(siIos), color: '#007AFF', desc: 'Canvas, camera, Voice Wake', docs: 'https://docs.molt.bot/ios' },
{ name: 'Android', icon: siIcon(siAndroid), color: '#34A853', desc: 'Canvas, camera, screen', docs: 'https://docs.molt.bot/android' },
{ name: 'Windows', icon: 'lucide:monitor', color: '#0078D4', desc: 'WSL2 recommended', docs: 'https://docs.molt.bot/windows' },
{ name: 'Linux', icon: siIcon(siLinux), color: '#FCC624', desc: 'Native support', docs: 'https://docs.molt.bot/linux' },
{ name: 'macOS', icon: siIcon(siMacos), color: '#FFFFFF', desc: 'Menu bar app + Voice Wake', docs: 'https://docs.openclaw.ai/macos' },
{ name: 'iOS', icon: siIcon(siIos), color: '#007AFF', desc: 'Canvas, camera, Voice Wake', docs: 'https://docs.openclaw.ai/ios' },
{ name: 'Android', icon: siIcon(siAndroid), color: '#34A853', desc: 'Canvas, camera, screen', docs: 'https://docs.openclaw.ai/android' },
{ name: 'Windows', icon: 'lucide:monitor', color: '#0078D4', desc: 'WSL2 recommended', docs: 'https://docs.openclaw.ai/windows' },
{ name: 'Linux', icon: siIcon(siLinux), color: '#FCC624', desc: 'Native support', docs: 'https://docs.openclaw.ai/linux' },
];
const productivityApps = [
{ name: 'Apple Notes', icon: 'lucide:sticky-note', color: '#FFCC00', desc: 'Native macOS/iOS notes', docs: 'https://clawdhub.com/skills/apple-notes' },
{ name: 'Apple Reminders', icon: 'lucide:check-square', color: '#FF9500', desc: 'Task management', docs: 'https://clawdhub.com/skills/apple-reminders' },
{ name: 'Things 3', icon: 'lucide:list-todo', color: '#4A90D9', desc: 'GTD task manager', docs: 'https://clawdhub.com/skills/things-mac' },
{ name: 'Notion', icon: siIcon(siNotion), color: '#FFFFFF', desc: 'Workspace & databases', docs: 'https://clawdhub.com/skills' },
{ name: 'Obsidian', icon: siIcon(siObsidian), color: '#7C3AED', desc: 'Knowledge graph notes', docs: 'https://clawdhub.com/skills/obsidian' },
{ name: 'Bear Notes', icon: 'lucide:pen-tool', color: '#DD4C4F', desc: 'Markdown notes', docs: 'https://clawdhub.com/skills' },
{ name: 'Trello', icon: siIcon(siTrello), color: '#0079BF', desc: 'Kanban boards', docs: 'https://clawdhub.com/skills/trello' },
{ name: 'GitHub', icon: siIcon(siGithub), color: '#FFFFFF', desc: 'Code, issues, PRs', docs: 'https://clawdhub.com/skills' },
{ name: 'Apple Notes', icon: 'lucide:sticky-note', color: '#FFCC00', desc: 'Native macOS/iOS notes', docs: 'https://clawhub.com/skills/apple-notes' },
{ name: 'Apple Reminders', icon: 'lucide:check-square', color: '#FF9500', desc: 'Task management', docs: 'https://clawhub.com/skills/apple-reminders' },
{ name: 'Things 3', icon: 'lucide:list-todo', color: '#4A90D9', desc: 'GTD task manager', docs: 'https://clawhub.com/skills/things-mac' },
{ name: 'Notion', icon: siIcon(siNotion), color: '#FFFFFF', desc: 'Workspace & databases', docs: 'https://clawhub.com/skills' },
{ name: 'Obsidian', icon: siIcon(siObsidian), color: '#7C3AED', desc: 'Knowledge graph notes', docs: 'https://clawhub.com/skills/obsidian' },
{ name: 'Bear Notes', icon: 'lucide:pen-tool', color: '#DD4C4F', desc: 'Markdown notes', docs: 'https://clawhub.com/skills' },
{ name: 'Trello', icon: siIcon(siTrello), color: '#0079BF', desc: 'Kanban boards', docs: 'https://clawhub.com/skills/trello' },
{ name: 'GitHub', icon: siIcon(siGithub), color: '#FFFFFF', desc: 'Code, issues, PRs', docs: 'https://clawhub.com/skills' },
];
const musicAudio = [
{ name: 'Spotify', icon: siIcon(siSpotify), color: '#1DB954', desc: 'Music playback control', docs: 'https://clawdhub.com/skills/spotify-player' },
{ name: 'Sonos', icon: siIcon(siSonos), color: '#FFFFFF', desc: 'Multi-room audio', docs: 'https://clawdhub.com/skills/sonoscli' },
{ name: 'Shazam', icon: siIcon(siShazam), color: '#0088FF', desc: 'Song recognition', docs: 'https://clawdhub.com/skills/songsee' },
{ name: 'Spotify', icon: siIcon(siSpotify), color: '#1DB954', desc: 'Music playback control', docs: 'https://clawhub.com/skills/spotify-player' },
{ name: 'Sonos', icon: siIcon(siSonos), color: '#FFFFFF', desc: 'Multi-room audio', docs: 'https://clawhub.com/skills/sonoscli' },
{ name: 'Shazam', icon: siIcon(siShazam), color: '#0088FF', desc: 'Song recognition', docs: 'https://clawhub.com/skills/songsee' },
];
const smartHome = [
{ name: 'Philips Hue', icon: siIcon(siPhilipshue), color: '#0065D3', desc: 'Smart lighting', docs: 'https://clawdhub.com/skills/openhue' },
{ name: '8Sleep', icon: 'lucide:bed', color: '#00B4D8', desc: 'Smart mattress', docs: 'https://clawdhub.com/skills/eightctl' },
{ name: 'Home Assistant', icon: siIcon(siHomeassistant), color: '#41BDF5', desc: 'Home automation hub', docs: 'https://clawdhub.com/skills/homeassistant' },
{ name: 'Philips Hue', icon: siIcon(siPhilipshue), color: '#0065D3', desc: 'Smart lighting', docs: 'https://clawhub.com/skills/openhue' },
{ name: '8Sleep', icon: 'lucide:bed', color: '#00B4D8', desc: 'Smart mattress', docs: 'https://clawhub.com/skills/eightctl' },
{ name: 'Home Assistant', icon: siIcon(siHomeassistant), color: '#41BDF5', desc: 'Home automation hub', docs: 'https://clawhub.com/skills/homeassistant' },
];
const tools = [
{ name: 'Browser', icon: siIcon(siGooglechrome), color: '#4285F4', desc: 'Chrome/Chromium control', docs: 'https://clawdhub.com/skills/verify-on-browser' },
{ name: 'Canvas', icon: 'lucide:monitor-smartphone', color: '#FF4500', desc: 'Visual workspace + A2UI', docs: 'https://docs.molt.bot/mac/canvas' },
{ name: 'Voice', icon: 'lucide:mic', color: '#9B59B6', desc: 'Voice Wake + Talk Mode', docs: 'https://clawdhub.com/skills/voice-transcribe' },
{ name: 'Gmail', icon: siIcon(siGmail), color: '#EA4335', desc: 'Pub/Sub email triggers', docs: 'https://docs.molt.bot/gmail-pubsub' },
{ name: 'Cron', icon: 'lucide:clock', color: '#F39C12', desc: 'Scheduled tasks', docs: 'https://docs.molt.bot/cron' },
{ name: 'Webhooks', icon: 'lucide:webhook', color: '#1ABC9C', desc: 'External triggers', docs: 'https://docs.molt.bot/webhook' },
{ name: '1Password', icon: siIcon(si1password), color: '#0572EC', desc: 'Secure credentials', docs: 'https://clawdhub.com/skills/1password' },
{ name: 'Weather', icon: 'lucide:cloud-sun', color: '#FFB300', desc: 'Forecasts & conditions', docs: 'https://clawdhub.com/skills/weather' },
{ name: 'Browser', icon: siIcon(siGooglechrome), color: '#4285F4', desc: 'Chrome/Chromium control', docs: 'https://clawhub.com/skills/verify-on-browser' },
{ name: 'Canvas', icon: 'lucide:monitor-smartphone', color: '#FF4500', desc: 'Visual workspace + A2UI', docs: 'https://docs.openclaw.ai/mac/canvas' },
{ name: 'Voice', icon: 'lucide:mic', color: '#9B59B6', desc: 'Voice Wake + Talk Mode', docs: 'https://clawhub.com/skills/voice-transcribe' },
{ name: 'Gmail', icon: siIcon(siGmail), color: '#EA4335', desc: 'Pub/Sub email triggers', docs: 'https://docs.openclaw.ai/gmail-pubsub' },
{ name: 'Cron', icon: 'lucide:clock', color: '#F39C12', desc: 'Scheduled tasks', docs: 'https://docs.openclaw.ai/cron' },
{ name: 'Webhooks', icon: 'lucide:webhook', color: '#1ABC9C', desc: 'External triggers', docs: 'https://docs.openclaw.ai/webhook' },
{ name: '1Password', icon: siIcon(si1password), color: '#0572EC', desc: 'Secure credentials', docs: 'https://clawhub.com/skills/1password' },
{ name: 'Weather', icon: 'lucide:cloud-sun', color: '#FFB300', desc: 'Forecasts & conditions', docs: 'https://clawhub.com/skills/weather' },
];
const mediaCreative = [
{ name: 'Image Gen', icon: 'lucide:image', color: '#E91E63', desc: 'AI image generation', docs: 'https://clawdhub.com/skills' },
{ name: 'GIF Search', icon: 'lucide:search', color: '#00DCDC', desc: 'Find the perfect GIF', docs: 'https://clawdhub.com/skills/gifgrep' },
{ name: 'Peekaboo', icon: 'lucide:eye', color: '#FF6B6B', desc: 'Screen capture & control', docs: 'https://clawdhub.com/skills/peekaboo' },
{ name: 'Camera', icon: 'lucide:camera', color: '#607D8B', desc: 'Photo/video capture', docs: 'https://clawdhub.com/skills' },
{ name: 'Image Gen', icon: 'lucide:image', color: '#E91E63', desc: 'AI image generation', docs: 'https://clawhub.com/skills' },
{ name: 'GIF Search', icon: 'lucide:search', color: '#00DCDC', desc: 'Find the perfect GIF', docs: 'https://clawhub.com/skills/gifgrep' },
{ name: 'Peekaboo', icon: 'lucide:eye', color: '#FF6B6B', desc: 'Screen capture & control', docs: 'https://clawhub.com/skills/peekaboo' },
{ name: 'Camera', icon: 'lucide:camera', color: '#607D8B', desc: 'Photo/video capture', docs: 'https://clawhub.com/skills' },
];
const socialComms = [
{ name: 'Twitter/X', icon: siIcon(siX), color: '#FFFFFF', desc: 'Tweet, reply, search', docs: 'https://clawdhub.com/skills/bird' },
{ name: 'Email', icon: 'lucide:mail', color: '#D44638', desc: 'Send & read emails', docs: 'https://clawdhub.com/skills/himalaya' },
{ name: 'Twitter/X', icon: siIcon(siX), color: '#FFFFFF', desc: 'Tweet, reply, search', docs: 'https://clawhub.com/skills/bird' },
{ name: 'Email', icon: 'lucide:mail', color: '#D44638', desc: 'Send & read emails', docs: 'https://clawhub.com/skills/himalaya' },
];
const showcase = [
{ name: 'Tesco Autopilot', icon: 'lucide:shopping-cart', color: '#00539F', desc: 'Automated grocery shopping', docs: 'https://docs.molt.bot/start/showcase' },
{ name: 'Bambu Control', icon: 'lucide:printer', color: '#00AE42', desc: '3D printer management', docs: 'https://docs.molt.bot/start/showcase' },
{ name: 'Oura Ring', icon: 'lucide:heart', color: '#E4B363', desc: 'Health data insights', docs: 'https://docs.molt.bot/start/showcase' },
{ name: 'Food Ordering', icon: 'lucide:utensils-crossed', color: '#FF5A5F', desc: 'Foodora integration', docs: 'https://docs.molt.bot/start/showcase' },
{ name: 'Tesco Autopilot', icon: 'lucide:shopping-cart', color: '#00539F', desc: 'Automated grocery shopping', docs: 'https://docs.openclaw.ai/start/showcase' },
{ name: 'Bambu Control', icon: 'lucide:printer', color: '#00AE42', desc: '3D printer management', docs: 'https://docs.openclaw.ai/start/showcase' },
{ name: 'Oura Ring', icon: 'lucide:heart', color: '#E4B363', desc: 'Health data insights', docs: 'https://docs.openclaw.ai/start/showcase' },
{ name: 'Food Ordering', icon: 'lucide:utensils-crossed', color: '#FF5A5F', desc: 'Foodora integration', docs: 'https://docs.openclaw.ai/start/showcase' },
];
---
<Layout title="Integrations — Moltbot">
<Layout title="Integrations — OpenClaw">
<div class="stars"></div>
<div class="nebula"></div>
@ -182,7 +163,7 @@ const showcase = [
<h2 class="section-title">
<span class="claw-accent">⟩</span> Chat Providers
</h2>
<p class="section-desc">Message Moltbot from any chat app — it responds right where you are.</p>
<p class="section-desc">Message OpenClaw from any chat app — it responds right where you are.</p>
<div class="grid">
{chatProviders.map((p) => (
<a href={p.docs} target="_blank" rel="noopener" class="card" style={`--accent: ${p.color}`}>
@ -216,7 +197,7 @@ const showcase = [
<h2 class="section-title">
<span class="claw-accent">⟩</span> Productivity
</h2>
<p class="section-desc">Notes, tasks, wikis, and code — Moltbot works with your favorite tools.</p>
<p class="section-desc">Notes, tasks, wikis, and code — OpenClaw works with your favorite tools.</p>
<div class="grid">
{productivityApps.map((p) => (
<a href={p.docs} target="_blank" rel="noopener" class="card" style={`--accent: ${p.color}`}>
@ -349,23 +330,23 @@ const showcase = [
))}
</div>
<div style="text-align: center; margin-top: 24px;">
<a href="https://docs.molt.bot/start/showcase" target="_blank" rel="noopener" class="showcase-link">View all showcase projects →</a>
<a href="https://docs.openclaw.ai/start/showcase" target="_blank" rel="noopener" class="showcase-link">View all showcase projects →</a>
</div>
</section>
<!-- CTA -->
<section class="cta-section">
<h2 class="cta-title">Ready to get started?</h2>
<p class="cta-desc">Install Moltbot and connect your first provider in minutes.</p>
<p class="cta-desc">Install OpenClaw and connect your first provider in minutes.</p>
<a href="/" class="cta-button">Get Started</a>
</section>
<!-- ClawdHub CTA -->
<section class="clawdhub-cta">
<h2 class="clawdhub-title">Want More Skills?</h2>
<p class="clawdhub-desc">Discover 100+ community-built skills on ClawdHub — the public registry for sharing and discovering agent capabilities.</p>
<a href="https://clawdhub.com" target="_blank" rel="noopener" class="clawdhub-button">
Browse ClawdHub →
<!-- ClawHub CTA -->
<section class="clawhub-cta">
<h2 class="clawhub-title">Want More Skills?</h2>
<p class="clawhub-desc">Discover 100+ community-built skills on ClawHub — the public registry for sharing and discovering agent capabilities.</p>
<a href="https://clawhub.com" target="_blank" rel="noopener" class="clawhub-button">
Browse ClawHub →
</a>
</section>
@ -373,11 +354,13 @@ const showcase = [
<nav class="footer-nav">
<a href="/">Home</a>
<span class="footer-separator">·</span>
<a href="/blog">Blog</a>
<span class="footer-separator">·</span>
<a href="/showcase">Showcase</a>
<span class="footer-separator">·</span>
<a href="/shoutouts">Shoutouts</a>
</nav>
<p>Built by <a href="https://molty.me" target="_blank" rel="noopener">Molty</a> 🦞, a space lobster AI with a <a href="https://soul.md" target="_blank" rel="noopener">soul</a>, by <a href="https://steipete.me" target="_blank" rel="noopener">Peter Steinberger</a> & <a href="https://github.com/moltbot/moltbot#community" target="_blank" rel="noopener">community</a>.</p>
<p>Built by <a href="https://molty.me" target="_blank" rel="noopener">Molty</a> 🦞, a space lobster AI with a <a href="https://soul.md" target="_blank" rel="noopener">soul</a>, by <a href="https://steipete.me" target="_blank" rel="noopener">Peter Steinberger</a> & <a href="https://github.com/openclaw/openclaw#community" target="_blank" rel="noopener">community</a>.</p>
</footer>
</main>
</Layout>
@ -634,7 +617,7 @@ const showcase = [
box-shadow: 0 8px 24px rgba(255, 77, 77, 0.4);
}
.clawdhub-cta {
.clawhub-cta {
text-align: center;
padding: 48px 24px;
border-radius: 20px;
@ -644,14 +627,14 @@ const showcase = [
margin-bottom: 40px;
}
.clawdhub-title {
.clawhub-title {
font-family: var(--font-display);
font-size: 1.8rem;
font-weight: 600;
margin-bottom: 8px;
}
.clawdhub-desc {
.clawhub-desc {
color: var(--text-muted);
margin-bottom: 24px;
max-width: 600px;
@ -659,7 +642,7 @@ const showcase = [
margin-right: auto;
}
.clawdhub-button {
.clawhub-button {
display: inline-block;
padding: 14px 32px;
border-radius: 10px;
@ -673,7 +656,7 @@ const showcase = [
box-shadow: 0 4px 16px rgba(0, 229, 204, 0.3);
}
.clawdhub-button:hover {
.clawhub-button:hover {
transform: translateY(-2px);
box-shadow: 0 8px 24px rgba(0, 229, 204, 0.4);
}

View File

@ -7,7 +7,7 @@ import extraTestimonials from '../data/testimonials-extra.json';
const allTestimonials = [...testimonials, ...extraTestimonials];
---
<Layout title="Shoutouts — Moltbot">
<Layout title="Shoutouts — OpenClaw">
<div class="stars"></div>
<div class="nebula"></div>
@ -17,7 +17,7 @@ const allTestimonials = [...testimonials, ...extraTestimonials];
<h1 class="title">
<span class="claw-accent">⟩</span> Shoutouts
</h1>
<p class="subtitle">What the community is saying about Moltbot</p>
<p class="subtitle">What the community is saying about OpenClaw</p>
</header>
<div class="shoutouts-grid">
@ -42,11 +42,13 @@ const allTestimonials = [...testimonials, ...extraTestimonials];
<nav class="footer-nav">
<a href="/">Home</a>
<span class="footer-separator">·</span>
<a href="/blog">Blog</a>
<span class="footer-separator">·</span>
<a href="/showcase">Showcase</a>
<span class="footer-separator">·</span>
<a href="/integrations">Integrations</a>
</nav>
<p>Built by <a href="https://molty.me" target="_blank" rel="noopener">Molty</a> 🦞, a space lobster AI with a <a href="https://soul.md" target="_blank" rel="noopener">soul</a>, by <a href="https://steipete.me" target="_blank" rel="noopener">Peter Steinberger</a> & <a href="https://github.com/moltbot/moltbot#community" target="_blank" rel="noopener">community</a>.</p>
<p>Built by <a href="https://molty.me" target="_blank" rel="noopener">Molty</a> 🦞, a space lobster AI with a <a href="https://soul.md" target="_blank" rel="noopener">soul</a>, by <a href="https://steipete.me" target="_blank" rel="noopener">Peter Steinberger</a> & <a href="https://github.com/openclaw/openclaw#community" target="_blank" rel="noopener">community</a>.</p>
</footer>
</main>
</Layout>

View File

@ -17,7 +17,7 @@ const categoryLabels: Record<string, string> = {
};
---
<Layout title="Showcase — What People Are Building with Moltbot">
<Layout title="Showcase — What People Are Building with OpenClaw">
<div class="stars"></div>
<div class="nebula"></div>
@ -61,22 +61,24 @@ const categoryLabels: Record<string, string> = {
<section class="cta-section">
<h2 class="cta-title">Built something cool?</h2>
<p class="cta-desc">Share your Moltbot creation with the community</p>
<p class="cta-desc">Share your OpenClaw creation with the community</p>
<div class="cta-buttons">
<a href="https://twitter.com/intent/tweet?text=Check%20out%20what%20I%20built%20with%20%40clawdbot%21" target="_blank" rel="noopener" class="cta-btn cta-primary">Share on X</a>
<a href="https://clawdhub.com" target="_blank" rel="noopener" class="cta-btn cta-hub">Browse Skills</a>
<a href="https://twitter.com/intent/tweet?text=Check%20out%20what%20I%20built%20with%20%40openclaw%21" target="_blank" rel="noopener" class="cta-btn cta-primary">Share on X</a>
<a href="https://clawhub.com" target="_blank" rel="noopener" class="cta-btn cta-hub">Browse Skills</a>
<a href="https://discord.com/invite/clawd" target="_blank" rel="noopener" class="cta-btn cta-secondary">Join Discord</a>
</div>
</section>
<p class="more-examples">
Looking for more? Check out <a href="https://docs.molt.bot/start/showcase" target="_blank" rel="noopener">even more examples in our docs</a> →
Looking for more? Check out <a href="https://docs.openclaw.ai/start/showcase" target="_blank" rel="noopener">even more examples in our docs</a> →
</p>
<footer class="footer">
<nav class="footer-nav">
<a href="/">Home</a>
<span class="footer-separator">·</span>
<a href="/blog">Blog</a>
<span class="footer-separator">·</span>
<a href="/shoutouts">Shoutouts</a>
<span class="footer-separator">·</span>
<a href="/integrations">Integrations</a>