@adaptic/maestro 1.10.7 → 1.10.8
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/slack-responded.sh +45 -1
- package/scripts/slack-send.sh +19 -0
package/package.json
CHANGED
|
@@ -159,6 +159,49 @@ EOF
|
|
|
159
159
|
exit 1 # Not yet handled
|
|
160
160
|
;;
|
|
161
161
|
|
|
162
|
+
release)
|
|
163
|
+
# release <channel_id> <message_ts> [session_id]
|
|
164
|
+
# Releases an unconfirmed lock so a legitimate retry isn't blocked by a
|
|
165
|
+
# 24h TTL. Called by slack-send.sh's exit trap when a send fails or the
|
|
166
|
+
# script crashes after acquiring the lock but before confirming the send.
|
|
167
|
+
#
|
|
168
|
+
# Safety:
|
|
169
|
+
# - Refuse to release if the lock has been confirmed (real send happened)
|
|
170
|
+
# - If session_id is provided, only release locks owned by that session
|
|
171
|
+
# (prevents a buggy caller from blowing away a sibling's in-flight lock)
|
|
172
|
+
#
|
|
173
|
+
# Lock metadata is stored in `meta` (acquire/confirm both write to it)
|
|
174
|
+
# using the format produced by the acquire/confirm sections above:
|
|
175
|
+
# session: "<id>"
|
|
176
|
+
# status: acquired (or confirmed)
|
|
177
|
+
CHANNEL="${2:?Channel ID required}"
|
|
178
|
+
MSG_TS="${3:?Message TS required}"
|
|
179
|
+
SESSION_ID="${4:-unknown}"
|
|
180
|
+
|
|
181
|
+
LOCK_DIR="$LOCK_BASE_DIR/${CHANNEL}-${MSG_TS}"
|
|
182
|
+
META="$LOCK_DIR/meta"
|
|
183
|
+
|
|
184
|
+
if [ ! -d "$LOCK_DIR" ]; then
|
|
185
|
+
echo "NOT_HELD"
|
|
186
|
+
exit 0
|
|
187
|
+
fi
|
|
188
|
+
|
|
189
|
+
if [ -f "$META" ] && grep -qE "^status:[[:space:]]*confirmed" "$META" 2>/dev/null; then
|
|
190
|
+
echo "ALREADY_CONFIRMED"
|
|
191
|
+
exit 0
|
|
192
|
+
fi
|
|
193
|
+
|
|
194
|
+
if [ -f "$META" ] && [ "$SESSION_ID" != "unknown" ]; then
|
|
195
|
+
if ! grep -qE "^session:[[:space:]]*\"?${SESSION_ID}\"?[[:space:]]*$" "$META" 2>/dev/null; then
|
|
196
|
+
echo "NOT_OWNED"
|
|
197
|
+
exit 0
|
|
198
|
+
fi
|
|
199
|
+
fi
|
|
200
|
+
|
|
201
|
+
rm -rf "$LOCK_DIR"
|
|
202
|
+
echo "RELEASED"
|
|
203
|
+
;;
|
|
204
|
+
|
|
162
205
|
mark)
|
|
163
206
|
# mark <message_ts> — backward-compatible mark
|
|
164
207
|
MSG_TS="${2:?Message TS required}"
|
|
@@ -175,11 +218,12 @@ EOF
|
|
|
175
218
|
;;
|
|
176
219
|
|
|
177
220
|
*)
|
|
178
|
-
echo "Usage: slack-responded.sh {acquire|confirm|check|mark|clean} [args...]"
|
|
221
|
+
echo "Usage: slack-responded.sh {acquire|confirm|release|check|mark|clean} [args...]"
|
|
179
222
|
echo ""
|
|
180
223
|
echo "Commands:"
|
|
181
224
|
echo " acquire <channel> <msg_ts> [session_id] — Atomically claim a response lock"
|
|
182
225
|
echo " confirm <channel> <msg_ts> [preview] — Record successful send"
|
|
226
|
+
echo " release <channel> <msg_ts> [session_id] — Release unconfirmed lock (send failed)"
|
|
183
227
|
echo " check <msg_ts> [channel] — Check if already handled"
|
|
184
228
|
echo " mark <msg_ts> — Legacy: mark as handled"
|
|
185
229
|
echo " clean — Purge old entries"
|
package/scripts/slack-send.sh
CHANGED
|
@@ -118,6 +118,21 @@ if [ -n "$RESPONDING_TO" ]; then
|
|
|
118
118
|
exit 0
|
|
119
119
|
fi
|
|
120
120
|
DEDUP_ACQUIRED="1"
|
|
121
|
+
|
|
122
|
+
# Lock-release safety net. If this script exits BEFORE confirming the
|
|
123
|
+
# lock (e.g. validation failed, Slack API errored, python script crashed
|
|
124
|
+
# during message conversion, caller killed us), we must release the lock
|
|
125
|
+
# so the next legitimate retry isn't blocked for 24 hours. The trap is
|
|
126
|
+
# cleared after the post-send confirm; if the confirm runs, we leave
|
|
127
|
+
# the lock in place (it's now a real send marker, not a placeholder).
|
|
128
|
+
cleanup_unconfirmed_lock() {
|
|
129
|
+
local exit_code=$?
|
|
130
|
+
if [ -n "$DEDUP_ACQUIRED" ] && [ -z "$DEDUP_CONFIRMED" ]; then
|
|
131
|
+
"$SCRIPT_DIR/slack-responded.sh" release "$CHANNEL" "$RESPONDING_TO" "$SESSION_ID" 2>/dev/null || true
|
|
132
|
+
fi
|
|
133
|
+
return "$exit_code"
|
|
134
|
+
}
|
|
135
|
+
trap cleanup_unconfirmed_lock EXIT
|
|
121
136
|
fi
|
|
122
137
|
|
|
123
138
|
# Show typing indicator before sending (non-blocking, fire-and-forget)
|
|
@@ -230,7 +245,11 @@ if [ "$STATUS" = "invalid_auth" ] || [ "$STATUS" = "token_revoked" ] || [ "$STAT
|
|
|
230
245
|
fi
|
|
231
246
|
|
|
232
247
|
# Post-send: confirm the response lock with message details (audit trail)
|
|
248
|
+
# and mark the trap as fulfilled so the exit-handler does NOT release the
|
|
249
|
+
# now-legitimate confirmation marker. Any non-OK status leaves DEDUP_CONFIRMED
|
|
250
|
+
# unset, so the EXIT trap releases the lock for legitimate retry.
|
|
233
251
|
if [ "$STATUS" = "OK" ] && [ -n "$RESPONDING_TO" ] && [ -n "$DEDUP_ACQUIRED" ]; then
|
|
234
252
|
PREVIEW=$(echo "$MESSAGE" | head -c 200)
|
|
235
253
|
"$SCRIPT_DIR/slack-responded.sh" confirm "$CHANNEL" "$RESPONDING_TO" "$PREVIEW" 2>/dev/null || true
|
|
254
|
+
DEDUP_CONFIRMED="1"
|
|
236
255
|
fi
|