opencode-gitlab-plugin 2.0.2 → 2.0.4

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,20 @@
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
+ ## [2.0.4](https://gitlab.com/vglafirov/opencode-gitlab-plugin/compare/v2.0.3...v2.0.4) (2026-04-01)
6
+
7
+
8
+ ### ♻️ Code Refactoring
9
+
10
+ * remove DAP agent/flow tools (moved to opencode-gitlab-dap) ([9377e43](https://gitlab.com/vglafirov/opencode-gitlab-plugin/commit/9377e430b72ecddcbefda866b9fc9262d96a9963))
11
+
12
+ ## [2.0.3](https://gitlab.com/vglafirov/opencode-gitlab-plugin/compare/v2.0.2...v2.0.3) (2026-03-22)
13
+
14
+
15
+ ### 🐛 Bug Fixes
16
+
17
+ * **work-items:** use WorkItem widgets for assignees, labels, and notes ([a33b616](https://gitlab.com/vglafirov/opencode-gitlab-plugin/commit/a33b616247ccaa47674b3221735ebff6bdb63c7a))
18
+
5
19
  ## [2.0.2](https://gitlab.com/vglafirov/opencode-gitlab-plugin/compare/v2.0.1...v2.0.2) (2026-03-22)
6
20
 
7
21
 
package/README.md CHANGED
@@ -40,6 +40,11 @@ A comprehensive GitLab API plugin for OpenCode that provides AI-powered access t
40
40
  - **🔧 Git Commands**: Execute safe, read-only git operations
41
41
  - **👥 Project Management**: Member management and project details
42
42
 
43
+ ### Companion Plugin: DAP (Duo Agent Platform)
44
+
45
+ For GitLab AI Catalog agent/flow management, flow execution, and `@` menu integration,
46
+ see [opencode-gitlab-dap](https://gitlab.com/vglafirov/opencode-gitlab-dap).
47
+
43
48
  ### Technical Features
44
49
 
45
50
  - **TypeScript**: Full type safety with comprehensive type definitions
@@ -53,7 +58,7 @@ A comprehensive GitLab API plugin for OpenCode that provides AI-powered access t
53
58
  - **Rate Limiting**: Built-in handling for GitLab API rate limits
54
59
  - **Caching**: Efficient API response handling
55
60
  - **Modular Architecture**: Clean separation of concerns with client and tool modules
56
- - **Comprehensive Testing**: 180 tests with full coverage of all features
61
+ - **Comprehensive Testing**: 225 tests with full coverage of all features
57
62
 
58
63
  ### GraphQL-Powered Tools
59
64
 
@@ -755,7 +760,7 @@ opencode-gitlab-plugin/
755
760
  │ ├── index.ts # Main plugin entry point
756
761
  │ ├── utils.ts # Utility functions
757
762
  │ └── validation.ts # GID validation utilities
758
- ├── tests/ # Test suite (180 tests)
763
+ ├── tests/ # Test suite (225 tests)
759
764
  │ ├── client/ # Client tests
760
765
  │ ├── tools/ # Tool tests
761
766
  │ ├── validation.test.ts # Validation tests
@@ -877,7 +882,7 @@ npm run test:coverage
877
882
 
878
883
  **Test Coverage:**
879
884
 
880
- - **180 tests** across 21 test files
885
+ - **225 tests** across 25 test files
881
886
  - Client tests for all API methods (REST and GraphQL)
882
887
  - Tool tests for all tool definitions
883
888
  - Validation tests for GID utilities
package/dist/index.js CHANGED
@@ -721,7 +721,30 @@ var IssuesClient = class extends GitLabApiClient {
721
721
  function toGid(type, id) {
722
722
  return `gid://gitlab/${type}/${id}`;
723
723
  }
724
- var WORK_ITEM_LIST_FIELDS = `
724
+ var WORK_ITEM_WIDGETS_FRAGMENT = `
725
+ widgets {
726
+ type
727
+ ... on WorkItemWidgetAssignees {
728
+ assignees {
729
+ nodes {
730
+ id
731
+ username
732
+ name
733
+ }
734
+ }
735
+ }
736
+ ... on WorkItemWidgetLabels {
737
+ labels {
738
+ nodes {
739
+ id
740
+ title
741
+ color
742
+ }
743
+ }
744
+ }
745
+ }
746
+ `;
747
+ var WORK_ITEM_FIELDS = `
725
748
  id
726
749
  iid
727
750
  title
@@ -729,6 +752,7 @@ var WORK_ITEM_LIST_FIELDS = `
729
752
  state
730
753
  createdAt
731
754
  updatedAt
755
+ confidential
732
756
  workItemType {
733
757
  id
734
758
  name
@@ -738,60 +762,15 @@ var WORK_ITEM_LIST_FIELDS = `
738
762
  username
739
763
  name
740
764
  }
741
- assignees {
742
- nodes {
743
- id
744
- username
745
- name
746
- }
747
- }
748
- labels {
749
- nodes {
750
- id
751
- title
752
- color
753
- }
754
- }
755
765
  webUrl
766
+ ${WORK_ITEM_WIDGETS_FRAGMENT}
756
767
  `;
757
768
  var GET_WORK_ITEM_QUERY = `
758
769
  query getWorkItem($fullPath: ID!, $iid: String!) {
759
770
  workspace: project(fullPath: $fullPath) {
760
771
  workItems(iid: $iid, first: 1) {
761
772
  nodes {
762
- id
763
- iid
764
- title
765
- description
766
- state
767
- createdAt
768
- updatedAt
769
- closedAt
770
- confidential
771
- workItemType {
772
- id
773
- name
774
- }
775
- author {
776
- id
777
- username
778
- name
779
- }
780
- assignees {
781
- nodes {
782
- id
783
- username
784
- name
785
- }
786
- }
787
- labels {
788
- nodes {
789
- id
790
- title
791
- color
792
- }
793
- }
794
- webUrl
773
+ ${WORK_ITEM_FIELDS}
795
774
  }
796
775
  }
797
776
  }
@@ -815,7 +794,7 @@ var LIST_WORK_ITEMS_QUERY = `
815
794
  first: $first
816
795
  ) {
817
796
  nodes {
818
- ${WORK_ITEM_LIST_FIELDS}
797
+ ${WORK_ITEM_FIELDS}
819
798
  }
820
799
  }
821
800
  }
@@ -839,7 +818,7 @@ var LIST_GROUP_WORK_ITEMS_QUERY = `
839
818
  first: $first
840
819
  ) {
841
820
  nodes {
842
- ${WORK_ITEM_LIST_FIELDS}
821
+ ${WORK_ITEM_FIELDS}
843
822
  }
844
823
  }
845
824
  }
@@ -852,20 +831,30 @@ var GET_WORK_ITEM_NOTES_QUERY = `
852
831
  nodes {
853
832
  id
854
833
  iid
855
- notes {
856
- nodes {
857
- id
858
- body
859
- createdAt
860
- updatedAt
861
- author {
862
- id
863
- username
864
- name
834
+ widgets {
835
+ type
836
+ ... on WorkItemWidgetNotes {
837
+ discussions {
838
+ nodes {
839
+ id
840
+ notes {
841
+ nodes {
842
+ id
843
+ body
844
+ createdAt
845
+ updatedAt
846
+ author {
847
+ id
848
+ username
849
+ name
850
+ }
851
+ system
852
+ resolvable
853
+ resolved
854
+ }
855
+ }
856
+ }
865
857
  }
866
- system
867
- resolvable
868
- resolved
869
858
  }
870
859
  }
871
860
  }
@@ -891,23 +880,7 @@ var CREATE_WORK_ITEM_MUTATION = `
891
880
  assigneesWidget: { assigneeIds: $assigneeIds }
892
881
  }) {
893
882
  workItem {
894
- id
895
- iid
896
- title
897
- description
898
- state
899
- createdAt
900
- updatedAt
901
- workItemType {
902
- id
903
- name
904
- }
905
- author {
906
- id
907
- username
908
- name
909
- }
910
- webUrl
883
+ ${WORK_ITEM_FIELDS}
911
884
  }
912
885
  errors
913
886
  }
@@ -931,17 +904,7 @@ var UPDATE_WORK_ITEM_MUTATION = `
931
904
  assigneesWidget: { assigneeIds: $assigneeIds }
932
905
  }) {
933
906
  workItem {
934
- id
935
- iid
936
- title
937
- description
938
- state
939
- updatedAt
940
- workItemType {
941
- id
942
- name
943
- }
944
- webUrl
907
+ ${WORK_ITEM_FIELDS}
945
908
  }
946
909
  errors
947
910
  }
@@ -975,6 +938,18 @@ var GET_WORK_ITEM_GID_QUERY = `
975
938
  }
976
939
  }
