mirror of
https://github.com/crabwise-ai/crabwalk.git
synced 2026-08-16 01:52:03 +00:00
Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f5eb110123 | ||
|
|
9181d11047 | ||
|
|
2155d0cffa | ||
|
|
a132a33c6b | ||
|
|
c39ae8a375 | ||
|
|
6811bf7c60 |
@@ -36,7 +36,7 @@ Full-stack React app using TanStack Start (file-based routing, SSR).
|
||||
|
||||
**TanStack DB pattern:** Create collections, use `useLiveQuery()` for reactive reads, `createTransaction()` for writes.
|
||||
|
||||
## Clawdbot Monitor
|
||||
## Moltbot (Clawdbot) Monitor
|
||||
|
||||
Real-time agent activity monitor at `/monitor`.
|
||||
|
||||
|
||||
+10
-4
@@ -9,16 +9,22 @@ RUN npm ci
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
# Production stage
|
||||
# Runtime stage
|
||||
FROM node:22-alpine AS runner
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
ENV NODE_ENV=production
|
||||
# NOTE: TanStack Start server entry produced by `vite build` does not bind a port
|
||||
# on its own in this repo, so we run the Vite dev server in Docker for now.
|
||||
# This makes the published image functional while we figure out a proper prod server.
|
||||
|
||||
ENV NODE_ENV=development
|
||||
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
|
||||
COPY --from=builder /app/dist ./dist
|
||||
COPY --from=builder /app/package.json ./
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
CMD ["node", "dist/server/server.js"]
|
||||
CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0", "--port", "3000"]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 🦀 Crabwalk
|
||||
|
||||
Real-time companion monitor for [Clawdbot](https://github.com/clawdbot/clawdbot) agents by [@luccasveg](https://x.com/luccasveg).
|
||||
Real-time companion monitor for [Moltbot (Clawdbot)](https://github.com/moltbot/moltbot) agents by [@luccasveg](https://x.com/luccasveg).
|
||||
|
||||
Watch your AI agents work across WhatsApp, Telegram, Discord, and Slack in a live node graph. See thinking states, tool calls, and response chains as they happen.
|
||||
|
||||
@@ -24,14 +24,18 @@ Watch your AI agents work across WhatsApp, Telegram, Discord, and Slack in a liv
|
||||
docker run -d \
|
||||
-p 3000:3000 \
|
||||
-e CLAWDBOT_API_TOKEN=your-token \
|
||||
-e CLAWDBOT_URL=ws://host.docker.internal:18789 \
|
||||
ghcr.io/luccast/crabwalk:latest
|
||||
```
|
||||
|
||||
> Note: When running Crabwalk in Docker, the Clawdbot gateway typically runs on the *host*.
|
||||
> Use `CLAWDBOT_URL=ws://host.docker.internal:18789` so the container can connect.
|
||||
|
||||
Or with docker-compose:
|
||||
|
||||
```bash
|
||||
curl -O https://raw.githubusercontent.com/luccast/crabwalk/master/docker-compose.yml
|
||||
CLAWDBOT_API_TOKEN=your-token docker-compose up -d
|
||||
CLAWDBOT_API_TOKEN=your-token CLAWDBOT_URL=ws://host.docker.internal:18789 docker-compose up -d
|
||||
```
|
||||
|
||||
### From source
|
||||
@@ -54,13 +58,14 @@ Requires clawdbot gateway running on the same machine.
|
||||
Find your token in the clawdbot config file:
|
||||
|
||||
```bash
|
||||
cat ~/.clawdbot/clawdbot.json | grep api_token
|
||||
# Look for gateway.auth.token
|
||||
cat ~/.clawdbot/clawdbot.json | rg "gateway\.auth\.token"
|
||||
```
|
||||
|
||||
Or copy it directly:
|
||||
|
||||
```bash
|
||||
export CLAWDBOT_API_TOKEN=$(cat ~/.clawdbot/clawdbot.json | grep -o '"api_token": *"[^"]*"' | cut -d'"' -f4)
|
||||
export CLAWDBOT_API_TOKEN=$(python3 -c "import json,os; print(json.load(open(os.path.expanduser('~/.clawdbot/clawdbot.json')))['gateway']['auth']['token'])")
|
||||
```
|
||||
|
||||
## Stack
|
||||
|
||||
Generated
+4
-19
@@ -1,14 +1,15 @@
|
||||
{
|
||||
"name": "crabwalk",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "crabwalk",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"dependencies": {
|
||||
"@tanstack/db": "^0.5.0",
|
||||
"@tanstack/history": "^1.132.0",
|
||||
"@tanstack/react-db": "^0.1.0",
|
||||
"@tanstack/react-query": "^5.0.0",
|
||||
"@tanstack/react-router": "^1.132.0",
|
||||
@@ -69,7 +70,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.6.tgz",
|
||||
"integrity": "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.28.6",
|
||||
"@babel/generator": "^7.28.6",
|
||||
@@ -1547,7 +1547,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.20.tgz",
|
||||
"integrity": "sha512-vXBxa+qeyveVO7OA0jX1z+DeyCA4JKnThKv411jd5SORpBKgkcVnYKCiBgECvADvniBX7tobwBmg01qq9JmMJw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@tanstack/query-core": "5.90.20"
|
||||
},
|
||||
@@ -1582,7 +1581,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/react-router/-/react-router-1.157.13.tgz",
|
||||
"integrity": "sha512-rLr6swdDhLjadAHbukg/XYurNi4q8AmmjP99QiWUnhRPKfrfmQ/O1UCvaowQ9GcaiyOG2COiJ9OlDAQU3k9MFQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@tanstack/history": "1.154.14",
|
||||
"@tanstack/react-store": "^0.8.0",
|
||||
@@ -1729,7 +1727,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/router-core/-/router-core-1.157.13.tgz",
|
||||
"integrity": "sha512-dl1avpRH2Pi1tYhxDzGEqI6DU9VQUf5zBeW1JJFs3LfJuVkGd2lG93dSUzH9seJNp77hm8JWhoX+k4QYMEB6KA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@tanstack/history": "1.154.14",
|
||||
"@tanstack/store": "^0.8.0",
|
||||
@@ -2040,7 +2037,6 @@
|
||||
"https://trpc.io/sponsor"
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"peerDependencies": {
|
||||
"typescript": ">=5.7.2"
|
||||
}
|
||||
@@ -2208,7 +2204,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.9.tgz",
|
||||
"integrity": "sha512-Lpo8kgb/igvMIPeNV2rsYKTgaORYdO1XGVZ4Qz3akwOj0ySGYMPlQWa8BaLn0G63D1aSaAQ5ldR06wCpChQCjA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"csstype": "^3.2.2"
|
||||
}
|
||||
@@ -2437,7 +2432,6 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"baseline-browser-mapping": "^2.9.0",
|
||||
"caniuse-lite": "^1.0.30001759",
|
||||
@@ -2672,8 +2666,7 @@
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
|
||||
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/d3-color": {
|
||||
"version": "3.1.0",
|
||||
@@ -2732,7 +2725,6 @@
|
||||
"resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
|
||||
"integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
|
||||
"license": "ISC",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
@@ -4576,7 +4568,6 @@
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz",
|
||||
"integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@@ -4586,7 +4577,6 @@
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz",
|
||||
"integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"scheduler": "^0.27.0"
|
||||
},
|
||||
@@ -4786,7 +4776,6 @@
|
||||
"resolved": "https://registry.npmjs.org/seroval/-/seroval-1.5.0.tgz",
|
||||
"integrity": "sha512-OE4cvmJ1uSPrKorFIH9/w/Qwuvi/IMcGbv5RKgcJ/zjA/IohDLU6SVaxFN9FwajbP7nsX0dQqMDes1whk3y+yw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
@@ -4964,7 +4953,6 @@
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
@@ -5054,7 +5042,6 @@
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
@@ -5271,7 +5258,6 @@
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz",
|
||||
"integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"esbuild": "^0.27.0",
|
||||
"fdir": "^6.5.0",
|
||||
@@ -5382,7 +5368,6 @@
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
|
||||
+3
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "crabwalk",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
@@ -28,7 +28,8 @@
|
||||
"superjson": "^2.2.0",
|
||||
"vite-tsconfig-paths": "^5.1.4",
|
||||
"ws": "^8.19.0",
|
||||
"zod": "^3.24.0"
|
||||
"zod": "^3.24.0",
|
||||
"@tanstack/history": "^1.132.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/vite": "^4.0.0",
|
||||
|
||||
@@ -67,10 +67,10 @@ export function addAction(action: MonitorAction) {
|
||||
const streamingId = `${action.runId}-stream`
|
||||
const existing = actionsCollection.state.get(streamingId)
|
||||
if (existing) {
|
||||
// Append content and update sessionKey if we learned it
|
||||
// Replace content (gateway sends cumulative text, not incremental deltas)
|
||||
actionsCollection.update(streamingId, (draft) => {
|
||||
if (action.content) {
|
||||
draft.content = (draft.content || '') + action.content
|
||||
draft.content = action.content
|
||||
}
|
||||
draft.seq = action.seq
|
||||
draft.timestamp = action.timestamp
|
||||
|
||||
@@ -60,6 +60,7 @@ export interface PresenceEntry {
|
||||
}
|
||||
|
||||
// Chat events
|
||||
// Note: gateway sends cumulative message content with each delta, not incremental chars
|
||||
export interface ChatEvent {
|
||||
runId: string
|
||||
sessionKey: string
|
||||
|
||||
@@ -122,7 +122,7 @@ function Home() {
|
||||
transition={{ duration: 0.5, delay: 0.3 }}
|
||||
className="font-console font-bold text-lg text-gray-400 mb-4 tracking-wide uppercase"
|
||||
>
|
||||
Open-Source Clawdbot Companion
|
||||
Open-Source Moltbot (Clawdbot) Companion
|
||||
</motion.p>
|
||||
|
||||
{/* Console-style description */}
|
||||
|
||||
Reference in New Issue
Block a user