moshcode
v0.107.0
Published
moshcode — a metal wrapper for coding engines and native UGig/CoinPay workflow CLIs, with OpenPRD and moshscript
Readme
moshcode 🤘
A metal wrapper CLI for agentic coding. moshcode doesn't reinvent the agent — it installs and drives existing ones (opencode, Claude Code, codex) and adds a tiny scripting toolkit (moshscript) on top. It also conducts adjacent native workflow tools for finding work and getting paid.
Install
curl -fsSL https://moshcoding.com/install.sh | shZero-dependency ESM — all it needs is Node.js 18+. Later: … | sh -s -- update
to upgrade, … | sh -s -- remove to uninstall.
Commands
moshcode help <command> drills into any of these — flags, examples and all.
moshcode help --json is the same thing for a machine.
This table is generated from the command table the CLI itself dispatches from
(moshcode help --markdown), so it cannot describe a verb that does not exist
or miss one that does. A test fails the build when it drifts.
| command | group | what it does |
|---|---|---|
| moshcode agents | engines | list engines, open their agent view, or launch autonomously |
| moshcode start | engines | launch an engine with its native defaults |
| moshcode herd | runtime | run agent sessions that outlive this terminal |
| moshcode swarm | runtime | one task, a herd of agents, one answer — plan, fan out, verify, synthesise (PRD 0015) |
| moshcode omarchy | runtime | the herd on the Omarchy bar: the snapshot a QML widget polls, and the plugin around it (PRD 0017) |
| moshcode fleet | runtime | the OpenFleet sysop tool: open a fleet, cap it, see the tree, stop a swarm, read the ledger (PRD 0016) |
| moshcode handoff | runtime | move a conversation from one engine to another, with its history (PRD 0018) |
| moshcode ps | runtime | list herd sessions and what each one is doing |
| moshcode cost usage | runtime | what each session is spending, read from the engines' own logs |
| moshcode attach | runtime | attach this terminal to a herd session |
| moshcode kill | runtime | end a herd session |
| moshcode wait | runtime | block until a session is blocked, done, or idle |
| moshcode restore | runtime | rebuild the herd's sessions after a reboot |
| moshcode ssh | runtime | persistent SSH workspaces — one connection, many clean commands |
| moshcode install | engines | install an engine or workflow tool |
| moshcode uninstall remove | engines | take an engine or workflow tool off this machine |
| moshcode upgrade update | engines | update moshcode, engines, or tools |
| moshcode mcp | extend | register and inspect MCP servers |
| moshcode skill skills | extend | install and inspect agent skills |
| moshcode prd | script | publish or list product requirement documents |
| moshcode login | account | authenticate with app.moshcode.sh |
| moshcode whoami | account | show the logged-in account |
| moshcode logout | account | clear the logged-in account |
| moshcode save | account | save this machine's pit settings to your account |
| moshcode load | account | bring your saved pit settings onto this machine |
| moshcode export | account | operator only: export the app's users as CSV, optionally cleaned |
| moshcode console | account | serve or connect to the browser terminal |
| moshcode dns | hosting | resolve Moshpit names on this machine |
| moshcode name | hosting | prove you hold a Moshpit name, so an app can use it as your identity |
| moshcode doh | hosting | run the DNS-over-HTTPS resolver |
| moshcode site serve | hosting | install web-server config for a Moshpit name |
| moshcode template templates | hosting | scaffold a stack for a Moshpit-hosted service |
| moshcode shorten short link | hosting | mint a short link on the pit — /f/ follows to your url |
| moshcode games game arcade | arcade | the moshcode arcade — twenty-two games, no menus |
| moshcode pwd where | system | show the current directory and git context |
| moshcode engines | engines | list engines and installation status, or apply an engine's settings defaults |
| moshcode tools | tools | list workflow tools and installation status |
| moshcode trade | tools | look up markets and trade through Alpaca |
| moshcode stocks advisor | tools | equity research from advis0r.com |
| moshcode crypto coins | tools | crypto market data from advis0r.com |
| moshcode news | tools | headlines from your feeds, or a search |
| moshcode rss | tools | read the same headlines in a full-screen reader |
| moshcode timer | business | track time — on, off, and what it added up to |
| moshcode client business merchant customer | business | who the work is for — clients, businesses, merchants |
| moshcode team teams | business | who may do what on this machine |
| moshcode rate rates | business | what an hour of agent time costs |
| moshcode billing invoice | business | turn tracked time into an invoice |
| moshcode payments | business | the rail invoices go out on |
| moshcode plugin plugins | extend | install moshcode's slash commands into Claude Code |
| moshcode commands | script | list built-in moshscript commands |
| moshcode completion | extend | print a shell completion script |
| moshcode run | script | run a moshscript |
| moshcode help --help -h | system | show command help |
| moshcode version --version -v | system | show the installed version |
Engines
moshcode engines # list installable engines
moshcode engines --json # machine-readable install status for automation
moshcode install opencode # install opencode (curl … | bash)
moshcode install privacycode # curl -fsSL https://getprivacycode.com/install | sh
moshcode install claude # npm i -g @anthropic-ai/claude-code
moshcode install codex # npm i -g @openai/codex
moshcode install kimi # curl -fsSL https://code.kimi.com/kimi-code/install.sh | bash
moshcode install qwen # npm i -g @qwen-code/qwen-code
moshcode install deepseek # npm i -g @serjm/deepseek-code
moshcode install mimocode # curl -fsSL https://mimo.xiaomi.com/install | bash (binary: mimo)
moshcode install omp # curl -fsSL https://omp.sh/install | sh
moshcode install openagents # curl -fsSL https://openagents.org/install.sh | bashopenagents is the odd one out: a launcher that supervises the engines above
rather than a coding agent itself. Its installer ends by offering to pair the
machine with a workspace — press Enter to skip that.
Autonomous agents versus raw starts
agents opens the engine's native agent view when it has one, so you land on
your agent list. Engines without an agents view instead start an autonomous
session by injecting the engine's native bypass or auto-approval mode. Either way,
use this only in an isolated container, VM, or workspace you trust:
moshcode agents claude # claude agents --dangerously-skip-permissions (agent view)
moshcode agents opencode # opencode --auto (autonomous)
moshcode agents privacycode # privacycode --auto (autonomous)
moshcode agents codex # codex --dangerously-bypass-approvals-and-sandbox agents (agent view)
moshcode agents gemini # gemini --approval-mode=yolo (autonomous)
moshcode agents kimi # kimi --yolo (autonomous)
moshcode agents qwen # qwen --approval-mode=yolo (autonomous)
moshcode agents deepseek # deepseek-code --turbo (autonomous)
moshcode agents mimocode # mimo --dangerously-skip-permissions --trust (autonomous)
moshcode agents omp # omp --auto-approve (autonomous)
moshcode agents aider # aider --yes-always (autonomous)
moshcode agents openagents # openagents (dashboard)Codex's native agents overview requires a CLI with codex agents support
(verified with 0.151.0) and, for the local daemon, the managed standalone
installation. moshcode install codex / moshcode upgrade codex use Codex's
official standalone installer on macOS/Linux; an npm-only install is not enough.
Existing npm installations are preserved. Windows retains npm and requires
--remote <server> for the agents overview.
/agents codex opens the same live overview of sessions on Codex's shared local
app-server daemon. The approval/sandbox bypass is passed for this invocation;
moshcode does not rewrite your global Codex settings or stop existing sessions.
Additional arguments are forwarded to the native agents subcommand, for example
moshcode agents codex --no-alt-screen.
For separate conversations, Codex's /new starts a fresh chat in the same CLI,
/resume reopens a saved chat, and /fork branches a conversation while preserving
the original. These commands are distinct from launching parallel subagents:
ask Codex to delegate work, then use its /agent or /subagents picker to switch
threads. See the Codex command reference
and subagent guide.
start is the explicit raw path. It injects nothing, so the native engine keeps
its normal permission model and receives only your arguments:
moshcode start claude
moshcode start codex --sandbox workspace-writeBare engine commands remain raw for backward compatibility, so moshcode claude
is shorthand for moshcode start claude. In the TUI, use /agents <engine> for
autonomous mode or /start <engine> for raw mode. Running moshcode agents or
/agents without an engine still lists engines and their install status.
The herd — sessions that outlive your terminal
Every launch above hands an engine the whole terminal and waits. That is why they feel native, and it is also why the pit can only do one thing at a time and why closing the lid kills the work.
The herd inverts it. Add -d and the session runs in a runtime that outlives
the pit, so you get your prompt back immediately:
moshcode start claude -d --name api # runs in the background, prompt returns
moshcode agents codex -d # autonomous, and still detached
moshcode ps # who is running, and who wants you
moshcode attach api # step in; Ctrl-b d steps back out
moshcode kill api # end itEverything on screen at once
moshcode herd tile┌─ work ──────────────────┬─ logs ──────────────────┐
│ $ npm test │ tailing deploy.log │
│ ✓ 1492 passing │ 12:04 build ok │
├─ api ───────────────────┴─────────────────────────┤
│ claude — Do you want to proceed? │
│ ❯ 1. Yes 2. No │
└───────────────────────────────────────────────────┘
herd S:shell A:agent X:stop B:pop out z:zoomEvery member becomes a tile in one window. Click a tile to focus it, Ctrl-b z
to blow it up full-screen and again to come back, Ctrl-b d to leave the lot
running. Start and stop without leaving:
| key | |
|---|---|
| Ctrl-b S | new shell tile |
| Ctrl-b A | new claude tile |
| Ctrl-b X | stop the focused tile |
| Ctrl-b B | pop it out into its own session |
| Ctrl-b z | zoom / unzoom |
moshcode herd untile puts them all back in their own sessions. Tiling is just
a view — the processes never restart, and a tiled member stays on moshcode ps
and answers read, prompt and wait exactly as before.
Needs tmux. The script(1) fallback gives each session its own pty with no way
to lay them out together, so it says so and points at the list instead.
The workspace
moshcode herd ui┌ herd ──────┬─ api ─────────────────────────────┐
│ herd │ │
│ │ claude │
│ MAIN │ Do you want to proceed? │
│ ▸ ! api │ ❯ 1. Yes │
│ · work │ 2. No │
│ SCRATCH │ │
│ · logs │ │
│ │ │
│ ACTIONS │ │
│ + shell │ │
│ + agent │ │
│ ✕ stop │ │
│ ⊞ tile │ │
│ ← detach │ │
│ │ │
│ enter ▸ … │ │
│ F12 ▸ … │ │
├────────────┴───────────────────────────────────┤
│ mosh ▸ ps · start claude · show <n> · detach │
└────────────────────────────────────────────────┘Members and actions down the left, the selected member's real terminal on
the right. Click a member to show it; click an action to start a shell, start an
agent, or stop the selected one. q detaches and leaves everything running.
Click the member that is already on screen — or press Enter — and the keyboard goes to it, so you are typing at the agent itself.
The mosh bar
The row along the bottom is a mosh prompt, and it is always there. F12 jumps
to it from anywhere, including from inside an agent that has taken the keyboard,
which makes it the way out of a session you cannot otherwise leave. Esc goes
back to the session; detach leaves with everything still running.
It takes any moshcode herd verb, so you can start a second agent without
leaving the first:
mosh ▸ start claude # another agent, now on screen
mosh ▸ show api # put a different member up
mosh ▸ ps # the roster, over the session, then out of the wayattach means show here — in a workspace the word means "put it in the
content pane", and the real attach would be a tmux client inside a tmux client.
Output grows the bar over the content for as long as you are reading it, then it
collapses back to one row.
moshcode attach <name> gets the bar too. A session you attach to directly
grows the same one-line prompt along the bottom for as long as you are there,
and it is taken away again when you detach — so a member is a plain member when
nobody is looking at it. show <name> from that bar switches you to another
member (and gives that one a bar before you land in it). The bar is the bottom
row either way, which is why one key finds it in both places.
The right-hand pane is not a picture of a session — it is the session's pane,
moved in. tmux's model is session → window → pane, so moving between windows
cannot keep anything on screen; but join-pane moves a running pane into an
existing window, so swapping only the content pane leaves the sidebar untouched.
Both panes keep their process and their scrollback because tmux is moving the
real thing, not redrawing it.
Group sessions with --herd <name> when you start them; anything without one is
in main. Without tmux there is nothing to swap panes with, so herd ui falls
back to a plain clickable list.
A workspace: a few shells and an agent
This is what most people actually want — a couple of shells to work in and an agent or two running beside them, none of which die when the terminal does:
cd ~/src/coinpay
moshcode herd shell --name work # a plain $SHELL
moshcode herd shell --name logs # another
moshcode agents claude -d --name api # and an agent$ moshcode ps
api claude blocked ~/src/coinpay 3m screen
logs shell idle ~/src/coinpay 3m screen
work shell idle ~/src/coinpay 3m screen
⚠ 1 waiting on you — moshcode attach apimoshcode attach work puts you in one; Ctrl-b s hops between all three;
Ctrl-b d leaves the lot running. Close the laptop and they are still there.
Agents moshcode does not ship
start only knows the engines moshcode installs. run takes anything —
an agent with no install spec here, a build, a script:
moshcode herd run --name cur -- cursor-agent
moshcode herd run --name build -- npm run watchEverything after -- is the command, flags and all. These get a roster entry
and the same state detection as a known engine: the shared rules match what a
terminal draws — a y/n prompt, a numbered menu, "esc to interrupt" — not
anything engine-specific, so an agent moshcode has never heard of still shows up
blocked when it stops to ask you something.
Close the terminal, drop the SSH link, come back tomorrow — moshcode ps still
answers, and moshcode attach puts you back inside. In the pit the same verbs
are /ps, /attach, /kill, and the roster prints on the way in.
Switching between them without leaving
Every session lives in one tmux server that moshcode owns, so once you are attached to any of them you can move around the whole herd without going back to the pit:
| key | |
|---|---|
| Ctrl-b s | pick from a list of every session |
| Ctrl-b ) / Ctrl-b ( | next / previous session |
| Ctrl-b L | back to the one you were just in |
| Ctrl-b d | detach — the session keeps running |
That server is started without your ~/.tmux.conf, so these are the stock
bindings whatever your own tmux does with the prefix. Under the no-tmux fallback
there is no switcher: detach with Ctrl-] and moshcode attach <name> the next
one.
Which one needs you
Every session carries a state: working, blocked, done, idle, or
unknown. blocked means a human decision is the only thing missing.
api claude blocked ~/src/coinpay 12m hook
web codex working ~/src/ugig.net 4m screen
audit opencode done ~/src/moshpit-dns 1h runtimeState comes from one authority per session, never two. An engine that reports
through a lifecycle hook (moshcode herd report <name> <state>) is believed and
its screen is not second-guessed; everything else is classified from the bottom
of its screen. Nothing recognisable reads unknown, which is a safe answer —
detection never gates a launch. Patterns that go stale can be fixed in
~/.moshcode/herd/rules.json without waiting for a release.
Blocked can also come and find you, using the same notification fan-out as
notify()/ask():
moshcode herd notify on --ask # email/SMS/Slack/Telegram/push
moshcode herd start claude --name watch # then run `moshcode herd watch` in the herdWith --ask, whatever you reply is typed into the session that was waiting.
What it is costing
Every engine already writes down what it used, so nothing has to be
instrumented or proxied — moshcode cost reads the CLIs' own session logs and
lines them up against the herd:
moshcode cost # per session, in the window (default: 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 # the same report, re-read every 10s
moshcode cost --json # for a script session engine model in out cache cost age pr
api claude claude-opus-5 1.2k 27k 10.5M $9.91~ 42m view #128
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.Under the table, burn is the slope: the same windows for every engine —
last 1 min, 15 min, 1 hour, 4 hours, 8 hours, and the report window — each with
what the requests inside it cost, that cost per hour of window, and the runs
behind it. cost says what the day cost; burn says whether the next hour will
cost the same, which is the number that decides whether to kill something.
From a box running a herd of claude sessions, moshcode cost --all --since 8h:
burn cost rate runs
last 1 min $1.32~ $79.16/h 2
last 15 min $38.34~ $153.35/h 8
last 1 hour $222.03~ $222.03/h 11
last 4 hours $966.27~ $241.57/h 19
last 8 hours $1786.84~ $223.35/h 45
window (8h) $1786.84~ $223.33/h 45
$3.72 a minute over the window, on averageThe rows come from the same per-request records the table does, priced the
same way, so a claude herd and a codex herd are comparable on one screen. A
window longer than --since is left out rather than shown short. Codex logs
running totals, so a turn is the difference between two of them; aider stamps
only the start of a run, so its whole run lands there. --json carries the rows
as burn, each with its cost split by engine.
view is a link — click it and the PR opens in your browser. The cost table
is where you notice a session that cost $300, and the next thing you want is
the thing it produced, which lives on GitHub rather than on this machine. The
cell is an OSC 8
hyperlink: the label stays four characters wide while the click target is the
full URL, so the column costs nothing to carry. Claude Code writes a pr-link
record when a session opens a pull request, and that is where this comes from —
other engines leave the column blank because they record nothing like it.
Not every terminal speaks OSC 8, and there is no way to ask one whether it does.
Piped output prints the raw URL instead, and MOSHCODE_HYPERLINKS=0 forces that
same plain form in a terminal that would otherwise paint a "view" nobody can
click. moshcode cost --json always carries pr and prs in full.
| engine | where the number comes from |
|---|---|
| claude | per-message usage in ~/.claude/projects/**/*.jsonl; a session's subagents and workflow agents (<session>/subagents/…) fold into its row |
| codex | cumulative token_count events in ~/.codex/sessions/… |
| opencode, privacycode | the per-message cost each one computed itself |
| aider | the running session total it prints into .aider.chat.history.md |
A ~ is an estimate, and an unmarked figure is not. opencode and aider
price their own messages, and that price is reported untouched. Claude Code and
Codex record tokens only — which is the honest state of things on a
subscription, where the marginal request costs nothing extra — so those are
multiplied by published rates to answer "what would this have cost on the API".
A model nobody has priced shows its tokens and no cost, rather than a
convincing-looking zero. Price it yourself in ~/.moshcode/pricing.json:
{ "gpt-5.6-sol": { "input": 1.25, "output": 10 } }Cache tokens get their own column because on a long agent session they are most
of the traffic and a tenth of the price; folding them into in makes a $3
session look like a $60 one. Attribution is engine + directory + "started before
this run did", so a session that shares a directory with another agent can pick
up its neighbour's work — --json carries the run list when you need to check.
gemini, kimi, qwen, deepseek, mimocode, omp and openagents keep no readable
usage log, so they report no cost rather than zero cost.
Driving it from a script or another agent
There is no second API — every verb takes --json, and that is what a machine
reads. wait exists to be branched on: exit 0 matched, 2 timed out, 3 no
such session.
moshcode herd start claude --name api --json
moshcode herd prompt api "port the auth routes" --wait
moshcode herd read api --lines 40
moshcode wait api --state blocked --timeout 1hmoshscript gets the same surface as values rather than exit codes, which is what makes fan-out practical:
herdStart("claude", { name: "api" });
herdStart("codex", { name: "web" });
herdPrompt("api", "port the auth routes");
herdPrompt("web", "port the dashboard");
await herdWait("api"); await herdWait("web");
say(herdRead("api", { lines: 20 }));Fanning work out is easy; joining on it used to be a hand-rolled polling loop.
--any returns on the first session to get there, --all when the last one
has, and both take the same --state and --timeout as a single wait:
moshcode wait --any api web docs # --json names the winner
moshcode wait --all api web --state doneconst first = await herdWait(["api", "web", "docs"], { any: true });
await herdWait(["api", "web"], { states: ["done"] });Swarm — one task, a herd of agents, one answer
Claude Code calls it ultracode: a prompt that becomes a workflow of agents. The herd already had every part of that, so this is the verb that composes them, on any engine moshcode can start:
moshcode swarm "port the auth routes and the dashboard to the new API"
· plan — claude is splitting the task into up to 4 pieces
1 auth routes owns src/auth/
2 dashboard owns src/dashboard/
3 shared API client owns src/api/client.js
· swarm port-the-auth-routes-an-1412: 3 sessions, 3 at a time (claude, herd swarm, fleet anthony@dev)
✓ port-the-auth-routes-an-1412-1 idle · t-01
✓ port-the-auth-routes-an-1412-2 idle · t-02
✓ port-the-auth-routes-an-1412-3 idle · t-03
· synthesis — claude is folding 3 pieces into one answerOne headless call splits the task into pieces that do not touch the same
files. Each piece runs in its own herd session, --agents of them at a time
(default 4, the same cap the claude engine's defaults put on Claude's own
workflows), prompted and waited on exactly as herd prompt --wait is, so every
piece is a task in the ledger. One more call folds the outputs into the answer
you read. --verify adds a skeptic per piece whose verdict the synthesis sees;
--plan-only shows the split and starts nothing; --keep leaves the sessions
in moshcode ps. A plan that does not parse runs the task as one piece rather
than not at all.
The fleet: who started what, under whose approval
Every swarm is recorded as OpenFleet:
the swarm id is minted before the plan, each member gets a record file and
the OPENFLEET_* variables beside its herd ones, and the fleet's ledger says
when the swarm was spawned, when each member started and ended, what the
synthesis said, and what was refused. The pane names are the member ids. A
bypass flag the ceiling forbids is refused before anything starts, and the
refusal is a ledger line the human reads. moshcode fleet is the sysop tool
over those files, the same files logicsrc fleet reads:
moshcode fleet tree
anthony@dev (implicit fleet, sysop anthony@dev, depth 1, hosts dev)
└─ 460a4502 claude-code working [bypass]
└─ swarm create-two-0541 "create two ..." 2/4 members until 06:11
├─ create-two-0541-1 (172ffd83) create hello.sh bash claude-code done [bypass] owns hello.sh
└─ create-two-0541-2 create bye.sh bash moshcode/claude working [bypass] owns bye.sh
moshcode fleet log --swarm create-two-0541 # spawn, starts, ends, in order, who did each
moshcode fleet stop create-two-0541 # end it as one unit, nested swarms first
moshcode fleet open --approvals native --depth 2 # a fleet with a ceiling; new roots join itopen and cap are the sysop's alone: a process carrying OPENFLEET_MEMBER
is an agent and is refused. tree is where the ceiling's clock and budget are
enforced: a member past its until or a swarm that has spent its budget is
stopped through its engine and ends timeout or budget in the ledger. moshcode ps groups its rows by fleet and swarm
and marks every session whose approvals are bypassed. The records live under
$OPENFLEET_HOME, default ~/.openfleet.
Let the engine say what it is doing
Reading a screen works and it rots — engines change their wording between releases and nothing tells you. When an engine has lifecycle hooks, install them once and its state comes from the engine itself:
moshcode herd hooks install claude
✓ claude — 3 hooks installed (stop, notification, prompt-submit)moshcode ps then reads hook in its last column instead of screen. The
file is merged, never clobbered — your own hooks stay, and hooks remove
takes out only what moshcode put in. A hook that fires outside a herd session
does nothing and exits 0, so installing one cannot break an engine you run by
hand, and the screen rules stay as the fallback for everything else.
moshcode herd doctor says what is installed, what has drifted, and — for the
first time — what is wrong with your rules.json instead of ignoring it.
The engine's settings, the way a herd wants them
An engine can also say how it would like to be configured. Claude Code's
defaults are ultracode off (a prompt runs as a workflow of agents only when
you ask for one in so many words; neither the setting nor the "ultracode"
keyword turns it on by itself), small workflows (Claude's own advisory
tier, fewer than 5 agents each) and a hard cap of 4 agents at once, so a
workflow you do ask for cannot eat the box the rest of the herd is running on.
moshcode install claude applies them; by hand:
moshcode engines defaults apply claude
✓ claude — 4 defaults applied (ultracode off by default, no ultracode keyword trigger, small workflows (under 5 agents), 4 agents at once, hard cap)Same rule as the hooks: the file is merged, never clobbered. A key you already
set — to anything — stays yours, defaults shows which ones those are, and
defaults remove takes out only a value that is still the one moshcode wrote.
What happened while you slept
Every prompt through the herd mints a task: an id, its state transitions
with timestamps, and the output it produced. ps still answers "now"; this
answers "what happened".
$ moshcode herd tasks api
t-01 22:14 done 4m "port the auth routes"
t-02 22:19 blocked 6h11 "run the migration"
$ moshcode herd task t-02 # transitions, and what came back
$ moshcode herd log api # the raw state history
$ moshcode herd stats api
api working 3h02 · blocked 6h11 · idle 1h40
blocked 6h11 over 2 spell(s) — that one is youBlocked time is the herd's name for human latency: the agent was ready and
you were asleep. Ledgers live in ~/.moshcode/herd/tasks/<session>.jsonl at
0600, capped at the last 500 tasks per session. From a script,
herdTasks(name) and herdTask(id) return them as values.
Agents that are not on this box
A deployed agent can be a herd member. Two kinds: a2a speaks
A2A v0.3.0 (card discovery,
message/send, tasks/get, tasks/cancel), and run is a bare endpoint that
takes POST {"prompt": …} — the shape a gradient agent deploy prints.
moshcode herd remote add research https://agents.do-ai.run/…/production --kind run
export MOSHCODE_REMOTE_RESEARCH_TOKEN=… # never written to the manifest, never synced$ moshcode ps
api claude blocked ~/src/coinpay 12m hook
research remote idle agents.do-ai.run — remoteprompt, read, wait and kill work on it unchanged, which is the point: a
fan-out script across a local pty and a deployed agent contains no if
(remote). A remote's state is the remote's claim — ps says remote in the
last column so it is never mistaken for something this box verified — and
kill on one deregisters it here rather than reaching across the network to
end somebody else's agent.
The herd, over A2A
moshcode herd serve exposes this machine's herd to any A2A client: the herd's
card at /.well-known/agent-card.json, each member at /<name>/,
message/send → prompt, tasks/get → the ledger, tasks/cancel → interrupt.
blocked is A2A's input-required; the states that do not map cleanly round
down and carry the honest one in task metadata.
moshcode login # it verifies tokens against app.moshcode.sh
moshcode herd serve # 127.0.0.1:7683 by defaultIt is a shell on a socket and is treated like one: no unauthenticated mode,
loopback included, a loud warning past 127.0.0.1, and sessions started with
--agent withheld unless you pass --expose-autonomous — an engine with its
approvals bypassed plus a network prompt is the worst pairing on the menu.
Which engine is best at this repo
Not a leaderboard run against engines nobody deploys on repos nobody has — your dataset, your engines, your machine:
moshcode herd eval --dataset evals/moshcode.jsonl --engines claude,codex --threshold 0.8A row is {"prompt": "…", "expect": "pattern"} or
{"prompt": "…", "rubric": "…"} (jsonl, json or csv). Scoring is either the
dataset's own patterns or an engine acting as judge (--judge claude). Exit
codes are distinct on purpose — 0 pass, 4 below the threshold, 5 the
harness could not run — because CI has to tell a worse agent from a broken box.
After a reboot
moshcode restore --dry-run # what would come back
moshcode restore --resume # and ask each engine to reopen its conversationThis brings back the shape — the sessions, in their directories, on their
engines. The processes are new. Work that was in flight is not still running,
and --resume only reaches engines that have a resume flag of their own.
What it runs on
tmux when the box has it: real resizing, scrollback, native attach. Without
tmux, sessions run under script(1) with their input on a FIFO — they work and
they persist, but their size is fixed when they start. With neither, launches
stay in the foreground and say so once. moshcode does not turn a soft dependency
into a hard one, so -d never fails; at worst it degrades and tells you what
would fix it.
The session manifest and every transcript are written 0600: engine argv and
engine output both carry secrets.
Parallel pit tabs
At the mosh prompt, /new opens and switches to another independent moshcode
tab. Run /agents <engine> in each tab and switch between them with tmux's
Ctrl-b n, Ctrl-b p, or Ctrl-b <number> keys. If moshcode is already inside
tmux, /new adds a window to that session and respects its configured window
keys. Otherwise the first /new opens an isolated two-tab workspace with those
default keys and its tab bar at the bottom.
Each tab is a separate moshcode process and provider CLIs still receive an
ordinary inherited terminal. Moshcode does not intercept or reinterpret their
input, output, full-screen UI, or provider-specific shortcuts. The feature
requires tmux; without it /new reports that requirement and leaves the
current pit untouched.
The modes are not identical across providers. In particular, OpenCode --auto
auto-approves permission requests but continues to enforce explicit deny rules.
SSH workspaces
/ssh keeps the SSH connection alive; ssh exec still gives each tool call a
clean command channel.
A coding run against a remote box is a few hundred small operations: read a
file, git status, apply a patch, run the tests. Each one as a fresh ssh
user@host cmd pays for a TCP handshake, a key exchange, a host-key check and
authentication every time. OpenSSH can carry many channels over one
authenticated connection, and moshcode ssh is a thin, careful wrapper over
exactly that — named targets, one persistent master connection per target,
and a --json execution surface built for agents.
moshcode ssh add dev [email protected] --cwd /srv/app # or an alias from ~/.ssh/config
moshcode ssh open dev # authenticate once
moshcode ssh exec dev -- git status --short # …then every command reuses it
moshcode ssh dev # a real shell, same connection
moshcode ssh close dev # or let it expire (--persist, default 10m)Nothing secret is stored. ~/.moshcode/ssh/targets.json holds a host, a port
and a directory; your ~/.ssh/config, agent, known_hosts, ProxyJump and
hardware keys keep working exactly as they do at the prompt, and host keys are
never auto-accepted. The connection lives in an OpenSSH ControlMaster behind a
socket only you can read, is checked with ssh -O check and closed with ssh
-O exit, and a socket the master has gone away from is cleaned up and reopened
on the next command.
For an agent: one connection, many clean commands
exec runs each command on its own channel with no PTY, so stdout, stderr and
the exit status come back separately and stdin stays raw. ok is the
command's verdict; transportOk is ssh's. A grep that finds nothing is
{ ok: false, transportOk: true, code: 1 } — a fact about the files, not the
network.
moshcode ssh exec dev --json -- git diff --stat
# {
# "ok": true, "target": "dev", "connected": true, "transportOk": true,
# "code": 0, "signal": null,
# "stdout": " src/app.ts | 12 +++++---\n", "stderr": "", "durationMs": 14
# }
# a model-produced multi-file patch, applied in one round trip
git diff | moshcode ssh exec dev --json --stdin --cwd /srv/app -- git apply -
moshcode ssh exec dev --json --timeout 10m -- pnpm test
moshcode ssh exec dev --env NODE_ENV=test -- pnpm test # for this command only
moshcode ssh exec dev --sh 'git log --oneline | head -5' # a pipeline, on purposeThere is no shell state between calls, deliberately: exec dev -- cd /tmp
followed by exec dev -- pwd still answers with the target's cwd. Independent
commands may run concurrently over the same connection. A run that performs a
hundred operations authenticates once.
The same objects come back from moshscript:
sshOpen("dev");
const r = sshExec("dev", ["git", "status", "--short"], { cwd: "/srv/app" });
if (!r.ok) say(r.stderr);
sshExec("dev", ["git", "apply", "-"], { cwd: "/srv/app", stdin: patch });
sshClose("dev");When shell state matters
Some work needs a shell that remembers: a cd, an export, a dev server, a
REPL. shell puts one in tmux on the remote box, where it outlives this
terminal, this connection, and the laptop lid.
moshcode ssh shell dev --name app # create or attach · Ctrl-b d leaves it running
moshcode ssh shell send dev/app "pnpm dev" # type into it without attaching
moshcode ssh shell read dev/app --lines 40 # its screen, as text
moshcode ssh shell kill dev/appIf tmux is not on the remote box, shell says so and exec keeps working;
nothing is installed remotely on your behalf.
put and get copy single files over the same connection with scp; put
lands as a temp file and is renamed into place. bench <name> measures fresh
connections against the shared one on your own hosts — on a loopback sshd the
median command went from ~96ms to ~12ms, and on a real network the handshake
is the part that grows.
Workflow tools: UGig, CoinPay, and the cloud CLIs
These remain independent native CLIs with their own authentication, configuration, command trees, output formats, and release cycles. MoshCode installs them and passes control through without reimplementing their APIs.
The primary development toolchain runs through moshcode as a
dev.profullstack.com user.
moshcode tools # list tools and native install status
moshcode tools --json # machine-readable install status for automation
moshcode install ugig # runs the vendor's official install script
moshcode install coinpay # same — each tool owns its installer
moshcode ugig --json gigs list # arguments/output go straight to ugig
moshcode coinpay wallet balance # arguments/output go straight to coinpayBufferOverride — the failure in front of you, already answered
BufferOverride is where humans and agents debug
together: every answer declares the versions it works on, who or what wrote it,
and whether anyone independent reproduced it. bo is that from a terminal.
moshcode install bo # npm i -g @profullstack/bufferoverride
moshcode bo run -- pnpm test # run it, keep what it printed, search for it
moshcode bo search "worker exited before finishing"
moshcode bo get a1b2c3d4e5 --markdownThe product is BufferOverride and the binary is bo — the same split
secrets/logicsrc and spinifex/spx have, keyed the short way round here
because this is a command you type every time something fails.
bo run -- wraps a command rather than replacing it: the wrapped command's exit
code passes straight through, so it can go in front of something already in CI
without changing what CI sees. It captures stdout, stderr, the exit code, the
OS, the architecture and the detected dependency versions, redacts what it
recognises as a secret, and searches for the failure before offering to
publish it. Nothing leaves the machine until you have seen it, and outside a TTY
nothing is published at all unless you pass --ask.
Redaction is best effort and cannot be complete — no pattern list catches a
custom-format secret — so --dry-run is the habit its own docs ask for.
Reads need no credential: search and get work before you have ever run bo
login. Publishing needs one, and bo login is a device-code exchange, so a
terminal never handles a browser session. bo mcp config prints the MCP
registration for a coding agent, which is the same graph over a different door.
CrawlProof — what the fleet costs and what it returns
CrawlProof knows who arrived on your sites and what
your ads delivered. crawlproof joins that to what the bank actually did, so
the terminal can answer the question a dashboard usually cannot: is any of this
paying for itself.
moshcode install crawlproof # npm i -g @profullstack/crawlproof
moshcode crawlproof # the live dashboard, last day, humans
moshcode crawlproof dashboard --range=1m
moshcode crawlproof stats site.com
moshcode crawlproof dashboard --json | jq .roi.derivedFive screens: ROI, Traffic, Ads, Money, Spend. Two rules run through the arithmetic and both exist because breaking either produces a nicer number that is false. Where an account advertises on its own slots, ad spend and ad earnings are one dollar moving between two pockets, so they are reported under Internal and counted as neither cost nor revenue. And a bank feed carries groceries next to servers, so cost is the business scope only.
It also says what it does not know, next to the number: a site that did not answer is missing rather than zero, and a fleet whose visits run far above its pageviews says so and offers the per-pageview figure instead.
Needs a CrawlProof API token in CRAWLPROOF_TOKEN or the token field of
~/.crawlproof.json. The money screens want a CoinPay merchant session as well;
without one the other four still work and the money panels say what is missing.
The dashboard is a TUI and wants Node 22.6+, while stats and --json run
anywhere.
crawlproof also ships in the cli-tools set, which symlinks a wrapper of the
same name that vendors this package. Installing both is fine: the wrapper hands
over to a crawlproof on PATH that is not its own, and refuses to follow one
that is.
Cloud + infra CLIs
moshcode install railway # npm i -g @railway/cli
moshcode install gh # GitHub release binary → ~/.local/bin
moshcode install supabase # GitHub release binary (no global npm package exists)
moshcode install doppler # official script, installed user-local (needs gpgv)
moshcode install doctl # GitHub release binary → ~/.local/bin
moshcode install turso # official script → ~/.turso (new shell to pick up PATH)
moshcode install tailscale # official script; system daemon, so it needs root
moshcode install coral # official script → ~/.local/bin (checksum-verified)
moshcode install spinifex # official script; Linux host platform, so it needs root
moshcode gh pr list # straight through to the native CLI
moshcode railway up
moshcode doctl compute droplet list
moshcode spinifex ec2 describe-instancesSpinifex — your own AWS-compatible cloud
Spinifex is the other end of the infra list:
instead of driving someone else's cloud, it turns your own hardware into one.
EC2, EBS, S3, VPC, and IAM, API-compatible with AWS, on bare metal, edge boxes,
or on-prem racks — so the same aws calls and Terraform providers work against
hardware you own.
moshcode install spinifex # curl -fsSL https://install.mulgadc.com | bash
moshcode spinifex version # straight through to the native `spx` CLI
moshcode spinifex admin init --node node1 --nodes 1The product is Spinifex, the binary is spx, and moshcode spinifex … is exact
passthrough to it — the same split as moshcode secrets and logicsrc.
Spinifex is a host platform, not a standalone binary, so its installer is the most invasive one on this list. Read this before running it:
- Linux only, and specifically Ubuntu 26.04 or Debian 13. The installer pulls QEMU/KVM, OVN/Open vSwitch, and the AWS CLI through apt.
- Root. It writes
/usr/local/bin/spx, systemd units, and scopedsudoers.drules. Like tailscale, it finds sudo itself; MoshCode only gets the password prompt out of the way first. - Your WAN interface must already be bridged to
br-wanbefore you start — check withip -br link show br-wan. The installer does not create it, and bridging a live uplink can drop the box off the network.
After it finishes, Spinifex's own docs take over — setup-ovn.sh --management,
spx admin init, then systemctl start spinifex.target. See
docs.mulgadc.com/docs/install.
MoshCode passes INSTALL_SPINIFEX_SKIP_NEWGRP=1, because on a TTY the vendor
script ends by execing newgrp spinifex to activate the new group. That would
strand you in a subshell instead of returning to the pit — and would park the
rest of a moshcode update run behind it. Log in again (or run newgrp
spinifex yourself) to pick up the group.
Re-running moshcode install spinifex is also its upgrade path: the installer
detects the existing install, replaces the binary, applies pending config
migrations, and restarts the services.
MCP server testing
moshcode install mcpjam # npm i -g @mcpjam/cli
moshcode mcpjam --help # straight through to the native CLIMCPJam is the companion to moshcode mcp: mcp registers a server across your
engines, mcpjam tells you whether that server is healthy first — health
checks, OAuth conformance, tool-surface diffing, and structured triage from the
terminal or CI. Re-running moshcode install mcpjam is also its upgrade path.
Noodle — a REST client that lives in the repo
moshcode install noodle # static binary → ~/.local/bin
moshcode noodle collection create my-api
moshcode noodle request create users/get --url https://api.example.com/users/42
moshcode noodle request run users/get --collection ./my-api
moshcode noodle --collection ./my-api # the TUINoodle is MCPJam one protocol over: MCPJam tells you
whether an MCP server answers, Noodle is how you ask an HTTP one anything at
all. Every request is a readable YAML file — method, url, path params, headers
— so a collection is reviewed in a diff and kept beside the code it exercises,
rather than living in a desktop app's private workspace. The same files drive
the TUI, the CLI and a script, which is what makes it a roster tool: request
run exits with a status and prints the exchange, so it pipes.
It ships a per-platform static binary on its own releases and the install script
picks the right one, checks it against the published SHA256SUMS, and renames
it over any existing copy. So there is no updater to reach for: re-running
moshcode install noodle is the upgrade path.
ElevenLabs — Eleven Agents, voices, and speech
moshcode install elevenlabs # npm i -g @elevenlabs/cli
moshcode elevenlabs auth login # PKCE OAuth, stored in the system keyring
moshcode elevenlabs agents list
moshcode elevenlabs agents push # upload local agent configs to the platform
moshcode elevenlabs text-to-speech convert …ElevenLabs' CLI manages
Eleven Agents — conversational voice agents you define in files and
push/pull against their platform, alongside the knowledge bases, tools,
tests and phone numbers those agents use. The same binary reaches the rest of
the API: voices, text-to-speech, dubbing, transcription, music, and workspace
usage.
They are agents in a different sense than the ones under /agents: you deploy
them and callers talk to them, rather than handing your terminal to one. That is
why it sits here with the workflow CLIs — every subcommand runs one request and
exits, so it pipes like the rest of the roster. --format json (the default
when stdout is not a TTY) and --query (JMESPath) are what a script wants.
The npm package is a small shim over a native binary shipped as an optional
dependency, so install it without --omit=optional or the elevenlabs on your
PATH will refuse to run. Re-running moshcode install elevenlabs is its upgrade
path.
Alchemy — onchain data, wallets, and x402
moshcode install alchemy # npm i -g @alchemy/cli
moshcode alchemy auth # browser login, then pick an app
moshcode alchemy evm balance --address 0x…
moshcode alchemy --json --no-interactive wallet send …Alchemy's CLI covers four things from one binary: querying onchain data across EVM and Solana (balances, NFTs, transfers, prices, blocks, logs, traces, simulations, raw RPC), managing Alchemy apps, networks, allowlists and webhooks, driving an agent-ready wallet (sends, swaps, contract calls, approvals, cross-chain bridges), and paying third-party x402 APIs in USDC under a spend cap.
alchemy auth opens a browser to link your account and saves the selected app's
API key; API keys and x402 wallet auth work too, depending on the command. Pass
--json --no-interactive when a script or agent is driving, which is also what
makes it read like the rest of the roster in a pipeline. It needs Node 22 or
newer, and re-running moshcode install alchemy is its upgrade path.
Where CoinPay is the payments product MoshCode ships alongside, Alchemy is the read side of the same world — the chain itself rather than one wallet's ledger.
yt-dlp, ffmpeg, ImageMagick — the media toolchain
moshcode install yt-dlp # static binary → ~/.local/bin
moshcode install ffmpeg # your distro's package manager (needs sudo)
moshcode install imagemagick # likewise
moshcode yt-dlp https://… # or `dl https://…` from cli-tools
moshcode ffmpeg -i in.mkv out.mp4The odd three out: not workflow CLIs, but the media toolchain the rest of the
roster is built on. cli-tools fronts all three — dl for yt-dlp, vid for
ffmpeg, img for ImageMagick — and every one of them used to answer a missing
binary by telling you to go and install a system package by hand. Now the
registry that installs cli-tools installs what it runs on.
yt-dlp comes from its own releases as a self-contained binary, so it needs
no python and no package manager. That is deliberate rather than convenient:
extractors break whenever a site changes its markup, upstream ships a fix within
days, and a distro package of yt-dlp is frozen for the life of a release. Its
upgrade is yt-dlp -U, the project's own updater.
ffmpeg and ImageMagick exist only as distro packages — no vendor script,
and the static rebuilds floating around are unsigned third-party redistributions
of somebody else's codec stack, on the two tools most likely to be pointed at a
file from the internet. So they go through apt/dnf/zypper/pacman/apk,
or Homebrew on macOS, and ask for sudo everywhere but a Mac (see below).
Re-running the install upgrades them.
ImageMagick answers to two names: magick on version 7, convert on 6, both
current across supported distros under the same package name. MoshCode looks for
either, so a good install is never reported missing.
gh, supabase, and doctl publish no cross-platform install script, so
MoshCode resolves the latest GitHub release and drops the binary in
$MOSHCODE_BIN (default ~/.local/bin) — no sudo, no package manager. Set
MOSHCODE_BIN to install elsewhere.
tailscale, spinifex, ffmpeg and imagemagick are the exceptions: none of
them is a user-local binary, so they go through the distro's package manager and
will ask for sudo (tailscale on macOS delegates to the App Store, and ffmpeg
and imagemagick to Homebrew, which refuses to run as root — so neither is
prompted for a password on a Mac; Spinifex has no macOS build at all).
MoshCode asks for that password before starting the work rather than letting
the installer stop for it partway through — which matters most in moshcode
update, where tailscale is one step in a long unattended run and the prompt
would otherwise land where nobody is watching. Nothing is asked when the plan has
no privileged step in it, when a credential is already cached, or on macOS.
Top-level passthrough preserves stdin, stdout, stderr, environment variables, the current directory, and the native exit result. That keeps JSON pipelines usable:
moshcode ugig --json gigs list | jq .Run moshcode ugig --help or moshcode coinpay --help for each tool's current
native setup and authentication commands. CoinPay currently requires Node.js
20+, while MoshCode itself remains compatible with Node.js 18+.
In the TUI, use /tools, /ugig [args…], or /coinpay [args…]. The native CLI
owns the terminal until it exits, then MoshCode returns to the pit.
Alpaca trading
Alpaca is a workflow tool, not a coding engine. Install its official Go CLI,
use alpaca for exact native passthrough, or use trade for the shorter market
and order vocabulary:
moshcode install alpaca # go install github.com/alpacahq/cli/cmd/alpaca@latest
moshcode trade login # Alpaca profile login; paper trading is the default
moshcode trade ticker AAPL # asset get --symbol-or-asset-id AAPL
moshcode trade quote AAPL # latest quote
moshcode trade analysis AAPL # quote/trade/bar snapshot for analysis
moshcode trade watch # list watchlists
moshcode trade positions # list open positions
moshcode trade orders # list open ordersbuy and sell are safe previews unless --submit is explicit. Other Alpaca
order flags pass through, including limit prices and its separate live-trading
opt-in:
moshcode trade buy AAPL 1 # adds --type market --dry-run
moshcode trade buy AAPL 1 --type limit --limit-price 185
moshcode trade buy AAPL --notional 100 # preview a $100 market buy
moshcode trade buy AAPL 1 --submit # places the paper order
moshcode trade raw data news --symbol AAPL # any native Alpaca command
moshcode alpaca order submit --help # exact native passthroughThe same facade is /trade … in the pit and trade(…) in moshscript.
Alpaca's CLI has no confirmation prompts; --submit intentionally removes
MoshCode's preview guard. Live trading additionally requires Alpaca's --live
opt-in or corresponding environment setting.
Equity research (moshcode stocks)
Where trade is Alpaca's order book, stocks is the research desk:
advis0r.com's public read-only API, rendered in the
pit. No key, no login, no write routes, no binary to install:
moshcode stocks NVDA # score, technicals, fundamentals, thesis, signals
moshcode stocks lookup rivian # company name → RIVN
moshcode stocks signals AAPL # what was said, quoted and sourced
moshcode stocks search "data center" # across every indexed transcript
moshcode stocks reports --limit 10 # the stored index, best score first
moshcode stocks discover fusion # a ranked watchlist (slow — analyzes each candidate)
moshcode stocks open NVDA # the shareable report pageAdd --json to any of them for the raw response. The same facade is /stocks …
in the pit, and MOSHCODE_ADVISOR_URL points it at another instance.
Reports are stored snapshots, not live quotes: every response carries
reportGeneratedAt and every renderer prints it, alongside whether the price is
delayed and which feed produced it. Scores labelled offline come from
deterministic rules rather than a model. It is a research aid, not advice, and
nothing under stocks can place an order.
Crypto market data (moshcode crypto)
crypto is stocks's sibling on the same host: advis0r's read-only crypto
routes over Alpaca's US crypto venue, which trades 24/7 and needs no extra
subscription.
moshcode crypto BTC # price, technicals, score, supply, order book
moshcode crypto lookup bitcoin # asset name → BTC/USD
moshcode crypto quote ETH-USD # latest trade + quote, spread in bps
moshcode crypto spark BTC ETH SOL # recent moves across pairs, as sparklines
moshcode crypto bars ETH-USD --timeframe 1Hour # historical OHLCV
moshcode crypto book BTC-USD --depth 5 # top of book, both sides
moshcode crypto assets # every supported pair
moshcode crypto open BTC # the shareable pagePairs are accepted as BTC, BTC-USD, BTC/USD or BTCUSD — a bare asset
resolves to that asset's USD pair. --json gives the raw response, /crypto …
is the same facade in the pit, and MOSHCODE_ADVISOR_URL points it elsewhere.
Unlike a stocks report, this is a live venue read, not a stored snapshot —
there are no transcripts, no filings and no signals behind a crypto pair, and
the failure mode runs the other way: the price is accurate to the second and
stale by the time you act on it. Every response stamps when it was fetched.
The technical score counts venue-local liquidity, so it is not comparable to
an equity's score, and each response ships the caveats that say so. Prices are
Alpaca's US venue alone and can differ materially from other exchanges. Research
aid, not advice — and like stocks, nothing under crypto can place an order.
Throttle (/nice)
The pit's job is starting other people's programs, and some of them are not shy. Run a few engines at once on a box you also want to type on and you get the failure everyone knows: nothing crashed, but the machine stops answering.
/nice agents claude # throttle this one engine
/nice pnpm -r build # …or this one shell line
/nice merge # …or any other pit command
/nice on # or throttle everything from here on
/nice mem 2G # a ceiling, so a runaway dies alone
/nice cpu 15 # yield more (nice takes -20..19)
/nice # what it is set to
/nice off # back to normal priority (the default)/nice <line> is the form to reach for. It runs anything the pit can already
run — a pit command, an engine, a tool, one of your aliases, or a bare shell
line — at low priority, without changing any setting. It works on all of those
because it hands the rest of the line back to the top of the dispatcher exactly
as an alias expansion does, rather than keeping a list of its own that would
drift. The leading slash is optional: /nice agents claude and
/nice /agents claude are the same line.
The throttle lasts exactly as long as the line that asked for it, including through an alias that expands into something else. The next thing you type is back to normal.
/nice on is the other half, for when the box is shared all day and you would
rather decide once. It is off by default — a throttle nobody asked for is a slow
engine nobody can explain — and it applies to engines started after you turn
it on. The settings words (on, off, status, cpu, io, mem) win the
first position, so a program named on is not reachable through /nice.
nice alone is half a fix, and it is worth knowing which half. It reorders
CPU, so it buys back the part of a freeze you could have waited out. It does
nothing about memory, and memory is the stall that actually costs you a session:
once free RAM runs out the kernel reclaims, reclaim goes to disk, and no
scheduling priority makes that faster. That is why /nice mem exists — it puts
the engine in a systemd scope with a hard ceiling, so the one runaway process
gets killed instead of the whole box going unresponsive.
The ceiling is the one setting that can silently not apply: systemd-run --user
needs a systemd user session, and an ssh login without lingering has none.
/nice says so in its status line rather than pretending, and the CPU and I/O
halves still work. On a box with no nice or ionice at all, and on Windows,
the whole thing is a no-op — engines spawn exactly as they did before.
Settings live in ~/.moshcode/nice.json, owner-only like the history file.
Aliases (/alias)
The pit is a prompt you sit at all day, so it lets you name the lines you keep
retyping. An alias runs in $SHELL unless it starts with /, in which case it
is a pit command:
/alias set gs "git status" # then /gs — and /gs -sb appends to it
/alias set cx "/agents codex" # a pit command, not a shell one
/alias # what is defined
/alias rm gsThey live in ~/.moshcode/aliases.json (owner-only, like the history file) and
survive between sessions. A name that is already a pit command, an engine, or a
tool is refused rather than shadowed — built-ins are dispatched first, so such
an alias would never run.
Some workflow tools ship a set of commands rather than one binary, and propose short words for them. Installing such a tool configures those words too — a dispatcher fronting seven commands is not reachable from the pit until the names that reach them exist:
/install cli-tools # or /tools install cli-tools
✓ cli-tools installed. 🤘
✓ /blog → blog-post
✓ /free → domainfree/upgrade does the same, because an upgrade is where a tool gains commands —
a roster adopted once at install time otherwise goes stale the first time the
tool ships something new. /alias install <tool> (or --all) re-runs it on
demand, for tools you installed before this existed.
The tool proposes and the pit disposes: moshcode reads the suggestions and
writes the file, so nothing else reaches into a config it does not own. A name
you bound yourself always wins — your /prs may carry --orgs flags a generic
suggestion knows nothing about — and a tool that offers nothing, or cannot be
asked, is silent rather than turning a successful install into an error.
Social posting from the pit
The pit can hand a prepared post to Bluesky or Nostr without storing either account's credentials in MoshCode:
/socials
/post bsky "shipped it 🤘"
/post nostr "shipped it 🤘"Bluesky opens its official compose intent. Nostr opens the MoshCode composer,
connects to a NIP-07 browser signer (or a NIP-46 bunker through
window.nostr.js), signs a kind-1
event, and publishes it to the displayed relays. Both flows leave the final
confirmation in the browser. If the pit is remote or headless, /post prints
the composer URL instead.
Getting paid (/timer, /client, /rate, /billing, /payments)
Every agentic CLI helps you do the work. This one also bills for it. Six words, each useful on its own — the timer needs no client, the rate needs no gateway (PRD 0012).
/timerand/billingnow prefer their own CLIs. Tracking time and sending an invoice are not moshcode ideas — they are useful under any agentic CLI, and on Windows, where moshcode does not go. So they also ship standalone:@profullstack/timerand@profullstack/billing.moshcode install timer billing # or: npm install -g @profullstack/timer @profullstack/billingInstalling them changes nothing on its own. Switch the hand-over on when you are ready to move:
billing import # look at what would come across billing import --apply # move it export MOSHCODE_EXTERNAL_BILLING=1 # /timer and /billing now run the CLIsIt is opt-in for a reason.
