Skip to content
gritpack

gritpack-installer

available

Installs one application, and Gritpack when it is missing

Install

gritpack install gritpack-installer '^1.2.45'

README

Installer

Status: design v0.1, 22 October 2026. Steps 1 (the terminal installer) and 2 (install scripts) live since Gritpack 1.2.41, 23 October 2026: curl -fsSL https://get.gritpack.org/install/<package> | sh works from an empty home on Linux AMD64 and macOS ARM64. Step 3 (the window and macOS Install <Title>.dmg, ad hoc signed) since 1.2.42, 25 October 2026; step 4 (Developer ID signing and notarization) waits on the Apple certificate

1. Purpose

A person who finds an application on a website should get it with one download and one confirmation, without knowing that Gritpack exists:

Download Loom  →  Install Loom.dmg  →  "Install Loom?"  →  OK  →  Loom is ready

Gritpack is how the application arrives, and how it is kept up to date afterwards, but installing Gritpack is never a separate step for the person.

2. Parts

PartWhat it is
installerOne small generic program per platform, released with Gritpack. It installs one labelled application, and Gritpack itself when it is missing. A terminal program, with an optional window.
LabelA small file naming the application and hub. It travels beside installer in each download; it is not part of the signed program.
gritpack-installerThe application that carries installer, published with each Gritpack release per platform (scripts/package-installer-capsule.sh).
Install scriptGET https://<hub>/install/<package>: a hub renders it on request for any application it serves, pinning the newest installer's SHA-256 per platform. It downloads installer from GET /v1/installer/<version>/<target> and runs it.
gritpack installer buildTurns a published application into its downloads. --platform linux saves the hub's install script (for publishers who host it themselves); --platform macos will package installer, the label, and the application's name and icon, signed.
Download pageget.gritpack.org/<package>, which detects the visitor's platform and serves the right download (with the window, step 3).

installer is built from the Gritpack workspace and uses the Gritpack library's client half (resolution, verified download, user-global installation), so it behaves exactly like gritpack install. It does not link the hub server, the metadata database or S3, which keeps it small.

3. What installer does

Install Loom 0.4.0 from get.gritpack.org?
  Loom: one console for machines, Frogfish apps and Residiuum
  [Y/n] y
installing gritpack 1.2.38, which keeps Loom up to date … ok
downloading @frogfish/loom 0.4.0, @frogfish/loom-runtime 0.2.1 … verified
installing Loom … ok
added ~/.frogfish/gritpack/bin to PATH in ~/.zprofile (open a new terminal)
Loom is ready: run `loom`
  1. Which application. From the command line (installer @frogfish/loom), else from the label. The label is a suggestion: the person confirms it, and what is installed is verified like any Gritpack installation, so a tampered label can at most offer a different public package, which the person sees.
  2. Confirm, showing the application's name, version, description and hub. --yes answers for unattended use; without a terminal and without --yes, it stops rather than guess.
  3. Gritpack. When no gritpack command is installed (in the Gritpack home or on PATH), it installs the gritpack application from get.gritpack.org, so gritpack installed upgrade keeps everything current. A gritpack that was copied into ~/.frogfish/gritpack/bin by hand, which Gritpack did not install, is moved to ~/.frogfish/gritpack/replaced/ (never deleted) and the person is told. Any other file there that Gritpack did not install is left alone, and the installer stops, naming it.
  4. The application, from the label's hub, into the same per-user Gritpack home (~/.frogfish/gritpack), with the same receipt gritpack install writes. Installing it again upgrades it.
  5. PATH. When ~/.frogfish/gritpack/bin is not on PATH, it offers to add it to the login profile of the person's shell (~/.zprofile, ~/.bash_profile or ~/.profile), once; --no-modify-path declines.
  6. Done, naming the commands the application installed.

An installer installs the newest version for the platform, so it does not need rebuilding when the application releases; only when its name or icon changes, or when installer itself is updated.

4. The label

schema = "gritpack/installer-label@1"
package = "@frogfish/loom"
hub = "get.gritpack.org"     # optional; default get.gritpack.org
title = "Loom"               # optional; default the package's local name

installer reads install.toml beside its executable, or in ../Resources/ when it runs inside a macOS application bundle.

4a. Downloads that carry their purpose (download codes)

An invitation is a link, not a download built for one person. The hub serves one generic, signed launcher under a name that ends in a code, and the launcher reads its own name:

