Skip to content
rlsbl.commands.check
On this page

Check command to query package name availability across npm, PyPI, the Go module proxy (pkg.go.dev), and GitHub repository namespaces.

#rlsbl.commands.check

#rlsbl.commands.check

Check command to query package name availability across npm, PyPI, the Go module proxy (pkg.go.dev), and GitHub repository namespaces.

#_request_with_backoff

python
def _request_with_backoff(url, timeout=5, max_retries=3, headers=None)

Wrap urllib.request.urlopen with retry logic for HTTP 429 responses.

On HTTP 429 (Too Many Requests): reads the Retry-After header (seconds). If present, sleeps that long. If absent, uses exponential backoff starting at 2 seconds (2, 4, 8, ...).

On other HTTP errors or non-HTTP errors (URLError, timeout): raises immediately without retrying.

Returns the response object on success, or raises the last exception after exhausting retries.

#_ultranormalize

python
def _ultranormalize(name)

Ultranormalize a package name for typosquatting detection.

Strips all separators (-, _, .), replaces visually ambiguous characters (l, L, i, I -> 1; o, O -> 0), and lowercases the result.

#_generate_ultranorm_variants

python
def _generate_ultranorm_variants(name)

Generate name variants that share the same ultranormalized form.

Starting from the PEP 503 normalized form (lowercase, separators normalized), produces all combinations of ambiguous character substitutions: l <-> 1, o <-> 0, i <-> 1 Returns (variants, capped) where variants is a list of up to 64 variants (excluding the original name) and capped is True when the total combination count exceeded the cap.

#_search_npm_similar

python
def _search_npm_similar(name)

Search the npm registry for packages with conflicting monikers.

Queries the npm search API for packages similar to name, then compares each result's normalized moniker against the candidate's. Returns a list of original package names that conflict.

Raises on failure (network, timeout). The caller is responsible for handling the exception appropriately.

#check_npm_availability

python
def check_npm_availability(name)

Check if an npm package name is available.

Returns {"status": "available"|"taken"|"error", "message"?: str}. Distinguishes 404 (truly available) from network/other errors.

#get_npm_variants

python
def get_npm_variants(name)

Generate common npm name variants for similarity checking.

npm's moniker collision algorithm strips all -, ., and _ characters and lowercases before comparing. We generate:

  1. All separator-swap variants (replace every separator with each of -._)
  2. The fully stripped form
  3. Insertion variants when the name has no separators (insert each of -._

at every interior position so we can detect existing hyphenated packages that would collide)

#check_pypi_availability

python
def check_pypi_availability(name)

Check if a PyPI package name is available.

Uses the Simple API (PEP 503) which correctly returns 200 for registered packages even if they have no releases (unlike the JSON API which 404s).

Returns {"status": "available"|"taken"|"error", "message"?: str}. Distinguishes 404 (truly available) from network/other errors.

#get_pypi_variants

python
def get_pypi_variants(name)

Generate common PyPI name variants for similarity checking.

#check_go_availability

python
def check_go_availability(name)

Check if a Go module path exists on pkg.go.dev.

Returns {"status": "not_found"|"exists"|"error", "message"?: str, "note"?: str}.

Go modules use repository paths (e.g. github.com/user/repo), not a flat claimable namespace, so we report "not found" / "exists" rather than the "available" / "taken" language used for npm and PyPI.

#check_github_availability

python
def check_github_availability(name)

Check if a repository name exists on GitHub.

Searches the GitHub API for repositories with the given name. Returns {"status": "available"|"exists"|"error", "count": int, ...}.

#_check_variants

python
def _check_variants(name, check_fn, get_variants_fn, delay_ms=0)

Check name variants for similarity using the given availability checker.

When delay_ms > 0, bypasses the thread pool and checks variants sequentially with time.sleep(delay_ms / 1000) between checks (no delay before the first check). This avoids triggering registry rate limits when many variants are generated.

Returns a list of variant names that are taken/exist.

#_add_structured_conflicts

python
def _add_structured_conflicts(result, names, rule)

Append {"name": ..., "rule": ...} objects to the unified conflict field.

This is the canonical machine-readable surface: every collision mechanism (npm moniker, pypi separator, pypi ultranorm, stdlib) folds its conflicts into result["structured_conflicts"] via this helper. The list is re-sorted by (name, rule) after each addition, so the final ordering is deterministic regardless of attach-site order — and a name that collides through two mechanisms at once contributes two distinct objects.

#_enumerate_conflicts

python
def _enumerate_conflicts(conflicts)

Render a conflict list as a comma-separated, single-quoted enumeration.

Example: ["foo-bar", "foo.bar"] -> "'foo-bar', 'foo.bar'".

#_classify_variant_collisions

python
def _classify_variant_collisions(name, taken_variants, registry)

Classify taken variants as hard normalization collisions or soft similar names.

Hard collisions are names the registry would reject because they normalize identically to the candidate. Soft similar names merely look alike but are distinct after normalization.

Returns (hard_collisions, soft_similar).

#_check_stdlib_collision

