Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
5 changes: 4 additions & 1 deletion .github/agents/go-source-documenter.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,12 @@ Rules from go.dev/doc/comment:

#### 2. File Header Comment (multi-file packages)

For packages with multiple `.go` files, each file gets a header describing its scope. Place it BEFORE the `package` declaration:
For packages with multiple `.go` files, each file gets a header describing its scope. Place it BEFORE the `package` declaration. Every file, `doc.go` and the test files included, opens above it with the copyright and license header and a blank line; that header is not a doc comment, so leave it as it is ([Copyright and License Headers](../../docs/development/file-headers.md)):

```go
// Copyright (c) 2026 José M. Requena Plens
// SPDX-License-Identifier: MIT

// branches.go implements the MCP tool handlers for GitLab branch
// operations: create, list, protect, and unprotect.
//
Expand Down
1 change: 1 addition & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ gitlab-mcp-server/
│ ├── reproduce_release/ # Release binaries rebuilt from the tag and compared byte for byte (make check-reproducible, make check-repeatable)
│ ├── audit_site_headers/ # The documentation site's security headers, judged after each deploy (make check-site-headers)
│ ├── audit_dco/ # Every commit of a pull request signed off by its author, the Developer Certificate of Origin (make check-dco)
│ ├── audit_file_headers/ # Every source file opens with the copyright and license header; -fix writes it (make check-file-headers, make fix-file-headers)
│ ├── audit_surface_quality/ # MCP surface metadata + output quality (-view; was audit_tools + audit_output)
│ ├── audit_supply_chain/ # Release-configuration invariants (SHA-pinned uses:, Dependabot cooldowns, SECURITY.md, installers)
│ ├── audit_tokens/ # Token overhead; -footprint, --compare-schemas (was audit_meta_schema); cl100k_base tokenizer (tokens.go)
Expand Down
2 changes: 1 addition & 1 deletion .github/instructions/go.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Follow idiomatic Go practices and community standards when writing Go code. Thes
- **BEFORE writing any code**, check what package name other `.go` files in the same directory use
- Use the SAME package name as existing files in that directory
- If it's a new directory, use the directory name as the package name
- Write **exactly one** `package <name>` line at the very top of the file
- Open the file with the copyright and license header (`// Copyright (c) 2026 José M. Requena Plens`, `// SPDX-License-Identifier: MIT`) and a blank line, then write **exactly one** `package <name>` line; `make fix-file-headers` writes the header and `make check-file-headers` fails a file without it (see [docs/development/file-headers.md](../../docs/development/file-headers.md))
- When using file creation or replacement tools:
- **ALWAYS verify** the target file doesn't already have a `package` declaration before adding one
- If replacing file content, include only ONE `package` declaration in the new content
Expand Down
1 change: 1 addition & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ What a review checks and what a merge requires are in [Code Review](https://gith
- [ ] Consolidated Go analysis passes on changed packages (or `make golangci-lint` / `make analyze`)
- [ ] Code is formatted: `make analyze-fix` (runs configured `golangci-lint` formatters: `goimports`, `gofumpt`, and `gci`)
- [ ] Follows idiomatic Go patterns and the conventions documented in `CLAUDE.md` / `.github/instructions/`
- [ ] Every new source file opens with the copyright and license header: `make check-file-headers` (`make fix-file-headers` writes it)

### Testing

Expand Down
3 changes: 3 additions & 0 deletions .github/scripts/cosign-sign-retry.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
#!/usr/bin/env bash
# Copyright (c) 2026 José M. Requena Plens
# SPDX-License-Identifier: MIT

# Sign a container image with cosign, retrying transient OIDC failures.
#
# Keyless signing resolves its identity token from the ambient GitHub OIDC
Expand Down
3 changes: 3 additions & 0 deletions .github/scripts/go-test-crash-aware.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
#!/usr/bin/env bash
# Copyright (c) 2026 José M. Requena Plens
# SPDX-License-Identifier: MIT

# go-test-crash-aware.sh — run a test suite through gotestsum and tell a Go
# runtime crash apart from a failing test.
#
Expand Down
3 changes: 3 additions & 0 deletions .github/scripts/needs-verdict.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
#!/usr/bin/env bash
# Copyright (c) 2026 José M. Requena Plens
# SPDX-License-Identifier: MIT

# Decide a fan-in job's verdict from the results of the jobs it needs.
#
# Reads RESULTS, the JSON of the `needs` context, and prints one line per job.
Expand Down
3 changes: 3 additions & 0 deletions .github/scripts/referrers-fallback-repair.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
#!/usr/bin/env bash
# Copyright (c) 2026 José M. Requena Plens
# SPDX-License-Identifier: MIT

# Make the referrers fallback tag say what the referrers it lists are.
#
# A registry without the OCI referrers API (ghcr.io answers 404 on
Expand Down
17 changes: 17 additions & 0 deletions .github/skills/create-mcp-tool/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,19 @@ only: `merge_requests.go` and `merge_requests_test.go` in `package mergerequests
Go's convention and the `stylecheck`/`revive` naming rules refuse underscores in
a package identifier, and the directory follows the package.

Every file opens with the copyright and license header and a blank line, as in
the templates below, `doc.go` and the test files included; `make
check-file-headers` fails a file without it and `make fix-file-headers` writes
it ([Copyright and License Headers](../../../docs/development/file-headers.md)).

## Step 1: Define Input/Output Structs

In `{domain}.go`:

```go
// Copyright (c) 2026 José M. Requena Plens
// SPDX-License-Identifier: MIT

package {domain}

import "github.com/jmrplens/gitlab-mcp-server/v3/internal/toolutil"
Expand Down Expand Up @@ -153,6 +161,9 @@ Error handling rules:
In `action_specs.go`, define the canonical route metadata once. Meta-tools, dynamic find/execute, `gitlab://tools` resources, audits, and individual tool projection consume this spec.

```go
// Copyright (c) 2026 José M. Requena Plens
// SPDX-License-Identifier: MIT

package {domain}

import (
Expand Down Expand Up @@ -209,6 +220,9 @@ Spec rules:
In `markdown.go`:

```go
// Copyright (c) 2026 José M. Requena Plens
// SPDX-License-Identifier: MIT

package {domain}

import (
Expand Down Expand Up @@ -285,6 +299,9 @@ Expected checks:
In `{domain}_test.go`:

```go
// Copyright (c) 2026 José M. Requena Plens
// SPDX-License-Identifier: MIT

package {domain}

import (
Expand Down
5 changes: 4 additions & 1 deletion .github/skills/go-source-documentation/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,12 @@ package tools

### Pattern 2: File Header Comment

For multi-file packages, each file gets a header describing its scope. The header goes immediately before the `package` declaration:
For multi-file packages, each file gets a header describing its scope. The header goes immediately before the `package` declaration. Above it, separated by a blank line, every file (`doc.go` and the test files included) opens with the copyright and license header, which is not a doc comment and is never edited into one ([Copyright and License Headers](../../../docs/development/file-headers.md)):

```go
// Copyright (c) 2026 José M. Requena Plens
// SPDX-License-Identifier: MIT

// branches.go implements MCP tool handlers for GitLab branch operations.
//
// It provides the following tools:
Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,13 @@ jobs:
# the first run of this rule found twenty-five constants nothing reads.
- name: Check no constant is left unread
run: make check-dead-consts
# Every source file opens with the copyright statement and the SPDX
# identifier of the license (the OpenSSF Best Practices criteria
# copyright_per_file and license_per_file). The gate reads git's file
# list, which this job's checkout carries, and judges what is committed,
# so it is never deferred.
- name: Check every source file carries its copyright and license header
run: make check-file-headers
# client-go takes the caller's context only as the gl.WithContext request
# option and builds the request from context.Background() without it,
# so a call that forgets it compiles, answers correctly and cannot be
Expand Down
9 changes: 8 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ link to each for Claude Code. OpenCode wiring is per developer: `opencode.json`
- **Conventional commits.** `feat:`, `fix:`, `docs:`, `test:`, `refactor:`,
`chore:`. Use the `git-commit` skill (`.claude/skills/git-commit/`) for
auto-detected type/scope.
- **A copyright and license header in every source file.** Each source
file opens with `Copyright (c) 2026 José M. Requena Plens` and
`SPDX-License-Identifier: MIT` as comments of its language, a Go file
with a blank line before its package clause or build constraint.
`make fix-file-headers` writes them into a new file and
`make check-file-headers` is the gate; which files carry them and where
is in `docs/development/file-headers.md`.
- **Coverage target: maximum possible, 100% when feasible.** CI fails
below 90% total coverage (`COVERAGE_MIN` in `.github/workflows/ci.yml`);
in practice the team pushes per-package coverage to 100%
Expand All @@ -69,7 +76,7 @@ make test # all unit tests, with coverage.out
make coverage # writes coverage.html

# Lint / analyze
make analyze # 31 steps: golangci-lint, govulncheck, markdownlint and the cmd/ audits and record checks
make analyze # 32 steps: golangci-lint, govulncheck, markdownlint and the cmd/ audits and record checks
make analyze-fix # apply gofumpt/goimports/gci/markdownlint --fix
make golangci-lint # Go-only gate
golangci-lint run --build-tags e2e ./internal/tools/branches/ # one package
Expand Down
14 changes: 11 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
> branch before a push, and [CONTRIBUTING](CONTRIBUTING.md#developer-certificate-of-origin)
> says what it certifies and how to sign off commits already made.

**This file is loaded into every session, so it holds the rules and an index, and the long-form references live in `docs/development/`**, read when a task needs them: [Repository Map](docs/development/repository-map.md) (the annotated tree of commands and packages), [Environment Variables and Flags](docs/development/configuration.md), [Test Infrastructure](docs/development/test-infrastructure.md), [Request Paths and Fine-Grained Grants](docs/development/request-paths.md) (R-PATH, R-PAGE and R-GRANT), [Adding or Changing a Limit](docs/development/adding-a-limit.md), [Release Process](docs/development/release-process.md), [Tier Gating](docs/development/tier-gating.md), [HTTP Mode Invariants](docs/development/http-invariants.md) and [Resource Subscriptions](docs/development/resource-subscriptions.md). Keep it that way: what a new section adds here is the rule and a link, and its explanation goes to the page that owns the topic. Claude Code warns at every start once this file passes a size limit that scales with the model's context window and never falls below 40,000 characters (150,000 for current models in a one-million-token window).
**This file is loaded into every session, so it holds the rules and an index, and the long-form references live in `docs/development/`**, read when a task needs them: [Repository Map](docs/development/repository-map.md) (the annotated tree of commands and packages), [Environment Variables and Flags](docs/development/configuration.md), [Test Infrastructure](docs/development/test-infrastructure.md), [Request Paths and Fine-Grained Grants](docs/development/request-paths.md) (R-PATH, R-PAGE and R-GRANT), [Adding or Changing a Limit](docs/development/adding-a-limit.md), [Release Process](docs/development/release-process.md), [Tier Gating](docs/development/tier-gating.md), [HTTP Mode Invariants](docs/development/http-invariants.md), [Resource Subscriptions](docs/development/resource-subscriptions.md) and [Copyright and License Headers](docs/development/file-headers.md). Keep it that way: what a new section adds here is the rule and a link, and its explanation goes to the page that owns the topic. Claude Code warns at every start once this file passes a size limit that scales with the model's context window and never falls below 40,000 characters (150,000 for current models in a one-million-token window).

## Project Overview

Expand Down Expand Up @@ -61,7 +61,7 @@
| MCP Icons | 51 icons (50 domain + brand mark), each a 3-entry `[]mcp.Icon`: one SVG (base64 data URI, `Sizes: ["any"]`, `currentColor`) plus light/dark 16×16 lossless WebP fallbacks (`Theme`-tagged, `cmd/gen_icon_webp`) for clients that reject SVG. The brand mark is the generated "fan-out" (`cmd/gen_brand` → `brandmark_gen.go`), original artwork replacing the former tanuki |
| Source files (tools) | 788 non-test Go files under `internal/tools/` |
| Test files (tools) | 488 test files under `internal/tools/` |
| Go packages | 309 in the module (`go list ./...`); 336 directories hold tracked `.go` files, the twenty-seven more being what `go list` leaves out: twenty-six `testdata` fixture packages (the two stand-in programs, the coverage audit's planted trees, the closed-server audit's planted module, the stand-in module the SDK route reader's tests read and the platform module the condition measurement's discovery lists) and `test/e2e/modeleval/internal/provider`, whose every file sits behind a build tag. 182 under `internal/tools/...` (the root package plus 181 sub-packages) |
| Go packages | 311 in the module (`go list ./...`); 338 directories hold tracked `.go` files, the twenty-seven more being what `go list` leaves out: twenty-six `testdata` fixture packages (the two stand-in programs, the coverage audit's planted trees, the closed-server audit's planted module, the stand-in module the SDK route reader's tests read and the platform module the condition measurement's discovery lists) and `test/e2e/modeleval/internal/provider`, whose every file sits behind a build tag. 182 under `internal/tools/...` (the root package plus 181 sub-packages) |

### Orbit live tests

Expand Down Expand Up @@ -93,6 +93,7 @@ gitlab-mcp-server/
│ ├── reproduce_release/ # Release binaries rebuilt from the tag and compared byte for byte (make check-reproducible, check-repeatable)
│ ├── audit_site_headers/ # The documentation site's security headers, after each deploy (make check-site-headers)
│ ├── audit_dco/ # Every commit of a pull request signed off by its author, the DCO (make check-dco)
│ ├── audit_file_headers/ # Every source file opens with the copyright and license header (make check-file-headers, fix-file-headers)
│ ├── godoc_tool/ # Go doc auditor and fixer (make check-godocs)
│ ├── audit_md_escaping/ # GitLab-authored values reaching Markdown unescaped (make check-md-escaping)
│ ├── audit_metrics/ # Tool, resource and prompt metrics
Expand Down Expand Up @@ -126,7 +127,7 @@ gitlab-mcp-server/
│ ├── gen_testing_docs/ # docs/development/testing/testing.md
│ ├── gen_tool_reference/ # The site's per-domain tool reference (make gen-tool-reference)
│ ├── gen_third_party_notices/ # THIRD_PARTY_NOTICES at release time
│ └── internal/ # Helpers the commands share (actionrequests, sdkroutes, actionids, apilive, graphqldocs, goprogram, sourcegate, mcpsurface, provenance, ...)
│ └── internal/ # Helpers the commands share (actionrequests, sdkroutes, actionids, apilive, fileheader, graphqldocs, goprogram, sourcegate, mcpsurface, provenance, ...)
├── internal/
│ ├── cachehints/ # SEP-2549 cache hints on MCP results
│ ├── capguard/ # Methods answered kept in step with capabilities declared
Expand Down Expand Up @@ -192,6 +193,13 @@ declaration and leave a file that does not parse. Shell commands stay right for
running, searching and generating; a script is justified only for a bulk mechanical
rewrite across many files, and the result must be verified to build.

**Every source file opens with the copyright and license header**, the two lines
`cmd/internal/fileheader` spells, as comments of its language: a new file is written
with them (`make fix-file-headers` adds them), a generator that writes source emits
them itself, and a file somebody else wrote is never stamped. `make check-file-headers`
is the gate, and [Copyright and License Headers](docs/development/file-headers.md)
says which files carry them and where.

## Key Development Patterns

### Adding a New MCP Tool
Expand Down
12 changes: 12 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ GitHub signs off a commit made in its web interface, such as an applied review s
- [ ] All tests pass: `go test ./... -count=1`
- [ ] Static analysis is clean: `make analyze` (run `make analyze-fix` first to apply supported Go and Markdown fixes)
- [ ] New tools have tests, and total coverage stays at or above the 90% CI enforces
- [ ] Every new source file opens with the [copyright and license header](#copyright-and-license-headers): `make check-file-headers`, or `make fix-file-headers` to write it
- [ ] Documentation is updated where the change shows: the site page for user-facing behavior (English and Spanish), `docs/development/` for contributor-facing changes (see [Documentation](#documentation))
- [ ] Commit messages follow conventional commits
- [ ] Every commit is signed off by its author (`git commit -s`), which certifies the [Developer Certificate of Origin](#developer-certificate-of-origin); `make check-dco` says which are not
Expand Down Expand Up @@ -258,6 +259,17 @@ internal/tools/
└── markdown.go # Markdown formatters (self-registered via init())
```

### Copyright and License Headers

Every source file opens with these two lines, written as comments of its language:

```go
// Copyright (c) 2026 José M. Requena Plens
// SPDX-License-Identifier: MIT
```

A shebang, an encoding declaration, a Dockerfile parser directive or a CSS `@charset` rule stays above them, and an Astro component carries them inside its frontmatter. `make fix-file-headers` writes them into a new file, `make check-file-headers` fails a file without them, and a generator that writes source writes them itself. A file somebody else wrote keeps its own notice and is not stamped with this one. [Copyright and License Headers](docs/development/file-headers.md) lists the files and where each kind carries the lines.

### Repository Tooling

Tooling this repository runs, its auditors, generators and release steps, is a Go command under `cmd/`, sharing what it needs through `cmd/internal/`, or under `test/e2e/` for the end-to-end orchestration. A Go command runs natively on every platform a contributor uses, is tested with the rest of the module, and needs no interpreter or package installed at run time in CI, so new tooling is written as one.
Expand Down
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# syntax=docker/dockerfile:1.28.0@sha256:bb22d9815c728170f72750f4e5b0d672e06176142e1d602c7e66c050100b7e5b
# Copyright (c) 2026 José M. Requena Plens
# SPDX-License-Identifier: MIT

# --- Build stage ---
FROM --platform=$BUILDPLATFORM golang:1.27.3-alpine3.24@sha256:f2c872bcee949b7be9c490efd02b48a8a2fbf947cdf533f1c58525ec9d8170fd AS builder
Expand Down
Loading
Loading