@n-seiji/nuthatch 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +163 -0
- package/README.md +34 -15
- package/dist/cli.js +3382 -43739
- package/package.json +1 -5
package/README.ja.md
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
[English](README.md)
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="docs/assets/logo.png" alt="nuthatch — hop between git worktrees" width="560">
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center"><em>ナットハッチが木々を渡るように、git worktree 間を hop する。</em></p>
|
|
8
|
+
|
|
9
|
+
`nuthatch` は zero-setup な git worktree manager。単一コマンド **`hop`** が、
|
|
10
|
+
任意の branch の worktree へジャンプする — 存在しなければその場で作成する。
|
|
11
|
+
人間 (対話的 picker) と AI coding agent (非対話、`--json`) の両方に対応。
|
|
12
|
+
|
|
13
|
+
## なぜ
|
|
14
|
+
|
|
15
|
+
- **Zero setup** — 状態ファイルなし、init コマンドなし。
|
|
16
|
+
`git worktree list --porcelain` が唯一の正本。任意のリポジトリで即動く。
|
|
17
|
+
- **Convention over config** — worktree は常に
|
|
18
|
+
`<root の親>/_worktree/<repo>/<branch>` に置かれるため、一覧やパスの推測が
|
|
19
|
+
速く予測可能。
|
|
20
|
+
- **AI native** — 全コマンドが非対話で完結し、`--json` はどこでも使え、path
|
|
21
|
+
は stdout・ログは stderr に出て、エラーは次の一手を教えてくれる。
|
|
22
|
+
|
|
23
|
+
## 使い方
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
hop # worktree/branch を対話的に選んで cd
|
|
27
|
+
hop feat/foo # feat/foo の worktree へ cd — 未作成ならその場で作成
|
|
28
|
+
hop root # root clone へ cd
|
|
29
|
+
hop - # 直前の worktree へ戻る
|
|
30
|
+
|
|
31
|
+
hop ls [--json] # worktree 一覧 (dirty, ahead/behind, kind)
|
|
32
|
+
hop rm <branch> # worktree を削除 (branch は残す) — managed/external 問わず、dirty には --force が必要
|
|
33
|
+
hop clean # ゴミ worktree を自動判定して削除 (managed のみ)
|
|
34
|
+
hop root <branch> # root clone を一時的に切替 (動作確認用) —
|
|
35
|
+
# 対象 branch が他所で checkout 済みなら、clean かつ unlocked な holder を swap する
|
|
36
|
+
hop root - # root clone を元に戻す (root の branch のみ; swap で detach した holder はそのまま)
|
|
37
|
+
|
|
38
|
+
hop -- <branch> # 予約コマンドと被る branch 名をエスケープ
|
|
39
|
+
# (`hop` 自体と同名の branch (例: `hop -- hop`) にも必要)
|
|
40
|
+
hop --help # usage を表示 (-h / hop help でも同じ)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
同じ branch が複数の worktree で checkout されている場合、branch だけを指定する
|
|
44
|
+
`hop rm` は削除対象を推測せず拒否する。対話的 picker は選択した path を、lock 内の
|
|
45
|
+
最終安全確認まで保持する。
|
|
46
|
+
|
|
47
|
+
### 対話的 picker
|
|
48
|
+
|
|
49
|
+
picker は候補を section に分けて表示する — 既存の worktree (root が先頭) と
|
|
50
|
+
未作成の branch — ステータスマーカー・整列した列・短縮パス付きで:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
WORKTREES
|
|
54
|
+
❯ ● main root ~/ghq/.../nuthatch
|
|
55
|
+
○ feat/picker managed …/_worktree/feat__picker
|
|
56
|
+
● codex/fix-x ext …/.claude/worktrees/x
|
|
57
|
+
|
|
58
|
+
BRANCHES — Enter creates a worktree
|
|
59
|
+
+ feat/idea local
|
|
60
|
+
+ origin/hotfix remote
|
|
61
|
+
|
|
62
|
+
(●=dirty ○=clean +=not created)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
candidate が 0 件になった section は (header ごと) 丸ごと消える —
|
|
66
|
+
検索クエリで絞り込んだ結果 0 件になった場合も同様。
|
|
67
|
+
|
|
68
|
+
各 section 内の順序は insertion 順ではなく固定: WORKTREES は root が先頭、
|
|
69
|
+
次に managed、その次に external (各グループ内は branch 名昇順、detached
|
|
70
|
+
HEAD の worktree はグループ内最後); BRANCHES は remote より local が先
|
|
71
|
+
(各グループ内は branch 名昇順)。これは検索フィルタ中も保たれる —
|
|
72
|
+
絞り込んでも残った項目の並びは変わらない。BRANCHES の行は dim 表示になり、
|
|
73
|
+
○/●/+ マーカーに加えて「既に worktree」か「まだ未作成」かが一目でわかる。
|
|
74
|
+
|
|
75
|
+
picker は terminal の alternate screen buffer (fzf や vim と同じ仕組み) で
|
|
76
|
+
動くため、scrollback 履歴に残らない — 実行のたびに画面を上書きし、
|
|
77
|
+
どう終了しても (選択、Esc/Ctrl-C、割り込み) shell の画面をきれいに復元する。
|
|
78
|
+
|
|
79
|
+
### 対話的 picker のキー
|
|
80
|
+
|
|
81
|
+
action panel は候補一覧の隣に列として表示される (overlay ではない) ので、
|
|
82
|
+
action を選ぶ間も一覧が見え続ける。60 列未満の terminal では横に並べられ
|
|
83
|
+
ないため、一覧の下にスタックする形にフォールバックする。
|
|
84
|
+
|
|
85
|
+
| キー | 動作 |
|
|
86
|
+
|---|---|
|
|
87
|
+
| `Enter` | 選択中の候補へ cd |
|
|
88
|
+
| `Tab`, `→`, `Ctrl+L`, `Ctrl+F` | 選択中の候補の action panel を開く (ここで cd / 削除 / root 切替) |
|
|
89
|
+
| `Ctrl+X` | 選択中の worktree を削除 (`external` は先に y/N を確認) |
|
|
90
|
+
| `Ctrl+R` | root clone を選択中の branch へ切替 (`external` は先に y/N を確認) |
|
|
91
|
+
| `↑`/`↓`, `Ctrl+P`/`Ctrl+N`, `Ctrl+K`/`Ctrl+J` | 選択を移動 (矢印・emacs・vim キーがすべて併用可) |
|
|
92
|
+
| `Esc` | 静かにキャンセル — exit 0、stdout は空のまま (shell wrapper は cd しない) |
|
|
93
|
+
| `Ctrl+C` | 割り込みとしてキャンセル — exit 130、実際の SIGINT と同じ |
|
|
94
|
+
|
|
95
|
+
action panel 内: 同じ上下移動キー (左右は閉じる操作に予約されており、
|
|
96
|
+
移動としては使われない)、`Enter` でハイライト中の action を実行、
|
|
97
|
+
`c`/`d`/`r` で cd/delete/switch-root を直接実行、`Esc`、`Tab`、`←`、
|
|
98
|
+
`Ctrl+H` で一覧に戻る (`←`/`Ctrl+H` は開く操作の `→`/`Ctrl+L`/`Ctrl+F` と
|
|
99
|
+
対になっている; `Tab` はどちらの状態からでもトグルする — Ghostty のように
|
|
100
|
+
Cmd+K のようなキーの組み合わせを Tab に remap する terminal で便利)。
|
|
101
|
+
`delete` はすでに作成済みの worktree (`managed` / `external`) すべてに
|
|
102
|
+
表示される (`external` の削除は panel からでも Ctrl+X からでも必ず y/N
|
|
103
|
+
を確認する); `switch root here` は root worktree 自身には表示されず、
|
|
104
|
+
`external` worktree に対しては HEAD を detach する可能性があるため
|
|
105
|
+
同じく先に y/N を確認する。削除すると候補一覧が再読み込みされ、picker を
|
|
106
|
+
抜けずに削除を続けられる; cd と switch-root は終了して結果の path を
|
|
107
|
+
出力する (hop の stdout 契約どおり)。
|
|
108
|
+
|
|
109
|
+
Shell 統合 (自動 `cd`):
|
|
110
|
+
|
|
111
|
+
```sh
|
|
112
|
+
# ~/.zshrc
|
|
113
|
+
eval "$(hop init zsh)"
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Install
|
|
117
|
+
|
|
118
|
+
> まだリリースされていない — バージョンは publish も tag もされていない。
|
|
119
|
+
> 最初の `v*` tag が出た後は、以下の選択肢が記載どおりに動く。
|
|
120
|
+
|
|
121
|
+
推奨: GitHub Release のバイナリ (bun 製、mise なら
|
|
122
|
+
`mise use github:n-seiji/nuthatch`)。npm 版は Node で動くため git 呼び出しが遅い
|
|
123
|
+
(hop ls ~400ms vs ~60ms) — CI や頻繁な呼び出しにはバイナリを使う。
|
|
124
|
+
|
|
125
|
+
```sh
|
|
126
|
+
# ビルド済みバイナリ (macOS arm64/x64, Linux x64) — Node.js 不要、最速:
|
|
127
|
+
curl -fsSL https://raw.githubusercontent.com/n-seiji/nuthatch/main/install.sh | sh
|
|
128
|
+
mise use github:n-seiji/nuthatch # mise、GitHub Release のバイナリ経由
|
|
129
|
+
|
|
130
|
+
# npm (低速: Node 経由で git を呼ぶ — バイナリの hop ls ~60ms に対し ~400ms)
|
|
131
|
+
npm i -g @n-seiji/nuthatch # または: bunx @n-seiji/nuthatch
|
|
132
|
+
mise use -g npm:@n-seiji/nuthatch # mise、npm 経由
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
install script は `hop` を `~/.local/bin` に置き (`HOP_INSTALL_DIR` で
|
|
136
|
+
上書き可)、常に最新の GitHub Release を取得する; 特定バージョンに固定する
|
|
137
|
+
には `HOP_VERSION=vX.Y.Z` を使う。Linux arm64 はビルド済みバイナリが
|
|
138
|
+
まだないため、npm install を使う。
|
|
139
|
+
|
|
140
|
+
## Agent skill (Claude Code / Codex plugin)
|
|
141
|
+
|
|
142
|
+
このリポジトリは plugin marketplace も兼ねており、
|
|
143
|
+
[`using-hop`](skills/using-hop/SKILL.md) skill を配布する —
|
|
144
|
+
coding agent に `hop` を非対話・安全に扱う方法を教える skill。
|
|
145
|
+
|
|
146
|
+
```sh
|
|
147
|
+
# Claude Code
|
|
148
|
+
/plugin marketplace add n-seiji/nuthatch
|
|
149
|
+
/plugin install hop@nuthatch
|
|
150
|
+
|
|
151
|
+
# Codex
|
|
152
|
+
codex plugin marketplace add n-seiji/nuthatch
|
|
153
|
+
codex plugin install hop
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Docs
|
|
157
|
+
|
|
158
|
+
- [docs/design.md](docs/design.md) — 設計書 (全文)
|
|
159
|
+
- [AGENTS.md](AGENTS.md) — このリポジトリで作業する coding agent 向けガイド
|
|
160
|
+
|
|
161
|
+
## License
|
|
162
|
+
|
|
163
|
+
GPL-3.0 — [LICENSE](LICENSE) 参照。
|
package/README.md
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
[日本語](README.ja.md)
|
|
2
|
+
|
|
1
3
|
<p align="center">
|
|
2
4
|
<img src="docs/assets/logo.png" alt="nuthatch — hop between git worktrees" width="560">
|
|
3
5
|
</p>
|
|
@@ -29,15 +31,22 @@ hop root # cd into the root clone
|
|
|
29
31
|
hop - # cd back to the previous worktree
|
|
30
32
|
|
|
31
33
|
hop ls [--json] # list worktrees (dirty, ahead/behind, kind)
|
|
32
|
-
hop rm <branch> # remove a worktree (branch is kept)
|
|
33
|
-
hop clean # auto-detect and remove garbage worktrees
|
|
34
|
-
hop root <branch> # temporarily switch the root clone (for verification)
|
|
35
|
-
|
|
34
|
+
hop rm <branch> # remove a worktree (branch is kept) — managed or external, dirty needs --force
|
|
35
|
+
hop clean # auto-detect and remove garbage worktrees (managed only)
|
|
36
|
+
hop root <branch> # temporarily switch the root clone (for verification) —
|
|
37
|
+
# swaps out a clean, unlocked holder if the branch is checked out elsewhere
|
|
38
|
+
hop root - # switch the root clone back (only root's branch; a swapped-out holder stays detached)
|
|
36
39
|
|
|
37
40
|
hop -- <branch> # escape a branch name that collides with a reserved command
|
|
41
|
+
# (also required for a branch named the same as your `hop` binary/alias, e.g. `hop -- hop`)
|
|
38
42
|
hop --help # print usage (also -h / hop help)
|
|
39
43
|
```
|
|
40
44
|
|
|
45
|
+
If Git reports the same branch checked out in multiple worktrees, the
|
|
46
|
+
branch-only `hop rm` command refuses rather than guessing which path to
|
|
47
|
+
remove. The interactive picker keeps the selected path through the final
|
|
48
|
+
lock-protected safety check.
|
|
49
|
+
|
|
41
50
|
### Interactive picker
|
|
42
51
|
|
|
43
52
|
The picker groups candidates into sections — existing worktrees (root first)
|
|
@@ -50,11 +59,11 @@ shortened paths:
|
|
|
50
59
|
○ feat/picker managed …/_worktree/feat__picker
|
|
51
60
|
● codex/fix-x ext …/.claude/worktrees/x
|
|
52
61
|
|
|
53
|
-
BRANCHES — Enter
|
|
62
|
+
BRANCHES — Enter creates a worktree
|
|
54
63
|
+ feat/idea local
|
|
55
64
|
+ origin/hotfix remote
|
|
56
65
|
|
|
57
|
-
(●=dirty ○=clean
|
|
66
|
+
(●=dirty ○=clean +=not created)
|
|
58
67
|
```
|
|
59
68
|
|
|
60
69
|
A section (header included) disappears entirely when it has no candidates —
|
|
@@ -85,8 +94,8 @@ since the two can't fit side by side.
|
|
|
85
94
|
|---|---|
|
|
86
95
|
| `Enter` | cd into the selected candidate |
|
|
87
96
|
| `Tab`, `→`, `Ctrl+L`, `Ctrl+F` | Open the action panel for the selected candidate (cd / delete / switch root here) |
|
|
88
|
-
| `Ctrl+X` | Delete the selected worktree (asks y/N first) |
|
|
89
|
-
| `Ctrl+R` | Switch the root clone to the selected branch
|
|
97
|
+
| `Ctrl+X` | Delete the selected worktree (asks y/N first for an `external` worktree) |
|
|
98
|
+
| `Ctrl+R` | Switch the root clone to the selected branch (asks y/N first for an `external` worktree) |
|
|
90
99
|
| `↑`/`↓`, `Ctrl+P`/`Ctrl+N`, `Ctrl+K`/`Ctrl+J` | Move the selection (arrow, emacs, and vim keys all work side by side) |
|
|
91
100
|
| `Esc` | Cancel quietly — exit 0, stdout stays empty (the shell wrapper just doesn't cd) |
|
|
92
101
|
| `Ctrl+C` | Cancel like an interrupt — exit 130, same as a real SIGINT |
|
|
@@ -97,8 +106,11 @@ highlighted action, `c`/`d`/`r` to run cd/delete/switch-root directly, and
|
|
|
97
106
|
`Esc`, `Tab`, `←`, or `Ctrl+H` to close it back to the list (`←`/`Ctrl+H`
|
|
98
107
|
mirror the `→`/`Ctrl+L`/`Ctrl+F` that open it; `Tab` toggles either way —
|
|
99
108
|
handy on terminals like Ghostty that remap a chord such as Cmd+K to Tab). `delete`
|
|
100
|
-
|
|
101
|
-
|
|
109
|
+
appears for any already-created worktree (`managed` or `external` — deleting
|
|
110
|
+
an `external` one always asks y/N, whether from the panel or Ctrl+X); `switch
|
|
111
|
+
root here` doesn't appear on the root worktree itself, and also asks y/N
|
|
112
|
+
first for an `external` worktree, since it can detach that worktree's HEAD.
|
|
113
|
+
Deleting reloads the
|
|
102
114
|
candidate list so you can keep deleting without leaving the picker; cd and
|
|
103
115
|
switch-root exit and print the resulting path, per hop's stdout contract.
|
|
104
116
|
|
|
@@ -114,12 +126,19 @@ eval "$(hop init zsh)"
|
|
|
114
126
|
> Not released yet — no version has been published or tagged. Once the first
|
|
115
127
|
> `v*` tag ships, the options below will work as described.
|
|
116
128
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
129
|
+
Recommended: the GitHub Release binary (built with bun; via mise,
|
|
130
|
+
`mise use github:n-seiji/nuthatch`). The npm version runs on Node, so its git
|
|
131
|
+
calls are slower (hop ls ~400ms vs ~60ms) — prefer the binary for CI or
|
|
132
|
+
frequent invocations.
|
|
120
133
|
|
|
121
|
-
|
|
134
|
+
```sh
|
|
135
|
+
# Prebuilt binary (macOS arm64/x64, Linux x64) — no Node.js required, fastest:
|
|
122
136
|
curl -fsSL https://raw.githubusercontent.com/n-seiji/nuthatch/main/install.sh | sh
|
|
137
|
+
mise use github:n-seiji/nuthatch # mise, via the GitHub Release binary
|
|
138
|
+
|
|
139
|
+
# npm (slower: shells out to git via Node — hop ls ~400ms vs ~60ms for the binary)
|
|
140
|
+
npm i -g @n-seiji/nuthatch # or: bunx @n-seiji/nuthatch
|
|
141
|
+
mise use -g npm:@n-seiji/nuthatch # mise, via npm
|
|
123
142
|
```
|
|
124
143
|
|
|
125
144
|
The install script places `hop` in `~/.local/bin` (override with
|
|
@@ -145,7 +164,7 @@ codex plugin install hop
|
|
|
145
164
|
|
|
146
165
|
## Docs
|
|
147
166
|
|
|
148
|
-
- [docs/design.md](docs/design.md) — full design document
|
|
167
|
+
- [docs/design.md](docs/design.md) — full design document
|
|
149
168
|
- [AGENTS.md](AGENTS.md) — guide for coding agents working on this repo
|
|
150
169
|
|
|
151
170
|
## License
|