Socket
Book a DemoInstallSign in
Socket

@gitlab/opencode-gitlab-plugin

Package Overview
Dependencies
Maintainers
6
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@gitlab/opencode-gitlab-plugin

GitLab tools plugin for OpenCode - provides GitLab API access for merge requests, issues, pipelines, and more

latest
Source
npmnpm
Version
1.1.0
Version published
Maintainers
6
Created
Source

OpenCode GitLab Plugin

GitLab CI npm version License: MIT

A comprehensive GitLab API plugin for OpenCode that provides AI-powered access to GitLab's REST API. This plugin enables seamless interaction with merge requests, issues, pipelines, repositories, epics, snippets, audit events, and more through natural language commands.

šŸ“‹ Table of Contents

✨ Features

Core Capabilities

  • šŸ”€ Merge Requests: Full CRUD operations, discussions, notes, changes, commits, and pipelines
  • šŸ“ Issues: Create, read, update, and comment on issues with advanced filtering
  • šŸŽÆ Work Items: Unified interface for issues, epics, tasks, and other work tracking items
  • šŸš€ CI/CD Pipelines: Monitor, analyze, retry pipeline jobs, and validate CI/CD configurations
  • šŸ“¦ Repository Operations: File management, commits, branches, tree navigation, and commit discussions
  • šŸ” Advanced Search: Multi-scope search across projects, code, issues, merge requests, commits, users, milestones, and documentation
  • šŸ“Š Epics: Enterprise-level epic management with issue associations
  • šŸ’¬ Snippets: Snippet discussions, notes, and comments management
  • šŸ”— Universal Discussions: Unified interface for discussions across all GitLab resources
  • āœ… TODOs: Personal task management and notifications
  • šŸ”’ Security: Vulnerability scanning and security report access
  • šŸ“š Wiki: Wiki page content retrieval
  • šŸ” Audit Events: Track project, group, and instance-level security events
  • šŸ”§ Git Commands: Execute safe, read-only git operations
  • šŸ‘„ Project Management: Member management and project details

Technical Features

  • TypeScript: Full type safety with comprehensive type definitions
  • ESM Support: Modern ES modules for optimal tree-shaking
  • Zod Validation: Runtime schema validation for all API inputs
  • GraphQL Support: Native GraphQL API support with type-safe mutations and queries
  • GID Validation: Automatic validation of GitLab Global IDs with descriptive error messages
  • Error Handling: Robust error handling with detailed error messages
  • Authentication: Multiple authentication methods (OAuth, API tokens)
  • Rate Limiting: Built-in handling for GitLab API rate limits
  • Caching: Efficient API response handling
  • Modular Architecture: Clean separation of concerns with client and tool modules
  • Comprehensive Testing: 142 tests with full coverage of all features

šŸ—ļø Architecture

System Architecture

graph TB
    subgraph "OpenCode Environment"
        AI[AI Assistant]
        Plugin[GitLab Plugin]
    end

    subgraph "Plugin Components"
        Tools[Tool Definitions]
        Client[GitLab API Client]
        Auth[Authentication Manager]
        Validator[Zod Schema Validator]
    end

    subgraph "GitLab API"
        REST[REST API v4]
        MR[Merge Requests]
        Issues[Issues]
        Pipelines[Pipelines]
        Repos[Repositories]
        Epics[Epics]
        Security[Security]
    end

    AI -->|Natural Language| Plugin
    Plugin --> Tools
    Tools --> Validator
    Validator --> Client
    Client --> Auth
    Auth --> REST
    REST --> MR
    REST --> Issues
    REST --> Pipelines
    REST --> Repos
    REST --> Epics
    REST --> Security

Plugin Structure

graph LR
    subgraph "src/index.ts"
        A[GitLabApiClient Class]
        B[Authentication Functions]
        C[Tool Definitions]
        D[Plugin Export]
    end

    A --> A1[HTTP Methods]
    A --> A2[Merge Request APIs]
    A --> A3[Issue APIs]
    A --> A4[Pipeline APIs]
    A --> A5[Repository APIs]
    A --> A6[Epic APIs]
    A --> A7[Search APIs]

    B --> B1[readTokenFromAuthStorage]
    B --> B2[getGitLabClient]

    C --> C1[60+ Tool Definitions]

    D --> A
    D --> B
    D --> C

Authentication Flow

