vde-worktree 0.0.19 → 0.0.21

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 CHANGED
@@ -447,7 +447,7 @@ vw completion zsh --install
447
447
  - `gh` 未導入
448
448
  - `gh auth` 未設定
449
449
  - API 失敗
450
- - `git config vde-worktree.enableGh false`
450
+ - `config.yml` の `github.enabled: false`
451
451
  - `--no-gh` を指定して実行
452
452
 
453
453
  ## JSON 契約
@@ -468,15 +468,39 @@ vw completion zsh --install
468
468
  - `message`
469
469
  - `details`
470
470
 
471
- ## 設定キー(git config)
472
-
473
- - `vde-worktree.baseBranch`
474
- - `vde-worktree.baseRemote`
475
- - `vde-worktree.enableGh`
476
- - `vde-worktree.hooksEnabled`
477
- - `vde-worktree.hookTimeoutMs`
478
- - `vde-worktree.lockTimeoutMs`
479
- - `vde-worktree.staleLockTTLSeconds`
471
+ ## 設定(config.yml
472
+
473
+ 設定ファイルは次の順で読み込みます:
474
+
475
+ - `$XDG_CONFIG_HOME/vde/worktree/config.yml`(fallback: `~/.config/vde/worktree/config.yml`)
476
+ - `cwd` から Git 境界(`.git`)まで探索した `.vde/worktree/config.yml`
477
+ - `<repoRoot>/.vde/worktree/config.yml`(linked worktree 実行時も参照)
478
+
479
+ 主な設定キー:
480
+
481
+ ```yaml
482
+ paths:
483
+ worktreeRoot: .worktree
484
+ git:
485
+ baseBranch: null
486
+ baseRemote: origin
487
+ github:
488
+ enabled: true
489
+ hooks:
490
+ enabled: true
491
+ timeoutMs: 30000
492
+ locks:
493
+ timeoutMs: 15000
494
+ staleLockTTLSeconds: 1800
495
+ list:
496
+ table:
497
+ columns: [branch, dirty, merged, pr, locked, ahead, behind, path]
498
+ selector:
499
+ cd:
500
+ prompt: "worktree> "
501
+ surface: auto # auto | inline | tmux-popup
502
+ tmuxPopupOpts: "80%,70%"
503
+ ```
480
504
 
481
505
  ## 現在のスコープ
482
506
 
package/README.md CHANGED
@@ -442,7 +442,7 @@ Overall policy:
442
442
  - `byPR === false` or explicit lifecycle "not merged" evidence => `overall = false`
443
443
  - otherwise `overall = null`
444
444
 
445
- `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`).
445
+ `byPR` becomes `null` and `pr.status` becomes `unknown` when PR lookup is unavailable (for example: `gh` missing, auth missing, API error, `github.enabled=false` in config.yml, or `--no-gh`).
446
446
 
447
447
  ## JSON Contract
448
448
 
@@ -462,17 +462,39 @@ Error shape:
462
462
  - `message`
463
463
  - `details`
464
464
 
465
- ## Configuration Keys
466
-
467
- Configured via `git config`:
468
-
469
- - `vde-worktree.baseBranch`
470
- - `vde-worktree.baseRemote`
471
- - `vde-worktree.enableGh`
472
- - `vde-worktree.hooksEnabled`
473
- - `vde-worktree.hookTimeoutMs`
474
- - `vde-worktree.lockTimeoutMs`
475
- - `vde-worktree.staleLockTTLSeconds`
465
+ ## Configuration (`config.yml`)
466
+
467
+ Configuration is loaded from:
468
+
469
+ - `$XDG_CONFIG_HOME/vde/worktree/config.yml` (fallback: `~/.config/vde/worktree/config.yml`)
470
+ - `.vde/worktree/config.yml` discovered from `cwd` to the local Git boundary (`.git`)
471
+ - `<repoRoot>/.vde/worktree/config.yml` (always considered, including linked worktree execution)
472
+
473
+ Supported keys (examples):
474
+
475
+ ```yaml
476
+ paths:
477
+ worktreeRoot: .worktree
478
+ git:
479
+ baseBranch: null
480
+ baseRemote: origin
481
+ github:
482
+ enabled: true
483
+ hooks:
484
+ enabled: true
485
+ timeoutMs: 30000
486
+ locks:
487
+ timeoutMs: 15000
488
+ staleLockTTLSeconds: 1800
489
+ list:
490
+ table:
491
+ columns: [branch, dirty, merged, pr, locked, ahead, behind, path]
492
+ selector:
493
+ cd:
494
+ prompt: "worktree> "
495
+ surface: auto # auto | inline | tmux-popup
496
+ tmuxPopupOpts: "80%,70%"
497
+ ```
476
498
 
477
499
  ## Current Scope
478
500
 
@@ -9,10 +9,24 @@ end
9
9
  function __vw_default_branch
10
10
  command git rev-parse --is-inside-work-tree >/dev/null 2>/dev/null; or return 0
11
11
 
