- Go 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
The mclass model was retrained with general-question negatives, so its logits and labels changed. Regenerate the Go golden from the new model so the parity test matches. The token ids do not change; the tokenizer is the same. |
||
| .commandcode/taste | ||
| cmd/mcode | ||
| docs | ||
| internal | ||
| .gitignore | ||
| CHANGELOG.md | ||
| go.mod | ||
| go.sum | ||
| README.md | ||
mcode
A coding agent for local models, served by malaikat. It starts the model server for you, keeps a small local model on track, and checks its work.
cd your-repo
mcode
Bare mcode opens the TUI and starts the default profile (glm47-flash) plus the
Laya sidecar. Run one task and exit:
mcode -p "fix the failing test" --yes
Build
go build -o bin/mcode ./cmd/mcode
mcode then needs malaikat on PATH, or MCODE_MALAIKAT set. It builds the
managed binary from ~/Projects/malaikat when that tree is newer.
A release build sets the version:
go build -ldflags "-X main.version=0.3.0" -o bin/mcode ./cmd/mcode
Test
go test ./...
The unit and integration tests use a fake model server, so they need no GPU. The
live test drives the real stack: it starts malaikat, runs real turns, captures a
preference with mclass, and judges the output with mverify. It is behind a build
tag and uses the tiny profile unless MCODE_LIVE_PROFILE says otherwise:
go test -tags live -run TestLiveEndToEnd -timeout 6m ./internal/runtime/
Commands
| Command | Action |
|---|---|
mcode |
the TUI in the current directory |
mcode -p "..." [--yes] |
run one task, print the answer, exit |
mcode approve |
not yet: approvals happen in the TUI |
mcode model [name] |
list malaikat profiles |
mcode goal [text|complete] |
show or set the durable goal |
mcode log [--session X] [--type T] [--limit N] |
search the session log |
mcode install [mclass|all] [--status] |
install the mclass companion |
mcode version |
print the version |
Flags: --cwd DIR, --model NAME, --mode lean|full|plan|minimal, --url URL,
--yes.
Slash commands
| Command | Action |
|---|---|
/plan [task] |
plan mode; /plan <task> plans it, /plan execute runs the plan |
/mode lean|full|plan|minimal |
change the tool surface |
/model [name] |
list or switch the malaikat profile |
/goal <text> / /goal complete |
set or verify-and-close the goal |
/verify |
run the acceptance checks now |
/accept |
list proposed and active checks; /accept <text> accepts one |
/accept reject <text> |
drop a proposal |
/accept undo <text> |
un-accept a check |
/compact |
compact the session now |
/undo |
restore the files the last turn changed |
/resume [id] |
resume a saved session |
/yes / /ask |
allow every command this session, or ask again |
/stop |
stop the current turn (Esc also stops) |
/help, /quit |
What makes it work on a local model
- A frozen prefix. The first system message does not change inside a session, so llama.cpp keeps its KV cache. Volatile state (goal, plan, todos, checks) rides on the newest request.
- A lean tool surface.
read,write,edit,bash,grep,glob,find,todo,criteria, andskillorask_userwhen the session has them.mode planis read-only. - A valid history, always. One message type for the whole program, and the history is validated before every request. Tool calls are committed with their results, so the model always sees what it did.
- The project's own checks.
go test ./...,npm test,make test, and the rest are detected at start and run after any turn that changed files. A failure goes back to the model as the next turn. A check the model suggests is a proposal: you accept it with/acceptbefore it runs. - Progress guards. The loop stops a model that only talks, repeats the same action, writes an essay, or fills the context.
- Laya. The System-1 sidecar reads intent, command risk, and stalls. When it is not running, the harness continues without it.
Preference model
mclass classifies coding preferences. It is a native Go MiniLM encoder plus
two heads: it reads the user text and writes a typed label. A durable preference
in a user turn is saved during the turn. A question is never saved. mcode install mclass downloads the model files (about 90 MB) from Hugging Face into
~/.mcode/opt/mclass/artifacts. No Python, no uv. Check the state with mcode install --status. Without the model, a built-in Bayes classifier runs.
Set MCODE_MCLASS=0 to force the Bayes classifier, or
MCODE_MCLASS_ARTIFACTS to a directory to use different model files.
Verification model
mverify judges fuzzy acceptance checks. It is a small TF-IDF plus logistic
regression classifier that asks: does this output satisfy this prompt? The model
is embedded in the binary, so it always runs. No install, no subprocess, no
Python.
On a verify pass the harness judges the output against the prompt once, then
judges each fuzzy check the model wrote. A pass needs the verifier to say pass
and a confidence at or above verify.confidence_threshold (default 0.7).
/goal complete hands failures back to the model and retries, up to
verify.max_retries (default 3). The automatic pass after an edit runs the
deterministic command checks only.
Set MCODE_MVERIFY to a path to use an external verifier instead.
Permissions
Every command is rated allow, ask, or deny. rm -rf /, curl | sh, a force-push
to main, and writes to system paths are denied. Installs, inline interpreters, and
network downloads ask. The prompt offers allow, allow for this session, allow all
this session, and deny. --yes allows the ask class. A deny is never weakened.
The project's own detected checks are pre-approved, because you already agreed to run them by launching mcode in the project.
Files
mcode keeps state in .mcode/ in the workspace: sessions/ (JSONL log and
snapshots), criteria.json, history, and goals/. It writes
.mcode/.gitignore so a wildcard git add never picks it up. Global state lives
in ~/.local/share/mcode and ~/.config/mcode.
Configuration
~/.config/mcode/config.json and .mcode/config.json merge over the defaults.
Environment variables win over both.
| Variable | Effect |
|---|---|
MCODE_PROFILE |
malaikat profile |
MCODE_MODEL |
model id sent to the server |
MCODE_MODE |
tool surface |
MCODE_URL |
attach to a running server |
MCODE_MALAIKAT |
path to the malaikat binary |
MCODE_MAX_TOKENS |
output cap for one reply |
MCODE_MAX_STEPS |
step fuse for one turn |
MCODE_LLAMA_ARGS |
extra malaikat serve arguments |
MCODE_LAYA=0 |
turn the sidecar off; a URL pins it |
MCODE_VERIFY=0 |
skip the acceptance pass |
MCODE_VERIFY_AUTORUN=0 |
skip the automatic pass after an edit |
MCODE_VERIFY_CONFIDENCE |
minimum confidence for a fuzzy check to pass |
MCODE_MVERIFY |
path to the fuzzy verifier |
MCODE_MCLASS=0 |
force the built-in Bayes preference classifier |
MCODE_MCLASS_ARTIFACTS |
directory that holds the mclass model files |
Not finished
mcode updatedoes not upgrade; build from source.- There is no command palette, mouse selection, or diff colouring in the TUI.
planmode saves the plan text, and/plan executeruns it, but the plan is not yet shown as a first-class panel.