@integrity-labs/agt-cli 0.28.830 → 0.28.832

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.
@@ -30289,10 +30289,19 @@ var UNDELIVERABLE_NOTICE_THROTTLE_MS = 5 * 60 * 1e3;
30289
30289
  function shouldPostUndeliverableNotice(lastNoticeAtMs, nowMs, throttleMs = UNDELIVERABLE_NOTICE_THROTTLE_MS) {
30290
30290
  return lastNoticeAtMs == null || nowMs - lastNoticeAtMs >= throttleMs;
30291
30291
  }
30292
- function undeliverableNoticeText(replay = channelReplayEnabled()) {
30293
- return noticePromiseIsHonest(replay) ? "\u23F3 I can't get to this right now \u2014 no need to resend; I'll pick it up automatically as soon as I'm free." : "\u23F3 I can't get to this right now. Please resend in a few minutes \u2014 I may not see this one.";
30292
+ function undeliverableNoticeText(replay) {
30293
+ const honest = noticePromiseIsHonest(replay);
30294
+ return honest ? "\u23F3 I can't get to this right now \u2014 no need to resend; I'll pick it up automatically as soon as I'm free." : "\u23F3 I can't get to this right now. Please resend in a few minutes \u2014 I may not see this one.";
30295
+ }
30296
+ function undeliverableNoticeTextForRepeat(i) {
30297
+ if (i.priorNotices <= 0) return undeliverableNoticeText(i.replay);
30298
+ if (i.priorNotices === 1) {
30299
+ return noticePromiseIsHonest(i.replay) ? "\u23F3 Still stuck on this one \u2014 the automatic pickup I mentioned has not happened. Please resend when you can." : "\u23F3 Still stuck on this one, and I still have not picked it up. Resending is the reliable way through.";
30300
+ }
30301
+ return null;
30294
30302
  }
30295
30303
  function noticePromiseIsHonest(replay) {
30304
+ if (replay === void 0) return false;
30296
30305
  if (typeof replay === "boolean") return replay;
30297
30306
  return markerReplayable({
30298
30307
  enabled: replay.enabled ?? channelReplayEnabled(),
@@ -30383,6 +30392,13 @@ function channelReplayEnabled() {
30383
30392
  defaultValue: true
30384
30393
  });
30385
30394
  }
30395
+ function combineMarkerReplayFacts(markers) {
30396
+ if (markers.length === 0) return null;
30397
+ return {
30398
+ hasPayload: markers.every((m) => m.hasPayload),
30399
+ discretionary: markers.some((m) => m.discretionary === true)
30400
+ };
30401
+ }
30386
30402
  function markerReplayable(i) {
30387
30403
  if (!i.enabled) return false;
30388
30404
  if (!i.hasPayload) return false;
@@ -39696,6 +39712,7 @@ await mcp.connect(new StdioServerTransport());
39696
39712
  var processedIds = /* @__PURE__ */ new Set();
39697
39713
  var lastBusyAckNoticeAt = /* @__PURE__ */ new Map();
39698
39714
  var lastUndeliverableNoticeAt = /* @__PURE__ */ new Map();
39715
+ var undeliverableNoticeCount = /* @__PURE__ */ new Map();
39699
39716
  var lastTurnFailedNoticeAt = /* @__PURE__ */ new Map();
39700
39717
  async function postDirectChatNoticeMessage(sessionId, content) {
39701
39718
  try {
@@ -39730,14 +39747,47 @@ function postDirectChatBusyAckNotice(sessionId) {
39730
39747
  }
39731
39748
  })();
39732
39749
  }
39750
+ function directChatSessionReplayFacts(sessionId) {
39751
+ if (!DIRECT_CHAT_PENDING_INBOUND_DIR) return null;
39752
+ const found = [];
39753
+ try {
39754
+ clearDirectChatPendingMarkersForSession(
39755
+ DIRECT_CHAT_PENDING_INBOUND_DIR,
39756
+ sessionId,
39757
+ (fullPath) => {
39758
+ try {
39759
+ const marker = JSON.parse(readFileSync11(fullPath, "utf-8"));
39760
+ found.push({ hasPayload: Boolean(marker.payload), discretionary: marker.discretionary });
39761
+ } catch {
39762
+ found.push({ hasPayload: false });
39763
+ }
39764
+ }
39765
+ );
39766
+ } catch {
39767
+ return null;
39768
+ }
39769
+ const facts = combineMarkerReplayFacts(found);
39770
+ return facts ? { enabled: channelReplayEnabled(), ...facts } : null;
39771
+ }
39733
39772
  function postDirectChatUndeliverableNotice(sessionId) {
39734
39773
  const now = Date.now();
39735
39774
  if (!shouldPostUndeliverableNotice(lastUndeliverableNoticeAt.get(sessionId), now)) {
39736
39775
  return;
39737
39776
  }
39738
39777
  lastUndeliverableNoticeAt.set(sessionId, now);
39778
+ const text = undeliverableNoticeTextForRepeat({
39779
+ replay: directChatSessionReplayFacts(sessionId) ?? void 0,
39780
+ priorNotices: undeliverableNoticeCount.get(sessionId) ?? 0
39781
+ });
39782
+ if (text === null) {
39783
+ lastUndeliverableNoticeAt.delete(sessionId);
39784
+ return;
39785
+ }
39739
39786
  void (async () => {
39740
- const ok = await postDirectChatNoticeMessage(sessionId, undeliverableNoticeText());
39787
+ const ok = await postDirectChatNoticeMessage(sessionId, text);
39788
+ if (ok) {
39789
+ undeliverableNoticeCount.set(sessionId, (undeliverableNoticeCount.get(sessionId) ?? 0) + 1);
39790
+ }
39741
39791
  if (!ok) {
39742
39792
  lastUndeliverableNoticeAt.delete(sessionId);
39743
39793
  process.stderr.write(
@@ -38414,10 +38414,19 @@ function undeliverableNoticeEligible(shouldEngage) {
38414
38414
  function shouldPostUndeliverableNotice(lastNoticeAtMs, nowMs, throttleMs = UNDELIVERABLE_NOTICE_THROTTLE_MS) {
38415
38415
  return lastNoticeAtMs == null || nowMs - lastNoticeAtMs >= throttleMs;
38416
38416
  }
38417
- function undeliverableNoticeText(replay = channelReplayEnabled()) {
38418
- return noticePromiseIsHonest(replay) ? "\u23F3 I can't get to this right now \u2014 no need to resend; I'll pick it up automatically as soon as I'm free." : "\u23F3 I can't get to this right now. Please resend in a few minutes \u2014 I may not see this one.";
38417
+ function undeliverableNoticeText(replay) {
38418
+ const honest = noticePromiseIsHonest(replay);
38419
+ return honest ? "\u23F3 I can't get to this right now \u2014 no need to resend; I'll pick it up automatically as soon as I'm free." : "\u23F3 I can't get to this right now. Please resend in a few minutes \u2014 I may not see this one.";
38420
+ }
38421
+ function undeliverableNoticeTextForRepeat(i) {
38422
+ if (i.priorNotices <= 0) return undeliverableNoticeText(i.replay);
38423
+ if (i.priorNotices === 1) {
38424
+ return noticePromiseIsHonest(i.replay) ? "\u23F3 Still stuck on this one \u2014 the automatic pickup I mentioned has not happened. Please resend when you can." : "\u23F3 Still stuck on this one, and I still have not picked it up. Resending is the reliable way through.";
38425
+ }
38426
+ return null;
38419
38427
  }
38420
38428
  function noticePromiseIsHonest(replay) {
38429
+ if (replay === void 0) return false;
38421
38430
  if (typeof replay === "boolean") return replay;
38422
38431
  return markerReplayable({
38423
38432
  enabled: replay.enabled ?? channelReplayEnabled(),
@@ -38452,6 +38461,13 @@ var UndeliverableNoticeScheduler = class {
38452
38461
  }
38453
38462
  /** decision-time stamps, keyed by conversation. Shared with other one-per-window system notices. */
38454
38463
  stamps = /* @__PURE__ */ new Map();
38464
+ /**
38465
+ * ENG-9413 AC4 — how many notices have actually been POSTED for this
38466
+ * conversation. Distinct from `stamps`, which is a decision-time throttle and
38467
+ * is dropped by `cancel()`: a notice that was scheduled and cancelled was
38468
+ * never seen by anyone and must not count toward escalation.
38469
+ */
38470
+ sent = /* @__PURE__ */ new Map();
38455
38471
  /** scheduled-but-unsent notices, keyed by conversation. */
38456
38472
  timers = /* @__PURE__ */ new Map();
38457
38473
  /** is a notice scheduled but not yet sent for this conversation? */
@@ -38462,6 +38478,30 @@ var UndeliverableNoticeScheduler = class {
38462
38478
  stampedAt(key2) {
38463
38479
  return this.stamps.get(key2);
38464
38480
  }
38481
+ /**
38482
+ * ENG-9413 AC4 — notices already POSTED for this conversation. Read by the
38483
+ * channel's send callback to pick escalated copy, or to say nothing at all.
38484
+ * The count is incremented AFTER `send` runs, so inside the callback this is
38485
+ * the number of PRIOR notices.
38486
+ */
38487
+ noticeCount(key2) {
38488
+ return this.sent.get(key2) ?? 0;
38489
+ }
38490
+ /**
38491
+ * ENG-9413 AC4 — record that a notice was CONFIRMED delivered.
38492
+ *
38493
+ * Called by the channel, not by `dispatch`, and that is the correction.
38494
+ * `dispatch`'s `send` is `() => void`: it returns before the Slack or Telegram
38495
+ * request completes, so incrementing there counted posts that never landed. A
38496
+ * failed post would then advance the escalation — the user's SECOND notice
38497
+ * would arrive worded as though they had already seen a first, and their third
38498
+ * would be suppressed entirely, on the strength of notices that were never
38499
+ * delivered. Raised in review on this PR; direct chat already got this right
38500
+ * by incrementing only on `ok`, and the shared scheduler now matches it.
38501
+ */
38502
+ noteDelivered(key2) {
38503
+ this.sent.set(key2, this.noticeCount(key2) + 1);
38504
+ }
38465
38505
  /**
38466
38506
  * ENG-6025: claim this conversation's one-notice-per-window slot for a
38467
38507
  * DIFFERENT system notice (the watchdog give-up line). Returns false when the
@@ -38533,6 +38573,7 @@ var UndeliverableNoticeScheduler = class {
38533
38573
  for (const timer of this.timers.values()) clearTimeout(timer);
38534
38574
  this.timers.clear();
38535
38575
  this.stamps.clear();
38576
+ this.sent.clear();
38536
38577
  }
38537
38578
  clearTimer(key2) {
38538
38579
  const timer = this.timers.get(key2);
@@ -38706,6 +38747,13 @@ function channelReplayEnabled() {
38706
38747
  defaultValue: true
38707
38748
  });
38708
38749
  }
38750
+ function combineMarkerReplayFacts(markers) {
38751
+ if (markers.length === 0) return null;
38752
+ return {
38753
+ hasPayload: markers.every((m) => m.hasPayload),
38754
+ discretionary: markers.some((m) => m.discretionary === true)
38755
+ };
38756
+ }
38709
38757
  function markerReplayable(i) {
38710
38758
  if (!i.enabled) return false;
38711
38759
  if (!i.hasPayload) return false;
@@ -43824,8 +43872,36 @@ function postUndeliverableNotice(channel, threadTs, isThreadReply, cause = "unkn
43824
43872
  send: () => sendUndeliverableNotice(channel, threadTs, conversationKey)
43825
43873
  });
43826
43874
  }
43875
+ function slackConversationReplayFacts(channel, threadTs) {
43876
+ if (!threadTs || !SLACK_PENDING_INBOUND_DIR) return null;
43877
+ const found = [];
43878
+ try {
43879
+ markSeenAllSlackPendingMarkersForThread(
43880
+ SLACK_PENDING_INBOUND_DIR,
43881
+ channel,
43882
+ threadTs,
43883
+ (fullPath) => {
43884
+ try {
43885
+ const marker = JSON.parse(readFileSync18(fullPath, "utf-8"));
43886
+ found.push({ hasPayload: Boolean(marker.payload), discretionary: marker.discretionary });
43887
+ } catch {
43888
+ found.push({ hasPayload: false });
43889
+ }
43890
+ }
43891
+ );
43892
+ } catch {
43893
+ return null;
43894
+ }
43895
+ const facts = combineMarkerReplayFacts(found);
43896
+ return facts ? { enabled: channelReplayEnabled(), ...facts } : null;
43897
+ }
43827
43898
  function sendUndeliverableNotice(channel, threadTs, conversationKey) {
43828
43899
  if (!BOT_TOKEN || !channel) return;
43900
+ const text = undeliverableNoticeTextForRepeat({
43901
+ replay: slackConversationReplayFacts(channel, threadTs) ?? void 0,
43902
+ priorNotices: slackUndeliverableNotices.noticeCount(conversationKey)
43903
+ });
43904
+ if (text === null) return;
43829
43905
  fetch("https://slack.com/api/chat.postMessage", {
43830
43906
  method: "POST",
43831
43907
  headers: {
@@ -43834,12 +43910,13 @@ function sendUndeliverableNotice(channel, threadTs, conversationKey) {
43834
43910
  },
43835
43911
  body: JSON.stringify({
43836
43912
  channel,
43837
- text: undeliverableNoticeText(),
43913
+ text,
43838
43914
  ...threadTs ? { thread_ts: threadTs } : {}
43839
43915
  })
43840
43916
  }).then((res) => res.json()).then((data) => {
43841
43917
  if (data?.ok === true && typeof data.ts === "string" && data.ts) {
43842
43918
  lastSlackUndeliverableNoticeInfo.set(conversationKey, { channel, ts: data.ts });
43919
+ slackUndeliverableNotices.noteDelivered(conversationKey);
43843
43920
  }
43844
43921
  }).catch(() => {
43845
43922
  });
@@ -41152,10 +41152,19 @@ var UNDELIVERABLE_NOTICE_THROTTLE_MS = 5 * 60 * 1e3;
41152
41152
  function shouldPostUndeliverableNotice(lastNoticeAtMs, nowMs, throttleMs = UNDELIVERABLE_NOTICE_THROTTLE_MS) {
41153
41153
  return lastNoticeAtMs == null || nowMs - lastNoticeAtMs >= throttleMs;
41154
41154
  }
41155
- function undeliverableNoticeText(replay = channelReplayEnabled()) {
41156
- return noticePromiseIsHonest(replay) ? "\u23F3 I can't get to this right now \u2014 no need to resend; I'll pick it up automatically as soon as I'm free." : "\u23F3 I can't get to this right now. Please resend in a few minutes \u2014 I may not see this one.";
41155
+ function undeliverableNoticeText(replay) {
41156
+ const honest = noticePromiseIsHonest(replay);
41157
+ return honest ? "\u23F3 I can't get to this right now \u2014 no need to resend; I'll pick it up automatically as soon as I'm free." : "\u23F3 I can't get to this right now. Please resend in a few minutes \u2014 I may not see this one.";
41158
+ }
41159
+ function undeliverableNoticeTextForRepeat(i) {
41160
+ if (i.priorNotices <= 0) return undeliverableNoticeText(i.replay);
41161
+ if (i.priorNotices === 1) {
41162
+ return noticePromiseIsHonest(i.replay) ? "\u23F3 Still stuck on this one \u2014 the automatic pickup I mentioned has not happened. Please resend when you can." : "\u23F3 Still stuck on this one, and I still have not picked it up. Resending is the reliable way through.";
41163
+ }
41164
+ return null;
41157
41165
  }
41158
41166
  function noticePromiseIsHonest(replay) {
41167
+ if (replay === void 0) return false;
41159
41168
  if (typeof replay === "boolean") return replay;
41160
41169
  return markerReplayable({
41161
41170
  enabled: replay.enabled ?? channelReplayEnabled(),
@@ -41190,6 +41199,13 @@ var UndeliverableNoticeScheduler = class {
41190
41199
  }
41191
41200
  /** decision-time stamps, keyed by conversation. Shared with other one-per-window system notices. */
41192
41201
  stamps = /* @__PURE__ */ new Map();
41202
+ /**
41203
+ * ENG-9413 AC4 — how many notices have actually been POSTED for this
41204
+ * conversation. Distinct from `stamps`, which is a decision-time throttle and
41205
+ * is dropped by `cancel()`: a notice that was scheduled and cancelled was
41206
+ * never seen by anyone and must not count toward escalation.
41207
+ */
41208
+ sent = /* @__PURE__ */ new Map();
41193
41209
  /** scheduled-but-unsent notices, keyed by conversation. */
41194
41210
  timers = /* @__PURE__ */ new Map();
41195
41211
  /** is a notice scheduled but not yet sent for this conversation? */
@@ -41200,6 +41216,30 @@ var UndeliverableNoticeScheduler = class {
41200
41216
  stampedAt(key2) {
41201
41217
  return this.stamps.get(key2);
41202
41218
  }
41219
+ /**
41220
+ * ENG-9413 AC4 — notices already POSTED for this conversation. Read by the
41221
+ * channel's send callback to pick escalated copy, or to say nothing at all.
41222
+ * The count is incremented AFTER `send` runs, so inside the callback this is
41223
+ * the number of PRIOR notices.
41224
+ */
41225
+ noticeCount(key2) {
41226
+ return this.sent.get(key2) ?? 0;
41227
+ }
41228
+ /**
41229
+ * ENG-9413 AC4 — record that a notice was CONFIRMED delivered.
41230
+ *
41231
+ * Called by the channel, not by `dispatch`, and that is the correction.
41232
+ * `dispatch`'s `send` is `() => void`: it returns before the Slack or Telegram
41233
+ * request completes, so incrementing there counted posts that never landed. A
41234
+ * failed post would then advance the escalation — the user's SECOND notice
41235
+ * would arrive worded as though they had already seen a first, and their third
41236
+ * would be suppressed entirely, on the strength of notices that were never
41237
+ * delivered. Raised in review on this PR; direct chat already got this right
41238
+ * by incrementing only on `ok`, and the shared scheduler now matches it.
41239
+ */
41240
+ noteDelivered(key2) {
41241
+ this.sent.set(key2, this.noticeCount(key2) + 1);
41242
+ }
41203
41243
  /**
41204
41244
  * ENG-6025: claim this conversation's one-notice-per-window slot for a
41205
41245
  * DIFFERENT system notice (the watchdog give-up line). Returns false when the
@@ -41271,6 +41311,7 @@ var UndeliverableNoticeScheduler = class {
41271
41311
  for (const timer of this.timers.values()) clearTimeout(timer);
41272
41312
  this.timers.clear();
41273
41313
  this.stamps.clear();
41314
+ this.sent.clear();
41274
41315
  }
41275
41316
  clearTimer(key2) {
41276
41317
  const timer = this.timers.get(key2);
@@ -41437,6 +41478,13 @@ function channelReplayEnabled() {
41437
41478
  defaultValue: true
41438
41479
  });
41439
41480
  }
41481
+ function combineMarkerReplayFacts(markers) {
41482
+ if (markers.length === 0) return null;
41483
+ return {
41484
+ hasPayload: markers.every((m) => m.hasPayload),
41485
+ discretionary: markers.some((m) => m.discretionary === true)
41486
+ };
41487
+ }
41440
41488
  function markerReplayable(i) {
41441
41489
  if (!i.enabled) return false;
41442
41490
  if (!i.hasPayload) return false;
@@ -42064,19 +42112,40 @@ function notifyUndeliverable(chatId, messageId, cause = "unknown") {
42064
42112
  send: () => void sendUndeliverableNotice(chatId, messageId)
42065
42113
  });
42066
42114
  }
42115
+ function telegramMarkerReplayFacts(chatId, messageId) {
42116
+ const path = pendingInboundPath(chatId, messageId);
42117
+ if (!path || !existsSync9(path)) return null;
42118
+ try {
42119
+ const marker = JSON.parse(readFileSync14(path, "utf-8"));
42120
+ const facts = combineMarkerReplayFacts([
42121
+ { hasPayload: Boolean(marker.payload), discretionary: marker.discretionary }
42122
+ ]);
42123
+ return facts ? { enabled: channelReplayEnabled(), ...facts } : null;
42124
+ } catch {
42125
+ return null;
42126
+ }
42127
+ }
42067
42128
  async function sendUndeliverableNotice(chatId, messageId) {
42129
+ const text = undeliverableNoticeTextForRepeat({
42130
+ replay: telegramMarkerReplayFacts(String(chatId), String(messageId)) ?? void 0,
42131
+ priorNotices: telegramUndeliverableNotices.noticeCount(String(chatId))
42132
+ });
42133
+ if (text === null) return;
42068
42134
  try {
42069
42135
  const resp = await telegramApiCall(
42070
42136
  "sendMessage",
42071
42137
  {
42072
42138
  chat_id: chatId,
42073
42139
  // ENG-6025: shared copy with the Slack undeliverable notice.
42074
- text: undeliverableNoticeText(),
42140
+ text,
42075
42141
  reply_to_message_id: Number(messageId),
42076
42142
  allow_sending_without_reply: true
42077
42143
  },
42078
42144
  1e4
42079
42145
  );
42146
+ if (resp.ok) {
42147
+ telegramUndeliverableNotices.noteDelivered(String(chatId));
42148
+ }
42080
42149
  if (!resp.ok) {
42081
42150
  process.stderr.write(
42082
42151
  `telegram-channel(${AGENT_CODE_NAME}): undeliverable notice failed (chat=${redactId(chatId)}): ${resp.description ?? "unknown"}
@@ -49,8 +49,8 @@ import {
49
49
  writeDirectChatSessionState,
50
50
  writeEgressAllowlist,
51
51
  writePersistentClaudeWrapper
52
- } from "./chunk-N4QVPPYS.js";
53
- import "./chunk-4ZPOP7EW.js";
52
+ } from "./chunk-W4KAZQBS.js";
53
+ import "./chunk-DUOFKTAD.js";
54
54
  import "./chunk-XWVM4KPK.js";
55
55
  export {
56
56
  EGRESS_BASELINE_DOMAINS,
@@ -104,4 +104,4 @@ export {
104
104
  writeEgressAllowlist,
105
105
  writePersistentClaudeWrapper
106
106
  };
107
- //# sourceMappingURL=persistent-session-W23U7GQU.js.map
107
+ //# sourceMappingURL=persistent-session-N6FIS7UY.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  paneLogPath
3
- } from "./chunk-N4QVPPYS.js";
4
- import "./chunk-4ZPOP7EW.js";
3
+ } from "./chunk-W4KAZQBS.js";
4
+ import "./chunk-DUOFKTAD.js";
5
5
  import "./chunk-XWVM4KPK.js";
6
6
 
7
7
  // src/lib/responsiveness-probe.ts
@@ -739,4 +739,4 @@ export {
739
739
  readAndResetSlackReplyBindingClassifications,
740
740
  readAndResetSlackReplyTargetClassifications
741
741
  };
742
- //# sourceMappingURL=responsiveness-probe-IRQKIEBW.js.map
742
+ //# sourceMappingURL=responsiveness-probe-LWYJM2DK.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  sessionTranscriptDir
3
- } from "./chunk-4ZPOP7EW.js";
3
+ } from "./chunk-DUOFKTAD.js";
4
4
 
5
5
  // src/lib/session-auth-dead.ts
6
6
  import { closeSync, openSync, readSync, readdirSync, statSync } from "fs";
@@ -203,4 +203,4 @@ export {
203
203
  decideSessionAuthState,
204
204
  probeSessionAuth
205
205
  };
206
- //# sourceMappingURL=session-auth-dead-VDDXVJTX.js.map
206
+ //# sourceMappingURL=session-auth-dead-LIPEYPBX.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@integrity-labs/agt-cli",
3
- "version": "0.28.830",
3
+ "version": "0.28.832",
4
4
  "description": "Augmented Team CLI — agent provisioning and management",
5
5
  "type": "module",
6
6
  "engines": {