sequenceDiagram
    participant User
    participant Plugin
    participant AuthManager
    participant Storage
    participant GitLab

    User->>Plugin: Initialize Plugin
    Plugin->>AuthManager: getGitLabClient()
    AuthManager->>AuthManager: Check GITLAB_TOKEN env
    alt Token in Environment
        AuthManager->>GitLab: Use env token
    else No env token
        AuthManager->>Storage: Read ~/.local/share/opencode/auth.json
        Storage->>AuthManager: Return token
        AuthManager->>GitLab: Use stored token
    end
    GitLab->>Plugin: API Response
    Plugin->>User: Tool Result

šŸ“¦ Installation

Prerequisites

  • Node.js >= 18.0.0
  • npm >= 9.0.0 or Bun
  • GitLab account with API access
  • GitLab Personal Access Token or OAuth token

Install from npm

# Install the package
npm install @gitlab/opencode-gitlab-plugin

# Or with Bun
bun add @gitlab/opencode-gitlab-plugin

# Or with yarn
yarn add @gitlab/opencode-gitlab-plugin

Install from GitLab Repository (Development)

# Using npm
npm install git+https://gitlab.com/gitlab-org/editor-extensions/opencode-gitlab-plugin.git

# Using Bun
bun add git+https://gitlab.com/gitlab-org/editor-extensions/opencode-gitlab-plugin.git

Install Specific Version

# Install specific version from npm
npm install @gitlab/opencode-gitlab-plugin@1.0.0

# Install from specific git tag
npm install git+https://gitlab.com/gitlab-org/editor-extensions/opencode-gitlab-plugin.git#v1.0.0

# Install from specific branch
npm install git+https://gitlab.com/gitlab-org/editor-extensions/opencode-gitlab-plugin.git#main

Using package.json

Add to your package.json:

{
  "dependencies": {
    "@gitlab/opencode-gitlab-plugin": "^1.0.0"
  }
}

Then run:

npm install

āš™ļø Configuration

Environment Variables

# Required: GitLab API Token
export GITLAB_TOKEN=glpat-xxxxxxxxxxxxxxxxxxxx

# Optional: Custom GitLab Instance (defaults to https://gitlab.com)
export GITLAB_INSTANCE_URL=https://gitlab.example.com

OpenCode Configuration

Add the following plugin to your opencode configuration ~/.config/opencode/opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": ["@gitlab/opencode-gitlab-plugin"]
}

Authentication Storage

The plugin supports reading tokens from OpenCode's auth storage:

Location: ~/.local/share/opencode/auth.json

Format:

{
  "gitlab": {
    "type": "oauth",
    "access": "your-oauth-token"
  }
}

Or for API tokens:

{
  "gitlab": {
    "type": "api",
    "key": "glpat-xxxxxxxxxxxxxxxxxxxx"
  }
}

Token Priority

  • GITLAB_TOKEN environment variable (highest priority)
  • OpenCode auth storage (~/.local/share/opencode/auth.json)
  • Error if no token found

šŸ› ļø Available Tools

The plugin provides 104 tools organized into the following categories:

Merge Request Tools (15 tools)

ToolDescription
gitlab_get_merge_requestGet details of a specific merge request with title, description, state, author, assignees, reviewers, labels, and diff stats
gitlab_list_merge_requestsList merge requests with filtering by state, scope, and labels
gitlab_create_merge_requestCreate a new merge request
gitlab_update_merge_requestUpdate merge request title, description, state, assignees, reviewers, and labels
gitlab_get_mr_changesGet file changes/diffs for a merge request
gitlab_list_mr_discussionsList discussion threads on a merge request with nested notes
gitlab_get_mr_discussionGet a specific discussion thread with all replies
gitlab_list_mr_notesList all comments in flat structure (easier than nested discussions)
gitlab_create_mr_noteAdd a comment or reply to a merge request discussion
gitlab_create_mr_discussionStart a new discussion thread (optionally on specific code lines)
gitlab_resolve_mr_discussionMark a discussion as resolved after addressing feedback
gitlab_unresolve_mr_discussionReopen a resolved discussion
gitlab_get_mr_commitsGet all commits in a merge request
gitlab_get_mr_pipelinesGet all pipelines for a merge request
gitlab_list_merge_request_diffsList file diffs with pagination support for large changesets

Issue Tools (10 tools)

ToolDescription
gitlab_create_issueCreate a new issue with title, description, labels, assignees, and milestone
gitlab_get_issueGet issue details including state, author, assignees, labels, and comments
gitlab_list_issuesList issues with filtering by state, labels, assignee, and milestone
gitlab_list_issue_notesList all comments including system notes
gitlab_list_issue_discussionsList discussion threads with nested notes
gitlab_get_issue_discussionGet a specific discussion thread with context
gitlab_create_issue_noteAdd a comment or reply to an issue discussion
gitlab_get_issue_noteGet a specific note by ID with full details
gitlab_resolve_issue_discussionMark an issue discussion as resolved
gitlab_unresolve_issue_discussionReopen a resolved issue discussion

