plk 0.1.0

Command sequence merger CLI — detects repeated command patterns and lets you save/run them as shortcuts
# plk

Command sequence merger CLI — detects repeated command patterns from your shell history and lets you save/run them as shortcuts.

## The Problem

You keep typing the same multi-step command sequences:

```sh
cd ~/project/frontend
pnpm run dev
```

```sh
git add .
git commit -m "wip"
git push
```

Every time. Manually. `plk` detects these patterns automatically and lets you run them with a single command.

## Installation

### From source

```sh
git clone https://github.com/BeepBoopBit/plk.git
cd plk
cargo build --release
cp target/release/plk ~/.local/bin/
```

### From crates.io

```sh
cargo install plk
```

## Quick Start

```sh
# 1. Install the shell hook
plk init --shell zsh   # or bash

# 2. Reload your shell
source ~/.zshrc

# 3. Use your shell normally — plk records commands in the background

# 4. After repeating patterns, check what plk detected
plk ls auto

# 5. Run a detected sequence
plk auto <id>

# 6. Save it as a named shortcut
plk save <id> --name dev

# 7. Run it anytime
plk run dev
```

See [QUICKSTART.md](QUICKSTART.md) for a detailed walkthrough.

## Commands

| Command | Description |
|---|---|
| `plk init [--shell zsh\|bash]` | Install shell hook, completions, and optionally enable swapx |
| `plk auto [id]` | List or run auto-detected sequences |
| `plk run <name>` | Run a saved shortcut |
| `plk ls auto` | List auto-detected sequences |
| `plk ls saved` | List saved shortcuts |
| `plk save <id> --name <n>` | Save an auto-detected sequence |
| `plk add --name <name> "<cmd>"` | Manually add a shortcut |
| `plk rm <name>` | Remove a saved shortcut |
| `plk dismiss <id>` | Dismiss a suggestion permanently |
| `plk gc` | Clean up old history entries |
| `plk reset` | Wipe all plk data and start fresh |

## How It Works

1. A shell hook (installed via `plk init`) records every command you run with its timestamp and working directory
2. `plk` segments your history into sessions (split by 5s gaps)
3. Repeated sequences of 2+ commands are detected and ranked by frequency
4. When a sequence is repeated enough times (default 10), plk suggests saving it:
   ```
   plk: "cd ~/project/frontend && pnpm run dev" repeated 10x. Save it? Run: plk save a1b2c3 --name <name>
        To dismiss: plk dismiss a1b2c3
   ```
5. You can browse, run, or save these as named shortcuts

## Configuration

Optional config at `~/.config/plk/config.toml`:

```toml
# Time gap (ms) that splits history into sessions (default: 5000)
session_gap_ms = 5000

# Minimum repetitions to detect a sequence (default: 2)
min_frequency = 2

# Only consider history from the last N days (default: 30)
history_days = 30

# Maximum history entries to keep (default: 10000)
max_history_entries = 10000

# Suggest saving a sequence after this many repetitions (default: 10, 0 to disable)
suggestion_threshold = 10

# Enable swapx integration — plk will write rules to ~/.config/swapx/rules.plk.yaml (default: false)
swapx_integration = false
```

## Data Storage

| What | Default Path |
|---|---|
| History log | `~/.local/share/plk/history.log` |
| Saved shortcuts | `~/.local/share/plk/shortcuts.json` |
| Dismissed suggestions | `~/.local/share/plk/dismissed.json` |
| Config | `~/.config/plk/config.toml` |

Override with `PLK_DATA_DIR` and `PLK_CONFIG_DIR` environment variables.

## swapx Integration

If you use [swapx](https://github.com/beepboopbit/swapx), plk can automatically register rules so that typing the first command of a shortcut triggers a swapx prompt.

### Setup

During `plk init`, if swapx is detected on your system, plk will ask:

```
swapx detected. Enable swapx integration? (y/N)
```

You can also enable it manually in `~/.config/plk/config.toml`:

```toml
swapx_integration = true
```

### How it works

When you save a shortcut, plk writes a rule to `~/.config/swapx/rules.plk.yaml` (a separate file from your manual swapx rules). The rule uses the raw command you typed as the match — so if you use zoxide and type `cd project`, the swapx match is `cd project`, not the resolved absolute path.

plk will also ask whether the rule should be **global** or **directory-scoped**:

```
Swapx rule scope — directory (/home/user/projects) or global? (d/G)
```

- **Global** (default) — the rule triggers anywhere
- **Directory** — the rule only triggers when you're in that specific directory (uses swapx's `dir` field)

### Example

```sh
plk add --name dev "cd prompt && pnpm run dev"
# Swapx rule scope — directory (/home/user/projects) or global? (d/G) G
```

Now typing `cd prompt` triggers swapx:

```
? cd prompt
  > plk: dev (cd prompt && pnpm run dev)
    just cd prompt (default)
```

Removing a shortcut (`plk rm`) or resetting (`plk reset`) cleans up `rules.plk.yaml` automatically — your manual swapx rules in `rules.yaml` are never touched.

## Shell Support

- **zsh** — full support (hook + tab completions with descriptions)
- **bash** — full support (hook + tab completions)

### Tip: Use zoxide for Smarter `cd`

[zoxide](https://github.com/ajeetdsouza/zoxide) is a smarter `cd` that learns which directories you visit most. It pairs well with plk — when you type `cd project` instead of `cd /home/user/long/path/to/project`, plk records the short alias you actually typed, making detected sequences more readable and swapx rules more intuitive.

### Tip: Use fzf for Better Tab Completion

If you have [fzf](https://github.com/junegunn/fzf) installed, its tab completion integration gives you a much nicer experience — fuzzy filtering, a preview of each sequence, and arrow-key selection instead of cycling through options.

For **zsh**, add to your `.zshrc` (after `plk init`):

```zsh
# fzf must be set up first: https://github.com/junegunn/fzf#setting-up-shell-integration
source <(fzf --zsh)
```

For **bash**, add to your `.bashrc` (after `plk init`):

```bash
eval "$(fzf --bash)"
```

Then `plk auto <TAB>` will open an fzf picker with the sequence descriptions.

## License

[MIT](LICENSE)