@integrity-labs/agt-cli 0.27.23 → 0.27.25

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.
@@ -15,7 +15,7 @@ import {
15
15
  provisionOrientHook,
16
16
  provisionStopHook,
17
17
  requireHost
18
- } from "../chunk-RM4XYPLD.js";
18
+ } from "../chunk-GI73VOGA.js";
19
19
  import {
20
20
  getProjectDir as getProjectDir2,
21
21
  getReadyTasks,
@@ -578,6 +578,37 @@ function decideChannelRestart(input) {
578
578
  return { restart: true, added, removed };
579
579
  }
580
580
 
581
+ // src/lib/sender-policy-restart-decision.ts
582
+ function decideSenderPolicyRestart(input) {
583
+ const {
584
+ previousHash,
585
+ currentHash,
586
+ sessionMode,
587
+ framework,
588
+ sessionHealthy,
589
+ channelSetRestartAlreadyScheduled
590
+ } = input;
591
+ if (previousHash === void 0) {
592
+ return { restart: false, firstPoll: true, changed: false };
593
+ }
594
+ if (previousHash === currentHash) {
595
+ return { restart: false, firstPoll: false, changed: false };
596
+ }
597
+ if (sessionMode !== "persistent") {
598
+ return { restart: false, firstPoll: false, changed: true };
599
+ }
600
+ if (framework !== "claude-code") {
601
+ return { restart: false, firstPoll: false, changed: true };
602
+ }
603
+ if (!sessionHealthy) {
604
+ return { restart: false, firstPoll: false, changed: true };
605
+ }
606
+ if (channelSetRestartAlreadyScheduled) {
607
+ return { restart: false, firstPoll: false, changed: true };
608
+ }
609
+ return { restart: true, firstPoll: false, changed: true };
610
+ }
611
+
581
612
  // src/lib/restart-breaker.ts
582
613
  function reaperRestartBreakerReason(activeKeys) {
583
614
  return activeKeys.length >= 2 ? "mcp-presence-reaper" : void 0;
@@ -2210,6 +2241,16 @@ var agentState = {
2210
2241
  knownIntegrationHashes: /* @__PURE__ */ new Map(),
2211
2242
  knownManagedMcpHashes: /* @__PURE__ */ new Map(),
2212
2243
  knownManagedMcpStructure: /* @__PURE__ */ new Map(),
2244
+ /**
2245
+ * ENG-5858: hash of the effective sender_policy returned by
2246
+ * /host/refresh for this agent. Tracked separately from
2247
+ * `knownChannelConfigHashes` because the channel-cred hash is
2248
+ * per-channel (cleared/rewritten per channel) whereas sender_policy is
2249
+ * agent-wide. A change here triggers a session restart so the
2250
+ * slack-channel / teams-channel MCP children pick up the new env vars
2251
+ * (they read SLACK_SENDER_POLICY / MSTEAMS_SENDER_POLICY only at boot).
2252
+ */
2253
+ knownSenderPolicyHashes: /* @__PURE__ */ new Map(),
2213
2254
  // ---------------------------------------------------------------------------
2214
2255
  // codeName-keyed
2215
2256
  // ---------------------------------------------------------------------------
@@ -2239,6 +2280,7 @@ function clearAgentState(agentId, codeName) {
2239
2280
  agentState.knownIntegrationHashes.delete(agentId);
2240
2281
  agentState.knownManagedMcpHashes.delete(agentId);
2241
2282
  agentState.knownManagedMcpStructure.delete(agentId);
2283
+ agentState.knownSenderPolicyHashes.delete(agentId);
2242
2284
  agentState.agentDisplayNames.delete(codeName);
2243
2285
  agentState.codeNameToAgentId.delete(codeName);
2244
2286
  let channelCacheMutated = false;
@@ -3166,7 +3208,7 @@ var cachedFrameworkVersion = null;
3166
3208
  var lastVersionCheckAt = 0;
3167
3209
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
3168
3210
  var lastResponsivenessProbeAt = 0;
3169
- var agtCliVersion = true ? "0.27.23" : "dev";
3211
+ var agtCliVersion = true ? "0.27.25" : "dev";
3170
3212
  function resolveBrewPath(execFileSync4) {
3171
3213
  try {
3172
3214
  const out = execFileSync4("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -4976,7 +5018,7 @@ async function processAgent(agent, agentStates) {
4976
5018
  const peersForHash = channelId === "telegram" ? extractCharterTelegramPeers(refreshData.charter?.raw_content ?? "", gateContext) : channelId === "slack" ? extractCharterSlackPeers(refreshData.charter?.raw_content ?? "", gateContext) : null;
4977
5019
  const sessionModeForHash = refreshData.agent.session_mode;
4978
5020
  const senderPolicyForHash = refreshData.sender_policy ?? null;
4979
- const CHANNEL_WRITE_VERSION = 7;
5021
+ const CHANNEL_WRITE_VERSION = 8;
4980
5022
  const configHash = createHash3("sha256").update(
4981
5023
  canonicalJson({
4982
5024
  writeVersion: CHANNEL_WRITE_VERSION,
@@ -5069,6 +5111,46 @@ async function processAgent(agent, agentStates) {
5069
5111
  }
5070
5112
  scheduleSessionRestart(agent.code_name, delay, "new channel set");
5071
5113
  }
5114
+ if (channelConfigConverged) {
5115
+ const hasSenderPolicyChannel = currentChannelIds.has("slack") || currentChannelIds.has("msteams");
5116
+ const senderPolicyForRestartHash = refreshData.sender_policy ?? null;
5117
+ const senderPolicyHash = createHash3("sha256").update(canonicalJson({ senderPolicy: senderPolicyForRestartHash })).digest("hex");
5118
+ const prevSenderPolicyHash = agentState.knownSenderPolicyHashes.get(agent.agent_id);
5119
+ const senderPolicyDecision = hasSenderPolicyChannel ? decideSenderPolicyRestart({
5120
+ previousHash: prevSenderPolicyHash,
5121
+ currentHash: senderPolicyHash,
5122
+ sessionMode: refreshData.agent.session_mode,
5123
+ framework: agentFrameworkCache.get(agent.code_name) ?? "openclaw",
5124
+ sessionHealthy: isSessionHealthy(agent.code_name),
5125
+ channelSetRestartAlreadyScheduled: restartDecision.restart
5126
+ }) : { restart: false, firstPoll: prevSenderPolicyHash === void 0, changed: false };
5127
+ if (senderPolicyDecision.restart) {
5128
+ log(
5129
+ `[hot-reload] sender_policy changed for '${agent.code_name}' (${prevSenderPolicyHash?.slice(0, 8) ?? "first"} \u2192 ${senderPolicyHash.slice(0, 8)}) \u2014 restarting session`
5130
+ );
5131
+ const notice = "Your sender_policy has been updated. Restarting session shortly so the channel MCP servers pick up the new gate.";
5132
+ const delivered = await injectMessage(
5133
+ agent.code_name,
5134
+ "system",
5135
+ notice,
5136
+ { task_name: "sender-policy-update" },
5137
+ log
5138
+ ).catch(() => false);
5139
+ const delay = delivered ? 8e3 : 3e3;
5140
+ if (!delivered) {
5141
+ log(
5142
+ `[hot-reload] Inject notification unconfirmed for '${agent.code_name}' \u2014 proceeding with shorter delay`
5143
+ );
5144
+ }
5145
+ scheduleSessionRestart(
5146
+ agent.code_name,
5147
+ delay,
5148
+ "sender_policy change",
5149
+ "sender-policy-change"
5150
+ );
5151
+ }
5152
+ agentState.knownSenderPolicyHashes.set(agent.agent_id, senderPolicyHash);
5153
+ }
5072
5154
  const agentSessionMode = refreshData.agent.session_mode;
5073
5155
  if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? "openclaw") === "claude-code") {
5074
5156
  try {