vde-worktree 0.0.15 → 0.0.17
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 +14 -8
- package/README.md +13 -7
- package/completions/fish/vw.fish +12 -2
- package/completions/zsh/_vw +12 -2
- package/dist/index.mjs +222 -123
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.ja.md
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
- Node.js 22+
|
|
23
23
|
- pnpm 10+
|
|
24
24
|
- `fzf`(`cd` に必須)
|
|
25
|
-
- `gh`(PR
|
|
25
|
+
- `gh`(PR 状態判定に任意)
|
|
26
26
|
|
|
27
27
|
## インストール / ビルド
|
|
28
28
|
|
|
@@ -111,7 +111,7 @@ autoload -Uz compinit && compinit
|
|
|
111
111
|
- `--verbose`: 詳細ログ
|
|
112
112
|
- `--no-hooks`: 今回のみ hook 無効化(`--allow-unsafe` 必須)
|
|
113
113
|
- `--allow-unsafe`: unsafe 操作の明示同意
|
|
114
|
-
- `--no-gh`: 今回の実行で `gh` による PR
|
|
114
|
+
- `--no-gh`: 今回の実行で `gh` による PR 状態判定を無効化
|
|
115
115
|
- `--hook-timeout-ms <ms>`: hook timeout 上書き
|
|
116
116
|
- `--lock-timeout-ms <ms>`: repo lock timeout 上書き
|
|
117
117
|
|
|
@@ -140,8 +140,8 @@ vw list --no-gh
|
|
|
140
140
|
機能:
|
|
141
141
|
|
|
142
142
|
- Git の porcelain 情報から worktree 一覧を取得
|
|
143
|
-
- branch/path/dirty/lock/merged/upstream を表示
|
|
144
|
-
- `--no-gh` 指定時は PR
|
|
143
|
+
- branch/path/dirty/lock/merged/PR/upstream を表示
|
|
144
|
+
- `--no-gh` 指定時は PR 状態判定をスキップ(`pr.status` は `unknown`、`merged.byPR` は `null`)
|
|
145
145
|
- 対話ターミナルでは Catppuccin 風の ANSI 色で表示
|
|
146
146
|
|
|
147
147
|
### `status`
|
|
@@ -424,14 +424,20 @@ vw completion zsh --install
|
|
|
424
424
|
- `merged.byAncestry`: ローカル履歴判定(`git merge-base --is-ancestor`)
|
|
425
425
|
- `merged.byPR`: GitHub PR merged 判定(`gh`)
|
|
426
426
|
- `merged.overall`: 最終判定
|
|
427
|
+
- `pr.status`: PR 状態(`none` / `open` / `merged` / `closed_unmerged` / `unknown`)
|
|
427
428
|
|
|
428
429
|
`overall` ポリシー:
|
|
429
430
|
|
|
430
|
-
- `byPR === true` -> `overall = true
|
|
431
|
-
- `
|
|
432
|
-
- `
|
|
431
|
+
- `byPR === true` -> `overall = true`(squash/rebase merge を含む)
|
|
432
|
+
- `byAncestry === false` -> `overall = false`
|
|
433
|
+
- `byAncestry === true` の場合は、分岐の証跡があるときだけ merged 扱い
|
|
434
|
+
- `.vde/worktree/state/branches/*.json` の lifecycle 記録
|
|
435
|
+
- lifecycle がない場合の `git reflog` フォールバック
|
|
436
|
+
- 分岐証跡が `baseBranch` に取り込まれていれば `overall = true`
|
|
437
|
+
- `byPR === false` または lifecycle が明示的に未取り込みなら `overall = false`
|
|
438
|
+
- それ以外は `overall = null`
|
|
433
439
|
|
|
434
|
-
`byPR` が `null` になる例:
|
|
440
|
+
`byPR` が `null` かつ `pr.status` が `unknown` になる例:
|
|
435
441
|
|
|
436
442
|
- `gh` 未導入
|
|
437
443
|
- `gh auth` 未設定
|
package/README.md
CHANGED
|
@@ -111,7 +111,7 @@ After `vw init`, the tool manages:
|
|
|
111
111
|
- `--verbose`: verbose logging
|
|
112
112
|
- `--no-hooks`: disable hooks for this run (requires `--allow-unsafe`)
|
|
113
113
|
- `--allow-unsafe`: explicit unsafe override
|
|
114
|
-
- `--no-gh`: disable GitHub CLI based PR
|
|
114
|
+
- `--no-gh`: disable GitHub CLI based PR status checks for this run
|
|
115
115
|
- `--hook-timeout-ms <ms>`: hook timeout override
|
|
116
116
|
- `--lock-timeout-ms <ms>`: repository lock timeout override
|
|
117
117
|
|
|
@@ -140,8 +140,8 @@ vw list --no-gh
|
|
|
140
140
|
What it does:
|
|
141
141
|
|
|
142
142
|
- Lists all worktrees from Git porcelain output
|
|
143
|
-
- Includes metadata such as branch, path, dirty, lock, merged, and upstream status
|
|
144
|
-
- With `--no-gh`, skips PR
|
|
143
|
+
- Includes metadata such as branch, path, dirty, lock, merged, PR status, and upstream status
|
|
144
|
+
- With `--no-gh`, skips PR status checks (`pr.status` becomes `unknown`, `merged.byPR` becomes `null`)
|
|
145
145
|
- In interactive terminal, uses Catppuccin-style ANSI colors
|
|
146
146
|
|
|
147
147
|
### `status`
|
|
@@ -424,14 +424,20 @@ Each worktree reports:
|
|
|
424
424
|
- `merged.byAncestry`: local ancestry check (`git merge-base --is-ancestor <branch> <baseBranch>`)
|
|
425
425
|
- `merged.byPR`: PR-based merged check via GitHub CLI
|
|
426
426
|
- `merged.overall`: final decision
|
|
427
|
+
- `pr.status`: PR state (`none` / `open` / `merged` / `closed_unmerged` / `unknown`)
|
|
427
428
|
|
|
428
429
|
Overall policy:
|
|
429
430
|
|
|
430
|
-
- `byPR === true` => `overall = true`
|
|
431
|
-
- `
|
|
432
|
-
- `
|
|
431
|
+
- `byPR === true` => `overall = true` (includes squash/rebase merges)
|
|
432
|
+
- `byAncestry === false` => `overall = false`
|
|
433
|
+
- when `byAncestry === true`, require divergence evidence before treating as merged
|
|
434
|
+
- lifecycle evidence from `.vde/worktree/state/branches/*.json`
|
|
435
|
+
- reflog fallback (`git reflog`) when lifecycle evidence is missing
|
|
436
|
+
- if divergence evidence is contained in `baseBranch`, `overall = true`
|
|
437
|
+
- `byPR === false` or explicit lifecycle "not merged" evidence => `overall = false`
|
|
438
|
+
- otherwise `overall = null`
|
|
433
439
|
|
|
434
|
-
`byPR` becomes `null` when PR lookup is unavailable (for example: `gh` missing, auth missing, API error, `vde-worktree.enableGh=false`, or `--no-gh`).
|
|
440
|
+
`byPR` becomes `null` and `pr.status` becomes `unknown` when PR lookup is unavailable (for example: `gh` missing, auth missing, API error, `vde-worktree.enableGh=false`, or `--no-gh`).
|
|
435
441
|
|
|
436
442
|
## JSON Contract
|
|
437
443
|
|
package/completions/fish/vw.fish
CHANGED
|
@@ -68,6 +68,10 @@ const toFlag = (value) => {
|
|
|
68
68
|
if (value === false) return "no"
|
|
69
69
|
return "unknown"
|
|
70
70
|
}
|
|
71
|
+
const toPrStatus = (value) => {
|
|
72
|
+
if (typeof value !== "string" || value.length === 0) return "n/a"
|
|
73
|
+
return value
|
|
74
|
+
}
|
|
71
75
|
let payload
|
|
72
76
|
try {
|
|
73
77
|
payload = JSON.parse(fs.readFileSync(0, "utf8"))
|
|
@@ -78,10 +82,11 @@ const worktrees = Array.isArray(payload.worktrees) ? payload.worktrees : []
|
|
|
78
82
|
for (const worktree of worktrees) {
|
|
79
83
|
if (typeof worktree?.branch !== "string" || worktree.branch.length === 0) continue
|
|
80
84
|
const merged = toFlag(worktree?.merged?.overall)
|
|
85
|
+
const pr = toPrStatus(worktree?.pr?.status)
|
|
81
86
|
const dirty = worktree?.dirty === true ? "yes" : "no"
|
|
82
87
|
const locked = worktree?.locked?.value === true ? "yes" : "no"
|
|
83
88
|
const path = toDisplayPath(worktree?.path)
|
|
84
|
-
const summary = `merged=${merged} dirty=${dirty} locked=${locked}${path ? ` path=${path}` : ""}`
|
|
89
|
+
const summary = `merged=${merged} pr=${pr} dirty=${dirty} locked=${locked}${path ? ` path=${path}` : ""}`
|
|
85
90
|
const sanitized = summary.replace(/[\t\r\n]+/g, " ").trim()
|
|
86
91
|
process.stdout.write(`${worktree.branch}\t${sanitized}\n`)
|
|
87
92
|
}
|
|
@@ -101,6 +106,10 @@ const toFlag = (value) => {
|
|
|
101
106
|
if (value === false) return "no"
|
|
102
107
|
return "unknown"
|
|
103
108
|
}
|
|
109
|
+
const toPrStatus = (value) => {
|
|
110
|
+
if (typeof value !== "string" || value.length === 0) return "n/a"
|
|
111
|
+
return value
|
|
112
|
+
}
|
|
104
113
|
let payload
|
|
105
114
|
try {
|
|
106
115
|
payload = JSON.parse(fs.readFileSync(0, "utf8"))
|
|
@@ -118,9 +127,10 @@ for (const worktree of worktrees) {
|
|
|
118
127
|
const name = rel.split(path.sep).join("/")
|
|
119
128
|
const branch = typeof worktree?.branch === "string" && worktree.branch.length > 0 ? worktree.branch : "(detached)"
|
|
120
129
|
const merged = toFlag(worktree?.merged?.overall)
|
|
130
|
+
const pr = toPrStatus(worktree?.pr?.status)
|
|
121
131
|
const dirty = worktree?.dirty === true ? "yes" : "no"
|
|
122
132
|
const locked = worktree?.locked?.value === true ? "yes" : "no"
|
|
123
|
-
const summary = `branch=${branch} merged=${merged} dirty=${dirty} locked=${locked}`
|
|
133
|
+
const summary = `branch=${branch} merged=${merged} pr=${pr} dirty=${dirty} locked=${locked}`
|
|
124
134
|
const sanitized = summary.replace(/[\t\r\n]+/g, " ").trim()
|
|
125
135
|
process.stdout.write(`${name}\t${sanitized}\n`)
|
|
126
136
|
}
|
package/completions/zsh/_vw
CHANGED
|
@@ -45,6 +45,10 @@ const toFlag = (value) => {
|
|
|
45
45
|
if (value === false) return "no"
|
|
46
46
|
return "unknown"
|
|
47
47
|
}
|
|
48
|
+
const toPrStatus = (value) => {
|
|
49
|
+
if (typeof value !== "string" || value.length === 0) return "n/a"
|
|
50
|
+
return value
|
|
51
|
+
}
|
|
48
52
|
let payload
|
|
49
53
|
try {
|
|
50
54
|
payload = JSON.parse(fs.readFileSync(0, "utf8"))
|
|
@@ -55,10 +59,11 @@ const worktrees = Array.isArray(payload.worktrees) ? payload.worktrees : []
|
|
|
55
59
|
for (const worktree of worktrees) {
|
|
56
60
|
if (typeof worktree?.branch !== "string" || worktree.branch.length === 0) continue
|
|
57
61
|
const merged = toFlag(worktree?.merged?.overall)
|
|
62
|
+
const pr = toPrStatus(worktree?.pr?.status)
|
|
58
63
|
const dirty = worktree?.dirty === true ? "yes" : "no"
|
|
59
64
|
const locked = worktree?.locked?.value === true ? "yes" : "no"
|
|
60
65
|
const path = toDisplayPath(worktree?.path)
|
|
61
|
-
const summary = `merged=${merged} dirty=${dirty} locked=${locked}${path ? ` path=${path}` : ""}`
|
|
66
|
+
const summary = `merged=${merged} pr=${pr} dirty=${dirty} locked=${locked}${path ? ` path=${path}` : ""}`
|
|
62
67
|
const sanitized = summary.replace(/[\t\r\n]+/g, " ").trim()
|
|
63
68
|
process.stdout.write(`${worktree.branch}\t${sanitized}\n`)
|
|
64
69
|
}
|
|
@@ -78,6 +83,10 @@ const toFlag = (value) => {
|
|
|
78
83
|
if (value === false) return "no"
|
|
79
84
|
return "unknown"
|
|
80
85
|
}
|
|
86
|
+
const toPrStatus = (value) => {
|
|
87
|
+
if (typeof value !== "string" || value.length === 0) return "n/a"
|
|
88
|
+
return value
|
|
89
|
+
}
|
|
81
90
|
let payload
|
|
82
91
|
try {
|
|
83
92
|
payload = JSON.parse(fs.readFileSync(0, "utf8"))
|
|
@@ -95,9 +104,10 @@ for (const worktree of worktrees) {
|
|
|
95
104
|
const name = rel.split(path.sep).join("/")
|
|
96
105
|
const branch = typeof worktree?.branch === "string" && worktree.branch.length > 0 ? worktree.branch : "(detached)"
|
|
97
106
|
const merged = toFlag(worktree?.merged?.overall)
|
|
107
|
+
const pr = toPrStatus(worktree?.pr?.status)
|
|
98
108
|
const dirty = worktree?.dirty === true ? "yes" : "no"
|
|
99
109
|
const locked = worktree?.locked?.value === true ? "yes" : "no"
|
|
100
|
-
const summary = `branch=${branch} merged=${merged} dirty=${dirty} locked=${locked}`
|
|
110
|
+
const summary = `branch=${branch} merged=${merged} pr=${pr} dirty=${dirty} locked=${locked}`
|
|
101
111
|
const sanitized = summary.replace(/[\t\r\n]+/g, " ").trim()
|
|
102
112
|
process.stdout.write(`${name}\t${sanitized}\n`)
|
|
103
113
|
}
|