@integrity-labs/agt-cli 0.28.618 → 0.28.620

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.
@@ -54,7 +54,7 @@ import {
54
54
  safeWriteJsonAtomic,
55
55
  setConfigHash,
56
56
  tripClass
57
- } from "../chunk-CKCXOIN3.js";
57
+ } from "../chunk-5ZJFTTGB.js";
58
58
  import {
59
59
  getProjectDir as getProjectDir2,
60
60
  getReadyTasks,
@@ -8030,14 +8030,23 @@ var ALLOWED_MESSAGE_SUBTYPES = /* @__PURE__ */ new Set([
8030
8030
  "file_share",
8031
8031
  "thread_broadcast"
8032
8032
  ]);
8033
- function decideSlackMessageForward(evt) {
8033
+ function matchesThirdPartyGrant(evt, thirdPartyBots) {
8034
+ const botId = evt.bot_id;
8035
+ if (!botId || !thirdPartyBots?.length)
8036
+ return false;
8037
+ return thirdPartyBots.some((b) => b.bot_id === botId || b.bot_user_id === botId);
8038
+ }
8039
+ function decideSlackMessageForward(evt, thirdPartyBots) {
8034
8040
  if (evt.type !== "message") {
8035
8041
  return { forward: true };
8036
8042
  }
8043
+ const granted = matchesThirdPartyGrant(evt, thirdPartyBots);
8037
8044
  if (!ALLOWED_MESSAGE_SUBTYPES.has(evt.subtype)) {
8038
- return { forward: false, reason: "subtype" };
8045
+ if (!granted || evt.subtype !== "bot_message") {
8046
+ return { forward: false, reason: "subtype" };
8047
+ }
8039
8048
  }
8040
- if (!evt.user) {
8049
+ if (!evt.user && !granted) {
8041
8050
  return { forward: false, reason: "no_user" };
8042
8051
  }
8043
8052
  const hasText = typeof evt.text === "string" && evt.text.trim().length > 0;
@@ -8132,7 +8141,13 @@ function classifyPeerMessage(msg, cfg, self) {
8132
8141
  }
8133
8142
  const peer = cfg.peers.find((p) => p.bot_user_id === msg.user);
8134
8143
  if (!peer) {
8135
- const thirdParty = cfg.third_party_bots?.find((b) => b.bot_user_id === msg.user);
8144
+ const thirdParty = cfg.third_party_bots?.find((b) => {
8145
+ if (msg.user && b.bot_user_id === msg.user)
8146
+ return true;
8147
+ if (!msg.bot_id)
8148
+ return false;
8149
+ return b.bot_id === msg.bot_id || b.bot_user_id === msg.bot_id;
8150
+ });
8136
8151
  if (thirdParty) {
8137
8152
  if (cfg.peer_disabled_mode === "cross_team_only") {
8138
8153
  return { kind: "drop", reason: "peer_disabled_cross_team" };
@@ -8249,6 +8264,39 @@ function parsePeerGroupIdsEnv(raw) {
8249
8264
  return [];
8250
8265
  return raw.split(",").map((s) => s.trim()).filter(Boolean);
8251
8266
  }
8267
+ function parseThirdPartyBotsEnv(raw) {
8268
+ if (!raw || !raw.trim())
8269
+ return [];
8270
+ let parsed;
8271
+ try {
8272
+ parsed = JSON.parse(raw);
8273
+ } catch {
8274
+ return [];
8275
+ }
8276
+ if (!Array.isArray(parsed))
8277
+ return [];
8278
+ const out = [];
8279
+ for (const item of parsed) {
8280
+ if (!item || typeof item !== "object")
8281
+ continue;
8282
+ const rec = item;
8283
+ const botUserId = typeof rec["bot_user_id"] === "string" ? rec["bot_user_id"].trim() : "";
8284
+ if (!botUserId)
8285
+ continue;
8286
+ if (!Array.isArray(rec["channel_ids"]))
8287
+ continue;
8288
+ const channels = rec["channel_ids"].filter((c) => typeof c === "string" && c.trim() !== "").map((c) => c.trim());
8289
+ const label = typeof rec["label"] === "string" && rec["label"].trim() ? rec["label"].trim() : void 0;
8290
+ const botId = typeof rec["bot_id"] === "string" && rec["bot_id"].trim() ? rec["bot_id"].trim() : void 0;
8291
+ out.push({
8292
+ bot_user_id: botUserId,
8293
+ channel_ids: channels,
8294
+ ...botId ? { bot_id: botId } : {},
8295
+ ...label ? { label } : {}
8296
+ });
8297
+ }
8298
+ return out;
8299
+ }
8252
8300
  function parsePeerAgentModeEnv(raw) {
8253
8301
  if (raw === "listen" || raw === "respond")
8254
8302
  return raw;
@@ -8330,7 +8378,7 @@ function decideInboundAccess(input) {
8330
8378
  // ../../packages/core/dist/channels/governance/slack-sender-gate.js
8331
8379
  function evaluateSlackInboundGate(evt, deps) {
8332
8380
  const isBot = Boolean(evt.bot_id);
8333
- const content = decideSlackMessageForward(evt);
8381
+ const content = decideSlackMessageForward(evt, deps.peerConfig.third_party_bots);
8334
8382
  const spDecision = decideSenderPolicyForward(evt, deps.senderPolicy);
8335
8383
  const senderPolicy = spDecision.forward ? { forward: true } : { forward: false, reason: classifySlackPolicyBlock(evt, deps.senderPolicy) };
8336
8384
  const peer = isBot ? (() => {
@@ -8428,7 +8476,15 @@ function buildSlackPeerClassifierConfigFromEnv(env, opts) {
8428
8476
  peer_agent_mode: parsePeerAgentModeEnv(env["SLACK_PEER_AGENT_MODE"]),
8429
8477
  peer_group_ids: parsePeerGroupIdsEnv(env["SLACK_PEER_GROUP_IDS"]),
8430
8478
  peers: parsePeersEnv(env["SLACK_PEERS"], env["SLACK_PEERS_GATE"]),
8431
- peer_disabled_mode: parseSlackPeerDisabledModeEnv(env, opts?.onWarn)
8479
+ peer_disabled_mode: parseSlackPeerDisabledModeEnv(env, opts?.onWarn),
8480
+ // ENG-8669 follow-up: this builder never populated the third-party
8481
+ // allowlist. ENG-8669 read `SLACK_THIRD_PARTY_BOTS` only in the MCP
8482
+ // adapter's own inline config, so every consumer of THIS builder — the
8483
+ // opencode manager-side SenderGate among them — saw `third_party_bots`
8484
+ // as undefined and could not admit a third-party bot under any
8485
+ // configuration. The allowlist was wired into one of the two Slack ingress
8486
+ // paths. Reading it here makes the two agree.
8487
+ third_party_bots: parseThirdPartyBotsEnv(env["SLACK_THIRD_PARTY_BOTS"])
8432
8488
  };
8433
8489
  }
8434
8490
 
@@ -11977,7 +12033,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
11977
12033
  var lastVersionCheckAt = 0;
11978
12034
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
11979
12035
  var lastResponsivenessProbeAt = 0;
11980
- var agtCliVersion = true ? "0.28.618" : "dev";
12036
+ var agtCliVersion = true ? "0.28.620" : "dev";
11981
12037
  function resolveBrewPath(execFileSync3) {
11982
12038
  try {
11983
12039
  const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();