docs: update guidelines for new user and developer (#16)

- Remove old docs 1ff2546f63b8eac799dcd70374258c0075380726
- Update guidelines for new user
- Update docs for development

---------
This commit is contained in:
VERSE
2026-07-02 16:54:03 +07:00
committed by GitHub
parent 8f89c15e72
commit b9cec2b3ac
9 changed files with 334 additions and 261 deletions
+1
View File
@@ -4,3 +4,4 @@ autocomplete
temp
docs/guide.md
task
docs/code
+221
View File
@@ -0,0 +1,221 @@
# IRIS documentation
Iris is a fast terminal autocomplete assistant written in Go. It wraps around your shell (Zsh, Bash, or Fish) to give you real-time command suggestions, a floating dropdown menu, and smart history search right where you type
## Table of contents
- [Getting started](#getting-started)
- [Usage guide](#usage-guide)
- [Configuration guide](#configuration-guide)
- [Troubleshooting guide](#troubleshooting-guide)
- [Developer guide](development.md)
## Getting started
### Dependencies
Before installing Iris, ensure your system meets the following requirements:
- OS: Linux or macOS
- Terminal emulator with ANSI escape sequence support
- Go 1.24 or newer if building from source
### Installation
You can install Iris using any of the three methods below:
#### Method 1: Install script (recommended)
Quickly download and install the precompiled binary using our install script:
```bash
curl -sSL https://raw.githubusercontent.com/versenilvis/iris/main/scripts/install.sh | sh
```
#### Method 2: Go install
If you already have Go installed on your system, install directly to your `GOBIN`:
```bash
go install github.com/versenilvis/iris@latest
```
Ensure that your `$GOPATH/bin` or `$HOME/go/bin` directory is added to your system `PATH`
#### Method 3: Build from source
To develop or compile Iris locally from source, install `just` command runner and execute `just reload`:
```bash
git clone https://github.com/versenilvis/iris.git
cd iris
just reload
```
### Shell integration setup
To enable intelligent auto-completion and overlay rendering, connect Iris to your shell environment
For Zsh (`~/.zshrc`):
```zsh
if command -v iris >/dev/null 2>&1; then
alias i="iris"
fi
```
For Bash (`~/.bashrc`):
```bash
if command -v iris >/dev/null 2>&1; then
alias i="iris"
fi
```
For Fish (`~/.config/fish/config.fish`):
```fish
if command -v iris >/dev/null 2>&1
alias i="iris"
end
```
Verify your installation by running:
```bash
iris version
```
## Usage guide
Once inside an interactive Iris session, your shell receives powerful real-time auto-completion overlays and navigation enhancements
### Core navigation
When you type a command or query, Iris displays a floating overlay box positioned directly below your cursor with matching suggestions
- Up arrow (`↑`): Move the selection cursor up through the suggestion list
- Down arrow (`↓`): Move the selection cursor down through the suggestion list
- Tab: Insert the currently highlighted suggestion directly into your command line buffer without executing it
- Enter: Execute the currently highlighted command immediately or submit the text typed in your prompt
- Esc: Temporarily dismiss and hide the overlay suggestion menu for the current line
- Shift+Tab: Permanently disable overlay suggestions until toggled back on
### Mode switching
Iris operates in two primary autocomplete modes: specification suggestions and history navigation
You can toggle between these modes instantly at any time by pressing `Ctrl+R`
- Specification mode (`spec`): Suggests available subcommands, flags, and arguments based on built-in tool specifications (such as git, npm, docker, or go)
- History mode (`history`): Suggests previous commands from your shell history that match your typed prefix using fuzzy matching
When navigating with arrow keys and pressing `Ctrl+R`, Iris resets the menu selection and immediately loads suggestions for your typed query under the newly active mode
### Instant alias expansion
Iris supports POSIX and shell aliases defined in your configuration
When you type an alias keyword and press the `Space` key, Iris immediately expands the alias into its full command inside your command line buffer
### Ghost text autosuggestions
When ghost text is enabled, Iris displays inline completion suggestions ahead of your cursor in a muted style
- Right Arrow (`→`): Accept the inline ghost text suggestion and append it to your current command line buffer
## Configuration guide
Iris uses a clean TOML configuration file located at `~/.config/iris/config.toml` to customize UI presentation, suggestion behavior, and core engine settings
### Default configuration structure
Below is a complete sample configuration template with all available parameters and comments:
```toml
# ~/.config/iris/config.toml
# iris configuration file
[core]
# schema version
# do not edit this field manually
version = 1
# override shell: "bash", "zsh", "fish", keep empty for auto detection
shell = ""
# startup mode: "last", "spec", "history"
# "last" = remember last mode used
mode = "last"
# enable debug logging
debug = false
[ui]
# enable inline ghost text
ghost-text = true
# maximum suggestions to display
max-suggestions = 100
# maximum height of the overlay
max-height = 15
[git]
# hide current branch in checkout/switch list
filter-active-branch = true
# merge remote and local branches with same name
deduplicate-branches = true
[updater]
# check for updates on startup
check-on-startup = true
# update channel: "stable", "nightly"
channel = "nightly"
# interval between update checks, e.g. "24h", "6h", "30m"
check-interval = "24h"
```
### Configuration sections
- `[core]`: Defines core engine settings including schema version, forced target shell (`bash`, `zsh`, `fish`), initial startup mode (`last`, `spec`, `history`), and diagnostic debug logging
- `[ui]`: Controls visual layout such as inline ghost text autocompletion, total suggestions rendered, and maximum overlay box height
- `[git]`: Specialized Git autocompletion behavior such as filtering out the currently active branch when switching and deduplicating local and remote branch names
- `[updater]`: Configures automated background updates, checking frequency (`check-interval`), and release track (`channel`)
### CLI configuration commands
Iris provides built-in commands to inspect and modify settings directly from your shell:
```bash
iris config init
iris config view
iris config edit
iris config reset
```
## Troubleshooting guide
If you encounter unexpected behavior while running Iris, use the diagnostic procedures outlined below
### Debug mode and logging
To inspect overlay positioning or command interception bugs in real time, launch Iris in debug mode:
```bash
iris -d
```
Runtime activities are written directly to the log file located at `~/.cache/iris/iris.log`. You can follow real-time events by running:
```bash
tail -f ~/.cache/iris/iris.log
```
> [!Caution]
> ### Common issues and solutions
> - Overlay Position Misaligned: Multi-line shell prompts (such as Starship) emitting ANSI codes can cause offset issues. Iris automatically parses carriage returns (`\r`) and horizontal escape codes (`\033[nC`) to anchor visual columns accurately
> - Menu Disappears When Toggling Mode: When pressing `Ctrl+R` after arrow navigation, Iris restores the original search query automatically so suggestions reload cleanly
> - Inspecting Crash Logs: If the session terminates unexpectedly, inspect captured stack traces by running `iris crash-log`
+111
View File
@@ -0,0 +1,111 @@
# Development guide
This document outlines the architectural principles, development workflow, and mandatory coding conventions for contributors working on the Iris codebase
## Architecture overview
Iris functions as a transparent pseudoterminal (PTY) bridge sitting between the user terminal emulator and the underlying interactive shell (`zsh`, `bash`, or `fish`)
- PTY Bridge (`root/wrapper.go`): Intercepts keystrokes in raw mode, tracks typed queries, manages shell input/output buffers, and handles escape sequences
- Overlay Rendering (`integration/overlay.go`): Computes visual character widths (`lipgloss.Width`), handles cursor column positioning, and draws floating menu boxes directly on the terminal grid
- Suggestion Engine (`root/suggestions.go`): Collects, deduplicates, and sorts command completions from static specifications and fuzzy history search
## Development workflow
### Setting up environment
Clone the repository and verify that all dependencies are synced:
```bash
git clone https://github.com/versenilvis/iris.git
cd iris
go mod tidy
```
### Building and reloading
To rapidly compile and reload your local development binary, ensure `just` is installed and run:
```bash
just reload
```
### Running tests
Run the full automated test suite without cache to verify system integrity before submitting code:
```bash
go test -v -count=1 ./...
```
OR
```bash
just test
```
OR using my own test analyzer script
```bash
just ana
```
### Running linters
Ensure zero linting errors across the codebase:
```bash
golangci-lint run ./...
go vet ./...
```
OR
```bash
just lint
```
### Some available `just` commands
We use `just` as our primary command runner. Below are common shortcuts available during development:
- `just build`: Compile standard local binary
- `just optimized-build`: Compile stripped, optimized binary
- `just reload`: Compile binary and hot-reload any currently running Iris session
- `just run`: Execute local `./iris` binary
- `just debug`: Launch `./iris -d` in debug logging mode
- `just test`: Execute full Go test suite
- `just ana`: Run custom project test analyzer script
- `just lint`: Execute static analysis and linter checks
- `just build-release <version>`: Build versioned release binary (e.g. `just build-release v1.2.0`)
## Mandatory engineering rules
Contributors must strictly adhere to the following core UI/UX and architectural principles:
### Absolute positioning for overlay rendering
- Never rely on relative cursor movements (`\033[nA` or `\033[nD`) across multi-line inputs to draw menus, as wrapping causes severe visual jitter
- Always compute absolute target columns (`targetCol = PromptLen + typedLen`) and use carriage return (`\r`) followed by horizontal positioning (`\033[targetColC`) to anchor the overlay box
### UI rules
- Stationary navigation vs dynamic typing: When navigating up or down through the menu (`↑` or `↓`), the overlay box position must remain fixed in place. When typing characters, the menu must shift dynamically along with the cursor column
- Menu hiding: When clearing the input line completely or when typing up to a completed token where no further completion exists, the overlay menu must automatically hide
- Context preservation: When moving left or right with arrow keys (`←` or `→`) or deleting characters with backspace, the engine must preserve context and re-evaluate the exact substring position to generate accurate suggestions
- Empty buffer arrow suppression: When the command line buffer is entirely empty, pressing left or right arrow keys (`←` or `→`) must not open the menu or trigger suggestions
- Temporary vs permanent dismissal: Pressing `Esc` hides the overlay menu temporarily for the current command line, whereas pressing `Shift+Tab` disables overlay suggestions permanently until toggled back on
- Non-blocking navigation and context awareness: When moving the cursor back to the start of a typed command line, cursor movement must never be blocked or frozen, and the overlay menu must dynamically preserve context relative to the cursor position
### Responsive PTY handling and non-Blocking UI
- Do not block raw PTY keystroke interception loops with long operations or arbitrary debounce timers that freeze user typing
- When handling navigation keys (up/down arrow) or mode toggles (`Ctrl+R`), update internal state synchronously and render UI feedback immediately
### Mode switching integrity
- When intercepting mode toggle keys (`Ctrl+R`), always reset navigation flags (`userNavigated = false`) and restore the original typed query buffer
- This ensures that switching from specification suggestions to history navigation reloads clean completion lists starting from index 0
### Concurrency safety
- The PTY output read loop and keystroke interception loop run asynchronously in separate goroutines
- Always use explicit synchronization (`sync.Mutex` or `sync.RWMutex`) when reading or modifying shared state variables such as `naiveBuffer`, `activeMode`, or `overlay.Items`
-28
View File
@@ -1,28 +0,0 @@
# Dynamic File Suggestion Generator (`commands/core/filegen.go`)
The `FileGenerator` is a dynamic suggestion engine that bridges the gap between static command specs and your live filesystem.
## How it works
The generator is assigned to commands or options that expect file paths (e.g., `git add`, `cat`, `go run`).
### Path Resolution
It handles both local and nested paths:
- `cat m` -> Scans `./` for entries starting with `m`.
- `cat src/` -> Scans `src/` for all entries.
- `cat src/main` -> Scans `src/` for entries starting with `main`.
### Intelligence Features
1. **Extension Filtering**: You can restrict the generator to specific files.
- `FileGenerator(".go")` -> Only shows `.go` files (used in `go build`).
2. **Directory Suffixing**: When a directory is suggested, Iris appends a `/` to the command string. This allows you to immediately continue typing to dive into the next level of the folder tree.
3. **Descriptions**: It automatically converts common extensions into human-readable labels (e.g., `.mp4` -> `video`, `.zip` -> `archive`).
4. **Directory-Only Mode**: Commands like `cd` use a special filter to hide all files and only show folders.
## Code Example
```go
// Registration for 'go run'
Generator: core.FileGenerator(".go")
```
When typing `go run `, Iris will scan the current directory, filter for `.go` extensions, and ignore images, binaries, or other unrelated files.
-25
View File
@@ -1,25 +0,0 @@
# Shell History Integration (`integration/history.go`)
The `history` module provides the Ctrl+R fuzzy search functionality by reading the user's persistent shell command history.
## Features
- **Zsh Extended Support**: Specifically parses the `: <timestamp>;<command>` format common in Zsh.
- **Lazy Loading**: Doesn't read the disk until the user actually requests history. This keeps startup time instantaneous.
- **Fuzzy Search**: Integrated with the `fuzzy` search engine.
- **Deduplication**: Automatically hides duplicate entries, showing only the most unique command variants.
## Data Flow
1. User presses `Ctrl+R`.
2. `root` sets `mode = "history"`.
3. `SearchHistory("")` is called.
4. If `cache` is empty:
- Reads `~/.zsh_history`.
- Strips metadata using `;` delimiter.
- Populates a slice of commands.
5. Search matches are sorted by the `fuzzy` engine.
6. Suggestions are returned to the `overlay` for rendering.
## Configuration
It currently looks for `.zsh_history` in the user's home directory.
-31
View File
@@ -1,31 +0,0 @@
# Overlay Rendering UI (`integration/overlay.go`)
The `overlay` package handles the visual representation of suggestions. It is designed to be "non-destructive," meaning it draws over the shell without corrupting the prompt or the scrollback buffer.
## Design Philosophy
- **ANSI ESC Everywhere**: It uses CSI (Command Sequence Introducer) codes to manipulate the terminal.
- **Save/Restore**: It uses `\0337` (DECSC) and `\0338` (DECRC) to jump back to the prompt after drawing the menu.
- **Fixed Width**: The box is exactly 72 characters wide (`boxWidth`) to ensure a consistent, premium feel.
## Technical Details
### Terminal Scrolling Protection
When rendering near the bottom of the screen, simply printing lines would cause the terminal to scroll and bury the prompt. Iris solves this by:
1. Moving to the prompt.
2. Printing N empty newlines.
3. Moving back up N lines.
4. Saving the cursor *again* at this new, stabilized location.
### Styling with Lipgloss
While Iris handles the positioning via raw ANSI codes, it uses **Lipgloss** for the "interior design":
- **Colors**: Dracula-inspired palette (`#BD93F9`, `#6272A4`).
- **Icons**: Fixed-width columns for badges.
- **Selection**: Highlights the active item with a background color (`#44475A`).
## Example Logic
To draw line 1 of the menu:
1. `\0338` (Jump to prompt anchor).
2. `\033[2B` (Move 2 lines down).
3. `\033[K` (Clear the entire line).
4. Print `│ [Icon] Command name... │`.
-40
View File
@@ -1,40 +0,0 @@
# IRIS: Central Integration & Event Loop (`root/`)
The `root` package is the entry point and the orchestration layer of IRIS. It handles the low-level terminal manipulation and the main interaction loop.
## How it works
1. **PTY Wrapper**: When you run `iris`, it starts a Pseudo-Terminal (PTY) and launches `bash` inside it.
2. **IO Interception**: It creates two "pumps":
- **Output Pump**: Forwards everything from Bash to your screen using `TermWrite` (synchronized to prevent UI glitches).
- **Input Pump**: Listens to your keyboard. If it detects you are typing a command, it records it in a `naiveBuffer` and triggers the suggestion engine.
3. **State Management**: It tracks whether you are in `spec` mode (command suggestions) or `history` mode (Ctrl+R).
## Key Components
### `root.go`
Contains the `runWrapper()` function which:
- Sets the terminal to **Raw Mode** so Iris can capture keys like `Tab`, `Esc`, or `Ctrl+C` before the shell does.
- Manages the `naiveBuffer`: a string that tracks exactly what you see on your prompt.
- Handles **Selection Logic**: When you press `Tab`, it modifies the Bash line using the `Ctrl+U` (clear line) + `selected command` sequence.
### `term_sync.go`
Provides `TermWrite`, a thread-safe wrapper around `os.Stdout`. It uses a `sync.Mutex` to ensure that if Bash and the Iris Overlay try to write at the exact same millisecond, the output doesn't get garbled.
## Example Flow
1. User types `g`.
2. `root` captures `g`, appends to `naiveBuffer`.
3. `root` calls `renderOverlay()`.
4. `renderOverlay` calls `Lookup("g")`.
5. `overlay` renders the result `git`.
6. User presses `Tab`.
7. `root` sends `Ctrl+U` to Bash, then sends `git ` (the completion).
## Hot-Reload
IRIS features an **Atomic Hot-Reload** mechanism designed for rapid development:
- **Signal Listener**: The root process listens for `SIGUSR1`.
- **Identity Exposure**: It exports `IRIS_PID` to the environment so child processes knows where to send the signal.
- **In-place Replacement**: Upon receiving the signal, Iris uses `syscall.Exec` to replace its current process image with the newly built binary.
- **Handoff Notification**: It uses `IRIS_RELOADED` to notify the new instance to announce its successful load.
-39
View File
@@ -1,39 +0,0 @@
# Command Specification & Navigation (`commands/core/spec.go`)
The `spec` module is the "language parser" of IRIS. it understands the relationship between commands, subcommands, and flags.
## Data Structures
- **`Spec`**: The top-level definition (e.g., for `git`).
- **`Subcommand`**: Recursively defined children (e.g., `commit` under `git`).
- **`Generator`**: A function that provides dynamic content (like files or docker IDs).
## The `Lookup` Algorithm
This is the most critical function in IRIS. It follows these steps:
1. **Tokenization**: Splits `"git commit -m"` into `["git", "commit", "-m"]`.
- *Empty tokens* (from a trailing space) indicate the user is ready for the next level of suggestions.
2. **Tree Walking**: It starts at the root (`git`) and tries to match each following token against the current node's subcommands.
3. **Context Identification**: Once it can't walk any further (e.g., a partial word or an option), it defines:
- `prefix`: The path already traveled.
- `partial`: The word currently being typed.
4. **Result Collection**: It gathers all valid subcommands and options that match the `partial` prefix.
## Example
Input: `git com`
1. Tokens: `["git", "com"]`
2. Walk: Root is `git`.
3. Next token `com` doesn't exactly match `commit`.
4. Stop walking. `partial` = `com`.
5. Suggestions: Look for subcommands of `git` starting with `com`.
6. Return: `git commit`.
## Shell Aliases & Priority
IRIS deeply integrates with your shell environment to provide a personalized experience:
- **Dynamic Alias Parsing**: Scans `.bashrc`, `.zshrc`, and other configuration files for aliases.
- **Highest Priority**: Shell Aliases are given top priority in the suggestion engine, appearing above manual specs and system commands.
- **Token Injection**: If a root command is recognized as an alias (e.g., `gr` for `go run`), IRIS injects the expanded tokens into the lookup engine to provide accurate subcommand suggestions.
- **Display**: Suggestions for aliases show the expanded command (e.g., `tmux a -t`) while noting the alias name in the description (e.g., `alias: ta`).
-97
View File
@@ -1,97 +0,0 @@
# Versioning and updates
Iris has a built-in update notification system designed to be non-intrusive and zero-latency
The update system is designed to keep Iris up to date while staying out of the way. It performs an asynchronous network check when the shell starts and notifies you exactly once per version after you run a command. This prevents redundant notifications and ensures that you only see an update message when a new release is actually available. The system also includes dedicated debugging tools to verify the notification logic without requiring real releases
## How it works
1. **Background check**: every time you open a new terminal, Iris launches a background goroutine to check for updates
- checks the network at most once every 6 hours to avoid GitHub API rate limiting
- has a 5 second timeout so it never hangs on a slow or missing network connection
- if there is no network, it fails silently with zero impact on startup
2. **State persistence**: state is stored in `~/.iris/update_state.json` with two fields:
- `last_check` - unix timestamp of the last network check
- `seen_version` - the latest version the user was already notified about
3. **Smart notification**:
- the notice only appears after you run your first command (triggered by the `IRIS_CMD_STOP` IPC signal from the shell hook)
- appears only once per session, never again even if you keep the terminal open
- if you have already been notified about a specific version, it will not show again until a newer GitHub release tag is detected
- when `iris update` is run successfully, the `seen_version` flag is cleared
## Build-time versioning
Iris uses Go `ldflags` to inject the version string at build time:
```bash
go build -ldflags="-X github.com/versenilvis/iris/root.Version=v1.2.0" -o iris main.go
```
If not provided, the version defaults to dev. The dev version will never trigger an update notification
## Commands
- `iris version` - print the current version of the running binary
- `iris update` - manually check for and apply the latest release
## Debugging and testing
There are two separate things to test: the update command itself, and the in-session notification banner
### Test 1: update command
Tests version fetching, comparison and the output message. No full Iris session needed
```bash
just build-release v0.0.1
just debug-update v1.99.0
```
Expected output
```
--- testing iris update command ---
checking for updates (current: v0.0.1)...
[IRIS] updating v0.0.1 -> v1.99.0
running: curl -sS https://raw.githubusercontent.com/versenilvis/iris/main/scripts/install.sh | sh
[IRIS] restart your terminal to use the new version
```
### Test 2: in-session notification banner
Tests the yellow notice that appears after you run your first command inside a live Iris session. Requires `iris.zsh` to be active in the inner shell so `IRIS_CMD_STOP` fires through the IPC pipe
```bash
just build-release v0.0.1
just debug-notify v1.99.0
```
Inside the new session, run any command. Expected output after the command
```
[IRIS] new version v0.0.1 -> v1.99.0 available, run iris update to upgrade
```
### Environment variables
| Variable | Purpose |
| -------------------------- | ----------------------------------------------------------------------------------- |
| `IRIS_UPDATE_URL` | override the GitHub API endpoint with a custom URL (used by `debug-update`) |
| `IRIS_MOCK_LATEST_VERSION` | skip network entirely, resolve to this version immediately (used by `debug-notify`) |
### State reset
To force a fresh network check on next launch, delete the state file:
```bash
rm ~/.iris/update_state.json
```
## Implementation details
| File | Purpose |
| ----------------- | ---------------------------------------------------------------------------------------- |
| `root/version.go` | holds the `Version` constant, defaults to `dev` |
| `root/update.go` | all update logic: state persistence, network fetch, version compare, commands |
| `root/wrapper.go` | wires the background check into the IPC loop, prints the notice on first `IRIS_CMD_STOP` |