12
- set -l configured (command git config --get vde-worktree.baseBranch 2>/dev/null)
13
- if test -n "$configured"
14
- echo $configured
15
- return
12
+ set -l vw_bin (__vw_current_bin)
13
+ if test -n "$vw_bin"
14
+ set -l configured (command $vw_bin list --json 2>/dev/null | command node -e '
15
+ const fs = require("fs")
16
+ let payload
17
+ try {
18
+ payload = JSON.parse(fs.readFileSync(0, "utf8"))
19
+ } catch {
20
+ process.exit(0)
21
+ }
22
+ if (typeof payload?.baseBranch === "string" && payload.baseBranch.length > 0) {
23
+ process.stdout.write(payload.baseBranch)
24
+ }
25
+ ' 2>/dev/null)
26
+ if test -n "$configured"
27
+ echo $configured
28
+ return
29
+ end
16
30
  end
17
31
 
18
32
  command git show-ref --verify --quiet refs/heads/main >/dev/null 2>/dev/null
@@ -117,12 +131,17 @@ try {
117
131
  process.exit(0)
118
132
  }
119
133
  const repoRoot = typeof payload?.repoRoot === "string" ? payload.repoRoot : ""
120
- if (repoRoot.length === 0) process.exit(0)
121
- const worktreeRoot = path.join(repoRoot, ".worktree")
134
+ const managedWorktreeRoot =
135
+ typeof payload?.managedWorktreeRoot === "string" && payload.managedWorktreeRoot.length > 0
136
+ ? payload.managedWorktreeRoot
137
+ : repoRoot.length > 0
138
+ ? path.join(repoRoot, ".worktree")
139
+ : ""
140
+ if (managedWorktreeRoot.length === 0) process.exit(0)
122
141
  const worktrees = Array.isArray(payload.worktrees) ? payload.worktrees : []
123
142
  for (const worktree of worktrees) {
124
143
  if (typeof worktree?.path !== "string" || worktree.path.length === 0) continue
125
- const rel = path.relative(worktreeRoot, worktree.path)
144
+ const rel = path.relative(managedWorktreeRoot, worktree.path)
126
145
  if (!rel || rel === "." || rel === ".." || rel.startsWith(`..${path.sep}`)) continue
127
146
  const name = rel.split(path.sep).join("/")
128
147
  const branch = typeof worktree?.branch === "string" && worktree.branch.length > 0 ? worktree.branch : "(detached)"
@@ -9,11 +9,27 @@ _vw_worktree_branches_raw() {
9
9
 
10
10
  _vw_default_branch_raw() {
11
11
  command git rev-parse --is-inside-work-tree >/dev/null 2>&1 || return 0
12
- local configured
13
- configured="$(command git config --get vde-worktree.baseBranch 2>/dev/null)"
14
- if [[ -n "${configured}" ]]; then
15
- print -r -- "${configured}"
16
- return 0
12
+ local vw_bin="${words[1]:-vw}"
13
+ if command -v "$vw_bin" >/dev/null 2>&1; then
14
+ local configured
15
+ configured="$(
16
+ command "$vw_bin" list --json 2>/dev/null | command node -e '
17
+ const fs = require("fs")
18
+ let payload
19
+ try {
20
+ payload = JSON.parse(fs.readFileSync(0, "utf8"))
21
+ } catch {
22
+ process.exit(0)
23
+ }
24
+ if (typeof payload?.baseBranch === "string" && payload.baseBranch.length > 0) {
25
+ process.stdout.write(payload.baseBranch)
26
+ }
27
+ ' 2>/dev/null
28
+ )"
29
+ if [[ -n "${configured}" ]]; then
30
+ print -r -- "${configured}"
31
+ return 0
32
+ fi
17
33
  fi
18
34
  if command git show-ref --verify --quiet refs/heads/main 2>/dev/null; then
19
35
  print -r -- "main"
@@ -94,12 +110,17 @@ try {
94
110
  process.exit(0)
95
111
  }
96
112
  const repoRoot = typeof payload?.repoRoot === "string" ? payload.repoRoot : ""
97
- if (repoRoot.length === 0) process.exit(0)
98
- const worktreeRoot = path.join(repoRoot, ".worktree")
113
+ const managedWorktreeRoot =
114
+ typeof payload?.managedWorktreeRoot === "string" && payload.managedWorktreeRoot.length > 0
115
+ ? payload.managedWorktreeRoot
116
+ : repoRoot.length > 0
117
+ ? path.join(repoRoot, ".worktree")
118
+ : ""
119
+ if (managedWorktreeRoot.length === 0) process.exit(0)
99
120
  const worktrees = Array.isArray(payload.worktrees) ? payload.worktrees : []
100
121
  for (const worktree of worktrees) {
101
122
  if (typeof worktree?.path !== "string" || worktree.path.length === 0) continue
102
- const rel = path.relative(worktreeRoot, worktree.path)
123
+ const rel = path.relative(managedWorktreeRoot, worktree.path)
103
124
  if (!rel || rel === "." || rel === ".." || rel.startsWith(`..${path.sep}`)) continue
104
125
  const name = rel.split(path.sep).join("/")
105
126
  const branch = typeof worktree?.branch === "string" && worktree.branch.length > 0 ? worktree.branch : "(detached)"