appmecca
v0.1.0-alpha.27
Published
The AppMecca command-line client — deploy and operate apps on AppMecca.
Readme
mecca
The AppMecca command-line client — TypeScript/Node rewrite of the Python mecca CLI.
Status: published to npm and Homebrew; still versioned as an alpha. 19 command modules —
app,auth,backup,bucket,build,configure,debug,domain,drive,exec,group,logs,ops,preflight,queue,register,status,var— and 653 tests across 23 files (measured 2026-08-17; re-measure rather than quoting this forward).preflightis a deliberate refusal stub, not a port. Remaining work is tracked indocs/plans/FEATURE-MECCA-CLI-TYPESCRIPT-REWRITE-PLAN.mdin the platform repo.
Installation
Homebrew (macOS — pulls Node in as a dependency):
brew tap appmecca/tap https://gitlab.com/appmecca-public/appmecca-homebrew-tap.git
brew trust appmecca/tap
brew install appmecca # or: brew install mecca — same formulaBoth one-time steps are structural: brew tap user/repo resolves to GitHub and
this tap is on GitLab, so the URL must be explicit; and Homebrew 6 refuses to
load a formula from an untrusted third-party tap, so skipping brew trust makes
the install fail rather than prompt.
npm (requires Node ≥ 22.19):
npm install -g appmeccaEither route installs the mecca command. npx appmecca <command> works too.
⚠ The package is appmecca; the command is mecca — the bin map decides
that. On Homebrew, appmecca is an alias for the formula; neither route
installs a binary called appmecca, because that name belongs to the separate
platform-operator CLI distributed by git clone.
⚠ pip install appmecca does not work — nothing is published to PyPI. An
earlier revision of this README said the Python CLI was installable that way; it
was not, and the name is unclaimed there.
Development
npm install
npm run check # format:check + lint + typecheck + test — run this before pushing
npm run build # bundle to dist/mecca.js
npm test # vitest
npm run test:watchRun the CLI straight from source without building:
npm run smoke -- --helpLayout
src/
main.ts program shell, argv hoisting, global options, footer hook
argv.ts global-option hoisting with the `--` boundary
options.ts option factories — ONE definition per cross-command concept
context.ts per-invocation resolved context (env, group, credential, client)
output.ts output(data, json) — JSON purity
client/ HTTP client, error taxonomy, FastAPI detail normalisation
config/ mecca.conf (INI) + session.json readers/writers
render/ table, status colours, spinner, hints, footer, escaping, dotenv
errors/ handle.ts — the single exit-code authority
commands/ one module per command group
util/ small pure helpers
test/
unit/ per-module and per-command tests
meta/ convention guards — option uniformity, printed-hint
resolution, Python round-trip, transport invariants, parity
helpers/ runCli harness, transport-level mock APIConventions
These are contracts, not preferences. Each one exists because its absence caused a real bug in the Python CLI; the full rationale is in the plan's §3.2.
- Exit codes:
0ok ·1errors ·2genuine usage errors only ·4session expired ·5CLI upgrade required ·app execpropagates the remote exit code. Every exit funnels througherrors/handle.ts(enforced by lint). --jsonimplies--force, suppresses footer/hints/prompts, and prints a single JSON document to stdout — all human output goes to stderr.- Every GET carries
Cache-Control: no-cacheand a unique_tquery param. Both halves are required: the CDN's cache key includes the query string. - No request retries. Waiting is done with command-level polling loops.
- Untrusted server strings are escaped before printing (
render/escape.ts). - File formats (
~/.appmecca/mecca.conf,~/.appmecca/session.json) are a cross-tool contract shared with theappmeccaadmin CLI — atomic writes, 0600, verified against the real Pythonconfigparser.
Licence
MIT
