@integrity-labs/agt-cli 0.28.390 → 0.28.392

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.
@@ -36537,6 +36537,36 @@ function clearRestartConfirmMarker(filePath) {
36537
36537
  }
36538
36538
  }
36539
36539
 
36540
+ // src/restart-context-notice.ts
36541
+ function parseRestartContextHint(json) {
36542
+ let obj;
36543
+ try {
36544
+ obj = JSON.parse(json);
36545
+ } catch {
36546
+ return null;
36547
+ }
36548
+ if (!obj || typeof obj !== "object") return null;
36549
+ const { topic, channel, thread_ts, written_at } = obj;
36550
+ if (typeof topic !== "string" || typeof channel !== "string" || typeof thread_ts !== "string" || typeof written_at !== "string") {
36551
+ return null;
36552
+ }
36553
+ if (!topic.trim()) return null;
36554
+ return { topic, channel, thread_ts, written_at };
36555
+ }
36556
+ function resolveRestartTopic(hint, expectedChannel, expectedThreadTs) {
36557
+ if (!hint) return null;
36558
+ if (hint.channel !== expectedChannel || hint.thread_ts !== expectedThreadTs) return null;
36559
+ const topic = hint.topic.trim();
36560
+ return topic ? topic : null;
36561
+ }
36562
+ function buildStrandedInboundNoticeText(topic) {
36563
+ const trimmed = topic?.trim();
36564
+ if (trimmed) {
36565
+ return `I was restarted mid-conversation (we were discussing: "${trimmed}") and may have missed your last message. Please re-send if I didn't reply.`;
36566
+ }
36567
+ return "I was restarted mid-conversation and may have missed your last message. Please re-send if I didn't reply.";
36568
+ }
36569
+
36540
36570
  // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.27.1_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
36541
36571
  import process2 from "process";
36542
36572
 
@@ -37664,6 +37694,15 @@ function clearScheduledTurnMarker(agentDir) {
37664
37694
  }
37665
37695
  }
37666
37696
 
37697
+ // src/slack-reply-scheduled-priority.ts
37698
+ function resolveSlackScheduledPriority(opts) {
37699
+ const inboundWins = !!(opts.inboundId || opts.enforceBound);
37700
+ const effectiveChannel = inboundWins ? opts.bindingChannel ?? opts.fallbackChannel : opts.scheduledDest ? opts.scheduledDest.channel : opts.fallbackChannel;
37701
+ const effectiveThreadTs = inboundWins ? opts.bindingThreadTs ?? void 0 : opts.scheduledDest ? opts.scheduledDest.thread_ts : opts.fallbackThreadTs ?? void 0;
37702
+ const settleThreadTs = inboundWins ? opts.bindingThreadTs ?? void 0 : opts.fallbackSettleThreadTs ?? void 0;
37703
+ return { effectiveChannel, effectiveThreadTs, settleThreadTs };
37704
+ }
37705
+
37667
37706
  // src/slack-allowlist-source.ts
37668
37707
  function parseAllowedUsersCsv(raw) {
37669
37708
  return new Set(
@@ -38841,6 +38880,7 @@ function getEffectivePingAllowedUsers() {
38841
38880
  return readLivePingAllowedUsers() ?? PING_ALLOWED_USERS;
38842
38881
  }
38843
38882
  var SLACK_PENDING_INBOUND_DIR = SLACK_AGENT_DIR ? join17(SLACK_AGENT_DIR, "slack-pending-inbound") : null;
38883
+ var SLACK_RESTART_CONTEXT_DIR = SLACK_AGENT_DIR ? join17(SLACK_AGENT_DIR, "slack-restart-context") : null;
38844
38884
  var SLACK_RECOVERY_OUTBOX_DIR = SLACK_AGENT_DIR ? join17(SLACK_AGENT_DIR, "slack-recovery-outbox") : null;
38845
38885
  var SLACK_RECOVERY_LEDGER_DIR = SLACK_AGENT_DIR ? join17(SLACK_AGENT_DIR, ".agt-slack-recovery-ledger") : null;
38846
38886
  var SLACK_DELIVERY_LEDGER_DIR = SLACK_AGENT_DIR ? join17(SLACK_AGENT_DIR, ".agt-inbound-delivery-ledger") : null;
@@ -39831,9 +39871,45 @@ var STRANDED_INBOUND_MIN_AGE_FROM_BOOT_MS = 6e4;
39831
39871
  var STRANDED_INBOUND_MAX_AGE_MS = 5 * 60 * 1e3;
39832
39872
  var strandedInboundNoticeFired = false;
39833
39873
  var strandedInboundNoticeInFlight = false;
39874
+ function readRestartTopicForMarker(filename, channel, threadTs) {
39875
+ if (!SLACK_RESTART_CONTEXT_DIR) return null;
39876
+ let raw;
39877
+ try {
39878
+ raw = readFileSync17(join17(SLACK_RESTART_CONTEXT_DIR, filename), "utf-8");
39879
+ } catch {
39880
+ return null;
39881
+ }
39882
+ return resolveRestartTopic(parseRestartContextHint(raw), channel, threadTs);
39883
+ }
39884
+ function removeRestartContextHint(filename) {
39885
+ if (!SLACK_RESTART_CONTEXT_DIR) return;
39886
+ try {
39887
+ unlinkSync7(join17(SLACK_RESTART_CONTEXT_DIR, filename));
39888
+ } catch {
39889
+ }
39890
+ }
39891
+ function clearAllRestartContextHints() {
39892
+ if (!SLACK_RESTART_CONTEXT_DIR) return;
39893
+ let names;
39894
+ try {
39895
+ names = readdirSync5(SLACK_RESTART_CONTEXT_DIR);
39896
+ } catch {
39897
+ return;
39898
+ }
39899
+ for (const name of names) {
39900
+ if (!name.endsWith(".json")) continue;
39901
+ try {
39902
+ unlinkSync7(join17(SLACK_RESTART_CONTEXT_DIR, name));
39903
+ } catch {
39904
+ }
39905
+ }
39906
+ }
39834
39907
  async function notifyStrandedInboundsOnFirstConnect() {
39835
39908
  if (strandedInboundNoticeFired || strandedInboundNoticeInFlight) return;
39836
- if (channelReplayEnabled()) return;
39909
+ if (channelReplayEnabled()) {
39910
+ clearAllRestartContextHints();
39911
+ return;
39912
+ }
39837
39913
  strandedInboundNoticeInFlight = true;
39838
39914
  let hadFailure = false;
39839
39915
  try {
@@ -39869,13 +39945,15 @@ async function notifyStrandedInboundsOnFirstConnect() {
39869
39945
  unlinkSync7(fullPath);
39870
39946
  } catch {
39871
39947
  }
39948
+ removeRestartContextHint(filename);
39872
39949
  continue;
39873
39950
  }
39874
39951
  seen.add(key2);
39952
+ const topic = readRestartTopicForMarker(filename, channel, thread_ts);
39875
39953
  const res = await postSlackMessage({
39876
39954
  channel,
39877
39955
  thread_ts,
39878
- text: "I was restarted mid-conversation and may have missed your last message. Please re-send if I didn't reply."
39956
+ text: buildStrandedInboundNoticeText(topic)
39879
39957
  });
39880
39958
  if (res.ok) {
39881
39959
  notified += 1;
@@ -39883,6 +39961,7 @@ async function notifyStrandedInboundsOnFirstConnect() {
39883
39961
  unlinkSync7(fullPath);
39884
39962
  } catch {
39885
39963
  }
39964
+ removeRestartContextHint(filename);
39886
39965
  } else {
39887
39966
  hadFailure = true;
39888
39967
  process.stderr.write(
@@ -41384,6 +41463,7 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
41384
41463
  `
41385
41464
  );
41386
41465
  }
41466
+ const enforceBound = bindingMode === "enforce" && (binding.classification === "bound" || binding.classification === "coords_corrected");
41387
41467
  const scheduledMarker = readScheduledTurnMarker(SLACK_AGENT_DIR);
41388
41468
  const scheduledDest = scheduledMarker ? resolveScheduledTurnDestination(scheduledMarker, { channel, thread_ts }) : null;
41389
41469
  if (scheduledDest?.retargeted) {
@@ -41392,7 +41472,6 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
41392
41472
  `
41393
41473
  );
41394
41474
  }
41395
- const effectiveChannel = scheduledDest ? scheduledDest.channel : channelGuard.corrected && channelGuard.channel ? channelGuard.channel : channel;
41396
41475
  const effectiveMessageTs = channelGuard.corrected ? channelGuard.messageTs : message_ts;
41397
41476
  if (bindingMode === "enforce" && binding.reject && !channelGuard.corrected && !scheduledDest) {
41398
41477
  process.stderr.write(
@@ -41401,7 +41480,6 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
41401
41480
  );
41402
41481
  return { content: [{ type: "text", text: binding.reject }], isError: true };
41403
41482
  }
41404
- const enforceBound = bindingMode === "enforce" && (binding.classification === "bound" || binding.classification === "coords_corrected");
41405
41483
  if (enforceBound && binding.channel && binding.channel !== channel) {
41406
41484
  process.stderr.write(
41407
41485
  `slack-channel(${AGENT_CODE_NAME}): reply_binding_channel_mismatch_rejected class=${binding.classification} model=${redactSlackId(channel)} registry=${redactSlackId(binding.channel)}
@@ -41447,7 +41525,16 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
41447
41525
  }
41448
41526
  }
41449
41527
  }
41450
- const effectiveThreadTs = scheduledDest ? scheduledDest.thread_ts : enforceBound ? binding.threadTs : channelGuard.corrected ? channelGuard.threadTs : hotThreadMode === "enforce" && hotGuard ? hotGuard.threadTs : baseThreadTs;
41528
+ const { effectiveChannel, effectiveThreadTs, settleThreadTs } = resolveSlackScheduledPriority({
41529
+ inboundId: inbound_id,
41530
+ enforceBound,
41531
+ scheduledDest: scheduledDest ?? null,
41532
+ bindingChannel: binding.channel,
41533
+ bindingThreadTs: binding.threadTs,
41534
+ fallbackChannel: channelGuard.corrected && channelGuard.channel ? channelGuard.channel : channel,
41535
+ fallbackThreadTs: channelGuard.corrected ? channelGuard.threadTs : hotThreadMode === "enforce" && hotGuard ? hotGuard.threadTs : baseThreadTs,
41536
+ fallbackSettleThreadTs: channelGuard.corrected ? channelGuard.threadTs : thread_ts
41537
+ });
41451
41538
  const hotThreadRedirected = hotThreadMode === "enforce" && hotGuard?.guard === "redirected_to_hot_thread";
41452
41539
  if (effectiveChannel) {
41453
41540
  recordReplyTargetClassification(
@@ -41497,7 +41584,6 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
41497
41584
  }
41498
41585
  const settleChannel = effectiveChannel;
41499
41586
  const settleMessageTs = effectiveMessageTs;
41500
- const settleThreadTs = enforceBound ? binding.threadTs : channelGuard.corrected ? channelGuard.threadTs : thread_ts;
41501
41587
  const settlePendingMarker = () => {
41502
41588
  if (!settleChannel) return;
41503
41589
  if (settleMessageTs) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@integrity-labs/agt-cli",
3
- "version": "0.28.390",
3
+ "version": "0.28.392",
4
4
  "description": "Augmented Team CLI — agent provisioning and management",
5
5
  "type": "module",
6
6
  "engines": {