{"id":51166790,"url":"https://github.com/altinity/acmctl","last_synced_at":"2026-06-26T20:01:53.861Z","repository":{"id":366379269,"uuid":"1200656539","full_name":"Altinity/acmctl","owner":"Altinity","description":"CLI tool for Altinity Cloud Manager API","archived":false,"fork":false,"pushed_at":"2026-06-21T14:07:32.000Z","size":190,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-06-21T16:08:05.680Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Altinity.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-03T17:12:13.000Z","updated_at":"2026-06-21T14:07:20.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Altinity/acmctl","commit_stats":null,"previous_names":["altinity/acmctl"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/Altinity/acmctl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Altinity%2Facmctl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Altinity%2Facmctl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Altinity%2Facmctl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Altinity%2Facmctl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Altinity","download_url":"https://codeload.github.com/Altinity/acmctl/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Altinity%2Facmctl/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34831250,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-26T02:00:06.560Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-26T20:01:52.891Z","updated_at":"2026-06-26T20:01:53.854Z","avatar_url":"https://github.com/Altinity.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# acmctl\n\nSlim CLI for the [Altinity Cloud Manager API](https://acm.altinity.cloud/docs/),\npaired with an `altinity-cloud` Claude Code skill for agent use.\n\n## Who uses what\n\n| Caller | Path |\n|---|---|\n| Human at a terminal | `acmctl` directly |\n| Bash script / CI | `acmctl` — stable interface, JSON output, single binary |\n| Agent in Claude Code | `altinity-cloud` skill — curl-direct with workflow recipes |\n\nThe skill and the CLI both hit the same API; pick whichever has lower\noverhead for your context. Agents save tokens by skipping `--help` and\ncalling `curl` directly with the patterns the skill provides; humans get\ndiscoverability and tab completion from `acmctl`.\n\n## Design\n\nacmctl exposes a small set of high-touch commands — login, env list/get,\ncluster list/get/launch/update/delete/temp-creds — plus a generic `raw`\npassthrough for the rest of the API. All output is JSON.\n\nThe full hand-curated mapping of all 269 endpoints is preserved in `_legacy/`\nas reference material — Go's toolchain ignores `_`-prefixed dirs, so it stays\ngreppable without participating in the build. Cherry-pick from there if a\nspecific tier-2 endpoint becomes hot enough to warrant typing.\n\n## The companion skill\n\nThe `altinity-cloud` skill lives in this repo at\n`skills/altinity-cloud/`. Contents:\n\n- `SKILL.md` — setup, common ops, conventions, per-tag index\n- `endpoints/\u003ctag\u003e.md` — 20 per-tag endpoint digests (clusters,\n  environments, billing, …)\n- `workflows.md` — multi-step recipes (launch-and-wait,\n  diagnose-slow-query, …)\n\nLoaded lazily by Claude Code — ~30 tokens of static context until\ntriggered. When triggered, ~3 KB of guidance loads. Per-tag files\nload only when the agent needs an endpoint outside the common-ops\nlist in SKILL.md.\n\n### Installing the skill\n\n`acmctl skills install` downloads the latest skill bundle (a\n`\u003cskill\u003e.zip` published by this repo's\n[Skill bundle](.github/workflows/skill-bundle.yml) GitHub Action)\nand copies it into the per-agent skills directory:\n\n```bash\nacmctl skills install                    # default: --scope global, --agent claude\nacmctl skills install --agent codex      # ~/.codex/skills/altinity-cloud/\nacmctl skills install --all              # claude + codex\nacmctl skills install --scope project    # ./.claude/skills/ (CWD)\nacmctl skills install --dry-run          # preview, no writes\nacmctl skills install --ref v1.0         # pin to a tagged release\n\nacmctl skills update                     # refresh whatever's installed\n```\n\n`install` errors if a local file would be overwritten (rerun with\n`--force`); `update` always overwrites — use it when you've made\nlocal edits you want reverted, or just to pull the latest content.\n\n## Installation\n\n```bash\ngo build -o acmctl .\ncp acmctl ~/bin/\n```\n\n## Profiles (multi-environment)\n\nA single `~/.acmctl.yaml` can hold multiple ACM environments —\nprod, dev, stage, …— and you switch between them per command or\nper shell.\n\n```yaml\n# ~/.acmctl.yaml\ndefault_profile: prod\nprofiles:\n  prod:\n    url: https://acm.altinity.cloud/api\n    token: \u003cprod token\u003e\n  dev:\n    url: https://acm.dev.altinity.cloud/api\n    token: \u003cdev token\u003e\n  stage:\n    url: https://acm.staging.altinity.cloud/api\n    token: \u003cstage token\u003e\n```\n\nManage profiles via:\n\n```bash\nacmctl config add-profile prod  --url https://acm.altinity.cloud/api\nacmctl config add-profile dev   --url https://acm.dev.altinity.cloud/api\nacmctl config add-profile stage --url https://acm.staging.altinity.cloud/api\n\nacmctl config list                # show all profiles + which is default\nacmctl config get                 # show the active profile's url + token state\nacmctl config use-profile dev     # change the default\nacmctl config remove-profile dev\n```\n\nSelect per command (highest precedence wins):\n\n1. `--profile \u003cname\u003e` flag\n2. `ACMCTL_PROFILE` env var\n3. `default_profile:` in the config\n4. fallback: the only profile, if exactly one is defined\n\n```bash\nacmctl --profile dev cluster list\nACMCTL_PROFILE=stage acmctl cluster list\n```\n\nTokens for `login` / `oauth` / `logout` apply to the **active**\nprofile. `acmctl logout --all` clears tokens from every profile.\n\nA legacy flat config (top-level `url`/`token`, no `profiles:`\nsection) is auto-loaded as a synthetic `default` profile and\nrewritten in the new layout on first save.\n\n## Authentication\n\nThree ways to populate a profile's token, in order of preference:\n\n### 1. 1Password-resolved API key (recommended for unattended use)\n\nMint a long-lived API key once via the ACM web UI (Account → API\ntokens), store it in 1Password, then resolve it at shell start:\n\n```bash\n# in ~/.acm.env or your shell rc, with ACM_API_KEY_OP_REF set to\n# the op:// reference of the item:\nexport ACM_API_KEY=$(op read --no-newline \"$ACM_API_KEY_OP_REF\")\n```\n\n`ACM_API_KEY` overrides any token saved in the active profile, so\nnothing needs to be on disk. This is what `iso-acm` (the sandboxed\nacm wrapper) uses.\n\n### 2. `acmctl oauth` — browser-based PKCE (interactive)\n\n```bash\nacmctl --profile prod oauth\n```\n\nOpens your default browser to the Auth0 sign-in for the configured\nAuth0 tenant, listens on a fixed loopback port (49152, fallback\n49153/49154) for the callback, and saves the resulting ACM session\ntoken to the active profile.\n\n\u003e **Status: blocked on an ACM backend change.** The full PKCE flow\n\u003e works against Auth0 (token exchange returns a valid id_token), but\n\u003e `POST /api/singleauth` rejects id_tokens minted by a Native CLI\n\u003e client with \"Bad credentials\" — the endpoint expects state from\n\u003e a flow ACM itself initiated server-side. Tracking:\n\u003e [issue #1](https://github.com/Altinity/acmctl/issues/1).\n\u003e Until that's resolved, `acmctl oauth` exits with a clear error;\n\u003e use the API-key path above instead.\n\nAuth0 setup required (one-time, by an admin of the\n`altinity.auth0.com` tenant):\n\n- Native application, **Token Endpoint Authentication Method: None**\n- Allowed Callback URLs:\n  ```\n  http://localhost:49152/cb\n  http://localhost:49153/cb\n  http://localhost:49154/cb\n  ```\n- Connections enabled: at least the SSO connection users sign in\n  with (`google-oauth2` and/or any enterprise SSO)\n\n### 3. `acmctl login` — email / password (legacy)\n\n```bash\nacmctl --profile prod login\n```\n\nPrompts for email + password. Most ACM tenants are SSO-only and\nwon't accept this; use `oauth` or the API-key path instead. Writes\nthe token to the active profile.\n\n`--token \u003ckey\u003e` non-interactively writes a known API key without\nprompting.\n\n### Sources, in precedence order\n\nFor each request, the URL and token are resolved separately:\n\n- **URL**: `--url` flag → `ACMCTL_URL` env → active profile's `url`\n- **Token**: `--token` flag → `ACM_API_KEY` env → active profile's `token`\n\n### Logging out\n\n```bash\nacmctl logout                    # clear active profile's token\nacmctl --profile dev logout      # clear a specific profile's token\nacmctl logout --all              # clear every profile's token\n```\n\n## Commands\n\n### Lifecycle\n\n```bash\nacmctl env list\nacmctl env get 37\n\nacmctl cluster list                       # all clusters\nacmctl cluster list --env 37              # filter by environment (client-side)\nacmctl cluster get 337\nacmctl cluster delete 337                 # keep resources\nacmctl cluster delete 337 --terminate     # tear down resources\nacmctl cluster temp-creds 337             # → {\"password\":\"...\"}\n```\n\n### Launch / Update (JSON body on stdin)\n\n```bash\ncat \u003c\u003cEOF | acmctl cluster launch 37\n{ \"name\": \"my-cluster\", \"nodeType\": \"s1\", \"version\": \"24.3\" }\nEOF\n\ncat update.json | acmctl cluster update 337\n```\n\n`launch`'s env-id arg is optional — falls back to `ACM_API_ENV_ID` env var.\n\n### Generic passthrough\n\n`acmctl raw \u003cMETHOD\u003e \u003cpath\u003e` covers everything else. Body is auto-detected:\n\n- **No body** — most GETs and DELETEs:\n  ```bash\n  acmctl raw GET /cluster/337/status\n  acmctl raw POST /cluster/337/backup\n  acmctl raw DELETE /cluster/337/0\n  ```\n- **JSON body** — pipe on stdin:\n  ```bash\n  echo '{\"name\":\"foo\"}' | acmctl raw POST /cluster/337\n  ```\n- **Form-urlencoded** — `-F key=value` (repeatable, supports `@file` to load):\n  ```bash\n  acmctl raw POST /cluster/337/query -F query='SELECT 1' -F user=admin\n  acmctl raw POST /cluster/337/kafka-configuration -F filename=k.xml -F xml=@./kafka.xml\n  ```\n\nCombining stdin JSON with `-F` flags is an error.\n\n## Output\n\nAll commands emit JSON to stdout. Pipe to `jq` for filtering / extraction. No\ntable or YAML formatting — agents and scripts both want JSON.\n\n## Restoring richer commands\n\nThe 269-endpoint hand-curated implementation lives in `_legacy/cmd/` and\n`_legacy/pkg/`. Go's build toolchain ignores directories starting with `_`, so\nthose files don't compile against the slim build but stay easy to grep.\n\nTo bring back, e.g., billing:\n\n```bash\ncp _legacy/cmd/billing.go cmd/\ncp _legacy/pkg/api/billing.go pkg/api/\n# Re-add helpers if needed: collectFieldFlags, flagsToParams (in _legacy/cmd/helpers.go)\ngo build ./...\n```\n\nSee `_legacy/README.md`.\n\n## Shell completion\n\n```bash\nsource \u003c(acmctl completion bash)\nacmctl completion zsh | source\nacmctl completion fish | source\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faltinity%2Facmctl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faltinity%2Facmctl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faltinity%2Facmctl/lists"}