Commit Graph
221 Commits
Author SHA1 Message Date
github-actions[bot] b934d7d837 docs(changelog): update for v0.6.0 [skip ci] 2026-08-09 14:13:51 +00:00
VERSE dd1fb156fc feat(history): atuin history support (#134)
closes #91

3 mode config atuin history
```toml
[core]
# 0 = off, 1 = atuin history only, 2 = atuin history + default history
atuin-history = 0
```
Default is Mode 0 (turn off), who uses atuin history has to config it
manually

Mode 1 = atuin only (as you can see only 11 commands):
<img width="1285" height="466" alt="image"
src="https://github.com/user-attachments/assets/ca520ec7-fb45-4403-8087-a4951ba8dba0"
/>

Mode 2 = combine shell history + atuin history (prefer atuin):
<img width="1261" height="469" alt="image"
src="https://github.com/user-attachments/assets/1558ad3e-38f3-4d6e-bc8e-cfc00ea9cb4b"
/>

Mode 0 = turn off atuin

---
Custom atuin db path if anyone's using their own path (leave empty to
use default from atuin)
```toml
atuin-db-path = ""
```

---

I also handled the search menu overlay of Atuin, IRIS won't show in this
mode, but you have to change the keybind between 2 tool cuz they're
using same keybind Ctrl + R, but I think using IRIS make it unnecessary
to use Atuin search mode (82b180c9610f75d41008a54dfde474c7f2cce015)


<img width="70%" alt="image"
src="https://github.com/user-attachments/assets/e0c62050-7e6e-4e37-a1cc-2bfb63e1e984"
/>

<i><b>Before (Menu layout completely broken)</b></i>

<img width="50%" alt="image"
src="https://github.com/user-attachments/assets/1e6d8de9-cde8-473d-8a42-4748c480c812"
/>

