@integrity-labs/agt-cli 0.28.321 → 0.28.322

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.
@@ -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-ZQSAZIVM.js");
103
+ const { resolveClaudeBinary } = await import("./persistent-session-L6S6HABH.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-DO6OWWGD.js.map
376
+ //# sourceMappingURL=claude-pair-runtime-ZL2U2NZJ.js.map
@@ -43,7 +43,7 @@ import {
43
43
  requireHost,
44
44
  safeWriteJsonAtomic,
45
45
  setConfigHash
46
- } from "../chunk-52RHLSXN.js";
46
+ } from "../chunk-FG7ELAP4.js";
47
47
  import {
48
48
  getProjectDir as getProjectDir2,
49
49
  getReadyTasks,
@@ -132,7 +132,7 @@ import {
132
132
  takeZombieDetection,
133
133
  transcriptActivityAgeSeconds,
134
134
  writeEgressAllowlist
135
- } from "../chunk-NAS4DZNG.js";
135
+ } from "../chunk-LJT3U3GQ.js";
136
136
  import {
137
137
  reapOrphanChannelMcps
138
138
  } from "../chunk-XWVM4KPK.js";
@@ -8309,7 +8309,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
8309
8309
  var lastVersionCheckAt = 0;
8310
8310
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
8311
8311
  var lastResponsivenessProbeAt = 0;
8312
- var agtCliVersion = true ? "0.28.321" : "dev";
8312
+ var agtCliVersion = true ? "0.28.322" : "dev";
8313
8313
  function resolveBrewPath(execFileSync2) {
8314
8314
  try {
8315
8315
  const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -9205,7 +9205,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
9205
9205
  if (codeNames.length === 0) return;
9206
9206
  void (async () => {
9207
9207
  try {
9208
- const { collectDiagnostics } = await import("../persistent-session-ZQSAZIVM.js");
9208
+ const { collectDiagnostics } = await import("../persistent-session-L6S6HABH.js");
9209
9209
  await api.post("/host/heartbeat", {
9210
9210
  host_id: hostId,
9211
9211
  agent_diagnostics: collectDiagnostics(codeNames)
@@ -9304,7 +9304,7 @@ async function pollCycle() {
9304
9304
  }
9305
9305
  try {
9306
9306
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
9307
- const { collectDiagnostics } = await import("../persistent-session-ZQSAZIVM.js");
9307
+ const { collectDiagnostics } = await import("../persistent-session-L6S6HABH.js");
9308
9308
  const diagCodeNames = [...agentState.persistentSessionAgents];
9309
9309
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames) : void 0;
9310
9310
  let tailscaleHostname;
@@ -9453,7 +9453,7 @@ async function pollCycle() {
9453
9453
  const {
9454
9454
  collectResponsivenessProbes,
9455
9455
  getResponsivenessIntervalMs
9456
- } = await import("../responsiveness-probe-NARLJJGH.js");
9456
+ } = await import("../responsiveness-probe-X2WATO46.js");
9457
9457
  const probeIntervalMs = getResponsivenessIntervalMs();
9458
9458
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
9459
9459
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -9485,7 +9485,7 @@ async function pollCycle() {
9485
9485
  collectResponsivenessProbes,
9486
9486
  livePendingInboundOldestAgeSeconds,
9487
9487
  parkPendingInbound
9488
- } = await import("../responsiveness-probe-NARLJJGH.js");
9488
+ } = await import("../responsiveness-probe-X2WATO46.js");
9489
9489
  const { getProjectDir: wedgeProjectDir } = await import("../claude-scheduler-FATCLHDM.js");
9490
9490
  const wedgeNow = /* @__PURE__ */ new Date();
9491
9491
  const liveAgents = agentState.persistentSessionAgents;
@@ -12581,7 +12581,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
12581
12581
  void api.post("/host/restart-ack", { host_id: hostId, agent_id: agentId, restart_requested_at: requestedAt }).catch((err) => log(`[restart-lane] ack failed for '${codeName}': ${err.message}`));
12582
12582
  void (async () => {
12583
12583
  try {
12584
- const { collectDiagnostics } = await import("../persistent-session-ZQSAZIVM.js");
12584
+ const { collectDiagnostics } = await import("../persistent-session-L6S6HABH.js");
12585
12585
  await api.post("/host/heartbeat", {
12586
12586
  host_id: hostId,
12587
12587
  agent_diagnostics: collectDiagnostics([codeName])
@@ -12631,7 +12631,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
12631
12631
  }
12632
12632
  try {
12633
12633
  const hostId = await getHostId();
12634
- const { collectDiagnostics } = await import("../persistent-session-ZQSAZIVM.js");
12634
+ const { collectDiagnostics } = await import("../persistent-session-L6S6HABH.js");
12635
12635
  await api.post("/host/heartbeat", {
12636
12636
  host_id: hostId,
12637
12637
  agent_diagnostics: collectDiagnostics([codeName])
@@ -13099,7 +13099,7 @@ async function processClaudePairSessions(agents) {
13099
13099
  killPairSession,
13100
13100
  pairTmuxSession,
13101
13101
  finalizeClaudePairOnboarding
13102
- } = await import("../claude-pair-runtime-DO6OWWGD.js");
13102
+ } = await import("../claude-pair-runtime-ZL2U2NZJ.js");
13103
13103
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
13104
13104
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
13105
13105
  const killed = await killPairSession(pairTmuxSession(pairId));
@@ -37623,6 +37623,11 @@ var DEFAULT_SCOPES = [
37623
37623
  "reactions:read",
37624
37624
  "reactions:write",
37625
37625
  "users:read",
37626
+ // ENG-7791: needed so users.info returns the sender's email, the join key that
37627
+ // links an inbound Slack sender to their organization_people record (inbound
37628
+ // identity reconcile). Existing installs without it degrade gracefully - the
37629
+ // reconcile no-ops until the bot is re-authorised with the wider scope set.
37630
+ "users:read.email",
37626
37631
  "users.profile:write"
37627
37632
  ];
37628
37633
  var SLACK_SCOPE_PRESETS = {
@@ -18031,8 +18031,76 @@ function createInboundContextClient(args) {
18031
18031
  };
18032
18032
  }
18033
18033
 
18034
- // src/slack-bot-user-id-client.ts
18034
+ // src/reconcile-identity-client.ts
18035
18035
  var REQUEST_TIMEOUT_MS5 = 1e4;
18036
+ function createReconcileIdentityClient(args) {
18037
+ if (!args.agtHost || !args.agtApiKey || !args.agentId) return null;
18038
+ const fetchImpl = args.fetchImpl ?? fetch;
18039
+ const log = args.log ?? (() => {
18040
+ });
18041
+ const base = args.agtHost.replace(/\/+$/, "");
18042
+ const agentId = args.agentId;
18043
+ const apiKey = args.agtApiKey;
18044
+ let cachedToken = null;
18045
+ let cachedTokenExpiresAt = 0;
18046
+ async function getToken() {
18047
+ if (cachedToken && Date.now() < cachedTokenExpiresAt) return cachedToken;
18048
+ const resp = await fetchImpl(`${base}/host/exchange`, {
18049
+ method: "POST",
18050
+ headers: { "Content-Type": "application/json" },
18051
+ // Scope the exchange to this agent (per-agent org gate, ADR-0042 P1).
18052
+ body: JSON.stringify({ host_key: apiKey, agent_id: agentId }),
18053
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS5)
18054
+ });
18055
+ if (!resp.ok) {
18056
+ const body = await resp.text().catch(() => "");
18057
+ throw new Error(`/host/exchange failed (${resp.status}): ${body.slice(0, 200)}`);
18058
+ }
18059
+ const data = await resp.json();
18060
+ cachedToken = data.token;
18061
+ cachedTokenExpiresAt = data.expires_at ? new Date(data.expires_at).getTime() - 12e4 : Date.now() + 55 * 6e4;
18062
+ return cachedToken;
18063
+ }
18064
+ async function postOnce(body) {
18065
+ const token = await getToken();
18066
+ return fetchImpl(`${base}/host/reconcile-sender-identity`, {
18067
+ method: "POST",
18068
+ headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
18069
+ body: JSON.stringify(body),
18070
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS5)
18071
+ });
18072
+ }
18073
+ async function emit(args2) {
18074
+ const body = {
18075
+ agent_id: agentId,
18076
+ platform: args2.platform,
18077
+ sender_id: args2.senderId,
18078
+ email: args2.email
18079
+ };
18080
+ try {
18081
+ let resp = await postOnce(body);
18082
+ if (resp.status === 401) {
18083
+ cachedToken = null;
18084
+ cachedTokenExpiresAt = 0;
18085
+ resp = await postOnce(body);
18086
+ }
18087
+ if (!resp.ok) {
18088
+ const text = await resp.text().catch(() => "");
18089
+ log(`reconcile-identity: POST failed (${resp.status}) platform=${args2.platform}: ${text.slice(0, 200)}`);
18090
+ }
18091
+ } catch (err) {
18092
+ log(`reconcile-identity: emit threw platform=${args2.platform}: ${err.message}`);
18093
+ }
18094
+ }
18095
+ return {
18096
+ reconcile(args2) {
18097
+ void emit(args2);
18098
+ }
18099
+ };
18100
+ }
18101
+
18102
+ // src/slack-bot-user-id-client.ts
18103
+ var REQUEST_TIMEOUT_MS6 = 1e4;
18036
18104
  function createSlackBotUserIdClient(args) {
18037
18105
  if (!args.agtHost || !args.agtApiKey || !args.agentId) return null;
18038
18106
  const fetchImpl = args.fetchImpl ?? fetch;
@@ -18051,7 +18119,7 @@ function createSlackBotUserIdClient(args) {
18051
18119
  headers: { "Content-Type": "application/json" },
18052
18120
  // ENG-7438: scope the exchange to this agent (per-agent org gate, ADR-0042 P1).
18053
18121
  body: JSON.stringify({ host_key: apiKey, agent_id: agentId }),
18054
- signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS5)
18122
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS6)
18055
18123
  });
18056
18124
  if (!resp.ok) {
18057
18125
  const body = await resp.text().catch(() => "");
@@ -18068,7 +18136,7 @@ function createSlackBotUserIdClient(args) {
18068
18136
  method: "POST",
18069
18137
  headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
18070
18138
  body: JSON.stringify({ agent_id: agentId, bot_user_id: botUserId2 }),
18071
- signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS5)
18139
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS6)
18072
18140
  });
18073
18141
  }
18074
18142
  async function emitAsync(botUserId2) {
@@ -18100,7 +18168,7 @@ function createSlackBotUserIdClient(args) {
18100
18168
  method: "POST",
18101
18169
  headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
18102
18170
  body: JSON.stringify({ agent_id: agentId, channel_id: "slack", healthy }),
18103
- signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS5)
18171
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS6)
18104
18172
  });
18105
18173
  };
18106
18174
  try {
@@ -18454,6 +18522,13 @@ var inboundContextClient = createInboundContextClient({
18454
18522
  log: (line) => process.stderr.write(`slack-channel: ${line}
18455
18523
  `)
18456
18524
  });
18525
+ var reconcileIdentityClient = createReconcileIdentityClient({
18526
+ agtHost: AGT_HOST,
18527
+ agtApiKey: AGT_API_KEY,
18528
+ agentId: AGT_AGENT_ID,
18529
+ log: (line) => process.stderr.write(`slack-channel: ${line}
18530
+ `)
18531
+ });
18457
18532
  var kanbanCardActiveClient = createKanbanCardActiveClient({
18458
18533
  agtHost: AGT_HOST,
18459
18534
  agtApiKey: AGT_API_KEY,
@@ -22249,10 +22324,11 @@ var slackReplayTimer = setInterval(() => {
22249
22324
  });
22250
22325
  }, SLACK_REPLAY_SCAN_INTERVAL_MS);
22251
22326
  slackReplayTimer.unref?.();
22252
- var userNameCache = /* @__PURE__ */ new Map();
22253
- async function resolveUserName(userId) {
22254
- if (!userId || userId === "unknown") return userId ?? "unknown";
22255
- const cached2 = userNameCache.get(userId);
22327
+ var userProfileCache = /* @__PURE__ */ new Map();
22328
+ var reconciledSlackSenders = /* @__PURE__ */ new Set();
22329
+ async function resolveUserProfile(userId) {
22330
+ if (!userId || userId === "unknown") return null;
22331
+ const cached2 = userProfileCache.get(userId);
22256
22332
  if (cached2 !== void 0) return cached2;
22257
22333
  try {
22258
22334
  const res = await fetch(
@@ -22260,14 +22336,30 @@ async function resolveUserName(userId) {
22260
22336
  { headers: { Authorization: `Bearer ${BOT_TOKEN}` } }
22261
22337
  );
22262
22338
  const data = await res.json();
22263
- const name = data.user?.profile?.display_name || data.user?.profile?.real_name || userId;
22264
- userNameCache.set(userId, name);
22265
- return name;
22339
+ if (!data.ok) return null;
22340
+ const profile = {
22341
+ name: data.user?.profile?.display_name || data.user?.profile?.real_name || userId,
22342
+ email: data.user?.profile?.email?.trim() || null,
22343
+ isStranger: data.user?.is_stranger === true
22344
+ };
22345
+ userProfileCache.set(userId, profile);
22346
+ return profile;
22266
22347
  } catch {
22267
- userNameCache.set(userId, userId);
22268
- return userId;
22348
+ return null;
22269
22349
  }
22270
22350
  }
22351
+ async function resolveUserName(userId) {
22352
+ if (!userId || userId === "unknown") return userId ?? "unknown";
22353
+ const profile = await resolveUserProfile(userId);
22354
+ return profile?.name ?? userId;
22355
+ }
22356
+ async function resolveUserEmail(userId) {
22357
+ if (!userId || userId === "unknown") return null;
22358
+ const profile = await resolveUserProfile(userId);
22359
+ if (!profile) return null;
22360
+ if (profile.isStranger) return null;
22361
+ return profile.email;
22362
+ }
22271
22363
  var currentWs = null;
22272
22364
  var isShuttingDown = false;
22273
22365
  var acquiredLockPath = null;
@@ -22703,6 +22795,17 @@ async function connectSocketMode() {
22703
22795
  if (channel && !isFromBot && evt.user !== botUserId) {
22704
22796
  resetThread(channel, threadTs);
22705
22797
  }
22798
+ if (reconcileIdentityClient && !isFromBot && evt.user && !reconciledSlackSenders.has(evt.user)) {
22799
+ const senderId = evt.user;
22800
+ reconciledSlackSenders.add(senderId);
22801
+ void resolveUserEmail(senderId).then((email2) => {
22802
+ if (email2) {
22803
+ reconcileIdentityClient.reconcile({ platform: "slack", senderId, email: email2 });
22804
+ } else {
22805
+ reconciledSlackSenders.delete(senderId);
22806
+ }
22807
+ });
22808
+ }
22706
22809
  const isAutoFollowed = !isDirectMessage && evt.type === "message" && isThreadReply && !!threadKey && trackedThreads.has(threadKey);
22707
22810
  const shouldEngage = decideSlackEngagement({
22708
22811
  type: evt.type ?? "message",
@@ -36,7 +36,7 @@ import {
36
36
  writeDirectChatSessionState,
37
37
  writeEgressAllowlist,
38
38
  writePersistentClaudeWrapper
39
- } from "./chunk-NAS4DZNG.js";
39
+ } from "./chunk-LJT3U3GQ.js";
40
40
  import "./chunk-XWVM4KPK.js";
41
41
  export {
42
42
  EGRESS_BASELINE_DOMAINS,
@@ -77,4 +77,4 @@ export {
77
77
  writeEgressAllowlist,
78
78
  writePersistentClaudeWrapper
79
79
  };
80
- //# sourceMappingURL=persistent-session-ZQSAZIVM.js.map
80
+ //# sourceMappingURL=persistent-session-L6S6HABH.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  paneLogPath
3
- } from "./chunk-NAS4DZNG.js";
3
+ } from "./chunk-LJT3U3GQ.js";
4
4
  import "./chunk-XWVM4KPK.js";
5
5
 
6
6
  // src/lib/responsiveness-probe.ts
@@ -427,4 +427,4 @@ export {
427
427
  readAndResetSlackReplyBindingClassifications,
428
428
  readAndResetSlackReplyTargetClassifications
429
429
  };
430
- //# sourceMappingURL=responsiveness-probe-NARLJJGH.js.map
430
+ //# sourceMappingURL=responsiveness-probe-X2WATO46.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@integrity-labs/agt-cli",
3
- "version": "0.28.321",
3
+ "version": "0.28.322",
4
4
  "description": "Augmented Team CLI — agent provisioning and management",
5
5
  "type": "module",
6
6
  "engines": {