gritpack invite-user bob@… --download …   →  link=https://get.gritpack.org/i/7KQ2MXBD9F
Bob opens the link                         →  "Download Join Frogfish"
the download                               →  Join Frogfish - 7KQ2MXBD9F.app (in a zip)
Bob opens it                               →  "Join gritpack.frogfish.io as bob@…?"  →  Join
  • The code is ten characters of Crockford's base32 (50 bits). For an invitation it is the enrollment code: the hub keeps only its SHA-256, and enrolling also needs the invited email. It works once and expires with the invitation; lookups are rate-limited.
  • The lookup (GET /v1/download-codes/<code>) answers what the code is for (title, email, profile, enrollment and package servers), nothing secret, and "not found" for unknown, used, revoked and expired codes alike. A hub answers its own invitations on its enrollment listener; the public hub also asks the hubs named by --download-code-peer (GRITPACK_DOWNLOAD_CODE_PEERS), so links and downloads for the private hub are served from get.gritpack.org.
  • The page GET /i/<code> offers the Mac download and, for Linux and Mac terminals, curl -fsSL https://get.gritpack.org/install/gritpack | sh -s -- --code <code>.
  • The download GET /download/<code> is the signed Gritpack Launcher.zip from the newest macOS gritpack-installer Capsule, with its bundle renamed <title> - <code>.app. Zip entries are copied as stored: a macOS signature does not cover a bundle's name.
  • The launcher takes the code from --code, else from the end of its bundle's (or executable's) name, ignoring copy suffixes such as (1) and 2. After joining, a launcher with no label copies itself to /Applications (else ~/Applications) as Gritpack Launcher and registers it; it declares gritpack:// links. When Gritpack is already installed, joining downloads nothing and only logs in.
  • Why the name, and not a file beside the app: macOS runs a freshly downloaded app from a randomised read-only copy holding only the app (App Translocation), and reading Downloads needs the person's permission; an app's own name survives both.

Not yet: Gritpack Launcher acting on gritpack:// links (macOS delivers them as Apple Events, which Jinn does not pass to applications yet); download codes for applications rather than invitations; joining a private hub and installing a private application in one step.

5. Downloads per platform

PlatformDownloadWindow
Linux, any terminal (macOS terminals too)curl -fsSL https://get.gritpack.org/install/<package> | sh: fetches a pinned, checksummed installer and runs it; arguments after sh -s -- reach it (--yes)terminal
macOSInstall <App>.dmg with a signed, notarized Install <App>.app carrying installer, the label and the app's iconJinn window
WindowsInstall <App>.exe (later)Jinn window

A macOS bundle carrying the app's name and icon is a different bundle, so it is signed per application where the Developer ID is (the release host or CI).

6. Order

  1. installer in the terminal: confirm, Gritpack when missing, the application, PATH.
  2. Install scripts served by the hub, and gritpack installer build --platform linux.
  3. The Jinn window; gritpack installer build --platform macos producing an unsigned .dmg for testing on Frogfish Macs.
  4. Signing and notarization, once the Apple Developer ID is settled.
  5. Windows.

7. Boundaries

  • Public applications first. An application on a private hub needs a login, which installer does not perform; it says so and names gritpack login.
  • installer never runs package code; installation is Gritpack's verified, hook-free user-global installation (GLOBAL_INSTALLATION.md).
  • A gritpack:// deep link, if added, only ever opens a confirmation, never a silent installation.

Versions and variants

All published versions and variants of gritpack-installer, newest first.
Version Variant Status Published
1.2.45 (latest) application/cli · executable/native · aarch64-apple-darwin available 2026-10-29
1.2.45 (latest) application/cli · executable/native · x86_64-unknown-linux-gnu available 2026-10-29
1.2.44 application/cli · executable/native · aarch64-apple-darwin available 2026-10-29
1.2.44 application/cli · executable/native · x86_64-unknown-linux-gnu available 2026-10-29
1.2.43 application/cli · executable/native · aarch64-apple-darwin available 2026-10-29
1.2.43 application/cli · executable/native · x86_64-unknown-linux-gnu available 2026-10-29
1.2.42 application/cli · executable/native · aarch64-apple-darwin available 2026-10-25
1.2.42 application/cli · executable/native · x86_64-unknown-linux-gnu available 2026-10-25
1.2.40 application/cli · executable/native · aarch64-apple-darwin available 2026-10-22
1.2.40 application/cli · executable/native · x86_64-unknown-linux-gnu available 2026-10-22
1.2.39 application/cli · executable/native · aarch64-apple-darwin available 2026-10-22
1.2.39 application/cli · executable/native · x86_64-unknown-linux-gnu available 2026-10-22

Dependencies

This package declares no dependencies.

Integrity evidence
Declared licence
LicenseRef-Frogfish-Binary-License-1.0
Licence files
share/installer/LICENSE share/installer/THIRD-PARTY-NOTICES
Capsule SHA-256
ca2f7f52db96f173c4e6597b7990f5b74541ae45e17435a815f22e480b49f2f7
Payload SHA-256
476058526404482c392e19bb4fb8fea55f38b0e40b6e6a69ba419bdf156e2b51
Capsule size
13.7 MiB

Presentation evidence — not a download link, and not an endorsement of the contents.