clawhouse 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +171 -0
- package/bin/clawhouse.js +29 -0
- package/lib/usage.js +568 -0
- package/package.json +30 -0
- package/public/furniture.json +128 -0
- package/public/furniture.png +0 -0
- package/public/icon-180.png +0 -0
- package/public/icon-192.png +0 -0
- package/public/icon-512.png +0 -0
- package/public/icon-maskable-512.png +0 -0
- package/public/index.html +3335 -0
- package/public/manifest.webmanifest +16 -0
- package/public/monitors.json +20 -0
- package/public/monitors.png +0 -0
- package/public/props.json +20 -0
- package/public/props.png +0 -0
- package/public/sprites.json +27 -0
- package/public/sprites.png +0 -0
- package/scripts/build-furniture.js +762 -0
- package/scripts/build-monitors.js +496 -0
- package/scripts/build-props.js +675 -0
- package/scripts/build-sprites.js +1065 -0
- package/scripts/export-profile-pics.js +180 -0
- package/scripts/generate-icons.js +124 -0
- package/server.js +944 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Amin Yekani
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# Clawhouse
|
|
2
|
+
|
|
3
|
+
**Live cost + model control for your [OpenClaw](https://openclaw.dev) fleet — in a pixel-art office your agents actually live in.**
|
|
4
|
+
|
|
5
|
+
> Part of **Clawvision** — the visualization family for OpenClaw. Clawhouse is the office; sibling apps will follow.
|
|
6
|
+
|
|
7
|
+
Other pixel-office projects show your agents walking around. This one is the only one that also tracks **what each session costs**, **which model is burning your budget**, and **lets you swap models without editing JSON**. The pixels are the hook; the cost panel is the reason to keep it open.
|
|
8
|
+
|
|
9
|
+
> _Demo GIF goes here — record with `npm run demo` and any screen recorder._
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Why this one
|
|
14
|
+
|
|
15
|
+
| | Clawhouse | [pixel-agents](https://github.com/pablodelucca/pixel-agents) | [Star-Office-UI](https://github.com/ringhyacinth/Star-Office-UI) | [agent-office](https://github.com/harishkotra/agent-office) |
|
|
16
|
+
|---|---|---|---|---|
|
|
17
|
+
| OpenClaw native (sessions, cron, sub-agents) | ✅ | ❌ Claude Code only | ✅ | ❌ Ollama |
|
|
18
|
+
| Live USD cost per agent / per window | ✅ | ❌ | ❌ | ❌ |
|
|
19
|
+
| Cost-aware room glow (red when burning hot) | ✅ | ❌ | ❌ | ❌ |
|
|
20
|
+
| Model switcher in-UI | ✅ | ❌ | ❌ | ❌ |
|
|
21
|
+
| Sub-agent visualisation | ✅ | ✅ | ❌ | ✅ |
|
|
22
|
+
| Speech bubbles for "needs attention" | ✅ | ✅ | ❌ | ❌ |
|
|
23
|
+
| Task-completion sound chime | ✅ | ✅ | ❌ | ❌ |
|
|
24
|
+
| Zero npm dependencies | ✅ | ❌ build chain | ❌ Python+pip | ❌ TS monorepo |
|
|
25
|
+
| One-command demo (no install) | ✅ `npm run demo` | ❌ | ❌ | ❌ |
|
|
26
|
+
|
|
27
|
+
## Features at a glance
|
|
28
|
+
|
|
29
|
+
- **Live cost panel** — per-agent USD spend rolled up by current session / 24h / 30d / 365d, with provider breakdown (Anthropic / OpenAI). Subscription-aware: prorates a flat monthly fee instead of pretending sub usage is per-token billed.
|
|
30
|
+
- **Cost-aware room glow** — agent's room flashes amber when this session is burning ≥40% of its 24h budget, red-pulsing when ≥75%. The "is this expensive?" gut check, visible at a glance.
|
|
31
|
+
- **Speech bubbles** — agents call out when they crash, fail consecutively, run hot on context, or are actively thinking. Severity-coloured (red / amber / blue) so a glance tells you which room to click.
|
|
32
|
+
- **Sub-agent minions** — small sprites cluster next to the parent when an agent has spawned background workers. `+N` badge appears past 3.
|
|
33
|
+
- **Sound chime** — opt-in (🔔 button in the topbar) WebAudio ding when an agent transitions from `running` to `done`. State persists in `localStorage`.
|
|
34
|
+
- **Model switcher** — drop-down in the side panel calls `openclaw config set` so you can demote Opus → Sonnet → Haiku without touching `~/.openclaw/openclaw.json`.
|
|
35
|
+
- **Products rail** — optional launcher strip above the office grid for apps and dashboards your agents build (`products.json`).
|
|
36
|
+
- **Stats panel** — token usage, context %, cache hit rate, model in use, recent sessions, scheduled cron jobs, queued tasks — all the data that's already in `~/.openclaw/` rendered without the JSON.
|
|
37
|
+
|
|
38
|
+
## Quick start
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Run instantly with no install (demo mode)
|
|
42
|
+
npx clawhouse --demo
|
|
43
|
+
|
|
44
|
+
# Or clone for local dev:
|
|
45
|
+
git clone https://github.com/aminyekani/clawhouse.git
|
|
46
|
+
cd clawhouse
|
|
47
|
+
npm run demo # synthetic full-cast demo, no OpenClaw needed
|
|
48
|
+
node server.js # live mode if OpenClaw is running on this machine
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Open **http://localhost:18890**. Demo mode is auto-enabled when `~/.openclaw` doesn't exist, or force it with `PIXEL_OFFICE_DEMO=1`.
|
|
52
|
+
|
|
53
|
+
## Requirements
|
|
54
|
+
|
|
55
|
+
| | |
|
|
56
|
+
|---|---|
|
|
57
|
+
| Node.js ≥ 22 | Uses built-in `node:sqlite` |
|
|
58
|
+
| OpenClaw | Optional — only needed for live fleet data |
|
|
59
|
+
|
|
60
|
+
## Configuration
|
|
61
|
+
|
|
62
|
+
All configuration via environment variables — no config file:
|
|
63
|
+
|
|
64
|
+
| Variable | Default | Description |
|
|
65
|
+
|---|---|---|
|
|
66
|
+
| `PIXEL_OFFICE_PORT` | `18890` | HTTP listen port |
|
|
67
|
+
| `PIXEL_OFFICE_HOST` | `0.0.0.0` | Bind address (`127.0.0.1` for local-only) |
|
|
68
|
+
| `OPENCLAW_URL` | `http://127.0.0.1:18789/` | OpenClaw gateway URL (for model-switch actions) |
|
|
69
|
+
| `OPENCLAW_STATE_DIR` | `~/.openclaw` | Path to your OpenClaw state directory |
|
|
70
|
+
| `PIXEL_OFFICE_DEMO` | _(unset)_ | Set `1` to force demo mode |
|
|
71
|
+
| `PIXEL_OFFICE_MODELS` | _(built-in list)_ | JSON array of `{id, label}` to offer in the model switcher |
|
|
72
|
+
|
|
73
|
+
## Customising your fleet
|
|
74
|
+
|
|
75
|
+
See **[docs/CUSTOMIZE.md](docs/CUSTOMIZE.md)** for step-by-step instructions on:
|
|
76
|
+
|
|
77
|
+
- Adding a new agent room (sprite, props, monitor, room theme)
|
|
78
|
+
- Changing an agent's appearance (skin, hair, outfit, face type, accessories)
|
|
79
|
+
- Writing a custom wall prop or monitor screen in the build scripts
|
|
80
|
+
- Adding products to the launcher rail
|
|
81
|
+
|
|
82
|
+
## Building sprite atlases
|
|
83
|
+
|
|
84
|
+
The PNG sprite sheets are pre-built and committed, so you only need to rebuild after changing visual definitions:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
npm run build # rebuild all atlases (sprites, props, monitors, furniture, icons)
|
|
88
|
+
npm run build:sprites # character sprites only
|
|
89
|
+
npm run build:profiles # export 768×768 profile pics (Telegram-ready)
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Running as a service (systemd)
|
|
93
|
+
|
|
94
|
+
```ini
|
|
95
|
+
# ~/.config/systemd/user/clawhouse.service
|
|
96
|
+
[Unit]
|
|
97
|
+
Description=Clawhouse fleet board
|
|
98
|
+
After=network.target
|
|
99
|
+
|
|
100
|
+
[Service]
|
|
101
|
+
WorkingDirectory=/path/to/clawhouse
|
|
102
|
+
ExecStart=/usr/bin/node server.js
|
|
103
|
+
Restart=on-failure
|
|
104
|
+
Environment=PIXEL_OFFICE_PORT=18890
|
|
105
|
+
|
|
106
|
+
[Install]
|
|
107
|
+
WantedBy=default.target
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
systemctl --user daemon-reload
|
|
112
|
+
systemctl --user enable --now clawhouse
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Optional: products.json
|
|
116
|
+
|
|
117
|
+
Drop a `products.json` next to `server.js` to add a launch strip above the office grid. See `products.example.json` for the full schema. Each product declares:
|
|
118
|
+
|
|
119
|
+
```jsonc
|
|
120
|
+
{
|
|
121
|
+
"products": [
|
|
122
|
+
{
|
|
123
|
+
"id": "my-dashboard",
|
|
124
|
+
"agentId": "analyst",
|
|
125
|
+
"name": "My Dashboard",
|
|
126
|
+
"description": "Short blurb shown in the card.",
|
|
127
|
+
"status": "live",
|
|
128
|
+
"port": 8787,
|
|
129
|
+
"path": "/dashboard/",
|
|
130
|
+
"start": {
|
|
131
|
+
"cwd": "/path/to/project",
|
|
132
|
+
"cmd": "node",
|
|
133
|
+
"args": ["start.mjs"]
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
]
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Status rules
|
|
141
|
+
|
|
142
|
+
| Age of last session activity | Status |
|
|
143
|
+
|---|---|
|
|
144
|
+
| < 1 minute | 🟢 active |
|
|
145
|
+
| 1–10 minutes | 🟡 idle |
|
|
146
|
+
| ≥ 10 minutes | ⚪ away |
|
|
147
|
+
|
|
148
|
+
## Burn-rate rules
|
|
149
|
+
|
|
150
|
+
The room glow compares the current session's billed cost to the trailing 24h:
|
|
151
|
+
|
|
152
|
+
| `session.billed / day.billed` | Visual |
|
|
153
|
+
|---|---|
|
|
154
|
+
| < 40% | normal room glow |
|
|
155
|
+
| 40 – 75% | 🟠 amber static glow ("hot") |
|
|
156
|
+
| ≥ 75% | 🔴 red pulse glow ("critical") |
|
|
157
|
+
|
|
158
|
+
## Speech-bubble rules
|
|
159
|
+
|
|
160
|
+
| Trigger | Variant |
|
|
161
|
+
|---|---|
|
|
162
|
+
| Last session ended mid-run (`abortedLastRun`) | 🔴 alert (pulse) |
|
|
163
|
+
| Same task failed ≥ 2× in a row | 🔴 alert (pulse) |
|
|
164
|
+
| Task issue in last 6h | 🟠 warn |
|
|
165
|
+
| Context window ≥ 95% full | 🟠 warn |
|
|
166
|
+
| Session running, agent active | 🔵 busy |
|
|
167
|
+
| Otherwise | personality quip (rotates each minute) |
|
|
168
|
+
|
|
169
|
+
## License
|
|
170
|
+
|
|
171
|
+
MIT — see [LICENSE](LICENSE).
|
package/bin/clawhouse.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// npx entrypoint — forwards CLI flags into env vars so `npx clawhouse`
|
|
3
|
+
// launches the same server.js the repo's `node server.js` does.
|
|
4
|
+
//
|
|
5
|
+
// --demo force demo mode (no ~/.openclaw needed)
|
|
6
|
+
// --port <n> listen port (overrides PIXEL_OFFICE_PORT)
|
|
7
|
+
// --host <addr> bind address (overrides PIXEL_OFFICE_HOST)
|
|
8
|
+
// --state-dir <d> path to OpenClaw state (overrides OPENCLAW_STATE_DIR)
|
|
9
|
+
//
|
|
10
|
+
// Anything else is passed straight through; defaults live in server.js.
|
|
11
|
+
|
|
12
|
+
const path = require('path');
|
|
13
|
+
|
|
14
|
+
const argv = process.argv.slice(2);
|
|
15
|
+
for (let i = 0; i < argv.length; i++) {
|
|
16
|
+
const flag = argv[i];
|
|
17
|
+
const next = argv[i + 1];
|
|
18
|
+
if (flag === '--demo') process.env.PIXEL_OFFICE_DEMO = '1';
|
|
19
|
+
else if (flag === '--port' && next) { process.env.PIXEL_OFFICE_PORT = next; i++; }
|
|
20
|
+
else if (flag === '--host' && next) { process.env.PIXEL_OFFICE_HOST = next; i++; }
|
|
21
|
+
else if (flag === '--state-dir' && next) { process.env.OPENCLAW_STATE_DIR = next; i++; }
|
|
22
|
+
else if (flag === '--openclaw' && next) { process.env.OPENCLAW_URL = next; i++; }
|
|
23
|
+
else if (flag === '--help' || flag === '-h') {
|
|
24
|
+
console.log('Usage: clawhouse [--demo] [--port N] [--host ADDR] [--state-dir PATH] [--openclaw URL]');
|
|
25
|
+
process.exit(0);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
require(path.join(__dirname, '..', 'server.js'));
|