@botbuddy/cli 1.32.3 → 1.32.4
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/src/wait.mjs +24 -1
package/package.json
CHANGED
package/src/wait.mjs
CHANGED
|
@@ -55,7 +55,13 @@ CONDITIONS (TYPE:key=val,key=val — repeat for several; --any wakes on the fir
|
|
|
55
55
|
timer:duration=<seconds> wake after N seconds (DB-clocked server-side)
|
|
56
56
|
timer:deadline=<ISO-8601> wake at an absolute time
|
|
57
57
|
chat:channel=<id>|* new Direct Chat message (or * = any channel you are in;
|
|
58
|
-
you are never woken by your own messages)
|
|
58
|
+
you are never woken by your own messages). Level-
|
|
59
|
+
triggered at arm: an unread reply from another
|
|
60
|
+
participant that already exists when you arm wakes
|
|
61
|
+
the wait immediately (payload.reason=unread_at_arm),
|
|
62
|
+
so send-then-arm never misses a fast reply. Respects
|
|
63
|
+
your read marker (mark_direct_chat_read) and your own
|
|
64
|
+
last message; a sibling session's reply still wakes.
|
|
59
65
|
lock:subtype=<t>,host=<h>[,slot=<s>][,claim=true]
|
|
60
66
|
a resource lock becomes available
|
|
61
67
|
subtype ∈ playwright_lane|vite_port|backend_port|supabase_local
|
|
@@ -273,6 +279,12 @@ async function registerWait(opts, conditions, deadlineIso) {
|
|
|
273
279
|
conditions,
|
|
274
280
|
deadline: deadlineIso,
|
|
275
281
|
mode: opts.mode,
|
|
282
|
+
// BOT-1753: always sent so the relay knows this client reports its replay
|
|
283
|
+
// boundary (a pre-1.32.3 client omits the key and the relay then skips the chat
|
|
284
|
+
// arm snapshot to avoid a chained-resume duplicate). "-1" = a fresh arm; a
|
|
285
|
+
// resume sends its `--since` cursor. The relay only arm-grants messages this
|
|
286
|
+
// wait will NOT replay itself.
|
|
287
|
+
since: String(opts.since ?? -1),
|
|
276
288
|
...(opts.localWaitId ? { local_wait_id: opts.localWaitId } : {}),
|
|
277
289
|
...(opts.expectedAgentId ? {
|
|
278
290
|
expected_agent_id: opts.expectedAgentId,
|
|
@@ -422,6 +434,7 @@ async function registerWait(opts, conditions, deadlineIso) {
|
|
|
422
434
|
return {
|
|
423
435
|
waitSessionId: body.wait_session_id ?? null,
|
|
424
436
|
cursorStart: body.cursor_start ?? null,
|
|
437
|
+
chatReplayFloor: body.chat_replay_floor ?? null,
|
|
425
438
|
// BOT-1184: the server canonicalizes lock-condition hosts on register and
|
|
426
439
|
// echoes them here so the client matches the canonical subject_key.
|
|
427
440
|
conditions: Array.isArray(body.conditions) ? body.conditions : null,
|
|
@@ -1059,6 +1072,7 @@ async function resolveRecoveryWaitSession(checkpoint, { reserveMissing = false }
|
|
|
1059
1072
|
registration: {
|
|
1060
1073
|
waitSessionId: body.wait_session_id,
|
|
1061
1074
|
cursorStart: body.cursor_start ?? null,
|
|
1075
|
+
chatReplayFloor: body.chat_replay_floor ?? null,
|
|
1062
1076
|
sessionTenant: checkpoint.tenant_id ?? null,
|
|
1063
1077
|
agentId: checkpoint.agent_id ?? null,
|
|
1064
1078
|
sessionId: checkpoint.arming_session_id ?? null,
|
|
@@ -1749,6 +1763,15 @@ export async function runWait(argv, { recoveryLocalWaitId = null } = {}) {
|
|
|
1749
1763
|
// Arm from the registration high-water mark unless the caller pinned an
|
|
1750
1764
|
// explicit --since (resume). cursor_start replays the register→connect gap.
|
|
1751
1765
|
if (opts.since == null && reg.cursorStart != null) effectiveSince = String(reg.cursorStart);
|
|
1766
|
+
// BOT-1753 (Codex R7 F2): a still-unread chat arm grant a dead/sibling wait left
|
|
1767
|
+
// below our replay boundary. Replay from just before it so it isn't stranded —
|
|
1768
|
+
// for a fresh arm AND a --since resume. The relay only reports a floor for a
|
|
1769
|
+
// message that is genuinely still unread, so this never re-delivers a read reply.
|
|
1770
|
+
if (reg.chatReplayFloor != null && /^\d+$/.test(String(reg.chatReplayFloor))) {
|
|
1771
|
+
if (effectiveSince == null || BigInt(reg.chatReplayFloor) < BigInt(effectiveSince)) {
|
|
1772
|
+
effectiveSince = String(reg.chatReplayFloor);
|
|
1773
|
+
}
|
|
1774
|
+
}
|
|
1752
1775
|
checkpoint = await store.update(checkpoint.local_wait_id, {
|
|
1753
1776
|
status: "armed",
|
|
1754
1777
|
cloud_wait_session_id: waitSessionId,
|