977
940
  `;
941
+ function flattenWidgets(raw) {
942
+ const widgets = raw.widgets;
943
+ if (!widgets) return raw;
944
+ const assigneesWidget = widgets.find((w) => w.type === "ASSIGNEES");
945
+ const labelsWidget = widgets.find((w) => w.type === "LABELS");
946
+ const { widgets: _w, ...rest } = raw;
947
+ return {
948
+ ...rest,
949
+ assignees: assigneesWidget?.assignees?.nodes ?? [],
950
+ labels: labelsWidget?.labels?.nodes ?? []
951
+ };
952
+ }
978
953
  var WorkItemsClient = class extends GitLabApiClient {
979
954
  async getWorkItem(projectId, workItemIid) {
980
955
  const result = await this.fetchGraphQL(GET_WORK_ITEM_QUERY, {
@@ -985,7 +960,7 @@ var WorkItemsClient = class extends GitLabApiClient {
985
960
  if (!workItem) {
986
961
  throw new Error(`Work item with iid ${workItemIid} not found in project ${projectId}`);
987
962
  }
988
- return workItem;
963
+ return flattenWidgets(workItem);
989
964
  }
990
965
  async listWorkItems(options) {
991
966
  const variables = {
@@ -997,10 +972,10 @@ var WorkItemsClient = class extends GitLabApiClient {
997
972
  };
998
973
  if (options.projectId) {
999
974
  const result = await this.fetchGraphQL(LIST_WORK_ITEMS_QUERY, { fullPath: options.projectId, ...variables });
1000
- return result.workspace?.workItems?.nodes ?? [];
975
+ return (result.workspace?.workItems?.nodes ?? []).map(flattenWidgets);
1001
976
  } else if (options.groupId) {
1002
977
  const result = await this.fetchGraphQL(LIST_GROUP_WORK_ITEMS_QUERY, { fullPath: options.groupId, ...variables });
1003
- return result.workspace?.workItems?.nodes ?? [];
978
+ return (result.workspace?.workItems?.nodes ?? []).map(flattenWidgets);
1004
979
  } else {
1005
980
  throw new Error("Either projectId or groupId must be provided");
1006
981
  }
@@ -1014,7 +989,9 @@ var WorkItemsClient = class extends GitLabApiClient {
1014
989
  if (!workItem) {
1015
990
  throw new Error(`Work item with iid ${workItemIid} not found in project ${projectId}`);
1016
991
  }
1017
- return workItem.notes?.nodes ?? [];
992
+ const notesWidget = workItem.widgets?.find((w) => w.type === "NOTES");
993
+ const discussions = notesWidget?.discussions?.nodes ?? [];
994
+ return discussions.flatMap((d) => d.notes?.nodes ?? []);
1018
995
  }
1019
996
  async createWorkItem(projectId, options) {
1020
997
  const labelIds = options.labels?.map((l) => toGid("Label", l));
@@ -1030,7 +1007,7 @@ var WorkItemsClient = class extends GitLabApiClient {
1030
1007
  if (result.workItemCreate.errors.length > 0) {
1031
1008
  throw new Error(`Failed to create work item: ${result.workItemCreate.errors.join(", ")}`);
1032
1009
  }
1033
- return result.workItemCreate.workItem;
1010
+ return flattenWidgets(result.workItemCreate.workItem);
1034
1011
  }
1035
1012
  async updateWorkItem(projectId, workItemIid, options) {
1036
1013
  const gidResult = await this.fetchGraphQL(GET_WORK_ITEM_GID_QUERY, {
@@ -1055,7 +1032,7 @@ var WorkItemsClient = class extends GitLabApiClient {
1055
1032
  if (result.workItemUpdate.errors.length > 0) {
1056
1033
  throw new Error(`Failed to update work item: ${result.workItemUpdate.errors.join(", ")}`);
1057
1034
  }
1058
- return result.workItemUpdate.workItem;
1035
+ return flattenWidgets(result.workItemUpdate.workItem);
1059
1036
  }
1060
1037
  async createWorkItemNote(projectId, workItemIid, body) {
1061
1038
  const gidResult = await this.fetchGraphQL(GET_WORK_ITEM_GID_QUERY, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-gitlab-plugin",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "GitLab tools plugin for OpenCode - provides GitLab API access for merge requests, issues, pipelines, and more",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",