Epic Tools (12 tools)

ToolDescription
gitlab_get_epicGet epic details with title, description, state, dates, and associated issues
gitlab_list_epicsList epics with filtering by state, author, and labels
gitlab_create_epicCreate a new epic in a group
gitlab_update_epicUpdate epic title, description, labels, dates, and state
gitlab_list_epic_issuesGet all issues linked to an epic
gitlab_add_issue_to_epicLink an issue to an epic
gitlab_remove_issue_from_epicUnlink an issue from an epic
gitlab_list_epic_notesList all comments on an epic
gitlab_list_epic_discussionsList discussion threads on an epic
gitlab_create_epic_noteAdd a comment or reply to an epic discussion
gitlab_get_epic_discussionGet a specific epic discussion thread
gitlab_get_epic_noteGet a specific epic note by ID

Pipeline Tools (8 tools)

ToolDescription
gitlab_list_pipelinesList pipelines with filtering by status, ref, and username
gitlab_get_pipelineGet pipeline details with jobs and status
gitlab_list_pipeline_jobsList all jobs in a pipeline with optional scope filtering
gitlab_get_job_logGet the log output of a specific CI job
gitlab_retry_jobRetry a failed or canceled job
gitlab_get_pipeline_failing_jobsGet only failed jobs for easier debugging
gitlab_lint_ci_configValidate CI/CD YAML configuration with project context
gitlab_lint_existing_ci_configValidate existing .gitlab-ci.yml from repository

Repository Tools (16 tools)

ToolDescription
gitlab_get_fileGet file contents from any branch, tag, or commit
gitlab_get_commitGet commit details with metadata, author, and stats
gitlab_list_commitsList commits with filtering by branch, path, and dates
gitlab_get_commit_diffGet diff for a specific commit
gitlab_create_commitCreate a commit with multiple file operations (create, update, delete, move)
gitlab_list_repository_treeList files and directories at a given path
gitlab_list_branchesList all branches in a repository
gitlab_list_commit_discussionsList discussion threads on a commit
gitlab_get_commit_discussionGet a specific commit discussion thread
gitlab_create_commit_noteAdd a comment to a commit (optionally line-specific)
gitlab_create_commit_discussionStart a new discussion on a commit
gitlab_get_commit_commentsGet all commit comments in flat structure

Search Tools (11 tools)

ToolDescription
gitlab_searchUniversal search across projects, issues, MRs, code, commits, users, and wikis
gitlab_issue_searchSpecialized issue search with better filtering
gitlab_merge_request_searchSpecialized merge request search with better filtering
gitlab_blob_searchSearch code/text within repository files
gitlab_commit_searchSearch commits by message, author, or SHA
gitlab_group_project_searchSearch projects within a specific group
gitlab_milestone_searchSearch milestones by title or description
gitlab_note_searchSearch comments across issues, MRs, and commits (Premium/Ultimate)
gitlab_user_searchSearch users by name or email
gitlab_wiki_blob_searchSearch wiki content with advanced filters
gitlab_documentation_searchSearch GitLab official documentation

Work Item Tools (6 tools)

ToolDescription
gitlab_get_work_itemGet a work item (unified model for issues, epics, tasks)
gitlab_list_work_itemsList work items in a project or group
gitlab_get_work_item_notesGet all comments for a work item
gitlab_create_work_itemCreate a new work item
gitlab_update_work_itemUpdate work item title, description, state, and labels
gitlab_create_work_item_noteAdd a comment to a work item

Security Tools (8 tools)

ToolDescription
gitlab_list_vulnerabilitiesList security vulnerabilities with filtering by state, severity, and type
gitlab_get_vulnerability_detailsGet detailed vulnerability information with remediation
gitlab_create_vulnerability_issueCreate an issue linked to vulnerabilities (GraphQL)
gitlab_dismiss_vulnerabilityDismiss vulnerability with reason (GraphQL)
gitlab_confirm_vulnerabilityConfirm a vulnerability as valid (GraphQL)
gitlab_revert_vulnerability_to_detectedRevert vulnerability state (GraphQL)
gitlab_update_vulnerability_severityUpdate vulnerability severity level (GraphQL)
gitlab_link_vulnerability_to_issueLink vulnerabilities to existing issue (GraphQL)

Note: All GraphQL-based security tools include automatic GID (Global ID) format validation.

