Fix#65
when the user presses Enter to run a command, Iris sets `isCommandActive
= true` so it knows a command is running and skips rendering the
overlay. After the command finishes, `isCommandActive` needs to reset to
`false` for Iris to work again. In zsh/fish, preexec/precmd hooks send
an `IRIS_CMD_STOP` signal over the IPC pipe, which Iris receives to
reset `isCommandActive = false`. Bash has no equivalent hook, so
`IRIS_CMD_STOP` is never sent and `isCommandActive` stays stuck at true
forever
so I added a bash-only fallback inside `isExecuting()`: if
`isCommandActive` is true but `TIOCGPGRP` (a kernel API) confirms the
shell's process group is back in the foreground (meaning the command
finished), automatically reset `isCommandActive` to false. zsh/fish
still rely on IPC signals as before
also added a `PROMPT_COMMAND` hook to iris init bash to `send
IRIS_CMD_STOP` after every command (belt-and-suspenders), though that's
not the main fix
### Summary of Changes
Fixes **#53** (*Fish shell integration panics with `inappropriate ioctl
for device`*).
#### 1. Fixed Non-TTY Stdin (`panic: inappropriate ioctl for device`) —
Fixes#53
- **Root Cause**: When executing `iris init fish | source` (or sourcing
shell configs), `os.Stdin` (FD 0) is connected to a pipe instead of a
TTY. Calling `term.MakeRaw()` on
a pipe returns `ENOTTY`.
- **Fix**: Guarded `term.MakeRaw()` with `term.IsTerminal()` checks
across `root/wrapper.go` and `root/root.go`. Added fallback to open and
use `/dev/tty` when `os.Stdin` is
not a terminal device.
- **Fish IPC Hooks**: Added `fish_preexec` and `fish_postexec` event
handlers to `iris init fish` to send `IRIS_CMD_START` / `IRIS_CMD_STOP`
IPC signals over `$IRIS_FD`.
#### 2. Fixed Shell Setup Order (Duplicate `fastfetch` / startup
executions) — Fixes#53
- **Root Cause**: `iris setup` appended the init script to the bottom of
shell configs (`config.fish`, `.zshrc`, `.bashrc`), causing pre-existing
interactive startup commands
to run twice.
- **Fix**: Updated `setupCmd` in `root/init.go` to **prepend** `# Iris
Autocomplete` to the top of shell configuration files.
#### 3. Fixed Terminal Exit Loop Handling — Relates to #50
- **Root Cause**: When typing `exit` in the wrapped shell, Linux PTY
returns `syscall.EIO` (`Input/output error`) on `ptmx.Read()` rather
than `io.EOF`. `runWrapper()` was
ignoring non-EOF errors and looping indefinitely without restoring the
terminal or calling `os.Exit(0)`.
- **Fix**: Updated the `ptmx.Read` error handler in `root/wrapper.go` to
handle `syscall.EIO` and exit cleanly.
---
### Issues Addressed
- Closes#53
- Relates to #50, #55
---
### Verification Tested
- [x] Verified `iris setup fish` / `iris init fish | source` initializes
without `ioctl` panic.
- [x] Verified typing `exit` in Fish, Zsh, and Bash terminates IRIS
cleanly and restores standard terminal state.
- [x] Ran `go test ./...` — all tests pass.
---------
Co-authored-by: verse91 <versedev.store@proton.me>
Co-authored-by: VERSE <sunnyone0901@gmail.com>
## Add
Make these things configurable
- Expand aliases
- Suggest hidden files (#59)
- Toggle menu and mode
```
[ui]
hidden-files = true # or false
[core]
expand-alias = true # or false
[keybindings]
toggle-mode = "ctrl+r"
toggle-menu = "ctrl+space"
```
- Auto reload config on changes: now just changes config and save the
file, IRIS will auto detect and reload in silent
- Added all these in config on init and docs
## Fix
I tested on holding backspace and the ghost text keep glitching so I
fixed it, this is just a small fix
- add transition scoring engine to learn sequential workflows per
directory using command skeletons
- prioritize current active git branch over older branches in
suggestions
- restore strict chronological order for history navigation and bypass
AI re-ranking
- add in-memory session history for instant access to just-run commands
- fix PTY prompt not syncing when using arrow keys in the history menu
- fix history tie-breaker to properly prioritize newer commands by
assigning larger IDs
- fix potential mutex deadlock between bufferMu and pty write during
history navigation
- fix workspace git detection to remove depth limits and correctly
identify repositories with detached HEADs
- fix SQLite connection leaks in frecency queries
- fix global state leaks in history tests by snapshotting and restoring
registry states
- modernize string prefix checks using strings.CutPrefix
When you paste text in most modern terminals (Alacritty, iTerm2, Kitty,
WezTerm...), the terminal enables bracketed paste mode and wraps the
pasted content between two control strings:
`\x1b[200~` --> start pasting
`\x1b[201~` --> end pasting
Previously, iris detected these two strings but didn't track the state.
Now I have:
Declared `inBracketedPaste := false` before the stdin loop
Set `inBracketedPaste = true` when receiving `\x1b[200~`, `false` when
receiving `\x1b[201~`
Checked `!inBracketedPaste` before triggering the alias expansion
reset `inBracketedPaste` on enter/ctrl-c/ctrl-u and when executing
Enhance lookup mechanics and priority propagation (`spec/lookup.go`)
Remove the requirement of typing a leading `-` when searching for
options, allowing flag suggestions to surface naturally during input
Accurately forward the `Priority` field from registry specs into the
`Suggestion` struct so the scoring engine evaluates relevance properly
Integrate scoring into the main suggestion pipeline
(`root/suggestions.go`)
Collect context signals using `scoring.CollectSignals(cwd, query,
rootCmd, store)` with the live working directory retrieved from
`spec.GetCWD()`
Pass the entire deduplicated list across spec, history and AI items
through `scoring.Score(deduped, signals)` to compute scores and sort by
descending order before rendering on screen
Record execution history in Frecency Store (`root/wrapper.go`)
Save the last executed command to `lastSubmittedCommand` whenever Enter
is pressed or a suggestion is selected
Trigger `store.Record(...)` asynchronously within the `IRIS_CMD_STOP`
hook using a dedicated goroutine guarded by panic recovery and timeout
limits, preventing blocks on the main shell thread
Optimize workspace identification for AI
(`internal/ai/context_provider.go`)
Use `workspace.DetectCached(cwd)` to instantly fetch ecosystem context
across Git, Node, Go, Rust, Python and Docker alongside active git
branch state
This caching mechanism avoids redundant subprocess execution when
outside git repositories, significantly speeding up prompt context
generation
This project is starting to grow, and I've seen flaws in the initial
project structure design
I think I'll restructure the entire project directory for better
scalability and also cleaner
## Feat
* feat(ai): add AI suggestion engine, context gathering, and ghost text
overlay (`v0.3.0`)
## Security & Perf
* fix(ai): restrict background `--help` execution to a hardcoded command
allowlist to prevent RCE
* fix(root): defer context cancellation in goroutine to prevent resource
leaks
* perf(ai): implement LRU eviction and maximum size limit for
`ProviderCache`
* perf(ai): truncate command context output
(`CommandContextProvider.Gather`) to 1000 characters to save tokens
## Bug Fixes
* fix(ai): add mutex synchronization and thread-safe snapshotting to
`AIEngine.RegisterProvider` and `GatherDynamicContext`
* fix(ai): return a copy of fresh `Suggestion` in `AIEngine.Suggest` to
prevent cache mutation
* fix(ai): use length-prefixed encoding in `EnvSnapshot.Hash` to prevent
delimiter collisions
* fix(ai): skip variable assignment lines containing `=` when extracting
Makefile targets
* fix(runner): check `scanner.Err()` and return `nil` on scan errors in
justfile generator
* test(ci): rename `git commit` to `git checkout` in overlay test to
resolve CI `typos` false positive
- I think it would be better if one for commands only, one for the spec
handling core logic so people won't be confused by the core logic inside
the commands folder (cleaner I guess)
- Regen docs
This pull request modernizes the codebase by adopting Go 1.21+ features, including built-in functions like min and max, standard library iterators such as strings.SplitSeq and strings.FieldsSeq, utility functions like maps.Copy and slices.Contains, and string manipulation helpers like strings.Cut and strings.CutPrefix. Feedback is provided on a test file where the usage of strings.Builder can be further optimized to avoid unnecessary string allocations during concatenation.
`go fix -diff ./...`
- correct nightly release tag name
989b61eefb212c18ca04b2121b382f19f86e39c2
- iris not start in tmux 0fef95430b6a1877810e3a4ffd8aa658f75c542c
- suggestions only show on full word typing
f29cbfd74a2d90371f8f369e6f8e7419f979da38
- keep current dir on reload instead of return home dir
a923e78f52a95e06587aff6856a6a81319b38e84