CClawMetryDocs

Configuration

Run it as a service#

clawmetry onboard sets up supervision for you. This page is for when you manage processes yourself.

What needs to run#

ProcessRequiredCommand
The sync daemonYespython -m clawmetry.sync
The dashboardFor the UIclawmetry --port 8900
The proxyOptionalclawmetry proxy start --foreground

The daemon is the one that matters. Without it the dashboard shows nothing.

Connecting without installing supervision#

bash
clawmetry connect --key cm_xxx --no-daemon

That writes the configuration and leaves the process to you.

systemd#

~/.config/systemd/user/clawmetry-sync.service
[Unit]
Description=ClawMetry sync daemon
After=network-online.target

[Service]
Type=simple
ExecStart=/usr/bin/python3 -m clawmetry.sync
Restart=always
RestartSec=10
Environment=CLAWMETRY_HOME=%h/.clawmetry

[Install]
WantedBy=default.target
~/.config/systemd/user/clawmetry-dashboard.service
[Unit]
Description=ClawMetry dashboard
After=clawmetry-sync.service

[Service]
Type=simple
ExecStart=/usr/local/bin/clawmetry --port 8900 --no-debug
Restart=always
RestartSec=10

[Install]
WantedBy=default.target
bash
systemctl --user daemon-reload
systemctl --user enable --now clawmetry-sync clawmetry-dashboard
systemctl --user status clawmetry-sync
loginctl enable-linger "$USER"     # survive logout

launchd (macOS)#

~/Library/LaunchAgents/com.clawmetry.sync.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key><string>com.clawmetry.sync</string>
  <key>ProgramArguments</key>
  <array>
    <string>/usr/bin/python3</string>
    <string>-m</string>
    <string>clawmetry.sync</string>
  </array>
  <key>RunAtLoad</key><true/>
  <key>KeepAlive</key><true/>
  <key>WorkingDirectory</key><string>/Users/YOU</string>
  <key>StandardErrorPath</key><string>/tmp/clawmetry-sync.err</string>
</dict>
</plist>
bash
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.clawmetry.sync.plist
launchctl kickstart -k gui/$(id -u)/com.clawmetry.sync   # restart after an edit

Set a working directory

A launchd job with no WorkingDirectory runs with cwd=/, and code that resolves a relative path will fail in ways that look like a permissions problem. Set it explicitly.

Also note: after editing a plist you must bootout and bootstrap again, or kickstart -k. Reloading alone does not pick up changes.

supervisord#

/etc/supervisor/conf.d/clawmetry.conf
[program:clawmetry-sync]
command=/usr/bin/python3 -m clawmetry.sync
directory=/home/agent
user=agent
autostart=true
autorestart=true
startsecs=10
stderr_logfile=/var/log/clawmetry-sync.err.log

[program:clawmetry-dashboard]
command=/usr/local/bin/clawmetry --port 8900 --no-debug
directory=/home/agent
user=agent
autostart=true
autorestart=true
bash
supervisorctl reread && supervisorctl update
supervisorctl status clawmetry-sync

Containers#

Run the daemon as the container's main process and the dashboard alongside it, or in a second container sharing the state volume.

Docker

Restarting safely#

bash
clawmetry sync --restart

This bounces the supervised service cleanly rather than sending a kill signal, so the daemon closes its DuckDB handle properly. An abrupt kill mid-write is how a store ends up needing recovery.

Which Python#

A common surprise on a machine with several interpreters: the daemon runs under whichever Python the service file names, which may not be the one your shell resolves. If a version bump does not seem to take effect, check what the service is actually executing.

bash
systemctl --user show clawmetry-sync -p ExecStart
ps -o command= -p "$(pgrep -f clawmetry.sync | head -1)"

Verifying#

bash
clawmetry status
curl -s localhost:8900/healthz

A monitoring check that means something:

bash
clawmetry status --json | jq -e '.daemon.running' >/dev/null
Cookie preferences