npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

opencode-gitlab-dap

v1.0.0

Published

OpenCode plugin for GitLab Duo Agent Platform (DAP) workflow model discovery and selection

Readme

opencode-gitlab-dap

OpenCode plugin for GitLab Duo Agent Platform (DAP) workflow model discovery and selection.


Overview

This plugin connects OpenCode to the GitLab Duo Agent Platform so users can discover and select workflow models configured for their GitLab namespace. It detects the current GitLab project, queries the DAP API for available models, caches the user's choice per project, and surfaces a TUI selection prompt when multiple models are available.


Architecture

sequenceDiagram
    participant TUI as OpenCode TUI
    participant Server as OpenCode Server
    participant Plugin as gitlab-dap Plugin
    participant Cache as GitLabModelCache
    participant API as GitLab DAP API

    TUI->>Server: POST /plugin/gitlab/discover
    Server->>Plugin: route handler
    Plugin->>Cache: check cached selection
    alt cache hit
        Plugin-->>Server: { status: "cached", model }
    else no cache
        Plugin->>API: detect project + discover models
        API-->>Plugin: DiscoveredModels
        alt pinned model
            Plugin-->>Server: { status: "pinned", model }
        else multiple models
            Plugin->>Server: askUser via plugin-select bus
            Server->>TUI: render selection prompt
            TUI-->>Server: user picks model
            Server-->>Plugin: selected ref
            Plugin->>Cache: save selection
            Plugin-->>Server: { status: "selected", model }
        else default only
            Plugin-->>Server: { status: "default", model }
        end
    end
    Server-->>TUI: JSON response

Install

This plugin is bundled internally with OpenCode. It is not installed as a standalone package. The plugin entry is registered automatically and exposes routes under the /plugin/gitlab/ prefix.


Configure

Authentication is resolved in this order:

  1. Request headers (x-plugin-auth-token, x-plugin-auth-instance)
  2. OpenCode auth store via input.getAuth("gitlab") (OAuth or API key)
  3. Environment variables as fallback

| Variable | Description | Default | | ------------------------ | ------------------------------------------------------- | -------------------- | | GITLAB_INSTANCE_URL | Base URL of your GitLab instance | https://gitlab.com | | GITLAB_TOKEN | Personal or project access token (when not using OAuth) | -- | | GITLAB_OAUTH_CLIENT_ID | OAuth application ID for the OAuth flow | -- |

The plugin also reads x-plugin-directory from request headers to scope cache and project detection to a specific working directory.


Routes

All routes are prefixed with /plugin/gitlab.

POST /discover

Detect the GitLab project, query DAP for available models, and return the resolved model or prompt the user to pick one.

Request:

{ "fresh": true }

Set fresh: true to clear the cache and re-discover. The body is optional.

Response (pinned):

{
  "status": "pinned",
  "model": { "name": "Claude 4", "ref": "claude_4" }
}

Response (asked then selected):

{
  "status": "selected",
  "model": { "name": "GPT-5", "ref": "gpt_5" }
}

Response (no auth):

{
  "status": "no_provider",
  "error": "No auth token found"
}

Possible status values: pinned, cached, default, selected, dismissed, no_provider, no_models, error.


POST /reply

Save a model selection directly, bypassing the interactive prompt.

Request:

{ "ref": "claude_4" }

Response:

{ "ref": "claude_4", "name": "Claude 4" }

POST /clear

Clear the cached discovery and selection for the current project.

Response:

true

GET /models

Return the current discovery state without triggering a new discovery.

Response:

{
  "models": [
    { "name": "Claude 4", "ref": "claude_4" },
    { "name": "GPT-5", "ref": "gpt_5" }
  ],
  "pinned": null,
  "default": { "name": "Claude 4", "ref": "claude_4" },
  "switching": true
}

Discovery flow

The discover function resolves models through a priority chain:

  1. No token -- returns no_provider immediately.
  2. Project detection -- uses GitLabProjectDetector to find the namespace from the working directory. Fails with no_provider if no project is found.
  3. DAP query -- calls GitLabModelDiscovery.discover() with the namespace GID. Returns no_models if the API returns nothing.
  4. Pinned -- if the namespace has a pinned model, it is saved to cache and returned.
  5. Cached -- if a previous selection exists in GitLabModelCache, it is returned.
  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.
  7. Default -- if only a default model exists (no selectable list), it is saved and returned.
  8. No models -- fallthrough when none of the above match.

Selection flow

When discovery returns status: "asked", the route handler triggers an interactive prompt:

  1. The /discover route calls askUser() with the list of models.
  2. askUser sends a POST to the internal plugin-select/ask endpoint on the OpenCode server.
  3. The server forwards the selection prompt to the TUI.
  4. When the user picks a model, the response flows back through the same path.
  5. The selected ref is saved via saveSelection() into GitLabModelCache.
  6. Subsequent /discover calls return status: "cached" without prompting again.

If the user dismisses the prompt, the response is { "status": "dismissed" }.


Develop

Build

npm run build

Uses tsup to produce CJS, ESM, and .d.ts outputs in dist/.

Test

npm test

Runs Vitest against test/. Watch mode is available with npm run test:watch.

Lint and type-check

npm run lint
npm run type-check

Clean

npm run clean

License

MIT