Metadata-Version: 2.4
Name: cd-browser
Version: 0.4.0
Summary: A fast keyboard-driven directory navigator for the terminal.
Author: Saky
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Utilities
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: black>=24.0; extra == "dev"
Requires-Dist: ruff>=0.3.0; extra == "dev"
Requires-Dist: mypy>=1.8.0; extra == "dev"
Requires-Dist: pre-commit>=3.7.0; extra == "dev"
Provides-Extra: release
Requires-Dist: build>=1.2; extra == "release"
Requires-Dist: twine>=5.0; extra == "release"
Dynamic: license-file

# cd-browser

**Stop typing paths. Browse them.**

`cd-browser` is a fast keyboard-driven directory navigator for the terminal.
It lets you explore directory trees visually and jump to any folder instantly.

![cd-browser demo](https://gitea.sakydogalo.es/saky/cd-browser/raw/branch/main/docs/demo.gif)

Repository (full demo + docs): https://gitea.sakydogalo.es/saky/cd-browser

## Why cd-browser?

Working in the terminal often means:

- typing long directory paths
- navigating deep folder trees
- repeating `cd ..` multiple times

`cd-browser` provides an **interactive terminal UI** that allows you to browse directories with the keyboard and return the selected path directly to your shell.

## Features

- ⌨️ Fully keyboard-driven workflow (`↑` / `↓` / `←` / `→`)
- 🌲 Expand and collapse directories (`→` to expand/enter, `←` to collapse/back)
- 📜 Persistent history between sessions (`h` history mode, `b` back, `f` forward)
- 🔎 Incremental filter mode (`/`, type to filter, `Backspace`, `Esc`), including accented and other non-ASCII characters
- 🧭 History filter mode (`/` inside history) with most-recent-first ordering
- 📄 Toggle file visibility (`a`) to switch between directories-only and mixed view
- ⚡ Fast jumps in large lists (`PgUp`/`PgDn`, `Home`/`End`, `g`/`G` in normal mode)
- 🚀 Contextual `open with` menu (`o`) with app detection based on your environment
- 🤖 Coding agent integration (Claude Code, Codex): start a new session or resume a stored one for the selected folder
- 🌳 `gitk` for folders inside a git repository
- 🔁 Blocking terminal editors restore the UI state when they exit (`nvim`, `nano`, `less`, `bat`)
- 🧩 Configurable app menu via `config.toml`, including your own custom commands
- 🛠 Development snapshot in header + detailed info panel (`i`)
- 👀 Toggle hidden entries with `.`
- 🖥 Native terminal interface
- 🔁 Works with Bash, Zsh and Fish
- ⚡ Returns the selected path to the shell (`Enter` to confirm, `Esc` to cancel)

## Controls

Normal mode:

- `↑` / `↓`: Move selection
- `→`: Expand directory, or enter when already expanded
- `←`: Collapse directory, or go to parent
- `Enter`: Confirm selected path and exit
- `Esc`: Cancel and return the original path
- `h`: Toggle history mode
- `b` / `f`: Back / forward in navigation history
- `.`: Toggle hidden entries
- `a`: Toggle file visibility
- `/`: Enter filter mode
- `o`: Open selected entry with an app (on `..`, opens the current directory)
- `i`: Toggle development info panel
- `PgUp` / `PgDn`: Page jump
- `Home` / `End`: Jump to first/last entry
- `g` / `G`: Jump to first/last entry

Filter mode:

- Type text: Filter visible entries in real time (case-insensitive)
- `↑` / `↓`: Move inside filtered results
- `Enter`: Apply filter and perform contextual action:
  - Directory: navigate into it without exiting `cd_`
  - File: open app selection menu
- `Esc`: Exit filter mode and clear query
- `Backspace`: Remove last filter character

History mode:

- `↑` / `↓`: Move through history entries (most recent at top)
- `Enter`: Jump to selected history path
- `Esc` or `h`: Exit history mode
- `PgUp` / `PgDn`, `Home` / `End`: Fast history navigation
- `/`: Enter history filter mode

History filter mode:

- Type text: Filter history entries in real time (case-insensitive)
- `↑` / `↓`: Move inside filtered history results
- `Enter`: Jump to selected history path
- `Esc`: Exit history filter mode and clear query
- `Backspace`: Remove last filter character

Open with menu (`o`):

- `↑` / `↓`: Move between app options
- `Enter`: Launch selected app
- `Esc`: Cancel

The menu is built every time you press `o`. An app is only listed when:

1. it supports the selected entry type (file or directory),
2. it does not need a desktop session, or one is available (not over SSH; on Linux `DISPLAY` or `WAYLAND_DISPLAY` must be set),
3. its executable is found in your `PATH`.

Built-in apps:

| id | Files | Directories | Mode |
|----|:-----:|:-----------:|------|
| `code` | ✅ | ✅ | background, needs GUI |
| `open` (`open` / `xdg-open`) | ✅ | ✅ | background, needs GUI |
| `antigravity` | ✅ | ✅ | background, needs GUI |
| `claude` (Claude Code) | — | ✅ | blocking (terminal), session picker |
| `codex` (Codex CLI) | — | ✅ | blocking (terminal), session picker |
| `opencode` | — | ✅ | blocking (terminal) |
| `gitk` | — | ✅ | background, needs GUI, only inside a git repository |
| `nvim` | ✅ | ✅ | blocking (terminal) |
| `nano`, `less`, `bat` | ✅ | — | blocking (terminal) |

Blocking apps take over the terminal; `cd-browser` restores its screen when they exit and reports a non-zero exit code or a killing signal.
Background apps are detached from the terminal session.

### Coding agent sessions

Choosing **Claude Code** or **Codex** on a directory opens a second menu:

- `New session` — starts the agent inside the directory
- one entry per stored session of that directory, newest first (`date  title`) — resumes it inside the directory

If the directory has no sessions, a new session starts directly. Each menu shows the 30 most recent sessions.

| | Claude Code | Codex |
|---|---|---|
| Sessions read from | `~/.claude/projects/` (`$CLAUDE_CONFIG_DIR`) | `~/.codex/sessions/` (`$CODEX_HOME`) |
| Title | your session name (`--name` / `/rename`), else the generated title or last prompt | the thread name, else the first real prompt |
| Not listed | non-interactive runs (`claude -p`, SDK) | non-interactive sources (`codex exec`, subagents) and archived sessions |
| Resume command | `claude --resume <id>` | `codex resume <id>` |

## Opener Configuration

`cd-browser` reads opener settings from:

- macOS/Linux: `~/.config/cd-browser/config.toml`
- Windows: `%APPDATA%/cd-browser/config.toml`

If the file does not exist, `cd-browser` creates it automatically with defaults.

Example:

```toml
[open_with]
files = ["code", "open", "antigravity", "nvim", "nano", "less", "bat"]
directories = ["code", "open", "claude", "codex", "opencode", "antigravity", "gitk", "nvim"]
```

You can reorder or remove entries to customize app priority.
Unknown ids are ignored; if no valid id remains, the defaults are used.

### Custom openers

Define your own commands under `[openers.<id>]` and reference the id in `open_with`:

```toml
[open_with]
files = ["vim", "nvim", "code"]
directories = ["code", "yazi"]

[openers.vim]
command = "vim {path}"   # {path} is replaced by the quoted path; appended if missing
label = "Vim"            # optional, defaults to the id
mode = "blocking"        # "background" (default) or "blocking"
files = true             # optional, default true
directories = true       # optional, default true
gui = false              # optional, default false: set true if it needs a desktop session

[openers.yazi]
command = "yazi"
mode = "blocking"
files = false
```

A custom opener with the same id as a built-in one replaces it.
Invalid entries (missing `command`, unknown `mode`, non-boolean flags) are ignored.
The configuration is read once per session: restart `cd_` after editing it.

## Quick Demo

Run:

```bash
cd_
```

Browse directories using the arrow keys and press **Enter** to jump directly to the selected folder.

## Documentation

See the documentation index:

```
docs/index.md
```

## Installation

Requires **Python 3.11+**.

Install the project in user mode:

```bash
pip install cd-browser
```

**Important**: After installation, run this to set up the `cd_` command:

```bash
cd_browser_post_install
```

This interactive script will guide you through enabling `cd_` in your shell.

## Shell Integration For `cd_`

Because a Python subprocess cannot directly change the parent shell directory, use a shell wrapper that captures the final path printed by `cd_browser`.

Bash or Zsh example:

```bash
cd_() {
  local target
  target="$(cd_browser)" || return

  if [ -n "$target" ] && [ -d "$target" ]; then
    cd "$target"
  fi
}
```

Fish example (`~/.config/fish/functions/cd_.fish`):

```fish
function cd_
    set -l target (cd_browser); or return
    if test -n "$target" -a -d "$target"
        cd $target
    end
end
```

After adding the function to your shell profile, reload it:

```bash
source ~/.bashrc
```

Or:

```bash
source ~/.zshrc
```

Then use:

```bash
cd_
```

- Inside `cd_browser`, press `.` to toggle hidden entries.

`cd_browser_post_install` can add the Bash/Zsh function for you; Fish users add the function above manually.

## Platform Compatibility

Practical conclusion:

- Best current support: **macOS and Linux**
- **Windows is partially supported**, but still needs real-world validation in Windows terminal environments before being considered fully supported

## Uninstall

If the project was installed with `pip`, remove it with:

```bash
pip uninstall cd-browser
```

**Important**: After uninstalling, remove the `cd_()` function from your shell profile (~/.bashrc or ~/.zshrc) to clean up completely.

## Developer Setup

Recommended setup:

```bash
make dev
```

Run the application in development mode:

```bash
python -m app.main
```

Useful development commands:

```bash
make fix
make quality
make run
```

The test suite never touches your real configuration or history: `tests/conftest.py` points `CD_BROWSER_CONFIG_FILE` and `CD_BROWSER_HISTORY_FILE` to temporary files.

### AI-assisted workflow

The project is developed with AI coding agents under a strict workflow (plan → review → build → validate → log).
The active agent is **Claude Code**; its rules live in `CLAUDE.md`, and every task is recorded in `docs/ai-worklog.md`, `docs/ai-prompts.md` and `docs/ai-execution-log.md`.

## Template Origin

This project was created from the Python AI Dev Template.

The original template documentation has been preserved in `README_TEMPLATE.md` so the project-specific README can focus on `cd-browser` usage and development.

For the original template setup, conventions, and generic workflow notes, see `README_TEMPLATE.md`.
