@henryqw/pi-herdr-done 0.4.1 → 0.4.2
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.md +2 -2
- package/extensions/done.ts +11 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,9 +23,9 @@ git -C <parent> pull --ff-only
|
|
|
23
23
|
herdr tab close "$HERDR_TAB_ID"
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
The parent pull runs only when this session ran in a linked worktree with a non-bare primary
|
|
26
|
+
The parent pull runs only when this session ran in a linked worktree with a non-bare primary. It fails safely when the parent has diverged. Parent tabs do not block worktree removal or the parent pull. Once removal succeeds, the current tab closes even when the parent pull fails. Concurrent completions serialize on a lock around the parent checkout.
|
|
27
27
|
|
|
28
|
-
Only the current session's tab closes, so sibling tabs in the same workspace survive. When another Herdr tab still uses the checkout
|
|
28
|
+
Only the current session's tab closes, so sibling tabs in the same workspace survive. When another Herdr tab still uses the current checkout, `/done` refuses and lists the blocking tabs by name; use `/done --force` to remove the checkout regardless. Command requires Pi running inside Herdr with `HERDR_ENV=1` and `HERDR_TAB_ID` set.
|
|
29
29
|
|
|
30
30
|
Dirty worktrees make `/done` fail. Commit or discard changes, or use `/done --force` to explicitly delete them.
|
|
31
31
|
|
package/extensions/done.ts
CHANGED
|
@@ -52,13 +52,10 @@ export default function herdrDoneExtension(pi: ExtensionAPI): void {
|
|
|
52
52
|
const snapshot = await herdr.json(["api", "snapshot"], { cwd: ctx.cwd });
|
|
53
53
|
const panes = (snapshot.result as { snapshot?: { panes?: SnapshotPane[] } } | undefined)?.snapshot?.panes;
|
|
54
54
|
if (!Array.isArray(panes)) throw new Error("herdr api snapshot returned no panes.");
|
|
55
|
-
const guarded = mainCheckout === checkout ? [checkout] : [checkout, mainCheckout];
|
|
56
|
-
const isGuarded = (cwd: string) =>
|
|
57
|
-
guarded.some((root) => cwd === root || cwd.startsWith(`${root}/`));
|
|
58
55
|
const dependentIds = [...new Set(panes
|
|
59
56
|
.filter((pane): pane is SnapshotPane & { tab_id: string; cwd: string } =>
|
|
60
|
-
typeof pane.tab_id === "string" && pane.tab_id !== tabId &&
|
|
61
|
-
|
|
57
|
+
typeof pane.tab_id === "string" && pane.tab_id !== tabId && typeof pane.cwd === "string" &&
|
|
58
|
+
(pane.cwd === checkout || pane.cwd.startsWith(`${checkout}/`)))
|
|
62
59
|
.map((pane) => pane.tab_id))];
|
|
63
60
|
if (dependentIds.length > 0) {
|
|
64
61
|
const listing = await herdr.json(["tab", "list"], { cwd: ctx.cwd });
|
|
@@ -77,14 +74,16 @@ export default function herdrDoneExtension(pi: ExtensionAPI): void {
|
|
|
77
74
|
"worktree", "remove", ...(option === "--force" ? ["--force"] : []), checkout,
|
|
78
75
|
], ctx.cwd);
|
|
79
76
|
});
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
77
|
+
try {
|
|
78
|
+
if (!parentIsBare && mainCheckout !== checkout) {
|
|
79
|
+
// Serialize concurrent completions pulling the same parent checkout.
|
|
80
|
+
// Run outside the removed checkout because its directory no longer exists.
|
|
81
|
+
await withWorktreeLock(mainCheckout, () => execOrThrow("git", ["pull", "--ff-only"], mainCheckout));
|
|
82
|
+
}
|
|
83
|
+
} finally {
|
|
84
|
+
// Close only this session's tab once its checkout is removed, even if the parent pull fails.
|
|
85
|
+
await herdr.run(["tab", "close", tabId], { cwd: tmpdir() });
|
|
84
86
|
}
|
|
85
|
-
// Close only this session's tab so unrelated tabs survive.
|
|
86
|
-
// Run outside the removed checkout because its directory no longer exists.
|
|
87
|
-
await herdr.run(["tab", "close", tabId], { cwd: tmpdir() });
|
|
88
87
|
},
|
|
89
88
|
});
|
|
90
89
|
}
|