diff --git a/.golangci.yml b/.github/.golangci.yml similarity index 100% rename from .golangci.yml rename to .github/.golangci.yml diff --git a/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md similarity index 100% rename from CODE_OF_CONDUCT.md rename to .github/CODE_OF_CONDUCT.md diff --git a/.github/labels.yml b/.github/labels.yml new file mode 100644 index 00000000..76c7de9c --- /dev/null +++ b/.github/labels.yml @@ -0,0 +1,176 @@ +# Kubernetes-style label taxonomy for mcpproxy-go +# Synced to GitHub via .github/workflows/label-sync.yml (crazy-max/ghaction-github-labeler) +# +# Color families: +# kind/* — indigo/purple (#5C4DBF – #7C6DD8) +# area/* — teal/cyan (#0B7A75 – #1AA3A0) +# priority/* — red/orange (#B60205 – #E4A000) +# triage/* — grey/slate (#4A5568 – #B0BEC5) +# size/* — green (#1A7F37 – #A2D7A0) +# kept defaults — GitHub conventional colours + +# --------------------------------------------------------------------------- +# kind/* — what type of change is this? +# --------------------------------------------------------------------------- +- name: "kind/bug" + color: "D93F0B" + description: "Something isn't working" + +- name: "kind/feature" + color: "6E40C9" + description: "New capability or user-visible behaviour" + +- name: "kind/enhancement" + color: "7C6DD8" + description: "Improvement to an existing feature" + +- name: "kind/docs" + color: "5C4DBF" + description: "Documentation only changes" + +- name: "kind/refactor" + color: "8B7FE8" + description: "Code restructuring with no behaviour change" + +- name: "kind/test" + color: "9B8FF5" + description: "Adding or improving tests" + +- name: "kind/chore" + color: "A89FD8" + description: "Maintenance, build, dependency, or CI changes" + +- name: "kind/security" + color: "B60205" + description: "Security fix or hardening" + +- name: "kind/question" + color: "C0B0EF" + description: "Further information is requested or a design question" + +# --------------------------------------------------------------------------- +# area/* — which part of the codebase / product domain? +# --------------------------------------------------------------------------- +- name: "area/proxy" + color: "0B7A75" + description: "Core MCP proxy engine and tool routing" + +- name: "area/oauth" + color: "0E8F89" + description: "OAuth 2.1 / PKCE authentication flows" + +- name: "area/docker" + color: "11A39D" + description: "Docker security isolation and container lifecycle" + +- name: "area/tray" + color: "14B8B1" + description: "macOS / Windows system-tray application" + +- name: "area/web-ui" + color: "17CCC4" + description: "Vue 3 web dashboard (frontend/)" + +- name: "area/cli" + color: "1AA3A0" + description: "Command-line interface (mcpproxy CLI commands)" + +- name: "area/storage" + color: "0E8080" + description: "BBolt database, config, and persistence" + +- name: "area/search" + color: "1296A0" + description: "BM25 / Bleve search index and tool discovery" + +- name: "area/teams" + color: "0A6E6E" + description: "Server edition multi-user / teams features" + +- name: "area/telemetry" + color: "178080" + description: "Anonymous usage telemetry and feedback" + +- name: "area/build-ci" + color: "1BAAAA" + description: "GitHub Actions, Makefile, build scripts" + +- name: "area/packaging" + color: "1DB8B8" + description: "Homebrew, .deb, Windows installer, Docker image" + +# --------------------------------------------------------------------------- +# priority/* — how urgent / impactful? +# --------------------------------------------------------------------------- +- name: "priority/critical" + color: "B60205" + description: "Must fix immediately — data loss, security, or total breakage" + +- name: "priority/high" + color: "D93F0B" + description: "Should be addressed in the current or next release" + +- name: "priority/medium" + color: "E4A000" + description: "Important but not blocking a release" + +- name: "priority/low" + color: "F9D0C4" + description: "Nice to have; address when bandwidth allows" + +# --------------------------------------------------------------------------- +# triage/* — where is this issue in the triage lifecycle? +# --------------------------------------------------------------------------- +- name: "triage/needs-triage" + color: "4A5568" + description: "Newly opened; not yet reviewed by a maintainer" + +- name: "triage/accepted" + color: "718096" + description: "Triaged and accepted for the backlog" + +- name: "triage/duplicate" + color: "A0AEC0" + description: "This issue or PR already exists" + +- name: "triage/wontfix" + color: "B0BEC5" + description: "This will not be worked on" + +- name: "triage/needs-information" + color: "CBD5E0" + description: "More information is needed from the reporter" + +# --------------------------------------------------------------------------- +# size/* — estimated effort (set by maintainer or PR automation) +# --------------------------------------------------------------------------- +- name: "size/XS" + color: "1A7F37" + description: "Trivial change — a few lines" + +- name: "size/S" + color: "2EA44F" + description: "Small — less than a day of work" + +- name: "size/M" + color: "57C374" + description: "Medium — a few days of work" + +- name: "size/L" + color: "85D99E" + description: "Large — up to a week of work" + +- name: "size/XL" + color: "A2D7A0" + description: "Extra-large — multi-week or architectural change" + +# --------------------------------------------------------------------------- +# GitHub conventional labels — keep as-is +# --------------------------------------------------------------------------- +- name: "good first issue" + color: "7057FF" + description: "Good for newcomers" + +- name: "help wanted" + color: "008672" + description: "Extra attention is needed" diff --git a/.github/workflows/label-sync.yml b/.github/workflows/label-sync.yml new file mode 100644 index 00000000..8744d128 --- /dev/null +++ b/.github/workflows/label-sync.yml @@ -0,0 +1,30 @@ +name: Label Sync + +on: + push: + branches: + - main + paths: + - '.github/labels.yml' + - '.github/workflows/label-sync.yml' + workflow_dispatch: + +permissions: + contents: read + issues: write + +jobs: + sync: + name: Sync labels to GitHub + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + + - name: Sync labels + uses: crazy-max/ghaction-github-labeler@548a7c3603594ec17c819e1239f281a3b801ab4d # v6.0.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + yaml-file: .github/labels.yml + dry-run: false + skip-delete: false diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 766f0077..7dfc717d 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -174,7 +174,7 @@ jobs: uses: golangci/golangci-lint-action@v7 with: version: v2.6.2 - args: --timeout=5m + args: --config .github/.golangci.yml --timeout=5m build: name: Build diff --git a/Makefile b/Makefile index a7e711eb..437baf3d 100644 --- a/Makefile +++ b/Makefile @@ -139,7 +139,7 @@ test-coverage: # Run linter lint: @echo "🔍 Running Go linter..." - golangci-lint run ./... + golangci-lint run --config .github/.golangci.yml ./... @echo "🔍 Running frontend linter..." cd frontend && npm install && npm run lint diff --git a/docs/development/testing.md b/docs/development/testing.md index 6f761a32..2178e4b0 100644 --- a/docs/development/testing.md +++ b/docs/development/testing.md @@ -97,7 +97,7 @@ The E2E tests use `@modelcontextprotocol/server-everything`: ./scripts/run-linter.sh # Or directly -golangci-lint run ./... +golangci-lint run --config .github/.golangci.yml ./... ``` ## Writing Tests diff --git a/scripts/run-linter.sh b/scripts/run-linter.sh index a1487b6c..ebf46b5e 100755 --- a/scripts/run-linter.sh +++ b/scripts/run-linter.sh @@ -23,4 +23,4 @@ if ! command_exists golangci-lint; then fi echo "Running golangci-lint..." -golangci-lint run ./cmd/... ./internal/... \ No newline at end of file +golangci-lint run --config .github/.golangci.yml ./cmd/... ./internal/... diff --git a/specs/053-oss-repo-improvements/spec.md b/specs/053-oss-repo-improvements/spec.md new file mode 100644 index 00000000..45f3ea58 --- /dev/null +++ b/specs/053-oss-repo-improvements/spec.md @@ -0,0 +1,153 @@ +# Spec 053 — OSS Repo Improvements (umbrella / work-split) + +**Status:** Decomposition spec — splits the remaining `oss_report.html` backlog into +independent work packages (WPs) so each can be executed in its own session/PR. +**Source:** `file:///Users/user/oss_report.html` (Parts 3.3 + 3.4). +**Date:** 2026-05-22 · **Owner:** @Dumbris + +> This is an **umbrella spec**. Each Track below is independently shippable; when a +> session picks one up, give it its own `specs/-/` spec+plan if non-trivial. +> "Owner: agent" = Claude can do it end-to-end; "Owner: user" = needs an account, +> Stripe, external submission, or human content; "mixed" = agent preps, user finalizes. + +--- + +## Already shipped (context) + +| PR | Delivered | +|----|-----------| +| #487 | Contributor Covenant CoC, issue templates, dependabot, coordinated-disclosure `SECURITY.md` (in `.github/`) → Community Standards 100% | +| #488 | README hero: frosted-tiles banner (`logo.svg`), web-UI demo GIF, macOS screenshots, cross-platform messaging, badge row, `scripts/demo/` pipeline; social-preview uploaded | +| #489 | Repo declutter (deleted report/backup junk, gitignore guards) | + +`CONTRIBUTING.md` (docs/) and `pull_request_template.md` already existed. + +--- + +## Track A — Finish Phase 1 (quick wins) + +### WP-A1 · Kubernetes-style label taxonomy +- **Owner:** agent · **Effort:** S · **Deps:** none +- Add `kind/*`, `area/*`, `priority/*`, `triage/*`, `size/*` + keep `good first issue`/`help wanted`. Define in a checked-in `.github/labels.yml` and sync via an `EndBug/label-sync` (or `crazy-max/ghaction-github-labeler`) workflow so labels are version-controlled. +- **Accept:** `gh label list` shows the taxonomy; a labeler workflow keeps it in sync. + +### WP-A2 · GitHub Sponsors + `FUNDING.yml` +- **Owner:** mixed (user opens Sponsors) · **Effort:** S · **Deps:** Sponsors enabled +- User enables GitHub Sponsors for @Dumbris/org (+Stripe). Then agent adds `.github/FUNDING.yml` (`github: [Dumbris]`, `custom: ["https://mcpproxy.app/sponsor"]`). +- **Accept:** Sponsor button live on the repo. + +### WP-A3 · Move remaining community files into `.github/` (root −2) +- **Owner:** agent · **Effort:** S · **Deps:** none +- `git mv CODE_OF_CONDUCT.md .github/` and `.golangci.yml .github/` (both still detected/honored there). Update `.golangci.yml` references in CI/`scripts/run-linter.sh` if any. +- **Accept:** root file count drops 2; lint + community profile still green. + +--- + +## Track B — Supply-chain security (CI) ← highest leverage for a "security" product + +### WP-B1 · CodeQL workflow +- **Owner:** agent · **Effort:** M · **Deps:** none +- `.github/workflows/codeql.yml` for Go + JavaScript (Vue frontend). Schedule + PR. + +### WP-B2 · OpenSSF Scorecard workflow + README badge +- **Owner:** agent · **Effort:** M · **Deps:** none (publishes results) +- `ossf/scorecard-action` with `publish_results: true`; add the Scorecard badge. + +### WP-B3 · Dependency-review on PRs +- **Owner:** agent · **Effort:** S · **Deps:** none +- `actions/dependency-review-action` gate on PR builds. + +### WP-B4 · Trivy scan for Docker images +- **Owner:** agent · **Effort:** M · **Deps:** none +- `aquasecurity/trivy-action` on `scanner-images.yml`/release image builds. + +### WP-B5 · Pin all GitHub Actions to commit SHAs +- **Owner:** agent · **Effort:** M · **Deps:** none +- 109 `@vN` action refs → 40-char SHAs (Scorecard `Pinned-Dependencies`, highest weight). Use `pin-github-action`/`frizbee`; let dependabot keep them current. +- **Accept:** `Pinned-Dependencies` check passes; dependabot configured for actions (already present). + +### WP-B6 · Verify/harden branch protection on `main` +- **Owner:** mixed (settings) · **Effort:** S · **Deps:** none +- Already requires review (`REVIEW_REQUIRED`). Confirm: required status checks (lint+unit+e2e+CodeQL+Scorecard), linear history, dismiss-stale. Document in `docs/`. + +--- + +## Track C — Release provenance + +### WP-C1 · cosign keyless signing of release artifacts +- **Owner:** agent · **Effort:** M · **Deps:** none +- Sign the checksums file via sigstore keyless in `release.yml` (no GoReleaser migration needed — bolt onto the existing pipeline). + +### WP-C2 · SBOM (Syft) attached to releases +- **Owner:** agent · **Effort:** M · **Deps:** none — `anchore/sbom-action`. + +### WP-C3 · SLSA build provenance +- **Owner:** agent · **Effort:** M · **Deps:** none — `slsa-framework/slsa-github-generator`. + +### WP-C4 · `CHANGELOG.md` via git-cliff +- **Owner:** agent · **Effort:** M · **Deps:** none +- Conventional Commits already in use → generate `CHANGELOG.md` with `git-cliff`, wire into `release.yml`. + +### WP-C5 · commitlint CI check (optional) +- **Owner:** agent · **Effort:** S · **Deps:** none — enforce Conventional Commits on PRs. + +--- + +## Track D — Discovery / distribution (mostly external) + +### WP-D1 · pkg.go.dev + Go Report Card verification +- **Owner:** agent · **Effort:** S — confirm module indexes on pkg.go.dev and the Go Report Card grade; fix lint nits to reach A if needed. + +### WP-D2 · MCP directory submissions +- **Owner:** mixed/user · **Effort:** L · **Deps:** accounts +- PR to `modelcontextprotocol/registry`; `smithery mcp publish`; mcp.so issue; pulsemcp form; mcphunt; glama claim. Agent can draft the registry PR + `server.json`. + +### WP-D3 · Awesome-list PRs +- **Owner:** mixed · **Effort:** M +- `punkpeye/awesome-mcp-servers`, `appcypher/awesome-mcp-servers`, `avelino/awesome-go` (needs Go Report Card A + tests). + +--- + +## Track E — Promotion / launch (user-led; agent can draft) + +### WP-E1 · 3 anchor blog posts +- **Owner:** mixed · **Effort:** L — (a) "Cutting context tokens by 99%", (b) "Defending against Tool Poisoning Attacks", (c) "Why MCP needs a gateway layer". Agent drafts; lives in `mcpproxy.app-website`. + +### WP-E2 · Coordinated 48-hour launch +- **Owner:** user · **Effort:** L — Show HN (Tue–Thu 08–11 ET) → r/mcp + r/LocalLLaMA + r/golang + r/selfhosted → X thread + LinkedIn → email first starrers. Target 500+ stars/24h. + +### WP-E3 · Newsletter / podcast / CFP pitches +- **Owner:** user · **Effort:** M — Golang Weekly, TLDR AI, Ben's Bites, Latent Space; Go Time, Changelog; AI Engineer Summit / GopherCon CFP. + +--- + +## Track F — Monetization (user-led) + +### WP-F1 · Sponsor tiers + `mcpproxy.app/sponsor` page +- **Owner:** user · **Effort:** M — Caddy-style tiers ($25/$249/$999/$3k+); page in `mcpproxy.app-website`. + +### WP-F2 · Sponsor outreach (~30 companies) +- **Owner:** user · **Effort:** L — Anthropic-ecosystem/IDE vendors; risk-mitigation framing (Filippo model). + +### WP-F3 · Auto sponsors mosaic in README (`sponsorkit`) +- **Owner:** agent · **Effort:** S · **Deps:** WP-A2/WP-F1. + +--- + +## Track G — Documentation + +### WP-G1 · Diátaxis restructure of `docs.mcpproxy.app` +- **Owner:** mixed · **Effort:** XL — Tutorials / How-to / Reference / Explanation quadrants; `mcpproxy.app-website`. + +--- + +## Recommended sequencing + +1. **Now, agent-only, this repo:** Track B (B1–B5) + Track C (C1–C4) + A1, A3 — the engineering/security/provenance work that reinforces the product's security positioning and needs no external accounts. Bundle as 2–3 PRs (e.g. "security workflows", "release provenance", "labels+declutter"). +2. **User unblocks:** A2/F1 (open Sponsors) → then F3. +3. **External, batchable:** D1–D3, then the E launch window once B/C give green security badges. +4. **Long-haul:** G1 docs, E1 blog drafts. + +## Non-goals +- License change (stay MIT). No AGPL/SSPL (kills enterprise adoption per report 3.4). +- No GoReleaser migration — extend the existing `release.yml`.