python
def _check_stdlib_collision(name)

Check if a name collides with a Python standard library module.

PEP 503 normalizes both the candidate and each stdlib name, then compares. Returns the stdlib module name on collision, or None.

#_check_single_name

python
def _check_single_name(name, registry, delay_ms=0)

Check a single name on a given registry, returning a structured result.

When delay_ms > 0, variant checks use sequential execution with a delay between requests instead of concurrent threads.

Returns a dict with keys: - name: the package name checked - registry: which registry was checked - status: "available", "taken", "exists", "not_found", or "error" - variants: list of similar names that are taken (npm/pypi only) - reason: why the name is taken/unavailable, or None if available/error. Values: "registered", "stdlib", "moniker", "normalized", "ultranorm" (set by _apply_ultranorm_check), or None. - error: error message if status is "error" (absent otherwise) - note: informational note (go/github only, absent otherwise) - github_count: number of GitHub repos (only when registry is "github") - conflicts: full list of colliding package names (npm moniker collisions only; the machine-readable form of the enumerated note) - conflict_rule: the normalization rule that makes the conflicts collide (accompanies conflicts)

#_registry_display

python
def _registry_display(registry)

Human-readable name for a registry, asked of the target that owns it.

#_format_single_result

python
def _format_single_result(result)

Print the verbose output for a single name check result.

Returns an exit code: 0 = available, 1 = taken/collision, 2 = error.

When status is "error", prints the error message and returns 2 immediately, skipping variant/GitHub output (same behavior as the old sys.exit(1) calls).

#_format_table_row

python
def _format_table_row(result)

Return a compact one-line dict suitable for table rendering.

Keys: name, status. The status is a short human-readable string.

#_apply_ultranorm_check

python
def _apply_ultranorm_check(result, registry, delay_ms)

Apply ultranormalization variant checking to a result dict (in-place).

Always runs for PyPI when the name was initially available. Checks each generated variant against PyPI Simple API, applying a delay between requests. Sets ultranorm_conflicts (list of taken variant names) on the result.

#_result_exit_code

python
def _result_exit_code(result)

Compute the exit code for a single check result without printing.

Mirrors the codes the human formatters return: 2 = error, 1 = taken/exists, 0 = available/not_found.

#_result_to_json

python
def _result_to_json(result, exit_code)

Project a check result dict onto the stable JSON surface for one name+target.

Carries the identity (name, target), status, reason, the unified structured_conflicts field (from the collision mechanisms), the human rule sentences for the tokens present, and the exit-relevant code. Optional keys (note, error, github_count) appear only when set.

#run_cmd

python
def run_cmd(registry, args, flags)

Check package name availability for one registry.

Checks one or more names on registry, warning about similar names. Returns (exit_code, payload) where payload is a list of per-name JSON objects (one per checked name). The caller owns process exit and aggregation across registries — this function never calls sys.exit.

Human output is printed here (byte-identical to prior behavior) unless flags["json"] is set, in which case nothing is printed and the caller renders the accumulated payloads.

More tools from this site

  • claudestream Drive Claude Code from Python: run it as a subprocess and read its output as typed events, with async and sync sessions, sandbox policies, and tools you define in Python
  • claudewheel A TUI Claude Code Launcher that lets you have more than one profile, manage sessions lifecycle, pick the exact CC version, model to use (even older unlisted ones), pick which GitHub account to use, etc.
  • dirstat Fast, single-binary directory statistics CLI: every file under a tree grouped by format, with counts, sizes, and lines of code, as a colored terminal table or as JSON
  • fastware A batteries-included ASGI framework: msgspec JSON, a managed Granian server, dependency injection, SSE, WebSockets, auth, and a test client
  • go-toml-edit Zero-dep TOML editing library for Go with comment preservation
  • howmuchleft The fastest Claude Code statusline: context window, 5-hour, and weekly limit usage as three customizable gradient bars, rendering in about 6 ms
  • orxtra
  • pgdesign
  • predraw Declarative rendering pipeline: describe a scene in JSON and get SVG, PNG and WebP out, with light and dark style tokens, reusable components and text converted to path outlines
  • reposummary Turn a git repository's history into a Markdown journal: pick a time window or revision range and get a readable digest of what changed, optionally narrated by an LLM
  • safegit git wrapper CLI that gives each commit its own temporary index and retries ref updates on conflict, so concurrent agents share one repository
  • saferm Command-line replacement for rm that archives every deletion with a mandatory reason and the context it ran in, so deleted files can be listed, inspected and restored
  • selfdoc Static Site Generator that builds a project's documentation site directly from its source code, so the docs can never drift from the code they describe, with SEO/AEO, first-class blog, search, and cross-project linking built in
  • strictcli
  • stricttest An always-on test-isolation floor: a pytest plugin and a Go env-hygiene module that make a test suite structurally unable to reach real credentials, the real HOME, the network, or the development repository.
  • wesktop A Python framework that turns an ASGI web app into a desktop application, serving it from a local Granian server and displaying it in a native OS window via pywebview
Search