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,8 +1,6 @@
## Install

Installs the binaries to `~/.local/bin` and the `kagi` skill to `~/.agents/skills/kagi`, and links
the skill into the skill directory of each agent that is set up: Claude Code, Codex, Antigravity,
and pi.
Installs the binaries to `~/.local/bin`.

```bash
curl -fsSL https://github.com/rubas/kagi/releases/download/__VERSION__/install.sh | sh -s -- __VERSION__
Expand Down
37 changes: 17 additions & 20 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,10 @@ jobs:
STAGING: ${{ matrix.staging }}
ARCHIVE: ${{ matrix.archive }}
run: |
mkdir -p "$STAGING/bin" "$STAGING/skills/kagi"
mkdir -p "$STAGING/bin"
cp target/release/kagi-search "$STAGING/bin/"
cp target/release/kagi-maps "$STAGING/bin/"
cp target/release/kagi-summarize "$STAGING/bin/"
cp skills/kagi/SKILL.md "$STAGING/skills/kagi/SKILL.md"
tar -czf "$ARCHIVE" "$STAGING"
- uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4.2.2
with:
Expand Down Expand Up @@ -209,10 +208,13 @@ jobs:
kagi_install() { HOME="$home" KAGI_INSTALL_BASE_URL="$dist" sh dist/install.sh "$@"; }
snapshot() { find "$home" -printf '%i %T@ %p %l\n' | sort; }

# Agent roots that exist get a link; the real skill copy of an older
# installer and a v0.4 per-binary skill dir go away.
mkdir -p "$home/.claude/skills/kagi" "$home/.codex" "$home/.gemini/antigravity-cli" \
"$home/.agents/skills/kagi-search"
# The upgrade from 0.5 removes the skill that release installed, its
# links, and a v0.4 per-binary skill dir.
mkdir -p "$home/.local/bin" "$home/.agents/skills/kagi" "$home/.agents/skills/kagi-search" \
"$home/.codex/skills"
ln -s ../../.agents/skills/kagi "$home/.codex/skills/kagi"
printf '#!/bin/sh\necho kagi-search 0.5.4\n' > "$home/.local/bin/kagi-search"
Comment thread
rubas marked this conversation as resolved.
Resolved
chmod +x "$home/.local/bin/kagi-search"
status=0
kagi_install --check "$TAG" || status=$?
test "$status" -eq 100
Expand All @@ -221,12 +223,9 @@ jobs:
test -x "$home/.local/bin/kagi-search"
test -x "$home/.local/bin/kagi-maps"
test -x "$home/.local/bin/kagi-summarize"
test -f "$home/.agents/skills/kagi/SKILL.md"
test ! -e "$home/.agents/skills/kagi"
test ! -e "$home/.agents/skills/kagi-search"
test "$(readlink "$home/.claude/skills/kagi")" = ../../.agents/skills/kagi
test "$(readlink "$home/.codex/skills/kagi")" = ../../.agents/skills/kagi
test "$(readlink "$home/.gemini/antigravity-cli/skills/kagi")" = ../../../.agents/skills/kagi
test -f "$home/.claude/skills/kagi/SKILL.md"
test ! -L "$home/.codex/skills/kagi"
test ! -e "$home/.pi"

# A second run finds the current version and changes nothing.
Expand All @@ -235,17 +234,15 @@ jobs:
test "$before" = "$(snapshot)"
kagi_install --check "$TAG"

# A symlinked config root gets the link realpath gives. A skills dir
# that links to the source dir keeps the real skill.
# A first install removes nothing: a skill the user brings stays.
home="$(mktemp -d)"
mkdir -p "$home/dots/claude" "$home/.agents/skills" "$home/.codex"
ln -s dots/claude "$home/.claude"
ln -s ../.agents/skills "$home/.codex/skills"
mkdir -p "$home/.agents/skills/kagi"
status=0
kagi_install --check "$TAG" || status=$?
test "$status" -eq 100
kagi_install "$TAG"
test "$(readlink "$home/.claude/skills/kagi")" = ../../../.agents/skills/kagi
test -f "$home/.claude/skills/kagi/SKILL.md"
test ! -L "$home/.agents/skills/kagi"
test -f "$home/.codex/skills/kagi/SKILL.md"
test -x "$home/.local/bin/kagi-search"
test -d "$home/.agents/skills/kagi"
- name: Write release notes
shell: bash
env:
Expand Down
21 changes: 4 additions & 17 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
## Goal

Unofficial Unix-style CLIs for Kagi: `kagi-search`, `kagi-maps`, `kagi-summarize`.
Each binary ships a companion agent skill from `skills/`.

## Gates

Expand All @@ -19,16 +18,6 @@ Each binary ships a companion agent skill from `skills/`.
needs `KAGI_SESSION_TOKEN` or `~/.config/kagi/session-token` and fails without
one.

## Layout

- `skills/kagi` is the one skill; it installs as `kagi`. A rename changes all
of these together:
- `install.sh` and the `install` task in `Taskfile.yml`
- `postInstall` and `skillNames` in `flake.nix`
- `.github/workflows/release.yml`
- the `name:` front matter in each `skills/*/SKILL.md`
- the documented install paths in `README.md`

## Decisions

- Three separate binaries. Do not reintroduce a combined command.
Expand All @@ -40,13 +29,11 @@ Each binary ships a companion agent skill from `skills/`.
`order` parameter. `kagi-maps` fetches the whole page, sorts locally, then
truncates to `--limit`.
- `install.sh` is the one installer. `task install` and the release smoke test
run it on local archives. It installs the skill once to
`~/.agents/skills/kagi` and links it into each agent's skill dir. The link
targets are the ones `realpath -m --relative-to` gives between the physical
paths, the same links a dotfiles fan-out from `~/.agents/skills` creates.
Keep them byte-identical, or the installer and the fan-out replace each
other's links on every run. `task install` packs the local build like a
run it on local archives. `task install` packs the local build like a
release archive, so it runs only on the two release platforms.
- The repo ships no agent skill; an agent that uses these CLIs brings its own.
On the upgrade from 0.5 or earlier, `install.sh` removes the skill that
release installed; later runs leave any `kagi` skill alone.
- 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 decides, not the parent commit, so a
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ 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/).

## [0.6.0] - 2026-09-26

### Removed

- The `kagi` agent skill. Releases no longer ship `skills/kagi`, and the Home
Manager module installs only the CLIs. On the upgrade from 0.5 or earlier,
`install.sh` removes `~/.agents/skills/kagi` and its links in `~/.claude/skills`,
`~/.codex/skills`, `~/.gemini/antigravity-cli/skills`, and
`~/.pi/agent/skills`. Each binary's `--help` lists every flag.

## [0.5.4] - 2026-09-23

### Added
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "kagi"
version = "0.5.4"
version = "0.6.0"
categories = ["command-line-utilities"]
edition = "2024"
homepage = "https://github.com/rubas/kagi"
Expand Down
27 changes: 4 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,8 @@ Requires a Kagi account with an active session token.
curl -fsSL https://github.com/rubas/kagi/releases/latest/download/install.sh | sh
```

The installer puts `kagi-search`, `kagi-maps`, and `kagi-summarize` in `~/.local/bin` and the
`kagi` skill in `~/.agents/skills/kagi`. It links the skill into the skill directory of each agent
whose configuration directory exists:

| Agent directory | Link |
| --------------------------- | ------------------------------------------------------------------------- |
| `~/.claude` | `~/.claude/skills/kagi` -> `../../.agents/skills/kagi` |
| `~/.codex` | `~/.codex/skills/kagi` -> `../../.agents/skills/kagi` |
| `~/.gemini/antigravity-cli` | `~/.gemini/antigravity-cli/skills/kagi` -> `../../../.agents/skills/kagi` |
| `~/.pi/agent` | `~/.pi/agent/skills/kagi` -> `../../../.agents/skills/kagi` |

A link replaces a skill directory that an older installer copied there. When a configuration
directory or its `skills` directory is a symlink, the link target is the relative path between the
resolved directories, the same path `realpath --relative-to` gives. A `skills` directory that links
to `~/.agents/skills` already holds the skill and gets no link.
The installer puts `kagi-search`, `kagi-maps`, and `kagi-summarize` in `~/.local/bin`. On the upgrade
from 0.5 or earlier, it removes the `kagi` agent skill and the links that release installed.

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.
Expand All @@ -43,7 +30,7 @@ Put a release tag or an option after `sh -s --`:

```bash
# Install a given release.
curl -fsSL https://github.com/rubas/kagi/releases/latest/download/install.sh | sh -s -- v0.5.4
curl -fsSL https://github.com/rubas/kagi/releases/latest/download/install.sh | sh -s -- v0.6.0
# 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
```
Expand Down Expand Up @@ -98,7 +85,7 @@ Install the CLIs directly:
nix profile install github:rubas/kagi
```

Or enable the Home Manager module to install the CLIs and companion skills:
Or enable the Home Manager module to install the CLIs:

```nix
{
Expand Down Expand Up @@ -218,12 +205,6 @@ kagi-summarize 'https://www.rust-lang.org/learn' --lang DE --json
- text: raw markdown summary
- json: `{ "summary": "..." }`

## Skills

This repo ships one companion skill for Claude Code and other agents:

- [`skills/kagi/SKILL.md`](skills/kagi/SKILL.md): one skill covering search, maps, and summarize

## License

[MIT](LICENSE)
3 changes: 1 addition & 2 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,7 @@ tasks:
cmds:
- cargo build --release
- rm -rf target/dist
- mkdir -p target/dist/{{.ROOT}}/bin target/dist/{{.ROOT}}/skills/kagi
- mkdir -p target/dist/{{.ROOT}}/bin
- cp target/release/kagi-search target/release/kagi-maps target/release/kagi-summarize target/dist/{{.ROOT}}/bin/
- cp skills/kagi/SKILL.md target/dist/{{.ROOT}}/skills/kagi/
- 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)"
25 changes: 2 additions & 23 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,7 @@
craneLib = crane.mkLib pkgs;
commonArgs = {
pname = "kagi";
version = "0.5.4";
# cleanSource, not crane's cleanCargoSource: postInstall installs the
# skills/*/SKILL.md files from the build source, which a cargo-only
# filter would drop.
version = "0.6.0";
src = pkgs.lib.cleanSource ./.;
strictDeps = true;
nativeBuildInputs = [
Expand Down Expand Up @@ -69,9 +66,6 @@
# The suite runs as its own check (checksFor) and in CI via `task test`;
# the installable package only builds the binaries.
doCheck = false;
postInstall = ''
install -Dm644 skills/kagi/SKILL.md "$out/share/kagi/skills/kagi/SKILL.md"
'';
}
);

