vde-worktree 0.0.17 → 0.0.18

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
@@ -135,12 +135,15 @@ vw init
135
135
  vw list
136
136
  vw list --json
137
137
  vw list --no-gh
138
+ vw list --full-path
138
139
  ```
139
140
 
140
141
  機能:
141
142
 
142
143
  - Git の porcelain 情報から worktree 一覧を取得
143
144
  - branch/path/dirty/lock/merged/PR/upstream を表示
145
+ - テーブル表示では長い `path` は端末幅に合わせて `…` で省略
146
+ - `--full-path` でテーブル表示の path 省略を無効化
144
147
  - `--no-gh` 指定時は PR 状態判定をスキップ(`pr.status` は `unknown`、`merged.byPR` は `null`)
145
148
  - 対話ターミナルでは Catppuccin 風の ANSI 色で表示
146
149
 
package/README.md CHANGED
@@ -135,12 +135,15 @@ What it does:
135
135
  vw list
136
136
  vw list --json
137
137
  vw list --no-gh
138
+ vw list --full-path
138
139
  ```
139
140
 
140
141
  What it does:
141
142
 
142
143
  - Lists all worktrees from Git porcelain output
143
144
  - Includes metadata such as branch, path, dirty, lock, merged, PR status, and upstream status
145
+ - In table output, long `path` values are truncated with `…` to fit terminal width by default
146
+ - Use `--full-path` to disable path truncation in table output
144
147
  - With `--no-gh`, skips PR status checks (`pr.status` becomes `unknown`, `merged.byPR` becomes `null`)
145
148
  - In interactive terminal, uses Catppuccin-style ANSI colors
146
149
 
@@ -189,6 +189,8 @@ for __vw_bin in vw vde-worktree
189
189
  complete -c $__vw_bin -l json -d "Output machine-readable JSON"
190
190
  complete -c $__vw_bin -l verbose -d "Enable verbose logs"
191
191
  complete -c $__vw_bin -l no-hooks -d "Disable hooks for this run (requires --allow-unsafe)"
192
+ complete -c $__vw_bin -l no-gh -d "Disable GitHub CLI based PR status checks for this run"
193
+ complete -c $__vw_bin -l full-path -d "Disable list table path truncation"
192
194
  complete -c $__vw_bin -l allow-unsafe -d "Explicit unsafe override in non-TTY mode"
193
195
  complete -c $__vw_bin -l strict-post-hooks -d "Fail when post hooks fail"
194
196
  complete -c $__vw_bin -l hook-timeout-ms -r -d "Override hook timeout"
@@ -200,6 +202,7 @@ for __vw_bin in vw vde-worktree
200
202
  complete -c $__vw_bin -n "__fish_seen_subcommand_from path" -a "(__vw_worktree_candidates_with_meta)"
201
203
  complete -c $__vw_bin -n "__fish_seen_subcommand_from switch" -a "(__vw_worktree_candidates_with_meta)"
202
204
  complete -c $__vw_bin -n "__fish_seen_subcommand_from del" -a "(__vw_worktree_candidates_with_meta)"
205
+ complete -c $__vw_bin -n "__fish_seen_subcommand_from list" -l full-path -d "Disable list table path truncation"
203
206
  complete -c $__vw_bin -n "__fish_seen_subcommand_from get" -a "(__vw_remote_branches)"
204
207
  complete -c $__vw_bin -n "__fish_seen_subcommand_from absorb" -a "(__vw_worktree_candidates_with_meta)"
205
208
  complete -c $__vw_bin -n "__fish_seen_subcommand_from unabsorb" -a "(__vw_worktree_candidates_with_meta)"
@@ -263,6 +263,8 @@ _vw() {
263
263
  "--json[Output machine-readable JSON]"
264
264
  "--verbose[Enable verbose logs]"
265
265
  "--no-hooks[Disable hooks for this run]"
266
+ "--no-gh[Disable GitHub CLI based PR status checks for this run]"
267
+ "--full-path[Disable list table path truncation]"
266
268
  "--allow-unsafe[Allow unsafe behavior in non-TTY mode]"
267
269
  "--strict-post-hooks[Fail when post hooks fail]"
268
270
  "--hook-timeout-ms[Override hook timeout]:ms:"
@@ -284,6 +286,10 @@ _vw() {
284
286
  arguments)
285
287
  local current_command="${line[1]:-${words[2]}}"
286
288
  case "${current_command}" in
289
+ list)
290
+ _arguments \
291
+ "--full-path[Disable list table path truncation]"
292
+ ;;
287
293
  status)
288
294
  _arguments \
