Installer Module¶
The installer system is split across two layers:
stackops.jobs.installerfor packaged install scriptsstackops.utils.schemas.installerfor the installer catalog and typed schemastackops.utils.installer_utilsfor the runtime engine
This page documents the runtime behavior that the current code exposes.
Core data model¶
The typed schema lives in stackops.utils.schemas.installer.installer_types.
InstallerData¶
from stackops.utils.schemas.installer.installer_types import InstallerData
installer_data: InstallerData = {
"appName": "fd",
"license": "MIT",
"doc": "A simple, fast and user-friendly alternative to find",
"repoURL": "https://github.com/sharkdp/fd",
"categoryLabels": ["search-navigation"],
"fileNamePattern": {
"amd64": {
"linux": "fd-v{version}-x86_64-unknown-linux-musl.tar.gz",
"windows": "fd-v{version}-x86_64-pc-windows-msvc.zip",
"darwin": "fd-v{version}-x86_64-apple-darwin.tar.gz",
},
"arm64": {
"linux": "fd-v{version}-aarch64-unknown-linux-musl.tar.gz",
"windows": None,
"darwin": "fd-v{version}-aarch64-apple-darwin.tar.gz",
},
},
}
Fields:
| Field | Meaning |
|---|---|
appName |
Display name and base executable name |
license |
License label stored in the installer catalog |
doc |
Description used in interactive selection |
repoURL |
"CMD" for command / script driven installs, or a GitHub repository URL |
categoryLabels |
Searchable category labels used by devops install --explore |
fileNamePattern |
arch -> os -> installer value mapping |
Other types¶
| Type | Purpose |
|---|---|
InstallerDataFiles |
Shape of installer_data.json |
InstallRequest |
{version: str | None, update: bool} |
InstallationResult |
Typed union of skipped, same_version, updated, and failed results |
CPU_ARCHITECTURES |
"amd64" or "arm64" |
OPERATING_SYSTEMS |
"windows", "linux", or "darwin" |
Helpers:
get_os_name()get_normalized_arch()
How installers are resolved¶
stackops.utils.installer_utils.installer_runner.get_installers() loads the catalog from:
stackops.utils.schemas.installer.INSTALLER_DATA_PATH_REFERENCE- resolved through
stackops.utils.path_reference.get_path_reference_path(...)
It then filters by:
- current OS
- current architecture
- optional package-group list
Example:
from stackops.utils.installer_utils.installer_runner import get_installers
from stackops.utils.schemas.installer.installer_types import (
get_normalized_arch,
get_os_name,
)
installers = get_installers(
os=get_os_name(),
arch=get_normalized_arch(),
which_cats=["termabc"],
)
Installation strategies¶
Installer._install_from_value() supports four current strategies.
1. Package-manager commands¶
If the resolved installer value contains a whitespace-separated package-manager token such as bun, npm, pip, uv, winget, powershell, irm, brew, curl, sudo, or cargo, the installer executes that shell command directly.
This is also the path used for entries whose repoURL is "CMD" and whose platform value is a raw command string.
2. Script installers¶
If the resolved installer value ends in:
.sh.ps1.py
the installer searches the packaged installer assets under stackops.jobs.installer and runs the matching script.
Current Python installer scripts are expected to expose:
Extra parameters are allowed only if they are optional.
3. Direct binary or archive URLs¶
If the resolved installer value is an http:// or https:// URL, the installer downloads it to ~/tmp_results/tmp_installers, decompresses supported archives, and then moves the resulting executable or .deb package into place.
4. GitHub releases¶
If repoURL is a GitHub repository URL, Installer.get_github_release() fetches release metadata and matches a release asset against the current platform's fileNamePattern.
Current matching behavior includes:
{version}substitution with the resolved tag name- fallback checks for
v-prefixed versus unprefixed versions - hyphen / underscore filename variants before the install fails
Install request handling¶
InstallRequest(version, update) is resolved against the installer kind before installation:
- installs are skipped when the executable already exists unless
update=Trueorversionis set --versionis accepted for GitHub release installers, script installers, andwinget install ...commands--updateis accepted for binary URL, GitHub release, script installers, andwinget install ...commands- unsupported
versionrequests are ignored with a warning; unsupportedupdaterequests warn and continue
Installer¶
stackops.utils.installer_utils.installer_class.Installer is the per-package orchestrator.
Main methods¶
| Method | Purpose |
|---|---|
get_description() |
Builds the interactive display label and includes a check_tool_exists() status mark |
install(version) |
Installs one tool without the typed InstallRequest wrapper |
install_requested(install_request) |
Installs one tool using InstallRequest |
install_robust(install_request) |
Returns a typed InstallationResult instead of raising install failures to the caller |
binary_download(version) |
Downloads and extracts the selected asset without final installation |
get_github_release(repo_url, version) |
Returns the selected asset URL and resolved version tag |
Example¶
from stackops.utils.installer_utils.installer_class import Installer
from stackops.utils.schemas.installer.installer_types import InstallRequest
installer = Installer(installer_data)
result = installer.install_robust(
install_request=InstallRequest(version=None, update=False),
)
print(result["kind"])
install_robust() currently returns one of these result shapes:
{"kind": "skipped", ...}{"kind": "same_version", ...}{"kind": "updated", ...}{"kind": "failed", ...}
CLI-style entrypoints¶
These helpers live in stackops.utils.installer_utils.installer_cli.
main_installer_cli(...)¶
from stackops.utils.installer_utils.installer_cli import main_installer_cli
main_installer_cli(
which="fd,bat,rg",
group=False,
interactive=False,
explore=False,
update=False,
version=None,
)
Parameters:
| Parameter | Meaning |
|---|---|
which |
Comma-separated app names, group names, or URLs |
group |
Treat which as package-group names |
interactive |
Launch interactive selection instead of parsing which |
explore |
Explore installer categoryLabels before installing |
update |
Allow reinstall or upgrade when supported |
version |
Request a specific version or tag when supported |
Other entrypoints¶
| Helper | Purpose |
|---|---|
install_interactively(install_request) |
Shows package groups plus installers, with JSON previews when tv is available |
install_group(package_group, install_request) |
Resolves a named package group and installs every matching catalog entry |
install_clis(clis_names, install_request) |
Installs explicit catalog names, aliases, GitHub URLs, or direct binary URLs |
install_if_missing(which, binary_name, verbose) |
Convenience guard that returns True if the tool exists or becomes installable |
Current CLI aliases:
agy->antigravity
Interactive mode currently:
- lists package groups first, prefixed with
📦 - lists installer options using
Installer.get_description() - uses
choose_from_dict_with_preview()whentvexists - falls back to
choose_from_options()otherwise
Package groups¶
The installer runtime consumes the groups defined in stackops.utils.schemas.installer.package_groups.PACKAGE_GROUP2NAMES.
Current group names:
sysabcshellsearchsys-monitorcode-analysistermabcdevdev-utilseyeagentsterminalbrowserseditorsdb-alldb-clidb-desktopdb-webdb-tuimediaguinwfile-sharingproductivity
Example:
from stackops.utils.schemas.installer.package_groups import PACKAGE_GROUP2NAMES
print(PACKAGE_GROUP2NAMES["agents"])
Bulk installation¶
stackops.utils.installer_utils.installer_runner.install_bulk() is the multi-package entrypoint.
from stackops.utils.installer_utils.installer_runner import install_bulk
from stackops.utils.schemas.installer.installer_types import InstallRequest
install_bulk(
installers_data=installers,
install_request=InstallRequest(version=None, update=False),
safe=False,
jobs=10,
fresh=False,
)
Current behavior:
- the first installer runs serially
- the remaining installers run through a stdlib process pool
fresh=Trueclears the version cache firstsafeis accepted but currently has no behavior- a Rich summary is rendered after the batch finishes
Direct URL installers¶
Two URL-oriented helpers are exposed separately:
from stackops.utils.installer_utils.install_from_url import (
install_from_binary_url,
install_from_github_url,
)
install_from_github_url(github_url)¶
- fetches the latest release
- lets the user choose a release asset interactively
- downloads, extracts, and installs it
- records the resolved version in the install-version cache when a tool name can be derived from the selected asset or repository
install_from_binary_url(binary_url)¶
- downloads a binary or archive directly
- extracts and installs it
- records
"latest"in the install-version cache only when a tool name can be derived during finalization
Version tracking and install paths¶
Current constants come from stackops.utils.source_of_truth:
| Constant | Current path |
|---|---|
INSTALL_VERSION_ROOT |
~/.config/stackops/cli_tools_installers/versions |
INSTALL_TMP_DIR |
~/tmp_results/tmp_installers |
LINUX_INSTALL_PATH |
~/.local/bin |
WINDOWS_INSTALL_PATH |
~/AppData/Local/Microsoft/WindowsApps |
Each installed tool gets a version marker file under INSTALL_VERSION_ROOT.
Security checks¶
Security and reporting helpers live under stackops.jobs.installer.checks.*. They are part of the installer subsystem, but they are not on the main install path described above. Use them when you need auditing or reporting around already installed tools rather than installation itself.
API reference¶
Installer schema¶
installer_types
¶
Package groups¶
package_groups
¶
Installer class¶
installer_class
¶
Installer runner¶
installer_runner
¶
package manager
Install request logic¶
install_request_logic
¶
Installer helper utilities¶
installer_helper
¶
handle_installer_not_found
¶
Handle installer not found with friendly suggestions using fuzzy matching.
Installer locator utilities¶
installer_locator_utils
¶
GitHub release scraper¶
github_release_scraper
¶
HTML scraper for GitHub release pages as fallback when API rate limit is exceeded.
fetch_expanded_assets
¶
fetch_expanded_assets(
username: str,
repo_name: str,
tag_name: str,
headers: dict[str, str],
) -> list[dict[str, Any]]
Fetch assets from the expanded_assets endpoint which contains all downloadable files.
scrape_github_release_page
¶
scrape_github_release_page(
username: str,
repo_name: str,
version: str | None = None,
) -> dict[str, Any] | None
Scrape GitHub release page HTML to extract release information. Falls back to this when API rate limit is hit.
GitHub release bulk helpers¶
github_release_bulk
¶
Script to fetch GitHub release information from installer JSON files. Extracts GitHub repository URLs and fetches latest release data with rate limiting.
AssetInfo
¶
Bases: TypedDict
Type definition for GitHub release asset information.
ReleaseInfo
¶
Bases: TypedDict
Type definition for GitHub release information.
OutputData
¶
Bases: TypedDict
Type definition for the output JSON data structure.
extract_github_repos_from_json
¶
Extract GitHub repository URLs from installer JSON file.
get_repo_name_from_url
¶
Extract owner/repo from GitHub URL as a tuple (username, repo_name).
fetch_github_release_data
¶
fetch_github_release_data(
username: str,
repo_name: str,
version: str | None = None,
) -> Dict[str, Any] | None
Fetch GitHub release data for the latest or a specific tag. Falls back to HTML scraping if API fails.
get_release_info
¶
get_release_info(
username: str,
repo_name: str,
version: str | None = None,
) -> ReleaseInfo | None
Return sanitized release information for the requested repository.
extract_release_info
¶
extract_release_info(
release_data: Dict[str, Any],
) -> ReleaseInfo | None
Extract relevant information from GitHub release data.
Install from URL helpers¶
install_from_url
¶
Installer CLI helpers¶
installer_cli
¶
Devops Devapps Install
Installer Python script main protocol¶
installer_main_protocol
¶
Installer explore helpers¶
installer_explore
¶
Category-label explorer for devops install --explore.
Installer summary helpers¶
installer_summary
¶
Offline installer entrypoint¶
installer_offline
¶
Offline installer models¶
installer_offline_models
¶
Offline installer constants¶
installer_offline_constants
¶
Offline installer publish helpers¶
installer_offline_publish
¶
Offline installer render helpers¶
installer_offline_render
¶
Offline installer script helpers¶
installer_offline_scripts
¶
Offline installer steps¶
installer_offline_steps
¶
Offline installer uv helpers¶
installer_offline_uv
¶
Installation check utilities¶
install_utils
¶
Installation Utilities¶
This module provides functionality to download and install pre-checked applications.
upload_app
¶
Uploads the app to cloud storage and returns the shareable link.
download_google_drive_file
¶
Downloads a file from Google Drive using gdown.
load_app_metadata_report
¶
Loads the app metadata report from CSV.
load_engine_results_report
¶
Loads the engine results report from CSV.
download_safe_apps
¶
Downloads and installs safe apps.
Installation checks¶
check_installations
¶
Check Installations¶
This module scans installed applications using VirusTotal and generates a safety report. It also provides functionality to download and install pre-checked applications.
Security CLI helpers¶
security_cli
¶
Security helper utilities¶
security_helper
¶
Security report utilities¶
report_utils
¶
Report Utilities¶
This module provides functionality to generate reports for installed applications.