@biffo/cli 0.247.9 → 0.248.1
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/package.json +1 -1
- package/scripts/claim.sh +79 -2
package/package.json
CHANGED
package/scripts/claim.sh
CHANGED
|
@@ -91,6 +91,9 @@ set -u
|
|
|
91
91
|
|
|
92
92
|
ISSUE=""
|
|
93
93
|
REPO=""
|
|
94
|
+
HOLDER=""
|
|
95
|
+
RELEASE=""
|
|
96
|
+
HOLDER_MARK="claim-holder:"
|
|
94
97
|
CHECK_ONLY=""
|
|
95
98
|
GUARD_BRANCH=""
|
|
96
99
|
|
|
@@ -106,6 +109,15 @@ while [ $# -gt 0 ]; do
|
|
|
106
109
|
shift 2
|
|
107
110
|
;;
|
|
108
111
|
--check) CHECK_ONLY=1; shift ;;
|
|
112
|
+
--as)
|
|
113
|
+
HOLDER="${2:-}"
|
|
114
|
+
shift 2
|
|
115
|
+
;;
|
|
116
|
+
--release)
|
|
117
|
+
HOLDER="${2:-}"
|
|
118
|
+
RELEASE=1
|
|
119
|
+
shift 2
|
|
120
|
+
;;
|
|
109
121
|
--guard)
|
|
110
122
|
GUARD_BRANCH="${2:-}"
|
|
111
123
|
shift 2
|
|
@@ -128,6 +140,23 @@ gh_issue() { if [ -n "$REPO" ]; then gh issue "$@" --repo "$REPO"; else gh issue
|
|
|
128
140
|
gh_pr() { if [ -n "$REPO" ]; then gh pr "$@" --repo "$REPO"; else gh pr "$@"; fi; }
|
|
129
141
|
gh_label() { if [ -n "$REPO" ]; then gh label "$@" --repo "$REPO"; else gh label "$@"; fi; }
|
|
130
142
|
|
|
143
|
+
# Does the newest claim comment on $1 carry holder token $2? (#1279)
|
|
144
|
+
#
|
|
145
|
+
# Reads the LAST claim comment rather than any, so a re-claim by a different
|
|
146
|
+
# session supersedes an older one rather than both matching for ever. Returns
|
|
147
|
+
# non-zero when it cannot tell -- an unreadable comment list must never read as
|
|
148
|
+
# "yours", or the flag becomes a way to steal a claim by guessing.
|
|
149
|
+
claim_held_by() {
|
|
150
|
+
_c=$(gh_issue view "$1" --json comments \
|
|
151
|
+
--jq "[.comments[]? | select(.body | contains(\"$HOLDER_MARK\"))] | last | .body // \"\"" \
|
|
152
|
+
2>/dev/null) || return 1
|
|
153
|
+
[ -n "$_c" ] || return 1
|
|
154
|
+
case "$_c" in
|
|
155
|
+
*"$HOLDER_MARK$2"*) return 0 ;;
|
|
156
|
+
*) return 1 ;;
|
|
157
|
+
esac
|
|
158
|
+
}
|
|
159
|
+
|
|
131
160
|
# This repo as `owner/name`, so a closing reference can be checked against it.
|
|
132
161
|
# GitHub records a CROSS-REPO closing reference in the same list as a local one
|
|
133
162
|
# -- tabsii-lms#43 closes tabsii-platform#553 -- so the number alone is not an
|
|
@@ -167,11 +196,51 @@ remote_branches() {
|
|
|
167
196
|
}
|
|
168
197
|
|
|
169
198
|
LABEL=in-progress
|
|
199
|
+
|
|
200
|
+
# --- holder identity (#1279) -------------------------------------------------
|
|
201
|
+
#
|
|
202
|
+
# A claim used to record WHEN and WHO, and every session on a workstation claims
|
|
203
|
+
# under the same GitHub actor. So a delegated agent could not distinguish
|
|
204
|
+
# "my orchestrator claimed this for me" from "a stranger claimed it 90 seconds
|
|
205
|
+
# ago", and the safe reading is to stop. On 2026-08-04 four agents were
|
|
206
|
+
# dispatched onto pre-claimed issues; one ran the check first and correctly
|
|
207
|
+
# refused to start, producing nothing. Whether a delegate works or stalls
|
|
208
|
+
# depended on whether it happened to check before starting.
|
|
209
|
+
#
|
|
210
|
+
# `--as <token>` makes the claim answerable: an existing claim carrying the same
|
|
211
|
+
# token reads as YOUR claim and returns free. `--release <token>` refuses to
|
|
212
|
+
# clear somebody else's.
|
|
213
|
+
#
|
|
214
|
+
# The token is opaque and never a secret -- it identifies a session, not a
|
|
215
|
+
# person, and appears in a public comment.
|
|
216
|
+
|
|
170
217
|
TAKEN=0
|
|
171
218
|
REASONS=""
|
|
172
219
|
|
|
173
220
|
note() { REASONS="${REASONS} $1\n"; TAKEN=1; }
|
|
174
221
|
|
|
222
|
+
# --- --release <token>: only the holder clears it (#1279) --------------------
|
|
223
|
+
#
|
|
224
|
+
# A claim nobody can prove ownership of is one anybody can clear, and a stale
|
|
225
|
+
# label left behind by a crashed session is indistinguishable from a live one.
|
|
226
|
+
# Refusing a mismatched release is what makes the token worth recording.
|
|
227
|
+
if [ -n "$RELEASE" ]; then
|
|
228
|
+
if claim_held_by "$ISSUE" "$HOLDER"; then
|
|
229
|
+
gh_issue edit "$ISSUE" --remove-label "$LABEL" >/dev/null 2>&1 || {
|
|
230
|
+
echo "${RED}claim: could not remove the '$LABEL' label.${OFF}" >&2
|
|
231
|
+
exit 2
|
|
232
|
+
}
|
|
233
|
+
echo "${GREEN}Released.${OFF} ${DIM}(held by $HOLDER)${OFF}"
|
|
234
|
+
exit 0
|
|
235
|
+
fi
|
|
236
|
+
echo "${RED}claim: #$ISSUE is not held by '$HOLDER' — refusing to release it.${OFF}" >&2
|
|
237
|
+
echo "${DIM} Clearing somebody else's claim is how two sessions end up on one issue.${OFF}" >&2
|
|
238
|
+
echo "${DIM} If the claim is genuinely stale (AGENTS.md: over an hour, no branch, no PR),${OFF}" >&2
|
|
239
|
+
echo "${DIM} remove the label by hand and say so in a comment.${OFF}" >&2
|
|
240
|
+
exit 1
|
|
241
|
+
fi
|
|
242
|
+
|
|
243
|
+
|
|
175
244
|
# --- --guard <branch>: the enforced pre-push gate -----------------------------
|
|
176
245
|
#
|
|
177
246
|
# Deliberately short-circuits before any of the four-signal machinery below —
|
|
@@ -290,7 +359,15 @@ fi
|
|
|
290
359
|
case ",$labels," in
|
|
291
360
|
*",$LABEL,"*)
|
|
292
361
|
updated=$(gh_issue view "$ISSUE" --json updatedAt --jq .updatedAt 2>/dev/null)
|
|
293
|
-
|
|
362
|
+
# Whose claim is it? (#1279) A claim carrying OUR token is not a collision --
|
|
363
|
+
# it is the orchestrator that dispatched us. Without this a delegated agent
|
|
364
|
+
# cannot tell its own reservation from a stranger's and correctly refuses to
|
|
365
|
+
# start, which is the failure this flag exists to remove.
|
|
366
|
+
if [ -n "$HOLDER" ] && claim_held_by "$ISSUE" "$HOLDER"; then
|
|
367
|
+
echo "${DIM}label carries '$LABEL', held by ${HOLDER} — that is you${OFF}"
|
|
368
|
+
else
|
|
369
|
+
note "${YELLOW}label${OFF} carries '$LABEL' (issue last updated $updated)"
|
|
370
|
+
fi
|
|
294
371
|
;;
|
|
295
372
|
esac
|
|
296
373
|
|
|
@@ -388,7 +465,7 @@ gh_issue edit "$ISSUE" --add-label "$LABEL" >/dev/null 2>&1 || {
|
|
|
388
465
|
exit 2
|
|
389
466
|
}
|
|
390
467
|
gh_issue comment "$ISSUE" \
|
|
391
|
-
--body "Claimed at $(date -u +%FT%TZ) by \`$(git config user.name 2>/dev/null || echo agent)
|
|
468
|
+
--body "Claimed at $(date -u +%FT%TZ) by \`$(git config user.name 2>/dev/null || echo agent)\`.${HOLDER:+ ${HOLDER_MARK}${HOLDER}} Release it — remove the label — on merge, or if you stop." \
|
|
392
469
|
>/dev/null 2>&1
|
|
393
470
|
|
|
394
471
|
echo "${GREEN}Claimed.${OFF}"
|