TODO Tools (4 tools)

ToolDescription
gitlab_list_todosList TODO items for current user with filtering
gitlab_mark_todo_doneMark a specific TODO as completed
gitlab_mark_all_todos_doneMark all pending TODOs as completed
gitlab_get_todo_countGet count of pending TODOs

Project & User Tools (3 tools)

ToolDescription
gitlab_get_projectGet project details and metadata
gitlab_list_project_membersList all members of a project
gitlab_get_current_userGet authenticated user information

Snippet Tools (5 tools)

ToolDescription
gitlab_list_snippet_discussionsList discussion threads on a snippet
gitlab_get_snippet_discussionGet a specific snippet discussion thread
gitlab_list_snippet_notesList all comments on a snippet
gitlab_create_snippet_noteAdd a comment or reply to a snippet discussion
gitlab_create_snippet_discussionStart a new discussion on a snippet

Discussion Tools (2 tools)

ToolDescription
gitlab_reply_to_discussionUniversal tool for replying to any discussion thread (MRs, issues, epics, commits, snippets)
gitlab_get_discussionUniversal tool for fetching discussion details from any resource type

Audit Event Tools (3 tools)

ToolDescription
gitlab_list_project_audit_eventsList audit events for a project (requires owner role)
gitlab_list_group_audit_eventsList audit events for a group (requires owner role)
gitlab_list_instance_audit_eventsList instance-level audit events (requires admin access)

Git Command Tool (1 tool)

ToolDescription
run_git_commandExecute safe, read-only git commands (status, log, show, diff, blame, etc.) with security restrictions

Wiki Tools (1 tool)

ToolDescription
gitlab_get_wiki_pageGet wiki page content and metadata

šŸ’” Usage Examples

Example 1: Create and Manage Issues

import gitlabPlugin from '@gitlab/opencode-gitlab-plugin';

const plugin = await gitlabPlugin({});

// Create a new issue
const issue = await plugin.tool.gitlab_create_issue.execute({
  project_id: 'my-group/my-project',
  title: 'Fix authentication bug',
  description:
    '## Problem\n\nUsers cannot login with OAuth.\n\n## Steps to Reproduce\n1. Go to login page\n2. Click OAuth button\n3. Error occurs',
  labels: 'bug,authentication,priority::high',
  assignee_ids: [42],
  milestone_id: 10,
  due_date: '2025-12-31',
});

console.log(`Issue created: ${issue.web_url}`);

// Add a comment to the issue
await plugin.tool.gitlab_create_issue_note.execute({
  project_id: 'my-group/my-project',
  issue_iid: issue.iid,
  body: 'I will start working on this today.',
});

// List all issues with specific labels
const issues = await plugin.tool.gitlab_list_issues.execute({
  project_id: 'my-group/my-project',
  labels: 'bug',
  state: 'opened',
});

Example 2: Review Merge Request

// Get merge request details
const mr = await plugin.tool.gitlab_get_merge_request.execute({
  project_id: 'gitlab-org/gitlab',
  mr_iid: 12345,
  include_changes: true,
});

// Get discussions
const discussions = await plugin.tool.gitlab_list_mr_discussions.execute({
  project_id: 'gitlab-org/gitlab',
  mr_iid: 12345,
});

// Add a review comment
await plugin.tool.gitlab_create_mr_note.execute({
  project_id: 'gitlab-org/gitlab',
  mr_iid: 12345,
  body: 'LGTM! Great work on this feature.',
});

Example 3: Debug Failed Pipeline

// List recent pipelines
const pipelines = await plugin.tool.gitlab_list_pipelines.execute({
  project_id: 'my-group/my-project',
  status: 'failed',
  limit: 5,
});

// Get failed jobs
const failedJobs = await plugin.tool.gitlab_get_pipeline_failing_jobs.execute({
  project_id: 'my-group/my-project',
  pipeline_id: pipelines[0].id,
});

// Get job logs
for (const job of failedJobs) {
  const log = await plugin.tool.gitlab_get_job_log.execute({
    project_id: 'my-group/my-project',
    job_id: job.id,
  });
  console.log(`Job ${job.name} failed with:\n${log}`);
}

// Retry failed jobs
await plugin.tool.gitlab_retry_job.execute({
  project_id: 'my-group/my-project',
  job_id: failedJobs[0].id,
});

Example 4: Create and Manage Epic

// Create an epic
const epic = await plugin.tool.gitlab_create_epic.execute({
  group_id: 'my-group',
  title: 'Q1 2025 Features',
  description: 'All features planned for Q1 2025',
  start_date: '2025-01-01',
  end_date: '2025-03-31',
  labels: 'Q1,planning',
});

