@integrity-labs/agt-cli 0.28.161 → 0.28.163

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.
@@ -3,7 +3,7 @@ import {
3
3
  formatMissingVar,
4
4
  isClaudeFastMode,
5
5
  probeMcpEnvSubstitution
6
- } from "./chunk-CQZDKD2U.js";
6
+ } from "./chunk-MTKFDGXO.js";
7
7
  import {
8
8
  reapOrphanChannelMcps
9
9
  } from "./chunk-XWVM4KPK.js";
@@ -1588,4 +1588,4 @@ export {
1588
1588
  stopAllSessionsAndWait,
1589
1589
  getProjectDir
1590
1590
  };
1591
- //# sourceMappingURL=chunk-2D5COEAS.js.map
1591
+ //# sourceMappingURL=chunk-OW6ERQHP.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-3AC6FSX6.js");
103
+ const { resolveClaudeBinary } = await import("./persistent-session-3ACIT7F5.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-VHRJFJDJ.js.map
376
+ //# sourceMappingURL=claude-pair-runtime-WEKLV5X5.js.map
@@ -28,7 +28,7 @@ import {
28
28
  requireHost,
29
29
  safeWriteJsonAtomic,
30
30
  setConfigHash
31
- } from "../chunk-TNTG4DNQ.js";
31
+ } from "../chunk-BEUGTZ7Z.js";
32
32
  import {
33
33
  getProjectDir as getProjectDir2,
34
34
  getReadyTasks,
@@ -70,7 +70,7 @@ import {
70
70
  takeZombieDetection,
71
71
  transcriptActivityAgeSeconds,
72
72
  writeEgressAllowlist
73
- } from "../chunk-2D5COEAS.js";
73
+ } from "../chunk-OW6ERQHP.js";
74
74
  import {
75
75
  CONVERSATION_FAILURE_CATEGORIES,
76
76
  DEFAULT_FRAMEWORK,
@@ -111,7 +111,7 @@ import {
111
111
  resolveChannels,
112
112
  resolveDmTarget,
113
113
  sumTranscriptUsageInWindow
114
- } from "../chunk-CQZDKD2U.js";
114
+ } from "../chunk-MTKFDGXO.js";
115
115
  import {
116
116
  parsePsRows,
117
117
  reapOrphanChannelMcps
@@ -6878,7 +6878,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
6878
6878
  var lastVersionCheckAt = 0;
6879
6879
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
6880
6880
  var lastResponsivenessProbeAt = 0;
6881
- var agtCliVersion = true ? "0.28.161" : "dev";
6881
+ var agtCliVersion = true ? "0.28.163" : "dev";
6882
6882
  function resolveBrewPath(execFileSync4) {
6883
6883
  try {
6884
6884
  const out = execFileSync4("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -8011,7 +8011,7 @@ async function pollCycle() {
8011
8011
  }
8012
8012
  try {
8013
8013
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
8014
- const { collectDiagnostics } = await import("../persistent-session-3AC6FSX6.js");
8014
+ const { collectDiagnostics } = await import("../persistent-session-3ACIT7F5.js");
8015
8015
  const diagCodeNames = [...agentState.persistentSessionAgents];
8016
8016
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames) : void 0;
8017
8017
  let tailscaleHostname;
@@ -8159,7 +8159,7 @@ async function pollCycle() {
8159
8159
  const {
8160
8160
  collectResponsivenessProbes,
8161
8161
  getResponsivenessIntervalMs
8162
- } = await import("../responsiveness-probe-ZXB5REIY.js");
8162
+ } = await import("../responsiveness-probe-5OCWCS3M.js");
8163
8163
  const probeIntervalMs = getResponsivenessIntervalMs();
8164
8164
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
8165
8165
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -8191,7 +8191,7 @@ async function pollCycle() {
8191
8191
  collectResponsivenessProbes,
8192
8192
  livePendingInboundOldestAgeSeconds,
8193
8193
  parkPendingInbound
8194
- } = await import("../responsiveness-probe-ZXB5REIY.js");
8194
+ } = await import("../responsiveness-probe-5OCWCS3M.js");
8195
8195
  const { getProjectDir: wedgeProjectDir } = await import("../claude-scheduler-FATCLHDM.js");
8196
8196
  const wedgeNow = /* @__PURE__ */ new Date();
8197
8197
  const liveAgents = agentState.persistentSessionAgents;
@@ -11692,7 +11692,7 @@ async function processClaudePairSessions(agents) {
11692
11692
  killPairSession,
11693
11693
  pairTmuxSession,
11694
11694
  finalizeClaudePairOnboarding
11695
- } = await import("../claude-pair-runtime-VHRJFJDJ.js");
11695
+ } = await import("../claude-pair-runtime-WEKLV5X5.js");
11696
11696
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
11697
11697
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
11698
11698
  const killed = await killPairSession(pairTmuxSession(pairId));
@@ -10,15 +10,48 @@ import { resolve as resolvePath } from "path";
10
10
  var URL_ENV = "AGT_REMOTE_MCP_URL";
11
11
  var TOKEN_FILE_ENV = "AGT_REMOTE_MCP_TOKEN_FILE";
12
12
  var TOKEN_VAR_ENV = "AGT_REMOTE_MCP_TOKEN_VAR";
13
+ var ALLOWLIST_ENV = "AGT_REMOTE_MCP_TOOL_ALLOWLIST";
13
14
  var REMOTE_FETCH_TIMEOUT_MS = 3e4;
14
15
  var remoteUrl = process.env[URL_ENV] ?? "";
15
16
  var tokenFile = process.env[TOKEN_FILE_ENV] ?? "";
16
17
  var tokenVar = process.env[TOKEN_VAR_ENV] ?? "";
17
18
  var label = process.env["AGT_REMOTE_MCP_LABEL"] || tokenVar || "remote-oauth";
19
+ var toolAllowlist = parseToolAllowlist(process.env[ALLOWLIST_ENV] ?? "");
18
20
  function logErr(msg) {
19
21
  process.stderr.write(`[remote-oauth-proxy:${label}] ${msg}
20
22
  `);
21
23
  }
24
+ function parseToolAllowlist(raw) {
25
+ const out = /* @__PURE__ */ new Set();
26
+ for (const part of (raw || "").split(",")) {
27
+ const name = part.trim();
28
+ if (name) out.add(name);
29
+ }
30
+ return out;
31
+ }
32
+ function filterToolsListMessage(message, allow) {
33
+ if (allow.size === 0) return { message, total: 0, kept: 0, advertised: [] };
34
+ let obj;
35
+ try {
36
+ obj = JSON.parse(message);
37
+ } catch {
38
+ return { message, total: 0, kept: 0, advertised: [] };
39
+ }
40
+ const result = obj?.result;
41
+ const tools = result?.tools;
42
+ if (!Array.isArray(tools)) return { message, total: 0, kept: 0, advertised: [] };
43
+ const nameOf = (t) => t && typeof t === "object" && typeof t.name === "string" ? t.name : "";
44
+ const advertised = tools.map(nameOf).filter((n) => n.length > 0);
45
+ const filtered = tools.filter((t) => allow.has(nameOf(t)));
46
+ result.tools = filtered;
47
+ return { message: JSON.stringify(obj), total: tools.length, kept: filtered.length, advertised };
48
+ }
49
+ function isToolCallBlocked(method, params, allow) {
50
+ if (allow.size === 0 || method !== "tools/call") return { blocked: false, name: "" };
51
+ const name = params && typeof params === "object" && typeof params.name === "string" ? params.name : "";
52
+ if (name && !allow.has(name)) return { blocked: true, name };
53
+ return { blocked: false, name };
54
+ }
22
55
  function readCurrentToken(file, varName) {
23
56
  let raw;
24
57
  try {
@@ -71,7 +104,7 @@ function extractJsonRpcMessages(contentType, body) {
71
104
  }
72
105
  return out;
73
106
  }
74
- async function forward(line, id, isNotification) {
107
+ async function forward(line, id, isNotification, method) {
75
108
  const token = readCurrentToken(tokenFile, tokenVar);
76
109
  if (!token) {
77
110
  logErr(`no token in ${tokenFile} (var ${tokenVar})`);
@@ -102,7 +135,24 @@ async function forward(line, id, isNotification) {
102
135
  }
103
136
  if (isNotification) return [];
104
137
  const messages = extractJsonRpcMessages(ct, body);
105
- if (messages.length > 0) return messages;
138
+ if (messages.length > 0) {
139
+ if (method === "tools/list" && toolAllowlist.size > 0) {
140
+ return messages.map((m) => {
141
+ const r = filterToolsListMessage(m, toolAllowlist);
142
+ if (r.total !== r.kept) {
143
+ logErr(`tools/list filtered ${r.total} -> ${r.kept} (allowlist ${toolAllowlist.size})`);
144
+ }
145
+ if (r.advertised.length > 0) {
146
+ const missing = [...toolAllowlist].filter((n) => !r.advertised.includes(n));
147
+ if (missing.length > 0) {
148
+ logErr(`allowlisted tools not advertised by server: ${missing.join(", ")}`);
149
+ }
150
+ }
151
+ return r.message;
152
+ });
153
+ }
154
+ return messages;
155
+ }
106
156
  const detail = body.slice(0, 300).replace(/\s+/g, " ").trim();
107
157
  return [jsonRpcError(id, -32002, `${label}: MCP server returned HTTP ${res.status}${detail ? ` (${detail})` : ""}`)];
108
158
  }
@@ -139,7 +189,19 @@ async function main() {
139
189
  }
140
190
  const isNotification = !("id" in parsed);
141
191
  const id = parsed.id;
142
- const task = forward(text, id, isNotification).then(writeReplies).catch((err) => {
192
+ if (!isNotification) {
193
+ const block = isToolCallBlocked(parsed.method, parsed.params, toolAllowlist);
194
+ if (block.blocked) {
195
+ logErr(`blocked tools/call to non-allowlisted tool "${block.name}"`);
196
+ const task2 = writeReplies([
197
+ jsonRpcError(id, -32601, `${label}: tool "${block.name}" is not enabled for this integration`)
198
+ ]).catch((err) => logErr(`handler error: ${err.message}`));
199
+ inflight.add(task2);
200
+ void task2.finally(() => inflight.delete(task2));
201
+ return;
202
+ }
203
+ }
204
+ const task = forward(text, id, isNotification, parsed.method).then(writeReplies).catch((err) => {
143
205
  logErr(`handler error: ${err.message}`);
144
206
  });
145
207
  inflight.add(task);
@@ -163,6 +225,9 @@ if (invokedDirectly) {
163
225
  }
164
226
  export {
165
227
  extractJsonRpcMessages,
228
+ filterToolsListMessage,
229
+ isToolCallBlocked,
166
230
  main,
231
+ parseToolAllowlist,
167
232
  readCurrentToken
168
233
  };
@@ -16359,10 +16359,16 @@ function parseAllowedUsersCsv(raw) {
16359
16359
  );
16360
16360
  }
16361
16361
  function extractAllowedUsersFromMcpJson(jsonText) {
16362
+ return extractSlackEnvAllowlistFromMcpJson(jsonText, "SLACK_ALLOWED_USERS");
16363
+ }
16364
+ function extractPingAllowedUsersFromMcpJson(jsonText) {
16365
+ return extractSlackEnvAllowlistFromMcpJson(jsonText, "SLACK_PING_ALLOWED_USERS");
16366
+ }
16367
+ function extractSlackEnvAllowlistFromMcpJson(jsonText, envKey) {
16362
16368
  const parsed = JSON.parse(jsonText);
16363
16369
  const slackServer = parsed.mcpServers?.["slack"];
16364
16370
  if (!slackServer) return null;
16365
- return parseAllowedUsersCsv(slackServer.env?.["SLACK_ALLOWED_USERS"]);
16371
+ return parseAllowedUsersCsv(slackServer.env?.[envKey]);
16366
16372
  }
16367
16373
 
16368
16374
  // src/slack-response-mode.ts
@@ -17178,6 +17184,7 @@ async function maybeSendMaintenanceNotice(args) {
17178
17184
  }
17179
17185
  var BLOCK_KIT_DISABLED = process.env.SLACK_BLOCK_KIT_DISABLED === "true";
17180
17186
  var ALLOWED_USERS = parseAllowedUsersCsv(process.env.SLACK_ALLOWED_USERS);
17187
+ var PING_ALLOWED_USERS = parseAllowedUsersCsv(process.env.SLACK_PING_ALLOWED_USERS);
17181
17188
  var THREAD_AUTO_FOLLOW = process.env.SLACK_THREAD_AUTO_FOLLOW ?? "off";
17182
17189
  var SLACK_SKIP_REACTION = (process.env.SLACK_SKIP_REACTION ?? "").trim();
17183
17190
  var SLACK_ACK_REACTION = (process.env.SLACK_ACK_REACTION ?? "").trim() || "eyes";
@@ -17255,6 +17262,27 @@ function readLiveAllowedUsers() {
17255
17262
  function getEffectiveAllowedUsers() {
17256
17263
  return readLiveAllowedUsers() ?? ALLOWED_USERS;
17257
17264
  }
17265
+ var livePingAllowedUsersCache = null;
17266
+ function readLivePingAllowedUsers() {
17267
+ if (!SLACK_MCP_CONFIG_PATH) return null;
17268
+ try {
17269
+ const mtimeMs = statSync2(SLACK_MCP_CONFIG_PATH).mtimeMs;
17270
+ if (livePingAllowedUsersCache && livePingAllowedUsersCache.mtimeMs === mtimeMs) {
17271
+ return livePingAllowedUsersCache.value;
17272
+ }
17273
+ const value = extractPingAllowedUsersFromMcpJson(
17274
+ readFileSync10(SLACK_MCP_CONFIG_PATH, "utf-8")
17275
+ );
17276
+ if (value === null) return null;
17277
+ livePingAllowedUsersCache = { mtimeMs, value };
17278
+ return value;
17279
+ } catch {
17280
+ return null;
17281
+ }
17282
+ }
17283
+ function getEffectivePingAllowedUsers() {
17284
+ return readLivePingAllowedUsers() ?? PING_ALLOWED_USERS;
17285
+ }
17258
17286
  var SLACK_PENDING_INBOUND_DIR = SLACK_AGENT_DIR ? join8(SLACK_AGENT_DIR, "slack-pending-inbound") : null;
17259
17287
  var SLACK_RECOVERY_OUTBOX_DIR = SLACK_AGENT_DIR ? join8(SLACK_AGENT_DIR, "slack-recovery-outbox") : null;
17260
17288
  var SLACK_RESTART_CONFIRM_FILE = SLACK_AGENT_DIR ? join8(SLACK_AGENT_DIR, "slack-restart-confirm.json") : null;
@@ -18282,6 +18310,7 @@ function buildSlackHelpMessage(codeName) {
18282
18310
  `\u2022 \`${agentSlashCommand("/onboard")}\` \u2014 re-run this agent's onboarding: re-interview, existing config kept (allowlisted users)`,
18283
18311
  `\u2022 \`${agentSlashCommand("/resume-onboarding")}\` \u2014 resume this agent's onboarding where it left off (allowlisted users)`,
18284
18312
  `\u2022 \`${agentSlashCommand("/status")}\` \u2014 this agent's model, session origin, uptime + connectivity`,
18313
+ `\u2022 \`${agentSlashCommand("/ping")}\` - confirm this agent's channel is connected: posts a visible pong (team + manager only)`,
18285
18314
  "\u2022 `/watch <google-doc-url> [duration]` (type it in chat) \u2014 watch a Google Doc for comments that mention me (default 2h, max 7d; auto-pauses when the window ends). In a shared channel, address me as `/watch-<my-name>`.",
18286
18315
  "\u2022 `/kill` \u2014 silence all agents in this thread for 6h (use as a thread reply)",
18287
18316
  "\u2022 `/unkill` \u2014 clear a kill (use as a thread reply)",
@@ -18780,6 +18809,46 @@ async function handleSlashCommandEnvelope(payload) {
18780
18809
  }
18781
18810
  return;
18782
18811
  }
18812
+ if (matchesAgentCommand(command, "/ping")) {
18813
+ if (!payload.channel_id) {
18814
+ await postEphemeralViaResponseUrl(
18815
+ responseUrl,
18816
+ `:warning: \`/ping\` needs a channel context - invoke it in a channel or DM where \`${codeName}\` is present.`,
18817
+ codeName
18818
+ );
18819
+ return;
18820
+ }
18821
+ const pingAllowed = getEffectivePingAllowedUsers();
18822
+ if (pingAllowed.size === 0 || !payload.user_id || !pingAllowed.has(payload.user_id)) {
18823
+ process.stderr.write(
18824
+ `slack-channel(${codeName}): /ping denied - user not in SLACK_PING_ALLOWED_USERS
18825
+ `
18826
+ );
18827
+ await postEphemeralViaResponseUrl(
18828
+ responseUrl,
18829
+ `\u{1F6AB} \`/ping\` is limited to \`${codeName}\`'s team and the person it reports to. If that's you, link your Slack in your Augmented Team contact preferences and wait for the next refresh.`,
18830
+ codeName
18831
+ );
18832
+ return;
18833
+ }
18834
+ const connected = currentWs != null && !isShuttingDown;
18835
+ const dot = connected ? "\u{1F7E2}" : "\u{1F534}";
18836
+ const state = connected ? "online" : "offline";
18837
+ const pong = `${dot} pong - \`${codeName}\` is ${state} (manager \u2022 ${(/* @__PURE__ */ new Date()).toISOString()}). Last activity: ${formatLastActivity()}.`;
18838
+ const sent = await postSlackMessage({
18839
+ channel: payload.channel_id,
18840
+ text: pong,
18841
+ ...payload.thread_ts ? { thread_ts: payload.thread_ts } : {}
18842
+ });
18843
+ if (!sent.ok) {
18844
+ await postEphemeralViaResponseUrl(
18845
+ responseUrl,
18846
+ `\u274C \`/ping\` could not post to this channel: ${sent.error ?? "unknown error"}. The channel may not be connected.`,
18847
+ codeName
18848
+ );
18849
+ }
18850
+ return;
18851
+ }
18783
18852
  }
18784
18853
  async function handleHelpCommand(opts) {
18785
18854
  const codeName = AGENT_CODE_NAME ?? "unknown";
@@ -16924,6 +16924,9 @@ var ALLOWED_CHATS = new Set(
16924
16924
  var DIAGNOSTIC_CHAT_IDS = new Set(
16925
16925
  (process.env.TELEGRAM_DIAGNOSTIC_CHAT_IDS ?? "").split(",").map((s) => s.trim()).filter(Boolean)
16926
16926
  );
16927
+ var PING_ALLOWED_CHAT_IDS = new Set(
16928
+ (process.env.TELEGRAM_PING_ALLOWED_CHAT_IDS ?? "").split(",").map((s) => s.trim()).filter(Boolean)
16929
+ );
16927
16930
  var PEER_CLASSIFIER_CONFIG = {
16928
16931
  peer_agent_mode: parsePeerAgentModeEnv(process.env.TELEGRAM_PEER_AGENT_MODE),
16929
16932
  peer_group_ids: parsePeerGroupIdsEnv(process.env.TELEGRAM_PEER_GROUP_IDS),
@@ -17354,6 +17357,7 @@ function buildTelegramHelpMessage(codeName) {
17354
17357
  `_Type these in any chat where the bot is present (intercepted by the agent):_`,
17355
17358
  `\u2022 /help \u2014 show this help`,
17356
17359
  `\u2022 /status \u2014 this agent's model, session origin, uptime + connectivity`,
17360
+ `\u2022 /ping-${codeName} - confirm this agent's channel is connected: posts a visible pong (team members and the agent's reports-to person)`,
17357
17361
  `\u2022 /watch <google-doc-url> [duration] \u2014 watch a Google Doc for comments that mention me (default 2h, max 7d; auto-pauses when the window ends)`,
17358
17362
  `\u2022 /restart \u2014 restart this agent`,
17359
17363
  `\u2022 /onboard \u2014 re-run this agent's onboarding: re-interview, existing config kept`,
@@ -17915,6 +17919,24 @@ var STATUS_SYNTAX_RE = /^\/status(?:@([A-Za-z0-9_]{1,64}))?(?:\s|$)/;
17915
17919
  function isStatusSyntax(text) {
17916
17920
  return STATUS_SYNTAX_RE.test(text);
17917
17921
  }
17922
+ var PING_SYNTAX_RE = /^\/ping(?:-([a-z0-9-]+))?(?:@([A-Za-z0-9_]{1,64}))?(?:\s|$)/i;
17923
+ function isPingSyntax(text) {
17924
+ return PING_SYNTAX_RE.test(text);
17925
+ }
17926
+ async function classifyPingCommand(text) {
17927
+ const m = PING_SYNTAX_RE.exec(text);
17928
+ if (!m) return "ignore";
17929
+ const codeSuffix = m[1];
17930
+ const botSuffix = m[2];
17931
+ if (codeSuffix && codeSuffix.toLowerCase() !== AGENT_CODE_NAME.toLowerCase()) {
17932
+ return "ignore";
17933
+ }
17934
+ if (botSuffix) {
17935
+ const ours = (await resolveBotIdentity()).bot_username;
17936
+ if (ours && botSuffix.toLowerCase() !== ours.toLowerCase()) return "ignore";
17937
+ }
17938
+ return "act";
17939
+ }
17918
17940
  var WATCH_SYNTAX_RE = /^\/watch(?:@([A-Za-z0-9_]{1,64}))?(?:\s|$)/;
17919
17941
  function isWatchSyntax(text) {
17920
17942
  return WATCH_SYNTAX_RE.test(text);
@@ -19447,7 +19469,7 @@ async function pollLoop() {
19447
19469
  const trimmedContent = content.trim();
19448
19470
  const isFromBot = !!msg.from?.is_bot;
19449
19471
  const nowMs = Date.now();
19450
- const telegramCommand = isHelpSyntax(trimmedContent) ? "help" : isStatusSyntax(trimmedContent) ? "status" : isWatchSyntax(trimmedContent) ? "watch" : (
19472
+ const telegramCommand = isHelpSyntax(trimmedContent) ? "help" : isStatusSyntax(trimmedContent) ? "status" : isPingSyntax(trimmedContent) ? "ping" : isWatchSyntax(trimmedContent) ? "watch" : (
19451
19473
  // ENG-6511: check /resume-onboarding before /onboard for clarity
19452
19474
  // (the prefixes are disjoint, so order is not load-bearing).
19453
19475
  isResumeOnboardingSyntax(trimmedContent) ? "resume-onboarding" : isOnboardSyntax(trimmedContent) ? "onboard" : isRestartSyntax(trimmedContent) ? "restart" : isInvestigateSyntax(trimmedContent) ? "investigate" : void 0
@@ -19623,6 +19645,46 @@ async function pollLoop() {
19623
19645
  } catch (err) {
19624
19646
  process.stderr.write(
19625
19647
  `telegram-channel(${AGENT_CODE_NAME}): /investigate verification-failed ack send failed: ${redactAugmentedPaths(err.message)}
19648
+ `
19649
+ );
19650
+ }
19651
+ }
19652
+ continue;
19653
+ }
19654
+ if (access.kind === "command" && access.command === "ping") {
19655
+ const disposition = await classifyPingCommand(trimmedContent);
19656
+ if (disposition === "act") {
19657
+ const senderId = msg.from?.id != null ? String(msg.from.id) : null;
19658
+ const authorized = PING_ALLOWED_CHAT_IDS.size > 0 && senderId != null && PING_ALLOWED_CHAT_IDS.has(senderId);
19659
+ try {
19660
+ if (!authorized) {
19661
+ process.stderr.write(
19662
+ `telegram-channel(${AGENT_CODE_NAME}): /ping denied - sender not in TELEGRAM_PING_ALLOWED_CHAT_IDS
19663
+ `
19664
+ );
19665
+ await telegramApiCall(
19666
+ "sendMessage",
19667
+ {
19668
+ chat_id: chatId,
19669
+ text: `\u{1F6AB} /ping is limited to ${AGENT_CODE_NAME}'s team and the person it reports to. If that's you, link your Telegram in your Augmented Team contact preferences and wait for the next refresh.`,
19670
+ reply_to_message_id: Number(msg.message_id)
19671
+ },
19672
+ 1e4
19673
+ );
19674
+ } else {
19675
+ await telegramApiCall(
19676
+ "sendMessage",
19677
+ {
19678
+ chat_id: chatId,
19679
+ text: `\u{1F7E2} pong - ${AGENT_CODE_NAME} is online (manager \u2022 ${(/* @__PURE__ */ new Date()).toISOString()}).`,
19680
+ reply_to_message_id: Number(msg.message_id)
19681
+ },
19682
+ 1e4
19683
+ );
19684
+ }
19685
+ } catch (err) {
19686
+ process.stderr.write(
19687
+ `telegram-channel(${AGENT_CODE_NAME}): /ping reply send failed: ${redactAugmentedPaths(err.message)}
19626
19688
  `
19627
19689
  );
19628
19690
  }
@@ -34,8 +34,8 @@ import {
34
34
  writeDirectChatSessionState,
35
35
  writeEgressAllowlist,
36
36
  writePersistentClaudeWrapper
37
- } from "./chunk-2D5COEAS.js";
38
- import "./chunk-CQZDKD2U.js";
37
+ } from "./chunk-OW6ERQHP.js";
38
+ import "./chunk-MTKFDGXO.js";
39
39
  import "./chunk-XWVM4KPK.js";
40
40
  export {
41
41
  EGRESS_BASELINE_DOMAINS,
@@ -74,4 +74,4 @@ export {
74
74
  writeEgressAllowlist,
75
75
  writePersistentClaudeWrapper
76
76
  };
77
- //# sourceMappingURL=persistent-session-3AC6FSX6.js.map
77
+ //# sourceMappingURL=persistent-session-3ACIT7F5.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  paneLogPath
3
- } from "./chunk-2D5COEAS.js";
4
- import "./chunk-CQZDKD2U.js";
3
+ } from "./chunk-OW6ERQHP.js";
4
+ import "./chunk-MTKFDGXO.js";
5
5
  import "./chunk-XWVM4KPK.js";
6
6
 
7
7
  // src/lib/responsiveness-probe.ts
@@ -304,4 +304,4 @@ export {
304
304
  readAndResetChannelDeflections,
305
305
  readAndResetChannelLaneClassifications
306
306
  };
307
- //# sourceMappingURL=responsiveness-probe-ZXB5REIY.js.map
307
+ //# sourceMappingURL=responsiveness-probe-5OCWCS3M.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@integrity-labs/agt-cli",
3
- "version": "0.28.161",
3
+ "version": "0.28.163",
4
4
  "description": "Augmented Team CLI — agent provisioning and management",
5
5
  "type": "module",
6
6
  "engines": {