Releases: moshcoder/moshcode
Release list
v0.36.0 — a herd you can click through
The herd gets a window you can actually work in.
A sidebar, not a modal list
moshcode herd ui is now a persistent workspace: members and actions down the left, the selected member's real terminal on the right.
┌ herd ──────┬─ api ─────────────────────────────┐
│ MAIN │ claude │
│ ▸ ! api │ Do you want to proceed? │
│ · work │ ❯ 1. Yes │
│ SCRATCH │ 2. No │
│ · logs │ │
│ ACTIONS │ │
│ + shell │ │
│ + agent │ │
│ ✕ stop │ │
│ ← detach │ │
└────────────┴───────────────────────────────────┘
Click a member to show it. Click an action to start a shell, start an agent, stop the selected one, tile everything, or detach.
The right-hand pane is not a picture of a session — it is the session's pane, moved in with join-pane. No polling, no re-render, no lost cursor, and the agent's own mouse handling still belongs to the agent.
The old modal list lives on as the automatic fallback where there's no tmux to swap panes on.
Tile everything
moshcode herd tile puts every member in one tiled window with start/stop bound in place; herd untile sends each one back to its own session, still running.
Install
curl -fsSL https://raw.githubusercontent.com/moshcoder/moshcode/main/install.sh | bash
or npm i -g moshcode@0.36.0
v0.35.0 — a clickable herd
What's Changed
- feat(herd): a clickable list of herds and their members by @ralyodio in #349
- chore(release): v0.35.0 by @ralyodio in #350
Full Changelog: v0.34.0...v0.35.0
v0.34.0 — shells in the herd
What's Changed
- feat(herd): shells and unknown agents in the herd, and help that opens with the use case by @ralyodio in #347
- chore(release): v0.34.0 by @ralyodio in #348
Full Changelog: v0.33.1...v0.34.0
v0.33.1 — find the switcher
What's Changed
- docs(herd): the session switcher you already have but could not find by @ralyodio in #345
- chore(release): v0.33.1 by @ralyodio in #346
Full Changelog: v0.33.0...v0.33.1
v0.33.0 — sessions that outlive your terminal
Sessions that outlive your terminal, and Moshpit names that a stock client will finally accept.
herd — the pit stops being a one-thing-at-a-time shell
moshcode start claude -d # runs detached, hands the prompt straight back/ps shows what is running and what state each session is in, /attach steps into one, and detaching leaves it running.
Two substrates behind one interface, because "requires tmux" was the wart worth removing rather than documenting:
| tmux | a single named server (socket moshcode). Full fidelity — resizing, scrollback, native attach. |
| pty | no tmux: script(1) allocates the pty and the child is detached with its stdin on a FIFO held O_RDWR, so it never sees EOF when the pit exits. Attach replays the transcript and relays keystrokes. |
| none | foreground passthrough, exactly as before — said once rather than implied. |
Sessions carry semantic state — working / blocked / done / idle / unknown — under one rule: each session has exactly one authority. A live hook report suppresses screen classification entirely, and expires, so a crashed agent cannot read working forever. Screen rules ship beside each engine's install spec, are anchored to what a terminal actually draws rather than to English words, and are overridable in ~/.moshcode/herd/rules.json when they rot.
A blocked session can page you through the existing notify/ask fan-out, with your reply typed back into the session that was waiting. Only transitions notify, so a session sitting blocked does not page every five seconds.
One surface for humans and agents: every verb takes --json, wait exits 0/2/3 so scripts can branch, and moshscript gets herdStart / herdPrompt / herdWait / herdRead / herdList / herdKill as values rather than exit codes.
Moshpit names now verify in curl, without flags
Two independent reasons they did not.
dns enable never turned proxy mode on. Everything else existed — moshpit-proxy checks an origin against the registry pin and re-signs with a root this machine generated, dns enable installs that root, and the resolver knew how to point names at it. Nothing ever connected them, so names resolved straight to their origin and a stock client got a certificate no CA had signed. Trust was being installed for a proxy that was never on the path. dns enable now probes for the proxy and starts the bridge in proxy mode when it finds one; --no-proxy opts out.
The probe is a TLS handshake, not a connect, and that distinction is the whole safety of it. "Is something listening on 443" is answered yes by the nginx on any origin box — and proxy mode would then point every live Moshpit name on the machine at a web server that has never heard of them. So the probe completes a handshake and checks who issued the certificate. Nothing is trusted in the process: the peer certificate is read, not verified, and only the issuer name is taken from it. Every uncertain case refuses, because proxy mode with nothing behind it resolves every name and then refuses every connection — which looks like the sites are down while dig stays healthy.
dns trust would install a certificate authority as a trust anchor. It installed whatever the socket served, given a matching registry pin. But a pin proves the registry vouches for that key; it says nothing about whether trusting it is bounded. A certificate marked CA:TRUE may issue for any name — its SAN describes what it speaks for, not what it may sign — so trusting one to reach seo.rank also handed its holder google.com. It went unnoticed because openssl's req -x509 defaults to CA:TRUE, which made every origin serve exactly the shape that must be refused, indistinguishable from a correct one until someone trusted it.
Now refused, with the remedy printed rather than a dead end — re-issuing from the same key leaves the published pin untouched, so the fix costs no registry change and breaks no client holding the old pin.
Pairs with profullstack/moshpit-proxy#18 and #19, which fix what origins issue and make an already-deployed box repair itself.
Upgrading
moshcode upgradev0.32.0 — coupons, conducted
New workflow tool: c0upons. Coupon search, submissions, and bounties, conducted from the pit.
moshcode install c0upons
moshcode c0upons search nike
moshcode c0upons latestIn the TUI: /c0upons [args…]. In moshscript: c0upons(...args).
Conducted, not wrapped
c0upons joins ugig, coinpay, and c0mpute as a workflow CLI moshcode conducts — arguments and output go straight through to the native command line, untouched. moshcode owns installing it and keeping it current; c0upons owns what it does.
$ moshcode tools
● c0upons c0upons — community coupon search, submissions, and bounties
moshcode upgrade carries it
No separate step to remember — an installed c0upons is picked up by moshcode upgrade, moshcode upgrade tools, and moshcode upgrade c0upons alike.
It is the first workflow tool whose updater is its own binary rather than a re-run of its installer. c0upons upgrade resolves its own path with command -v and replaces itself in place, so it moves the version wherever the installer originally put it — the opencode case rather than the privacycode one, where a vendor updater can't find our install and aborts every time.
| how it upgrades | |
|---|---|
ugig coinpay c0mpute |
re-run the vendor install script |
c0upons |
c0upons upgrade — replaces its own binary |
Nothing else moved
Additive, so a minor. No plugin bumps: the change is CLI-side only, and no plugin names a command that moved.
v0.31.0 — report, and list
Breaking, in the plugins. /stocks:reports is now /stocks:list.
If you have the stocks plugin installed
claude plugin update stocks@moshcode
claude plugin update crypto@moshcodeThen restart the engine.
| was | now |
|---|---|
/stocks:reports |
/stocks:list |
Why
v0.30.0 renamed /stocks:stocks to /stocks:report — which fixed a stutter and immediately created a worse problem, by putting report and reports next to each other. One letter apart, and nothing at the prompt distinguishes them: singular takes a symbol and writes one report, plural takes none and lists everything covered. That's a coin-flip every time you type it.
list rather than index, which was the other candidate and the word the docs already used in prose: in a plugin about equities, /stocks:index reads as a market index, and someone would reasonably expect S&P 500 data from it. list can't be misread that way.
The CLI didn't change
moshcode stocks list has been an alias for reports since the verb existed. So this makes the plugin agree with the CLI rather than diverge from it — moshcode stocks list and /stocks:list are now the same words for the same thing.
Current command sets
stocks@moshcode |
crypto@moshcode |
|
|---|---|---|
| shared | help report quote lookup |
help report quote lookup |
| its own | signals research list discover |
book bars spark pairs |
Both plugins go to 0.4.0. crypto is bumped too because its /crypto:help names the stocks command set — without it, an existing install would keep printing a command that no longer exists.
v0.30.0 — one vocabulary
Breaking, in the plugins. Three commands were renamed, and both plugins gained a /help.
If you have either plugin installed
claude plugin update stocks@moshcode
claude plugin update crypto@moshcodeThen restart the engine. Until you do, your install keeps the old names — a moshcode upgrade does not carry plugin changes.
| was | now |
|---|---|
/stocks:stocks NVDA |
/stocks:report NVDA |
/crypto:crypto BTC |
/crypto:report BTC |
/crypto:coin bitcoin |
/crypto:lookup bitcoin |
One vocabulary across both
The two plugins had grown separate words for the same question — stocks and crypto for "the full report", coin and lookup for "name → symbol". Knowing one taught you nothing about the other. And the headline command in each was named after its own plugin, which is what produced the /crypto:crypto stutter.
They can't ship the same set — a crypto pair has no earnings transcript, an equity has no order book — but they can share vocabulary, and now do:
stocks@moshcode |
crypto@moshcode |
|
|---|---|---|
| shared | help report quote lookup |
help report quote lookup |
| its own | signals research reports discover |
book bars spark pairs |
Eight each, four spelled identically. /stocks:report NVDA and /crypto:report BTC are the same question asked of different markets.
New
/stocks:help, /crypto:help — each lists its own plugin's commands, no tool call needed. "Command not found" now has a signpost.
/stocks:quote NVDA — the four-line read: price, score, and how stale the snapshot is. It exists because moshcode stocks quote already worked in the CLI, so the plugin was the one surface where the word didn't — which is how it got found.
Guards
Two tests now hold the shape: every plugin must ship each shared name, and no command may repeat its own plugin's name — the rule /crypto:crypto would have failed.
Nothing in the moshcode CLI changed. moshcode stocks and moshcode crypto keep every verb and alias they had.
v0.29.3 — updates that reach you
A patch release. The moshcode half changes nothing you can see; the part that matters is in the plugins.
Both plugins are now 0.2.0
Claude Code only pulls a new copy of a plugin when the plugin's own version moves:
"If set, users only receive updates when you bump this field."
Both plugins had declared 0.1.0 since the day they were created — through every change since, including v0.29.2, which rewrote every command file to carry the namespaced /stocks:… and /crypto:… names. Existing installs kept serving the old copy, so the surface people were told to use was not the surface they had.
Both now declare 0.2.0, which makes those edits reachable:
claude plugin update stocks@moshcode
claude plugin update crypto@moshcodeRestart the engine afterwards. If you installed either plugin for the first time today, you already have the current content and this changes nothing for you.
moshcode upgrade does not do this. It updates the CLI and leaves installed plugins exactly where they were — which was not obvious anywhere, and is now in the README.
Stopping it happening again
The plugin version joins the catalog in src/plugins.mjs, right beside the command list an editor is already touching when they change a plugin, with the update mechanism spelled out above it. A test pins the catalog to the manifest that ships, and it was checked to fail when the two disagree rather than merely passing today.
v0.29.2 — commands you can actually type
A patch release: one documentation fix, and one rendering fix.
Plugin commands are namespaced, and now say so (#331)
Every plugin command was advertised bare — /crypto, /stocks, /signals — and none of those exist. Claude Code namespaces plugin commands as /<plugin>:<command> always, not only when two plugins collide, so the first thing anyone tried after installing was:
$ /crypto BTC
Unknown command: /crypto
The real names:
| plugin | commands |
|---|---|
stocks@moshcode |
/stocks:stocks /stocks:signals /stocks:research /stocks:lookup /stocks:reports /stocks:discover |
crypto@moshcode |
/crypto:crypto /crypto:quote /crypto:book /crypto:bars /crypto:spark /crypto:pairs /crypto:coin |
Typing / and picking from the menu inserts the right form for you.
Fixed in the catalog, both plugin READMEs, the main README, and the cross-references inside the command files themselves — those tell the model which command to offer next, so a bare name there sent you to the same dead end one step later.
Nothing inside the moshcode pit changed. There, the same research really is plain /stocks … and /crypto …, because those are moshcode's own commands rather than a plugin's. Having both spellings in one project is the genuinely confusing part, so the READMEs now call it out.
Also fixed: the invitation printed after installing appended a hardcoded NVDA to whatever came first in the command list — telling anyone who installed the crypto plugin to go try a stock. Each plugin now carries its own runnable example (/crypto:crypto BTC), and a test asserts it invokes a command that plugin actually ships.
Why it survived two releases: the drift test compared the advertised commands against bare filenames, so /crypto "matched" crypto.md and stayed green — nothing checked the name against how the file is actually invoked. It now derives the namespaced form.
A down move no longer reads as "$-186.36" (#330)
moshcode crypto <PAIR> signed the change by letting the price formatter carry the minus, which put it after the currency mark. An up move read +$186.36 and a down move read $-186.36 — the same quantity rendered two different shapes depending on direction. The sign now leads in both cases, the way the percentage already did.
Thanks to @clawedassistant26 for catching it. It has been wrong since /crypto shipped in v0.27.0.