// Add issues to epic
await plugin.tool.gitlab_add_issue_to_epic.execute({
  group_id: 'my-group',
  epic_iid: epic.iid,
  issue_id: 123,
});

// List all issues in epic
const epicIssues = await plugin.tool.gitlab_list_epic_issues.execute({
  group_id: 'my-group',
  epic_iid: epic.iid,
});

// Add a comment
await plugin.tool.gitlab_create_epic_note.execute({
  group_id: 'my-group',
  epic_iid: epic.iid,
  body: 'Epic created and issues linked successfully!',
});

Example 5: Search and Analyze Code

// Search for code containing specific patterns
const codeResults = await plugin.tool.gitlab_blob_search.execute({
  search: 'async function processPayment',
  project_id: 'my-group/my-project',
  limit: 10,
});

// Search for related issues
const issues = await plugin.tool.gitlab_issue_search.execute({
  search: 'payment processing bug',
  project_id: 'my-group/my-project',
  state: 'opened',
});

// Get file content
const fileContent = await plugin.tool.gitlab_get_file.execute({
  project_id: 'my-group/my-project',
  file_path: 'src/payment/processor.ts',
  ref: 'main',
});

Example 6: Manage TODOs

// Get TODO count
const todoCount = await plugin.tool.gitlab_get_todo_count.execute({});

// List pending TODOs
const todos = await plugin.tool.gitlab_list_todos.execute({
  state: 'pending',
  type: 'MergeRequest',
  limit: 20,
});

// Mark specific TODO as done
await plugin.tool.gitlab_mark_todo_done.execute({
  todo_id: todos[0].id,
});

// Mark all TODOs as done
await plugin.tool.gitlab_mark_all_todos_done.execute({});

Example 7: Create Commit with Multiple Files

// Create a commit with multiple file operations
const commit = await plugin.tool.gitlab_create_commit.execute({
  project_id: 'my-group/my-project',
  branch: 'feature/new-api',
  commit_message: 'feat: add new API endpoints',
  actions: [
    {
      action: 'create',
      file_path: 'src/api/v2/users.ts',
      content: 'export const getUsers = async () => { ... }',
    },
    {
      action: 'update',
      file_path: 'src/api/index.ts',
      content: 'export * from "./v2/users";',
    },
    {
      action: 'delete',
      file_path: 'src/api/deprecated.ts',
    },
  ],
  author_name: 'John Doe',
  author_email: 'john@example.com',
});

Example 8: Manage Security Vulnerabilities

// List vulnerabilities in a project
const vulnerabilities = await plugin.tool.gitlab_list_vulnerabilities.execute({
  project_id: 'my-group/my-project',
  state: 'detected',
  severity: 'high',
  report_type: 'sast',
});

// Create an issue for critical vulnerabilities
const issue = await plugin.tool.gitlab_create_vulnerability_issue.execute({
  project_path: 'my-group/my-project',
  vulnerability_ids: ['gid://gitlab/Vulnerability/123', 'gid://gitlab/Vulnerability/124'],
});

// Dismiss a false positive
await plugin.tool.gitlab_dismiss_vulnerability.execute({
  vulnerability_id: 'gid://gitlab/Vulnerability/125',
  reason: 'FALSE_POSITIVE',
  comment: 'This is a test file and not part of production code',
});

// Confirm a real vulnerability
await plugin.tool.gitlab_confirm_vulnerability.execute({
  vulnerability_id: 'gid://gitlab/Vulnerability/126',
  comment: 'Confirmed - needs immediate attention',
});

// Update severity based on assessment
await plugin.tool.gitlab_update_vulnerability_severity.execute({
  vulnerability_ids: ['gid://gitlab/Vulnerability/127'],
  severity: 'CRITICAL',
  comment: 'Upgrading to critical - affects production authentication',
});

// Link vulnerabilities to existing issue
await plugin.tool.gitlab_link_vulnerability_to_issue.execute({
  issue_id: 'gid://gitlab/Issue/42',
  vulnerability_ids: ['gid://gitlab/Vulnerability/128', 'gid://gitlab/Vulnerability/129'],
});

šŸ”§ Development

Project Structure

