vde-worktree 0.0.18 → 0.0.19
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 +2 -0
- package/README.md +2 -0
- package/dist/index.mjs +51 -25
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.ja.md
CHANGED
|
@@ -142,6 +142,7 @@ vw list --full-path
|
|
|
142
142
|
|
|
143
143
|
- Git の porcelain 情報から worktree 一覧を取得
|
|
144
144
|
- branch/path/dirty/lock/merged/PR/upstream を表示
|
|
145
|
+
- JSON メタデータには non-base branch ごとに `pr.status` と `pr.url` を含む
|
|
145
146
|
- テーブル表示では長い `path` は端末幅に合わせて `…` で省略
|
|
146
147
|
- `--full-path` でテーブル表示の path 省略を無効化
|
|
147
148
|
- `--no-gh` 指定時は PR 状態判定をスキップ(`pr.status` は `unknown`、`merged.byPR` は `null`)
|
|
@@ -428,6 +429,7 @@ vw completion zsh --install
|
|
|
428
429
|
- `merged.byPR`: GitHub PR merged 判定(`gh`)
|
|
429
430
|
- `merged.overall`: 最終判定
|
|
430
431
|
- `pr.status`: PR 状態(`none` / `open` / `merged` / `closed_unmerged` / `unknown`)
|
|
432
|
+
- `pr.url`: branch の最新 PR URL(取得不可時は `null`)
|
|
431
433
|
|
|
432
434
|
`overall` ポリシー:
|
|
433
435
|
|
package/README.md
CHANGED
|
@@ -142,6 +142,7 @@ What it does:
|
|
|
142
142
|
|
|
143
143
|
- Lists all worktrees from Git porcelain output
|
|
144
144
|
- Includes metadata such as branch, path, dirty, lock, merged, PR status, and upstream status
|
|
145
|
+
- JSON metadata includes `pr.status` and `pr.url` for each non-base branch
|
|
145
146
|
- In table output, long `path` values are truncated with `…` to fit terminal width by default
|
|
146
147
|
- Use `--full-path` to disable path truncation in table output
|
|
147
148
|
- With `--no-gh`, skips PR status checks (`pr.status` becomes `unknown`, `merged.byPR` becomes `null`)
|
|
@@ -428,6 +429,7 @@ Each worktree reports:
|
|
|
428
429
|
- `merged.byPR`: PR-based merged check via GitHub CLI
|
|
429
430
|
- `merged.overall`: final decision
|
|
430
431
|
- `pr.status`: PR state (`none` / `open` / `merged` / `closed_unmerged` / `unknown`)
|
|
432
|
+
- `pr.url`: latest PR URL for the branch (`null` when unavailable)
|
|
431
433
|
|
|
432
434
|
Overall policy:
|
|
433
435
|
|
package/dist/index.mjs
CHANGED
|
@@ -853,8 +853,11 @@ const toTargetBranches = ({ branches, baseBranch }) => {
|
|
|
853
853
|
}
|
|
854
854
|
return [...uniqueBranches];
|
|
855
855
|
};
|
|
856
|
-
const
|
|
857
|
-
return new Map(branches.map((branch) => [branch,
|
|
856
|
+
const buildUnknownPrStateMap = (branches) => {
|
|
857
|
+
return new Map(branches.map((branch) => [branch, {
|
|
858
|
+
status: "unknown",
|
|
859
|
+
url: null
|
|
860
|
+
}]));
|
|
858
861
|
};
|
|
859
862
|
const parseUpdatedAtMillis = (value) => {
|
|
860
863
|
if (typeof value !== "string" || value.length === 0) return Number.NEGATIVE_INFINITY;
|
|
@@ -870,7 +873,11 @@ const toPrStatus = (record) => {
|
|
|
870
873
|
if (state === "CLOSED") return "closed_unmerged";
|
|
871
874
|
return "unknown";
|
|
872
875
|
};
|
|
873
|
-
const
|
|
876
|
+
const toPrUrl = (record) => {
|
|
877
|
+
if (typeof record.url === "string" && record.url.length > 0) return record.url;
|
|
878
|
+
return null;
|
|
879
|
+
};
|
|
880
|
+
const parsePrStateByBranch = ({ raw, targetBranches }) => {
|
|
874
881
|
try {
|
|
875
882
|
const parsed = JSON.parse(raw);
|
|
876
883
|
if (Array.isArray(parsed) !== true) return null;
|
|
@@ -882,31 +889,43 @@ const parsePrStatusByBranch = ({ raw, targetBranches }) => {
|
|
|
882
889
|
if (targetBranchSet.has(record.headRefName) !== true) continue;
|
|
883
890
|
const updatedAtMillis = parseUpdatedAtMillis(record.updatedAt);
|
|
884
891
|
const status = toPrStatus(record);
|
|
892
|
+
const url = toPrUrl(record);
|
|
885
893
|
const current = latestByBranch.get(record.headRefName);
|
|
886
894
|
if (current === void 0 || updatedAtMillis > current.updatedAtMillis || updatedAtMillis === current.updatedAtMillis && index > current.index) latestByBranch.set(record.headRefName, {
|
|
887
895
|
updatedAtMillis,
|
|
888
896
|
index,
|
|
889
|
-
status
|
|
897
|
+
status,
|
|
898
|
+
url
|
|
890
899
|
});
|
|
891
900
|
}
|
|
892
901
|
const result = /* @__PURE__ */ new Map();
|
|
893
902
|
for (const branch of targetBranches) {
|
|
894
903
|
const latest = latestByBranch.get(branch);
|
|
895
|
-
|
|
904
|
+
if (latest === void 0) {
|
|
905
|
+
result.set(branch, {
|
|
906
|
+
status: "none",
|
|
907
|
+
url: null
|
|
908
|
+
});
|
|
909
|
+
continue;
|
|
910
|
+
}
|
|
911
|
+
result.set(branch, {
|
|
912
|
+
status: latest.status,
|
|
913
|
+
url: latest.url
|
|
914
|
+
});
|
|
896
915
|
}
|
|
897
916
|
return result;
|
|
898
917
|
} catch {
|
|
899
918
|
return null;
|
|
900
919
|
}
|
|
901
920
|
};
|
|
902
|
-
const
|
|
921
|
+
const resolvePrStateByBranchBatch = async ({ repoRoot, baseBranch, branches, enabled = true, runGh = defaultRunGh }) => {
|
|
903
922
|
if (baseBranch === null) return /* @__PURE__ */ new Map();
|
|
904
923
|
const targetBranches = toTargetBranches({
|
|
905
924
|
branches,
|
|
906
925
|
baseBranch
|
|
907
926
|
});
|
|
908
927
|
if (targetBranches.length === 0) return /* @__PURE__ */ new Map();
|
|
909
|
-
if (enabled !== true) return
|
|
928
|
+
if (enabled !== true) return buildUnknownPrStateMap(targetBranches);
|
|
910
929
|
try {
|
|
911
930
|
const result = await runGh({
|
|
912
931
|
cwd: repoRoot,
|
|
@@ -922,19 +941,19 @@ const resolvePrStatusByBranchBatch = async ({ repoRoot, baseBranch, branches, en
|
|
|
922
941
|
"--limit",
|
|
923
942
|
"1000",
|
|
924
943
|
"--json",
|
|
925
|
-
"headRefName,state,mergedAt,updatedAt"
|
|
944
|
+
"headRefName,state,mergedAt,updatedAt,url"
|
|
926
945
|
]
|
|
927
946
|
});
|
|
928
|
-
if (result.exitCode !== 0) return
|
|
929
|
-
const prStatusByBranch =
|
|
947
|
+
if (result.exitCode !== 0) return buildUnknownPrStateMap(targetBranches);
|
|
948
|
+
const prStatusByBranch = parsePrStateByBranch({
|
|
930
949
|
raw: result.stdout,
|
|
931
950
|
targetBranches
|
|
932
951
|
});
|
|
933
|
-
if (prStatusByBranch === null) return
|
|
952
|
+
if (prStatusByBranch === null) return buildUnknownPrStateMap(targetBranches);
|
|
934
953
|
return prStatusByBranch;
|
|
935
954
|
} catch (error) {
|
|
936
|
-
if (error.code === "ENOENT") return
|
|
937
|
-
return
|
|
955
|
+
if (error.code === "ENOENT") return buildUnknownPrStateMap(targetBranches);
|
|
956
|
+
return buildUnknownPrStateMap(targetBranches);
|
|
938
957
|
}
|
|
939
958
|
};
|
|
940
959
|
|
|
@@ -1133,7 +1152,7 @@ const resolveLifecycleFromReflog = async ({ repoRoot, branch, baseBranch }) => {
|
|
|
1133
1152
|
divergedHead: latestWorkHead
|
|
1134
1153
|
};
|
|
1135
1154
|
};
|
|
1136
|
-
const resolveMergedState = async ({ repoRoot, branch, head, baseBranch,
|
|
1155
|
+
const resolveMergedState = async ({ repoRoot, branch, head, baseBranch, prStateByBranch }) => {
|
|
1137
1156
|
if (branch === null) return {
|
|
1138
1157
|
byAncestry: null,
|
|
1139
1158
|
byPR: null,
|
|
@@ -1154,7 +1173,7 @@ const resolveMergedState = async ({ repoRoot, branch, head, baseBranch, prStatus
|
|
|
1154
1173
|
if (result.exitCode === 0) byAncestry = true;
|
|
1155
1174
|
else if (result.exitCode === 1) byAncestry = false;
|
|
1156
1175
|
}
|
|
1157
|
-
const prStatus = branch === baseBranch ? null :
|
|
1176
|
+
const prStatus = branch === baseBranch ? null : prStateByBranch.get(branch)?.status ?? null;
|
|
1158
1177
|
let byPR = null;
|
|
1159
1178
|
if (prStatus === "merged") byPR = true;
|
|
1160
1179
|
else if (prStatus === "none" || prStatus === "open" || prStatus === "closed_unmerged") byPR = false;
|
|
@@ -1208,9 +1227,16 @@ const resolveMergedState = async ({ repoRoot, branch, head, baseBranch, prStatus
|
|
|
1208
1227
|
})
|
|
1209
1228
|
};
|
|
1210
1229
|
};
|
|
1211
|
-
const
|
|
1212
|
-
if (branch === null || branch === baseBranch) return {
|
|
1213
|
-
|
|
1230
|
+
const resolveWorktreePrState = ({ branch, baseBranch, prStateByBranch }) => {
|
|
1231
|
+
if (branch === null || branch === baseBranch) return {
|
|
1232
|
+
status: null,
|
|
1233
|
+
url: null
|
|
1234
|
+
};
|
|
1235
|
+
const prState = prStateByBranch.get(branch);
|
|
1236
|
+
return {
|
|
1237
|
+
status: prState?.status ?? null,
|
|
1238
|
+
url: prState?.url ?? null
|
|
1239
|
+
};
|
|
1214
1240
|
};
|
|
1215
1241
|
const resolveMergedOverall = ({ byAncestry, byPR, byLifecycle }) => {
|
|
1216
1242
|
if (byPR === true || byLifecycle === true) return true;
|
|
@@ -1258,7 +1284,7 @@ const resolveUpstreamState = async (worktreePath) => {
|
|
|
1258
1284
|
remote: upstreamRef.stdout.trim()
|
|
1259
1285
|
};
|
|
1260
1286
|
};
|
|
1261
|
-
const enrichWorktree = async ({ repoRoot, worktree, baseBranch,
|
|
1287
|
+
const enrichWorktree = async ({ repoRoot, worktree, baseBranch, prStateByBranch }) => {
|
|
1262
1288
|
const [dirty, locked, merged, upstream] = await Promise.all([
|
|
1263
1289
|
resolveDirty(worktree.path),
|
|
1264
1290
|
resolveLockState({
|
|
@@ -1270,14 +1296,14 @@ const enrichWorktree = async ({ repoRoot, worktree, baseBranch, prStatusByBranch
|
|
|
1270
1296
|
branch: worktree.branch,
|
|
1271
1297
|
head: worktree.head,
|
|
1272
1298
|
baseBranch,
|
|
1273
|
-
|
|
1299
|
+
prStateByBranch
|
|
1274
1300
|
}),
|
|
1275
1301
|
resolveUpstreamState(worktree.path)
|
|
1276
1302
|
]);
|
|
1277
|
-
const pr =
|
|
1303
|
+
const pr = resolveWorktreePrState({
|
|
1278
1304
|
branch: worktree.branch,
|
|
1279
1305
|
baseBranch,
|
|
1280
|
-
|
|
1306
|
+
prStateByBranch
|
|
1281
1307
|
});
|
|
1282
1308
|
return {
|
|
1283
1309
|
branch: worktree.branch,
|
|
@@ -1296,7 +1322,7 @@ const collectWorktreeSnapshot = async (repoRoot, { noGh = false } = {}) => {
|
|
|
1296
1322
|
listGitWorktrees(repoRoot),
|
|
1297
1323
|
resolveEnableGh(repoRoot)
|
|
1298
1324
|
]);
|
|
1299
|
-
const
|
|
1325
|
+
const prStateByBranch = await resolvePrStateByBranchBatch({
|
|
1300
1326
|
repoRoot,
|
|
1301
1327
|
baseBranch,
|
|
1302
1328
|
branches: worktrees.map((worktree) => worktree.branch),
|
|
@@ -1310,7 +1336,7 @@ const collectWorktreeSnapshot = async (repoRoot, { noGh = false } = {}) => {
|
|
|
1310
1336
|
repoRoot,
|
|
1311
1337
|
worktree,
|
|
1312
1338
|
baseBranch,
|
|
1313
|
-
|
|
1339
|
+
prStateByBranch
|
|
1314
1340
|
});
|
|
1315
1341
|
}))
|
|
1316
1342
|
};
|
|
@@ -1665,7 +1691,7 @@ const commandHelpEntries = [
|
|
|
1665
1691
|
details: [
|
|
1666
1692
|
"Table output includes branch, path, dirty, lock, merged, PR state, and ahead/behind vs base branch.",
|
|
1667
1693
|
"By default, long path values are truncated to fit terminal width.",
|
|
1668
|
-
"JSON output includes PR and upstream metadata fields."
|
|
1694
|
+
"JSON output includes PR status/url and upstream metadata fields."
|
|
1669
1695
|
],
|
|
1670
1696
|
options: ["--full-path"]
|
|
1671
1697
|
},
|