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

@foss.global/interfaces

v2.7.0

Published

Shared TypeScript interfaces and TypedRequest contracts for the foss.global Git platform ecosystem.

Readme

@foss.global/interfaces

Shared TypeScript DTOs and TypedRequest contracts for the foss.global Git platform ecosystem.

This package intentionally contains contracts only. Runtime forge adapters belong in @foss.global/codefeed, and the Git storage/protocol engine belongs in @foss.global/gitmanager.

Issue Reporting and Security

For reporting bugs, issues, or security vulnerabilities, please visit community.foss.global/. This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a code.foss.global/ account to submit Pull Requests directly.

Install

pnpm add @foss.global/interfaces

Usage

import type { data, requests } from '@foss.global/interfaces';

const repo: data.IPublicRepo = {
  id: 1,
  org: 'foss.global',
  name: 'interfaces',
  slug: 'foss.global/interfaces',
  orgAvatarUrl: '',
  description: 'Shared contracts',
  language: 'TypeScript',
  htmlUrl: 'https://code.foss.global/foss.global/interfaces',
  cloneUrl: 'https://code.foss.global/foss.global/interfaces.git',
  sshUrl: 'ssh://[email protected]:29419/foss.global/interfaces.git',
  starsCount: 0,
  forksCount: 0,
  watchersCount: 0,
  openIssuesCount: 0,
  openPrCount: 0,
  releaseCount: 0,
  size: 0,
  defaultBranch: 'main',
  updatedAt: new Date().toISOString(),
  createdAt: new Date().toISOString(),
  archived: false,
  topics: [],
};

type PublicOverviewRequest = requests.IReq_PublicOverview;

Runner and CI contracts

Runner protocol v1 is exposed through runnerProtocolVersion. The package root and the data namespace both export the complete runner and CI DTO set:

import {
  runnerProtocolVersion,
  type IClaimJobResponse,
  type ICiEnqueueJobRequest,
  type IRegisterRunnerRequest,
} from '@foss.global/interfaces';

const registration: IRegisterRunnerRequest = {
  registrationRequestId: 'registration-1',
  protocolVersion: runnerProtocolVersion,
  runnerVersion: '0.1.0',
  name: 'linux-amd64-1',
  labels: ['linux', 'amd64'],
  capabilities: {
    executor: 'oci',
    runtime: 'docker',
    networks: ['none', 'bridge'],
    sourceArchives: ['tar.gz'],
    artifacts: false,
    caches: false,
    serviceContainers: false,
  },
};

const enqueue: ICiEnqueueJobRequest = {
  idempotencyKey: 'build-main-1',
  tenantId: 'foss.global',
  repositoryId: 'foss.global/interfaces',
  requiredLabels: ['linux', 'amd64'],
  job: {
    image: 'node:24',
    command: ['pnpm', 'test'],
    network: 'none',
  },
};

type ClaimedJob = IClaimJobResponse;

The runner lifecycle contracts cover registration, sessions, runner and job heartbeats, claim/lease identity, fencing tokens, ordered log chunks, completion, abandonment, and recovery. The CI control-plane contracts cover job enqueue and summaries, log pages, cancellation, and runner drain state.

Protocol v1 describes OCI execution with Docker or Podman and tar.gz source archives. Artifacts, caches, and service containers are explicitly unsupported in the v1 capability shape. Supported job network modes are none and bridge; the execution service remains responsible for enforcing the advertised capability.

GitManager ref inventory contracts

IGitManagerRefRequest, IGitManagerRef, and TGitManagerRefInventoryResult describe a complete, paginated ref inventory. Without prefixes, every ref under refs/ is listed, including notes, pull, keep-around, and provider-internal namespaces. HEAD is reported separately in head. Annotated tags carry their fully peeled object. Symbolic refs carry their target ref name; a symbolic ref whose target does not resolve is still listed, with a null objectId and objectType.

import type {
  IGitManagerRef,
  IGitManagerRefRequest,
  TGitManagerRefInventoryResult,
} from '@foss.global/interfaces';

declare function listRefs(
  request: IGitManagerRefRequest,
): Promise<TGitManagerRefInventoryResult>;

const collectRefs = async (): Promise<IGitManagerRef[]> => {
  const refs: IGitManagerRef[] = [];
  let cursor: string | undefined;
  while (true) {
    const result = await listRefs({ org: 'foss.global', repo: 'interfaces', cursor });
    if (result.status === 'stale') {
      refs.length = 0;
      cursor = undefined;
      continue;
    }
    refs.push(...result.refs);
    if (result.pagination.status === 'exhausted') {
      return refs;
    }
    cursor = result.pagination.cursor;
  }
};

// A complete ref name as the only prefix is an exact lookup.
const main = await listRefs({
  org: 'foss.global',
  repo: 'interfaces',
  prefixes: ['refs/heads/main'],
});

