The other question you have with six agents running
moshcode ps answers "which one is blocked". It has never answered "what is
this costing me", and with a herd running overnight that is the question you
wake up to.
session engine model in out cache cost age
api claude claude-opus-5 1.2k 27k 10.5M $9.91~ 42m
audit codex gpt-5.6-sol 400 200 600 — 12m
total $9.91~ 1.6k in · 27k out · 10.5M cached
~ estimated from published rates; unmarked figures are the engine's own.
⚠ no rate for gpt-5.6-sol — tokens counted, cost omitted.
Nothing is instrumented, wrapped or proxied to produce that. Every engine
already writes down what it used, because it needs the numbers itself — Claude
Code keeps a per-message usage block in ~/.claude/projects/**/*.jsonl, Codex
emits cumulative token_count events into ~/.codex/sessions/…, opencode and
privacycode store a cost they computed themselves in SQLite, and aider prints
a running session total into .aider.chat.history.md beside the code. This
reads what is on disk and lines it up against the herd.
moshcode cost # per session, last 24h
moshcode cost api # one session, with its engine runs
moshcode cost --all --since 7d # every engine session on the box, herd or not
moshcode cost --watch # re-read every 10s — the slope is the point
moshcode cost --json # for a scriptAlso moshcode herd cost, /cost in the pit, and cost() in moshscript.
--all needs no herd at all, so a foreground moshcode agents claude is
covered the same way.
A ~ is an estimate and an unmarked figure is not
opencode and aider price their own messages, and that price is reported
untouched — they know which model actually served the request. Claude Code and
Codex record tokens and nothing else, which is the honest state of things on a
subscription where the marginal request costs nothing extra, so those get
multiplied by a rate card and marked. The mark is the whole point: one of those
numbers is a measurement and the other is "what this would have cost on the
API". --json carries it as costSource.
A model nobody has priced shows its tokens and no cost, rather than a
convincing-looking $0. Only Anthropic rates ship, because a Codex or Kimi
model id (gpt-5.6-sol is what a rollout actually records) does not appear on
any public price list and inventing one would be worse than a blank. Your own
rates go in ~/.moshcode/pricing.json and win over the shipped table:
{ "gpt-5.6-sol": { "input": 1.25, "output": 10 } }Cache tokens get a column of their own for the same reason. On a long agent
session they are most of the traffic and a tenth of the price — fold them into
in and a $3 session reads like a $60 one, which is the opposite of the point.
Attribution is engine + directory + "started before this run did". That is right
for the ordinary case of one agent per directory and can be wrong when two
sessions of the same engine share one, so --json carries the raw run list
rather than implying an answer, and a run that matches no session is its own
line instead of being absorbed into a neighbour's total. gemini, kimi, qwen,
deepseek and openagents keep no readable usage log, so they report no cost —
which is not the same as zero cost, and the report says so.
A name can publish, not just point
target proxies a name at a web server its owner already runs. That is the
right primitive and the wrong first step: most people who claim a name have
something to publish and nowhere to publish it from, so the commonest thing in
the registry was a name that never became a site.
A name can now carry a feed — paste an RSS or Atom URL next to any name you
hold and /n/<name> renders it, as a blog with dates and excerpts or as a
podcast with cover art, running times and a player. The layout is inferred from
whether the entries carry audio enclosures, and can be overridden when the guess
is wrong.
The other half is somewhere to put writing that does not exist anywhere yet:
POST /api/moshpit/sites/blue.eggs/content
{"kind":"link","title":"Worth reading","url":"https://example.com/post"}
Eight kinds — section and page for navigation, then text, link, image, gallery,
video and embed — which is the set a link aggregator has because it is the set
people actually post. It upserts on the slug, because the caller is a webhook
and anything firing over HTTP retries: a publish endpoint that makes a second
copy on every redelivery is one you cannot point automation at.
And GET /api/moshpit/log finally exposes the allocation record. "The directory
can be mirrored and served by anyone" was true of the schema and false of the
product, because nothing could read the log; now a second copy of the registry
is something a stranger can build.
moshscript catches up with the CLI
The vocabulary had drifted to 43 verbs against 54 commands, with no way for a
script to authenticate, reach the pit's aliases, or read a tool's output as
anything but an exit code. Account verbs (login, whoami, requireLogin,
logout) close that, with identity() in src/auth.mjs as the one place that
decides what "logged in" means so the CLI and a script can never disagree.
The paddle is on the game's clock
Pong and breakout tick at 60Hz and move the ball on that clock; the paddle — the
one object you are actually steering — was still being moved by the keypress
itself, one jump per key. A terminal has no key-up, only auto-repeat, so that is
two problems and neither of them is "the paddle is slow". Both paddles now run
on the same clock as everything else on the board.
Housekeeping
The ThreatCrush pack moves to 1.7.0, replacing a local scoping fix, and its PR
comment is scoped to the files a PR actually changes.