289
295
  "1:branch:_vw_complete_worktree_branches_with_meta"
package/dist/index.mjs CHANGED
@@ -1488,6 +1488,10 @@ const CD_FZF_EXTRA_ARGS = [
1488
1488
  "--preview-window=right,60%,wrap",
1489
1489
  "--ansi"
1490
1490
  ];
1491
+ const LIST_TABLE_COLUMN_COUNT = 8;
1492
+ const LIST_TABLE_PATH_COLUMN_INDEX = 7;
1493
+ const LIST_TABLE_PATH_MIN_WIDTH = 12;
1494
+ const LIST_TABLE_CELL_HORIZONTAL_PADDING = 2;
1491
1495
  const COMPLETION_SHELLS = ["zsh", "fish"];
1492
1496
  const COMPLETION_FILE_BY_SHELL = {
1493
1497
  zsh: "zsh/_vw",
@@ -1656,9 +1660,14 @@ const commandHelpEntries = [
1656
1660
  },
1657
1661
  {
1658
1662
  name: "list",
1659
- usage: "vw list [--json]",
1663
+ usage: "vw list [--json] [--full-path]",
1660
1664
  summary: "List worktrees with status metadata.",
1661
- details: ["Table output includes branch, path, dirty, lock, merged, PR state, and ahead/behind vs base branch.", "JSON output includes PR and upstream metadata fields."]
1665
+ details: [
1666
+ "Table output includes branch, path, dirty, lock, merged, PR state, and ahead/behind vs base branch.",
1667
+ "By default, long path values are truncated to fit terminal width.",
1668
+ "JSON output includes PR and upstream metadata fields."
1669
+ ],
1670
+ options: ["--full-path"]
1662
1671
  },
1663
1672
  {
1664
1673
  name: "status",
@@ -2484,6 +2493,26 @@ const formatListUpstreamCount = (value) => {
2484
2493
  if (value === null) return "-";
2485
2494
  return String(value);
2486
2495
  };
2496
+ const resolveListColumnContentWidth = ({ rows, columnIndex }) => {
2497
+ return rows.reduce((width, row) => {
2498
+ const cell = row[columnIndex] ?? "";
2499
+ return Math.max(width, stringWidth(cell));
2500
+ }, 0);
2501
+ };
2502
+ const resolveListPathColumnWidth = ({ rows, disablePathTruncation }) => {
2503
+ if (disablePathTruncation) return null;
2504
+ if (process.stdout.isTTY !== true) return null;
2505
+ const terminalColumns = process.stdout.columns;
2506
+ if (typeof terminalColumns !== "number" || Number.isFinite(terminalColumns) !== true || terminalColumns <= 0) return null;
2507
+ const measuredNonPathWidth = Array.from({ length: LIST_TABLE_PATH_COLUMN_INDEX }).map((_, index) => resolveListColumnContentWidth({
2508
+ rows,
2509
+ columnIndex: index
2510
+ })).reduce((sum, width) => sum + width, 0);
2511
+ const borderWidth = LIST_TABLE_COLUMN_COUNT + 1;
2512
+ const paddingWidth = LIST_TABLE_COLUMN_COUNT * LIST_TABLE_CELL_HORIZONTAL_PADDING;
2513
+ const availablePathWidth = Math.floor(terminalColumns) - borderWidth - paddingWidth - measuredNonPathWidth;
2514
+ return Math.max(LIST_TABLE_PATH_MIN_WIDTH, availablePathWidth);
2515
+ };
2487
2516
  const resolveAheadBehindAgainstBaseBranch = async ({ repoRoot, baseBranch, worktree }) => {
2488
2517
  if (baseBranch === null) return {
2489
2518
  ahead: null,
@@ -2642,6 +2671,7 @@ const renderGeneralHelpText = ({ version }) => {
2642
2671
  " --verbose Enable verbose logs.",
2643
2672
  " --no-hooks Disable hooks for this run (requires --allow-unsafe).",
2644
2673
  " --no-gh Disable GitHub CLI based PR status checks for this run.",
2674
+ " --full-path Disable list table path truncation.",
2645
2675
  " --allow-unsafe Explicitly allow unsafe behavior in non-TTY mode.",
2646
2676
  " --hook-timeout-ms <ms> Override hook timeout.",
2647
2677
  " --lock-timeout-ms <ms> Override repository lock timeout.",
@@ -2747,6 +2777,10 @@ const createCli = (options = {}) => {
2747
2777
  description: "Enable GitHub CLI based PR status checks (disable with --no-gh)",
2748
2778
  default: true
2749
2779
  },
2780
+ fullPath: {
2781
+ type: "boolean",
2782
+ description: "Disable list table path truncation"
2783
+ },
2750
2784
  allowUnsafe: {
2751
2785
  type: "boolean",
2752
2786
  description: "Allow unsafe operations"
@@ -3073,43 +3107,53 @@ const createCli = (options = {}) => {
3073
3107
  return EXIT_CODE.OK;
3074
3108
  }
3075
3109
  const theme = createCatppuccinTheme({ enabled: shouldUseAnsiColors({ interactive: runtime.isInteractive }) });
3110
+ const rows = [[
3111
+ "branch",
3112
+ "dirty",
3113
+ "merged",
3114
+ "pr",
3115
+ "locked",
3116
+ "ahead",
3117
+ "behind",
3118
+ "path"
3119
+ ], ...await Promise.all(snapshot.worktrees.map(async (worktree) => {
3120
+ const distanceFromBase = await resolveAheadBehindAgainstBaseBranch({
3121
+ repoRoot,
3122
+ baseBranch: snapshot.baseBranch,
3123
+ worktree
3124
+ });
3125
+ const isBaseBranch = worktree.branch !== null && snapshot.baseBranch !== null && worktree.branch === snapshot.baseBranch;
3126
+ const mergedState = isBaseBranch === true ? "-" : worktree.merged.overall === true ? "merged" : worktree.merged.overall === false ? "unmerged" : "unknown";
3127
+ const prState = formatPrDisplayState({
3128
+ prStatus: worktree.pr.status,
3129
+ isBaseBranch
3130
+ });
3131
+ return [
3132
+ `${worktree.path === repoContext.currentWorktreeRoot ? "*" : " "} ${worktree.branch ?? "(detached)"}`,
3133
+ worktree.dirty ? "dirty" : "clean",
3134
+ mergedState,
3135
+ prState,
3136
+ worktree.locked.value ? "locked" : "-",
3137
+ formatListUpstreamCount(distanceFromBase.ahead),
3138
+ formatListUpstreamCount(distanceFromBase.behind),
3139
+ formatDisplayPath(worktree.path)
3140
+ ];
3141
+ }))];
3142
+ const pathColumnWidth = resolveListPathColumnWidth({
3143
+ rows,
3144
+ disablePathTruncation: parsedArgs.fullPath === true
3145
+ });
3146
+ const columnsConfig = pathColumnWidth === null ? void 0 : { [LIST_TABLE_PATH_COLUMN_INDEX]: {
3147
+ width: pathColumnWidth,
3148
+ truncate: pathColumnWidth
3149
+ } };
3076
3150
  const colorized = colorizeListTable({
3077
- rendered: table([[
3078
- "branch",
3079
- "dirty",
3080
- "merged",
3081
- "pr",
3082
- "locked",
3083
- "ahead",
3084
- "behind",
3085
- "path"
3086
- ], ...await Promise.all(snapshot.worktrees.map(async (worktree) => {
3087
- const distanceFromBase = await resolveAheadBehindAgainstBaseBranch({
3088
- repoRoot,
3089
- baseBranch: snapshot.baseBranch,
3090
- worktree
3091
- });
3092
- const isBaseBranch = worktree.branch !== null && snapshot.baseBranch !== null && worktree.branch === snapshot.baseBranch;
3093
- const mergedState = isBaseBranch === true ? "-" : worktree.merged.overall === true ? "merged" : worktree.merged.overall === false ? "unmerged" : "unknown";
3094
- const prState = formatPrDisplayState({
3095
- prStatus: worktree.pr.status,
3096
- isBaseBranch
3097
- });
3098
- return [
3099
- `${worktree.path === repoContext.currentWorktreeRoot ? "*" : " "} ${worktree.branch ?? "(detached)"}`,
3100
- worktree.dirty ? "dirty" : "clean",
3101
- mergedState,
3102
- prState,
3103
- worktree.locked.value ? "locked" : "-",
3104
- formatListUpstreamCount(distanceFromBase.ahead),
3105
- formatListUpstreamCount(distanceFromBase.behind),
3106
- formatDisplayPath(worktree.path)
3107
- ];
3108
- }))], {
3151
+ rendered: table(rows, {
3109
3152
  border: getBorderCharacters("norc"),
3110
3153
  drawHorizontalLine: (lineIndex, rowCount) => {
3111
3154
  return lineIndex === 0 || lineIndex === 1 || lineIndex === rowCount;
3112
- }
3155
+ },
3156
+ columns: columnsConfig
3113
3157
  }),
3114
3158
  theme
3115
3159
  });