Modules¶
An overview of the packages that make up olink.
The API reference below is generated automatically from the source docstrings.
Core (olink.core)¶
Domain logic: git remote parsing, ecosystem detection, target definitions, the target registry, custom exceptions, and pinned-target persistence.
Project metadata: git remotes, ecosystem detection, package name extraction.
Git note: This module reads .git/config directly instead of calling git commands. This is faster but has limitations: - Supports [url “…”].insteadOf rewrites (longest-match prefix wins). - Does not support [include] directives in git config (no recursive merging). - Recognized platforms: github, gitlab, bitbucket, gitea, forgejo (incl. codeberg).
Hostname heuristic falls back when host is not the canonical SaaS one (self-hosted GitHub Enterprise, GitLab CE, Gitea, Forgejo).
GitLab subgroups (e.g., group/subgroup/repo) are parsed as owner=”group” and repo=”subgroup/repo”. The generated URL https://host/group/subgroup/repo is correct for GitLab, but may not work for other platforms with nested paths.
- class olink.core.project.EcosystemConfig(name, display_name, config_file, get_package_name, extra_signals=())[source]¶
Bases:
objectConfiguration for an ecosystem.
config_file is the canonical filename (or glob) used by the simple existence check. extra_signals lists additional filename globs that also count as “ecosystem present” — used for ecosystems where multiple, equally-valid metadata layouts exist (e.g. CPAN’s Makefile.PL / dist.ini / lib/*.pm).
- Parameters:
- class olink.core.project.ParsedRemote(platform, host, owner, repo)[source]¶
Bases:
objectParsed git remote URL.
- olink.core.project.detect_ecosystems(cwd)[source]¶
Detect which ecosystems are present in the given directory.
- olink.core.project.get_open_vsx_name(cwd)[source]¶
Build publisher.name extension id from package.json.
Open VSX (and VS Code Marketplace) identify extensions by publisher + name. Both fields required — raises ProjectMetadataError if either missing. Caller must split on ‘.’ to extract URL components.
- olink.core.project.get_package_name(cwd, ecosystem)[source]¶
Get the package name for a specific ecosystem.
- olink.core.project.get_remote_url(cwd, remote_name='origin')[source]¶
Get the URL for a git remote, applying [url].insteadOf rewrites if configured.
- olink.core.project.parse_remote_url(url)[source]¶
Parse a git remote URL into its components.
- Parameters:
url (str)
- Return type:
All target definitions.
- class olink.core.targets.ActionsTarget[source]¶
Bases:
GitPageTargetOpen the CI/CD page (Actions, Pipelines).
- class olink.core.targets.BranchesTarget[source]¶
Bases:
GitPageTargetOpen the branches page.
- class olink.core.targets.BundlephobiaTarget[source]¶
Bases:
TargetOpen Bundlephobia (browser bundle size analyzer). Requires package.json.
- class olink.core.targets.ClickPyTarget[source]¶
Bases:
TargetOpen ClickPy ClickHouse-backed stats dashboard. Requires pyproject.toml.
- class olink.core.targets.CodecovTarget[source]¶
Bases:
TargetOpen the Codecov page for the project.
Codecov only integrates with GitHub, GitLab, and Bitbucket. Self-hosted forges (Gitea, Forgejo, Codeberg) are unsupported — raise rather than emit a 404 URL.
- class olink.core.targets.CommitsTarget[source]¶
Bases:
GitPageTargetOpen the commit history.
- class olink.core.targets.CoverallsTarget[source]¶
Bases:
TargetOpen the Coveralls page for the project.
Coveralls only integrates with GitHub, GitLab, and Bitbucket. Self-hosted forges (Gitea, Forgejo, Codeberg) are unsupported — raise rather than emit a 404 URL.
- class olink.core.targets.CpanTarget[source]¶
Bases:
TargetSurface MetaCPAN lookup for Perl dependencies from lightweight cpanfile metadata.
- class olink.core.targets.CratesTarget[source]¶
Bases:
TargetOpen crates.io crate page. Requires Cargo.toml with [package].name.
- class olink.core.targets.DepsDevTarget(ecosystem=None)[source]¶
Bases:
MultiEcosystemTargetGoogle deps.dev — dependency graph and security info.
- Parameters:
ecosystem (str | None)
- class olink.core.targets.DiscussionsTarget[source]¶
Bases:
GitPageTargetOpen the discussions page.
- class olink.core.targets.DocsRsTarget[source]¶
Bases:
TargetExpose docs.rs so Rust users can jump directly to hosted API docs.
- class olink.core.targets.EcosystemsTarget(ecosystem=None)[source]¶
Bases:
MultiEcosystemTargetecosyste.ms registry index. Uses host-style ecosystem slugs (pypi.org, npmjs.org).
- Parameters:
ecosystem (str | None)
- class olink.core.targets.GemsTarget[source]¶
Bases:
TargetOpen rubygems.org gem page. Requires *.gemspec with spec.name = “…”.
- class olink.core.targets.GitPageTarget[source]¶
Bases:
TargetBase for targets that open a specific page on the git hosting platform.
Subclasses set _page to a key in PLATFORM_URLS. Resolution raises UnsupportedFeatureError when the page is unavailable on the detected platform (e.g. discussions on GitLab).
- class olink.core.targets.GoDocsTarget[source]¶
Bases:
TargetProvide an intuitive alias for Go users who look for docs-oriented target names.
- class olink.core.targets.GoPkgTarget[source]¶
Bases:
TargetExpose pkg.go.dev so Go maintainers can inspect published module docs.
- class olink.core.targets.HackageTarget[source]¶
Bases:
TargetHelp Haskell maintainers inspect package metadata directly on Hackage.
- class olink.core.targets.HexTarget[source]¶
Bases:
TargetOpen hex.pm (Elixir) package page. Uses OTP app: atom from mix.exs.
- class olink.core.targets.InspectorTarget[source]¶
Bases:
TargetOpen PyPI Inspector (browse package source/files). Requires pyproject.toml.
- class olink.core.targets.IssuesTarget[source]¶
Bases:
GitPageTargetOpen the issues page.
- class olink.core.targets.JsDelivrTarget[source]¶
Bases:
TargetShortcut CDN package inspection for frontend dependency debugging workflows.
- class olink.core.targets.LibRsTarget[source]¶
Bases:
TargetOpen lib.rs (alternative crates.io browser, faster UX). Requires Cargo.toml.
- class olink.core.targets.LibrariesIOTarget(ecosystem=None)[source]¶
Bases:
MultiEcosystemTargetLibraries.io aggregate package page. Slugs match ecosystem keys 1:1.
- Parameters:
ecosystem (str | None)
- class olink.core.targets.MavenTarget[source]¶
Bases:
TargetExpose Maven Central pages for JVM artifacts based on standard project coordinates.
- class olink.core.targets.MultiEcosystemTarget(ecosystem=None)[source]¶
-
Base class for targets that support multiple ecosystems.
Supports suffix notation: target:ecosystem e.g., snyk:pypi, deps:npm, libraries-io:cargo
- Parameters:
ecosystem (str | None)
- class olink.core.targets.NPMStatTarget[source]¶
Bases:
TargetOpen npm-stat download charts. Uses ?package=<name> query string.
- class olink.core.targets.NPMTarget[source]¶
Bases:
TargetOpen npmjs.com package page. Handles scoped names (@org/pkg) via _encode_name.
- class olink.core.targets.NuGetTarget[source]¶
Bases:
TargetOpen NuGet (.NET) package page. Falls back to *.csproj filename when <PackageId> absent.
- class olink.core.targets.OpenVSXTarget[source]¶
Bases:
TargetEnable extension authors to jump from local metadata straight to Open VSX listings.
- class olink.core.targets.OriginTarget[source]¶
Bases:
TargetOpen the remote origin URL.
Reads .git/config; raises NotGitRepoError outside a repo, NoRemoteError if ‘origin’ is not configured.
- class olink.core.targets.PackagephobiaTarget[source]¶
Bases:
TargetOpen Packagephobia (install size). Uses ?p=<name> query — urlencode handles scoped names.
- class olink.core.targets.PackagistTarget[source]¶
Bases:
TargetOpen Packagist PHP package page. Composer name format vendor/package preserved.
- class olink.core.targets.PePyTarget[source]¶
Bases:
TargetOpen PePy.tech download stats. Requires pyproject.toml.
- class olink.core.targets.PiWheelsTarget[source]¶
Bases:
TargetExpose piwheels so Python projects can validate Raspberry Pi package availability.
- class olink.core.targets.PipTrendsTarget[source]¶
Bases:
TargetOpen piptrends.com download trends. Requires pyproject.toml.
- class olink.core.targets.PubTarget[source]¶
Bases:
TargetOpen pub.dev (Dart/Flutter) package page. Requires pubspec.yaml.
- class olink.core.targets.PullsTarget[source]¶
Bases:
GitPageTargetOpen the pull/merge requests page.
- class olink.core.targets.PyPIJSONTarget[source]¶
Bases:
TargetOpen the JSON API endpoint for the package — useful for CI scripts and metadata checks.
- class olink.core.targets.PyPIStatsTarget[source]¶
Bases:
TargetOpen pypistats.org download charts. Requires pyproject.toml.
- class olink.core.targets.PyPITarget[source]¶
Bases:
TargetOpen the canonical PyPI project page. Requires pyproject.toml with [project].name.
- class olink.core.targets.ReleasesTarget[source]¶
Bases:
GitPageTargetOpen the releases page.
- class olink.core.targets.RubyGemsStatsTarget[source]¶
Bases:
TargetExpose RubyGems usage stats to help maintainers gauge adoption quickly.
- class olink.core.targets.SafetyDBTarget[source]¶
Bases:
TargetOpen Safety DB vulnerability page for the PyPI package. Requires pyproject.toml.
- class olink.core.targets.SecurityTarget[source]¶
Bases:
GitPageTargetOpen the security page.
- class olink.core.targets.SkypackTarget[source]¶
Bases:
TargetSupport quick compatibility checks against Skypack’s ESM package view.
- class olink.core.targets.SnykTarget(ecosystem=None)[source]¶
Bases:
MultiEcosystemTargetSnyk security advisor. Snyk uses non-obvious slugs (npm-package, golang, rust).
- Parameters:
ecosystem (str | None)
- class olink.core.targets.SocketTarget(ecosystem=None)[source]¶
Bases:
MultiEcosystemTargetExpose Socket.dev package risk pages across major ecosystems from one target.
- Parameters:
ecosystem (str | None)
- class olink.core.targets.Target[source]¶
Bases:
ABCBase class for all targets.
Subclasses set name (CLI identifier) and description (help text), then implement get_url(cwd). Implementations MUST raise OlinkError subclasses (NoRemoteError, ProjectMetadataError, UnsupportedFeatureError) rather than generic exceptions — CLI relies on the hierarchy for user-facing messages.
- abstract get_url(cwd)[source]¶
Return the URL to open for this target, given a project directory.
- Parameters:
- Raises:
OlinkError – Subclass appropriate to the failure (missing config, unsupported platform, etc.). Never a generic Exception.
- Return type:
- class olink.core.targets.UnpkgTarget[source]¶
Bases:
TargetGive maintainers a direct view of published npm artifacts as served by UNPKG.
- class olink.core.targets.UpstreamTarget[source]¶
Bases:
TargetOpen the upstream remote URL (fork workflows where origin = your fork).
Raises NoRemoteError if ‘upstream’ remote is not configured.
- class olink.core.targets.WikiTarget[source]¶
Bases:
GitPageTargetOpen the wiki page.
- olink.core.targets.get_platform_url(base_url, platform, page)[source]¶
Get URL for a specific page on a platform.
Target catalog - explicit registration of all targets.
- olink.core.catalog.get_target(name)[source]¶
Get a target instance by name.
Supports suffix notation for multi-ecosystem targets: - “snyk” - auto-detect ecosystem - “snyk:pypi” - explicit Python ecosystem - “deps:npm” - explicit npm ecosystem
- olink.core.catalog.list_available_targets(cwd)[source]¶
List targets available for the current project.
Returns (name, description, target_cls, ecosystem) tuples.
Custom exceptions for olink.
- exception olink.core.exceptions.NoRemoteError[source]¶
Bases:
OlinkErrorNo git remote configured.
- exception olink.core.exceptions.NotGitRepoError[source]¶
Bases:
OlinkErrorNot inside a git repository.
- exception olink.core.exceptions.ProjectMetadataError[source]¶
Bases:
OlinkErrorCould not read project metadata.
- exception olink.core.exceptions.UnknownPlatformError[source]¶
Bases:
OlinkErrorUnknown git hosting platform.
- exception olink.core.exceptions.UnknownTargetError[source]¶
Bases:
OlinkErrorUnknown target specified.
- exception olink.core.exceptions.UnsupportedFeatureError[source]¶
Bases:
OlinkErrorFeature not available on this platform.
Global pin persistence.
Pins are the first user-global state olink stores (everything else is derived from project files). Kept as a plain ordered JSON list so it can be edited by hand and rewritten from scratch. Failures here must never break the TUI, so read errors degrade to an empty list rather than raising.
- olink.core.pins.config_dir()[source]¶
Resolve olink’s config directory, honoring XDG_CONFIG_HOME.
- Return type:
- olink.core.pins.load_pins()[source]¶
Return pinned target names in order; empty on missing/corrupt/unreadable.
- olink.core.pins.pins_file()[source]¶
Path to the JSON file holding the ordered list of pinned target names.
- Return type:
CLI (olink.cli)¶
Typer command-line interface.
CLI interface for olink.
- olink.cli.app.main_callback(target=<typer.models.ArgumentInfo object>, directory=<typer.models.OptionInfo object>, dry_run=<typer.models.OptionInfo object>, list_available_flag=<typer.models.OptionInfo object>, list_all_flag=<typer.models.OptionInfo object>, _version=<typer.models.OptionInfo object>)[source]¶
Open external URLs related to your project.
TUI (olink.tui)¶
Textual terminal user interface.
Main TUI application.
- class olink.tui.app.OlinkTUI(cwd)[source]¶
Bases:
App[None]Main TUI application managing state and widget composition.
Create an instance of an app.
- Parameters:
driver_class¶ – Driver class or None to auto-detect. This will be used by some Textual tools.
css_path¶ – Path to CSS or None to use the CSS_PATH class variable. To load multiple CSS files, pass a list of strings or paths which will be loaded in order.
watch_css¶ – Reload CSS if the files changed. This is set automatically if you are using textual run with the dev switch.
ansi_color¶ – Allow ANSI colors if True, or convert ANSI colors to RGB if False, None to use “ansi” parameter from themes.
cwd (str)
- Raises:
CssPathError – When the supplied CSS path(s) are an unexpected type.
- BINDINGS: ClassVar[list[BindingType]] = [Binding(key='q', action='quit', description='Quit', show=True, key_display=None, priority=False, tooltip='', id=None, system=False, group=None), Binding(key='tab', action='toggle_mode', description='Toggle view', show=True, key_display=None, priority=True, tooltip='', id=None, system=False, group=None), Binding(key='o', action='open_target', description='Open', show=True, key_display=None, priority=False, tooltip='', id=None, system=False, group=None), Binding(key='c', action='copy_target', description='Copy', show=True, key_display=None, priority=False, tooltip='', id=None, system=False, group=None), Binding(key='p', action='toggle_pin', description='Pin', show=True, key_display=None, priority=False, tooltip='', id=None, system=False, group=None), Binding(key='slash', action='start_search', description='Search', show=False, key_display=None, priority=False, tooltip='', id=None, system=False, group=None), Binding(key='escape', action='cancel_search', description='Cancel search', show=False, key_display=None, priority=False, tooltip='', id=None, system=False, group=None)]¶
The default key bindings.
- compose()[source]¶
Yield child widgets for a container.
This method should be implemented in a subclass.
- Return type:
Iterable[Widget]
- action_cancel_search()[source]¶
Cancel search, restore full list, refocus target list.
- Return type:
None
- on_input_changed(event)[source]¶
Filter the target list as the user types in the search bar.
- Parameters:
event (Changed)
- Return type:
None
- on_input_submitted(_event)[source]¶
Confirm search: hide input, keep filtered list, refocus list.
- Parameters:
_event (Submitted)
- Return type:
None
- action_toggle_pin()[source]¶
Pin/unpin the highlighted target, persist, and keep it selected.
The app’s in-memory list is the session’s source of truth: we toggle it first, then try to persist. If the write fails the change still stands (surfaced as an error), and a later successful toggle cannot silently drop it by reloading a stale file from disk.
- Return type:
None
- olink.tui.app.launch_tui(cwd)[source]¶
Entry point for the TUI.
- Parameters:
cwd (str)
- Return type:
None
Action handlers for the TUI.
Data models for the TUI.
- class olink.tui.models.FilterState(mode='available')[source]¶
Bases:
objectCurrent TUI filter/view state.
- Parameters:
mode (str)
- class olink.tui.models.TargetItem(name, description, target_cls, ecosystem=None, pinned=False)[source]¶
Bases:
objectA target entry for display in the TUI.
- Parameters:
- olink.tui.models.build_available_targets(cwd)[source]¶
Build list of targets available for the current project.
- Parameters:
cwd (str)
- Return type:
- olink.tui.models.order_by_pins(items, pinned)[source]¶
Return items pinned-first, marking each item’s pinned flag.
Pinned items come first in the order they appear in pinned; the rest keep their incoming order. Pin names absent from items are ignored, so in the TUI’s “available” mode a pin only surfaces when it applies to this project. This function mutates each input item’s pinned flag in place; it does not create copies.
- Parameters:
items (list[TargetItem])
- Return type:
Custom Textual widgets for the TUI.
- class olink.tui.widgets.SearchInput[source]¶
Bases:
InputSearch bar that appears when / is pressed.
Initialise the Input widget.
- Parameters:
value¶ – An optional default value for the input.
placeholder¶ – Optional placeholder text for the input.
highlighter¶ – An optional highlighter for the input.
password¶ – Flag to say if the field should obfuscate its content.
restrict¶ – A regex to restrict character inputs.
type¶ – The type of the input.
max_length¶ – The maximum length of the input, or 0 for no maximum length.
suggester¶ – [Suggester][textual.suggester.Suggester] associated with this input instance.
validators¶ – An iterable of validators that the Input value will be checked against.
validate_on¶ – Zero or more of the values “blur”, “changed”, and “submitted”, which determine when to do input validation. The default is to do validation for all messages.
valid_empty¶ – Empty values are valid.
select_on_focus¶ – Whether to select all text on focus.
name¶ – Optional name for the input widget.
id¶ – Optional ID for the widget.
classes¶ – Optional initial classes for the widget.
disabled¶ – Whether the input is disabled or not.
tooltip¶ – Optional tooltip.
compact¶ – Enable compact style (without borders).
- class olink.tui.widgets.StatusBar(content='', *, expand=False, shrink=False, markup=True, name=None, id=None, classes=None, disabled=False)[source]¶
Bases:
StaticBottom status bar showing mode, count, and messages.
Initialize a Widget.
- Parameters:
*children¶ – Child widgets.
name¶ – The name of the widget.
id¶ – The ID of the widget in the DOM.
classes¶ – The CSS classes for the widget.
disabled¶ – Whether the widget is disabled or not.
markup¶ – Enable content markup?
content (VisualType)
expand (bool)
shrink (bool)
markup (bool)
name (str | None)
id (str | None)
classes (str | None)
disabled (bool)
- class olink.tui.widgets.TargetListWidget[source]¶
Bases:
ListViewScrollable list of targets.
Initialize a ListView.
- Parameters:
*children¶ – The ListItems to display in the list.
initial_index¶ – The index that should be highlighted when the list is first mounted.
name¶ – The name of the widget.
id¶ – The unique ID of the widget used in CSS/query selection.
classes¶ – The CSS classes of the widget.
disabled¶ – Whether the ListView is disabled or not.
- BINDINGS: ClassVar[list[BindingType]] = [Binding(key='j', action='cursor_down', description='Down', show=False, key_display=None, priority=False, tooltip='', id=None, system=False, group=None), Binding(key='k', action='cursor_up', description='Up', show=False, key_display=None, priority=False, tooltip='', id=None, system=False, group=None)]¶
- Key(s) | Description |:- | :- |enter | Select the current item. |up | Move the cursor up. |down | Move the cursor down. |
- get_selected_item()[source]¶
Get the currently highlighted target item.
- Return type:
TargetItem | None
- update_items(items)[source]¶
Replace the list contents.
- Parameters:
items (list[TargetItem])
- Return type:
None
- class olink.tui.widgets.TargetRow(item)[source]¶
Bases:
ListItemA single target row in the list.
Initialize a Widget.
- Parameters:
- compose()[source]¶
Called by Textual to create child widgets.
This method is called when a widget is mounted or by setting recompose=True when calling [refresh()][textual.widget.Widget.refresh].
Note that you don’t typically need to explicitly call this method.
Example
```python def compose(self) -> ComposeResult:
yield Header() yield Label(“Press the button below:”) yield Button() yield Footer()
- Return type:
Iterable[Widget]