Run Command Code — the coding agent CLI — on Termux with a launcher that actually works on Android.
The upstream command-code npm package does not install cleanly on Termux and
its binaries cannot be executed as published. This repository fixes both
problems with a small installer and a portable launcher, and documents the
whole setup.
This repository contains no Command Code source code. It installs the published npm package at run time. Command Code is a separate project with its own license and terms; see LICENSE.
Two real, reproducible failures on a stock Termux install:
-
npm i -g command-codeaborts. The package publishes a bin namedcmd, and$PREFIX/bin/cmdis already owned by Termux'stermux-toolspackage:npm error code EEXIST npm error path /data/data/com.termux/files/usr/bin/cmd -
The published bins cannot be executed. Their shebang is
#!/usr/bin/env node, and Android has no/usr/bin/env:$ $PREFIX/lib/node_modules/command-code/dist/index.mjs --version bad interpreter: No such file or directory
scripts/install.sh installs the package into a private npm prefix
(~/.local, which does not collide with anything) and installs
bin/cmdcode, a launcher that resolves Node.js and the package entry point at
run time.
| Requirement | Notes |
|---|---|
| Termux | Android 7+; from F-Droid, not the Play Store build |
| Node.js 22 or newer | pkg install nodejs, then node -v |
| npm | ships with the nodejs package |
bash |
ships with Termux |
| ~300 MB free | the upstream package and its dependencies are large |
Check what you have:
node -v # must print v22.x or newer
npm -vgit clone https://github.com/XtrComSu/command-code-termux.git
cd command-code-termux
./scripts/install.shAlready have the repository? Then simply:
./scripts/install.shThe installer is idempotent: re-running it skips work that is already done.
It validates the environment first, refuses to run outside Termux, never
overwrites a file it did not create, and verifies the result by running
cmdcode --version.
Options:
./scripts/install.sh --help # all options
./scripts/install.sh --version latest # newest published version instead of the pin
./scripts/install.sh --prefix-termux # install into $PREFIX instead of ~/.local
./scripts/install.sh -y # allow it to upgrade/install prerequisites
./scripts/install.sh --force # reinstall and replace a launcher it did not createpkg install -y nodejs
npm install -g --prefix "$HOME/.local" command-code@1.73.4
install -m 0755 bin/cmdcode "$PREFIX/bin/cmdcode"
ln -sf cmdcode "$PREFIX/bin/cmdc"Verify:
cmdcode --versionUpstream publishes cmd as a bin name. Termux:API already owns $PREFIX/bin/cmd,
and the Termux:API add-on calls that path by absolute name, so replacing it
blindly is a bad idea. scripts/finish-cmdcode.sh installs a dispatcher that
serves both: Termux:API calls keep working, and cmd becomes Command Code too.
./scripts/finish-cmdcode.shThe original file is kept at $PREFIX/share/termux-command-code-termux/cmd.orig
and the script prints the one-line command that reverts the change.
./scripts/uninstall.sh # launchers + npm package, keeps your config
./scripts/uninstall.sh --purge-config # also deletes ~/.commandcodeYour ~/.commandcode directory (sessions, settings, stored provider keys) is
preserved unless you explicitly pass --purge-config.
Everything is optional; the CLI runs with no configuration at all.
Any one of these is enough:
cmdcode login # browser login for a Command Code account
cmdcode login openai # ChatGPT / Codex subscription
cmdcode login copilot # GitHub Copilot subscriptionIf the browser does not open, the CLI prints a link. Open that link on the
same device: the callback server listens on 127.0.0.1 on this phone, so a
different device or machine cannot complete the handshake. You can also paste
an API key into the prompt instead, or skip the flow entirely:
export COMMAND_CODE_API_KEY=... # taken from https://commandcode.ai/studio/auth/cli
cmdcode status # confirms which credential is in useTo use your own model provider instead of a Command Code plan, use /connect
inside a session, or declare a provider in ~/.commandcode/providers.json.
Keys are stored in ~/.commandcode/auth.json (mode 0600); providers.json
accepts only references such as "apiKey": "$OPENROUTER_API_KEY", never a raw
secret. --local-only keeps every request on your own endpoints.
.env.example lists every supported variable with a description and no
values. Copy it somewhere private and source it:
mkdir -p ~/.config/command-code-termux
cp .env.example ~/.config/command-code-termux/env
$EDITOR ~/.config/command-code-termux/env
. ~/.config/command-code-termux/envMost useful ones:
| Variable | Effect |
|---|---|
COMMAND_CODE_API_KEY |
authenticate without the browser flow |
CMD_LOCAL_ONLY=1 |
never contact commandcode.ai (same as --local-only) |
DO_NOT_TRACK=1 |
disable telemetry and machine fingerprinting |
CMDC_ROOT |
override where the launcher looks for the package |
CMDC_NODE |
override the Node.js binary the launcher uses |
cd ~/your/project
cmdcode # interactive sessionThe first launch asks about onboarding and permissions; --skip-onboarding and
-t/--trust skip those prompts for scripted or repeated runs.
cmdcode # start an interactive session
cmdcode "explain this repo" # start with an initial message
cmdcode -p "run the tests" # non-interactive: answer on stdout, then exitUseful options (from cmdcode --help):
| Option | Purpose |
|---|---|
-c, --continue |
resume the last conversation |
-r, --resume [name] |
resume by id or name, or pick from history |
--fork-session |
fork a resumed session instead of continuing it |
-m, --model <id> |
pin a model for the session |
--effort <level> |
reasoning effort, where the model supports it |
--permission-mode <mode> |
standard, plan, accept-edits, yolo |
--plan |
start in plan mode |
--add-dir <dir> |
add another directory to the workspace |
--local-only |
BYOK endpoints only, no Command Code backend |
--list-models |
show available models |
--no-auto-update |
disable the background updater for one run |
--max-turns <n> |
cap turns in -p mode |
Commands:
| Command | Purpose |
|---|---|
cmdcode info |
platform, Node.js, memory and terminal diagnostics |
cmdcode status |
authentication state and which credential is used |
cmdcode whoami |
account details |
cmdcode login [provider] / logout |
authenticate / sign out |
cmdcode mcp add|list|get|remove|add-json|auth |
MCP servers |
cmdcode skills add|remove|list |
skills from GitHub repositories |
cmdcode mods add|remove|list |
extensions from npm, git or a local path |
cmdcode taste enable|disable|push|pull |
taste-learning packages |
cmdcode update [--check-only] |
update the installed package |
cmdcode help |
built-in help |
Examples:
cmdcode -p "summarise the git log of the last 10 commits" --output-format text
cmdcode --model <model-id> -p "write a test for src/parse.ts"
cmdcode -w experiment -p "prototype a CLI for this repo".
├── bin/
│ └── cmdcode # the launcher that gets installed to $PREFIX/bin
├── scripts/
│ ├── install.sh # one-command installer (idempotent, non-destructive)
│ ├── uninstall.sh # removes only what this project created
│ └── finish-cmdcode.sh # optional `cmd` dispatcher for Termux:API
├── tests/
│ └── run-tests.sh # syntax, launcher, installer and hygiene checks
├── .env.example # optional variables, names only, no values
├── .gitignore
├── .editorconfig
├── CONTRIBUTING.md
├── LICENSE # MIT for this repository only
├── README.md
└── SECURITY.md
scripts/install.sh
│ npm install -g --prefix ~/.local command-code@<pin>
│ cp bin/cmdcode → $PREFIX/bin/cmdcode (+ symlinks: cmdc, commandcode, command-code)
▼
$ cmdc → $PREFIX/bin/cmdcode (POSIX/bash launcher, shebang pinned to Termux's bash)
│ 1. locate node: $CMDC_NODE → $PREFIX/bin/node → PATH
│ 2. refuse Node.js < 22 before loading the bundle
│ 3. locate the package: $CMDC_ROOT → ~/.local → $PREFIX → `npm root -g`
│ 4. prepend $PREFIX/bin to PATH for child processes
▼
node ~/.local/lib/node_modules/command-code/dist/index.mjs "$@"
▼
Command Code CLI (upstream, own license)
Runtime state and credentials are written by Command Code itself under
~/.commandcode/ and are never touched by this project.
./tests/run-tests.shThe suite runs entirely in a temporary directory: it never modifies $PREFIX,
your ~/.local install or your ~/.commandcode. It checks shell syntax,
launcher argument passing, the missing-package and broken-node error paths, the
cmd dispatcher against Termux:API and Command Code invocations, repository
hygiene (no secrets, personal paths or LAN addresses in the tree), and — when
cmdcode happens to be installed — that the real CLI starts.
CMDC_SKIP_NETWORK=1 ./tests/run-tests.sh # skip the live check
shellcheck scripts/*.sh tests/*.sh bin/cmdcode # optionalcmdcode update --check-only # see what is available
cmdcode update # update the installed package
./scripts/install.sh --version latest --force # or via this installer| Symptom | Cause and fix |
|---|---|
bad interpreter: No such file or directory |
you ran the raw npm bin. Use cmdcode, not .../command-code/dist/index.mjs. |
npm error EEXIST ... /bin/cmd |
you used npm i -g. Install with ./scripts/install.sh, which uses ~/.local. |
Command Code needs Node.js 22 or newer |
pkg install nodejs, then confirm with node -v. |
cmdcode: command-code package was not found |
the package was removed or lives elsewhere. Re-run ./scripts/install.sh, or set CMDC_ROOT. |
| Login waits at "Complete login in your browser" | open the printed link on this device; the callback is 127.0.0.1 on this phone. Or paste an API key, or set COMMAND_CODE_API_KEY. |
Everything is root-owned after installing through su |
the installer chowns to $HOME's owner; if it could not, run chown -R "$(id -u):$(id -g)" ~/.local/lib ~/.local/bin. |
cmd still opens Termux:API |
that is expected by default. Run ./scripts/finish-cmdcode.sh to serve both. |
cmdcode not found after installing |
$PREFIX/bin is missing from PATH in that shell. Open a new Termux session. |
- Android/Termux only. The launcher assumes
$PREFIX/bin/bashexists. - Requires Node.js 22+. Termux's
nodejspackage tracks Node.js releases, so on a device that has not runpkg upgradeyet, install Node.js 22+ by another means or upgrade Termux's packages. - Large footprint: the upstream package plus dependencies is ~300 MB.
- Upstream's self-updater (
cmdcode update) writes into the npm prefix this project chose. That is expected; use--no-auto-updateif your setup is managed externally. - Interactive TUI needs a real terminal; piping
cmdcodeinto a file or another program will not render it. Use-pfor non-interactive runs.
- Never commit
~/.commandcode/. It holdsauth.json(Command Code account credentials and BYOK provider keys) plus session transcripts and a telemetry id..gitignoreexcludes it, and so should yours. - This repository never embeds credentials.
.env.examplecontains variable names and descriptions only. No secret belongs inscripts/install.sh. - Keys pasted into
providers.jsonare rejected by design; use"$VAR"references instead. - Prefer
DO_NOT_TRACK=1, and--local-only/CMD_LOCAL_ONLY=1when every request should stay on your own endpoints. - The installer's version is pinned so a fresh install is reproducible. Review
cmdcode updatebefore letting it jump versions. - Report vulnerabilities as described in SECURITY.md.
See CONTRIBUTING.md. In short: run ./tests/run-tests.sh,
keep the repository free of secrets and personal paths, and remember that the
MIT license covers this repository only — not Command Code.
MIT for this repository. Command Code itself is licensed separately by its authors; see LICENSE and https://commandcode.ai.