Skip to content

Releases: eirikb/gg

179

12 Jun 15:13
e6514fd

Choose a tag to compare

check_or_update_tool used find() on the glob result, so with several cached entries for the same tool (rat_eq_3.18.0, rat_star_, ...) it only ever checked the alphabetically first one. A hard-pinned =x.y.z entry sorting first made 'update rat -u' report 'Already up to date' while the entry actually being executed (*) was stale.

Now all matching entries are checked/updated, each reported with its version selector (rat@=3.18.0, rat@~3.22, ...) like the all-tools path.

178

10 Jun 11:33
329a2cd

Choose a tag to compare

178

Docker Hub rate-limits anonymous pulls from shared GitHub runner IPs, which made test-container jobs fail in 'Initialize containers' before any test ran (and fail-fast then cancelled innocent sibling jobs). The same official images are served by public.ecr.aws/docker/library without those limits. Also set fail-fast: false so one transient pull failure only needs a re-run of that single job.

177

10 Jun 11:03
be50308

Choose a tag to compare

177

Busybox-style escape hatch for renamed gg.cmd: 'node.cmd gg update' behaves as 'gg.cmd update'. This lets a tool launched via its own applet (e.g. a renamed postmortemthis.cmd) call back into gg through the same .cmd file, via the GG_CMD_PATH it inherits.

The jump-out word is strictly lowercase 'gg' and is stripped uniformly, so 'gg.cmd gg node' also means 'gg.cmd node'. Plain applet dispatch is unchanged.

176

10 Jun 10:24
38ebbd2

Choose a tag to compare

