Keep AI provider subscription rate windows warm with tiny, state-gated pings β so your 5-hour Claude/OpenAI windows are already counting down before real work starts.
Three parts, smallest possible blast radius:
| Part | What it does | What it never does |
|---|---|---|
core/scan.sh |
Finds credentials in the usual places, reports sha256 fingerprints only | Print, move, or transmit a token |
core/pulse.sh |
One ~1β16 token ping per lane per interval (default 5h05m) | Retry-hammer, refresh credentials, run without a lanes file |
cli.mjs / plugin |
scan Β· dry-run Β· run Β· status |
Schedule itself; send pings from chat |
node cli.mjs scan --suggest # 1. find credentials (fingerprint report + commented lane suggestions)
$EDITOR lanes.conf # 2. review, dedupe by fingerprint, uncomment lanes DELIBERATELY
node cli.mjs dry-run # 3. verify every lane resolves its token (no pings)
node cli.mjs run # 4. one live pass
crontab -e # 5. */5 * * * * flock -n /tmp/mm-pulse.lock .../core/pulse.shThe per-lane state gate makes cron cadence irrelevant to ping volume β run it
every 5 minutes; each lane only fires when its last ping is β₯ PULSE_INTERVAL_SECONDS
(default 5h05m) old, capped at PULSE_DAILY_CAP (default 6) per day.
~/.claude/.credentials.json (Claude Code native login) Β· ~/.codex/auth.json
(Codex CLI) Β· ~/.openclaw/.env + gateway.systemd.env + PULSE_SCAN_ENV_FILES
(ANTHROPIC_/OPENAI_/CLAUDE_CODE_OAUTH_* vars) Β· OpenClaw per-agent sqlite auth
stores. Same fingerprint = same credential β don't ping it twice.
Legacy auth-profiles.json files are not scanned directly anymore because
current OpenClaw stores auth profiles in sqlite. Pulse can still use a real
legacy JSON file through an explicit claude-cmd / openai-cmd lane with
jq, but this box's old JSON path is a broken migration stub, not a live source.
claude-env <lane> <ENV_VAR> # claude -p, OAuth token from env var (source via PULSE_ENV_FILE)
claude-cmd <lane> <shell cmd> # claude -p, token from command stdout (e.g. sqlite/jq read)
claude-native <lane> # claude -p with NO override β CLI self-refreshes its own login
openai-env <lane> <ENV_VAR> # API-key health check, skipped unless PULSE_ALLOW_API_KEYS=1
openai-cmd <lane> <shell cmd> # API-key health check, skipped unless PULSE_ALLOW_API_KEYS=1
exec <lane> <shell cmd> # arbitrary ping command (rc 0 = OK)
Why claude-native matters: overriding with a token read from
.credentials.json 401s once the stored access token expires; running the CLI
natively lets it refresh itself.
Mac Keychain is not a first-class scan source in the VPS engine. If Pulse runs
on a Mac, prefer claude-native so Claude Code uses its own login/refresh path
(Keychain or otherwise). A Mac-only claude-cmd lane can also call security,
but the VPS cron cannot read another machine's Keychain unless you deliberately
bridge to that machine, which should be treated as a separate lane with its own
blast radius.
- Discovered β pinged. Scan suggestions are always commented out; a human uncomments lanes.
- Tokens never logged. Logs carry lane names, rcs, and truncated model output only.
- API-key lanes are opt-in. They prove key health but do not warm
subscription windows; set
PULSE_ALLOW_API_KEYS=1only when that small spend is deliberate. - Kill switch:
touch $PULSE_HOME/pulse.off. Dry-run before first live pass. - Failed/limited pings still stamp the lane β no retry hammering.
- One engine, one scheduler. Never run two engines against the same accounts (that's a double-ping β we learned this the hard way, 2026-07-03).
- Engine-of-record: this package β crontab
MOLTMASTER_PULSErunscore/pulse.shevery 5 min (flock-guarded), state in/root/.openclaw/moltmaster/pulse/, kill switchpulse.off. Cutover from the workspace prototype completed 2026-07-04; the legacy copies were removed. lanes.confis box-specific and git-ignored βlanes.conf.exampleis the shippable template.index.tsplugin registration is unproven until the next approved gateway restart; treat/pulseas reference design until then.
extensions/ (here, live use) β publish to ClawHub (openclaw plugins install clawhub:...)
β maybe upstream openclaw/openclaw extensions/ PR once proven.