Skip to content

[DEV-85] Support GitLab Cloud and GitLab self-hosted as task trackers across devpm CLI, devintern code, and pm-desktop - #54

Merged
danii1 merged 2 commits into
mainfrom
feature/dev-85-attempt-3
Aug 27, 2026
Merged

[DEV-85] Support GitLab Cloud and GitLab self-hosted as task trackers across devpm CLI, devintern code, and pm-desktop#54
danii1 merged 2 commits into
mainfrom
feature/dev-85-attempt-3

Conversation

@danii1

@danii1 danii1 commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Task: DEV-85

Summary: Support GitLab Cloud and GitLab self-hosted as task trackers across devpm CLI, devintern code, and pm-desktop

Implementation Details

I'll start by analyzing the repository state and understanding the existing patterns before implementing GitLab support.
I'm on feature/dev-85-attempt-3 with a clean tree. Let me check for partial work from previous attempts and explore the codebase structure.
No partial work on previous branches — starting fresh. Let me explore the codebase thoroughly to understand all integration points.
Subagents failed due to network errors — I'll explore directly.
Now let me explore the pm package structure:
I have a good picture of the architecture now. Let me examine the remaining integration points:
I now have full context. Let me set up my implementation plan:
Now implementing. Starting with the task-trackers package — types and metadata:
Now tracker-meta.ts:
Now the core piece — the GitLab client:
Now wire the client into exports and the probe:
Now the config loader — add GitLab URL/project parsing and env config resolution:
Now export the new helpers from the package index:
I made an error — DEFAULT_GITLAB_BASE_URL comes from the client, not utils, and would duplicate with export * from "./clients/index.ts". Fixing:
Existing tests pass. Now the GitLab client tests:
Tokenizer doesn't handle key:"quoted value" prefixes. Fixing the client and test typo:
Now extend the tracker-meta tests with gitlab coverage:
task-trackers done. Now the pm package — GitLabBackend:
Now the pm init-shared metadata (wizard prompts, docs, names):
Now pm backend tests — add a GitLabBackend describe block modeled after GitHubBackend:
Now the code package. First, check settings types:
Now the GitLab task tracker client for code:
Let me clean up that regex — I accidentally wrote escaped slashes. Fixing to mirror the GitHub client style:
Now wire the manager, capabilities, change detector, init-scaffold, normalize-task-keys, and resolveProjectKey:
Now the change detector:
Now init-scaffold (TRACKER_SETUP, TRACKER_DOCS, settings example):
Now normalize-task-keys and resolveProjectKey in index.ts:
The code init wizard is metadata-driven — good. Now let me check the GitHub client test to model the GitLab one:
The reference regex needs to require a / in any project-path prefix (like GitHub's), so PROJ-123 isn't misparsed:
All code tests pass. Now the docs:
Now the .env.example files:
Now packages/code/.env.example:
Now the docs enumerations:
Typecheck passes everywhere. Now format and lint:
No warnings from new files. Now run the full monorepo test suite:
All green. Let me check for any remaining exact-set assertions in tests:
Let me strengthen the code init-wizard tests with GitLab coverage:
All suites pass. Final verification — format check and a review of the complete diff:
Final full-repo verification:
DEV-85 is implemented across all four surfaces. Summary of the change (36 files, ~434 insertions):

@devintern/task-trackers (foundation)

  • New src/clients/gitlab.ts: GitLab REST v4 client (PRIVATE-TOKEN auth, subgroup paths via encodeURIComponent), with issue CRUD, subtask task-lists, labels (add_labels/remove_labels so existing labels survive), notes (system notes filtered), project/user listing, and a searchIssues translator mapping GitHub-style qualifiers (is:open, label:, assignee:@me, updated:>=) to list filters — including x-total pagination count
  • gitlab added to TrackerType/TRACKER_META (GITLAB_TOKEN + GITLAB_PROJECT required; GITLAB_BASE_URL optional → https://gitlab.com default, self-hosted keeps protocol incl. http)
  • New sanitizeGitlabBaseUrl / parseGitLabProject (accepts group/sub/repo, numeric IDs, pasted URLs) and a credential probe via GET /user

@getdevintern/pm

  • GitLabBackend (capabilities mirror GitHub: labels ✓, freeform ✗, epic-link ✗, attachments ✗, type→label mapping Story→enhancement etc.) + factory case with env-var-naming errors
  • Init wizard metadata: prompts for instance URL (Enter = gitlab.com) → token (deep link to <instance>/-/user_settings/personal_access_tokens) → project path; docs URL wired

@getdevintern/code

  • GitLabTaskTrackerClient: full TaskTrackerClient parity — label-based status transitions w/ reopen-close, comment-only estimation, /uploads/ attachment download, parseGitLabIssueReference accepting 123, #123, group/sub/repo#123, URLs (/-/issues/) while rejecting Jira-style keys
  • Wired into manager (incl. GITLAB_STATUS_LABELS), capabilities, worker change detector, init scaffold/settings template, key normalization, resolveProjectKey, CLI help

pm-desktop: zero code changes needed — verified the wizard/tracker-switcher pick GitLab up via PM_TRACKER_SETUP/TRACKER_META (test now asserts it explicitly).

Docs & config: docs/pm/gitlab-integration.md + docs/code/gitlab-integration.md (Cloud vs self-hosted, token scopes), both .env.example files, CLAUDE/AGENTS enumerations.

Verification: 22 new GitLab client tests, new pm backend tests, 14 new code adapter tests; full monorepo green — 11/11 test tasks pass (code: 813, pm: 323, desktop: 543, task-trackers: 165+), typecheck 11/11, lint 0 errors, oxfmt applied.


This PR was automatically created by @devintern/code

devintern-internal[bot] added 2 commits August 24, 2026 15:32
…as task trackers across devpm CLI, devintern code, and pm-desktop
- security (critical): only fetch /uploads/ attachment links whose origin
  matches the configured GitLab instance; external hosts are skipped so a
  planted link can no longer exfiltrate the PRIVATE-TOKEN
- bug (high): updateIssueComment now targets the noteable-scoped Notes API
  (PUT /projects/:id/issues/:iid/notes/:note_id) and takes the issue iid;
  updateEstimationComment passes it through, fixing guaranteed 404s
- bug (medium): GitLabTaskTrackerClient normalizes GITLAB_BASE_URL via
  sanitizeGitlabBaseUrl so protocol-less values like gitlab.example.com work
  from every entry point
- bug (medium): guard decodeURIComponent in parseGitLabProject and in
  attachment filename extraction; malformed escapes fall back to the raw
  segment / skip that URL instead of throwing or aborting all downloads
- bug (medium): listIssueComments paginates until exhausted (filtering
  system notes per page) so dedup checks see comments beyond page 1

Tests: regression tests for token-leak prevention, noteable-scoped comment
updates, pagination, malformed percent-escapes, and base URL sanitization
@danii1
danii1 merged commit 54bc64c into main Aug 27, 2026
1 check passed
@danii1
danii1 deleted the feature/dev-85-attempt-3 branch August 27, 2026 10:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant