The CLI uses five codes, defined as constants in cli/src/runtime.ts: EXIT_OK, EXIT_ERROR, EXIT_USAGE, EXIT_CONFLICT and EXIT_ENVIRONMENT. The seven device commands (login, logout, attach, detach, status, watch, and prune) use the same five values: any unknown command or invalid flag exits with 2; login with a credential that already exists, logout with a credential coming from MALETA_DEVICE_TOKEN, attach with a Maleta already bound, and prune with a maleta watch running all exit with 3 (EXIT_CONFLICT); no device command uses 4.
#Code table
| Code | Constant | When it happens |
|---|---|---|
0 | EXIT_OK | init completed; help printed; validate completed; install or sync finished with failures === 0 — skipped or unsupported items still exit with 0. |
1 | EXIT_ERROR | Unreadable or invalid document; any planning, GitHub resolution, limit, collision, staging, or write error; plugin failure. |
2 | EXIT_USAGE | Unknown command, unknown option, invalid flag value, or flag used with the wrong command. |
3 | EXIT_CONFLICT | init targeting a file that already exists: it is opened with openSync(target, "wx"), which results in EEXIST. |
4 | EXIT_ENVIRONMENT | The file's targetOs differs from the host during install or sync; the native tray binary is missing or lacks permission to execute; or the desktop tray is unavailable. |
#Usage errors exit with 2
- stderr receives the message
[error] <mensagem>followed byRun 'maleta --help' for usage. - Usage errors are:
unknown command '<x>',unknown option '<x>',--file requires a path,--tool must be all, claude, codex, or agents,--dry-run is only supported by install and syncand--tool is only supported by install and sync. - If
--helpor-happears anywhere in the arguments, help takes precedence over usage errors and exits with0.
maleta install --tool nope --file ./maleta.json
echo "exit=$?"#The 4 versus 1 caveat
The same targetOs mismatch produces different codes depending on how it is used. On the command line, install and sync compare the value before building the plan: they print [error] targetOs '<x>' does not match the local host '<y>'; refusing install (or refusing sync) and the process exits with 4.
When createInstallPlan is called as a library, the corresponding check throws PlanError with the message targetOs '<x>' does not match the local host '<y>' — without the suffix ; refusing <mode>. If the error is not caught, the exception propagates; callers that catch it and map it to the host process's exit code must treat it as 1, not 4.
#What still exits with 0
- Skills skipped because they do not exist in the local assets: the
[skip] …line is printed, but the summary still reports success. - Plugins skipped because they are Claude-only under another
--tool, or because they are not in the local plugin manifest. maleta validate --tool claude: the flag is accepted and silently ignored, without affecting the result.