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

@getunblocked/sdk

v0.1.5

Published

Lightweight TypeScript SDK for the Unblocked Public API.

Readme

Unblocked TypeScript SDK

Lightweight TypeScript wrapper for the Unblocked Public API.

The SDK uses the same API token authentication as the public API: pass a Personal Access Token or Team Access Token as a bearer token. You can pass the token explicitly or set UNBLOCKED_API_TOKEN.

Install

bun add @getunblocked/sdk
# or: npm install @getunblocked/sdk

The package is a public scoped package on npm. The compiled dist/ is committed to the repo too, so a direct git install needs no build step and pulls in no dependencies (the SDK has zero runtime dependencies):

bun add git+ssh://[email protected]/unblocked/unblocked-typescript-sdk.git#v0.1.0

Always pin a tag (e.g. #v0.1.0) for git installs so they're reproducible — omitting it tracks the default branch.

The github:owner/repo shorthand and plain https git URLs go through GitHub's unauthenticated tarball API, which 404s on a private repo. Use the git+ssh:// URL above (or a tokenized https URL) so a git install authenticates.

Public template extraction: now that the SDK package is public, examples/eve-pr-triage can be extracted into its own repo (unblocked/eve-pr-triage-agent, configured as a GitHub template repo for the "Use this template" button — no -template suffix; keep eve in the name for harness discoverability). Swap its @getunblocked/sdk dependency from file:../.. to the published package and drop the predeploy/postdeploy tarball step. Leave a link-out here and in docs/agent-frameworks.md. The extraction's benefits (Vercel deploy button, public showcase, own issue tracker) switch on once the SDK is public.

When the GitHub repo goes public: enable npm provenance — add id-token: write to the permissions block in publish.yml and --provenance to the npm publish step. Provenance is blocked while the source repo is private (the attestation publishes repo/workflow metadata to the public Sigstore log), even though the npm package itself is public.

Quickstart

import Unblocked from "@getunblocked/sdk";

const unblocked = new Unblocked({
  apiKey: process.env.UNBLOCKED_API_TOKEN,
});

const research = await unblocked.context.research({
  query: "How does the user authentication system work?",
});

console.log(research.summary);
for (const source of research.sources) {
  console.log(source.content);
  console.log(source.url);
}

const code = await unblocked.context.search.code({
  query: "rate limiting",
});

const urls = await unblocked.context.get.urls({
  urls: ["https://my.company.com/apollo/ticket/123456"],
});

The same flow is available as a runnable script — from a clone of this repo (no install or build step needed):

UNBLOCKED_API_TOKEN=unb_... node examples/quickstart.mjs "How does auth work?"

Documentation

Detailed guides live in docs/:

Authentication

Unblocked supports Personal Access Tokens and Team Access Tokens. Both are sent as:

Authorization: Bearer <token>

The client resolves tokens in this order:

  1. new Unblocked({ apiKey })
  2. new Unblocked({ token })
  3. UNBLOCKED_API_TOKEN
  4. UNBLOCKED_API_KEY

apiKey and token can also be async token providers:

const unblocked = new Unblocked({
  apiKey: async () => getTokenFromSecretManager(),
});

Client Options

const unblocked = new Unblocked({
  apiKey: process.env.UNBLOCKED_API_TOKEN,
  baseUrl: "https://getunblocked.com/api",
  timeoutMs: 30_000,
  maxRetries: 2,
  retryDelayMs: 500,
  fetch: globalThis.fetch,
});

GET, PUT, and DELETE requests retry transient network failures and 408, 429, 500, 502, 503, and 504 responses. POST and PATCH are not retried by default because they are not generally safe to replay.

API Surface

const unblocked = new Unblocked();

await unblocked.context.research({ query, instruction, effort });

await unblocked.context.search.code({ query, instruction });
await unblocked.context.search.prs({ query, instruction });
await unblocked.context.search.issues({ query, instruction });
await unblocked.context.search.documentation({ query, instruction });
await unblocked.context.search.messages({ query, instruction });

await unblocked.context.query.issues({ query, projects, user_name });
await unblocked.context.query.prs({ query, projects, user_name });

await unblocked.context.get.urls({ urls });
await unblocked.context.get.rules({ repoName, ruleId, task, language, paths });

Search, query, and get methods resolve to { sources: ContextSearchSource[] }. Research also returns a summary and the effort used:

const research = await unblocked.context.research({ query: "How does auth work?" });

research.summary;   // string
research.sources;   // [{ content, title?, url?, sourceType?, provider? }, ...]
research.effort;    // "low" | "medium" | "high"

const code = await unblocked.context.search.code({ query: "rate limiting" });
code.sources;       // [{ content, title?, url?, sourceType?, provider? }, ...]

See docs/context.md for the full surface and effort levels.

Low-Level Requests

The resource methods cover the public API, but the client also exposes typed request helpers for new endpoints or advanced callers:

const result = await unblocked.request("POST", "/tools/context/research", {
  body: { query: "How does auth work?" },
});

Agent Frameworks

The SDK exports plain functions and JSON-schema-shaped descriptors so frameworks can adapt them without pulling in framework-specific dependencies.

import { createUnblockedTools, unblockedToolSchemas } from "@getunblocked/sdk";

const tools = createUnblockedTools({
  apiKey: process.env.UNBLOCKED_API_TOKEN,
});

export const research = {
  ...unblockedToolSchemas.research,
  execute: tools.research,
};

For frameworks such as Flue or Eve, put the wrapper above in the framework's TypeScript tool file and let that framework handle its own tool registration conventions.

See examples/quickstart.mjs for a minimal runnable script, and examples/context-research-tool.ts for the tool-module pattern above.

For a full local programmable-harness demo, see examples/flue-bug-triage. For a deployable GitHub-App-webhook PR-triage agent that makes Unblocked context a required triage step, see examples/eve-pr-triage.

Runtime Support

  • ESM package
  • No runtime dependencies
  • Uses the platform fetch
  • Requires Node.js 18+ or any runtime with fetch

Error Handling

Non-2xx API responses throw UnblockedApiError with status, statusText, response headers, parsed response body, and requestId (the X-Request-ID header). The thrown error is a status-specific subclass — UnblockedBadRequestError (400), UnblockedAuthenticationError (401), UnblockedPermissionDeniedError (403), UnblockedNotFoundError (404), UnblockedRateLimitError (429), and UnblockedServerError (5xx) — all extending UnblockedApiError. Request timeouts throw UnblockedTimeoutError.

import { UnblockedApiError, UnblockedTimeoutError } from "@getunblocked/sdk";

try {
  await unblocked.context.research({ query: "How does auth work?" });
} catch (error) {
  if (error instanceof UnblockedApiError) {
    console.error(error.status, error.body, error.requestId);
  } else if (error instanceof UnblockedTimeoutError) {
    console.error(error.message);
  }
}

See docs/errors-and-retries.md for the full subclass table.