Expand Down Expand Up @@ -151,20 +145,10 @@
let
cfg = config.programs.kagi;
package = self.packages.${pkgs.stdenv.hostPlatform.system}.default;
skillNames = [ "kagi" ];

mkSkillFiles =
root:
builtins.listToAttrs (
map (name: {
name = "${root}/${name}";
value.source = "${cfg.package}/share/kagi/skills/${name}";
}) skillNames
);
in
{
options.programs.kagi = {
enable = lib.mkEnableOption "Kagi search, maps, and summarization CLIs and skills";
enable = lib.mkEnableOption "Kagi search, maps, and summarization CLIs";

package = lib.mkOption {
type = lib.types.package;
Expand All @@ -175,11 +159,6 @@

config = lib.mkIf cfg.enable {
home.packages = [ cfg.package ];

home.file =
mkSkillFiles ".agents/skills"
// mkSkillFiles ".claude/skills"
// mkSkillFiles ".gemini/antigravity-cli/skills";
};
};
};
Expand Down
52 changes: 13 additions & 39 deletions install.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env sh
# Install or update kagi-search, kagi-maps, kagi-summarize, and the kagi skill.
# Install or update kagi-search, kagi-maps, and kagi-summarize.
#
# usage: install.sh [--check] [--force] [<version-tag>]
#
Expand Down Expand Up @@ -107,55 +107,29 @@ fi
tar -xzf "$tmp/${root}.tar.gz" -C "$tmp"

# Fail before touching any installed files if the archive layout drifted.
for file in bin/kagi-search bin/kagi-maps bin/kagi-summarize skills/kagi/SKILL.md; do
for file in bin/kagi-search bin/kagi-maps bin/kagi-summarize; do
if [ ! -f "$tmp/$root/$file" ]; then
echo "unexpected archive layout: missing $root/$file" >&2
exit 1
fi
done

# The per-binary skill dirs of v0.4 and earlier are legacy; remove them.
for dir in .agents/skills .claude/skills .codex/skills .gemini/antigravity-cli/skills .pi/agent/skills; do
rm -rf "$HOME/$dir/kagi-search" "$HOME/$dir/kagi-maps" "$HOME/$dir/kagi-summarize"
done

# The skill has one source, ~/.agents/skills/kagi.
skill="$HOME/.agents/skills/kagi"
rm -rf "$skill"
install -d "$skill"
install -m 644 "$tmp/$root/skills/kagi/SKILL.md" "$skill/SKILL.md"
skill="$(cd "$skill" && pwd -P)"

# Each agent whose config root exists gets a relative link to the skill. Like
# the realpath -m --relative-to of a dotfiles fan-out, the target runs between
# the physical paths, so it resolves through a symlinked config root and the
# installer and the fan-out never replace each other's link.
link() { # <agent config root>
[ -d "$HOME/$1" ] || return 0
install -d "$HOME/$1/skills"
dir="$(cd "$HOME/$1/skills" && pwd -P)"
# A skills dir that is the source dir already holds the skill.
[ "$dir/kagi" != "$skill" ] || return 0
base="$dir"
up=""
while :; do
case "$skill" in "$base"/*) break ;; esac
base="${base%/*}"
up="../$up"
# Releases up to 0.5.4 installed an agent skill: one kagi dir plus its links,
# or per-binary dirs in v0.4 and earlier. Remove them only on the upgrade from
# such a release, so a skill the user brings under the same name survives.
case "$installed" in
0.[0-5].*)
for dir in .agents/skills .claude/skills .codex/skills .gemini/antigravity-cli/skills .pi/agent/skills; do
rm -rf "$HOME/$dir/kagi" "$HOME/$dir/kagi-search" "$HOME/$dir/kagi-maps" "$HOME/$dir/kagi-summarize"
done
rm -rf "$dir/kagi"
ln -s "$up${skill#"$base"/}" "$dir/kagi"
echo "linked $HOME/$1/skills/kagi -> $up${skill#"$base"/}"
}
link .claude
link .codex
link .gemini/antigravity-cli
link .pi/agent
echo "removed the kagi agent skill that kagi ${installed} installed"
;;
esac

# kagi-search goes last: its --version marks the install as current, so an
# install that fails before it runs again in full.
install -d "$bin_dir"
for bin in kagi-maps kagi-summarize kagi-search; do
install -m 755 "$tmp/$root/bin/$bin" "$bin_dir/$bin"
done
echo "installed kagi ${target}: kagi-search, kagi-maps, and kagi-summarize in ${bin_dir}, the skill in ${skill}"
echo "installed kagi ${target}: kagi-search, kagi-maps, and kagi-summarize in ${bin_dir}"
Loading