Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .github/release-notes.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
## Install

Installs the binaries to `~/.local/bin`.

```bash
curl -fsSL https://github.com/rubas/kagi/releases/download/__VERSION__/install.sh | sh -s -- __VERSION__
mise use -g github:rubas/kagi@__VERSION__
```
1 change: 0 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ jobs:
# task and zizmor come with the incus runner image.
- run: task fmt:check
- run: task lint
- run: shellcheck install.sh
- run: task test
- run: task test:release-check
- run: task deps:machete
Expand Down
67 changes: 1 addition & 66 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -150,39 +150,13 @@ jobs:
name: ${{ matrix.archive }}
path: ${{ matrix.archive }}

installer:
name: Installer
needs: [prepare, tag]
if: ${{ !cancelled() && !failure() && needs.prepare.outputs.should_release == 'true' }}
runs-on: ubuntu-latest
permissions:
contents: read # checkout source to upload install.sh
id-token: write # sign build provenance attestations
attestations: write # store build provenance attestations
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-installer
cancel-in-progress: false
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ needs.prepare.outputs.ref }}
persist-credentials: false
- uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4.2.2
with:
subject-path: install.sh
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: install.sh
path: install.sh

release:
name: Release
runs-on: ubuntu-latest
needs: [prepare, build, installer]
needs: [prepare, build]
Comment thread
rubas-agent[bot] marked this conversation as resolved.
if: ${{ !cancelled() && !failure() && needs.prepare.outputs.should_release == 'true' }}
permissions:
contents: write # publish the GitHub release
attestations: read # smoke test verifies the attestations of the built archive and install.sh
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-release
cancel-in-progress: false
Expand All @@ -196,44 +170,6 @@ jobs:
with:
path: dist
merge-multiple: true
- name: Smoke-test install.sh against built artifacts
shell: bash
env:
TAG: ${{ needs.prepare.outputs.tag }}
GH_TOKEN: ${{ github.token }}
run: |
gh attestation verify dist/install.sh --repo "$GITHUB_REPOSITORY"
home="$(mktemp -d)"
dist="file://$PWD/dist"
kagi_install() { HOME="$home" KAGI_INSTALL_BASE_URL="$dist" sh dist/install.sh "$@"; }
snapshot() { find "$home" -printf '%i %T@ %p %l\n' | sort; }

# An upgrade replaces the installed version.
mkdir -p "$home/.local/bin"
printf '#!/bin/sh\necho kagi-search 0.5.4\n' > "$home/.local/bin/kagi-search"
chmod +x "$home/.local/bin/kagi-search"
status=0
kagi_install --check "$TAG" || status=$?
test "$status" -eq 100

kagi_install "$TAG"
test -x "$home/.local/bin/kagi-search"
test -x "$home/.local/bin/kagi-maps"
test -x "$home/.local/bin/kagi-summarize"

# A second run finds the current version and changes nothing.
before="$(snapshot)"
kagi_install "$TAG" | grep -Fx "kagi ${TAG#v} is current"
test "$before" = "$(snapshot)"
kagi_install --check "$TAG"

# A first install.
home="$(mktemp -d)"
status=0
kagi_install --check "$TAG" || status=$?
test "$status" -eq 100
kagi_install "$TAG"
test -x "$home/.local/bin/kagi-search"
- name: Write release notes
shell: bash
env:
Expand All @@ -249,4 +185,3 @@ jobs:
files: |
dist/kagi-linux-x86_64.tar.gz
dist/kagi-macos-aarch64.tar.gz
dist/install.sh
17 changes: 4 additions & 13 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,6 @@ covers install, the token, and usage.

## Gates

- `task ci` runs `task check`, the release-profile check, `nix build`, cargo-machete, and
cargo-deny. GitHub Actions runs all of it except `task test:nix`. Run `task ci` yourself after
you touch `flake.nix`, `flake.lock`, or `Cargo.toml`, because nothing else builds the Nix
package. This includes a lock-only input refresh.
- `task lint`, and with it `task check` and `task ci`, runs `zizmor`. The `nix develop` shell does
not include it, so put `zizmor` on `PATH` first.
- `task test:live` calls the real Kagi service. Run it when you change the request path or a
parser: `src/cli.rs`, `src/client.rs`, or `src/parse.rs`. It needs a session token (see
`README.md`) and fails without one.
Expand All @@ -21,9 +15,10 @@ covers install, the token, and usage.
- Never hardcode a session token.
- `--sort` means two things. `kagi-search` sends it to Kagi as the `order` parameter. `kagi-maps`
gets the whole result page, sorts it locally, then cuts it to `--limit`.
- `install.sh` is the one installer. `task install` and the release smoke test run it on local
archives. `task install` packs the local build like a release archive, so it runs only on the
two release platforms.
- Our machines install the CLIs with mise (`github:rubas/kagi`). mise picks the release archive
by the OS and architecture in its name, `kagi-linux-x86_64.tar.gz` or
`kagi-macos-aarch64.tar.gz`, and finds the binaries in its `bin/` dir. A change to an archive
name or layout breaks the install on every machine.
- The repo ships no agent skill. The `search` skill in rubas/dotfiles covers these CLIs.
- A version bump is the release trigger. On each push to `main`, `release.yml` reads `version`
from `Cargo.toml`. When the tag `v<version>` does not exist, it tags and publishes. The tag
Expand All @@ -39,9 +34,5 @@ covers install, the token, and usage.

## Pitfalls

