@erclx/aitk 0.111.0 → 0.111.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.
|
@@ -53,6 +53,8 @@ The baseline lives at `.claude/.tmp/pr-poll/baseline.txt` under the main worktre
|
|
|
53
53
|
|
|
54
54
|
The four review headings the script matches are written by `claude-pr-review` and `claude-address-review`. A project that posts its reviews under different headings edits the three jq filters in the script to match, or every pull request reads as never reviewed.
|
|
55
55
|
|
|
56
|
+
`RESPONSE` is qualified by recency as well as by count, so it means a reply the last pass has not already answered rather than one this script has not seen before. A worker answers a finding and the reviewing session posts its close-out seconds later, which is the ordinary handback rather than a race, so a count on its own reported the answered thread on the next run and the re-review it routed to stopped at its own guard. The state now fires when the newest reply is stamped later than the last pass, and on a pull request carrying no pass at all, which is a worker talking to nobody and worth the turn. A reply landing inside the same second as the pass is dropped, matching the comparison `claude-pr-review` makes on the same two fields.
|
|
57
|
+
|
|
56
58
|
`STALLED` is the one state the script derives from a heading rather than from a commit or a count, since `claude-pr-review` posts the open heading exactly when a dispatch is owed, per the threshold that skill states. The heading alone cannot carry it, because an open pass means a dispatch was owed and made, so the ordinary healthy thread is a worker still working. The age of that pass is the third test: the state fires when the open pass covers the head, nothing has followed it, and it is older than the `STALE_AFTER` seconds set at the top of the script. It reports once per entry and fires again after any commit or reply resets the thread. A project whose workers run longer than the default two hours raises that number.
|
|
57
59
|
|
|
58
60
|
The state reaches every stalled dispatch, since one threshold governs the heading and the dispatch alike and a pass carrying anything posts the open heading. A minors-only pass therefore reports here on the same terms as a blocking one, which widens the state from what it caught while the two were split. It stays a heading test rather than a count test, so nothing here pins the summary line, which is a second string this script does not own.
|
|
@@ -48,11 +48,19 @@ JQ_LAST_REVIEWED_HEAD='
|
|
|
48
48
|
| . == "## Review" or . == "## Review closed")
|
|
49
49
|
] | last | .commit.oid // empty
|
|
50
50
|
'
|
|
51
|
-
|
|
51
|
+
# The count alone answers whether a reply is new to this script, which is not
|
|
52
|
+
# the same question as whether it is newer than the pass it answers. The stamp
|
|
53
|
+
# of the newest reply comes out of the same selection so the recency test costs
|
|
54
|
+
# no second filter, and it is the one this file compares against `submittedAt`.
|
|
55
|
+
JQ_REPLY_STATE='
|
|
52
56
|
[ .comments[]
|
|
53
57
|
| select((.body // "") | split("\n")[0] | rtrimstr("\r")
|
|
54
58
|
| . == "## Review response" or . == "## Rebase")
|
|
55
|
-
]
|
|
59
|
+
] as $replies
|
|
60
|
+
| ($replies | length | tostring)
|
|
61
|
+
+ " "
|
|
62
|
+
+ ([ $replies[] | .createdAt // empty | fromdateiso8601 | floor ]
|
|
63
|
+
| max // 0 | tostring)
|
|
56
64
|
'
|
|
57
65
|
|
|
58
66
|
# `claude-pr-review` states the threshold and posts `## Review` exactly when a
|
|
@@ -69,18 +77,28 @@ JQ_REPLY_COUNT='
|
|
|
69
77
|
# script runs wherever the plugin is installed. A review carrying no stamp reads
|
|
70
78
|
# as age zero and classifies nothing, which is the same answer the carry-forward
|
|
71
79
|
# path gives a pull request this run could not read.
|
|
80
|
+
#
|
|
81
|
+
# The stamp itself is emitted as a third field beside the age it was derived
|
|
82
|
+
# from, because the reply test below compares against the instant rather than
|
|
83
|
+
# against the elapsed seconds. A missing stamp reads as zero there too, where it
|
|
84
|
+
# sends a reply to be reported rather than suppressed. The two readers therefore
|
|
85
|
+
# fail in opposite directions on the same absent field, since zero silences the
|
|
86
|
+
# age test above and zero is the value the reply test reports on.
|
|
72
87
|
JQ_LAST_REVIEW_STATE='
|
|
73
88
|
[ .reviews[]
|
|
74
89
|
| select((.body // "") | split("\n")[0] | rtrimstr("\r")
|
|
75
90
|
| . == "## Review" or . == "## Review closed")
|
|
76
91
|
] | last
|
|
77
|
-
| if . == null then "none 0"
|
|
78
|
-
else (
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
92
|
+
| if . == null then "none 0 0"
|
|
93
|
+
else (if .submittedAt == null then 0
|
|
94
|
+
else (.submittedAt | fromdateiso8601 | floor)
|
|
95
|
+
end) as $at
|
|
96
|
+
| ((.body | split("\n")[0] | rtrimstr("\r")
|
|
97
|
+
| if . == "## Review" then "open" else "closed" end)
|
|
98
|
+
+ " "
|
|
99
|
+
+ (if $at == 0 then "0" else (((now | floor) - $at) | tostring) end)
|
|
100
|
+
+ " "
|
|
101
|
+
+ ($at | tostring))
|
|
84
102
|
end
|
|
85
103
|
'
|
|
86
104
|
|
|
@@ -102,7 +120,10 @@ carry_forward() {
|
|
|
102
120
|
old=$(grep "^$n " "$STATE" || true)
|
|
103
121
|
if [ -n "$old" ]; then
|
|
104
122
|
# Every other classification compares a field against itself on a carried
|
|
105
|
-
# line, so it fires nothing.
|
|
123
|
+
# line, so it fires nothing. That is also what keeps the two stamps unread
|
|
124
|
+
# here: the baseline never held them, so both arrive empty, and the count
|
|
125
|
+
# test in front of them fails before either reaches a numeric comparison.
|
|
126
|
+
# STALLED reads a heading that is carried too, so
|
|
106
127
|
# the field is blanked to a value no branch matches. Echoing it intact would
|
|
107
128
|
# classify a pull request this run never reached while stderr below says the
|
|
108
129
|
# opposite, and one successful read restores it a run later. An already
|
|
@@ -146,9 +167,14 @@ snapshot() {
|
|
|
146
167
|
fi
|
|
147
168
|
|
|
148
169
|
prior=$(jq -r "$JQ_LAST_REVIEWED_HEAD" <<<"$payload")
|
|
149
|
-
|
|
150
|
-
#
|
|
151
|
-
#
|
|
170
|
+
# Split here rather than carried whole, because the count keeps the fourth
|
|
171
|
+
# column every baseline written so far already reads, and the stamp goes to
|
|
172
|
+
# the end of the line beside the pass stamp it is compared against.
|
|
173
|
+
reply_state=$(jq -r "$JQ_REPLY_STATE" <<<"$payload")
|
|
174
|
+
resp=${reply_state%% *}
|
|
175
|
+
reply_at=${reply_state##* }
|
|
176
|
+
# Three space-separated fields, so the line below carries them as its own
|
|
177
|
+
# sixth, seventh, and eighth rather than needing a split.
|
|
152
178
|
review_state=$(jq -r "$JQ_LAST_REVIEW_STATE" <<<"$payload")
|
|
153
179
|
|
|
154
180
|
# `gh pr view --json mergeable` reports UNKNOWN until GitHub finishes
|
|
@@ -168,7 +194,7 @@ snapshot() {
|
|
|
168
194
|
merges=conflict
|
|
169
195
|
fi
|
|
170
196
|
|
|
171
|
-
echo "$n $head ${prior:-none} $resp $merges $review_state"
|
|
197
|
+
echo "$n $head ${prior:-none} $resp $merges $review_state $reply_at"
|
|
172
198
|
done
|
|
173
199
|
}
|
|
174
200
|
|
|
@@ -185,7 +211,7 @@ CHANGED=0
|
|
|
185
211
|
# would fire on every later run and the board would never read "No movement."
|
|
186
212
|
FINAL=""
|
|
187
213
|
|
|
188
|
-
while read -r n head prior resp merges heading age; do
|
|
214
|
+
while read -r n head prior resp merges heading age pass_at reply_at; do
|
|
189
215
|
[ -z "$n" ] && continue
|
|
190
216
|
state=$heading
|
|
191
217
|
old=$(grep "^$n " "$STATE" || true)
|
|
@@ -244,7 +270,26 @@ while read -r n head prior resp merges heading age; do
|
|
|
244
270
|
fi
|
|
245
271
|
fi
|
|
246
272
|
CHANGED=1
|
|
247
|
-
elif [ "$resp" -gt "$old_resp" ]
|
|
273
|
+
elif [ "$resp" -gt "$old_resp" ] &&
|
|
274
|
+
{ [ "$pass_at" = 0 ] || [ "$reply_at" -gt "$pass_at" ]; }; then
|
|
275
|
+
# The count says the reply is new to this script and the stamp says it is
|
|
276
|
+
# newer than the pass, and both are needed. A worker answers a finding and
|
|
277
|
+
# the reviewing session closes out seconds later, so the count alone reports
|
|
278
|
+
# an answered thread on the next run and the session spends a turn learning
|
|
279
|
+
# `claude-pr-review` will refuse it. The gaps observed were 96, 24, and 35
|
|
280
|
+
# seconds, which is a reviewing session reading a reply and posting, so this
|
|
281
|
+
# is the ordinary handback rather than a race.
|
|
282
|
+
#
|
|
283
|
+
# A pull request carrying no pass at all reads as stamp zero and reports,
|
|
284
|
+
# which is the case the count was the right test for: a reply with nothing
|
|
285
|
+
# behind it is a worker talking to nobody and worth the turn. The test is
|
|
286
|
+
# strictly greater to match the guard `claude-pr-review` states on the same
|
|
287
|
+
# two fields, which drops a reply landing inside the same second as the
|
|
288
|
+
# pass, a narrower failure than the one it removes.
|
|
289
|
+
#
|
|
290
|
+
# The gate sits in the condition rather than in the body so a suppressed
|
|
291
|
+
# reply falls through to STALLED below, which is a thread this run should
|
|
292
|
+
# still be able to reach.
|
|
248
293
|
echo "RESPONSE #$n answered with no new commit"
|
|
249
294
|
CHANGED=1
|
|
250
295
|
elif [ "$heading" = open ] && [ "$old_heading" != reported ] &&
|