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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @JSONbored
47 changes: 47 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Bug report
description: Report a backend, API, MCP, GitHub App, or signal issue.
title: "[Bug]: "
labels:
- bug
body:
- type: textarea
id: summary
attributes:
label: Summary
description: What is wrong?
validations:
required: true
- type: dropdown
id: area
attributes:
label: Area
options:
- REST API
- MCP
- GitHub App
- Registry sync
- GitHub backfill
- Signal logic
- Tests/CI
- Documentation
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected behavior
validations:
required: true
- type: textarea
id: actual
attributes:
label: Actual behavior
validations:
required: true
- type: textarea
id: validation
attributes:
label: Validation
description: Include commands, status codes, or sanitized logs. Do not include secrets, wallet details, or private tokens.
validations:
required: false
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Security issue
url: https://github.com/JSONbored/gittensory/security/advisories/new
about: Please report security issues privately. Do not open a public issue with secrets or sensitive data.
29 changes: 29 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Feature request
description: Suggest a backend signal, API, MCP, GitHub App, or operational improvement.
title: "[Feature]: "
labels:
- enhancement
body:
- type: textarea
id: problem
attributes:
label: Problem
description: What contributor, maintainer, or repo-owner problem should this solve?
validations:
required: true
- type: textarea
id: proposal
attributes:
label: Proposal
description: Describe the backend behavior, signal, or API shape.
validations:
required: true
- type: checkboxes
id: boundaries
attributes:
label: Boundaries
options:
- label: This is backend-only.
- label: This does not require storing user PATs.
- label: This does not expose wallet details, raw trust scores, or private rankings publicly.
- label: This does not auto-label, auto-close, or auto-merge contributor work.
18 changes: 18 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
version: 2
updates:
- package-ecosystem: npm
directory: /
schedule:
interval: weekly
open-pull-requests-limit: 5
groups:
npm-minor-and-patch:
update-types:
- minor
- patch

- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
open-pull-requests-limit: 5
14 changes: 14 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
## Summary

-

## Validation

- [ ] `npm run test:ci`

## Safety

- [ ] Backend-only change
- [ ] No secrets, wallet details, user PATs, raw trust scores, or private rankings exposed
- [ ] Public text avoids compensation-seeking or optimization-tactic language
- [ ] OpenAPI/MCP behavior updated where needed
46 changes: 46 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: CI

on:
pull_request:
push:
branches:
- main

permissions:
contents: read

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
validate:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5

- name: Setup Node
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
with:
node-version: 24
cache: npm

- name: Install dependencies
run: npm ci

- name: Typecheck
run: npm run typecheck

- name: Test with coverage
run: npm run test:coverage

- name: Worker runtime tests
run: npm run test:workers

- name: MCP package check
run: npm run build:mcp && npm run test:mcp-pack

- name: Audit dependencies
run: npm audit --audit-level=moderate
56 changes: 56 additions & 0 deletions .github/workflows/npm-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Publish MCP Package

on:
push:
tags:
- "mcp-v*.*.*"

permissions:
contents: read
id-token: write

concurrency:
group: npm-publish-${{ github.ref_name }}
cancel-in-progress: false

jobs:
publish:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Checkout
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5

- name: Setup Node
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
with:
node-version: 24
registry-url: https://registry.npmjs.org

- name: Verify release tag
env:
REF_NAME: ${{ github.ref_name }}
run: |
set -euo pipefail
node -e 'const tag=process.env.REF_NAME; if (!/^mcp-v[0-9]+\.[0-9]+\.[0-9]+$/.test(tag)) { throw new Error("Invalid MCP release tag: " + tag); }'
export VERSION="${REF_NAME#mcp-v}"
node -e 'const pkg=require("./packages/gittensory-mcp/package.json"); const expected=process.env.VERSION; if (pkg.version !== expected) { throw new Error("package version " + pkg.version + " does not match tag " + expected); }'

- name: Install dependencies
run: npm ci

- name: Full validation gate
run: npm run test:ci

