Replace the footer's placeholder usage with a real observation ledger
The footer showed invented percentages. It now shows what two harnesses actually report, or says it does not know. lumbridge-core gains an append-only per-profile UsageLedger and a projection that labels every derived value estimated, withholds a burn rate from a single sample, withholds a window fraction with no reported ceiling, withholds an exhaustion estimate that lands after the reset, and reports an expired window as rolled over rather than freezing its last percentage. A missing fact renders as missing, never as zero. (0012) lumbridge-harness is the impure side: processes, clocks, and untrusted wire text in, observations out. Three adapters: - Codex's account/rateLimits/read over the app-server's JSON-RPC stdio. The client cannot express a request outside a two-variant enum and answers every server-to-client request with -32601, so a harness asking Lumbridge for a credential is refused by construction. (0013) - Claude Code's session transcripts, as a byte-offset tail follower that reports nothing until the backlog is read to EOF — a partially-read backlog is indistinguishable from a burst of spend, and the first run against 20 MB reported forty-six billion tokens an hour. The parser models four counters, so the conversations in those files are not representable. (0014) - Claude Code's five-hour and seven-day subscription windows, via a bridge installed as its statusLine command. 0014 had claimed no such surface existed; it does, and the record is corrected in place rather than quietly edited. Lumbridge does not read the OAuth credential to call the account usage endpoint, which is what comparable tools do — AGENTS.md forbids it, and 0015 says so rather than leaving the gap unexplained. Also in here: a capability-check ordering fix in the workspace reducer, where the applied-request replay table was consulted before the capability check and so answered questions the caller had no right to ask; the GPUI spike wired to the live probes with per-harness gauges and provenance chips; and a launcher that matches its own window by PID, because GPUI sets WM_NAME but not _NET_WM_NAME and a title match never succeeded. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
7fe84f71e2
commit
ef52aa7ce2
@@ -0,0 +1,108 @@
|
||||
"""Extract Claude Code's rate-limit windows from a status-line payload.
|
||||
|
||||
Invoked by `claude-statusline-bridge.sh` with the feed path as argv[1] and the
|
||||
status-line JSON on stdin. Appends only the rate-limit fields to the feed and
|
||||
prints a status line.
|
||||
|
||||
Must never fail: a status-line command that errors degrades the user's Claude
|
||||
Code session, so every step is guarded and this always exits 0 having printed.
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
# Keep the feed bounded. The probe only needs the newest line; older ones are
|
||||
# superseded snapshots, not history worth keeping.
|
||||
MAX_FEED_BYTES = 256 * 1024
|
||||
WINDOW_NAMES = ("five_hour", "seven_day")
|
||||
PERCENT_KEYS = ("used_percentage", "utilization", "resets_at")
|
||||
|
||||
|
||||
def extract(payload):
|
||||
"""Return the record to append: rate-limit fields and nothing else.
|
||||
|
||||
The payload also carries the session's cost, transcript path, working
|
||||
directory, and model. None of that is Lumbridge's business, and none of it
|
||||
is copied — this builds a fresh dict rather than filtering the original.
|
||||
"""
|
||||
record = {"rate_limits_available": payload.get("rate_limits_available")}
|
||||
limits = payload.get("rate_limits")
|
||||
if not isinstance(limits, dict):
|
||||
return record
|
||||
windows = {}
|
||||
for name in WINDOW_NAMES:
|
||||
window = limits.get(name)
|
||||
if not isinstance(window, dict):
|
||||
continue
|
||||
kept = {
|
||||
key: window[key]
|
||||
for key in PERCENT_KEYS
|
||||
if isinstance(window.get(key), (int, float))
|
||||
and not isinstance(window.get(key), bool)
|
||||
}
|
||||
if kept:
|
||||
windows[name] = kept
|
||||
if windows:
|
||||
record["rate_limits"] = windows
|
||||
return record
|
||||
|
||||
|
||||
def status_line(record):
|
||||
if record.get("rate_limits_available") is False:
|
||||
return "lumbridge · no plan limits on this account"
|
||||
windows = record.get("rate_limits")
|
||||
if not windows:
|
||||
return "lumbridge · no window reported yet"
|
||||
parts = []
|
||||
for name, label in (("five_hour", "5h"), ("seven_day", "7d")):
|
||||
window = windows.get(name)
|
||||
if not window:
|
||||
continue
|
||||
percent = window.get("used_percentage", window.get("utilization"))
|
||||
if percent is None:
|
||||
continue
|
||||
parts.append(f"{label} {max(0.0, 100.0 - float(percent)):.0f}% left")
|
||||
if not parts:
|
||||
return "lumbridge · no window reported yet"
|
||||
return "lumbridge · " + " · ".join(parts)
|
||||
|
||||
|
||||
def append(feed, record):
|
||||
if not feed:
|
||||
return
|
||||
try:
|
||||
# Rotate rather than grow without bound. The probe resets its read
|
||||
# offset when the file shrinks, so a rotation costs one reading.
|
||||
if os.path.exists(feed) and os.path.getsize(feed) > MAX_FEED_BYTES:
|
||||
open(feed, "w").close()
|
||||
# Append so concurrent Claude Code sessions do not clobber each other;
|
||||
# a short line written in append mode lands intact.
|
||||
with open(feed, "a") as handle:
|
||||
handle.write(json.dumps(record, separators=(",", ":")) + "\n")
|
||||
except Exception:
|
||||
pass # A feed we cannot write is not worth breaking a session over.
|
||||
|
||||
|
||||
def main():
|
||||
feed = sys.argv[1] if len(sys.argv) > 1 else ""
|
||||
try:
|
||||
payload = json.load(sys.stdin)
|
||||
except Exception:
|
||||
print("lumbridge · unreadable status payload")
|
||||
return 0
|
||||
if not isinstance(payload, dict):
|
||||
print("lumbridge · unreadable status payload")
|
||||
return 0
|
||||
record = extract(payload)
|
||||
append(feed, record)
|
||||
print(status_line(record))
|
||||
return 0
|
||||
|
||||
|
||||
try:
|
||||
sys.exit(main())
|
||||
except Exception:
|
||||
# Last resort: never let a status line take a session down.
|
||||
print("lumbridge")
|
||||
sys.exit(0)
|
||||
Reference in New Issue
Block a user