claude-span-kit: Stretching Metered Claude Sessions
Why: Damien's Claude usage is metered in 5-hour blocks he burns through fast when actively working, while his weekly cap usually goes underused — so we built tooling to time-shift work across blocks instead of losing the afternoon to a reset timer.
Two tools, one portable kit at /home/plex/claude-span-kit/ (canonical copy; install.sh deploys it). Both are strictly on-demand — nothing recurring was added to cron.
1. warmclaude — session preheater
The 5-hour rate-limit clock starts at the first prompt of a block. warmclaude 4:30pm schedules a minimal Haiku ping (claude --model haiku -p ping, a few hundred tokens) 2 hours before the stated work-start time (-h N adjusts the lead, fractions OK; -n dry-run; -l lists pending pings), so the block's reset lands mid-session and a heavy work stretch can draw on two blocks' budget.
- I installed it to
~/.local/bin/warmclaude. Scheduling backend:atif present, else transientsystemd-run --usertimers (what this box uses —atis not installed). Pings log to~/.claude/warmclaude.log. - Gotcha (resolved): user linger was off, which would have killed scheduled pings on full logout. Damien warmed a sudo lease mid-session and I ran
sudo loginctl enable-linger plex— user timers now survive logout on this box. On a new machine,install.shdetects and flags this. - Live-tested end to end: timer created, fired, ping logged OK.
2. span-sessions — block-spanning long jobs
A Claude Code user skill at ~/.claude/skills/span-sessions/, invoked as /span-sessions at the start of a long unattended job. The session then: rewrites a durable checkpoint (.claude/CONTINUE.md, project-relative) at every milestone; runs the bundled scripts/budget.py to check context occupancy and block usage; and when the block nears exhaustion, parks and schedules in-session one-shot cron jobs (reset +10 min, backup +40 min) that auto-resume the work. The terminal must stay open — the resume jobs are in-memory, which is deliberate: the full transcript is reviewable on return.
budget.pyreads context occupancy from the newest session transcript'susageblock and block usage vianpx ccusage. It estimates the true reset time by anchoring to the block's first real message rather than ccusage's hour-floored start — validated within 3 minutes of the claude.ai usage page's countdown.- Knobs:
CLAUDE_CTX_LIMIT(default 200000),CLAUDE_BLOCK_LIMIT(default = largest completed historical block, a proxy for the unpublished plan limit).
3. Portability and open questions
Migration over LAN is rsync -a ~/claude-span-kit/ newbox:~/claude-span-kit/ && ./install.sh; deps are python3, npx, a logged-in claude CLI, GNU date, and at/systemd-run. The README documents the educated guesses we shipped rather than blocked on: reset-time rounding (covered by the +10/+40 double-shot resume), the block-limit proxy, and the assumption that headless pings trip the same account-wide clock as interactive use.
4. Public distribution over skyhouse.dev
Because the apex already serves /home/plex/www as static files, publishing needed no new DNS record and no new NPM proxy host — just a directory. The kit is now installable on any internet-connected machine (and shareable with colleagues) via:
curl -fsSL https://skyhouse.dev/span-kit/install.sh | bash~/claude-span-kit/publish.shrebuilds the tarball +SHA256SUMSinto/home/plex/www/span-kit/, copies the bootstrap fromweb/install.sh, and stamps version/date/checksum into the landing page. BumpVERSIONfirst. Theweb/dir andpublish.share deliberately excluded from the shipped tarball.- The bootstrap refuses to install on a checksum mismatch, moves any existing
~/claude-span-kitaside rather than deleting it, never uses sudo, and confines writes to~/claude-span-kit,~/.claude/skills/,~/.local/bin/. The landing page tells readers to inspect it before piping — the right advice for someone else's install script, including ours. - Unauthenticated and public (unlike
/serverjournal/, which is htpasswd-gated), but unlisted — nothing links to it from the homepage. It contains no credentials; that was checked before publishing. - Verified end to end: installed from the public URL into an isolated
HOMEand ran the result, and confirmed genuine off-LAN reachability by fetching the page from outside the network rather than trusting the local/etc/hostssplit-horizon mapping.
Net effect: long implementation jobs can now be told to span rate-limit blocks unattended, and work sessions can start with a pre-aged block — both on demand, nothing recurring.
← Back to Admin Hub