@henryqw/pi-herdr-done 1.0.1 → 1.0.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 +8 -15
- package/docs/done-flow.svg +166 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
# `@henryqw/pi-herdr-done`
|
|
2
2
|
|
|
3
|
-
Finish a Herdr worktree task by removing its checkout, closing its tabs, and updating the parent.
|
|
4
|
-
|
|
5
|
-
## Why
|
|
6
|
-
|
|
7
|
-
- **Created for**: Pi users finishing work in a Herdr-managed linked worktree.
|
|
8
|
-
- **Advantage**: One command performs cleanup and refuses unsafe removal unless you explicitly force it.
|
|
3
|
+
Finish a Herdr-managed linked worktree task by removing its checkout, closing its tabs, and updating the parent. One command performs cleanup and refuses unsafe removal unless you explicitly force it.
|
|
9
4
|
|
|
10
5
|
## Install
|
|
11
6
|
|
|
@@ -15,9 +10,9 @@ pi install npm:@henryqw/pi-herdr-done
|
|
|
15
10
|
|
|
16
11
|
Requires the Herdr CLI and a Pi session running inside a Herdr-managed linked worktree.
|
|
17
12
|
|
|
18
|
-
##
|
|
13
|
+
## Works with
|
|
19
14
|
|
|
20
|
-
[`@henryqw/pi-herdr-clone`](https://pi.henry.wang/extensions/pi-herdr-clone)
|
|
15
|
+
**Improves.** [`@henryqw/pi-herdr-clone`](https://pi.henry.wang/extensions/pi-herdr-clone) creates the worktree workspace that `/done` later removes.
|
|
21
16
|
|
|
22
17
|
## Use
|
|
23
18
|
|
|
@@ -28,11 +23,11 @@ Commit or discard current changes, then run `/done` and confirm. The command wai
|
|
|
28
23
|
| `/done` | command | Remove the current worktree checkout, close its Herdr workspace's tabs, and fast-forward the parent workspace. |
|
|
29
24
|
| `/done --force` | command | Same, even when the worktree is dirty or used by tabs in another workspace. |
|
|
30
25
|
|
|
31
|
-
|
|
26
|
+
## Flow
|
|
32
27
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
28
|
+

|
|
29
|
+
|
|
30
|
+
Both forms wait for Pi to become idle before cleanup. `/done` asks for confirmation. `/done --force` skips confirmation because the flag already states intent.
|
|
36
31
|
|
|
37
32
|
Normal removal runs:
|
|
38
33
|
|
|
@@ -43,15 +38,13 @@ git -C <parent> pull --ff-only
|
|
|
43
38
|
herdr tab close "$HERDR_TAB_ID"
|
|
44
39
|
```
|
|
45
40
|
|
|
46
|
-
### Parent pull and tabs
|
|
47
|
-
|
|
48
41
|
- The parent pull runs only when this session ran in a linked worktree with a non-bare primary.
|
|
49
42
|
- It fails safely when the parent has diverged.
|
|
50
43
|
- Parent tabs do not block worktree removal or the parent pull.
|
|
51
44
|
- Once removal succeeds, every tab in the current Herdr workspace closes, even when the parent pull fails.
|
|
52
45
|
- Concurrent completions serialize on a lock around the parent checkout.
|
|
53
46
|
|
|
54
|
-
|
|
47
|
+
## Limits and recovery
|
|
55
48
|
|
|
56
49
|
- Tabs in the current Herdr workspace close automatically.
|
|
57
50
|
- If a tab from another workspace still uses the current checkout, `/done` refuses and lists it by name. Use `/done --force` to remove the checkout regardless.
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg width="1280" height="720" viewBox="0 0 1280 720" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="done-flow-title done-flow-desc">
|
|
3
|
+
<title id="done-flow-title">Safe worktree completion</title>
|
|
4
|
+
<desc id="done-flow-desc">Sequence showing /done waiting for Pi, requiring confirmation or explicit force, refusing unsafe normal removal, then closing workspace tabs around a conditional parent fast-forward whose failure does not stop final tab closure.</desc>
|
|
5
|
+
<defs>
|
|
6
|
+
<style>@import url('https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500;600&family=Noto+Sans+KR:wght@400;500;600&family=Noto+Serif+KR:wght@400&display=swap');</style>
|
|
7
|
+
<style>
|
|
8
|
+
.lifeline { stroke: rgba(16,24,40,.20); stroke-width: 1; stroke-dasharray: 4 4; }
|
|
9
|
+
.activation { fill: rgba(16,24,40,.06); stroke: #4c5665; stroke-width: .8; }
|
|
10
|
+
.fragment { fill: rgba(16,24,40,.02); stroke: rgba(16,24,40,.24); stroke-width: 1; }
|
|
11
|
+
.fragment-tab { fill: #f0eee9; stroke: rgba(16,24,40,.24); stroke-width: 1; }
|
|
12
|
+
.fragment-label { fill: #4c5665; font: 500 8px 'Geist Mono', monospace; text-anchor: middle; letter-spacing: .12em; }
|
|
13
|
+
.guard { fill: #4c5665; font: 400 8px 'Geist Mono', monospace; letter-spacing: .04em; }
|
|
14
|
+
.gate-badge { fill: rgba(29,78,216,.08); stroke: #1d4ed8; stroke-width: 1; }
|
|
15
|
+
.gate-label { fill: #1d4ed8; font: 500 8px 'Geist Mono', monospace; text-anchor: middle; letter-spacing: .08em; }
|
|
16
|
+
.message { fill: none; stroke: #4c5665; stroke-width: 1.2; marker-end: url(#done-flow-arrow); }
|
|
17
|
+
.message-return { fill: none; stroke: #4c5665; stroke-width: 1.2; stroke-dasharray: 4 4; marker-end: url(#done-flow-arrow); }
|
|
18
|
+
.message-accent { fill: none; stroke: #1d4ed8; stroke-width: 1.4; marker-end: url(#done-flow-arrow-accent); }
|
|
19
|
+
.label-mask { fill: #f0eee9; }
|
|
20
|
+
.message-label { fill: #4c5665; font: 400 8px 'Geist Mono', monospace; text-anchor: middle; letter-spacing: .04em; }
|
|
21
|
+
.message-label-accent { fill: #1d4ed8; font: 500 8px 'Geist Mono', monospace; text-anchor: middle; letter-spacing: .04em; }
|
|
22
|
+
.actor { fill: #fff; stroke: #101828; stroke-width: 1; }
|
|
23
|
+
.actor-input { fill: rgba(76,86,101,.10); stroke: #6a7282; stroke-width: 1; }
|
|
24
|
+
.actor-state { fill: rgba(16,24,40,.05); stroke: #4c5665; stroke-width: 1; }
|
|
25
|
+
.actor-name { fill: #101828; font: 600 12px 'Geist', sans-serif; text-anchor: middle; }
|
|
26
|
+
.actor-sub { fill: #4c5665; font: 400 9px 'Geist Mono', monospace; text-anchor: middle; letter-spacing: .04em; }
|
|
27
|
+
.boundary { stroke: rgba(16,24,40,.24); stroke-width: 1; stroke-dasharray: 4 4; }
|
|
28
|
+
.boundary-label { fill: #4c5665; font: 500 8px 'Geist Mono', monospace; text-anchor: middle; letter-spacing: .08em; }
|
|
29
|
+
.legend-label { fill: #4c5665; font: 400 8px 'Geist', sans-serif; }
|
|
30
|
+
.legend-title { fill: #6a7282; font: 500 8px 'Geist Mono', monospace; letter-spacing: .16em; }
|
|
31
|
+
</style>
|
|
32
|
+
<marker id="done-flow-arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto">
|
|
33
|
+
<polygon points="0 0,8 3,0 6" fill="#4c5665"/>
|
|
34
|
+
</marker>
|
|
35
|
+
<marker id="done-flow-arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto">
|
|
36
|
+
<polygon points="0 0,8 3,0 6" fill="#1d4ed8"/>
|
|
37
|
+
</marker>
|
|
38
|
+
<marker id="done-flow-arrow-link" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto">
|
|
39
|
+
<polygon points="0 0,8 3,0 6" fill="#1d4ed8"/>
|
|
40
|
+
</marker>
|
|
41
|
+
</defs>
|
|
42
|
+
|
|
43
|
+
<rect width="1280" height="720" fill="#f0eee9"/>
|
|
44
|
+
|
|
45
|
+
<!-- Combined fragment frame and region divider -->
|
|
46
|
+
<rect class="fragment" x="120" y="200" width="544" height="232" rx="4"/>
|
|
47
|
+
<line x1="128" y1="352" x2="656" y2="352" stroke="rgba(16,24,40,.20)" stroke-width="1" stroke-dasharray="4 4"/>
|
|
48
|
+
|
|
49
|
+
<!-- Lifelines -->
|
|
50
|
+
<line class="lifeline" x1="136" y1="96" x2="136" y2="624"/>
|
|
51
|
+
<line class="lifeline" x1="404" y1="96" x2="404" y2="624"/>
|
|
52
|
+
<line class="lifeline" x1="652" y1="96" x2="652" y2="624"/>
|
|
53
|
+
<line class="lifeline" x1="1124" y1="96" x2="1124" y2="624"/>
|
|
54
|
+
|
|
55
|
+
<!-- Activation bars -->
|
|
56
|
+
<rect class="activation" x="400" y="124" width="8" height="476"/>
|
|
57
|
+
<rect class="activation" x="648" y="304" width="8" height="32"/>
|
|
58
|
+
<rect class="activation" x="648" y="456" width="8" height="16"/>
|
|
59
|
+
<rect class="activation" x="1120" y="544" width="8" height="24"/>
|
|
60
|
+
|
|
61
|
+
<!-- Fragment labels sit above lifelines for legibility -->
|
|
62
|
+
<rect class="fragment-tab" x="120" y="200" width="40" height="16" rx="4"/>
|
|
63
|
+
<text class="fragment-label" x="140" y="212">ALT</text>
|
|
64
|
+
<rect class="gate-badge" x="168" y="200" width="104" height="16" rx="4"/>
|
|
65
|
+
<text class="gate-label" x="220" y="212">SAFETY GATE</text>
|
|
66
|
+
<rect class="label-mask" x="128" y="220" width="528" height="16"/>
|
|
67
|
+
<text class="guard" x="132" y="232">[normal /done]</text>
|
|
68
|
+
<text class="guard" x="260" y="232">CONFIRM; DIRTY OR OTHER-WORKSPACE TAB USING CHECKOUT → REFUSE</text>
|
|
69
|
+
<rect class="label-mask" x="128" y="360" width="528" height="16"/>
|
|
70
|
+
<text class="guard" x="132" y="372">[explicit --force]</text>
|
|
71
|
+
<text class="guard" x="260" y="372">PERMITS FORCED REMOVAL · IRREVERSIBLE</text>
|
|
72
|
+
|
|
73
|
+
<!-- Messages: time flows downward -->
|
|
74
|
+
<line class="message" x1="136" y1="124" x2="400" y2="124"/>
|
|
75
|
+
<rect class="label-mask" x="200" y="104" width="136" height="12" rx="4"/>
|
|
76
|
+
<text class="message-label" x="268" y="112">RUN /DONE [--FORCE]</text>
|
|
77
|
+
|
|
78
|
+
<path class="message" d="M408 148 H452 Q460 148 460 156 V172 Q460 180 452 180 H412"/>
|
|
79
|
+
<rect class="label-mask" x="468" y="156" width="112" height="12" rx="4"/>
|
|
80
|
+
<text class="message-label" x="524" y="164">WAIT FOR PI IDLE</text>
|
|
81
|
+
|
|
82
|
+
<line class="message" x1="400" y1="256" x2="136" y2="256"/>
|
|
83
|
+
<rect class="label-mask" x="208" y="236" width="120" height="12" rx="4"/>
|
|
84
|
+
<text class="message-label" x="268" y="244">CONFIRM REMOVAL?</text>
|
|
85
|
+
|
|
86
|
+
<line class="message-return" x1="136" y1="280" x2="400" y2="280"/>
|
|
87
|
+
<rect class="label-mask" x="228" y="260" width="80" height="12" rx="4"/>
|
|
88
|
+
<text class="message-label" x="268" y="268">CONFIRMED</text>
|
|
89
|
+
|
|
90
|
+
<line class="message" x1="408" y1="304" x2="648" y2="304"/>
|
|
91
|
+
<rect class="label-mask" x="480" y="284" width="96" height="12" rx="4"/>
|
|
92
|
+
<text class="message-label" x="528" y="292">CHECK SAFETY</text>
|
|
93
|
+
|
|
94
|
+
<line class="message-return" x1="648" y1="328" x2="408" y2="328"/>
|
|
95
|
+
<rect class="label-mask" x="484" y="308" width="88" height="12" rx="4"/>
|
|
96
|
+
<text class="message-label" x="528" y="316">CLEAR / REFUSE</text>
|
|
97
|
+
|
|
98
|
+
<path class="message" d="M408 396 H452 Q460 396 460 404 V412 Q460 420 452 420 H412"/>
|
|
99
|
+
<rect class="label-mask" x="468" y="400" width="104" height="12" rx="4"/>
|
|
100
|
+
<text class="message-label" x="520" y="408">ACCEPT --FORCE</text>
|
|
101
|
+
|
|
102
|
+
<line class="message-accent" x1="408" y1="464" x2="648" y2="464"/>
|
|
103
|
+
<rect class="label-mask" x="448" y="436" width="160" height="20" rx="4"/>
|
|
104
|
+
<text class="message-label-accent" x="528" y="444">CLEAR OR EXPLICIT FORCE</text>
|
|
105
|
+
<text class="message-label-accent" x="528" y="452">REMOVE WORKTREE</text>
|
|
106
|
+
|
|
107
|
+
<!-- Successful removal is the partial-success boundary -->
|
|
108
|
+
<line class="boundary" x1="40" y1="488" x2="392" y2="488"/>
|
|
109
|
+
<line class="boundary" x1="888" y1="488" x2="1240" y2="488"/>
|
|
110
|
+
<text class="boundary-label" x="640" y="492">PARTIAL-SUCCESS BOUNDARY · WORKTREE REMOVED</text>
|
|
111
|
+
|
|
112
|
+
<line class="message" x1="400" y1="516" x2="136" y2="516"/>
|
|
113
|
+
<rect class="label-mask" x="180" y="496" width="176" height="12" rx="4"/>
|
|
114
|
+
<text class="message-label" x="268" y="504">CLOSE OTHER WORKSPACE TABS</text>
|
|
115
|
+
|
|
116
|
+
<line class="message" x1="408" y1="544" x2="1120" y2="544"/>
|
|
117
|
+
<rect class="label-mask" x="684" y="516" width="160" height="20" rx="4"/>
|
|
118
|
+
<text class="message-label" x="764" y="524">IF LINKED + NON-BARE PRIMARY</text>
|
|
119
|
+
<text class="message-label" x="764" y="532">LOCK + FAST-FORWARD ONLY</text>
|
|
120
|
+
|
|
121
|
+
<line class="message-return" x1="1120" y1="568" x2="408" y2="568"/>
|
|
122
|
+
<rect class="label-mask" x="696" y="548" width="136" height="12" rx="4"/>
|
|
123
|
+
<text class="message-label" x="764" y="556">UPDATED OR FAILED</text>
|
|
124
|
+
|
|
125
|
+
<line class="message" x1="400" y1="600" x2="136" y2="600"/>
|
|
126
|
+
<rect class="label-mask" x="184" y="580" width="168" height="12" rx="4"/>
|
|
127
|
+
<text class="message-label" x="268" y="588">ALWAYS CLOSE CURRENT TAB</text>
|
|
128
|
+
|
|
129
|
+
<!-- Actors are drawn after messages -->
|
|
130
|
+
<rect x="56" y="40" width="160" height="56" rx="6" fill="#f0eee9"/>
|
|
131
|
+
<rect class="actor-input" x="56" y="40" width="160" height="56" rx="6"/>
|
|
132
|
+
<text class="actor-name" x="136" y="68">Herdr workspace</text>
|
|
133
|
+
<text class="actor-sub" x="136" y="84">CURRENT + OTHER TABS</text>
|
|
134
|
+
|
|
135
|
+
<rect x="324" y="40" width="160" height="56" rx="6" fill="#f0eee9"/>
|
|
136
|
+
<rect class="actor" x="324" y="40" width="160" height="56" rx="6"/>
|
|
137
|
+
<text class="actor-name" x="404" y="68">Pi /done</text>
|
|
138
|
+
<text class="actor-sub" x="404" y="84">IDLE BEFORE CLEANUP</text>
|
|
139
|
+
|
|
140
|
+
<rect x="572" y="40" width="160" height="56" rx="6" fill="#f0eee9"/>
|
|
141
|
+
<rect class="actor-state" x="572" y="40" width="160" height="56" rx="6"/>
|
|
142
|
+
<text class="actor-name" x="652" y="68">Removal gate</text>
|
|
143
|
+
<text class="actor-sub" x="652" y="84">WORKTREE + TAB USE</text>
|
|
144
|
+
|
|
145
|
+
<rect x="1044" y="40" width="160" height="56" rx="6" fill="#f0eee9"/>
|
|
146
|
+
<rect class="actor" x="1044" y="40" width="160" height="56" rx="6"/>
|
|
147
|
+
<text class="actor-name" x="1124" y="68">Parent checkout</text>
|
|
148
|
+
<text class="actor-sub" x="1124" y="84">CONDITIONAL UPDATE</text>
|
|
149
|
+
|
|
150
|
+
<!-- Legend strip -->
|
|
151
|
+
<line x1="40" y1="640" x2="1240" y2="640" stroke="rgba(16,24,40,.141)" stroke-width=".8"/>
|
|
152
|
+
<text class="legend-title" x="40" y="668">LEGEND</text>
|
|
153
|
+
|
|
154
|
+
<line class="message" x1="128" y1="664" x2="164" y2="664"/>
|
|
155
|
+
<text class="legend-label" x="176" y="668">Action</text>
|
|
156
|
+
|
|
157
|
+
<line class="message-return" x1="264" y1="664" x2="300" y2="664"/>
|
|
158
|
+
<text class="legend-label" x="312" y="668">Return or result</text>
|
|
159
|
+
|
|
160
|
+
<rect class="fragment" x="448" y="656" width="32" height="16" rx="4"/>
|
|
161
|
+
<text class="fragment-label" x="464" y="668">ALT</text>
|
|
162
|
+
<text class="legend-label" x="492" y="668">Safety branch</text>
|
|
163
|
+
|
|
164
|
+
<line class="message-accent" x1="624" y1="664" x2="660" y2="664"/>
|
|
165
|
+
<text class="legend-label" x="672" y="668">Successful removal</text>
|
|
166
|
+
</svg>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@henryqw/pi-herdr-done",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Close and remove the current Herdr worktree from Pi.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
"files": [
|
|
17
17
|
"LICENSE",
|
|
18
18
|
"extensions",
|
|
19
|
-
"README.md"
|
|
19
|
+
"README.md",
|
|
20
|
+
"docs/done-flow.svg"
|
|
20
21
|
],
|
|
21
22
|
"scripts": {
|
|
22
23
|
"test": "node --test test/*.test.ts",
|