176
Feature/eirikb/agent cli tools (#262)

* Add agent CLI tools: claude, codex, gemini-cli

Three coding-agent CLIs from the major labs, all contained in gg's cache
(no system-wide installers):

- claude (Anthropic): native binary from downloads.claude.ai, no
  installer. Requires the extension-less-filename fix in
  bloody_indiana_jones (the asset is a raw binary named 'claude' with no
  extension, which the old .extension().unwrap() panicked on).
- gemini-cli (Google): npm @google/gemini-cli on a gg-managed Node, via
  a new NpmPackageSpec pattern (mirrors the Ruby gems approach) that
  installs into npm_home/ in the tool's own cache dir.
- codex (OpenAI): npm @openai/codex. NOT GitHub releases -- that page
  mixes alpha prereleases with many same-prefixed assets
  (codex-app-server, bundles, .zst), and gg's selector picked
  codex-app-server-package alpha and then silently fell through to a
  system /usr/bin/codex. The npm package resolves the right stable
  native binary per platform via optionalDependencies.

npm installs are kept fully self-contained: npm_config_cache and
npm_config_devdir are pointed inside the tool's cache dir so nothing
leaks to ~/.npm or ~/.cache/node-gyp.

Verified end-to-end in an isolated cache+HOME: all three download,
install into .cache/gg, and run the cached binary (claude 2.1.168,
codex-cli 0.137.0, gemini 0.45.2) with no install-time pollution of HOME.

Extracted from feature/eirikb/agent-clis.

* Add more agent CLI tools: qwen, kimi, vibe

The remaining first-party lab CLIs (by the lab, for their own models):

- qwen (Alibaba): npm @qwen-code/qwen-code on a gg-managed Node, same
  NpmPackageSpec pattern as gemini-cli/codex.
- kimi (Moonshot AI): native per-platform binaries from
  MoonshotAI/kimi-cli GitHub releases.
- vibe (Mistral, powered by Devstral): native per-platform binaries
  from mistralai/mistral-vibe GitHub releases.

kimi and vibe both publish several same-platform assets per release
(kimi's -onedir bundles, vibe's vibe-acp-* editor-protocol builds), so
the os+arch+version sort ties and selection becomes arbitrary -- the
same prefix-collision problem codex had on GitHub releases. New
excluded_asset_keywords on the GitHub executor filters these out at
download-listing time, keeping selection deterministic.

xAI, DeepSeek and Z.ai have no official CLIs (community tools only),
so this completes the set for now.

Verified end-to-end in an isolated cache+HOME: all three download,
install into .cache/gg, and run the cached binary (kimi 1.47.0,
vibe 2.14.1, qwen 0.17.1). Aliases qwen-code/kimi-cli/mistral-vibe
also dispatch correctly.

175

09 Jun 21:17
8cf9bcc

Choose a tag to compare

175

The stage4 binary (reqwest) already reads the conventional proxy env vars, but both bootstrap downloaders ignored them:

  • stage2.ps1 (Windows): Invoke-WebRequest only knows the system WinINET proxy, so pointing https_proxy at an alternative (e.g. unauthenticated corporate) proxy had no effect, and downloads died with errors like "Proxy Authorization Required". Now passes -Proxy plus -ProxyUseDefaultCredentials when https_proxy/all_proxy is set to an http(s) URL.

  • stage3 (Linux/macOS C): always connected directly to the blob host on port 80. Now parses http_proxy/HTTP_PROXY/all_proxy/ALL_PROXY ([http://]host[:port]), connects through the proxy and sends an absolute-URI GET. Non-http schemes (socks) are ignored; credentials are stripped with a notice (no base64 in stage3).

Also check the HTTP status line in stage3: previously a 404/407/502 response body was downloaded and only failed later with a confusing "Hash did not match"; now it fails immediately with "HTTP error NNN". The first read is NUL-terminated before the strstr header parsing, which was relying on luck before.

Tested end-to-end against the live blob store with a real release hash: direct, via a local forwarding proxy (absolute-URI request verified), creds-stripping, socks ignored, unreachable proxy, and 404 on both paths. stage2.ps1 logic verified with pwsh.

174

08 Jun 09:30
e6ea27e

Choose a tag to compare

174

create_isolated_test_dir() named its temp dir after the current nanosecond timestamp. Under parallel test execution two tests could get the same timestamp, share a dir, and have one delete it while another was still using it -- intermittently failing at fs::remove_dir_all (seen in CI on macos-14).

Switch to tempfile::tempdir() for guaranteed uniqueness and automatic cleanup on drop, dropping the manual remove_dir_all calls. Verified stable across 20 repeated parallel runs.

173

08 Jun 08:54
e65a092

Choose a tag to compare

173

download() streamed the response body regardless of status code, so a rate-limited or forbidden source (403/503 with an HTML/text body) was saved as the archive and only blew up later during extraction with a misleading 'Invalid gzip header' or 'Could not find EOCD' panic.

Check res.status() right after the response and panic with the URL and status code instead. Added a regression test that serves a 403 from a local socket and asserts the download fails with the status message (verified it fails without the fix).

171

06 Jun 07:36
252591e

Choose a tag to compare

171
  • rustls-webpki 0.103.10 -> 0.103.13: DoS via panic on malformed CRL BIT STRING (high), plus two low-severity name-constraint issues
  • tar 0.4.45 -> 0.4.46: PAX header desynchronization (medium) - relevant since gg extracts downloaded archives with this crate
  • rand 0.8.5 -> 0.8.6 and 0.9.2 -> 0.9.4: unsoundness with custom loggers using rand::rng() (low)

Lockfile-only change; all transitive.

170

06 Jun 06:36
b11f1f1

Choose a tag to compare

170

stage3 (unix):

  • Replace unchecked gethostbyname (NULL deref = segfault on DNS failure, IPv4-only) with getaddrinfo and a connect loop, matching main-win.c. Fixes silent crash on IPv6-only or DNS-less networks.
  • Guard HTTP response parsing: missing Content-Length or header terminator no longer NULL-derefs; read errors no longer loop on a dead socket. Both now print an error and clean up stage4.tmp.

stage2.sh:

  • Distinguish 'no stage3 binary could execute' (exit 126/127, truly unsupported system) from 'stage3 ran but failed' (network, hash mismatch). The latter now reports a download failure instead of the misleading 'Your system is not supported'.
  • Document that glob order intentionally tries aarch64 before x86_64 (Apple Silicon picks native over Rosetta).

169

06 Jun 06:08
4f9dd57

Choose a tag to compare

169

Fixes #248. gg has no 32-bit target, so assets like uv-i686-pc-windows-msvc.zip were being matched as Arch::Any and shadowing the real x86_64 asset on 64-bit Windows.