This repository now contains the local Codex plugin itself. It targets a self-managed GitLab Community Edition 15.9.3 server.
The implementation is intentionally conservative. It uses local Codex skills,
Python scripts, GitLab REST API v4, git, and optionally glab. It does not
use MCP servers, app connectors, OAuth workspace connectors, GitLab Duo,
GitLab external agents, GitLab Orbit MCP, GitLab-managed Codex credentials,
GitLab.com-only behavior, GitLab 16.x/17.x/18.x-only APIs, Premium/Ultimate
behavior, or OpenAI's GitHub connector.
- Plugin name:
gitlab-ce-15-9. - Target GitLab version: GitLab Community Edition 15.9.3.
- API base:
/api/v4. - Auth inputs: explicit script arguments, a user-level credential env file,
GITLAB_HOSTplusGITLAB_TOKEN, repo metadata, or user-level site profiles that reference local token environment variables. - Project identifiers: numeric project IDs or URL-encoded namespace/project paths.
- Write safety: writes default to dry-run and require explicit confirmation.
- Inline MR discussion safety: the plugin must not guess
position; unverified file/line requests fall back to plain MR notes.
See:
docs/facts/api-boundary.mdfor the allowed GitLab API surface.docs/facts/development-guidelines.mdfor current implementation rules.docs/facts/implementation-status.mdfor the current plugin inventory.docs/facts/validation-matrix.mdfor unit-tested and real-server validation status.
This is a local Codex plugin. Install or link this repository through the local Codex plugin mechanism you use for development, then configure a self-managed GitLab CE 15.9.3 host.
The easiest first-run path is to let the auth doctor create a local credential env file outside the repository:
python3 scripts/gitlab_auth.py doctor --repo . --init-credential-fileBy default this creates:
~/.config/codex-gitlab-plugin/credentials.env
Open that local file, fill in GITLAB_TOKEN=, save it, and rerun doctor.
Do not paste token values into chat. The credential file is a user-level local
file and must stay outside repositories.
The credential file supports:
GITLAB_HOST=https://gitlab.example.com
GITLAB_TOKEN=
GITLAB_PROJECT=group/projectFor shell-based setup, you can also create local environment values from
.env.example:
cp .env.example .envThe scripts do not load .env automatically. Export these values into the
shell, launcher, or environment that starts Codex if you want a newly opened
Codex session to reuse them.
Optional user-level profile metadata can live outside repositories at:
~/.config/codex-gitlab-plugin/profiles.json
Example:
{
"defaultProfile": "default",
"profiles": {
"default": {
"host": "https://gitlab.example.com",
"tokenEnv": "GITLAB_TOKEN"
}
}
}Optional repo-level metadata in .gitlab-codex.json can select a profile,
project, or remote without storing token values:
{
"profile": "default",
"project": "group/project",
"remote": "origin"
}Repo-level metadata is intentionally not a token store or host override. Use
explicit --host, GITLAB_HOST, or a user-level profile to choose the host.
Profile tokenEnv values are used only when the profile declares a host and
that host matches the resolved GitLab host.
Use one command to see what is missing before running GitLab workflows:
python3 scripts/gitlab_auth.py doctor --repo .The doctor command emits JSON for agent and UI consumption. It does not prompt for secrets and never prints token values. The output includes:
- current auth state such as
not_configured,missing_token,invalid_token,forbidden, orauthenticated. - missing inputs such as host, token, or project.
- safe token locations: the user-level credential env file,
GITLAB_TOKEN, a profiletokenEnvenvironment variable, or one-off--token. - guidance that tokens must stay local and must not be pasted into chat.
- whether the current token source can be reused by a new Codex session.
Supported token locations:
- Credential env file: best for first-run local setup across repositories.
GITLAB_TOKEN: best for a default local Codex environment.- Profile
tokenEnv: best for a site profile that names a local environment variable without storing the token in the profile. --token: useful for one command only; a new Codex session will not reuse it.
If doctor reports missing_token, configure the token locally and rerun the
same command. If it reports invalid_token, update the local token source. If
it reports forbidden, use a token that can access the project or configure a
project override. Do not paste tokens into chat.
Override the credential file location only when needed:
python3 scripts/gitlab_auth.py doctor --credential-env-file /path/to/credentials.envConservative token guidance:
- Read-only workflows: prefer
read_api. - Live writes such as issue creation or MR notes: use
apionly for the sandbox or project that needs it. - Do not commit
.envor token values.
First read-only smoke tests:
python3 scripts/gitlab_auth.py status --repo . --project "$GITLAB_PROJECT"
python3 scripts/discover_gitlab_context.py --repo . --no-mr-search
python3 scripts/gitlab_context.py --host "$GITLAB_HOST" --project "$GITLAB_PROJECT".codex-plugin/plugin.json
AGENTS.md
skills/
gitlab/
gl-create-issue/
gl-review-mr/
gl-address-comments/
gl-fix-ci/
gl-publish/
scripts/
auth_resolver.py
gitlab_auth.py
gitlab_api.py
discover_gitlab_context.py
gitlab_context.py
create_issue.py
issue_workflow.py
fetch_mr_context.py
inspect_pipeline.py
post_mr_note.py
mr_discussions.py
publish_workflow.py
tests/
test_auth_resolver.py
test_gitlab_auth.py
test_gitlab_api.py
test_inspect_pipeline.py
test_workflows.py
docs/
facts/
planning/
- Resolve and report authentication state as JSON without printing token values.
- Fetch read-only project, issue, and MR context.
- Infer local GitLab host, project, branch, and optional current MR from git remote context.
- Read/search/update/note/close/reopen GitLab issues with confirmed writes only.
- Fetch MR metadata, commits, diffs, discussions, and pipelines.
- List MR discussions, draft replies, and plan resolve/reopen actions with confirmed writes only.
- Inspect pipeline jobs and failed-job traces.
- Draft issue creation requests and execute them only with
--execute --confirm. - Draft MR notes and execute them only with
--execute --confirm. - Fall back to plain MR notes when inline position is not explicitly verified.
- Plan branch, commit, push, and draft MR creation; live publish requires explicit files plus
--execute --confirmand can bind execution to the reviewed dry-runplan_id.
Future-looking material is kept under docs/planning/:
docs/planning/roadmap.mddocs/planning/plugin-design.md
Planned but not yet implemented work includes broader fixture coverage, optional publishing workflows, real-server sandbox validation, and only later an MCP wrapper if scripts become too cumbersome.
Run from the repository root:
python3 -m unittest discover -s tests -v
python3 -m compileall -q scripts testsPlugin manifest validation uses the plugin-creator validator. Run it with a
Python environment that has PyYAML available:
PYTHONPATH=/path/to/pyyaml python3 /path/to/plugin-creator/scripts/validate_plugin.py .