# Default clone target is ~/resq; override with RESQ_DIR=...
curl -fsSL https://get.resq.software | shThis endpoint is not a redirect to main. It serves one pinned commit and
SHA-256 verifies every byte before sending it; on mismatch it returns 502 with a
shell snippet that exits non-zero, never installer bytes.
Merging to main does not by itself change what you get here. What you receive
is decided by the pinned digests in worker/src/index.js, so it changes only
when a reviewed pin bump merges and deploys. Cutting a release does not move
this endpoint either: the release publishes the artifacts, and a separate
reviewed pull request repoints the pins at them.
You do not have to take that on faith. Verify against a single immutable release, so the installer and the digest list cannot describe different versions:
REL=https://get.resq.software/v0.4.0
curl -fsSL "$REL/SHA256SUMS"
curl -fsSL "$REL/install.sh" | sha256sum # must match the install.sh line
# Or just read it before running it
curl -fsSL "$REL/install.sh" -o install.sh
less install.sh && sh install.shThe unversioned paths work too, but a deploy landing between the two requests would leave you comparing an installer from one release against digests from another.
Pin to an exact release, which never changes:
curl -fsSL https://get.resq.software/v0.4.0/install.sh | shWhat happens, in order:
- Installs
gh(GitHub CLI) if missing - Authenticates with GitHub
- Installs Nix via the Determinate Systems installer for reproducible toolchains
- Lets you choose which repo to clone
- Runs
nix developto build the dev environment - Installs the canonical git hooks (delegating to
resq pre-commit) - Offers to scaffold a repo-type-specific
local-pre-push(auto-detects Rust / Python / Node / .NET / C++ / Nix)
Run unattended (CI / provisioning):
REPO=npm YES=1 RESQ_DIR=/srv/work \
curl -fsSL https://get.resq.software | shFor provisioning, prefer a version-pinned URL so a later release cannot change what your machines install without you deciding to:
REPO=npm YES=1 curl -fsSL https://get.resq.software/v0.4.0/install.sh | sh| Repo | What | Languages |
|---|---|---|
programs |
Solana on-chain programs | Rust (Anchor) |
dotnet-sdk |
.NET client libraries | C# |
pypi |
Python packages (MCP + DSA) | Python |
crates |
Rust workspace (CLI + DSA + resq binary) |
Rust |
npm |
TypeScript packages (UI + DSA) | TypeScript |
vcpkg |
C++ libraries | C++ |
viz |
3D visualization — Three.js/Cesium web + Unity | TypeScript / C# |
docs |
Documentation site | MDX |
dev |
This repo — install scripts and onboarding | Shell / PowerShell |
Public repos sync to the monorepo automatically.
This table is the public, non-archived, non-fork set (excluding .github), and
it is the same list the installers offer. landing used to appear here and in the installer
menu; it is now private, so choosing it failed at clone time. The rule is
mechanical on purpose — repo-drift.yml re-derives it from the GitHub API and
fails when this list and reality disagree, so the next such change is caught by
CI rather than by whoever runs the installer next.
Each script can be run on its own without going through the full onboarding flow.
| Script | Use case | Bootstrap |
|---|---|---|
install.sh / install.ps1 |
Full onboarding — installs prereqs, clones a repo, sets up dev env + hooks | curl -fsSL https://get.resq.software | sh |
install-hooks.sh / install-hooks.ps1 |
Drop the canonical git hooks into any repo. Asks to scaffold local-pre-push if resq is on PATH |
cd <repo> && curl -fsSL https://get.resq.software/hooks.sh | sh |
install-resq.sh |
Install the resq CLI binary from the latest GitHub Release (SHA256-verified). Falls back to cargo install --git if no release asset matches the host platform |
curl -fsSL https://get.resq.software/resq.sh | sh |
Every one of these is served pinned and hash-verified, and each has a
version-locked form — https://get.resq.software/v0.4.0/hooks.sh and so on.
https://get.resq.software/SHA256SUMS lists the digest of all of them.
Common env vars across all of them:
YES=1— skip prompts (CI / provisioning)GIT_HOOKS_SKIP=1— disable installed hooks for a sessionRESQ_SKIP_LOCAL_SCAFFOLD=1— opt out of thelocal-pre-pushscaffold prompt
To pin a revision, use a version-locked URL rather than an environment
variable. (This section previously documented RESQ_DEV_REF=<sha|tag>; no
script has ever implemented it, so it silently did nothing.)
install.sh additionally honours REPO, RESQ_DIR, RESQ_BIN_DIR,
SKIP_RESQ_CLI and NO_COLOR — run sh install.sh --help for the current
list.
| Repo | Language | Setup |
|---|---|---|
| programs | Rust / Anchor | anchor build |
| dotnet-sdk | C# / .NET 9 | dotnet restore |
| pypi | Python | uv sync |
| crates | Rust | cargo build |
| npm | TypeScript | bun install |
| vcpkg | C++ | cmake --preset default |
| viz | TypeScript / C# | bun install · dotnet restore |
| docs | MDX / Mintlify | mintlify dev |
| dev | Shell / PowerShell | shellcheck install.sh · node worker/test/index.test.mjs |
One authored value, one action:
echo 0.4.1 > VERSION
sh bin/stamp.sh # propagates VERSION + hook digests into both installers
# open a PR, merge it — that is the releaseDo not tag by hand. Merging a VERSION change to main is what releases:
CI validates it, creates the tag itself, publishes the Release and
SHA256SUMS, and opens a pin-bump PR. Merging that is what changes the bytes
https://get.resq.software serves.
Two gates, both ordinary code review:
| merging | changes |
|---|---|
a VERSION bump |
what is published as a release |
| the pin-bump PR | what users actually receive |
Everything else is generated. bin/stamp.sh --check runs on every pull
request and verifies by regeneration, so a stamped value cannot be forgotten —
forgetting it is a diff. Values marked GENERATED should never be hand-edited.
No Cloudflare credential is stored in GitHub. Deployment is Cloudflare Workers
Builds pulling from this repository, and worker-live afterwards checks that
the endpoint serves exactly what main declares — hashing the bytes on the
wire, not trusting the Worker's own claim about them.
AGENTS.md has the full reasoning, including why tagging is an output of the
release rather than its trigger.
Every ResQ repo ships an AGENTS.md at the root — the canonical plain-text dev guide. That's where the build/test/lint commands, architecture notes, and standards for that specific repo live. Read it first.
Org-wide guidance (onboarding, hooks contract, commit format, PR process) lives in the .github org repo: CONTRIBUTING.md, SECURITY.md, CODE_OF_CONDUCT.md. Every public repo falls back to those automatically.
Everything is pinned via Nix flakes. No "works on my machine" issues.
| Language | Tools |
|---|---|
| Rust | rustc, cargo, clippy, rustfmt, cargo-deny |
| TypeScript | bun, node, turbo |
| Python | python 3.12, uv, ruff, mypy |
| C# | dotnet 9 |
| C++ | gcc, cmake, clang-format |
| Protobuf | buf, protoc |
| Solana | solana-cli, anchor |
Six hook shims live in resq-software/crates — embedded in the resq binary and served at a stable raw URL. install-hooks.sh picks the best path automatically:
resqon PATH → callsresq hooks install, which scaffolds the 6 canonical hooks from the templates embedded in the binary. Offline, versioned with the installedresq.- No
resq→ falls back tocurlfromresq-software/crates/master/.../templates/git-hooks/.
The hooks delegate logic back to the resq binary (resq pre-commit, etc.), so updates roll out via cargo install --git (or install-resq.sh) without editing every repo.
| Hook | What it gates |
|---|---|
pre-commit |
resq pre-commit — copyright, secrets, audit, polyglot format |
commit-msg |
Conventional Commits + ! marker; blocks WIP: / fixup! / squash! on main |
prepare-commit-msg |
Prepends [TICKET-123] from branch name |
pre-push |
Force-push guard, branch-naming convention (feat/, fix/, …, changeset-release/* allowed) |
post-checkout / post-merge |
Notifies on lock-file changes (Cargo, bun, uv, flake) |
Each hook then dispatches to .git-hooks/local-<hook-name> (if executable) — the only place a repo commits hook customization. Generate one with the right language template:
resq hooks scaffold-local --kind auto # detects rust/python/node/dotnet/cpp/nixresq hooks doctor reports drift, resq hooks update re-syncs from the embedded canonical, resq hooks status prints a one-line shell-friendly summary.
The canonical content lives in exactly one place: crates/resq-cli/templates/git-hooks/. The crates repo's own .git-hooks/ (for dog-fooding) is kept identical via hooks-sync.yml. The dev/ repo used to ship a third copy and was retired in Phase 4 — install-hooks.sh now fetches from the crates source (or lets resq hooks install do it offline). Bats + Rust integration tests cover the hook behavior end-to-end.
Apache License 2.0