opencode-gitlab-plugin 2.8.2 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,28 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
4
4
 
5
+ ## [3.0.0](https://gitlab.com/vglafirov/opencode-gitlab-plugin/compare/v2.8.2...v3.0.0) (2026-09-21)
6
+
7
+
8
+ ### ⚠ BREAKING CHANGES
9
+
10
+ * the default export is a plugin definition object rather than a
11
+ plugin function. Anything importing the default export and calling it must use
12
+ the named `gitlabPlugin` export instead. OpenCode v1 hosts older than 1.18.29
13
+ do not understand object entrypoints and must stay on 2.x. On OpenCode v2 the
14
+ configuration key is `plugins`, and options move from a tuple to
15
+ `{ "package": "...", "options": { ... } }`; v1's `plugin` key is normalised
16
+ automatically.
17
+
18
+ ### ✨ Features
19
+
20
+ * support the v2 plugin SDK ([0b0fe45](https://gitlab.com/vglafirov/opencode-gitlab-plugin/commit/0b0fe4521210820fe4a424499fecaee4d9f55ae6))
21
+
22
+
23
+ ### 🐛 Bug Fixes
24
+
25
+ * **ci:** sync lockfile with npm 11.6.2 ([ceb68d7](https://gitlab.com/vglafirov/opencode-gitlab-plugin/commit/ceb68d7229d847070233566661472e43f4cdcc3a))
26
+
5
27
  ## [2.8.2](https://gitlab.com/vglafirov/opencode-gitlab-plugin/compare/v2.8.1...v2.8.2) (2026-09-18)
6
28
 
7
29
 
package/README.md CHANGED
@@ -266,6 +266,14 @@ Full example with lazy-mcp configured in opencode (`~/.config/opencode/opencode.
266
266
  "command": ["npx", "-y", "lazy-mcp@latest", "--config", "~/.config/lazy-mcp/servers.json"]
267
267
  }
268
268
  },
269
+ "plugins": [{ "package": "opencode-gitlab-plugin", "options": { "tools": false } }]
270
+ }
271
+ ```
272
+
273
+ On OpenCode v1, use the legacy tuple form instead:
274
+
275
+ ```json
276
+ {
269
277
  "plugin": [["opencode-gitlab-plugin", { "tools": false }]]
270
278
  }
271
279
  ```
@@ -298,6 +306,16 @@ export GITLAB_INSTANCE_URL=https://gitlab.example.com
298
306
 
299
307
  Add the following plugin to your opencode configuration `~/.config/opencode/opencode.json`:
300
308
 
309
+ ```json
310
+ {
311
+ "$schema": "https://opencode.ai/config.json",
312
+ "plugins": ["opencode-gitlab-plugin"]
313
+ }
314
+ ```
315
+
316
+ The package ships both plugin SDK entrypoints, so it also works on OpenCode v1 with the
317
+ legacy `plugin` key:
318
+
301
319
  ```json
302
320
  {
303
321
  "$schema": "https://opencode.ai/config.json",
@@ -490,9 +508,9 @@ The plugin provides **64 tools** organized into the following categories:
490
508
  ### Example 1: Create and Manage Issues
491
509
 
492
510
  ```javascript
493
- import gitlabPlugin from 'opencode-gitlab-plugin';
511
+ import { allTools } from 'opencode-gitlab-plugin';
494
512
 
495
- const plugin = await gitlabPlugin({});
513
+ const plugin = { tool: allTools };
496
514
 
497
515
  // Create a new issue
498
516
  const issue = await plugin.tool.gitlab_create_issue.execute({
@@ -782,6 +800,7 @@ await plugin.tool.gitlab_link_vulnerability_to_issue.execute({
782
800
 
783
801
  ```
784
802
  opencode-gitlab-plugin/
803
+ ├── index.ts # Package-root entrypoint for local v2 plugin loading
785
804
  ├── src/
786
805
  │ ├── client/ # API client modules
787
806
  │ │ ├── base.ts # Base client with HTTP & GraphQL methods
@@ -806,8 +825,12 @@ opencode-gitlab-plugin/
806
825
  │ │ ├── repository.ts # Repository tool definitions
807
826
  │ │ ├── discussions-unified.ts # Unified discussion tools (4 tools)
808
827
  │ │ ├── notes-unified.ts # Unified notes tools (3 tools)
828
+ │ │ ├── index.ts # Aggregated tool registries
809
829
  │ │ └── ... # Other tool definitions
810
- │ ├── index.ts # Main plugin entry point
830
+ │ ├── v2/ # Plugin SDK v2 entry point
831
+ │ │ ├── plugin.ts # Plugin.define({ id, setup })
832
+ │ │ └── tool-adapter.ts # v1 tool definitions -> v2 tool registrations
833
+ │ ├── index.ts # Main plugin entry point (v2 setup + v1 server)
811
834
  │ ├── utils.ts # Utility functions
812
835
  │ └── validation.ts # GID validation utilities
813
836
  ├── tests/ # Test suite (225 tests)
@@ -863,6 +886,25 @@ npm run format
863
886
  npm run format:check
864
887
  ```
865
888
 
889
+ ### Loading a Local Checkout
890
+
891
+ OpenCode v2 resolves a plugin configured by absolute path by probing
892
+ `<directory>/server` and `<directory>/index` — it does **not** read the package's
893
+ `main`/`exports`. The repository root ships an `index.ts` for exactly this, so point
894
+ the config at the checkout root:
895
+
896
+ ```json
897
+ {
898
+ "plugins": [{ "package": "/abs/path/to/opencode-gitlab-plugin" }]
899
+ }
900
+ ```
901
+
902
+ This loads `src/` directly, so OpenCode's watcher picks up edits without a rebuild.
903
+ Confirm it loaded with `opencode plugin list` — the `gitlab` plugin should be listed.
904
+
905
+ A path to a _file_ (for example `.../dist/index.js`) is rejected with
906
+ `configured plugin path must be a directory`.
907
+
866
908
  ### Git Hooks
867
909
 
868
910
  The project uses Husky for Git hooks:
package/dist/index.d.ts CHANGED
@@ -1,7 +1,19 @@
1
- import { Plugin } from '@opencode-ai/plugin';
1
+ import * as _opencode_plugin_promise_plugin from '@opencode/plugin/promise/plugin';
2
+ import { ToolDefinition, Plugin as Plugin$1 } from '@opencode-ai/plugin';
3
+ import { Plugin } from '@opencode/plugin';
2
4
 
3
5
  /**
4
- * GitLab Tools Plugin for OpenCode
6
+ * Tools exposed over the standalone MCP server (`opencode-gitlab-plugin` binary).
7
+ */
8
+ declare const mcpTools: Record<string, ToolDefinition>;
9
+ /**
10
+ * Every tool registered by the OpenCode plugin.
11
+ */
12
+ declare const allTools: Record<string, ToolDefinition>;
13
+
14
+ declare const PLUGIN_ID = "gitlab";
15
+ /**
16
+ * GitLab Tools Plugin for OpenCode (plugin SDK v2)
5
17
  *
6
18
  * Provides tools for interacting with GitLab:
7
19
  * - Merge requests: get, list, changes, create, update, commits, pipelines, diffs (paginated), auto-merge
@@ -22,6 +34,26 @@ import { Plugin } from '@opencode-ai/plugin';
22
34
  * - Git: execute safe, read-only git commands in repository
23
35
  * - Orbit: Knowledge Graph API (status, schema, query, neighbors)
24
36
  */
25
- declare const gitlabPlugin: Plugin;
37
+ declare const gitlabPluginV2: Plugin.Plugin;
38
+
39
+ /**
40
+ * GitLab Tools Plugin for OpenCode — legacy (v1) plugin SDK entrypoint.
41
+ *
42
+ * Kept so the package keeps working on OpenCode v1. New installs use the v2
43
+ * `setup()` implementation in `./v2/plugin.ts`.
44
+ *
45
+ * @deprecated Use the default export with the v2 plugin SDK.
46
+ */
47
+ declare const gitlabPlugin: Plugin$1;
48
+ /**
49
+ * Dual entrypoint: OpenCode v2 calls `setup()`, OpenCode v1 calls `server()`.
50
+ *
51
+ * See https://opencode.ai/v2/docs/build/plugins/migrate-v1
52
+ */
53
+ declare const _default: {
54
+ server: Plugin$1;
55
+ id: string;
56
+ setup: (context: _opencode_plugin_promise_plugin.Context) => Promise<_opencode_plugin_promise_plugin.Cleanup | void> | _opencode_plugin_promise_plugin.Cleanup | void;
57
+ };
26
58
 
27
- export { gitlabPlugin as default, gitlabPlugin };
59
+ export { PLUGIN_ID, allTools, _default as default, gitlabPlugin, gitlabPluginV2, mcpTools };
package/dist/index.js CHANGED
@@ -5789,45 +5789,139 @@ then use that ID (e.g., 377844873).`,
5789
5789
  })
5790
5790
  };
5791
5791
 
5792
+ // src/tools/index.ts
5793
+ var mcpTools = {
5794
+ ...mergeRequestTools,
5795
+ ...issueTools,
5796
+ ...epicTools,
5797
+ ...pipelineTools,
5798
+ ...repositoryTools,
5799
+ ...searchTools,
5800
+ ...projectTools,
5801
+ ...userTools,
5802
+ ...securityTools,
5803
+ ...todoTools,
5804
+ ...wikiTools,
5805
+ ...workItemTools,
5806
+ ...discussionsUnifiedTools,
5807
+ ...notesUnifiedTools,
5808
+ ...gitTools,
5809
+ ...auditTools,
5810
+ ...awardEmojiTools
5811
+ };
5812
+ var allTools = {
5813
+ ...mcpTools,
5814
+ ...orbitTools
5815
+ };
5816
+
5817
+ // src/v2/plugin.ts
5818
+ import { Plugin } from "@opencode/plugin";
5819
+
5820
+ // src/v2/tool-adapter.ts
5821
+ import { tool as tool19 } from "@opencode-ai/plugin";
5822
+ var z19 = tool19.schema;
5823
+ function toInputSchema(args) {
5824
+ const schema = z19.toJSONSchema(z19.object(args ?? {}), { io: "input" });
5825
+ delete schema["$schema"];
5826
+ return {
5827
+ type: "object",
5828
+ properties: {},
5829
+ additionalProperties: false,
5830
+ ...schema
5831
+ };
5832
+ }
5833
+ function toToolResult(result) {
5834
+ if (typeof result === "string") {
5835
+ return { content: result };
5836
+ }
5837
+ const metadata = { ...result.metadata ?? {} };
5838
+ if (result.title !== void 0) metadata["title"] = result.title;
5839
+ if (result.attachments !== void 0) metadata["attachments"] = result.attachments;
5840
+ return {
5841
+ content: result.output,
5842
+ ...Object.keys(metadata).length > 0 ? { metadata } : {}
5843
+ };
5844
+ }
5845
+ function toLegacyContext(context, directory, worktree) {
5846
+ return {
5847
+ sessionID: context.sessionID,
5848
+ messageID: context.messageID,
5849
+ agent: context.agent,
5850
+ directory,
5851
+ worktree,
5852
+ abort: context.signal,
5853
+ metadata: (update) => void context.progress(update),
5854
+ ask: async () => {
5855
+ }
5856
+ };
5857
+ }
5858
+ function adaptTool(name, definition, options) {
5859
+ const validator = z19.object(definition.args ?? {});
5860
+ return {
5861
+ name,
5862
+ description: definition.description,
5863
+ input: toInputSchema(definition.args),
5864
+ async execute(input, context) {
5865
+ const parsed = validator.parse(input ?? {});
5866
+ const legacyContext = toLegacyContext(context, options.directory, options.worktree);
5867
+ const result = await definition.execute(
5868
+ parsed,
5869
+ legacyContext
5870
+ );
5871
+ return toToolResult(result);
5872
+ }
5873
+ };
5874
+ }
5875
+ function adaptTools(tools, options) {
5876
+ return Object.entries(tools).map(([name, definition]) => adaptTool(name, definition, options));
5877
+ }
5878
+
5879
+ // src/v2/plugin.ts
5880
+ var PLUGIN_ID = "gitlab";
5881
+ var LAZY_MCP_HINT = `## GitLab Tools via lazy-mcp
5882
+ GitLab API tools (MRs, issues, pipelines, security, search, repos, users, todos, work items, discussions, notes, audit, git, award emoji) are served via the "gitlab" MCP server through lazy-mcp. Use lazy-mcp_list_commands with server "gitlab" to discover and call them.
5883
+ DAP tools (agents, flows, memory, skills) are on the "gitlab-dap" server instead.`;
5884
+ var gitlabPluginV2 = Plugin.define({
5885
+ id: PLUGIN_ID,
5886
+ async setup(ctx) {
5887
+ if (ctx.options["tools"] === false) {
5888
+ await ctx.session.hook("context", (event) => {
5889
+ event.system.push({ type: "text", text: LAZY_MCP_HINT });
5890
+ });
5891
+ return;
5892
+ }
5893
+ const directory = ctx.location.directory;
5894
+ const worktree = ctx.location.project.directory ?? directory;
5895
+ const tools = adaptTools(allTools, { directory, worktree });
5896
+ await ctx.tool.transform((editor) => {
5897
+ for (const definition of tools) {
5898
+ editor.add(definition);
5899
+ }
5900
+ });
5901
+ }
5902
+ });
5903
+
5792
5904
  // src/index.ts
5793
5905
  var gitlabPlugin = async (_input, options) => {
5794
- if (options?.tools === false) {
5906
+ if (options?.["tools"] === false) {
5795
5907
  return {
5796
- "experimental.chat.system.transform": async (_input2, output) => {
5797
- output.system.push(
5798
- `## GitLab Tools via lazy-mcp
5799
- GitLab API tools (MRs, issues, pipelines, security, search, repos, users, todos, work items, discussions, notes, audit, git, award emoji) are served via the "gitlab" MCP server through lazy-mcp. Use lazy-mcp_list_commands with server "gitlab" to discover and call them.
5800
- DAP tools (agents, flows, memory, skills) are on the "gitlab-dap" server instead.`
5801
- );
5908
+ "experimental.chat.system.transform": async (_hookInput, output) => {
5909
+ output.system.push(LAZY_MCP_HINT);
5802
5910
  }
5803
5911
  };
5804
5912
  }
5805
- return {
5806
- tool: {
5807
- ...mergeRequestTools,
5808
- ...issueTools,
5809
- ...epicTools,
5810
- ...pipelineTools,
5811
- ...repositoryTools,
5812
- ...searchTools,
5813
- ...projectTools,
5814
- ...userTools,
5815
- ...securityTools,
5816
- ...todoTools,
5817
- ...wikiTools,
5818
- ...workItemTools,
5819
- ...discussionsUnifiedTools,
5820
- ...notesUnifiedTools,
5821
- ...gitTools,
5822
- ...auditTools,
5823
- ...awardEmojiTools,
5824
- ...orbitTools
5825
- }
5826
- };
5913
+ return { tool: allTools };
5914
+ };
5915
+ var index_default = {
5916
+ ...gitlabPluginV2,
5917
+ server: gitlabPlugin
5827
5918
  };
5828
- var index_default = gitlabPlugin;
5829
5919
  export {
5920
+ PLUGIN_ID,
5921
+ allTools,
5830
5922
  index_default as default,
5831
- gitlabPlugin
5923
+ gitlabPlugin,
5924
+ gitlabPluginV2,
5925
+ mcpTools
5832
5926
  };
5833
5927
  //# sourceMappingURL=index.js.map