
Research
5 Malicious Chrome Extensions Enable Session Hijacking in Enterprise HR and ERP Systems
Five coordinated Chrome extensions enable session hijacking and block security controls across enterprise HR and ERP platforms.
@gitlab/opencode-gitlab-plugin
Advanced tools
GitLab tools plugin for OpenCode - provides GitLab API access for merge requests, issues, pipelines, and more
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, and more through natural language commands.
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
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
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
# Configure npm to use GitLab Package Registry
npm config set @gitlab-org:registry https://gitlab.com/api/v4/projects/76386853/packages/npm/
# Install the package
npm install @vglafirov/opencode-gitlab-plugin
# Or with Bun
bun add @vglafirov/opencode-gitlab-plugin
# Or with yarn
yarn add @vglafirov/opencode-gitlab-plugin
# Using npm
npm install git+https://gitlab.com/vglafirov/opencode-gitlab-plugin.git
# Using Bun
bun add git+https://gitlab.com/vglafirov/opencode-gitlab-plugin.git
# Install specific version from registry
npm install @vglafirov/opencode-gitlab-plugin@1.0.0
# Install from specific git tag
npm install git+https://gitlab.com/vglafirov/opencode-gitlab-plugin.git#v1.0.0
# Install from specific branch
npm install git+https://gitlab.com/vglafirov/opencode-gitlab-plugin.git#main
Add to your package.json:
{
"dependencies": {
"@vglafirov/opencode-gitlab-plugin": "^1.0.0"
},
"publishConfig": {
"@gitlab-org:registry": "https://gitlab.com/api/v4/projects/76386853/packages/npm/"
}
}
Then run:
npm install
# 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
Add the following plugin to your opencode configuration ~/.config/opencode/opencode.json:
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["@vglafirov/opencode-gitlab-plugin"]
}
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"
}
}
GITLAB_TOKEN environment variable (highest priority)~/.local/share/opencode/auth.json)The plugin provides 68+ tools organized into the following categories:
graph LR
MR[Merge Requests] --> Get[gitlab_get_merge_request]
MR --> List[gitlab_list_merge_requests]
MR --> Create[gitlab_create_merge_request]
MR --> Update[gitlab_update_merge_request]
MR --> Changes[gitlab_get_mr_changes]
MR --> Discussions[gitlab_list_mr_discussions]
MR --> Notes[gitlab_list_mr_notes]
MR --> CreateNote[gitlab_create_mr_note]
MR --> Commits[gitlab_get_mr_commits]
MR --> Pipelines[gitlab_get_mr_pipelines]
| Tool | Description |
|---|---|
gitlab_get_merge_request | Get details of a specific merge request |
gitlab_list_merge_requests | List merge requests with filtering |
gitlab_create_merge_request | Create a new merge request |
gitlab_update_merge_request | Update an existing merge request |
gitlab_get_mr_changes | Get file changes/diff for a merge request |
gitlab_list_mr_discussions | List discussion threads on a merge request |
gitlab_list_mr_notes | List all comments in flat structure |
gitlab_create_mr_note | Add a comment to a merge request |
gitlab_get_mr_commits | Get commits in a merge request |
gitlab_get_mr_pipelines | Get pipelines for a merge request |
| Tool | Description |
|---|---|
gitlab_create_issue | Create a new issue in a project |
gitlab_get_issue | Get details of a specific issue |
gitlab_list_issues | List issues with filtering |
gitlab_list_issue_notes | List all comments on an issue |
gitlab_create_issue_note | Add a comment to an issue |
| Tool | Description |
|---|---|
gitlab_get_work_item | Get a single work item (issue, epic, task) |
gitlab_list_work_items | List work items in a project or group |
gitlab_get_work_item_notes | Get all comments for a work item |
gitlab_create_work_item | Create a new work item |
gitlab_update_work_item | Update an existing work item |
gitlab_create_work_item_note | Add a comment to a work item |
| Tool | Description |
|---|---|
gitlab_list_pipelines | List pipelines for a project |
gitlab_get_pipeline | Get details of a specific pipeline |
gitlab_list_pipeline_jobs | List jobs for a pipeline |
gitlab_get_job_log | Get log output of a CI job |
gitlab_retry_job | Retry a failed or canceled job |
gitlab_get_pipeline_failing_jobs | Get all failed jobs in a pipeline |
| Tool | Description |
|---|---|
gitlab_get_file | Get contents of a file from repository |
gitlab_get_commit | Get a single commit with full details |
gitlab_list_commits | List commits with filtering |
gitlab_get_commit_diff | Get diff for a specific commit |
gitlab_create_commit | Create a commit with multiple file actions |
gitlab_list_repository_tree | List files and directories |
gitlab_list_branches | List branches in a repository |
| Tool | Description |
|---|---|
gitlab_search | Search across GitLab (projects, issues, MRs, code, etc.) |
gitlab_issue_search | Specialized issue search |
gitlab_blob_search | Search file content in repositories |
gitlab_merge_request_search | Specialized merge request search |
| Tool | Description |
|---|---|
gitlab_get_epic | Get details of a specific epic |
gitlab_list_epics | List epics for a group |
gitlab_create_epic | Create a new epic |
gitlab_update_epic | Update an existing epic |
gitlab_list_epic_issues | Get all issues associated with an epic |
gitlab_add_issue_to_epic | Link an issue to an epic |
gitlab_remove_issue_from_epic | Unlink an issue from an epic |
gitlab_list_epic_notes | List all comments on an epic |
gitlab_create_epic_note | Add a comment to an epic |
| Tool | Description |
|---|---|
gitlab_list_todos | List TODO items for current user |
gitlab_mark_todo_done | Mark a specific TODO as done |
gitlab_mark_all_todos_done | Mark all TODOs as done |
gitlab_get_todo_count | Get count of pending TODOs |
| Tool | Description |
|---|---|
gitlab_get_project | Get details of a specific project |
gitlab_list_project_members | List members of a project |
gitlab_get_current_user | Get current user information |
| Tool | Description |
|---|---|
gitlab_list_vulnerabilities | List security vulnerabilities |
gitlab_get_vulnerability_details | Get details for a specific vulnerability |
gitlab_create_vulnerability_issue | Create issue linked to vulnerabilities (GraphQL) |
gitlab_dismiss_vulnerability | Dismiss vulnerability with reason (GraphQL) |
gitlab_confirm_vulnerability | Confirm a security vulnerability (GraphQL) |
gitlab_revert_vulnerability_to_detected | Revert vulnerability to detected state (GraphQL) |
gitlab_update_vulnerability_severity | Update vulnerability severity level (GraphQL) |
gitlab_link_vulnerability_to_issue | Link existing issue to vulnerabilities (GraphQL) |
Note: All GraphQL-based security tools include automatic GID (Global ID) format validation to ensure correct parameter formats before making API calls.
| Tool | Description |
|---|---|
gitlab_get_wiki_page | Get a wiki page with its content |
import gitlabPlugin from '@vglafirov/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',
});
// 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.',
});
// 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,
});
// 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!',
});
// 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',
});
// 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({});
// 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',
});
// 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'],
});
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
# Clone the repository
git clone https://gitlab.com/vglafirov/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
The project uses Husky for Git hooks:
This project follows Conventional Commits:
<type>(<scope>): <subject>
<body>
<footer>
Types:
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Code style changes (formatting, etc.)refactor: Code refactoringperf: Performance improvementstest: Adding or updating testsbuild: Build system changesci: CI/CD changeschore: Other changes (dependencies, etc.)revert: Revert a previous commitExamples:
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"
# Build for production
npm run build
# The build process:
# 1. Compiles TypeScript to ESM
# 2. Generates type definitions
# 3. Outputs to dist/ directory
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coverage
Test Coverage:
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]
The .gitlab-ci.yml defines the following stages:
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
The release process is fully automated using semantic-release:
fix: ā Patch version (1.0.x)feat: ā Minor version (1.x.0)BREAKING CHANGE: ā Major version (x.0.0)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 CIThe core API client that handles all GitLab REST API interactions.
constructor(instanceUrl: string, token: string)
async fetch<T>(method: string, path: string, body?: unknown): Promise<T>
async fetchText(method: string, path: string): Promise<string>
/**
* 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:
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' }
);
private encodeProjectId(projectId: string): string
Handles URL encoding for project paths (e.g., gitlab-org/gitlab ā gitlab-org%2Fgitlab)
function readTokenFromAuthStorage(): string | undefined;
Reads GitLab token from OpenCode auth storage (~/.local/share/opencode/auth.json).
Supports:
{ type: "oauth", access: "token" }{ type: "api", key: "token" }function getGitLabClient(): GitLabApiClient;
Creates and returns a configured GitLab API client.
Priority:
GITLAB_TOKEN environment variablefunction 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
function validateGid(gid: string, expectedType?: string): void;
Validates GID format and throws descriptive error if invalid.
Parameters:
gid - The GID to validateexpectedType - Optional expected resource typeThrows: 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 IDsdismissVulnerability() - validates vulnerability IDconfirmVulnerability() - validates vulnerability IDrevertVulnerability() - validates vulnerability IDupdateVulnerabilitySeverity() - validates vulnerability IDslinkVulnerabilityToIssue() - validates both issue ID and vulnerability IDsAll 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
},
});
All API calls include comprehensive error handling:
if (!response.ok) {
const errorText = await response.text();
throw new Error(`GitLab API error ${response.status}: ${errorText}`);
}
All tool responses are JSON-formatted:
return JSON.stringify(result, null, 2);
.gitignore for sensitive filesThe plugin requires a GitLab token with appropriate scopes:
api: Full API access (recommended)read_api: Read-only access (limited functionality)read_repository: Repository read accesswrite_repository: Repository write access (for commits)GitLab API has rate limits:
The plugin does not implement rate limiting logic. Consider implementing retry logic in your application.
The plugin enforces HTTPS for all API calls. HTTP URLs are not supported.
Contributions are welcome! Please follow these guidelines:
graph TD
A[Fork Repository] --> B[Create Feature Branch]
B --> C[Make Changes]
C --> D[Write Tests]
D --> E[Run Linting]
E --> F[Commit with Convention]
F --> G[Push to Fork]
G --> H[Create Merge Request]
H --> I[Code Review]
I --> J{Approved?}
J -->|Yes| K[Merge to Main]
J -->|No| C
K --> L[Automated Release]
Fork the repository
# Fork on GitLab UI, then clone
git clone https://gitlab.com/YOUR_USERNAME/opencode-gitlab-plugin.git
Create a feature branch
git checkout -b feat/my-new-feature
Make your changes
Run quality checks
npm run lint
npm run format
npm run build
npm test
Commit with conventional commits
git commit -m "feat: add new tool for project milestones"
Push and create MR
git push origin feat/my-new-feature
# Create merge request on GitLab
To
add a new GitLab API tool:
Add API method to GitLabApiClient
async getProjectMilestones(projectId: string) {
const encodedProject = this.encodeProjectId(projectId);
return this.fetch<Record<string, unknown>[]>(
'GET',
`/projects/${encodedProject}/milestones`
);
}
Add tool definition
gitlab_list_milestones: tool({
description: 'List milestones for a project',
args: {
project_id: z.string().describe('The project ID or path'),
state: z.enum(['active', 'closed', 'all']).optional(),
},
execute: async (args, _ctx) => {
const client = getGitLabClient();
const milestones = await client.getProjectMilestones(args.project_id);
return JSON.stringify(milestones, null, 2);
},
});
Update documentation
For questions, issues, or feature requests:
Made with ā¤ļø for the OpenCode community
FAQs
GitLab tools plugin for OpenCode - provides GitLab API access for merge requests, issues, pipelines, and more
The npm package @gitlab/opencode-gitlab-plugin receives a total of 337 weekly downloads. As such, @gitlab/opencode-gitlab-plugin popularity was classified as not popular.
We found that @gitlab/opencode-gitlab-plugin demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.Ā It has 6 open source maintainers collaborating on the project.
Did you know?

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.

Research
Five coordinated Chrome extensions enable session hijacking and block security controls across enterprise HR and ERP platforms.

Research
Node.js patched a crash bug where AsyncLocalStorage could cause stack overflows to bypass error handlers and terminate production servers.

Research
/Security News
A malicious Chrome extension steals newly created MEXC API keys, exfiltrates them to Telegram, and enables full account takeover with trading and withdrawal rights.