<i ><b>After handling (not shows anymore)</b></i>
2026-08-09 21:08:11 +07:00
github-actions[bot] bf4f424e79 docs(changelog): update for v0.5.4 [skip ci] 2026-08-08 07:30:41 +00:00
shemishtameshandshemishtamesh e334af8d88 fix(nix): update stale vendorHash for new go.mod dependencies (#132)
new dependencies added in #131 require updating the `vendorHash` in the
nix flake

Co-authored-by: shemishtamesh <shemishtamail@gmail.com>
2026-08-08 14:27:20 +07:00
github-actions[bot] 55d55957c0 docs(changelog): update for v0.5.3 [skip ci] 2026-08-07 10:19:56 +00:00
VERSE 87b91c45d7 feat: update changelog (#131)
closes #130 

- CHANGELOG.md file for people who can view changelog from github
---
`iris changelog` command:
`iris changelog [version]` (e.g. iris changelog v0.5.1)
`iris changelog -n 3` (see changelog of 3 latest releaseas)

=> `iris changelog` looks just like CHANGELOG.md, grouped headers and
all. It only stops looking that way if we personally overwrite that
release's description with something else
=> With 1-hour local cache (invalidated on updater-channel change),
`--refresh` flag to bypass, graceful fallback to stale cache on GitHub
rate-limiting

---
- New auto update config
```toml
# 0 = off (default, notify only), 1 = auto-install, 2 = always confirm first
auto-update = 1
```

- New just debug-changelog and just debug-autoupdate recipes (fully
offline, mocked HTTP servers, no real network/config touched)
2026-08-07 17:16:18 +07:00
Cedric 4a4ab3c102 fix(wrapper): follow the shell working directory in the wrapper process (#129)
Fixes #124.

Since #78 the shell reports `IRIS_CWD` on `chpwd`, but the wrapper only
passes it to
`spec.SetCWD` for suggestions. Its own working directory never moves, so
tools that
read the pane's foreground process to locate the shell resolve the wrong
path after a
`cd`. I hit this with herdr, which stopped detecting the git repository
of a pane once
IRIS was in it. tmux uses the same lookup for `pane_current_path`.

The absolute path check matches what `spec.SetCWD` already does, so both
treat a
malformed value the same way. The `os.Chdir` error is dropped because
the path comes
from the shell integration, the user cannot act on the failure, and
keeping the last
known directory is better than stopping the loop.

`go test ./...` passes. I tested this end to end on macOS only: the
wrapper followed
the `cd`, and herdr picked the repository back up.

One limitation: the outer launcher process keeps its start directory,
only the wrapper
running `runWrapper` follows. That was enough for herdr, which reads the
wrapper.
2026-08-06 19:36:48 +07:00
VERSE fc1634b007 fix: start iris in multiplexer panes instead of inheriting a dead one (#120)
closes #62
when you open a new Zellij pane, the shell inherits Iris’s environment
variables, so it thinks Iris is already running. But the pane doesn't
inherit the underlying connection (FD 13), so suggestions silently fail
into a dead pipe

the old code only checked for `tmux` by process name, ignoring Zellij
completely

- Fixed:

instead of checking for specific app names, Iris now tracks the active
terminal device (`IRIS_TTY`)

if a new shell detects that it's on a different `TTY` than Iris, it
clears the stale environment variables so Iris can start fresh. The
`IRIS_PID != PPID` check prevents Iris from trying to re-exec itself
when spawning sub-shells.

```sh
if [ -n "$IRIS_PID" ] && [ "$IRIS_PID" != "$PPID" ] && [ "${TTY:-$(tty 2>/dev/null)}" != "$IRIS_TTY" ]; then
    unset IRIS_PID IRIS_IS_CHILD IRIS_FD IRIS_TTY
fi

```
2026-08-06 15:42:56 +07:00
verse91 2a87cd9783 fix(ci): prevent goreleaser resolving a same commit nightly tag as the current tag 2026-08-06 13:59:54 +07:00
VERSE 7a97ea9016 fix: mode doesn't work correctly (#128)
closes #122 
please read the conversation to understand this change

The bug was that the reset-mode-to-config-default logic already existed
in the code (activeMode = loadMode()) but sat in a switch case that
could never execute, the bytes it matched (\r, \n, Ctrl+C, Ctrl+U) were
already intercepted and handled earlier in the same loop iteration with
an unconditional continue, so control never reached that switch
2026-08-06 13:46:40 +07:00
VERSE ce404335ed docs(readme): remove ⌘ 2026-08-06 13:42:53 +07:00
VERSE a93a31ab4e fix(ci): nightly tags breaking release changelogs (#126)
After released v0.5.0, I saw that v0.5.0 showed only 1 commit changelog
instead of the real 16 commits since v0.4.21

Nightly builds tag every push to main, so a nightly tag can land on the
exact same commit as a stable release tag
GoReleaser picked that nearby nightly as the `previous release` when
building the changelog

Fixes:

- `.goreleaser.yaml`: added `git.ignore_tags`: ["*-nightly.*"] so
changelog diffing skips nightly tags entirely
- `nightly.yml`: the cleanup step deleted a tag named `nightly`, but
each run tags as `v<version>-nightly.<sha>`, so it never actually
deleted anything and nightly tags piled up unbounded. Now deletes all
previous `v*-nightly.*` tags/releases before creating the new one
2026-08-06 10:43:06 +07:00
João Vitor Alves 0595ddd4b9 fix: update nightly releases (#125)
Nightly updates correctly detected the newest version, but the installer
always queried GitHub’s `/releases/latest` endpoint. Since that endpoint
only returns the latest stable release, `iris update` downloaded the
stable binary even when the nightly channel was configured.

This change passes the selected nightly tag to the installer through
`IRIS_RELEASE_TAG`. When set, the installer queries
`/releases/tags/<tag>`, locates that nightly release’s assets, and
installs the correct binary. Stable updates continue to use
`/releases/latest` unchanged.
2026-08-06 10:12:46 +07:00
VERSE 994ff83675 docs(readme): small note in shell config and fix line space
Clarified IRIS's advantages over Fig and added note about auto-start configuration.
2026-08-05 00:17:49 +07:00
verse91 53f104577f docs: add auto-start setup instructions 2026-08-05 00:06:13 +07:00
VERSE d299d1c7c7 refactor(path): use XDG config for all platforms (#119)
closes #112
Replace `os.UserConfigDir()` with explicit `~/.config` fallback to align
macOS, Linux, and other platforms on same config location
Respects `XDG_CONFIG_HOME` if set, otherwise uses `~/.config/iris/`
2026-08-04 23:51:59 +07:00
VERSE 75aa1fbe38 fix: handle non-ascii characters command (#118)
closes #106

please read the conversation to understand this PR
tested on:
- Accented letters: é, ü, ñ
- Non-Latin scripts: Chinese characters (中文), Arabic (العربية)
- Symbols & Punctuation: ©, €, ™, —
- Emojis: 🚀, 😀

<img width="1312" height="976" alt="image"
src="https://github.com/user-attachments/assets/613f7e2b-3681-4a64-aeeb-e44f4276c8ee"
/>
2026-08-04 23:13:23 +07:00
VERSE 30619a8621 docs: AI guide (#117)
- AGENTS.md
- CLAUDE.md

I think we need this because I know many or most of contributors is
using AI for contributing
This is not excessive
2026-08-04 22:34:21 +07:00
VERSE 3a97efad18 docs(readme): add themes directory reference
Updated the themes directory reference in README
2026-08-04 15:16:35 +07:00
VERSE b5734b4e85 docs: theme config and list of theme templates (#116)
- Added theme configuration guide in README
- Added some theme templates
- Added list of theme templates in `themes/`
2026-08-04 15:15:21 +07:00
b14b26e663 feat(config): add theme customization (#81)
Added theme customization via config.toml
#17
```
[theme]
border = "#665C54"
accent = "#FABD2F"
muted = "#928374"
text = "#EBDBB2"
text_sel = "#FBF1C7"
match = "#FE8019"
desc = "#A89984"
desc_sel = "#EBDBB2"
sel_bg = "#504945"
scroll_info = "#83A598"
ghost_text = "#7C6F64"
hist= "#fe8019"
hist_sel = "#d65d0e"
sys = "#fb4934"
sys_sel = "#cc241d"
alias = "#b8bb26"
alias_sel = "#98971a"


```

---------

Co-authored-by: verse91 <versedev.store@proton.me>
Co-authored-by: VERSE <sunnyone0901@gmail.com>
2026-08-04 13:49:10 +07:00
VERSE b79d25a082 docs(readme): add navigate-right config 2026-08-03 18:50:04 +07:00
Ashvin Singh dfaa051f31 fix: make Right Arrow configurable and correct overlay positioning (#110)
## Summary

Closes #108

This PR fixes two issues related to terminal interaction and rendering:

- Make Right Arrow ghost acceptance configurable instead of hard-coded.
- Correct overlay positioning when the shell prompt wraps across
terminal lines.

## Changes

### Right Arrow configuration

- Add a new `navigate-right` keybinding to the configuration.
- Add `navigate-right = "right"` to the default configuration to
preserve existing behavior.
- Update the wrapper to use the configured binding instead of a
hard-coded Right Arrow check.
- Forward the Right Arrow escape sequence to the PTY when
`navigate-right` is unset, allowing the shell or terminal to handle it
normally.

### Overlay positioning

- Compute the cursor's current column from the total visual width
instead of using the accumulated width directly.
- Correctly handle wrapped prompts by calculating the cursor column
modulo the terminal width.
- Clamp the overlay position so it never extends beyond the terminal
width.
- Extend debug logging with the computed cursor position to aid
troubleshooting.

## Why

Right Arrow ghost acceptance was previously implemented as a hard-coded
behavior, making it impossible to disable or remap through
configuration. This change makes it consistent with the existing
configurable keybindings while preserving the default behavior.

Overlay positioning assumed that the prompt length represented the
cursor's current column. When the prompt wrapped onto a new terminal
line, this assumption caused the suggestion overlay to be positioned
incorrectly. Computing the cursor column from the wrapped position
ensures the overlay is aligned with the actual cursor.

## Testing

- [x] Default configuration retains Right Arrow ghost acceptance.
- [x] Setting `navigate-right = ""` forwards Right Arrow to the shell.
- [x] Existing keybindings continue to function as before.
- [x] Overlay is correctly positioned for both short and wrapped
prompts.
- [x] Overlay remains within terminal bounds.
2026-08-03 18:48:53 +07:00
shemishtameshandshemishtamesh 0b77c9334b fix(spec): isolate __complete probe from the controlling terminal (#111)
run the `__complete` probe subprocess in its own session so that a
cobra-incompatible binary that ignores `__complete` can't mess with the
user's controlling terminal.
tested on both macos and nixos.
encountered the problem while trying to use
[visidata](https://www.visidata.org/).

---------

Co-authored-by: shemishtamesh <shemishtamail@gmail.com>
2026-08-03 17:05:47 +07:00
d669e97423 fix: support kitty keyboard protocol for ctrl keybindings (#101)
Fixes #88

## Root cause

`MatchKey` treated `Ctrl+M` and the Enter key as the same raw byte
(`0x0d`). After editing the generated config, a `ctrl+m` binding could
shadow Enter, causing Return to toggle mode instead of executing the
selected command.

While investigating this, I also found that `MatchKey` only recognized
raw control bytes for `ctrl+<letter>` bindings. In Fish and terminals
that use the Kitty keyboard protocol (e.g. Kitty and Foot), those key
combinations may instead be sent as CSI sequences such as `\x1b[106;5u`,
preventing navigation bindings like `ctrl+j` / `ctrl+k` from being
matched.

## Changes

* `internal/config/keys.go`

* Reserve the Enter byte (`0x0d`) so it cannot be claimed by a `ctrl+m`
keybinding.
* Add `matchKittyCtrl()` to support Kitty keyboard protocol CSI
sequences for `ctrl+<letter>` bindings when the Ctrl modifier is
present.
* `root/wrapper.go`

* Extract `handleNavKey()` to remove duplicated navigation handling
logic.
* `internal/config/config_test.go`

* Add regression tests covering the Enter/`ctrl+m` fix and Kitty
keyboard protocol key sequences.

## Tested

* `go test ./...` — 201 passed
* Verified that Enter is no longer shadowed by `ctrl+m` after editing
the generated config.
* Verified that `ctrl+j` / `ctrl+k` navigation works correctly in Fish.

---------

Co-authored-by: verse91 <versedev.store@proton.me>
Co-authored-by: VERSE <sunnyone0901@gmail.com>
2026-08-02 14:40:55 +07:00
VERSE 6faa2e3274 feat(spec): support tool aliases (#107)
closes #57

IRIS now automatically read and suggest internal configuration aliases
for Git (`.gitconfig`, `.git/config`) and Cargo (`.cargo/config.toml`)

- Added the `Provider` interface and extended registry for CLI tools
that define aliases
- Git: parse aliases via `git config --show-scope`, supporting raw
tab/space separation and scope differentiation
- Cargo: traverse the directory tree upwards to root to read the
`.cargo/config.toml` configuration
- 0ms hot-path caching: key caching is calculated entirely via `os.Stat`
mtime (no subprocess spawn) combined with a 2-second TTL window to
ensure 0ms latency when typing
- Lookup integration: display alias suggestions at the subcommand level
and automatically expand aliases as the user enters further arguments
(ignore shell pipeline commands starting with `!`)
2026-08-02 14:30:46 +07:00
M57 476ca3946b fix: update stale vendorHash after lipgloss v2 upgrade (#99)
Commit `efc49ba` (feat: upgrade to lipgloss v2, #94) changed
`go.mod`/`go.sum` (lipgloss v1 → v2, ~24 dependency version bumps) but
did not update `vendorHash` in `flake.nix`.

As a result `nix build .#iris` (and any consumer) fails with a
fixed-output derivation hash mismatch:

```
error: hash mismatch in fixed-output derivation 'iris-<rev>-go-modules.drv':
         specified: sha256-kBSMhUsuCKIjAXjGfl1WSjCX+tlGi9BTnkRu9ScW6M0=
            got:    sha256-KQNloP/Aj283YQ4d5LFu/2Pbb2HbVTZPhLK1fs4xvGw=
```

This one-line change updates `vendorHash` to the hash actually produced
by the module set at HEAD. Verified: `nix build .#iris` succeeds with
the corrected hash.

Run `nix flake update` afterwards to regenerate `flake.lock`.
2026-08-01 18:51:42 +07:00
Kieran Klukas df42c95fa9 feat: adopt x/ansi instead of hand rolling escape sequences (#96)
also contains the lipgloss width change from #94
2026-08-01 16:30:52 +07:00
Kieran Klukas efc49bacfe feat: upgrade to lipgloss v2 (#94)
Hi! 

I upgraded lipgloss to v2 and also took the opportunity to migrate some
of the raw escape sequence handling to x/ansi. Feel free to cherry pick
whatever is helpful from this!
2026-08-01 00:19:16 +07:00
VERSE 23bd718899 docs(readme): reorder badge and description 2026-07-31 23:21:30 +07:00
VERSE bf75dc239b feat(path): support for XDG base directories (#95)
closes #93
2026-07-31 22:58:09 +07:00
VERSE aba4dc9716 chore(readme): #2 repo of the day badge
Updated README to include Trendshift badge and reordered platform badges.
2026-07-31 22:41:32 +07:00
verse91 9786f14158 chore(aur): transfer the aur maintainer 2026-07-31 22:31:25 +07:00
VERSE 8a1cec331a fix(overlay): dynamic select key ui component (#90)
closes #85
2026-07-31 19:03:38 +07:00
VERSE 235a7f98ea fix(config): resolve enter key submission and keybinding issues (#89)
closes #88
closes #85
2026-07-31 18:38:31 +07:00
verse91 85a9a7d55d fix(release): rename AUR package to iris-cli-bin due to upstream conflict 2026-07-31 17:48:27 +07:00
verse91 331f4c176c chore(release): release v0.4.18 2026-07-31 17:45:12 +07:00
verse91 84a7064e6a fix(release): correct AUR git url and workflow secret mapping 2026-07-31 17:32:38 +07:00
verse91 e4d799bdd8 chore(gitignore): ignore vendor directory and generated tarballs 2026-07-31 17:29:37 +07:00
verse91 15b5cccc42 fix(release): use preremove instead of prerm for goreleaser v2 compatibility 2026-07-31 17:23:21 +07:00
VERSEanduse-the-fork e09f4609f6 build: support pkg managers installation (#87)
closes #71, #84, #86
- AUR
- Homebrew
- Nix
- Debian (.deb)
- RPM (.rpm)
- Aqua
- ASDF

This is my first time doing this, so there might be mistakes. If you
can't download it through any pkg manager, please leave a comment or
open an issue

---------

Co-authored-by: use-the-fork <23747916+use-the-fork@users.noreply.github.com>
2026-07-31 17:16:31 +07:00
VERSE e9e50c7dea fix(history): respect zdotdir config (#83)
closes #82

Also added a `HISTFILE` so it always reads the correct file that the
shell is pointing to

Is there a `HISTFILE`? If so, use it
If it's Zsh: Is there a `ZDOTDIR`? Use `ZDOTDIR/.zsh_history`
If it's Fish: Is there an `XDG_DATA_HOME`? Use
`XDG_DATA_HOME/fish/fish_history`
If none of them are present, revert to the default `$HOME/...`
2026-07-31 15:12:49 +07:00
verse91 9663788de6 fix(config): sync config_cmd.go template with init.go template 2026-07-31 11:05:28 +07:00
VERSE 4421d6e6a5 docs(readme): warning about potential conflicts 2026-07-31 10:55:54 +07:00
VERSE a885c7462a feat(config): ui width, auto exec, selection and navigation configs (#80)
closes #67

So I made an auto-exec confg `auto-exec = true`
(e32c0ba6ed69f3c764353e58b8fbacf160f37d5a) which means:
- If you want your command in the prompt to be executed right away, you
can set this = false (for example, you are typing `nvim ~/.conf` but
IRIS is suggesting `nvim ~/.config`, it will ignore the suggestion and
exec what you are typing, this is current default behavior)
- If you want to auto execute full command which is being suggested, you
can set this = true (this is the opposite of above, when you are typing
`nvim ~/.conf` but IRIS is suggesting `nvim ~/.config`, it will auto
exec `nvim ~/.config` instead, but sometime you want to exec what you
are typing instead of the suggestion right?, just press esc or shift tab
to hide the menu and it will)

---

Select keybinding to replace tab
(0dc01cba8c610e8d6fd8c50f6a71bdcc061a098f)
`select = "ctrl+y"`

Some users may love nvim keybinding or emacs, so I bring navigation
keybinding to be configurable (0dc01cba8c610e8d6fd8c50f6a71bdcc061a098f)
```
navigate-up = "ctrl+k"
navigate-down = "ctrl+j"
```
---

I also added a option for UI width
(dfa3b810a7be406fe4652b3886020f37bb166811)
`max-width = 80`
- If you configure `max-width` to be larger than the actual width of the
current terminal, Iris will automatically "compress" the window to match
the terminal's width (meaning it will never overflow and break the
interface)
- If you configure `max-width` too small (e.g 10), the interface will
have cramped text, making it look very bad. So, I've set a minimum safe
min limit of 40. If the configured value is smaller than this, Iris will
automatically use 40

Small note: If you set `max-width = 0` (or leave it blank), it will
automatically use Iris's default standard size of 76. SO you can
confidently customize it without fear of breaking the UI (I hope so
lmao)

---

Added a fallback to ensure Iris never crashes or loses shortcuts if the
user accidentally deletes keybinding configuration lines or
intentionally assigns empty strings " "
(f682c9bf623f3ed46ad0763221145604dbd91b07)

Fix typo `toggle_mode` to `toggle-mode`
(b39be6673e552735fa65a6c9807510c83b4d9cdd)

if you have a better config design, please tell me, I always listen to
your idea
2026-07-31 10:49:10 +07:00
Pavel NaumovandPavel Naumov 9f43fcb352 fix: sync shell working directory for suggestions (#78)
## Summary
- synchronize the shell current working directory with Iris over the
existing IPC pipe
- use the synchronized directory for file, workspace, Git, and history
suggestions on macOS
- preserve the Linux `/proc/<pid>/cwd` and process-CWD fallbacks
- update zsh, bash, and fish integrations while preserving command exit
status

## Problem
On macOS, `/proc/<pid>/cwd` is unavailable, so `GetCWD` fell back to the
directory where Iris was launched, usually `$HOME`. After changing
directories in the shell, file suggestions could therefore continue to
come from `$HOME`.

## Tests
- `go test -race ./spec`
- `go test ./root -run ^'$'`
- `go test ./... -run ^'$'`
- generated zsh, bash, and fish hook syntax checks

Co-authored-by: Pavel Naumov <Pavel.Naumov@berekebank.kz>
2026-07-31 10:01:05 +07:00
Paolo Ricciuti cee756e2c1 fix: arrow up history entries (#77)
Closes #76 

Session history was recorded only after receiving `IRIS_CMD_STOP`.
Directly launched Bash sessions may not install that completion hook,
and Bash does not flush `.bash_history` until the shell exits.

There was also a race where `Enter` was sent to the shell before Iris
stored the submitted command, allowing fast commands to finish before
the command was captured.

The fix is

- Record commands in session history immediately when they are
submitted.
- Store the submitted command before sending Enter to the shell.
- Keep command-completion handling responsible for exit-code and
frecency data.

Once again (and please tell me if you prefer not) I'm not fluent in `go`
so this was all Sol
2026-07-31 09:53:31 +07:00
Paolo Ricciuti 2573ad73b4 feat: add shell login option (#75)
Closes #72
2026-07-30 22:45:23 +07:00
VERSE 37182f7212 fix(history): substring fuzzy search (#74)
closes #73

<img width="1434" height="302" alt="image"
src="https://github.com/user-attachments/assets/87bb8431-40c7-4ee8-ad58-79c4fea6efa7"
/>

I used use prefix match
imagine you have a long command ENOUGH that you used to use (like
image), with fuzzy search + substring, it will always show suggestion
about that command in the list but in the bottom
and I see this very annoying

but now I limit the score from fuzzy search, if the command is too long
(which means fuzzy score is extremely weak), skip it right away

<img width="1296" height="437" alt="image"
src="https://github.com/user-attachments/assets/77d807a2-ddce-4c37-9f5b-a02cd44de325"
/>

it now has substring support
2026-07-30 21:11:34 +07:00
VERSE 0049256844 docs: move user guide to top level readme (#70)
- I moved all information from user guide docs to top level readme so
now people can find information about IRIS easier and faster
- Also, some people always ask me how to uninstall while uninstall
subcommand already in IRIS, I've added to docs
- Corrected the way to install with go command
2026-07-30 13:27:35 +07:00