Skip to content

hiradp/htools

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

80 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

htools

CI

🧰 A collection of small terminal tools that share one config file, one sqlite database, and one dashboard design language β€” a task tracker, a git-worktree manager, a tmux wrapper, and a few glances that come together in a tmux "control center".

what's inside

crate what it is
htask a little sqlite-backed task tracker (+ hprobe, a prod-alert investigator)
htree a git worktree wrapper
hmux a tmux wrapper (+ a live session-switcher dashboard)
hagent a dashboard of live Claude Code agents β€” who's working, idle, or blocked
hsys a system monitor β€” CPU/RAM/disk/net gauges + processes/ports, with kill
hclock a clock for a tmux pane β€” time, date, load/uptime/battery
hlib shared plumbing (settings, db, theme & co.) β€” glue, not a tool
skills agent skills for Claude Code, symlinked in by just install

the tools

Build and install everything with just install (see below). Every binary also takes a global --config-dir <dir> to point at a different config home, and --version / --help. Then:

htask β€” a task tracker

Bare htask opens the dashboard; the subcommands are the CLI over the same store.

htask add fix the flaky login test +bug repo:api  # words = title; +tag, key:value, and
                                                   # URLs / owner/repo#123 / #channel peel off
htask add review acme/api#421                       # source auto-detected from the issue ref
htask add --title "literal: title" -d "a description"
htask ls                                            # live tasks, one per line
htask ls --status todo --tag repo:api               # filter by --status / --tag / --source / -a archived
htask ls --json                                     # machine output (the inter-tool contract)
htask show 9f3ac1                                   # one task in full (--json too)
htask start 9f3ac1                                  # mark in-progress
htask done 9f3ac1                                   # mark done   (undo β†’ back to todo)
htask edit 9f3ac1 --add-tag prio:high --rm-tag bug  # field edits; bare `edit <id>` opens $EDITOR
htask archive 9f3ac1                                # the only removal β€” status is preserved

IDs are the last 6 hex of a task's uuid; any unambiguous suffix resolves (an ambiguous one lists the candidates rather than guessing).

htask start --repo β€” the orchestrator. Given one or more --repo, start does more than flip status: it marks the task in-progress, then for each repo creates a git worktree (via htree) and opens a tmux session (via hmux) to work in β€” a per-task workbench at <workbench_root>/<short-id>/<repo>, every worktree on branch hiradp/<slug>-<short-id>, in a session named htask-<short-id>-<slug>. Re-running resumes it: existing worktrees and the session are reused, so start doubles as "get me back into this task".

htask start 9f3ac1 --repo api --repo web                 # a worktree per repo + a tmux session, then drop in
htask start 9f3ac1 --repo api --base main --branch wip   # fork from main, name the branch/session yourself

Dashboard keys:

key does
j / k, ↓ / ↑ move selection
g / G first / last
enter detail popup
tab cycle the status filter
v live ↔ archived
s / d / u start Β· done Β· undo
S start in repos (multi-select picker β€” type to filter, space toggles, ^a all, enter starts)
o quick-add (words +tag key:value url)
a archive (with a y/n confirm)
b open the task's source in the browser
r refresh Β· ? help Β· q quit

Mouse: click selects, double-click opens the source (or the detail popup), the wheel scrolls.

hprobe β€” turn a prod alert into an investigation

A second binary that ships in the htask crate. hprobe <alert…> joins the words into a task titled by the alert and sourced prod, then opens an agent-only tmux session (just the coding agent β€” no editor/git windows) seeded with a prompt. It's idempotent per incident: re-running with the same alert resumes the live investigation instead of spawning a duplicate (a resolved alert that re-fires starts fresh).

hprobe checkout latency spike in us-east-1

The repo it runs in and the prompt template are [hprobe] settings ({args} in the template is replaced by the alert text).

htree β€” a git worktree wrapper

Per-task worktrees laid out <into>/<repo>, tracked in the shared db. It's the plumbing htask start drives, but it stands on its own.

htree add my-feature --into ~/wb/9f3ac1 --repo api          # worktree on branch my-feature at ~/wb/9f3ac1/api; prints the path
htree add my-feature --into ~/wb/9f3ac1 --repo api --reuse  # idempotent: reprint the path if it already exists
htree add my-feature --into ~/wb/9f3ac1 --repo owner/api --base main
htree ls                     # registered worktrees (--repo to filter, --json for machine output)
htree repos                  # repos you can add to: under repos_root + the registry (--json)
htree rm my-feature          # remove the worktree (--branch also deletes the branch, --force if dirty)
htree clean                  # sweep up: drop stale registrations + remove clean, fully-merged worktrees

--repo resolves a path, an owner/repo or bare name under [htree] repos_root, or the basename of a repo already in the registry; with none, the repo containing the current directory.

hmux β€” a tmux wrapper (+ session dashboard)

Bare hmux is a live session-switcher dashboard; the subcommands build sessions.