opencode-gitlab-plugin/
ā”œā”€ā”€ src/
│   ā”œā”€ā”€ client/              # API client modules
│   │   ā”œā”€ā”€ base.ts         # Base client with HTTP & GraphQL methods
│   │   ā”œā”€ā”€ security.ts     # Security/vulnerability management
│   │   ā”œā”€ā”€ issues.ts       # Issue management
│   │   ā”œā”€ā”€ merge-requests.ts # Merge request operations
│   │   ā”œā”€ā”€ pipelines.ts    # CI/CD pipeline operations
│   │   ā”œā”€ā”€ repository.ts   # Repository operations
│   │   ā”œā”€ā”€ epics.ts        # Epic management
│   │   ā”œā”€ā”€ search.ts       # Search operations
│   │   ā”œā”€ā”€ todos.ts        # TODO management
│   │   ā”œā”€ā”€ wikis.ts        # Wiki operations
│   │   ā”œā”€ā”€ work-items.ts   # Work item operations
│   │   ā”œā”€ā”€ audit.ts        # Audit events
│   │   ā”œā”€ā”€ git.ts          # Git operations
│   │   └── index.ts        # Client exports
│   ā”œā”€ā”€ tools/              # Tool definitions
│   │   ā”œā”€ā”€ security.ts     # Security tool definitions
│   │   ā”œā”€ā”€ issues.ts       # Issue tool definitions
│   │   ā”œā”€ā”€ merge-requests.ts # MR tool definitions
│   │   ā”œā”€ā”€ pipelines.ts    # Pipeline tool definitions
│   │   ā”œā”€ā”€ repository.ts   # Repository tool definitions
│   │   └── ...             # Other tool definitions
│   ā”œā”€ā”€ index.ts            # Main plugin entry point
│   ā”œā”€ā”€ utils.ts            # Utility functions
│   └── validation.ts       # GID validation utilities
ā”œā”€ā”€ tests/                  # Test suite (142 tests)
│   ā”œā”€ā”€ client/             # Client tests
│   ā”œā”€ā”€ tools/              # Tool tests
│   ā”œā”€ā”€ validation.test.ts  # Validation tests
│   └── utils.test.ts       # Utility tests
ā”œā”€ā”€ dist/                   # Compiled output (generated)
│   ā”œā”€ā”€ index.js           # ESM bundle
│   └── index.d.ts         # TypeScript definitions
ā”œā”€ā”€ .husky/                 # Git hooks
│   ā”œā”€ā”€ commit-msg         # Commitlint hook
│   └── pre-commit         # Lint-staged hook
ā”œā”€ā”€ .gitlab-ci.yml         # CI/CD pipeline configuration
ā”œā”€ā”€ package.json           # Package metadata
ā”œā”€ā”€ tsconfig.json          # TypeScript configuration
ā”œā”€ā”€ vitest.config.ts       # Vitest test configuration
ā”œā”€ā”€ .eslintrc.json         # ESLint configuration
ā”œā”€ā”€ .prettierrc.json       # Prettier configuration
ā”œā”€ā”€ .commitlintrc.json     # Commitlint configuration
ā”œā”€ā”€ .releaserc.json        # Semantic-release configuration
ā”œā”€ā”€ CHANGELOG.md           # Auto-generated changelog
ā”œā”€ā”€ INSTALLATION.md        # Installation guide
└── README.md              # This file

Setup Development Environment

# Clone the repository
git clone https://gitlab.com/gitlab-org/editor-extensions/opencode-gitlab-plugin.git
cd opencode-gitlab-plugin

# Install dependencies
npm install

# Build the plugin
npm run build

# Watch mode for development
npm run dev

# Run linting
npm run lint

# Fix linting issues
npm run lint:fix

# Format code
npm run format

# Check formatting
npm run format:check

Git Hooks

The project uses Husky for Git hooks:

  • pre-commit: Runs lint-staged to lint and format staged files
  • commit-msg: Validates commit messages using commitlint

Commit Message Convention

This project follows Conventional Commits:

<type>(<scope>): <subject>

<body>

<footer>

Types:

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation changes
  • style: Code style changes (formatting, etc.)
  • refactor: Code refactoring
  • perf: Performance improvements
  • test: Adding or updating tests
  • build: Build system changes
  • ci: CI/CD changes
  • chore: Other changes (dependencies, etc.)
  • revert: Revert a previous commit

Examples:

git commit -m "feat: add support for GitLab wiki pages"
git commit -m "fix: handle empty API responses correctly"
git commit -m "docs: update installation instructions"
git commit -m "ci: add automated release workflow"

Building

# Build for production
npm run build

# The build process:
# 1. Compiles TypeScript to ESM
# 2. Generates type definitions
# 3. Outputs to dist/ directory

Testing

# Run tests
npm test

# Run tests in watch mode
npm run test:watch

