@integrity-labs/agt-cli 0.27.78 → 0.27.80

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.
@@ -9,7 +9,7 @@ import {
9
9
  parseDeliveryTarget,
10
10
  registerFramework,
11
11
  wrapScheduledTaskPrompt
12
- } from "./chunk-5SWHKUL3.js";
12
+ } from "./chunk-GNIA4KN5.js";
13
13
 
14
14
  // ../../packages/core/dist/integrations/registry.js
15
15
  var INTEGRATION_REGISTRY = [
@@ -7488,4 +7488,4 @@ export {
7488
7488
  managerInstallSystemUnitCommand,
7489
7489
  managerUninstallSystemUnitCommand
7490
7490
  };
7491
- //# sourceMappingURL=chunk-RCCPYN3U.js.map
7491
+ //# sourceMappingURL=chunk-Y4INY5FA.js.map
@@ -100,7 +100,7 @@ async function spawnPairSession(session) {
100
100
  return { ok: true };
101
101
  } catch {
102
102
  }
103
- const { resolveClaudeBinary } = await import("./persistent-session-4HYXVGKO.js");
103
+ const { resolveClaudeBinary } = await import("./persistent-session-LGKYKSBP.js");
104
104
  const claudeBin = resolveClaudeBinary();
105
105
  const pairEnv = {
106
106
  ...process.env,
@@ -373,4 +373,4 @@ export {
373
373
  startClaudePair,
374
374
  submitClaudePairCode
375
375
  };
376
- //# sourceMappingURL=claude-pair-runtime-EZ73GJW7.js.map
376
+ //# sourceMappingURL=claude-pair-runtime-BK76FFIY.js.map
@@ -16,7 +16,7 @@ import {
16
16
  provisionStopHook,
17
17
  requireHost,
18
18
  safeWriteJsonAtomic
19
- } from "../chunk-RCCPYN3U.js";
19
+ } from "../chunk-Y4INY5FA.js";
20
20
  import {
21
21
  getProjectDir as getProjectDir2,
22
22
  getReadyTasks,
@@ -53,7 +53,7 @@ import {
53
53
  stopPersistentSession,
54
54
  takeWatchdogGiveUpCount,
55
55
  takeZombieDetection
56
- } from "../chunk-FAR2FJBQ.js";
56
+ } from "../chunk-FD5YRWYC.js";
57
57
  import {
58
58
  KANBAN_CHECK_COMMAND,
59
59
  appendDmFooter,
@@ -76,7 +76,7 @@ import {
76
76
  resolveConnectivityProbe,
77
77
  resolveDmTarget,
78
78
  wrapScheduledTaskPrompt
79
- } from "../chunk-5SWHKUL3.js";
79
+ } from "../chunk-GNIA4KN5.js";
80
80
  import {
81
81
  parsePsRows,
82
82
  reapOrphanChannelMcps
@@ -680,6 +680,20 @@ function decideSenderPolicyRestart(input) {
680
680
  return { restart: true, firstPoll: false, changed: true };
681
681
  }
682
682
 
683
+ // src/lib/msteams-behaviour-restart.ts
684
+ function extractMsTeamsBehaviourSubset(config2) {
685
+ const adaptiveCardsEnabled = config2?.["adaptive_cards_enabled"] === true;
686
+ return {
687
+ thread_auto_follow: config2?.["thread_auto_follow"] ?? "off",
688
+ channel_response_mode: config2?.["channel_response_mode"] ?? "mention_only",
689
+ adaptive_cards_enabled: adaptiveCardsEnabled,
690
+ // The adapter only emits MSTEAMS_ADAPTIVE_CARDS_ASK_USER_ENABLED when the
691
+ // parent flag is also on — mirror that so toggling ask_user while
692
+ // Adaptive Cards is off (a no-op for the env) doesn't restart.
693
+ adaptive_cards_ask_user_enabled: adaptiveCardsEnabled && config2?.["adaptive_cards_ask_user_enabled"] === true
694
+ };
695
+ }
696
+
683
697
  // src/lib/channel-quarantine.ts
684
698
  import { readFileSync } from "fs";
685
699
  import { join } from "path";
@@ -1288,6 +1302,7 @@ var GATEABLE_RESTART_REASONS = /* @__PURE__ */ new Set([
1288
1302
  "model-change",
1289
1303
  "channel-set-change",
1290
1304
  "sender-policy-change",
1305
+ "channel-behaviour-change",
1291
1306
  "hot-reload-mcp",
1292
1307
  "mcp-presence-reaper"
1293
1308
  ]);
@@ -2658,6 +2673,16 @@ var agentState = {
2658
2673
  * (they read SLACK_SENDER_POLICY / MSTEAMS_SENDER_POLICY only at boot).
2659
2674
  */
2660
2675
  knownSenderPolicyHashes: /* @__PURE__ */ new Map(),
2676
+ /**
2677
+ * ENG-6024: hash of the Teams behaviour subset (thread_auto_follow,
2678
+ * channel_response_mode, adaptive_cards_enabled/_ask_user_enabled) from the
2679
+ * agent's msteams channel config. Same last-hop rationale as
2680
+ * `knownSenderPolicyHashes`: teams-channel reads the corresponding env vars
2681
+ * once at boot, and neither the channel-set restart nor the .mcp.json drift
2682
+ * watcher fires on a value-only change, so this dedicated trigger restarts
2683
+ * the session when an operator saves the webapp's Teams Advanced panel.
2684
+ */
2685
+ knownMsTeamsBehaviourHashes: /* @__PURE__ */ new Map(),
2661
2686
  // ---------------------------------------------------------------------------
2662
2687
  // codeName-keyed
2663
2688
  // ---------------------------------------------------------------------------
@@ -2688,6 +2713,7 @@ function clearAgentState(agentId, codeName) {
2688
2713
  agentState.knownManagedMcpHashes.delete(agentId);
2689
2714
  agentState.knownManagedMcpStructure.delete(agentId);
2690
2715
  agentState.knownSenderPolicyHashes.delete(agentId);
2716
+ agentState.knownMsTeamsBehaviourHashes.delete(agentId);
2691
2717
  agentState.agentDisplayNames.delete(codeName);
2692
2718
  agentState.codeNameToAgentId.delete(codeName);
2693
2719
  let channelCacheMutated = false;
@@ -3115,14 +3141,32 @@ function startRealtimeIntegrationContext(config2) {
3115
3141
  if (agentIds.length === 0) return;
3116
3142
  const sb = ensureClient(config2);
3117
3143
  const filterStr = agentIds.length === 1 ? `agent_id=eq.${agentIds[0]}` : `agent_id=in.(${agentIds.join(",")})`;
3118
- integrationContextChannel = sb.channel("plugin-context-realtime").on("postgres_changes", {
3144
+ integrationContextChannel = sb.channel("agent-integration-context-realtime").on("postgres_changes", {
3145
+ event: "INSERT",
3146
+ schema: "public",
3147
+ table: "agent_integration_context",
3148
+ filter: filterStr
3149
+ }, (payload) => {
3150
+ const row = payload.new;
3151
+ log2(`[realtime] agent_integration_context INSERT for agent ${row.agent_id} (plugin ${row.plugin_id})`);
3152
+ onContextChange(row);
3153
+ }).on("postgres_changes", {
3154
+ event: "UPDATE",
3155
+ schema: "public",
3156
+ table: "agent_integration_context",
3157
+ filter: filterStr
3158
+ }, (payload) => {
3159
+ const row = payload.new;
3160
+ log2(`[realtime] agent_integration_context UPDATE for agent ${row.agent_id} (plugin ${row.plugin_id})`);
3161
+ onContextChange(row);
3162
+ }).on("postgres_changes", {
3119
3163
  event: "INSERT",
3120
3164
  schema: "public",
3121
3165
  table: "plugin_context",
3122
3166
  filter: filterStr
3123
3167
  }, (payload) => {
3124
3168
  const row = payload.new;
3125
- log2(`[realtime] plugin_context INSERT for agent ${row.agent_id} (plugin ${row.plugin_id})`);
3169
+ log2(`[realtime] plugin_context (legacy) INSERT for agent ${row.agent_id} (plugin ${row.plugin_id})`);
3126
3170
  onContextChange(row);
3127
3171
  }).on("postgres_changes", {
3128
3172
  event: "UPDATE",
@@ -3131,7 +3175,7 @@ function startRealtimeIntegrationContext(config2) {
3131
3175
  filter: filterStr
3132
3176
  }, (payload) => {
3133
3177
  const row = payload.new;
3134
- log2(`[realtime] plugin_context UPDATE for agent ${row.agent_id} (plugin ${row.plugin_id})`);
3178
+ log2(`[realtime] plugin_context (legacy) UPDATE for agent ${row.agent_id} (plugin ${row.plugin_id})`);
3135
3179
  onContextChange(row);
3136
3180
  }).subscribe((status) => {
3137
3181
  if (status === "SUBSCRIBED") {
@@ -3140,7 +3184,7 @@ function startRealtimeIntegrationContext(config2) {
3140
3184
  log2(`[realtime] Integration context channel: ${status}`);
3141
3185
  }
3142
3186
  });
3143
- log2(`[realtime] Subscribing to plugin_context for ${agentIds.length} agent(s)`);
3187
+ log2(`[realtime] Subscribing to agent_integration_context (+ legacy plugin_context) for ${agentIds.length} agent(s)`);
3144
3188
  }
3145
3189
  function stopRealtimeIntegrationContext() {
3146
3190
  if (!integrationContextChannel) return;
@@ -3668,7 +3712,7 @@ var cachedMaintenanceWindow = null;
3668
3712
  var lastVersionCheckAt = 0;
3669
3713
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
3670
3714
  var lastResponsivenessProbeAt = 0;
3671
- var agtCliVersion = true ? "0.27.78" : "dev";
3715
+ var agtCliVersion = true ? "0.27.80" : "dev";
3672
3716
  function resolveBrewPath(execFileSync4) {
3673
3717
  try {
3674
3718
  const out = execFileSync4("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -4782,7 +4826,7 @@ async function pollCycle() {
4782
4826
  }
4783
4827
  try {
4784
4828
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
4785
- const { collectDiagnostics } = await import("../persistent-session-4HYXVGKO.js");
4829
+ const { collectDiagnostics } = await import("../persistent-session-LGKYKSBP.js");
4786
4830
  const diagCodeNames = [...agentState.persistentSessionAgents];
4787
4831
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames) : void 0;
4788
4832
  let tailscaleHostname;
@@ -4855,7 +4899,7 @@ async function pollCycle() {
4855
4899
  const {
4856
4900
  collectResponsivenessProbes,
4857
4901
  getResponsivenessIntervalMs
4858
- } = await import("../responsiveness-probe-NUGYDDMS.js");
4902
+ } = await import("../responsiveness-probe-C6ZWB26H.js");
4859
4903
  const probeIntervalMs = getResponsivenessIntervalMs();
4860
4904
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
4861
4905
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -5761,6 +5805,52 @@ async function processAgent(agent, agentStates) {
5761
5805
  );
5762
5806
  }
5763
5807
  agentState.knownSenderPolicyHashes.set(agent.agent_id, senderPolicyHash);
5808
+ if (currentChannelIds.has("msteams")) {
5809
+ const msteamsEntry = refreshData.channel_configs?.["msteams"];
5810
+ const behaviourSubset = extractMsTeamsBehaviourSubset(
5811
+ msteamsEntry?.config
5812
+ );
5813
+ const behaviourHash = createHash3("sha256").update(canonicalJson(behaviourSubset)).digest("hex");
5814
+ const prevBehaviourHash = agentState.knownMsTeamsBehaviourHashes.get(agent.agent_id);
5815
+ const behaviourDecision = decideSenderPolicyRestart({
5816
+ previousHash: prevBehaviourHash,
5817
+ currentHash: behaviourHash,
5818
+ sessionMode: refreshData.agent.session_mode,
5819
+ framework: agentFrameworkCache.get(agent.code_name) ?? "openclaw",
5820
+ sessionHealthy: isSessionHealthy(agent.code_name),
5821
+ // A channel-set or sender-policy restart scheduled this tick will
5822
+ // respawn the MCP children with the freshly-written env for free.
5823
+ channelSetRestartAlreadyScheduled: channelSetRestartScheduled || senderPolicyDecision.restart
5824
+ });
5825
+ if (behaviourDecision.restart) {
5826
+ log(
5827
+ `[hot-reload] msteams behaviour settings changed for '${agent.code_name}' (${prevBehaviourHash?.slice(0, 8) ?? "first"} \u2192 ${behaviourHash.slice(0, 8)}) \u2014 restarting session`
5828
+ );
5829
+ const behaviourNotice = "Your Microsoft Teams channel behaviour settings were updated. Restarting session shortly so the teams-channel MCP picks up the new configuration.";
5830
+ const behaviourDelivered = await injectMessage(
5831
+ agent.code_name,
5832
+ "system",
5833
+ behaviourNotice,
5834
+ { task_name: "channel-update" },
5835
+ log
5836
+ ).catch(() => false);
5837
+ const behaviourDelay = behaviourDelivered ? 8e3 : 3e3;
5838
+ if (!behaviourDelivered) {
5839
+ log(
5840
+ `[hot-reload] Inject notification unconfirmed for '${agent.code_name}' \u2014 proceeding with shorter delay`
5841
+ );
5842
+ }
5843
+ scheduleSessionRestart(
5844
+ agent.code_name,
5845
+ behaviourDelay,
5846
+ "msteams behaviour change",
5847
+ "channel-behaviour-change"
5848
+ );
5849
+ }
5850
+ agentState.knownMsTeamsBehaviourHashes.set(agent.agent_id, behaviourHash);
5851
+ } else {
5852
+ agentState.knownMsTeamsBehaviourHashes.delete(agent.agent_id);
5853
+ }
5764
5854
  }
5765
5855
  const agentSessionMode = refreshData.agent.session_mode;
5766
5856
  if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? "openclaw") === "claude-code") {
@@ -9022,7 +9112,7 @@ async function processClaudePairSessions(agents) {
9022
9112
  killPairSession,
9023
9113
  pairTmuxSession,
9024
9114
  finalizeClaudePairOnboarding
9025
- } = await import("../claude-pair-runtime-EZ73GJW7.js");
9115
+ } = await import("../claude-pair-runtime-BK76FFIY.js");
9026
9116
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
9027
9117
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
9028
9118
  const killed = await killPairSession(pairTmuxSession(pairId));