Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
36 changes: 14 additions & 22 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,10 @@ 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.
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"
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"
# Past 0.5, a skill the user brings under the same name stays.
mkdir -p "$home/.claude/skills/kagi"
kagi_install --force "$TAG"
test -d "$home/.claude/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