@integrity-labs/agt-cli 0.19.19 → 0.19.20

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.
@@ -22,7 +22,7 @@ import {
22
22
  resolveChannels,
23
23
  resolveDmTarget,
24
24
  wrapScheduledTaskPrompt
25
- } from "../chunk-WQJL6EGC.js";
25
+ } from "../chunk-IWFXAB4O.js";
26
26
  import {
27
27
  findTaskByTemplate,
28
28
  getProjectDir,
@@ -1811,18 +1811,41 @@ var config = null;
1811
1811
  var running = false;
1812
1812
  var pollTimer = null;
1813
1813
  var PANE_TAIL_PREVIEW_LINES = 5;
1814
- function extractCharterTelegramPeers(rawContent) {
1814
+ function extractCharterTelegramPeers(rawContent, gateContext) {
1815
1815
  if (!rawContent || rawContent.length === 0) return [];
1816
1816
  try {
1817
1817
  const parsed = extractFrontmatter(rawContent);
1818
1818
  const frontmatter = parsed.frontmatter;
1819
1819
  const peers = frontmatter?.multi_agent?.telegram_peers;
1820
1820
  if (!peers || !Array.isArray(peers)) return [];
1821
+ const teamBotIds = new Set(gateContext?.teamPeerBotIds ?? []);
1822
+ const grants = gateContext?.crossTeamGrants ?? [];
1823
+ const intraOrg = gateContext?.crossTeamPeerIntraOrg ?? "unrestricted";
1824
+ const now = (gateContext?.now ?? (() => /* @__PURE__ */ new Date()))();
1821
1825
  const out = [];
1822
1826
  for (const p of peers) {
1823
- if (p && typeof p === "object" && typeof p.code_name === "string" && typeof p.bot_id === "number" && Number.isInteger(p.bot_id) && p.bot_id > 0) {
1824
- out.push({ code_name: p.code_name, bot_id: p.bot_id, agent_id: "" });
1827
+ if (!p || typeof p !== "object" || typeof p.code_name !== "string" || typeof p.bot_id !== "number" || !Number.isInteger(p.bot_id) || p.bot_id <= 0) {
1828
+ continue;
1829
+ }
1830
+ const grantId = typeof p.cross_team_grant_id === "string" && p.cross_team_grant_id.length > 0 ? p.cross_team_grant_id : null;
1831
+ let gate = null;
1832
+ if (gateContext === void 0) {
1833
+ gate = "same_team";
1834
+ } else if (teamBotIds.has(p.bot_id)) {
1835
+ gate = "same_team";
1836
+ } else if (grantId) {
1837
+ const grant = grants.find((g) => g.grant_id === grantId);
1838
+ if (grant && !grant.revoked_at && (!grant.expires_at || new Date(grant.expires_at) > now) && grant.granted_agent_bot_id === p.bot_id) {
1839
+ gate = `grant:${grantId}`;
1840
+ } else {
1841
+ gate = null;
1842
+ }
1843
+ } else if (intraOrg === "unrestricted") {
1844
+ gate = "intra_org_unrestricted";
1845
+ } else {
1846
+ gate = null;
1825
1847
  }
1848
+ out.push({ code_name: p.code_name, bot_id: p.bot_id, agent_id: "", gate_path: gate });
1826
1849
  }
1827
1850
  return out;
1828
1851
  } catch {
@@ -1968,7 +1991,7 @@ function clearAgentCaches(agentId, codeName) {
1968
1991
  var cachedFrameworkVersion = null;
1969
1992
  var lastVersionCheckAt = 0;
1970
1993
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
1971
- var agtCliVersion = true ? "0.19.19" : "dev";
1994
+ var agtCliVersion = true ? "0.19.20" : "dev";
1972
1995
  function resolveBrewPath(execFileSync3) {
1973
1996
  try {
1974
1997
  const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -2920,6 +2943,22 @@ async function pollCycle() {
2920
2943
  }
2921
2944
  const data = await api.post("/host/agents", { host_id: hostId });
2922
2945
  const agents = data.agents ?? [];
2946
+ const restartAcks = /* @__PURE__ */ new Map();
2947
+ for (const agent of agents) {
2948
+ const requested = agent.restart_requested_at ?? null;
2949
+ if (!requested) continue;
2950
+ const prev = state.agents.find((a) => a.agentId === agent.agent_id);
2951
+ const lastProcessed = prev?.lastRestartProcessedAt ?? null;
2952
+ if (lastProcessed && Date.parse(lastProcessed) >= Date.parse(requested)) continue;
2953
+ log(`[restart] Dashboard requested restart for '${agent.code_name}' at ${requested}`);
2954
+ try {
2955
+ const { execSync: es } = await import("child_process");
2956
+ es(`tmux kill-session -t agt-${agent.code_name} 2>/dev/null`, { stdio: "ignore" });
2957
+ } catch {
2958
+ }
2959
+ stopPersistentSessionAndForgetMcpBaseline(agent.code_name);
2960
+ restartAcks.set(agent.agent_id, requested);
2961
+ }
2923
2962
  const frameworksThisCycle = new Set(agents.map((a) => a.framework).filter(Boolean));
2924
2963
  for (const fw of frameworksThisCycle) {
2925
2964
  await ensureFrameworkBinary(fw);
@@ -2954,6 +2993,18 @@ async function pollCycle() {
2954
2993
  }
2955
2994
  }
2956
2995
  }
2996
+ if (restartAcks.size > 0) {
2997
+ for (const ack of agentStates) {
2998
+ const requested = restartAcks.get(ack.agentId);
2999
+ if (requested) ack.lastRestartProcessedAt = requested;
3000
+ }
3001
+ try {
3002
+ const ackedState = { ...state, agents: agentStates };
3003
+ writeFileSync3(getStateFile(), JSON.stringify(ackedState, null, 2));
3004
+ } catch (err) {
3005
+ log(`[restart] failed to persist ack immediately: ${err.message}`);
3006
+ }
3007
+ }
2957
3008
  try {
2958
3009
  for (const [channelId, codeNames] of activeChannels) {
2959
3010
  for (const codeName of codeNames) {
@@ -3447,12 +3498,21 @@ async function processAgent(agent, agentStates) {
3447
3498
  activeChannels.set(channelId, /* @__PURE__ */ new Set());
3448
3499
  }
3449
3500
  activeChannels.get(channelId).add(agent.code_name);
3450
- const teamSettingsForHash = channelId === "telegram" ? {
3451
- telegram_peer_disabled: Boolean(
3452
- refreshData.team?.settings?.["telegram_peer_disabled"] ?? false
3453
- )
3454
- } : null;
3455
- const peersForHash = channelId === "telegram" ? extractCharterTelegramPeers(refreshData.charter?.raw_content ?? "") : null;
3501
+ const teamSettings = refreshData.team?.settings;
3502
+ const peerDisabledMode = (() => {
3503
+ const next = teamSettings?.["peer_disabled"];
3504
+ if (next === "off" || next === "cross_team_only" || next === "all") return next;
3505
+ return teamSettings?.["telegram_peer_disabled"] === true ? "all" : "off";
3506
+ })();
3507
+ const teamSettingsForHash = channelId === "telegram" || channelId === "slack" ? { peer_disabled: peerDisabledMode } : null;
3508
+ const crossTeamData = refreshData;
3509
+ const refreshHasCrossTeamFields = Array.isArray(crossTeamData.team_peer_bot_ids);
3510
+ const gateContext = refreshHasCrossTeamFields ? {
3511
+ teamPeerBotIds: crossTeamData.team_peer_bot_ids ?? [],
3512
+ crossTeamGrants: crossTeamData.cross_team_grants?.inbound ?? [],
3513
+ crossTeamPeerIntraOrg: crossTeamData.organization?.cross_team_peer_intra_org ?? "unrestricted"
3514
+ } : void 0;
3515
+ const peersForHash = channelId === "telegram" ? extractCharterTelegramPeers(refreshData.charter?.raw_content ?? "", gateContext) : null;
3456
3516
  const configHash = createHash2("sha256").update(canonicalJson({ config: entry.config, team: teamSettingsForHash, peers: peersForHash })).digest("hex");
3457
3517
  const cacheKey = `${agent.agent_id}:${channelId}`;
3458
3518
  let onDiskPresent = true;
@@ -3473,15 +3533,14 @@ async function processAgent(agent, agentStates) {
3473
3533
  }
3474
3534
  try {
3475
3535
  const sessionMode2 = refreshData.agent.session_mode;
3476
- const telegramPeerDisabled = channelId === "telegram" ? Boolean(
3477
- refreshData.team?.settings?.["telegram_peer_disabled"] ?? false
3478
- ) : void 0;
3479
- const telegramPeers = channelId === "telegram" ? extractCharterTelegramPeers(refreshData.charter?.raw_content ?? "") : void 0;
3536
+ const peerDisabled = channelId === "telegram" || channelId === "slack" ? peerDisabledMode : void 0;
3537
+ const telegramPeerDisabled = channelId === "telegram" ? peerDisabledMode === "all" : void 0;
3538
+ const telegramPeers = channelId === "telegram" ? extractCharterTelegramPeers(refreshData.charter?.raw_content ?? "", gateContext) : void 0;
3480
3539
  frameworkAdapter.writeChannelCredentials(
3481
3540
  agent.code_name,
3482
3541
  channelId,
3483
3542
  entry.config,
3484
- { sessionMode: sessionMode2, agentId: agent.agent_id, telegramPeerDisabled, telegramPeers }
3543
+ { sessionMode: sessionMode2, agentId: agent.agent_id, telegramPeerDisabled, peerDisabled, telegramPeers }
3485
3544
  );
3486
3545
  knownChannelConfigHashes.set(cacheKey, configHash);
3487
3546
  saveChannelHashCache2();
@@ -6711,6 +6770,19 @@ async function stopPolling(opts = {}) {
6711
6770
  }
6712
6771
  function startManager(opts) {
6713
6772
  config = opts;
6773
+ try {
6774
+ const stateFile = getStateFile();
6775
+ if (existsSync3(stateFile)) {
6776
+ const raw = readFileSync3(stateFile, "utf-8");
6777
+ const parsed = JSON.parse(raw);
6778
+ if (Array.isArray(parsed.agents)) {
6779
+ state.agents = parsed.agents;
6780
+ log(`[startup] rehydrated ${state.agents.length} agent state(s) from ${stateFile}`);
6781
+ }
6782
+ }
6783
+ } catch (err) {
6784
+ log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
6785
+ }
6714
6786
  log(
6715
6787
  `[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join4(homedir3(), ".augmented", "manager.log")}`
6716
6788
  );
@@ -6879,6 +6951,7 @@ process.on("disconnect", () => {
6879
6951
  });
6880
6952
  export {
6881
6953
  ChildProcessError,
6954
+ extractCharterTelegramPeers,
6882
6955
  markAgentForFreshMemorySync,
6883
6956
  startManager,
6884
6957
  stopManager