hmux                                              # dashboard: live sessions, color-coded by kind; enter switches
hmux open work ~/wb/9f3ac1/api ~/wb/9f3ac1/web    # create-or-attach: a window per worktree (editor beside git) + an agent window
hmux open probe ~/wb/x/api --agent-only           # build only the agent window (an incident probe)
hmux open work ~/wb/x/api --agent "claude --model opus"  # override the agent window's command
hmux ctrl                                         # the control center (see below)
hmux tools                                        # a session of plain shells, one per [hmux] tools dir

open is create-or-attach (an existing session is re-entered, never rebuilt β€” this is what makes htask start resumable). It attaches when stdout is a terminal, otherwise prints the session name (the contract orchestrators consume). Dashboard keys: j / k move, g / G top/bottom, enter switch, q quit.

hagent β€” a dashboard of live Claude Code agents

Shows every Claude Code agent across your tmux panes and what it's doing β€” blocked (needs you), working, or idle β€” with blocked sorted to the top so a "needs you" never hides. State is fed by Claude Code hooks that report into <data_dir>/agents/; install-hooks wires those up.

hagent                 # the dashboard; enter switches to the agent's pane, r refresh, q quit
hagent install-hooks   # merge hagent's hooks into your ~/.claude*/settings.json (additive; run by `just install`)
hagent install-hooks --dry-run   # show which config dirs would be written, change nothing

(hagent hook is the internal writer the hooks invoke on each event β€” not run by hand.)

hsys β€” a system monitor

CPU / RAM / disk / network gauges above a process-and-port list you can kill from. No subcommands; [hsys] refresh_secs sets the idle refresh cadence (default 2s).

Keys: j / k move, x kill, a toggle all ↔ mine (your terminal's processes, the default), l toggle listening-only ↔ all, r refresh, q quit.

hclock β€” a clock for a tmux pane

Time and date, with load average, uptime, and battery underneath (gathered best-effort β€” a field that's missing is simply dropped). No subcommands; [hclock] refresh_secs / status_refresh_secs tune the redraw and status cadences. q / Esc / Ctrl-C quit.

the control center

The tools stand alone, but hmux ctrl is where they come together: one create-or-attach tmux session whose single window is a 2Γ—3 grid of the suite's own glances β€”

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  htask     β”‚  hclock    β”‚  hmux      β”‚   top
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  hsys      β”‚  a shell   β”‚  hagent    β”‚   bottom
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β€” with the cursor landing in the bottom-middle shell to drive from. htask and hmux are fixed; the clock, the bottom-left (hsys), and the bottom-right (hagent) panes run commands you can swap in [hmux] config. Because it's create-or-attach, it's a stable home you drop back into rather than rebuild.

Its companion hmux tools opens a second session of plain shell windows, one per directory listed in [hmux] tools β€” the repos you like to keep a terminal in. Both pair well with a tmux key binding of your own (the author binds prefix + ! to hmux ctrl and prefix + @ to hmux tools).

building

A macOS/Linux suite that leans on tmux and git (and lsof behind hsys, uptime / pmset behind hclock); build it with a Rust toolchain.

Everything goes through just:

just            # list the recipes (this, but fresher)
just install    # binaries onto PATH, seed config, symlink agent skills, wire hagent hooks
just fix        # auto-fix: clippy suggestions, then fmt
just check      # fmt + clippy, read-only, warnings are errors
just test       # run the tests
just ci         # check + test β€” the whole gauntlet

If it's not in the justfile, you probably don't need it.

config

One file for the whole suite: ~/.config/htools/config.toml (under $XDG_CONFIG_HOME if set). just install seeds it from config/default.toml, never clobbering an existing one, and that same default is embedded into every binary as a floor β€” so a missing or sparse file still loads.

Top-level keys are suite-wide; each [tool] section is that tool's own. Values layer embedded defaults β†’ the file β†’ HTOOLS_* environment variables (__ separates nested keys, e.g. HTOOLS_HTREE__REPOS_ROOT=/srv/repos).

data_dir = "~/.local/share/htools"   # suite-wide: holds htools.db and agents/
refresh_secs = 1.0                    # suite-wide: dashboards' idle refresh, seconds (per-tool override)

[htree]
repos_root = "~/Code"                 # repos live at <repos_root>/<owner>/<repo>

[htask]
workbench_root = "~/.local/share/htools/workbench"   # start --repo lays out <root>/<short-id>/<repo>

[hmux]
editor = "nvim"                       # each worktree window: editor (run as `<editor> .`) beside git
git = "lazygit"
agent = "claude"                      # the agent window's command
clock = "hclock"                      # ctrl's top-middle pane
ports = "hsys"                        # ctrl's bottom-left pane
agents = "hagent"                     # ctrl's bottom-right pane
tools = []                            # `hmux tools` windows, one per existing dir (leading ~ expands)

[hprobe]
repo = "probe"                        # the repo an investigation runs in
prompt = "Can you investigate {args}" # the agent's seed prompt; {args} = the alert text

[hsys]
refresh_secs = 2.0                    # slower: a refresh walks procs and shells to lsof

[hclock]
refresh_secs = 0.25                   # redraw cadence β€” sub-second so the seconds tick smoothly
status_refresh_secs = 5.0             # load/uptime/battery re-read, far slower

license

MIT β€” see LICENSE.

About

🧰 A collection of tools.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors