@integrity-labs/agt-cli 0.28.936 → 0.28.938

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.
@@ -30357,10 +30357,32 @@ function matchesThirdPartyGrant(evt, thirdPartyBots) {
30357
30357
  return false;
30358
30358
  return thirdPartyBots.some((b) => b.bot_id === botId || b.bot_user_id === botId);
30359
30359
  }
30360
+ function humanEditedMessage(evt) {
30361
+ if (evt.type !== "message" || evt.subtype !== "message_changed")
30362
+ return null;
30363
+ const inner = evt.message;
30364
+ if (!inner?.edited)
30365
+ return null;
30366
+ const merged = { ...evt };
30367
+ delete merged["message"];
30368
+ delete merged["subtype"];
30369
+ for (const [k, v] of Object.entries(inner)) {
30370
+ if (k === "edited" || v === void 0)
30371
+ continue;
30372
+ merged[k] = v;
30373
+ }
30374
+ merged["type"] = "message";
30375
+ if (evt.ts !== void 0)
30376
+ merged["edit_ts"] = evt.ts;
30377
+ return merged;
30378
+ }
30360
30379
  function decideSlackMessageForward(evt, thirdPartyBots) {
30361
30380
  if (evt.type !== "message") {
30362
30381
  return { forward: true };
30363
30382
  }
30383
+ const edited = humanEditedMessage(evt);
30384
+ if (edited)
30385
+ return decideSlackMessageForward(edited, thirdPartyBots);
30364
30386
  const granted = matchesThirdPartyGrant(evt, thirdPartyBots);
30365
30387
  if (!ALLOWED_MESSAGE_SUBTYPES.has(evt.subtype)) {
30366
30388
  if (!granted || evt.subtype !== "bot_message") {
@@ -30391,6 +30413,8 @@ function isAppMentionEcho(evt, botUserId2) {
30391
30413
  function slackInboundDedupId(evt) {
30392
30414
  if (!evt.channel || !evt.ts)
30393
30415
  return null;
30416
+ if (evt.edit_ts)
30417
+ return `${evt.channel}:${evt.ts}:message_edit:${evt.edit_ts}`;
30394
30418
  return `${evt.channel}:${evt.ts}:${evt.type ?? "unknown"}`;
30395
30419
  }
30396
30420
  function decideSlackEngagement(input) {
@@ -49157,18 +49181,19 @@ async function connectSocketMode() {
49157
49181
  return;
49158
49182
  }
49159
49183
  if (msg.type !== "events_api" || !msg.payload?.event) return;
49160
- const evt = msg.payload.event;
49161
- if (evt.user === botUserId) return;
49162
- if (evt.type !== "app_mention" && evt.type !== "message") return;
49163
- if (isAppMentionEcho(evt, botUserId)) {
49164
- noteEchoDropped(mentionTwinAudit, evt.channel ?? null, evt.ts ?? null, Date.now());
49184
+ const rawEvt = msg.payload.event;
49185
+ if (rawEvt.user === botUserId) return;
49186
+ if (rawEvt.type !== "app_mention" && rawEvt.type !== "message") return;
49187
+ if (isAppMentionEcho(rawEvt, botUserId)) {
49188
+ noteEchoDropped(mentionTwinAudit, rawEvt.channel ?? null, rawEvt.ts ?? null, Date.now());
49165
49189
  recordChannelDeflection(SLACK_AGENT_DIR, "slack", "duplicate");
49166
49190
  process.stderr.write(
49167
- `slack-channel(${AGENT_CODE_NAME}): [channel-duplicate] dropped app_mention echo channel=${redactSlackId(evt.channel)} ts=${redactSlackId(evt.ts)}
49191
+ `slack-channel(${AGENT_CODE_NAME}): [channel-duplicate] dropped app_mention echo channel=${redactSlackId(rawEvt.channel)} ts=${redactSlackId(rawEvt.ts)}
49168
49192
  `
49169
49193
  );
49170
49194
  return;
49171
49195
  }
49196
+ const evt = humanEditedMessage(rawEvt) ?? rawEvt;
49172
49197
  const dedupId = slackInboundDedupId(evt);
49173
49198
  if (dedupId && markInboundDelivered("slack", dedupId)) {
49174
49199
  const isMention = evt.type === "app_mention";
@@ -49630,6 +49655,19 @@ async function connectSocketMode() {
49630
49655
  // Also inject own_bot_user_id so the agent can identify self-mentions in
49631
49656
  // future without relying on external directory lookups.
49632
49657
  ...effectiveIsAutoFollowed ? { auto_followed: "true" } : {},
49658
+ // ENG-9416: this inbound is a human EDIT of an earlier message, not a
49659
+ // new one. Slack delivered it as `message_changed`; the filter
49660
+ // unwrapped it and this carries the fact through to the agent, which
49661
+ // is the "log it distinguishably" half of the ticket - applied to the
49662
+ // ADMIT path, where there was no marker at all, rather than only to
49663
+ // the drop log.
49664
+ //
49665
+ // It matters to the reader of the message: `message_ts` is the
49666
+ // ORIGINAL's, so a reply threads correctly, and without this flag an
49667
+ // edit of a message the agent already answered is indistinguishable
49668
+ // from the user asking again. With it, the agent can say "I see you
49669
+ // edited that" instead of answering twice.
49670
+ ...evt.edit_ts ? { edited: "true" } : {},
49633
49671
  ...botUserId ? { own_bot_user_id: botUserId } : {},
49634
49672
  // Only set these when we actually have attachments to avoid
49635
49673
  // bloating every notification with empty metadata.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@integrity-labs/agt-cli",
3
- "version": "0.28.936",
3
+ "version": "0.28.938",
4
4
  "description": "Augmented Team CLI — agent provisioning and management",
5
5
  "type": "module",
6
6
  "engines": {