{"_id":"@ecology91/glab-axi","_rev":"2-eb628dc23843d9849d6f656c0b1ad385","name":"@ecology91/glab-axi","dist-tags":{"latest":"0.7.1"},"versions":{"0.7.0":{"name":"@ecology91/glab-axi","version":"0.7.0","keywords":["gitlab","cli","agent","axi","toon","glab"],"author":{"name":"Christopher McKay"},"license":"MIT","_id":"@ecology91/glab-axi@0.7.0","maintainers":[{"name":"ecology91","email":"ecology91@proton.me"}],"homepage":"https://www.npmjs.com/package/@ecology91/glab-axi","bin":{"glab-axi":"dist/bin/glab-axi.js"},"dist":{"shasum":"21d72957c0a6a3963ce010967b98cdae3e2f08fe","tarball":"https://registry.npmjs.org/@ecology91/glab-axi/-/glab-axi-0.7.0.tgz","fileCount":106,"integrity":"sha512-HufG1xugF+HrPrQAZcPV7LlJ+FLSp8faBYlk3xZLsPahV9i/gt9fpUCjC75eie7dIluDJZYs29IGKYqFZt4q3w==","signatures":[{"sig":"MEYCIQDMd4c0G3G8E6xWXlVBWIpWlRvAL95B5bxTapIG8PESEgIhALPJJBnRygZWvM+7zsrAkKOUW3okhPWAyNUAbxEHqd36","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":602882},"type":"module","engines":{"node":">=20"},"gitHead":"5b0d43df71d80751c2f18b03ba416646d4875168","scripts":{"dev":"tsx bin/glab-axi.ts","lint":"eslint .","test":"vitest run","build":"tsc","format":"prettier --write .","test:watch":"vitest","skill:build":"tsx scripts/build-skill.ts","skill:check":"tsx scripts/build-skill.ts --check","format:check":"prettier --check .","prepublishOnly":"npm run build && npm run skill:build"},"_npmUser":{"name":"ecology91","email":"ecology91@proton.me"},"_npmVersion":"12.0.2","description":"AXI-compliant glab CLI wrapper for GitLab — token-efficient TOON output, contextual suggestions, idempotent mutations","directories":{},"_nodeVersion":"24.15.0","dependencies":{"yaml":"^2.5.0","axi-sdk-js":"^0.1.7","@toon-format/toon":"^2.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.0.0","eslint":"^9.0.0","vitest":"^3.0.0","globals":"^15.0.0","prettier":"^3.3.0","@eslint/js":"^9.0.0","typescript":"^5.7.0","@types/node":"^22.0.0","typescript-eslint":"^8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/glab-axi_0.7.0_1786186641278_0.7517810456236653","host":"s3://npm-registry-packages-npm-production"}},"0.7.1":{"name":"@ecology91/glab-axi","version":"0.7.1","description":"AXI-compliant glab CLI wrapper for GitLab — token-efficient TOON output, contextual suggestions, idempotent mutations","type":"module","homepage":"https://www.npmjs.com/package/@ecology91/glab-axi","keywords":["gitlab","cli","agent","axi","toon","glab"],"bin":{"glab-axi":"dist/bin/glab-axi.js"},"publishConfig":{"access":"public"},"scripts":{"build":"tsc","dev":"tsx bin/glab-axi.ts","test":"vitest run","test:watch":"vitest","lint":"eslint .","format":"prettier --write .","format:check":"prettier --check .","skill:build":"tsx scripts/build-skill.ts","skill:check":"tsx scripts/build-skill.ts --check","prepublishOnly":"npm run build && npm run skill:build"},"license":"MIT","author":{"name":"Christopher McKay"},"engines":{"node":">=20"},"dependencies":{"@toon-format/toon":"^2.3.0","axi-sdk-js":"^0.1.7","yaml":"^2.5.0"},"devDependencies":{"@eslint/js":"^9.0.0","@types/node":"^22.0.0","eslint":"^9.0.0","globals":"^15.0.0","prettier":"^3.3.0","tsx":"^4.0.0","typescript":"^5.7.0","typescript-eslint":"^8.0.0","vitest":"^3.0.0"},"_id":"@ecology91/glab-axi@0.7.1","_nodeVersion":"24.15.0","_npmVersion":"12.0.2","dist":{"integrity":"sha512-fccER/85kkGjJKX+sJ5vfeHaGnadxAUZ7ER4v2h1SK5Syq7TwNVyTwlHgUXiHm9Tauw4dsNfmNoAnivQRG9WVQ==","shasum":"5ff1395cc2b7e374c7c087cc65eb9f615d64a7fb","tarball":"https://registry.npmjs.org/@ecology91/glab-axi/-/glab-axi-0.7.1.tgz","fileCount":106,"unpackedSize":603791,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDLa46PketD4iQLo4HFN73DLYyw0VmS8vYfdWjxzrBuzQIgVPHOflfiYwr/RjfqNxYFwu5W7cB3tgPziEaofN5E5Cg="}]},"_npmUser":{"name":"ecology91","email":"ecology91@proton.me"},"directories":{},"maintainers":[{"name":"ecology91","email":"ecology91@proton.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/glab-axi_0.7.1_1786324335706_0.07841046848939381"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-08T10:57:21.140Z","modified":"2026-08-10T01:12:16.056Z","0.7.0":"2026-08-08T10:57:21.441Z","0.7.1":"2026-08-10T01:12:15.851Z"},"author":{"name":"Christopher McKay"},"license":"MIT","homepage":"https://www.npmjs.com/package/@ecology91/glab-axi","keywords":["gitlab","cli","agent","axi","toon","glab"],"description":"AXI-compliant glab CLI wrapper for GitLab — token-efficient TOON output, contextual suggestions, idempotent mutations","maintainers":[{"name":"ecology91","email":"ecology91@proton.me"}],"readme":"# glab-axi\n\nAn [AXI](https://agentskills.io)-compliant CLI that wraps the GitLab [`glab`](https://gitlab.com/gitlab-org/cli) CLI for autonomous agents.\nIt is the GitLab twin of [`gh-axi`](https://github.com/kunchenguid/gh-axi): token-efficient [TOON](https://toonformat.dev/) output, minimal default schemas, contextual next-step suggestions, idempotent mutations, and structured errors on stdout - everything an agent needs to operate GitLab from the shell without burning tokens or guessing.\n\n## Why\n\nAgents drive CLIs by reading stdout. Raw `glab`/REST output is verbose JSON full of fields an agent will never use, mutations error on already-satisfied state, and failures leak stack traces. `glab-axi` fixes all of that:\n\n- **TOON, not JSON** - ~40% fewer tokens, still readable.\n- **Minimal schemas** - lists default to 3-5 fields; ask for more with `--fields a,b,c`.\n- **Pre-computed aggregates** - pipeline views report `checks: N passed, M failed, K running` and an at-a-glance verdict, so an agent never has to count jobs.\n- **Stuck pipelines are named, not just slow** - a pending job no active runner can take is reported in a `stuck` section with the reason, so a poller can tell \"blocked, escalate\" from \"still running, keep waiting\".\n- **Real totals, not guesses** - list output reads GitLab's own count (`count: 30 of 847 total`) instead of restating the `--limit` it was just given.\n- **Bounded, greppable CI logs** - `ci log` strips ANSI noise and truncates to a token-safe tail; a truncated trace also spills the full log to a local file the agent can grep instead of paying for it in context.\n- **Idempotent mutations** - closing a closed issue or merging a merged MR is a no-op with exit 0.\n- **Definitive empty states** and **contextual `help[]` suggestions** on every list and mutation.\n- **Structured errors on stdout** - actionable, and they never leak the underlying tool's name.\n- **Fails loud on a typo** - an unrecognized flag or subcommand exits 2 naming what was wrong and listing the valid set, rather than being dropped. A silently ignored `--stat closed` would hand back open issues at exit 0, and an agent cannot tell that from the filtered result it asked for.\n\n## Quick Start\n\nInstall the Agent Skill globally from the root of an authenticated checkout:\n\n```sh\nnpx skills add . --skill glab-axi -g\n```\n\nYou can also install directly from the private self-hosted GitLab project:\n\n```sh\nnpx skills add https://gitlab.example.com/group/glab-axi.git --skill glab-axi -g\n```\n\nCopy your private project's clone URL and keep its `.git` suffix. Configure Git credentials for that host before running the command: the installer disables credential prompts while cloning, so it cannot stop to ask for a username or password.\n\nThe flags keep the install narrow and guided:\n\n- `-g` selects global scope, making the skill available across projects.\n- `--skill glab-axi` installs only the user skill and excludes the maintainer-only `glab-axi-release` skill.\n- Leaving off the installer's `-y` keeps the human agent, installation-method (when applicable), and final confirmation prompts. When the installer detects that an AI agent is running it becomes non-interactive automatically, so those prompts will not appear in an agent-driven shell.\n\nThe installed [Agent Skill](https://agentskills.io) invokes the exact released `@ecology91/glab-axi@0.7.1` package on demand, while commands and follow-up suggestions keep using the `glab-axi` executable name. It does not depend on a global npm CLI install.\nYou still need the GitLab [`glab`](https://gitlab.com/gitlab-org/cli) CLI installed and authenticated (`glab auth login`), and Node.js 20 or newer.\nFor a self-hosted instance, authenticate `glab` against that host. Use `-R <host>/group/project` for a project target, `--host <host>` for host-level operations, or `GITLAB_HOST=<host>` to select the host for a project already resolved from a hostless `-R` or the current GitLab remote (see [Targeting a project](#targeting-a-project)).\n\nThe skill is not a user-facing slash command (`user-invocable: false`).\nJust ask for anything that touches GitLab - filing an issue, reviewing a merge request, chasing a failed pipeline, cutting a release - and the agent loads the skill on its own when it recognizes the task.\nIt loads on demand rather than sitting in the context window, so it costs no per-session tokens, and it works in any agent that supports the skill format.\n\n## Other ways to install\n\nThe scoped CLI can also run without a global install, and it can add ambient\nsession context when you opt in.\n\n### Zero setup\n\nRun a specific published version without a global install:\n\n```sh\nnpx -y @ecology91/glab-axi@0.7.1 mr --help\n```\n\n### Global npm install\n\nA global install gives you the `glab-axi` command directly, which is handy for running it yourself:\n\n```sh\nnpm install -g @ecology91/glab-axi\nglab-axi issue list\n```\n\nThe generated skill's versioned scoped request does not depend on the global install. The bare command stays on the globally installed version until you upgrade it.\n\nCompare the installed command against what is published:\n\n```sh\nglab-axi --version\nnpm view @ecology91/glab-axi version\n```\n\nIf those differ, upgrade the global copy in place:\n\n```sh\nnpm install -g @ecology91/glab-axi@latest\n```\n\nOr, if you only use the skill and no [session hook](#session-hook) needs the bare `glab-axi` command, drop the global copy:\n\n```sh\nnpm uninstall -g @ecology91/glab-axi\n```\n\n### Session hook\n\nWant ambient GitLab context - the current project's open issues and merge requests - in every agent session, instead of loading on demand?\nWith the CLI installed globally, opt into the hook:\n\n```sh\nglab-axi setup hooks\n```\n\nThat installs an idempotent `SessionStart` hook for Claude Code, Codex, and OpenCode.\nEach session then opens with a compact dashboard of the current project, so the agent can act immediately with no invocation needed.\nRestart your agent session afterwards so the new hook takes effect; re-running the command repairs the hook's path after a reinstall.\n\n## Usage\n\nRun with no arguments for a dashboard of the current project (open issues, open merge requests, suggested next commands):\n\n```sh\nglab-axi\n```\n\nIf no GitLab project resolves, it prints `project: none` with a hint instead of guessing. If a request to the server fails, the affected section renders `unavailable - <reason>` rather than a false `0 open` - a real zero and \"could not ask the server\" are different facts.\n\nDrill in command-first:\n\n```sh\nglab-axi issue list --state opened\nglab-axi issue view 12 --comments\nglab-axi issue links 12\nglab-axi mr view 42 --full\nglab-axi mr view 42 --reviews\nglab-axi mr diff 42\nglab-axi ci status --branch main\nglab-axi ci log 46450 --full\n```\n\nEvery response ends with `help:` hints for logical next steps. Run `glab-axi --help` for global flags, or `glab-axi <command> --help` for per-command usage.\n\n### Commands\n\n| Command   | What it does |\n|-----------|--------------|\n| (none)    | Dashboard of the current project |\n| `issue`   | list / view / links / create / edit / close / reopen / comment |\n| `mr`      | list / view / create / update / merge / approve / unapprove / checks / diff / comment (by IID; `view`, `merge`, `checks`, and `diff` also take a full MR URL) |\n| `ci`      | list / view / status / jobs / watch / log / run / retry / cancel (pipelines; `watch` blocks until a pipeline finishes and exits non-zero if it did not succeed) |\n| `project` | view / list / create / delete (`delete` names its target and requires `--yes`) |\n| `repo`    | create-file / create-branch (writes the project's git contents) |\n| `label`   | list / create / edit / delete |\n| `variable`| list / get / set / delete (plain, unmasked CI/CD variables) |\n| `secret`  | list / set / delete (masked & protected CI/CD variables; `list` never reveals values) |\n| `release` | list / view / create / edit / delete |\n| `search`  | issues / mrs / projects |\n| `api`     | raw GitLab REST passthrough with a `{project}` placeholder |\n| `auth`    | status / git-credential (host-scoped credentials and install introspection - see [Credentials](#credentials)) |\n| `config`  | get (read-only configuration introspection; refuses credential keys) |\n| `setup`   | install agent SessionStart hooks |\n\nIssues and merge requests are addressed by their project-scoped **IID** (the number in the URL).\n\n### Targeting a project\n\n`glab-axi` is fully generic - it works against gitlab.com or any self-hosted GitLab. The target project is resolved in priority order:\n\n1. `-R [host/]group/project` placed **after** the command (e.g. `glab-axi mr list -R gitlab.example.com/group/project`). A two-segment value is always `group/project`, even when the group name contains a dot (e.g. `firstname.lastname`, the standard username shape on LDAP/SSO instances); only a 3+-segment value can lead with a host, and then only when it's a host `glab` is already configured for or (as a last resort) contains a dot. Nested group paths are supported.\n2. The `origin` git remote of the current repository.\n\nA git remote only resolves to a project when its host is one the `glab` CLI is actually configured for, or when `GITLAB_HOST` explicitly names that host. A remote on a different forge (GitHub, Bitbucket, etc.) resolves to no project rather than a guess.\n\nThe HOST follows explicit identity rather than ambient precedence. A host carried by `-R` cannot be redirected by `GITLAB_HOST`; `--host` and a host carried by `-R` must agree or the command refuses. When `-R` carries no host, `--host` wins over `GITLAB_HOST`, which may otherwise override the git remote. `--host` alone (no `-R`) targets a self-hosted instance for host-level operations that have no project - `search projects`, `project list`, `api user` - without a project in scope; a project-scoped command still fails loud if no project resolved. A host-only `-R <host>` (naming a host but no group/project) is rejected with a `VALIDATION_ERROR` pointing at `--host`, rather than silently falling through to the default host.\n\n`mr view`, `mr merge`, `mr checks`, and `mr diff` accept a full merge request URL in place of the IID (e.g. `glab-axi mr merge https://gitlab.example.com/group/subgroup/project/-/merge_requests/42`). The URL's host, full nested project path, and IID are one identity and override ambient remote or `GITLAB_HOST` state. Explicit `-R` or `--host` values must match that URL; contradictory identities are rejected instead of resolved by precedence.\n\n`mr merge --sha <40-hex>` binds an immediate merge to the reviewed source head. It checks the current head, still sends GitLab's server-side `sha` compare-and-swap to close the race, and distinguishes a fresh guarded merge, already-merged exact head, stale head, already-merged different head, and contradictory post-merge response. `--sha` cannot combine with `--rebase` (which creates a new head) or `--auto` (which defers the merge beyond the reviewed instant).\n\nIf GitLab reports a successful guarded merge but omits the source-head fields, the CLI performs one canonical MR read. A matching merged head returns the ordinary verified receipt with `source_head_sha` and `head_match: true`. If independent head evidence remains unavailable, the mutation still returns success with `state: merged`, the requested `reviewed_head_sha`, and `head_verification: unavailable`; it deliberately omits `source_head_sha` and `head_match`. Callers must treat that as “merge completed, independent head receipt unavailable,” not as a verified head match. The already-merged preflight remains stricter and refuses success unless GitLab records the exact reviewed head.\n\n`mr create` accepts native `--source-branch`/`--target-branch` and the `--head`/`--base` aliases. For a same-host cross-project MR, an explicit `-R` identifies the target and `--source-project <id|[host/]group/project>` identifies the source (including an existing fork). The command resolves and verifies both projects on one GitLab host, checks for an already-open MR with the exact project IDs and branches, then POSTs through the source project with the target's numeric ID. A repeat returns `already: true` rather than creating a duplicate, and the create receipt must report the resolved project IDs. It creates a merge request between existing projects; it does not create a fork.\n\n`mr view --reviews` adds approval state (who approved, approvals given/required) and discussion-thread resolution counts. GitLab review semantics are approvals, unapproval, comments, and resolving discussions; there is no direct GitHub requested-changes equivalent, so this CLI deliberately does not emulate an `mr review` verdict. `mr diff` prints a bounded per-file summary (path, status, `+`/`-` line counts) by default; `--full` emits the complete reconstructed unified diff. `mr merge --auto` sets GitLab's merge-when-pipeline-succeeds: it merges immediately if there is no pipeline (or it already passed), otherwise it defers and reports the scheduled state instead of a merge commit SHA; it cannot combine with `--rebase`. When GitLab refuses a merge, the error names the specific cause plus the command that clears it. `mr list` and `mr view` accept the same `--jq`/`--json` escape hatches as `api` (see below).\n\n```sh\n# explicit host + project\nglab-axi issue list -R gitlab.example.com/group/subgroup/project\n\n# project from the git remote, host overridden by env\nGITLAB_HOST=gitlab.example.com glab-axi mr list\n\n# host-level op on a self-hosted instance, no project involved\nglab-axi search projects backend --host gitlab.example.com\n```\n\n### Projects and their repositories\n\n`project` addresses the project entity; `repo` writes its git contents.\nTogether they cover a project's whole lifecycle without dropping to `api`.\n\n```sh\n# create a project, seed its default branch, and open a feature branch with a diff\nglab-axi project create my-group/my-service --readme\nglab-axi repo create-file .gitlab-ci.yml -R my-group/my-service --content-file ci.yml\nglab-axi repo create-branch feature-x -R my-group/my-service\nglab-axi repo create-file src/app.ts -R my-group/my-service --branch feature-x --content \"export const app = 1;\"\n\n# tear it down again\nglab-axi project delete my-group/my-service --yes\n```\n\n`repo create-file` commits a single file directly to `--branch` (defaulting to the project's default branch), creating that branch when the repository is still empty.\nContent comes from `--content`, `--content-file`, or piped stdin.\n`repo create-branch` branches from `--ref` (also defaulting to the default branch).\nBoth are idempotent: an existing file or branch is a no-op (`already: true`), never an overwrite.\n`repo create-file` writes UTF-8 text only; binary content (images, compiled assets) is rejected with an actionable error rather than silently corrupted.\n\n`project delete` is destructive, so it takes its target as an explicit positional (a numeric project id, or a `[host/]group/project` path) rather than falling back to the resolved project, and it requires `--yes` - it never prompts.\nDeleting an already-absent project is a no-op (`already_absent: true`).\nThe reported outcome is read back from the server, not assumed: on instances with delayed project deletion enabled the project isn't purged immediately, it's renamed and marked for deletion, so the response reports `status: scheduled` plus `purge_after` instead of `status: ok` (deleting an already-scheduled project again is also a no-op, `already: true`).\n\nGitLab project creation has no direct equivalent to GitHub's clone/template flags in this wrapper. `project create --clone` and `--template` remain explicit validation refusals rather than silently claiming unsupported behavior.\n\n### Raw API passthrough\n\nAnything the dedicated commands do not cover, reach via `api`. The `{project}` placeholder is replaced with the resolved, URL-encoded project id:\n\n```sh\nglab-axi api projects/{project}/members\nglab-axi api POST projects/{project}/labels --raw-field name=urgent --raw-field color=#d9534f\nglab-axi api projects/{project}/pipelines --paginate\n```\n\nBy default `api` emits TOON with noisy fields stripped. To pull a single field or feed the response to your own tooling, use `--jq` or `--raw`, which both operate on the raw, unmodified JSON:\n\n```sh\nglab-axi api projects/{project}/merge_requests/5 --jq .state          # -> opened\nglab-axi api projects/{project}/merge_requests/5 --jq .sha             # head SHA\nglab-axi api projects/{project} --raw | jq .default_branch\n```\n\n`--jq <expr>` applies a jq expression (raw output, like `jq -r`) and needs the `jq` binary on `PATH`; `--raw` (alias `--json`) prints the JSON response verbatim and needs nothing. When both are passed, `--jq` wins.\n\n`mr list` and `mr view` expose the same `--jq`/`--json` flags, operating on GitLab's raw response and bypassing schema flags like `--full`/`--comments`/`--reviews`:\n\n```sh\nglab-axi mr view 42 --jq .detailed_merge_status\nglab-axi mr view 42 --jq '{sha: (.sha // .diff_refs.head_sha), target_branch, source_project_id, target_project_id, state, detailed_merge_status, merge_commit_sha, squash_commit_sha}'\nglab-axi mr list --state opened --jq '.[].iid'\n```\n\nThe `mr view --json` response is GitLab's raw MR object. The scalar fields in the example are the stable pre/post evidence surface: current source head, target branch, source and target project IDs, state, detailed merge status, and merge/squash commit SHAs. Callers must require scalar output and validate any commit value as exactly 40 hexadecimal characters. `--jq` uses the external `jq` binary; use `--json` and parse the raw JSON yourself when `jq` is unavailable.\n\n### Credentials\n\nCloning or pushing a private project over HTTPS needs a credential.\n`auth` reads the one the GitLab CLI already manages, so nothing has to parse its config file - an internal detail that can change without warning.\n\nA credential is **host-scoped**, so `auth` is host-addressed like the other host-level operations: pass `--host <host>`, or let a `-R host/group/project` or the git remote supply it.\n\n`auth status` answers whether a working credential exists, and never prints it:\n\n```sh\nglab-axi auth status\n```\n\n`auth status` is diagnostic and intentionally exits successfully even when it reports an absent or unavailable credential. For a readiness gate that must fail when authentication does not work, use an authenticated read: `glab-axi api user --host <host>`.\n\n```\ninstall:\n  bin: /usr/bin/glab\n  version: 1.53.0\n  config_file: ~/.config/glab-cli/config.yml\n  default_host: gitlab.com\nhosts[2]{host,token,account}:\n  gitlab.com,absent,no credential\n  gitlab.example.com,present,someuser\nhelp[3]:\n  Default host gitlab.com has no working credential, so any command omitting --host targets it - pass `--host <host>` explicitly, or change the default\n  ...\n```\n\n`account` is who the credential actually authenticated as, not merely what is on disk - a stale token reports `unavailable - <reason>` rather than a misleading green.\n`token` reports **presence only**, never any part of a value.\n\nPass `--host <host>` to scope the report to one host; without it, every configured host is reported.\n\n#### Diagnosing setup\n\nThe `install` block answers a question nothing else on the agent surface can: **which binary is this actually driving, and which configuration is it reading**.\n\nThat matters because the answer is not always the one you expect.\nA machine with two installs of the GitLab CLI on `PATH` - say an OS package early and a much newer snap late - silently drives whichever comes first, with its own config file and its own default host.\nWhen more than one is found, a `shadowed` section names them all:\n\n```\nshadowed[2]{path,version,active}:\n  /usr/bin/glab,1.36.0,yes\n  /snap/bin/glab,1.108.0,no\n```\n\nThe section only appears when there is a genuine conflict, so seeing it at all *is* the finding.\nOne binary reachable through several `PATH` entries (`/usr/bin` and `/bin` on a merged-`usr` system) is one install, not a conflict, and is not reported as one.\n\n`default_host` is the other half.\nIt is the host a command that omits `--host` lands on, so a default pointing at an instance you never authenticated against means a single call that forgets the flag aims at a dead account.\nWhen that host has no working credential, `auth status` says so in `help[]` rather than leaving it to be inferred.\n\n`auth git-credential` is a [git credential helper](https://git-scm.com/docs/gitcredentials): it speaks git's `key=value` protocol on stdin and stdout, so it can be handed straight to git.\n\n```sh\ngit -c credential.helper='!glab-axi auth git-credential' \\\n  clone https://gitlab.example.com/group/project.git\n```\n\nTwo things to know about it:\n\n- **It is the only surface that emits a password**, because that is what the git protocol requires. It is meant for git to consume, not for an agent to read, and whatever invokes it owns keeping that output out of logs, transcripts, and status lines. Use `auth status` whenever the question is \"do I have a credential\" rather than \"give me the credential\".\n- **It does not emit TOON, and stays silent on failure.** git parses its stdout as credential fields and treats anything else as malformed, so a structured error would break the operation the verb exists to serve. The exit code carries the outcome; `auth status` is where a readable diagnosis lives.\n\nReading is all it does - `store` and `erase` pass through untouched, and nothing here writes, rotates, or caches a credential.\n\nNote that `GITLAB_TOKEN`, when set, answers for **every** host and overrides the per-host store, so a credential reported under one host may be that environment token rather than an entry for that host.\n\n### Configuration\n\n`config get` reads the GitLab CLI's own configuration, reporting which scope answered:\n\n```sh\nglab-axi config get host                                  # global\nglab-axi config get api_host --host gitlab.example.com    # per-host\n```\n\n```\nconfig:\n  key: host\n  value: gitlab.com\n  scope: global\n```\n\nA key that is genuinely unset reads `value: unset`; a read that *failed* errors instead, because \"unset\" and \"could not read\" are opposite facts.\n\n**Credential keys are refused.** Any key whose name contains `token` is rejected before the read happens - the underlying CLI will happily print a live token, and this one never does.\nUse `auth status` for the question that actually needs answering: whether a credential is present and still works.\n\n`config` is read-only; `config set` and `config list` are deliberately refused, the latter because a bulk dump would carry the per-host token to stdout.\n\n## Development\n\n```sh\nnpm install\nnpm run dev -- issue list      # run from source via tsx\nnpm run build                  # tsc -> dist/\nnpm test                       # vitest (unit tests mock the glab layer; no network)\nnpm run lint\nnpm run format:check\nnpm run skill:check            # fail if SKILL.md is stale\n```\n\nThe skill shipped in the npm package is generated from the CLI's own help (`npm run skill:build`), and CI fails if it has drifted - commit the regenerated file.\n\nArchitecture notes live in [`AGENTS.md`](./AGENTS.md). The short version: every shell-out goes through `src/gl.ts`, which targets GitLab via `glab api` (REST passthrough) - the host through `GITLAB_HOST`, the project through its URL-encoded path. `src/commands/mr.ts` is the reference template for the per-domain command files.\n\n## Releasing\n\nEvery notable change is recorded under `## [Unreleased]` in [`CHANGELOG.md`](./CHANGELOG.md), following the [Keep a Changelog](https://keepachangelog.com/) convention.\n\nThis managed fork publishes the public scoped package `@ecology91/glab-axi` from a reviewed, clean commit. The executable remains `glab-axi`. The initial fork release is `0.7.0`, derived from upstream `glab-axi` `v0.6.0` (`102871a`) plus the capability and package-identity changes recorded in this changelog.\n\nPublishing is an explicit maintainer action, not a GitHub release side effect. Reverify `npm whoami`, confirm `npm view @ecology91/glab-axi version` is absent or older, run the full validation and packed-tarball checks, commit and push the release, then publish with `npm publish --access public` from that verified commit. Finally install into a clean temporary prefix and prove both `glab-axi --version` and `glab-axi mr --help` match the published contract.\n\nThe complete command-by-command procedure lives in [`skills/glab-axi-release/SKILL.md`](./skills/glab-axi-release/SKILL.md). It is the release source of truth.\n\n## License\n\n[MIT](./LICENSE) (c) Christopher McKay\n","readmeFilename":"README.md"}