Prefixes match whole path components, so refs/heads/ma does not select refs/heads/main. Overlapping prefixes select their de-duplicated union, and an empty prefixes array is rejected as invalid. Pages are sorted by ref name in byte order and each carries inventoryDigest, the SHA-256 of the complete selection defined on IGitManagerRefInventoryPage. A cursor is opaque and bound to the repository, the prefix set, and that digest. When the selected refs or HEAD change between pages, the next call returns status: 'stale' instead of a page that would mix two states; the caller restarts without a cursor. A cursor is a transport continuation, not a durable replication checkpoint.

GitManager remote transfer and size contracts

IGitManagerImportMirrorRequest and IGitManagerRefreshMirrorRequest take IGitManagerRemoteTransferOptions: an optional credential (TGitManagerRemoteCredential, HTTP Basic), optional caCertificates (PEM, used as Git's CA bundle for that transfer) and an optional timeoutMs (default 120000, at most 21600000). A credential reaches Git only through the Git process environment as an Authorization header, so it never appears in the remote URL, on a command line, in the repository's Git config, or in an error. It requires an https remote without user information, and Git does not follow redirects while it carries one. A refresh reuses the mirror's stored remote URL.

IGitManagerRepositorySize measures a repository's object database: objectCount distinct objects, objectBytes (their uncompressed sizes, which do not depend on packing) and storageBytes (every file of the object database, which does).

GitManager atomic push and default branch contracts

IGitManagerAtomicPushRequest pushes IGitManagerAtomicPushRefUpdates from a managed repository to remoteUrl as one transaction: the remote applies every update or none, and a remote that does not advertise the atomic capability is refused rather than pushed to ref by ref. Every update is leased: expectedOldObjectId is the object the remote ref must point at now (null to create a ref that must not exist), and newObjectId is the object to set (null to delete). The URL is used for that push only; it must be https, or http to a loopback host. The transfer options are those of importMirror, except that a push credential is also accepted for loopback http.

IGitManagerAtomicPushResult is applied when every ref is ok and rejected when no ref changed. Each IGitManagerAtomicPushRefResult is ok, stale (the lease failed) or rejected (a hook, ref protection, or another ref of the same push failed), with the remote's reason as message. Every ref that is not ok also carries a classified TGitManagerAtomicPushRefReason: stale-lease, atomic-collateral (refused only because another ref failed), transaction-failed (the remote could not commit, typically a concurrent change; read the remote back), hook-declined, non-fast-forward, local-rejected or remote-rejected for any other refusal.

IGitManagerSetDefaultBranchRequest points a repository's HEAD at an existing branch, named as in IGitManagerRepositoryInfo.defaultBranch. With allowUnborn: true the branch may not exist yet: HEAD then names it unborn until a push creates it, so that one atomic push can create the new default branch and delete the old one, which Git refuses while HEAD names the old one.

An IGitManagerProtectedRefViolation names a ref update that the protected ref rules refuse and the TGitManagerProtectedRefViolationRule it breaks: create, delete, force-push (the old object is not an ancestor of the new one) or not-a-commit. GitManager decides it with the same check its pre-receive hook enforces.

Origin contracts

TOriginState records where a native entity came from: native, imported with an IOriginRef, or unknown, which never means native. An IOriginRef names the source by the operator-minted forge connection instanceId, the entityKind (repository), the source entityId (a Gitea repository's decimal ID) and parentId (null for repositories, whose Gitea IDs are unique per instance). It carries no URLs, paths, configuration or run IDs, digests, or authority.

Forge inventory contracts

IForgeInventoryReport, IForgeInventoryPage<TItem>, IForgeInventoryNamespace, IForgeInventoryRepository and IForgeInventoryIssue describe operator inventory observations. They are exported from both the package root and data. This package supplies types; it does not scan a forge or validate network responses.

Stable provider identifiers are opaque strings qualified by instance and ID namespace. Mutable paths remain separate segment arrays, preserving GitLab subgroups and literal hyphens. A source without a stable identifier reports an unresolved identity. URLs must be credential-free, and inventory responses need operator authorization rather than anonymous public exposure.

Issue observations separate the provider row ID from its repository-local number (GitLab iid) and retain the repository identity. They preserve empty body text, unknown metadata, open/closed state, provider issue classification, confidentiality, reported author identity and provider content timestamps. The reported author does not prove original attribution for previously imported issues. Comments, labels, milestones, assignees, attachments and history require their own inventory and preservation work; this metadata DTO does not claim that those collections or external writes are implemented.

Every canonical entity class has an explicit capability and collection result, including classes not inspected or unavailable. Additional provider features have their own entries. enumerated means the selected collection was exhausted for its recorded visibility scope; a public or caller-visible live scan does not establish a complete frozen migration inventory. Page continuation, exhaustion, and interrupted enumeration have distinct discriminated shapes.

Counts and byte quantities use nonnegative decimal strings to avoid JSON integer precision loss. Unknown size differs from zero, and estimated repository storage size is not the size of a future Git push. Runtime adapters must validate values, scope consistency, capability/result agreement, cursor binding, diagnostics, and authorization. These DTOs do not establish replication authority, historical import fidelity, checksummed manifests, or durable recovery checkpoints.

Forge source inventory contracts

IForgeSourceInventoryReport is the authenticated, read-only measurement of a source forge before its one-time migration, read with a site administrator's token. It counts users, organizations, teams, memberships, keys, packages by type, and per repository the Git refs and objects, LFS objects, issues, pull requests, comments, reviews, reactions, attachments, releases (drafts included) with asset bytes, wiki pages, access settings, webhooks, push mirrors, Actions settings, and the Actions runs and artifacts that are archived rather than migrated.

Every count is a TForgeSourceMeasure: complete with a decimal-string value, partial with the value observed before a retryable failure, or notMeasured when no read was attempted. inventoryComplete is true only when discovery finished and no measure is partial or not measured; incompleteReasons lists why not. limitations names source data the provider exposes to no administrator read and that is reissued rather than migrated, such as Gitea's user-scoped Actions secrets; everything readable is a measure instead. Reasons are sanitized text, never raw response bodies or URLs.

Git counts other than the forge-reported size, and LFS counts, are read at the Git level from a mirror clone of every advertised ref: refs by namespace, distinct objects and their uncompressed bytes, and the LFS objects that pointers in any reachable revision reference. LFS objects are checked through the forge's LFS batch API and split into held objects with their bytes and missingObjects, which cannot be migrated.

The same mirror records the repository's head, an IForgeSourceRepositoryHead: the ref HEAD names as target (null when HEAD is detached or not symbolic) and whether it resolves. An empty repository's HEAD is unborn and does not resolve; in any other repository a HEAD that does not resolve names a missing branch, such as a default branch deleted at the source, and an import's HEAD diverges from the source at apply time until the source names an existing branch. A target that differs from the API's defaultBranch shows that the forge's setting and its Git HEAD disagree. head is null when the mirror was not measured and absent in reports from generators that predate it.

Beside its counts, a repository records each release as an IForgeSourceRelease in releaseRecords, drafts included: the source ids, tag, target, name, body, flags, the forge's creation and publication times, an IForgeSourceReleaseAuthor snapshot (the source account's id and login, never a native user) and its IForgeSourceReleaseAssets with their storage uuid, name as stored, size and download count. The forge exposes no asset digest, so none is recorded; a consumer verifies content itself. The download count moves with every download and never decides whether a release changed. protections records, as read, the branch and tag protection rules that access counts: an IForgeSourceBranchProtection keeps the rule name (an exact name or a glob), whether anyone may push or force-push, every allowlist with its switch, and the review, status check, signing and file pattern restrictions; an IForgeSourceTagProtection keeps its name pattern and allowlist. Whether a rule can be enforced natively is the consumer's verdict. Releases, assets and tag rules sort by numeric id, branch rules by name in code-unit order. Both are null when their counts are not complete and absent in reports from generators that predate them.

Owners are a TForgeSourceOwnerInventory union: an organization carries its members, teams, team memberships and repository grants, labels and Actions secret count; a user carries its account flags and SSH and GPG key counts. Both carry repositories, webhooks, Actions variables, runners and packages by type. totals.owners sums the owner-level counts; the repository-shaped totals sum repositories only.

A run first reads IForgeSourceInventoryDiscovery, then measures independent TForgeSourceInventoryUnits (the instance, each owner and each repository). A failed unit, or one holding a partial measure, is measured again on resume. Discovery records each repository's id as a decimal string and its unit carries it, so a unit whose name now answers with another id fails instead of measuring the repository that took the name. id is absent in discoveries from generators that predate it; a consumer that keys on ids refuses those. IForgeSourceInventory is deterministic: it carries no run timestamps (the source's own times, such as release creation, are source state), owners sort by kind and name, repositories by owner and name. The report adds collisionCheck, the source owner and repository names that already exist natively, exactly or case-insensitively, sorted by subject, source and native name. A report is a complete planning basis only when inventoryComplete is true and the collision check ran.

A report never contains secret values, credentials, tokens, private keys, Actions secret or variable values, webhook secrets, or mirror remote URLs.

Exports

  • data: public DTOs for users, organizations, repositories, contents, commits, diffs, releases, issues, activity, news, stats, codefeed commit results, GitManager repository/read/push API results, origin references, forge and forge source inventories, and runner/CI contracts.
  • requests: TypedRequest contracts for codefeed, publicOverview, publicOrg, publicRepo, publicFile, and publicCommits.
  • Barrel exports: all public data and request interfaces are also exported from the package root.

Testing

pnpm test
pnpm run build

License and Legal Information

This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the repository license file.

Please note: The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.

Trademarks

This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.

Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.

Company Information

Task Venture Capital GmbH Registered at District Court Bremen HRB 35230 HB, Germany

For any legal inquiries or further information, please contact us via email at [email protected].

By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.