The public CLI is mendcode. It opens the interactive terminal coding harness, runs setup/status checks, manages packages, and controls optional mflow/TSM/worktree integrations.
Development checkouts may still have a local mend shim, but the public installer and package metadata expose mendcode and mendcode-runtime. Public docs and screenshots should use mendcode.
mendcode # open MendCode TUI in the current project
mendcode --worktree [target] # open MendCode in a git worktree by branch/path/id
mendcode --tsm [target|--all] # open TSM workspace with a MendCode split
mendcode run "message" # open TUI with an initial message
mendcode session list --format json
mendcode chat "message" # run a control-plane chat turn
mendcode status
mendcode loops status # list loop workflows
mendcode doctor
mendcode checkmendcode session exposes the real session, prompt, status, event, subagent,
loop, permission, question, and diff state to another local agent. It does not
create a second provider stack or a separate session database; it uses the same
runtime and project directory as the TUI.
mendcode session create --title "Implement the feature" --format json
mendcode session send ses_... "Do the work" --async --format json
mendcode session status ses_... --format json
mendcode session inspect ses_... --format json
mendcode session wait ses_... --timeout-ms 1800000 --format json
mendcode session events ses_... --follow --format json
mendcode session cancel ses_... --format jsonAvailable lifecycle operations are create, list, get, inspect,
rename, fork, archive, delete, send, status, wait, cancel,
events, and export. send --async returns immediately after starting a
detached MendCode runtime; wait and events can then monitor the same
session. Without --async, send waits for the prompt operation to finish.
JSON output is line-delimited and uses the versioned mendcode.cli.v1 envelope:
{
"protocol": "mendcode.cli.v1",
"kind": "event | result | error",
"event": "session.completed",
"eventID": "evt_...",
"timestamp": 1760000000000,
"sessionID": "ses_...",
"data": {}
}mendcode run --format json is the lower-level streaming surface for tool,
step, text, reasoning, and session lifecycle events. Secret-like fields are
redacted before JSON emission, while normal usage counters remain available.
See Automation runtime for the complete contract.
Use the canonical loop guide for the full contract and lifecycle details: Loop Workflows.
/loop # natural-language loop creation/activation inside the TUI
/loops # operator dashboard for active and historical loops
The public loop CLI supports status/list, examples/templates, draft, show, tail, monitor, tick, daemon, service, run, activate, pause, resume, and stop. Use tick ... --execute for a real agent turn; run is record-only. Signal, override, delete, and agent-retarget actions belong to the assistant tool or local API rather than the public CLI.
The setup flow separates required harness readiness from optional product features.
Required setup:
provider: the provider/auth path MendCode can use.models: model role projection for runtime use.budget: API/budget posture when API-based usage is enabled.prompt: prompt mode and focus behavior.
Optional setup:
package: active team/runtime package.tui: TUI profile and visual preferences.memory: global/project memory config.permissions: global default permission mode and smart-reviewer role.
Useful commands:
mendcode setup status
mendcode setup plan
mendcode setup doctorCompleting setup records local project state. It does not mean provider credentials are committed. Provider credentials, OAuth tokens, API keys, local mflow room secrets, caches, and machine-local state must stay outside shared packages and repository docs.
The setup provider step is labeled Connect Provider because it is the place
where MendCode validates the provider/auth path the runtime can actually use.
Provider credentials are local user state, not package or repository content.
The provider picker can include:
- hosted/API providers configured through the normal MendCode auth path;
- the upstream
opencodeprovider surface when available; - local CLI-backed providers such as
Claude Code.
Claude Code is a local CLI bridge. MendCode validates that the claude
binary is installed, that claude auth status --json reports an authenticated
local account, and then exposes version-compatible Claude Code models through
the normal model picker. Optional config can override the binary path, home
path, and launch arguments for machines that keep Claude Code state outside the
default shell environment.
Example provider options:
Keep this config free of secrets. It should point to local tools and local state only; the CLI remains responsible for its own login/session files.
Common MendCode config paths:
.mendcode/mendcode.json: project config, focus defaults, package metadata, budget/worktree policy, loop service settings, and integration settings..mendcode/generated/opencode.json: generated compatibility config for the adapted runtime..mendcode/prompt-mode.json: persisted prompt mode consumed bymendcode run,mendcode chat, and the TUI footer..mendcode/prompts/custom.md: optional project-local Markdown instructions for thecustomPrompt Context mode..mendcode/models.yaml: project model-role config.~/.config/mendcode/models.yaml: global model-role config.~/.config/mendcode/mendcode.json: global MendCode config.~/.config/mendcode/permissions.json: global permission mode and reviewer-role config..mendcode/tui/profile.json: TUI profile..mendcode/packages/state.json: installed/enabled package state..mendcode/registry.json: package registry sources..mendcode/memory/: project memory config, entries, and proposals when project memory is enabled..mendcode/mflow/state.json: mflow local state..mflow/config.toml: mflow runtime config scaffold..mendcode/tsm/state.json: optional TSM state..mendcode/worktree/state.json: managed/adopted worktree registry.
MendCode exposes passive prompt-cache controls through the cache block in the
project or global MendCode config. The controls affect cache keys and provider
cache annotations that MendCode sends with a request; they never delete a
provider's remote cache and they never schedule refresh or keepalive requests.
This policy is separate from MendCode's local runtime/cache directories and from the Usage Insights statistics cache. It controls request shaping and provider annotations; it does not configure local cache size, eviction, or statistics retention.
The public CLI is:
mendcode cache status [--format text|json] [--json]
mendcode cache enable [--global] [--provider <id>] [--model <id>] [--session <id>] [--project-path <path>]
mendcode cache disable [--global] [--provider <id>] [--model <id>] [--session <id>] [--project-path <path>]on is an alias for enable and off is an alias for disable. Without
--global, mutation commands update the active project's config. With
--global, they update the global config. --project-path is only valid with
--global and writes an exact normalized project-path override. A model target
requires --provider; --provider and --model are valid together and target
one provider model. Session and project targets cannot be combined with a
provider or model target, and a project target cannot be combined with a
session target.
The cache block is optional. If it is absent, MendCode uses a conservative
provider-aware default: OpenAI requests use smart, while other providers
preserve existing legacy behavior.
{
"cache": {
"mode": "smart",
"projects": {
"/Users/me/src/example": { "mode": "smart" }
},
"sessions": {
"mode": "selected",
"include": ["ses_allowed"],
"exclude": ["ses_blocked"]
},
"providers": {
"openai": {
"mode": "smart",
"models": ["openai/gpt-6-astra"],
"exclude_models": ["openai/legacy-model"]
},
"openrouter": {
"models": ["openai/gpt-5.6-mini"]
}
}
}
}Supported values and scopes:
mode:offsuppresses MendCode cache controls;smartenables only the verified passive-key paths described below. Omit it to use the provider-aware default (OpenAIsmart; other providerslegacy).projects: exact normalized project paths mapped to{ "mode": "off" }or{ "mode": "smart" }. Use absolute paths for portable global config.sessions.mode:all,selected, ornone.includeselects session IDs andexcludeblocks session IDs. An excluded session wins over inclusion.providers: provider IDs mapped to an optionalmode,modelsallowlist, andexclude_modelslist. Model matching accepts the configured runtime ID, API model ID, and their final path component.
Resolution is deterministic. Disabling rules win in this order: global
mode: off, project off, session none/exclusion/not-selected, provider
off, then model exclusion or allowlist rejection. Enabling then resolves from
the global mode, project mode, provider selection, or explicitly included
session; otherwise OpenAI uses smart and other providers use legacy.
smart is deliberately conservative. A passive cache key is enabled only for
a binding that has a verified local wire contract:
- ChatGPT subscription/OAuth on OpenAI Codex Responses Lite uses the provider-native, session-scoped key already required by that adapter. This is not a MendCode-managed key and is not shared across sessions, projects, or accounts;
- API-key authentication uses a managed key only for a non-Responses-Lite
binding with OpenAI's
@ai-sdk/openaiSDK atapi.openai.com, or the OpenRouter SDK/compatible route atopenrouter.ai; - in both cases, provider, endpoint, SDK, authentication, and transport must match the verified binding.
The built-in verification is provider/SDK/endpoint based. An exact-model
restriction is applied only when providers.<id>.models or
providers.<id>.exclude_models is configured. Therefore, when a global or
provider policy is smart, use an allowlist if caching must be limited to
known models; a model name alone is not evidence of provider support.
Other providers, custom endpoints, and incomplete bindings do not receive a
newly inferred managed key. Existing provider-specific options and legacy
annotations remain governed by their existing transform path unless the policy
is explicitly off; smart does not overwrite an unverified provider option.
MendCode does not infer TTL, cache warmth, hit rate, price savings, weekly-limit
percentage, or provider support from a model name alone.
off removes recognized cache fields from request options and message/provider
annotations, including promptCacheKey, prompt_cache_key, cacheControl,
cachePoint, cache_control, copilot_cache_control, and gateway
caching: "auto". For ChatGPT OAuth, the internal disable marker is consumed
before the request is forwarded upstream. This is local request shaping, not
remote-cache delete access.
# Inspect the effective policy for the current project.
mendcode cache status --format json
# Enable conservative caching for the current project's OpenAI provider.
mendcode cache enable --provider openai
# Allow one exact model and disable another model on the same provider.
mendcode cache enable --provider openai --model openai/gpt-6-astra
mendcode cache disable --provider openai --model openai/legacy-model
# Limit caching to one session, or disable it for a session.
mendcode cache enable --session ses_allowed
mendcode cache disable --session ses_blocked
# Manage an exact project override from the global config.
mendcode cache enable --global --project-path /Users/me/src/example
mendcode cache disable --global --project-path /Users/me/src/examplecache status reports the effective mode, the current project, the configured
block, and activeKeeper: false. The reported configured block is the merged
policy visible to the current project; it includes any projects, sessions,
and providers rules. The status command does not take a session ID. To
inspect session policy, read configured.sessions: none disables all
sessions, selected permits only IDs in include, and exclude always wins.
Cache Keeper, scheduled refresh, automatic warm-up, and provider canaries are not part of this control surface. A cache key may still consume request/quota/ weekly-limit usage, and missing provider cache metrics remain unknown rather than being converted to a zero or used to claim a cache hit. The provider's usage report or account UI is authoritative for actual token accounting and remaining subscription quota.
If another MendCode backend currently owns the local database, a standalone
cache status invocation may fail with a writer-lock error. That error means
the status was not read; it is not evidence that caching is enabled or
disabled. Keep the active backend running and query through its existing
client, or retry after it releases the writer. Do not delete the lock manually.
The TUI keeps a temporary in-memory edit history for the active prompt:
Ctrl+_undoes the latest prompt edit. On many keyboards, pressCtrl+Shift+-.Ctrl+Yredoes a prompt edit.- On macOS,
⌘Zand⌘⇧Zare also available by default. Ctrl+Zremains the POSIX terminal suspend shortcut and does not undo prompt text.
This history is intentionally not persisted. It can recover text cleared while the prompt is still open, but closing the prompt or TUI discards it.
Override the bindings in .mendcode/tui.json or ~/.config/mendcode/tui.json:
{
"keybinds": {
"input_undo": "ctrl+_,super+z",
"input_redo": "ctrl+y,super+shift+z"
}
}Focus profiles tune provider-family behavior, model role defaults, prompt policy, tool posture, budget posture, and worktree policy.
Built-in focus families include:
codexclaudegeminikimideepseekmistral
Commands:
mendcode focus status
mendcode focus list
mendcode focus show codex
mendcode focus use codexUse focus profiles to keep provider-specific behavior explicit. Do not describe them as proprietary upstream prompt dumps; MendCode adapts behavior for provider/model families without pretending to be those products.
Prompt mode controls how much MendCode harness context is added to runtime requests. The persisted state lives in .mendcode/prompt-mode.json and is shown in the TUI footer/status surfaces.
| Mode | What it does | Good for |
|---|---|---|
minimal |
Uses a small MendCode boundary and avoids the full harness prompt. Persistent memory remains independent and can still be retrieved when enabled. | Low-noise experiments, debugging prompt influence, narrow one-off tasks. |
focus |
Default mode. Uses the selected focus profile and provider-family policy. | Normal daily coding. |
full |
Adds the focus behavior plus MendCode product/runtime policy and integration context. Legacy dev-js config is normalized to full. |
Work that needs package, memory, workflow, or product policy context. |
custom |
Uses the safe MendCode boundary plus .mendcode/prompts/custom.md; it does not inherit the extra focus or full sections. The file is capped at 32 KiB. |
Project-specific instructions that should be versioned with the checkout. |
Current public setup/status surfaces should be used to inspect prompt readiness:
mendcode setup status
mendcode status
mendcode prompt build --mode custom --json
mendcode prompt mode customWhen .mendcode/prompts/custom.md is valid, its configured name appears in setup
and in the Ctrl+P MendCode Prompt Context selector. The internal mode remains
custom, but the visible label can be chosen per project with frontmatter:
---
name: Hello World Demo
---
always say first Hello World!The name is metadata and is not sent to the provider; only the Markdown body is
added to the custom prompt. If no name is provided, MendCode derives a readable
label from the first heading or filename.
The loader accepts only a non-empty regular file inside the active project root,
normalizes UTF-8 line endings, and reads at most 32 KiB. Missing, empty, oversized,
unreadable, or escaped-symlink files leave the selected mode visible in diagnostics
but use a safe fallback without inventing prompt text. Remove the file to make the
custom option disappear from selectors; use mendcode prompt mode or
mendcode status to inspect the relative path, byte count, origin, and fallback
reason without printing the file body.
For team rollout, packages can include the reserved
.mendcode/prompts/custom.md file and prompt mode state as part of the runtime
pack. For manual local experiments, edit .mendcode/prompt-mode.json with one of
minimal, focus, full, or custom, then verify through setup/status and the TUI footer.
Models are configured by role instead of hardcoding one model everywhere.
Common roles:
defaultsmallplanbuildcodesubagenttitlecompactionsummarymemoryExtractormemoryDreammemoryAssistantpermissionReviewer
Example:
version: 0
enabled: true
roles:
default:
providerID: "<provider>"
modelID: "<default-model>"
authMode: "<auth-mode>"
build:
providerID: "<provider>"
modelID: "<model-for-build>"
authMode: "<auth-mode>"
small:
providerID: "<provider>"
modelID: "<model-for-lightweight-tasks>"
authMode: "<auth-mode>"
memoryDream:
providerID: "<provider>"
modelID: "<model-for-memory-maintenance>"
authMode: "<auth-mode>"
memoryAssistant:
providerID: "<provider>"
modelID: "<model-for-memory-side-chat>"
authMode: "<auth-mode>"
permissionReviewer:
providerID: "<provider>"
modelID: "<model-for-permission-review>"
authMode: "<auth-mode>"Commands:
mendcode models status
mendcode models presets
mendcode models set-default <provider> <model> --auth-mode <auth-mode> --enable
mendcode models use-preset <preset-id> --enable
mendcode models planThe CLI currently writes the default model role directly. For non-default roles
such as build, code, subagent, memoryExtractor, memoryDream,
memoryAssistant, or permissionReviewer, edit models.yaml and run
mendcode models plan / mendcode models status to verify projection. Roles
are explicit; the generic review role is not part of the model configuration.
Public docs should keep model examples provider-neutral; teams can pin their own
provider and model choices in local or package-specific config.
Useful inspection commands:
mendcode providers status
mendcode auth status
mendcode permissions status
mendcode memory status
mendcode memory search "project convention"
mendcode memory preview "project convention"Permission modes:
| Mode | Behavior |
|---|---|
approval |
Manual approval remains the default posture. |
smart |
Auto-approves only bounded read-only shell requests. Risky or ambiguous requests use the configured AI reviewer when applicable, and fall back to a prompt if it is unavailable; scripts, deletes, writes, privilege changes, network commands, and other non-read-only commands are never auto-approved. |
full_access |
Reduces permission prompts for the current policy surface, but explicit deny rules still matter. Use only when that trust posture is intentional. |
Configure permissions:
mendcode permissions status
mendcode permissions set-default approval
mendcode permissions set-default smart
mendcode permissions set-default full_access
mendcode permissions set-reviewer-role permissionReviewerDescribe smart as AI-assisted permission review, not as “secure by default”. It depends on the configured reviewer role and still needs a sane trust boundary.
Memory behavior:
- Memory can be global or project-scoped.
- Runtime memory is injected as transient system context; it is not copied into normal chat history unless the user asks to see it.
- Generated memory proposals are approval-gated.
- Direct
mendcode memory addis for explicit user requests to save memory. mendcode memory searchandmendcode memory previeware the right commands before editing, deleting, applying, or rejecting entries/proposals.- The Memory Center view adds saved/pending views, category policy, Dream status/logs, workspace awareness, and constrained side chat.
Example:
mendcode memory status
mendcode memory list --scope global
mendcode memory list --scope project
mendcode memory search "release workflow"
mendcode memory preview "release workflow"
mendcode memory add "Use docs screenshots with the public mendcode command." --scope projectCommon next commands:
mendcode packages status
mendcode mflow status
mendcode worktree status
mendcode tsm statusUse Packages and team sharing, Customization, mflow coordination, and TSM and worktrees for deeper workflows.
{ "provider": { "claude-code": { "options": { "binaryPath": "claude", "homePath": "", "launchArgs": "" } } } }