# Run tests with coverage
npm run test:coverage

Test Coverage:

  • 142 tests across 18 test files
  • Client tests for all API methods
  • Tool tests for all tool definitions
  • Validation tests for GID utilities
  • GraphQL method tests
  • All tests passing āœ…

šŸš€ CI/CD Pipeline

Pipeline Stages

graph LR
    A[Test] --> B[Build]
    B --> C[Release]

    A --> A1[Lint]
    A --> A2[Format Check]
    A --> A3[Unit Tests]

    B --> B1[TypeScript Build]
    B --> B2[Generate Types]

    C --> C1[Semantic Release]
    C --> C2[Publish to Registry]
    C --> C3[Create Git Tag]
    C --> C4[Update Changelog]

Pipeline Configuration

The .gitlab-ci.yml defines the following stages:

1. Test Stage

  • test:lint: Runs ESLint on source code
  • test:format: Checks code formatting with Prettier
  • test:unit: Runs unit tests (placeholder)

2. Build Stage

  • build: Compiles TypeScript and generates artifacts
    • Uses tsup for bundling
    • Generates ESM output
    • Creates TypeScript definitions
    • Artifacts expire in 1 week

3. Release Stage

  • release: Automated versioning and publishing
    • Only runs on main branch
    • Uses semantic-release
    • Publishes to GitLab Package Registry
    • Creates Git tags
    • Updates CHANGELOG.md
    • Artifacts never expire

Semantic Release Workflow

sequenceDiagram
    participant Dev as Developer
    participant Git as Git Repository
    participant CI as GitLab CI
    participant SR as Semantic Release
    participant Reg as Package Registry

    Dev->>Git: Push to main branch
    Git->>CI: Trigger pipeline
    CI->>CI: Run tests
    CI->>CI: Build package
    CI->>SR: Run semantic-release
    SR->>SR: Analyze commits
    SR->>SR: Determine version
    SR->>SR: Generate changelog
    SR->>Git: Create tag & commit
    SR->>Reg: Publish package
    SR->>Git: Create GitLab release

Release Process

The release process is fully automated using semantic-release:

  • Commit Analysis: Analyzes commit messages since last release
  • Version Calculation: Determines next version based on commit types
    • fix: → Patch version (1.0.x)
    • feat: → Minor version (1.x.0)
    • BREAKING CHANGE: → Major version (x.0.0)
  • Changelog Generation: Updates CHANGELOG.md
  • Package Publishing: Publishes to GitLab Package Registry
  • Git Tagging: Creates and pushes version tag
  • GitLab Release: Creates release notes on GitLab

Environment Variables

The CI/CD pipeline uses the following variables:

  • CI_JOB_TOKEN: GitLab CI token (automatic)
  • CI_PROJECT_ID: Project ID (automatic)
  • CI_API_V4_URL: GitLab API URL (automatic)
  • HUSKY: Set to 0 to disable hooks in CI

šŸ“š API Reference

GitLabApiClient Class

The core API client that handles all GitLab REST API interactions.

Constructor

constructor(instanceUrl: string, token: string)

HTTP Methods

async fetch<T>(method: string, path: string, body?: unknown): Promise<T>
async fetchText(method: string, path: string): Promise<string>

GraphQL Methods

/**
 * Execute a GraphQL query or mutation
 * @template T - The expected type of the data field in the GraphQL response
 * @param query - The GraphQL query or mutation string
 * @param variables - Optional variables for the query
 * @returns The data from the GraphQL response
 */
async fetchGraphQL<T>(query: string, variables?: Record<string, unknown>): Promise<T>

Features:

  • Full TypeScript type safety with generic return types
  • Automatic error handling for both HTTP and GraphQL errors
  • Support for query variables
  • Used by all GraphQL-based security tools

Example:

const result = await client.fetchGraphQL<{ vulnerability: { id: string } }>(
  `mutation($id: VulnerabilityID!) {
    vulnerabilityConfirm(input: { id: $id }) {
      vulnerability { id state }
      errors
    }
  }`,
  { id: 'gid://gitlab/Vulnerability/123' }
);

Project ID Encoding

private encodeProjectId(projectId: string): string

Handles URL encoding for project paths (e.g., gitlab-org/gitlab → gitlab-org%2Fgitlab)

Authentication Functions

readTokenFromAuthStorage

function readTokenFromAuthStorage(): string | undefined;

Reads GitLab token from OpenCode auth storage (~/.local/share/opencode/auth.json).

Supports:

  • OAuth tokens: { type: "oauth", access: "token" }
  • API tokens: { type: "api", key: "token" }

