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

@foundation0/git

v1.3.4

Published

Foundation 0 Git API and MCP server

Readme

git

@foundation0/git exposes a generated Git API object where methods follow the shape repo.issue.create(...), repo.pr.merge(...), etc.

The API client maps GH-style feature paths to Gitea REST endpoints and executes real HTTP requests through fetch.

Install

Install globally:

pnpm add -g @foundation0/git

Run MCP server through npm without a global install:

npx -y -p @foundation0/git f0-git-mcp --help

Using pnpm:

pnpm dlx @foundation0/git f0-git-mcp --help

Installation in this monorepo

From repo root:

pnpm install

Run tests:

pnpm --filter @foundation0/git test

Quick start

import { createGitServiceApi } from '@foundation0/git'

const api = createGitServiceApi({
  config: {
    platform: 'GITEA',
    giteaHost: 'https://gitea.example.com',
    giteaToken: process.env.GITEA_TOKEN,
  },
  defaultOwner: 'example-org',
  defaultRepo: 'example-repo',
})

You can also import the singleton:

import { gitServiceApi } from '@foundation0/git'

All methods return:

type GitServiceApiExecutionResult = {
  mapping: GitApiFeatureMapping
  request: {
    url: string
    method: string
    headers: Record<string, string>
    query: string[]
    body?: unknown
  }
  status: number
  ok: boolean
  body: unknown
}

Core request shapes

Write methods accept request fields directly (recommended), or you can set the raw request body with data / json / payload / requestBody.

await api.repo.issue.create({
  title: 'Bug report',
  body: 'Describe issue details',
  labels: ['bug'],
})

// equivalent explicit-body form
await api.repo.issue.create({
  data: { title: 'Bug report', body: 'Describe issue details', labels: ['bug'] },
})

Use headers to pass custom headers and query for additional URL params.

await api.repo.issue.list({
  headers: { 'X-Request-Id': 'local' },
  query: { state: 'open', limit: 20, page: 1 },
})

Popular workflow examples

1) Issue lifecycle (most used)

// List issues in the default repo
await api.repo.issue.list()

// Create a new issue
await api.repo.issue.create({
  data: {
    title: 'Login fails with 401',
    body: 'Repro: open login page and click submit.',
    labels: ['bug'],
  },
})

// View an issue
await api.repo.issue.view('17')

// Comment on an issue
await api.repo.issue.comment('17', {
  data: { body: 'We are investigating this now.' },
})

// Edit title/body
await api.repo.issue.edit('17', {
  data: {
    title: 'Login fails with 401 (investigating)',
    body: 'Updated with steps to reproduce.',
  },
})

// Close and reopen
await api.repo.issue.close('17', { reason: 'not_planned' })
await api.repo.issue.reopen('17')

2) Pull request workflow

// Open a pull request
await api.repo.pr.create({
  data: {
    title: 'chore: improve error handling',
    body: 'Adds retries and better messaging.',
    head: 'feature/error-handling',
    base: 'main',
  },
})

// List and inspect PRs
await api.repo.pr.list({ query: { state: 'open' } })
await api.repo.pr.view('42')

// Add a review comment
await api.repo.pr.comment('42', {
  data: { body: 'Looks good, please add one test for this branch.' },
})

// Manage PR lifecycle
await api.repo.pr.close('42')
await api.repo.pr.reopen('42')
await api.repo.pr.merge('42')

3) Release flow

await api.repo.release.create({
  data: {
    tag_name: 'v1.2.0',
    name: 'v1.2.0',
    body: 'Changelog and upgrade notes.',
  },
})

await api.repo.release.list()
await api.repo.release.view('v1.2.0')
await api.repo.release.delete('v1.2.0')

4) Repository setup and sync

// Read current repo
await api.repo.view()

// Create repository for authenticated user
await api.repo.create({ data: { name: 'new-repo', description: 'Automation workspace' } })

// Fork and sync mirror repo
await api.repo.fork()
await api.repo.sync()

5) Team triage with labels

await api.repo.label.listManaged()

await api.repo.label.upsert('priority-high', {
  color: '#d73a4a',
  description: 'Initial escalation label',
})

await api.repo.label.getByName('priority-high')

await api.repo.label.upsert('priority-high', {
  color: '#fbca04',
  description: 'Escalated issue',
})

await api.repo.label.deleteByName('priority-high')

6) Search and discovery

await api.search.issues({
  query: {
    q: 'repo:example-org/example-repo is:open',
    sort: 'created',
  },
})

await api.search.prs({
  query: {
    q: 'repo:example-org/example-repo is:pr is:open',
    sort: 'updated',
  },
})

await api.search.repos({
  query: {
    q: 'name:example-repo',
    limit: 10,
  },
})

7) CI workflow dispatch

await api.workflow.list()
await api.workflow.view('ci.yml')
await api.workflow.run('ci.yml', {
  data: {
    ref: 'main',
  },
})
await api.workflow.disable('ci.yml')
await api.workflow.enable('ci.yml')

8) Security material for automation

await api.secret.list()
await api.variable.list()
await api.variable.set('CANARY', {
  data: {
    value: 'true',
  },
})

Targeting a specific repository

Defaults can be replaced per call by passing owner/repo arguments.

await api.repo.issue.create('acme', 'infra', {
  data: {
    title: 'Issue in another repo',
    body: 'Cross-repo task',
  },
})

Notes

  1. Some endpoints expose top-level methods too (for example api.issue.create(...)), but repo.* is the canonical usage style for this package.
  2. This package currently ships with Gitea mapping, with PLATFORM/GITEA_* configuration ready for multi-platform expansion.
  3. Use the generated feature matrix/spec to discover every mapped command before adding new workflows.