clawctl 0.2.0__tar.gz
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.
- clawctl-0.2.0/LICENSE +21 -0
- clawctl-0.2.0/PKG-INFO +273 -0
- clawctl-0.2.0/README.md +247 -0
- clawctl-0.2.0/clawctl/__init__.py +2 -0
- clawctl-0.2.0/clawctl/cli.py +510 -0
- clawctl-0.2.0/clawctl/db.py +473 -0
- clawctl-0.2.0/clawctl/schema.sql +68 -0
- clawctl-0.2.0/clawctl.egg-info/PKG-INFO +273 -0
- clawctl-0.2.0/clawctl.egg-info/SOURCES.txt +20 -0
- clawctl-0.2.0/clawctl.egg-info/dependency_links.txt +1 -0
- clawctl-0.2.0/clawctl.egg-info/entry_points.txt +2 -0
- clawctl-0.2.0/clawctl.egg-info/requires.txt +6 -0
- clawctl-0.2.0/clawctl.egg-info/top_level.txt +2 -0
- clawctl-0.2.0/dashboard/__init__.py +0 -0
- clawctl-0.2.0/dashboard/__main__.py +3 -0
- clawctl-0.2.0/dashboard/index.html +1464 -0
- clawctl-0.2.0/dashboard/server.py +166 -0
- clawctl-0.2.0/pyproject.toml +44 -0
- clawctl-0.2.0/setup.cfg +4 -0
- clawctl-0.2.0/tests/test_cli.py +363 -0
- clawctl-0.2.0/tests/test_db.py +622 -0
- clawctl-0.2.0/tests/test_server.py +137 -0
clawctl-0.2.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Larry Ludlow
|
|
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.
|
clawctl-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: clawctl
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Coordination layer for OpenClaw agent fleets
|
|
5
|
+
Author: Larry Ludlow
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/lludlow/clawctl
|
|
8
|
+
Project-URL: Repository, https://github.com/lludlow/clawctl
|
|
9
|
+
Project-URL: Issues, https://github.com/lludlow/clawctl/issues
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Requires-Python: >=3.9
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: click
|
|
21
|
+
Requires-Dist: flask
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Requires-Dist: pytest; extra == "dev"
|
|
24
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
25
|
+
Dynamic: license-file
|
|
26
|
+
|
|
27
|
+
# clawctl
|
|
28
|
+
|
|
29
|
+
Coordination layer for [OpenClaw](https://github.com/openclaw/openclaw) agent fleets. Task board, inter-agent messaging, activity feed, and a live web dashboard — all backed by a single SQLite database.
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
$ clawctl board
|
|
33
|
+
|
|
34
|
+
═══ CLAWCTL ═══ agent: chat
|
|
35
|
+
|
|
36
|
+
── ○ pending (2) ──
|
|
37
|
+
#4 Summarize weekly spending from transaction exports
|
|
38
|
+
#6 Find showtimes for new releases this weekend [movie]
|
|
39
|
+
|
|
40
|
+
── ▶ in_progress (2) ──
|
|
41
|
+
#1 Research best noise-cancelling headphones under $300 [research]
|
|
42
|
+
#5 Write a Python script to rename photos by EXIF date [coding]
|
|
43
|
+
|
|
44
|
+
── ✗ blocked (1) ──
|
|
45
|
+
#3 File notes from the headphone research [notes]
|
|
46
|
+
|
|
47
|
+
── ✓ done (1) ──
|
|
48
|
+
#2 Check portfolio risk exposure for earnings week [trading]
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Why this exists
|
|
52
|
+
|
|
53
|
+
Multiple agents working in parallel need a shared source of truth. Without one, you get duplicate work, missed handoffs, and no audit trail.
|
|
54
|
+
|
|
55
|
+
clawctl is the answer for OpenClaw fleets:
|
|
56
|
+
|
|
57
|
+
- **Zero infrastructure.** Local SQLite in WAL mode. No cloud, no signup, no build step.
|
|
58
|
+
- **SSH-queryable.** `ssh your-vps clawctl board` works out of the box.
|
|
59
|
+
- **Race-safe.** Atomic claims and completions via single-UPDATE patterns with WHERE guards. No read-then-write races.
|
|
60
|
+
- **Auditable.** Every mutation hits an append-only activity log with optional JSON metadata for linking PRs, issues, test results.
|
|
61
|
+
- **OpenClaw-native.** Install as a skill, drop into any agent's workflow.
|
|
62
|
+
|
|
63
|
+
## Install
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
pip install clawctl
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Or from source:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
git clone https://github.com/lludlow/clawctl.git
|
|
73
|
+
cd clawctl
|
|
74
|
+
pip install -e .
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Requirements:** Python >= 3.9
|
|
78
|
+
|
|
79
|
+
## Quick start
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# Initialize
|
|
83
|
+
clawctl init
|
|
84
|
+
|
|
85
|
+
# Register the fleet
|
|
86
|
+
clawctl register chat --role "everyday triage & delegation"
|
|
87
|
+
clawctl register research --role "deep reasoning & web search"
|
|
88
|
+
clawctl register coding --role "sandboxed code execution"
|
|
89
|
+
clawctl register notes --role "knowledge graph & note-taking"
|
|
90
|
+
clawctl register trading --role "read-only market analysis"
|
|
91
|
+
clawctl register family --role "mention-gated secure responder"
|
|
92
|
+
clawctl register movie --role "watchlists & recommendations"
|
|
93
|
+
|
|
94
|
+
# Chat agent delegates work to specialists
|
|
95
|
+
CLAW_AGENT=chat clawctl add "Research best noise-cancelling headphones under $300" --for research
|
|
96
|
+
CLAW_AGENT=chat clawctl add "Write a Python script to rename photos by EXIF date" --for coding -p 1
|
|
97
|
+
CLAW_AGENT=chat clawctl add "File notes from the headphone research" --for notes
|
|
98
|
+
|
|
99
|
+
# Research agent picks up its task
|
|
100
|
+
CLAW_AGENT=research clawctl claim 1
|
|
101
|
+
CLAW_AGENT=research clawctl start 1
|
|
102
|
+
CLAW_AGENT=research clawctl done 1 -m "Top 3 picks with comparison table" \
|
|
103
|
+
--meta '{"note":"~/notes/headphone-research.md"}'
|
|
104
|
+
|
|
105
|
+
# Research hands off to notes for filing
|
|
106
|
+
CLAW_AGENT=research clawctl msg notes "Research complete, ready to file" --task 3
|
|
107
|
+
|
|
108
|
+
# Monitor
|
|
109
|
+
clawctl board
|
|
110
|
+
clawctl fleet
|
|
111
|
+
clawctl feed --last 10
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Agent integration
|
|
115
|
+
|
|
116
|
+
The typical agent loop:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
# On startup — check messages, find work
|
|
120
|
+
CLAW_AGENT=coding clawctl checkin
|
|
121
|
+
CLAW_AGENT=coding clawctl inbox --unread
|
|
122
|
+
CLAW_AGENT=coding clawctl next
|
|
123
|
+
|
|
124
|
+
# Do the work, then close out
|
|
125
|
+
CLAW_AGENT=coding clawctl done <id> -m "Script written and tested" \
|
|
126
|
+
--meta '{"script":"~/scripts/rename-photos.py","tests":"passed"}'
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Add a heartbeat to each agent's cron:
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
*/10 * * * * CLAW_AGENT=chat clawctl checkin
|
|
133
|
+
*/10 * * * * CLAW_AGENT=research clawctl checkin
|
|
134
|
+
*/10 * * * * CLAW_AGENT=coding clawctl checkin
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Add to each agent's system prompt or AGENTS.md:
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
Before starting work: clawctl inbox --unread && clawctl list --mine
|
|
141
|
+
After completing work: clawctl done <id> -m "what I did"
|
|
142
|
+
Only claim tasks assigned to you or matching your role.
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
> If `CLAW_AGENT` is not set, clawctl falls back to `$USER` and prints a one-time warning on identity-sensitive commands.
|
|
146
|
+
|
|
147
|
+
## Commands
|
|
148
|
+
|
|
149
|
+
### Tasks
|
|
150
|
+
|
|
151
|
+
| Command | Description |
|
|
152
|
+
|---------|-------------|
|
|
153
|
+
| `add SUBJECT` | Create a task. Options: `-d` description, `-p 0\|1\|2` priority, `--for AGENT` pre-assign, `--parent ID` subtask |
|
|
154
|
+
| `list` | List active tasks. Options: `--mine`, `--status STATUS`, `--owner AGENT`, `--all` (include done/cancelled) |
|
|
155
|
+
| `next` | Show the highest-priority actionable task for the current agent |
|
|
156
|
+
| `claim ID` | Claim a task. Options: `--force` to override, `--meta JSON` |
|
|
157
|
+
| `start ID` | Begin work (transitions to in_progress). Options: `--meta JSON` |
|
|
158
|
+
| `done ID` | Complete a task. Options: `-m` note, `--force`, `--meta JSON` |
|
|
159
|
+
| `review ID` | Mark task as ready for review. Options: `--meta JSON` |
|
|
160
|
+
| `cancel ID` | Cancel a task. Options: `--meta JSON` |
|
|
161
|
+
| `block ID --by OTHER` | Mark task as blocked. Options: `--meta JSON` |
|
|
162
|
+
| `board` | Kanban board view grouped by status |
|
|
163
|
+
|
|
164
|
+
### Messages
|
|
165
|
+
|
|
166
|
+
| Command | Description |
|
|
167
|
+
|---------|-------------|
|
|
168
|
+
| `msg AGENT BODY` | Send a message. Options: `--task ID`, `--type TYPE` |
|
|
169
|
+
| `broadcast BODY` | Message all agents (type: alert) |
|
|
170
|
+
| `inbox` | Read messages. Options: `--unread` |
|
|
171
|
+
|
|
172
|
+
### Fleet
|
|
173
|
+
|
|
174
|
+
| Command | Description |
|
|
175
|
+
|---------|-------------|
|
|
176
|
+
| `register NAME` | Register an agent. Options: `--role TEXT` |
|
|
177
|
+
| `checkin` | Heartbeat — update presence, check for unread |
|
|
178
|
+
| `fleet` | Show all agents with status and current task |
|
|
179
|
+
| `whoami` | Show identity, role, and DB path |
|
|
180
|
+
|
|
181
|
+
### Monitoring
|
|
182
|
+
|
|
183
|
+
| Command | Description |
|
|
184
|
+
|---------|-------------|
|
|
185
|
+
| `feed` | Activity log. Options: `--last N`, `--agent NAME`, `--meta` |
|
|
186
|
+
| `summary` | Fleet overview with counts and recent events |
|
|
187
|
+
|
|
188
|
+
### Dashboard
|
|
189
|
+
|
|
190
|
+
| Command | Description |
|
|
191
|
+
|---------|-------------|
|
|
192
|
+
| `dashboard` | Start the web UI. Options: `--port INT` (default: 3737), `--verbose` |
|
|
193
|
+
| `dashboard --stop` | Stop the running dashboard |
|
|
194
|
+
|
|
195
|
+
## Task statuses
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
pending ─→ claimed ─→ in_progress ─→ done
|
|
199
|
+
↘ blocked ↗ ↘ cancelled
|
|
200
|
+
↘ review ↗
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
`list` excludes done/cancelled by default and sorts by status priority (in_progress > claimed > blocked > review > pending), oldest first. `--all` flips to newest-first for history browsing.
|
|
204
|
+
|
|
205
|
+
## Activity metadata
|
|
206
|
+
|
|
207
|
+
Mutating commands (`claim`, `start`, `done`, `block`) accept `--meta` with a JSON string stored in the activity log. Use it to link back to external artifacts:
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
clawctl claim 1 --meta '{"source":"whatsapp","channel":"general"}'
|
|
211
|
+
clawctl done 1 -m "Top 3 picks with pros/cons" --meta '{"note":"~/notes/headphone-research.md"}'
|
|
212
|
+
|
|
213
|
+
# Review what happened overnight
|
|
214
|
+
clawctl feed --last 50 --agent research --meta
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Web dashboard
|
|
218
|
+
|
|
219
|
+
A live web UI served by Flask with token authentication and SSE for real-time updates.
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
clawctl dashboard
|
|
223
|
+
# Opens at http://localhost:3737/?token=<TOKEN>
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Features:
|
|
227
|
+
- Live board with SSE push updates (no polling)
|
|
228
|
+
- Task detail view with messages and metadata grid
|
|
229
|
+
- Complete and delete actions from the UI
|
|
230
|
+
- Terminal/hacker aesthetic with optional CRT effects
|
|
231
|
+
- Keyboard accessible (Esc to close, Tab trapping in modals)
|
|
232
|
+
- Works on narrow viewports
|
|
233
|
+
- Token persisted at `~/.openclaw/.clawctl-token` across restarts
|
|
234
|
+
|
|
235
|
+
The dashboard is read-mostly — it shares the same SQLite database the CLI writes to. The CLI is the primary interface; the dashboard is for monitoring.
|
|
236
|
+
|
|
237
|
+
## Architecture
|
|
238
|
+
|
|
239
|
+
```
|
|
240
|
+
┌─────────────────────────────┐
|
|
241
|
+
│ clawctl CLI (Python/Click) │ ← Every agent calls this
|
|
242
|
+
├─────────────────────────────┤
|
|
243
|
+
│ db.py — all SQL lives here │ ← Shared by CLI + Flask
|
|
244
|
+
├─────────────────────────────┤
|
|
245
|
+
│ SQLite (WAL mode) │ ← ~/.openclaw/clawctl.db
|
|
246
|
+
├─────────────────────────────┤
|
|
247
|
+
│ 5 tables + indexes: │
|
|
248
|
+
│ tasks task_deps │ ← Board + blocking graph
|
|
249
|
+
│ messages agents │ ← Comms + fleet registry
|
|
250
|
+
│ activity │ ← Append-only audit log
|
|
251
|
+
├─────────────────────────────┤
|
|
252
|
+
│ Flask dashboard (optional) │ ← dashboard/server.py
|
|
253
|
+
└─────────────────────────────┘
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
**Key design decisions:**
|
|
257
|
+
|
|
258
|
+
- **All SQL in `db.py`.** The CLI and Flask server import it. No queries in `cli.py` or `server.py`.
|
|
259
|
+
- **Race safety.** `claim_task()` and `complete_task()` use atomic single-UPDATE with WHERE guards and rowcount checks. No read-then-write.
|
|
260
|
+
- **Normalized blocking.** Dependencies live in the `task_deps` join table with a UNIQUE constraint. Not JSON columns.
|
|
261
|
+
- **Parameterized queries.** Every query uses `?` placeholders. No string interpolation.
|
|
262
|
+
- **Idempotent completions.** `done` on an already-done task is a safe no-op.
|
|
263
|
+
|
|
264
|
+
## Environment variables
|
|
265
|
+
|
|
266
|
+
| Variable | Default | Description |
|
|
267
|
+
|----------|---------|-------------|
|
|
268
|
+
| `CLAW_AGENT` | `$USER` (with warning) | Agent identity for all commands |
|
|
269
|
+
| `CLAW_DB` | `~/.openclaw/clawctl.db` | Database file path |
|
|
270
|
+
|
|
271
|
+
## License
|
|
272
|
+
|
|
273
|
+
MIT
|
clawctl-0.2.0/README.md
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
# clawctl
|
|
2
|
+
|
|
3
|
+
Coordination layer for [OpenClaw](https://github.com/openclaw/openclaw) agent fleets. Task board, inter-agent messaging, activity feed, and a live web dashboard — all backed by a single SQLite database.
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
$ clawctl board
|
|
7
|
+
|
|
8
|
+
═══ CLAWCTL ═══ agent: chat
|
|
9
|
+
|
|
10
|
+
── ○ pending (2) ──
|
|
11
|
+
#4 Summarize weekly spending from transaction exports
|
|
12
|
+
#6 Find showtimes for new releases this weekend [movie]
|
|
13
|
+
|
|
14
|
+
── ▶ in_progress (2) ──
|
|
15
|
+
#1 Research best noise-cancelling headphones under $300 [research]
|
|
16
|
+
#5 Write a Python script to rename photos by EXIF date [coding]
|
|
17
|
+
|
|
18
|
+
── ✗ blocked (1) ──
|
|
19
|
+
#3 File notes from the headphone research [notes]
|
|
20
|
+
|
|
21
|
+
── ✓ done (1) ──
|
|
22
|
+
#2 Check portfolio risk exposure for earnings week [trading]
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Why this exists
|
|
26
|
+
|
|
27
|
+
Multiple agents working in parallel need a shared source of truth. Without one, you get duplicate work, missed handoffs, and no audit trail.
|
|
28
|
+
|
|
29
|
+
clawctl is the answer for OpenClaw fleets:
|
|
30
|
+
|
|
31
|
+
- **Zero infrastructure.** Local SQLite in WAL mode. No cloud, no signup, no build step.
|
|
32
|
+
- **SSH-queryable.** `ssh your-vps clawctl board` works out of the box.
|
|
33
|
+
- **Race-safe.** Atomic claims and completions via single-UPDATE patterns with WHERE guards. No read-then-write races.
|
|
34
|
+
- **Auditable.** Every mutation hits an append-only activity log with optional JSON metadata for linking PRs, issues, test results.
|
|
35
|
+
- **OpenClaw-native.** Install as a skill, drop into any agent's workflow.
|
|
36
|
+
|
|
37
|
+
## Install
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pip install clawctl
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Or from source:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
git clone https://github.com/lludlow/clawctl.git
|
|
47
|
+
cd clawctl
|
|
48
|
+
pip install -e .
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**Requirements:** Python >= 3.9
|
|
52
|
+
|
|
53
|
+
## Quick start
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# Initialize
|
|
57
|
+
clawctl init
|
|
58
|
+
|
|
59
|
+
# Register the fleet
|
|
60
|
+
clawctl register chat --role "everyday triage & delegation"
|
|
61
|
+
clawctl register research --role "deep reasoning & web search"
|
|
62
|
+
clawctl register coding --role "sandboxed code execution"
|
|
63
|
+
clawctl register notes --role "knowledge graph & note-taking"
|
|
64
|
+
clawctl register trading --role "read-only market analysis"
|
|
65
|
+
clawctl register family --role "mention-gated secure responder"
|
|
66
|
+
clawctl register movie --role "watchlists & recommendations"
|
|
67
|
+
|
|
68
|
+
# Chat agent delegates work to specialists
|
|
69
|
+
CLAW_AGENT=chat clawctl add "Research best noise-cancelling headphones under $300" --for research
|
|
70
|
+
CLAW_AGENT=chat clawctl add "Write a Python script to rename photos by EXIF date" --for coding -p 1
|
|
71
|
+
CLAW_AGENT=chat clawctl add "File notes from the headphone research" --for notes
|
|
72
|
+
|
|
73
|
+
# Research agent picks up its task
|
|
74
|
+
CLAW_AGENT=research clawctl claim 1
|
|
75
|
+
CLAW_AGENT=research clawctl start 1
|
|
76
|
+
CLAW_AGENT=research clawctl done 1 -m "Top 3 picks with comparison table" \
|
|
77
|
+
--meta '{"note":"~/notes/headphone-research.md"}'
|
|
78
|
+
|
|
79
|
+
# Research hands off to notes for filing
|
|
80
|
+
CLAW_AGENT=research clawctl msg notes "Research complete, ready to file" --task 3
|
|
81
|
+
|
|
82
|
+
# Monitor
|
|
83
|
+
clawctl board
|
|
84
|
+
clawctl fleet
|
|
85
|
+
clawctl feed --last 10
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Agent integration
|
|
89
|
+
|
|
90
|
+
The typical agent loop:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# On startup — check messages, find work
|
|
94
|
+
CLAW_AGENT=coding clawctl checkin
|
|
95
|
+
CLAW_AGENT=coding clawctl inbox --unread
|
|
96
|
+
CLAW_AGENT=coding clawctl next
|
|
97
|
+
|
|
98
|
+
# Do the work, then close out
|
|
99
|
+
CLAW_AGENT=coding clawctl done <id> -m "Script written and tested" \
|
|
100
|
+
--meta '{"script":"~/scripts/rename-photos.py","tests":"passed"}'
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Add a heartbeat to each agent's cron:
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
*/10 * * * * CLAW_AGENT=chat clawctl checkin
|
|
107
|
+
*/10 * * * * CLAW_AGENT=research clawctl checkin
|
|
108
|
+
*/10 * * * * CLAW_AGENT=coding clawctl checkin
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Add to each agent's system prompt or AGENTS.md:
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
Before starting work: clawctl inbox --unread && clawctl list --mine
|
|
115
|
+
After completing work: clawctl done <id> -m "what I did"
|
|
116
|
+
Only claim tasks assigned to you or matching your role.
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
> If `CLAW_AGENT` is not set, clawctl falls back to `$USER` and prints a one-time warning on identity-sensitive commands.
|
|
120
|
+
|
|
121
|
+
## Commands
|
|
122
|
+
|
|
123
|
+
### Tasks
|
|
124
|
+
|
|
125
|
+
| Command | Description |
|
|
126
|
+
|---------|-------------|
|
|
127
|
+
| `add SUBJECT` | Create a task. Options: `-d` description, `-p 0\|1\|2` priority, `--for AGENT` pre-assign, `--parent ID` subtask |
|
|
128
|
+
| `list` | List active tasks. Options: `--mine`, `--status STATUS`, `--owner AGENT`, `--all` (include done/cancelled) |
|
|
129
|
+
| `next` | Show the highest-priority actionable task for the current agent |
|
|
130
|
+
| `claim ID` | Claim a task. Options: `--force` to override, `--meta JSON` |
|
|
131
|
+
| `start ID` | Begin work (transitions to in_progress). Options: `--meta JSON` |
|
|
132
|
+
| `done ID` | Complete a task. Options: `-m` note, `--force`, `--meta JSON` |
|
|
133
|
+
| `review ID` | Mark task as ready for review. Options: `--meta JSON` |
|
|
134
|
+
| `cancel ID` | Cancel a task. Options: `--meta JSON` |
|
|
135
|
+
| `block ID --by OTHER` | Mark task as blocked. Options: `--meta JSON` |
|
|
136
|
+
| `board` | Kanban board view grouped by status |
|
|
137
|
+
|
|
138
|
+
### Messages
|
|
139
|
+
|
|
140
|
+
| Command | Description |
|
|
141
|
+
|---------|-------------|
|
|
142
|
+
| `msg AGENT BODY` | Send a message. Options: `--task ID`, `--type TYPE` |
|
|
143
|
+
| `broadcast BODY` | Message all agents (type: alert) |
|
|
144
|
+
| `inbox` | Read messages. Options: `--unread` |
|
|
145
|
+
|
|
146
|
+
### Fleet
|
|
147
|
+
|
|
148
|
+
| Command | Description |
|
|
149
|
+
|---------|-------------|
|
|
150
|
+
| `register NAME` | Register an agent. Options: `--role TEXT` |
|
|
151
|
+
| `checkin` | Heartbeat — update presence, check for unread |
|
|
152
|
+
| `fleet` | Show all agents with status and current task |
|
|
153
|
+
| `whoami` | Show identity, role, and DB path |
|
|
154
|
+
|
|
155
|
+
### Monitoring
|
|
156
|
+
|
|
157
|
+
| Command | Description |
|
|
158
|
+
|---------|-------------|
|
|
159
|
+
| `feed` | Activity log. Options: `--last N`, `--agent NAME`, `--meta` |
|
|
160
|
+
| `summary` | Fleet overview with counts and recent events |
|
|
161
|
+
|
|
162
|
+
### Dashboard
|
|
163
|
+
|
|
164
|
+
| Command | Description |
|
|
165
|
+
|---------|-------------|
|
|
166
|
+
| `dashboard` | Start the web UI. Options: `--port INT` (default: 3737), `--verbose` |
|
|
167
|
+
| `dashboard --stop` | Stop the running dashboard |
|
|
168
|
+
|
|
169
|
+
## Task statuses
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
pending ─→ claimed ─→ in_progress ─→ done
|
|
173
|
+
↘ blocked ↗ ↘ cancelled
|
|
174
|
+
↘ review ↗
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
`list` excludes done/cancelled by default and sorts by status priority (in_progress > claimed > blocked > review > pending), oldest first. `--all` flips to newest-first for history browsing.
|
|
178
|
+
|
|
179
|
+
## Activity metadata
|
|
180
|
+
|
|
181
|
+
Mutating commands (`claim`, `start`, `done`, `block`) accept `--meta` with a JSON string stored in the activity log. Use it to link back to external artifacts:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
clawctl claim 1 --meta '{"source":"whatsapp","channel":"general"}'
|
|
185
|
+
clawctl done 1 -m "Top 3 picks with pros/cons" --meta '{"note":"~/notes/headphone-research.md"}'
|
|
186
|
+
|
|
187
|
+
# Review what happened overnight
|
|
188
|
+
clawctl feed --last 50 --agent research --meta
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Web dashboard
|
|
192
|
+
|
|
193
|
+
A live web UI served by Flask with token authentication and SSE for real-time updates.
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
clawctl dashboard
|
|
197
|
+
# Opens at http://localhost:3737/?token=<TOKEN>
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Features:
|
|
201
|
+
- Live board with SSE push updates (no polling)
|
|
202
|
+
- Task detail view with messages and metadata grid
|
|
203
|
+
- Complete and delete actions from the UI
|
|
204
|
+
- Terminal/hacker aesthetic with optional CRT effects
|
|
205
|
+
- Keyboard accessible (Esc to close, Tab trapping in modals)
|
|
206
|
+
- Works on narrow viewports
|
|
207
|
+
- Token persisted at `~/.openclaw/.clawctl-token` across restarts
|
|
208
|
+
|
|
209
|
+
The dashboard is read-mostly — it shares the same SQLite database the CLI writes to. The CLI is the primary interface; the dashboard is for monitoring.
|
|
210
|
+
|
|
211
|
+
## Architecture
|
|
212
|
+
|
|
213
|
+
```
|
|
214
|
+
┌─────────────────────────────┐
|
|
215
|
+
│ clawctl CLI (Python/Click) │ ← Every agent calls this
|
|
216
|
+
├─────────────────────────────┤
|
|
217
|
+
│ db.py — all SQL lives here │ ← Shared by CLI + Flask
|
|
218
|
+
├─────────────────────────────┤
|
|
219
|
+
│ SQLite (WAL mode) │ ← ~/.openclaw/clawctl.db
|
|
220
|
+
├─────────────────────────────┤
|
|
221
|
+
│ 5 tables + indexes: │
|
|
222
|
+
│ tasks task_deps │ ← Board + blocking graph
|
|
223
|
+
│ messages agents │ ← Comms + fleet registry
|
|
224
|
+
│ activity │ ← Append-only audit log
|
|
225
|
+
├─────────────────────────────┤
|
|
226
|
+
│ Flask dashboard (optional) │ ← dashboard/server.py
|
|
227
|
+
└─────────────────────────────┘
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
**Key design decisions:**
|
|
231
|
+
|
|
232
|
+
- **All SQL in `db.py`.** The CLI and Flask server import it. No queries in `cli.py` or `server.py`.
|
|
233
|
+
- **Race safety.** `claim_task()` and `complete_task()` use atomic single-UPDATE with WHERE guards and rowcount checks. No read-then-write.
|
|
234
|
+
- **Normalized blocking.** Dependencies live in the `task_deps` join table with a UNIQUE constraint. Not JSON columns.
|
|
235
|
+
- **Parameterized queries.** Every query uses `?` placeholders. No string interpolation.
|
|
236
|
+
- **Idempotent completions.** `done` on an already-done task is a safe no-op.
|
|
237
|
+
|
|
238
|
+
## Environment variables
|
|
239
|
+
|
|
240
|
+
| Variable | Default | Description |
|
|
241
|
+
|----------|---------|-------------|
|
|
242
|
+
| `CLAW_AGENT` | `$USER` (with warning) | Agent identity for all commands |
|
|
243
|
+
| `CLAW_DB` | `~/.openclaw/clawctl.db` | Database file path |
|
|
244
|
+
|
|
245
|
+
## License
|
|
246
|
+
|
|
247
|
+
MIT
|