getGitLabClient

function getGitLabClient(): GitLabApiClient;

Creates and returns a configured GitLab API client.

Priority:

  • GITLAB_TOKEN environment variable
  • OpenCode auth storage
  • Throws error if no token found

Validation Functions

isValidGid

function isValidGid(gid: string, expectedType?: string): boolean;

Validates GitLab Global ID (GID) format.

Parameters:

  • gid - The GID to validate (e.g., gid://gitlab/Vulnerability/123)
  • expectedType - Optional expected resource type (e.g., 'Vulnerability', 'Issue')

Returns: true if valid, false otherwise

Example:

isValidGid('gid://gitlab/Vulnerability/123'); // true
isValidGid('gid://gitlab/Issue/456', 'Issue'); // true
isValidGid('gid://gitlab/Vulnerability/123', 'Issue'); // false (wrong type)
isValidGid('invalid-gid'); // false

validateGid

function validateGid(gid: string, expectedType?: string): void;

Validates GID format and throws descriptive error if invalid.

Parameters:

  • gid - The GID to validate
  • expectedType - Optional expected resource type

Throws: Error with descriptive message if GID format is invalid

Example:

validateGid('gid://gitlab/Vulnerability/123'); // No error
validateGid('invalid-gid'); // Throws: "Invalid GitLab Global ID: 'invalid-gid'. Expected format: gid://gitlab/ResourceType/{id}"
validateGid('gid://gitlab/Issue/123', 'Vulnerability'); // Throws: "Invalid GitLab Global ID of type 'Vulnerability'..."

Usage in Security Tools:

All GraphQL-based security tools automatically validate GID parameters:

  • createVulnerabilityIssue() - validates vulnerability IDs
  • dismissVulnerability() - validates vulnerability ID
  • confirmVulnerability() - validates vulnerability ID
  • revertVulnerability() - validates vulnerability ID
  • updateVulnerabilitySeverity() - validates vulnerability IDs
  • linkVulnerabilityToIssue() - validates both issue ID and vulnerability IDs

Tool Schema Validation

All tools use Zod for runtime validation:

import { tool } from '@opencode-ai/plugin';
const z = tool.schema; // Zod v4 compatible

// Example tool definition
gitlab_get_merge_request: tool({
  description: 'Get details of a specific merge request',
  args: {
    project_id: z.string().describe('The project ID or URL-encoded path'),
    mr_iid: z.number().describe('The internal ID of the merge request'),
    include_changes: z.boolean().optional().describe('Include file changes'),
  },
  execute: async (args, ctx) => {
    // Implementation
  },
});

Error Handling

All API calls include comprehensive error handling:

if (!response.ok) {
  const errorText = await response.text();
  throw new Error(`GitLab API error ${response.status}: ${errorText}`);
}

Response Formatting

All tool responses are JSON-formatted:

return JSON.stringify(result, null, 2);

šŸ” Security Considerations

Token Storage

  • Environment Variables: Recommended for CI/CD and production
  • Auth Storage: Convenient for local development
  • Never commit tokens: Use .gitignore for sensitive files

API Permissions

The plugin requires a GitLab token with appropriate scopes:

  • api: Full API access (recommended)
  • read_api: Read-only access (limited functionality)
  • read_repository: Repository read access
  • write_repository: Repository write access (for commits)

Rate Limiting

GitLab API has rate limits:

  • Authenticated requests: 2,000 requests per minute
  • Unauthenticated requests: 10 requests per minute

The plugin does not implement rate limiting logic. Consider implementing retry logic in your application.

HTTPS Only

The plugin enforces HTTPS for all API calls. HTTP URLs are not supported.

šŸ¤ Contributing

Contributions are welcome! Please see our Contributing Guide for detailed guidelines on:

  • Code style and conventions
  • Development workflow
  • Testing requirements
  • Submitting merge requests
  • Developer Certificate of Origin and License

Quick Start for Contributors:

  • Commit Messages: Use conventional commits format

    feat(scope): add new feature
    fix(scope): fix bug
    docs(scope): update documentation
    
  • Code Quality: Ensure all checks pass

    npm run lint
    npm test
    
  • Testing: Add tests for new features

šŸ™ Acknowledgments

  • OpenCode Team: For the plugin SDK and framework
  • GitLab: For the comprehensive REST API
  • Contributors: All contributors to this project

šŸ“ž Support

For questions, issues, or feature requests:

šŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

Made with ā¤ļø for the OpenCode community

Keywords

opencode

FAQs

Package last updated on 13 Jan 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts