Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Bun-based monorepo with workspace packages under `packages/*`. The marketing sit
| Package | Role | Published |
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------- | --------------- |
| `@getdevintern/code` | CLI for task automation (`devintern`): Jira + multi-PM support, configurable AI agent | yes |
| `@getdevintern/pm` | CLI for PM task/story creation (`devpm`): supports Jira, Linear, Trello, Azure DevOps, Asana, GitHub Issues, Markdown | yes |
| `@getdevintern/pm` | CLI for PM task/story creation (`devpm`): supports Jira, Linear, Trello, Azure DevOps, Asana, GitHub Issues, GitLab, Markdown | yes |
| `@devintern/pm-desktop` | Electron desktop app for `@getdevintern/pm`: multi-ticket AI task creation for your tracker | no, application |
| `@devintern/agent-harness` | Shared agent harness abstraction | no, source-only |
| `@devintern/dashboard-ui` | Local observability dashboard UI (Vite + React), bundled into `@getdevintern/code` at build time | no, source-only |
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Bun-based monorepo with workspace packages under `packages/*`. The marketing sit
| Package | Role | Published |
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------- | --------------- |
| `@getdevintern/code` | CLI for task automation (`devintern`): Jira + multi-PM support, configurable AI agent | yes |
| `@getdevintern/pm` | CLI for PM task/story creation (`devpm`): supports Jira, Linear, Trello, Azure DevOps, Asana, GitHub Issues, Markdown | yes |
| `@getdevintern/pm` | CLI for PM task/story creation (`devpm`): supports Jira, Linear, Trello, Azure DevOps, Asana, GitHub Issues, GitLab, Markdown | yes |
| `@devintern/pm-desktop` | Electron desktop app for `@getdevintern/pm`: multi-ticket AI task creation for your tracker | no, private |
| `@devintern/agent-harness` | Shared agent harness abstraction | no, source-only |
| `@devintern/dashboard-ui` | Local observability dashboard UI (Vite + React), bundled into `@getdevintern/code` at build time | no, source-only |
Expand Down
4 changes: 2 additions & 2 deletions docs/code/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ You can run `devintern` from any subdirectory of your project and it will find t

## Required Configuration

The active task tracker is set with `TASK_TRACKER` (defaults to `jira`). Supported values: `jira`, `linear`, `trello`, `asana`, `azure-devops`, `github`, `markdown`.
The active task tracker is set with `TASK_TRACKER` (defaults to `jira`). Supported values: `jira`, `linear`, `trello`, `asana`, `azure-devops`, `github`, `gitlab`, `markdown`.

### Jira (default)

Expand Down Expand Up @@ -219,7 +219,7 @@ The active tracker is read from the `TASK_TRACKER` environment variable (default
- `todoStatus`: Status to reset to if implementation fails (e.g., "To Do", "Backlog")
- `storyPointsField`: Custom field ID for story points (e.g., `"customfield_10016"` for Jira); auto-discovered if omitted

**Supported trackers:** `jira`, `linear`, `trello`, `asana`, `azure-devops`, `github`, `markdown`.
**Supported trackers:** `jira`, `linear`, `trello`, `asana`, `azure-devops`, `github`, `gitlab`, `markdown`.

**Backward compatibility:** Existing Jira-only files using the legacy top-level `projects` key continue to work without any changes.

Expand Down
142 changes: 142 additions & 0 deletions docs/code/gitlab-integration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
---
title: "Implement GitLab Issues with @devintern/code"
sidebarLabel: "GitLab Integration"
description: "Fetch GitLab issues (cloud or self-hosted), track status labels, implement with your coding agent, and post results back."
section: "Code"
order: 6
dateModified: 2026-08-24
tags: ["gitlab", "gitlab-self-hosted", "devintern/code", "integration"]
---

# Implement GitLab Issues with @devintern/code

@devintern/code can implement work directly from GitLab issues: fetch issue details and comments, run a feasibility check, move status labels, execute your AI agent, commit changes, and post results back on the issue. Both **GitLab Cloud** and **self-hosted instances** are supported.

## Prerequisites

- [Bun](https://bun.sh) and `@getdevintern/code` installed globally
- GitLab personal access token with the `api` scope
- Git repository for your project

## Setup

### 1. Set the task tracker

In `.devintern-code/.env`:

```bash
TASK_TRACKER=gitlab
```

### 2. Add GitLab credentials

```bash
# Cloud default — omit for gitlab.com; set for self-hosted:
GITLAB_BASE_URL=https://gitlab.example.com

GITLAB_TOKEN=glpat_xxxxxxxxxxxx
GITLAB_PROJECT=group/sub/repo
```

- `GITLAB_BASE_URL` — instance root URL. Omit for GitLab Cloud (`https://gitlab.com` is the default). Self-hosted instances keep their protocol, so internal `http://` hosts work.
- `GITLAB_TOKEN` — personal access token from `/-/user_settings/personal_access_tokens` on the same instance, with the **`api`** scope.
- `GITLAB_PROJECT` — project path (`group/repo`, subgroups allowed: `group/sub/repo`) or a numeric project ID.

### 3. Configure status labels

Like GitHub Issues, GitLab has no built-in workflow states that map cleanly across teams, so @devintern/code maps statuses to labels. Create the labels in your project, then configure them in `.devintern-code/settings.json` using the project path as the key:

```json
{
"gitlab": {
"projects": {
"acme/team/webapp": {
"inProgressStatus": "In Progress",
"todoStatus": "To Do",
"prStatus": "In Review"
}
}
}
}
```

To keep statuses mutually exclusive, also list them in `.devintern-code/.env`:

```bash
GITLAB_STATUS_LABELS=To Do,In Progress,In Review
```

When a status changes, @devintern/code adds the target label and removes the other labels in this list. Transitioning to `closed` or `done` closes the issue instead of applying a label; moving back to an open status reopens it.

## Running an issue

Pass an issue number, `#number`, a `group/sub/repo#123` reference, or a full issue URL:

```bash
# Issue number
devintern 123 --create-pr

# Full issue URL (self-hosted URLs work too)
devintern https://gitlab.com/acme/team/webapp/-/issues/123 --create-pr
```

This workflow:

1. Fetches the issue body, labels, and comments
2. Runs a feasibility assessment (skippable with `--skip-clarity-check`)
3. Applies the `inProgressStatus` label (unless `--skip-comments` is set)
4. Creates a feature branch, runs your agent, commits, and optionally opens a PR
5. Applies the `prStatus` label after PR creation
6. Posts implementation or assessment comments on the issue

## Batch processing with --query

Select multiple issues with familiar qualifiers — @devintern/code translates them to GitLab's [list issues](https://docs.gitlab.com/ee/api/issues.html#list-project-issues) filters. Queries are always scoped to `GITLAB_PROJECT`:

```bash
devintern --query "is:open label:bug" --create-pr
devintern --query 'is:open "login flow"' --create-pr
devintern --query "assignee:@me" --create-pr
```

Supported qualifiers: `is:open` / `is:closed`, `label:name` (repeatable), `assignee:@me` / `assignee:username`, `updated:>=<date>`. Anything else is free-text search.

The first 100 matching issues are processed in sequence.

## Story points estimation

GitLab issues have no estimation field, so `--estimate` runs in comment-only mode: the analysis is posted (or updated) as an issue comment with the suggested points, reasoning, risks, and unclear areas.

## Token scopes for Cloud vs. self-hosted

| Scope | Needed for |
| ----- | ---------- |
| `api` | Full read/write access (recommended) |
| `read_api` | Read-only setups (fetching issues works; posting comments and label transitions will fail) |

Self-hosted tokens only exist on their own instance — a gitlab.com token cannot authenticate against your on-premises GitLab and vice versa.

## Limitations

- **Attachments:** files embedded in issue bodies (`/uploads/...` links) are downloaded for the agent using your token; other external links stay as references.
- **Status labels:** labels named in `settings.json` must already exist in the project. The error message lists available labels when one is missing.
- **Comments:** use `--skip-comments` to skip issue comments and label transitions for a run.
- **Pull requests:** PR creation targets GitHub/Bitbucket remotes today; GitLab merge-request automation is not part of this integration yet.

## Troubleshooting

**"Missing required GitLab credentials"**

Ensure `GITLAB_TOKEN` and `GITLAB_PROJECT` are set in `.devintern-code/.env`.

**"GitLab API error (401)"**

Token rejected: check that it was created on the same instance as `GITLAB_BASE_URL`, has not expired, and carries the `api` scope.

**"Label \"In Progress\" not found in the project"**

Create the label in your project (Issues → Labels) or change the status names in `settings.json` to match existing labels.

**Old status labels pile up on issues**

Set `GITLAB_STATUS_LABELS` to the full list of status label names so transitions remove the previous status.
2 changes: 1 addition & 1 deletion docs/pm/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ dateModified: 2026-08-08

Set `TASK_TRACKER` to choose your PM tool. Defaults to `jira` if not specified.

Supported backends: `jira`, `linear`, `trello`, `azure-devops`, `asana`, `github`, `markdown`
Supported backends: `jira`, `linear`, `trello`, `azure-devops`, `asana`, `github`, `gitlab`, `markdown`

```bash
TASK_TRACKER=jira
Expand Down
113 changes: 113 additions & 0 deletions docs/pm/gitlab-integration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
---
title: "Create GitLab Issues with @devintern/pm"
sidebarLabel: "GitLab Integration"
description: "File well-specified GitLab issues from AI drafts on gitlab.com or a self-hosted instance."
section: "PM"
order: 7
---

# Create GitLab Issues with @devintern/pm

@devintern/pm creates GitLab issues directly from AI-generated stories and tasks. Setup takes a few minutes: you need a Personal Access Token and a target project. Both **GitLab Cloud (gitlab.com)** and **self-hosted instances** are supported.

## How It Works

@devintern/pm uses the [GitLab REST API v4](https://docs.gitlab.com/ee/api/issues.html) to create and update issues in a project you configure.

- New issues appear under the project's **Issues** tab
- Stories, bugs, tasks, and epics map to issue labels (see below)
- Subtasks become linked issues with a task list on the parent issue
- Epic linking is not supported: project issues have no native parent hierarchy, so the epic linking step is skipped in interactive mode and the `--epic` flag is ignored

## Cloud vs. Self-Hosted

| Flavor | `GITLAB_BASE_URL` | Notes |
| --------------------- | ------------------------- | ----------------------------------------------- |
| GitLab Cloud | omit (default `https://gitlab.com`) | Works out of the box |
| Self-managed instance | e.g. `https://gitlab.example.com` | Protocol is kept; `http://` internal hosts work |

## Setup

### 1. Set the backend

In your `.devintern-pm/.env`:

```bash
TASK_TRACKER=gitlab

# Cloud (default) — omit or leave commented:
# GITLAB_BASE_URL=https://gitlab.com

# Self-hosted — set your instance root URL:
GITLAB_BASE_URL=https://gitlab.example.com
```

`GITLAB_BASE_URL` is the instance root, without `/api/v4`.

### 2. Create a Personal Access Token

1. Sign in to your GitLab instance
2. Go to **User Settings → Access Tokens** (`/-/user_settings/personal_access_tokens`)
3. Create a token with the **`api`** scope (read + write). A read-only setup needs `read_api`, but @devintern/pm creates and updates issues, so `api` is required.
4. Copy the token (tokens starting `glpat-…` cannot be viewed again after creation)

Project access tokens and group access tokens also work if they include the `api` scope and at least **Reporter** role on the target project.

### 3. Configure the target project

```bash
GITLAB_TOKEN=glpat_xxxxxxxxxxxx
GITLAB_PROJECT=group/repo
```

`GITLAB_PROJECT` accepts:

- A project path: `group/repo` or with subgroups `group/sub/repo`
- A numeric project ID (visible under the project name on the project overview)

Run `devpm --interactive` to create your first issue.

## Issue Types and Labels

When you pick an issue type in @devintern/pm, it applies a GitLab label:

| devpm issue type | GitLab label |
| ---------------- | ------------- |
| Story | `enhancement` |
| Bug | `bug` |
| Task | `task` |
| Epic | `epic` |

New projects do not include all of these labels by default. Create them under **Issues → Labels** in your project, or issue creation may fail when applying a missing label.

## What Gets Created

| devpm concept | GitLab object |
| ------------------------- | ------------------------------------------------------------- |
| Story / Bug / Task / Epic | Issue with title, description, and mapped label |
| Subtask | New issue linked from a `## Subtasks` task list on the parent |
| Epic link | Not supported (step is skipped) |

## Troubleshooting

**"Missing required environment variables"**

Set both `GITLAB_TOKEN` and `GITLAB_PROJECT` in `.devintern-pm/.env`. `GITLAB_BASE_URL` is optional for gitlab.com but required for self-hosted instances.

**"GitLab API error (401)"**

- Token is invalid or expired: generate a new one
- On self-hosted instances, confirm the token was created on the same instance as `GITLAB_BASE_URL`

**"GitLab API error (403)"**

- Token lacks the `api` scope
- Your account lacks permission to create issues in that project (need at least Reporter)

**"Invalid GITLAB_PROJECT"**

Use `group/repo` (subgroups allowed) or a numeric project ID — not the human-readable project name alone.

**Self-signed certificates**

The integration talks to your instance's normal HTTPS endpoint. Instances behind self-signed TLS need the certificate trusted at the OS level where @devintern/pm runs.
2 changes: 1 addition & 1 deletion docs/pm/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ devpm init
In a terminal, this starts an interactive setup wizard that:

- Detects an existing @devintern/code configuration (`.devintern-code/.env`) in the same project and offers to reuse those tracker credentials, so you skip straight to validation
- Asks which tracker you use (Jira, Linear, Trello, Azure DevOps, Asana, GitHub Issues, or markdown files)
- Asks which tracker you use (Jira, Linear, Trello, Azure DevOps, Asana, GitHub Issues, GitLab, or markdown files)
- Links you directly to the provider's token creation page and prompts for each credential, with a pointer to the matching setup guide in these docs
- Validates the connection with a real API call before finishing (you can retry, edit values, or skip)
- Writes your answers to `.devintern-pm/.env` and updates your `.gitignore` to exclude `.devintern-pm/.env` (to prevent leaking secrets)
Expand Down
2 changes: 1 addition & 1 deletion docs/pm/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ devpm --prompt <text> [options]

### Additional Options

- `--epic, -e <key>`: Link the created story to an epic (e.g., PROJ-100). Ignored for trackers that do not support a real epic/parent hierarchy (Trello, GitHub Issues, Markdown).
- `--epic, -e <key>`: Link the created story to an epic (e.g., PROJ-100). Ignored for trackers that do not support a real epic/parent hierarchy (Trello, GitHub Issues, GitLab, Markdown).
- `--type, -t <type>`: Issue type (default: "Task"). Common types: Task, Story, Bug, Epic. Only applied by backends that support issue types (Jira, Azure DevOps, GitHub, Markdown); ignored by Linear, Trello, and Asana.
- `--custom, -c <text>`: Additional custom instructions for the requirements
- `--attach <path>`: Attach a local file for agent context (and upload on create when the tracker supports it). Repeatable. Supported: images, text/docs, PDF (not Office binaries such as `.docx`). Max 10 files.
Expand Down
13 changes: 12 additions & 1 deletion packages/code/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Copy this file to .env and update with your actual values

# Task Tracker Selection
# Which task tracker to use: jira (default) | linear | github | azure-devops | asana | trello | markdown
# Which task tracker to use: jira (default) | linear | github | gitlab | azure-devops | asana | trello | markdown
# Only the credentials for the selected tracker are required.
# TASK_TRACKER=jira

Expand Down Expand Up @@ -36,6 +36,17 @@ JIRA_API_TOKEN=your-api-token-here
# When transitioning an issue, other labels in this list are removed.
# GITHUB_STATUS_LABELS=To Do,In Progress,In Review

# GitLab Configuration (required when TASK_TRACKER=gitlab)
# Works with gitlab.com and self-hosted instances (stable REST v4 endpoints).
# GITLAB_BASE_URL=https://gitlab.example.com
# Personal access token with the `api` scope, created on the same instance:
# <instance>/-/user_settings/personal_access_tokens
# GITLAB_TOKEN=glpat_xxxxxxxxxxxx
# Target project path (subgroups allowed) or numeric project ID
# GITLAB_PROJECT=group/sub/repo
# Optional: comma-separated status label names treated as mutually exclusive.
# GITLAB_STATUS_LABELS=To Do,In Progress,In Review

# Azure DevOps Configuration (required when TASK_TRACKER=azure-devops;
# also required for `devintern worker connect azure-devops`)
# Organization from your dev.azure.com URL, a PAT with Work Items read/write,
Expand Down
4 changes: 3 additions & 1 deletion packages/code/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@ This file provides guidance to Claude Code when working with this repository.

**Environment Variables (.devintern-code/.env):**

- `TASK_TRACKER` - Task tracker type: `jira` (default), `linear`, `github`, `azure-devops`, `asana`, `trello`, or `markdown`
- `TASK_TRACKER` - Task tracker type: `jira` (default), `linear`, `github`, `gitlab`, `azure-devops`, `asana`, `trello`, or `markdown`
- `ASANA_API_TOKEN` - Asana personal access token (required when `TASK_TRACKER=asana`); optional `ASANA_DEFAULT_PROJECT_GID`, `ASANA_STORY_POINTS_FIELD`
- `AZURE_DEVOPS_ORG`, `AZURE_DEVOPS_PAT`, `AZURE_DEVOPS_PROJECT` - Azure DevOps credentials (required when `TASK_TRACKER=azure-devops`)
- `LINEAR_API_KEY` - Linear personal API key (required when `TASK_TRACKER=linear`)
- `GITHUB_REPO` - Target `owner/repo` for GitHub Issues (required when `TASK_TRACKER=github`; requires `GITHUB_TOKEN`, App credentials cannot substitute)
- `GITHUB_STATUS_LABELS` - Optional comma-separated mutually-exclusive status label names for GitHub transitions
- `GITLAB_TOKEN`, `GITLAB_PROJECT`, `GITLAB_BASE_URL` - GitLab credentials (required when `TASK_TRACKER=gitlab`; base URL optional, defaults to https://gitlab.com)
- `GITLAB_STATUS_LABELS` - Optional comma-separated mutually-exclusive status label names for GitLab transitions
- `JIRA_BASE_URL`, `JIRA_EMAIL`, `JIRA_API_TOKEN` - JIRA credentials
- `TRELLO_API_KEY`, `TRELLO_API_TOKEN` - Trello credentials (required when `TASK_TRACKER=trello`)
- `TRELLO_DEFAULT_BOARD_ID` - Optional Trello board ID for settings lookup and status transitions
Expand Down
Loading
Loading