opencode-gitlab-dap 1.0.0 → 1.1.1
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/README.md +78 -183
- package/dist/index.cjs +2793 -164
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2785 -164
- package/dist/index.js.map +1 -1
- package/package.json +6 -7
package/README.md
CHANGED
|
@@ -1,235 +1,130 @@
|
|
|
1
1
|
# opencode-gitlab-dap
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
An [opencode](https://opencode.ai) plugin that discovers GitLab foundational and custom agents
|
|
4
|
+
from the [GitLab AI Catalog](https://docs.gitlab.com/ee/user/ai_catalog/) and injects them as
|
|
5
|
+
native agents into the opencode agent picker.
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
## Requirements
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Architecture
|
|
14
|
-
|
|
15
|
-
```mermaid
|
|
16
|
-
sequenceDiagram
|
|
17
|
-
participant TUI as OpenCode TUI
|
|
18
|
-
participant Server as OpenCode Server
|
|
19
|
-
participant Plugin as gitlab-dap Plugin
|
|
20
|
-
participant Cache as GitLabModelCache
|
|
21
|
-
participant API as GitLab DAP API
|
|
22
|
-
|
|
23
|
-
TUI->>Server: POST /plugin/gitlab/discover
|
|
24
|
-
Server->>Plugin: route handler
|
|
25
|
-
Plugin->>Cache: check cached selection
|
|
26
|
-
alt cache hit
|
|
27
|
-
Plugin-->>Server: { status: "cached", model }
|
|
28
|
-
else no cache
|
|
29
|
-
Plugin->>API: detect project + discover models
|
|
30
|
-
API-->>Plugin: DiscoveredModels
|
|
31
|
-
alt pinned model
|
|
32
|
-
Plugin-->>Server: { status: "pinned", model }
|
|
33
|
-
else multiple models
|
|
34
|
-
Plugin->>Server: askUser via plugin-select bus
|
|
35
|
-
Server->>TUI: render selection prompt
|
|
36
|
-
TUI-->>Server: user picks model
|
|
37
|
-
Server-->>Plugin: selected ref
|
|
38
|
-
Plugin->>Cache: save selection
|
|
39
|
-
Plugin-->>Server: { status: "selected", model }
|
|
40
|
-
else default only
|
|
41
|
-
Plugin-->>Server: { status: "default", model }
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
Server-->>TUI: JSON response
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
---
|
|
9
|
+
- opencode with the `gitlab` provider configured and Duo Workflow (DWS) enabled
|
|
10
|
+
- GitLab OAuth or PAT authentication (via `opencode-gitlab-auth` or manual config)
|
|
11
|
+
- GitLab project with AI Catalog agents enabled
|
|
12
|
+
- `gitlab-ai-provider` >= 6.2.0 (peer dependency, bundled with opencode's gitlab provider)
|
|
48
13
|
|
|
49
14
|
## Install
|
|
50
15
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
---
|
|
54
|
-
|
|
55
|
-
## Configure
|
|
56
|
-
|
|
57
|
-
Authentication is resolved in this order:
|
|
58
|
-
|
|
59
|
-
1. Request headers (`x-plugin-auth-token`, `x-plugin-auth-instance`)
|
|
60
|
-
2. OpenCode auth store via `input.getAuth("gitlab")` (OAuth or API key)
|
|
61
|
-
3. Environment variables as fallback
|
|
62
|
-
|
|
63
|
-
| Variable | Description | Default |
|
|
64
|
-
| ------------------------ | ------------------------------------------------------- | -------------------- |
|
|
65
|
-
| `GITLAB_INSTANCE_URL` | Base URL of your GitLab instance | `https://gitlab.com` |
|
|
66
|
-
| `GITLAB_TOKEN` | Personal or project access token (when not using OAuth) | -- |
|
|
67
|
-
| `GITLAB_OAUTH_CLIENT_ID` | OAuth application ID for the OAuth flow | -- |
|
|
68
|
-
|
|
69
|
-
The plugin also reads `x-plugin-directory` from request headers to scope cache and project detection to a specific working directory.
|
|
70
|
-
|
|
71
|
-
---
|
|
72
|
-
|
|
73
|
-
## Routes
|
|
74
|
-
|
|
75
|
-
All routes are prefixed with `/plugin/gitlab`.
|
|
76
|
-
|
|
77
|
-
### POST /discover
|
|
78
|
-
|
|
79
|
-
Detect the GitLab project, query DAP for available models, and return the resolved model or prompt the user to pick one.
|
|
80
|
-
|
|
81
|
-
**Request:**
|
|
82
|
-
|
|
83
|
-
```json
|
|
84
|
-
{ "fresh": true }
|
|
16
|
+
```bash
|
|
17
|
+
opencode plugin opencode-gitlab-dap
|
|
85
18
|
```
|
|
86
19
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
**Response (pinned):**
|
|
20
|
+
Or add to your `~/.config/opencode/opencode.json`:
|
|
90
21
|
|
|
91
22
|
```json
|
|
92
23
|
{
|
|
93
|
-
"
|
|
94
|
-
"model": { "name": "Claude 4", "ref": "claude_4" }
|
|
24
|
+
"plugin": ["opencode-gitlab-dap"]
|
|
95
25
|
}
|
|
96
26
|
```
|
|
97
27
|
|
|
98
|
-
|
|
28
|
+
No further configuration needed. The plugin reads GitLab auth and model cache automatically.
|
|
99
29
|
|
|
100
|
-
|
|
101
|
-
{
|
|
102
|
-
"status": "selected",
|
|
103
|
-
"model": { "name": "GPT-5", "ref": "gpt_5" }
|
|
104
|
-
}
|
|
105
|
-
```
|
|
30
|
+
## How it works
|
|
106
31
|
|
|
107
|
-
|
|
32
|
+
On every opencode startup the plugin:
|
|
108
33
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
34
|
+
1. Reads the GitLab auth token from `~/.local/share/opencode/auth.json`
|
|
35
|
+
2. Reads the already-cached GitLab workflow model from `gitlab-ai-provider`'s model cache (no extra network call)
|
|
36
|
+
3. Queries two GitLab GraphQL APIs in parallel:
|
|
37
|
+
- `aiFoundationalChatAgents` — project-scoped foundational agents (Planner, Data Analyst, Security Analyst, GitLab Duo, etc.)
|
|
38
|
+
- `aiCatalogConfiguredItems` — custom agents explicitly enabled for the project
|
|
39
|
+
4. Injects all discovered agents into opencode's config via the `config` hook — they appear in the `/agents` dialog and the Tab agent picker
|
|
40
|
+
5. Each agent runs through GitLab Duo Agent Platform (DWS), with tool actions executed locally by opencode
|
|
115
41
|
|
|
116
|
-
|
|
42
|
+
## Agent types
|
|
117
43
|
|
|
118
|
-
|
|
44
|
+
### Foundational agents
|
|
119
45
|
|
|
120
|
-
|
|
46
|
+
Built-in GitLab agents available based on your project's Duo Workflow license:
|
|
121
47
|
|
|
122
|
-
|
|
48
|
+
| Agent | Description |
|
|
49
|
+
| ---------------- | ------------------------------- |
|
|
50
|
+
| GitLab Duo | General-purpose agentic chat |
|
|
51
|
+
| Planner | Issue and project planning |
|
|
52
|
+
| Data Analyst | GitLab data analysis (GLQL) |
|
|
53
|
+
| Security Analyst | Security vulnerability analysis |
|
|
123
54
|
|
|
124
|
-
|
|
55
|
+
These are fetched via `aiFoundationalChatAgents` and are scoped to what's enabled for your project.
|
|
125
56
|
|
|
126
|
-
|
|
127
|
-
{ "ref": "claude_4" }
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
**Response:**
|
|
131
|
-
|
|
132
|
-
```json
|
|
133
|
-
{ "ref": "claude_4", "name": "Claude 4" }
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
---
|
|
57
|
+
### Custom agents
|
|
137
58
|
|
|
138
|
-
|
|
59
|
+
User-defined agents created in the [GitLab AI Catalog](https://docs.gitlab.com/ee/user/ai_catalog/).
|
|
60
|
+
Custom agents must be explicitly enabled for the project to appear.
|
|
139
61
|
|
|
140
|
-
|
|
62
|
+
Custom agents run with their full `flowConfig` (system prompt, tools, routing) sent directly to DWS.
|
|
63
|
+
Their sessions are linked to the correct agent page in the GitLab UI (`/automate/agents/<id>/`).
|
|
141
64
|
|
|
142
|
-
|
|
65
|
+
## Agent picker UX
|
|
143
66
|
|
|
144
|
-
|
|
145
|
-
true
|
|
146
|
-
```
|
|
67
|
+
Agents appear in:
|
|
147
68
|
|
|
148
|
-
|
|
69
|
+
- **`/agents` slash command** — shows all agents with `[GitLab Foundational Agent]` or `[GitLab Custom Agent]` labels
|
|
70
|
+
- **Tab agent switcher** — switch the active agent for the current session
|
|
71
|
+
- **Session header** — shows the active agent name
|
|
149
72
|
|
|
150
|
-
|
|
73
|
+
## Self-hosted GitLab
|
|
151
74
|
|
|
152
|
-
|
|
75
|
+
For OAuth-based auth, the `enterpriseUrl` from `opencode-gitlab-auth` is used automatically.
|
|
153
76
|
|
|
154
|
-
|
|
77
|
+
For PAT-based auth on self-hosted instances, set:
|
|
155
78
|
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
"models": [
|
|
159
|
-
{ "name": "Claude 4", "ref": "claude_4" },
|
|
160
|
-
{ "name": "GPT-5", "ref": "gpt_5" }
|
|
161
|
-
],
|
|
162
|
-
"pinned": null,
|
|
163
|
-
"default": { "name": "Claude 4", "ref": "claude_4" },
|
|
164
|
-
"switching": true
|
|
165
|
-
}
|
|
79
|
+
```bash
|
|
80
|
+
export GITLAB_INSTANCE_URL=https://your-instance.com
|
|
166
81
|
```
|
|
167
82
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
## Discovery flow
|
|
171
|
-
|
|
172
|
-
The `discover` function resolves models through a priority chain:
|
|
173
|
-
|
|
174
|
-
1. **No token** -- returns `no_provider` immediately.
|
|
175
|
-
2. **Project detection** -- uses `GitLabProjectDetector` to find the namespace from the working directory. Fails with `no_provider` if no project is found.
|
|
176
|
-
3. **DAP query** -- calls `GitLabModelDiscovery.discover()` with the namespace GID. Returns `no_models` if the API returns nothing.
|
|
177
|
-
4. **Pinned** -- if the namespace has a pinned model, it is saved to cache and returned.
|
|
178
|
-
5. **Cached** -- if a previous selection exists in `GitLabModelCache`, it is returned.
|
|
179
|
-
6. **Asked** -- if selectable models exist and nothing is cached, the list is returned with `status: "asked"` so the route handler can prompt the user.
|
|
180
|
-
7. **Default** -- if only a default model exists (no selectable list), it is saved and returned.
|
|
181
|
-
8. **No models** -- fallthrough when none of the above match.
|
|
182
|
-
|
|
183
|
-
---
|
|
83
|
+
## Logging
|
|
184
84
|
|
|
185
|
-
|
|
85
|
+
The plugin writes debug logs to:
|
|
186
86
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
2. `askUser` sends a `POST` to the internal `plugin-select/ask` endpoint on the OpenCode server.
|
|
191
|
-
3. The server forwards the selection prompt to the TUI.
|
|
192
|
-
4. When the user picks a model, the response flows back through the same path.
|
|
193
|
-
5. The selected `ref` is saved via `saveSelection()` into `GitLabModelCache`.
|
|
194
|
-
6. Subsequent `/discover` calls return `status: "cached"` without prompting again.
|
|
195
|
-
|
|
196
|
-
If the user dismisses the prompt, the response is `{ "status": "dismissed" }`.
|
|
197
|
-
|
|
198
|
-
---
|
|
87
|
+
```
|
|
88
|
+
~/.local/share/opencode/log/gitlab-dap.log
|
|
89
|
+
```
|
|
199
90
|
|
|
200
|
-
|
|
91
|
+
Useful for debugging agent discovery issues.
|
|
201
92
|
|
|
202
|
-
|
|
93
|
+
## Architecture
|
|
203
94
|
|
|
204
|
-
```
|
|
205
|
-
|
|
95
|
+
```
|
|
96
|
+
Plugin init
|
|
97
|
+
└─ readAuth() reads ~/.local/share/opencode/auth.json
|
|
98
|
+
└─ GitLabModelCache reads ~/.cache/opencode/gitlab-workflow-model-cache.json
|
|
99
|
+
└─ fetchCatalogAgents()
|
|
100
|
+
├─ aiFoundationalChatAgents (GraphQL) → foundational agents
|
|
101
|
+
└─ aiCatalogConfiguredItems (GraphQL) → custom agents
|
|
102
|
+
└─ aiCatalogAgentFlowConfig (GraphQL) → per-agent flow config YAML
|
|
103
|
+
└─ config hook mutates cfg.agent in-place
|
|
104
|
+
└─ Agent.Service reads the same config object → agents appear in picker
|
|
105
|
+
|
|
106
|
+
Per prompt (via gitlab-ai-provider):
|
|
107
|
+
└─ providerOptions.gitlab.workflowDefinition → DWS workflow type
|
|
108
|
+
└─ providerOptions.gitlab.flowConfig → custom agent flow config
|
|
109
|
+
└─ providerOptions.gitlab.aiCatalogItemVersionId → links session in GitLab UI
|
|
206
110
|
```
|
|
207
111
|
|
|
208
|
-
|
|
112
|
+
## Development
|
|
209
113
|
|
|
210
|
-
|
|
114
|
+
```bash
|
|
115
|
+
# Install dependencies
|
|
116
|
+
bun install
|
|
211
117
|
|
|
212
|
-
|
|
118
|
+
# Run tests
|
|
213
119
|
npm test
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
Runs [Vitest](https://vitest.dev) against `test/`. Watch mode is available with `npm run test:watch`.
|
|
217
120
|
|
|
218
|
-
|
|
121
|
+
# Build dist
|
|
122
|
+
npm run build
|
|
219
123
|
|
|
220
|
-
|
|
221
|
-
npm run lint
|
|
124
|
+
# Type check
|
|
222
125
|
npm run type-check
|
|
223
126
|
```
|
|
224
127
|
|
|
225
|
-
### Clean
|
|
226
|
-
|
|
227
|
-
```sh
|
|
228
|
-
npm run clean
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
---
|
|
232
|
-
|
|
233
128
|
## License
|
|
234
129
|
|
|
235
|
-
|
|
130
|
+
MIT
|