- name: Packed tarball smoke test
run: |
set -euo pipefail
PACK_JSON="$(npm pack --workspace @jsonbored/gittensory-mcp --json)"
TARBALL="$(node -e 'const fs=require("fs"); const input=fs.readFileSync(0,"utf8"); process.stdout.write(JSON.parse(input)[0].filename)' <<< "$PACK_JSON")"
TMP="$(mktemp -d)"
npm --prefix "$TMP" init -y >/dev/null
npm --prefix "$TMP" install "$PWD/$TARBALL" >/dev/null
"$TMP/node_modules/.bin/gittensory-mcp" --help >/dev/null

- name: Publish with npm trusted publishing
run: npx -y npm@11.15.0 publish --workspace @jsonbored/gittensory-mcp --access restricted
67 changes: 67 additions & 0 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: Pages

on:
push:
branches:
- main
workflow_dispatch:

permissions:
contents: read

concurrency:
group: pages-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
name: Build docs
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
persist-credentials: false

- name: Setup Node
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
with:
node-version: 24
cache: npm

- name: Install dependencies
run: npm ci

- name: Check docs
run: npm run docs:check

- name: Configure Pages
uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0

- name: Build docs
env:
GITTENSORY_SITE_URL: https://jsonbored.github.io/gittensory/
GITTENSORY_SITE_BASE: /gittensory/
run: npm run docs:build

- name: Upload Pages artifact
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
with:
path: site/.vitepress/dist

deploy:
name: Deploy docs
runs-on: ubuntu-latest
needs: build
if: ${{ github.ref == 'refs/heads/main' && vars.GITTENSORY_DOCS_DEPLOY == 'true' }}
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy Pages
id: deployment
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ dist/
.DS_Store
coverage/
*.tsbuildinfo
site/.vitepress/cache/
!migrations/*.sql
12 changes: 12 additions & 0 deletions .gitleaks.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
title = "Gittensory secret scanning"

[extend]
useDefault = true

[[allowlists]]
description = "Public GitHub App OAuth client ID"
regexes = ['''Iv23li574mpdLo2PnVN4''']
paths = [
'''^wrangler\.jsonc$''',
'''^worker-configuration\.d\.ts$''',
]
41 changes: 41 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Contributing

Gittensory is a backend-only project. Contributions should improve the API, GitHub App, MCP
surface, registry/backfill jobs, signal logic, tests, or operational safety.

## Scope

Accepted contribution areas:

- deterministic signal builders for contributors, maintainers, and repo owners
- GitHub App webhook, check-run, and sanitized comment behavior
- registry, bounty, issue, PR, label, queue, and collision ingestion
- Cloudflare Worker, D1, Queue, and scheduled job reliability
- MCP tools and the thin npm MCP wrapper
- test coverage, invariants, fixtures, OpenAPI/MCP contracts, and CI hardening

Out of scope:

- frontend UI work
- public leaderboards
- public wallet or raw trust-score exposure
- auto-labeling, auto-closing, auto-merging, or mutating contributor work
- storing contributor PATs
- public text that implies compensation estimates or optimization tactics

## Quality Bar

- Run `npm run test:ci` before opening a PR.
- Add or update tests for behavior changes.
- Keep API and MCP responses structured and machine-readable.
- Keep public GitHub comments advisory, sanitized, and non-spammy.
- Prefer deterministic, evidence-based rules over opaque scoring.
- Use Conventional Commit style for release-quality changelog output.

## Pull Request Checklist

- The change is backend-only.
- Tests cover the new behavior or regression.
- Public surfaces do not expose secrets, wallet details, raw trust scores, or private rankings.
- Public text avoids compensation-seeking or optimization-tactic language.
- OpenAPI and MCP schemas stay aligned with behavior.
6 changes: 6 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
SPDX-License-Identifier: AGPL-3.0-only

Gittensory is licensed under the GNU Affero General Public License v3.0 only.

The full license text is available at:
https://www.gnu.org/licenses/agpl-3.0.txt
Loading
Loading