- `flake.nix` repeats the package version as a literal. Bump it in the same commit as
`Cargo.toml`, or `nix build` makes a package with the old version.
- `install.sh` runs under `sh` on Linux with GNU tools and on macOS with BSD tools. Use POSIX sh
and only flags that both sets have: no `realpath --relative-to`, no `ln -T`.
- `ci.yml` runs its checks only on a pull request from a branch of this repo, so a fork PR never
reaches the incus runners. A fork PR shows no checks. That is the gate, not a broken run.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ All notable changes to this project are documented in this file.
The format is loosely based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project follows [Semantic Versioning](https://semver.org/).

## [Unreleased]

### Removed

- `install.sh`. Releases no longer ship it. Install with mise instead:
`mise use -g github:rubas/kagi`. The release archives keep their names and
their attestation.
- The Nix flake, with its package, dev shell, and Home Manager module.

## [0.6.1] - 2026-09-30

### Removed
Expand Down
80 changes: 7 additions & 73 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,82 +14,17 @@ Kagi account and its session token.

## Install

### From a GitHub release
Releases ship Linux x86_64 and macOS aarch64 builds. Install them with [mise](https://mise.jdx.dev),
which verifies the GitHub attestation of the release archive:

```bash
curl -fsSL https://github.com/rubas/kagi/releases/latest/download/install.sh | sh
mise use -g github:rubas/kagi
```

The installer puts `kagi-search`, `kagi-maps`, and `kagi-summarize` in `~/.local/bin`.

Run the same command again to update. When `~/.local/bin/kagi-search --version` already shows the
target version, the installer says so and changes nothing.

Put a release tag or an option after `sh -s --`:
Without mise, build from source:

```bash
# Install a given release.
curl -fsSL https://github.com/rubas/kagi/releases/latest/download/install.sh | sh -s -- v0.6.1
# Show the installed and the latest version, and install nothing.
curl -fsSL https://github.com/rubas/kagi/releases/latest/download/install.sh | sh -s -- --check
```

- `--check` exits 0 when the installed version matches the target and 100 when kagi is not
installed or has a different version.
- `--force` installs again when the version already matches.

Supported platforms: Linux x86_64 and macOS aarch64.

When the GitHub CLI (`gh`) is available, the installer verifies the build provenance attestation of
the release archive before it changes a file. Without `gh`, it warns and continues. The Nix flake
below is the fully verifiable path: `flake.lock` pins every input by hash.

The release also attests `install.sh`. To verify the installer before you run it:

```bash
curl -fsSLO https://github.com/rubas/kagi/releases/latest/download/install.sh &&
gh attestation verify install.sh --repo rubas/kagi &&
KAGI_INSTALL_VERIFY=require sh install.sh
```

| Variable | Effect |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `KAGI_INSTALL_VERIFY` | `auto` (default) verifies when `gh` is available. `require` fails without `gh`. `skip` does not verify. |
| `KAGI_INSTALL_BASE_URL` | Downloads the archive from this URL instead of the GitHub release, for example `file:///tmp/kagi`. Needs a version tag. |
| `KAGI_INSTALL_VERSION` | The version tag when no argument gives one. |
| `KAGI_INSTALL_REPO` | The GitHub repository, `rubas/kagi` by default. |

### From source

```bash
cargo install --git https://github.com/rubas/kagi.git
```

### With Nix flakes

Install the CLIs directly:

```bash
nix profile install github:rubas/kagi
```

Or enable the Home Manager module to install the CLIs:

```nix
{
inputs.kagi.url = "github:rubas/kagi";

outputs = { kagi, ... }: {
homeConfigurations.example = home-manager.lib.homeManagerConfiguration {
modules = [
kagi.homeManagerModules.default
{
programs.kagi.enable = true;
}
];
};
};
}
cargo install --git https://github.com/rubas/kagi
```

## Authentication
Expand Down Expand Up @@ -153,12 +88,11 @@ kagi-summarize 'https://www.rust-lang.org/learn' --lang DE --json
## Development

```bash
nix develop
task check
```

`task lint` also runs [zizmor](https://github.com/zizmorcore/zizmor) over the workflows. The dev
shell does not include it, so install `zizmor` yourself or that step fails.
`task lint` also runs [zizmor](https://github.com/zizmorcore/zizmor) over the workflows, so install
`zizmor` first.

## License

Expand Down
18 changes: 0 additions & 18 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,6 @@ tasks:
cmds:
- cargo check --release

test:nix:
desc: Build the default Nix package
cmds:
- nix build .# --no-link

deps:machete:
desc: Check for unused dependencies
cmds:
Expand Down Expand Up @@ -103,23 +98,10 @@ tasks:
- task lint
- task test
- task test:release-check
- task test:nix
- task deps:machete
- task deps:deny

build:
desc: Build the release binary
cmds:
- cargo build --release

install:
desc: Install the local build with install.sh, in the same layout as a release (Linux x86_64 and macOS aarch64 only)
vars:
ROOT: '{{if eq OS "darwin"}}kagi-macos-aarch64{{else}}kagi-linux-x86_64{{end}}'
cmds:
- cargo build --release
- rm -rf target/dist
- mkdir -p target/dist/{{.ROOT}}/bin
- cp target/release/kagi-search target/release/kagi-maps target/release/kagi-summarize target/dist/{{.ROOT}}/bin/
- tar -czf target/dist/{{.ROOT}}.tar.gz -C target/dist {{.ROOT}}
- KAGI_INSTALL_BASE_URL="file://$PWD/target/dist" KAGI_INSTALL_VERIFY=skip sh install.sh --force "v$(target/release/kagi-search --version | cut -d' ' -f2)"
43 changes: 0 additions & 43 deletions flake.lock

This file was deleted.

Loading