@integrity-labs/agt-cli 0.28.1077 → 0.28.1079

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.
package/dist/bin/agt.js CHANGED
@@ -40,12 +40,12 @@ import {
40
40
  success,
41
41
  table,
42
42
  warn
43
- } from "../chunk-RAIBOJ2A.js";
43
+ } from "../chunk-TTSW5ZM2.js";
44
44
  import {
45
45
  getProjectDir,
46
46
  isSessionResumeDisabled,
47
47
  readDirectChatSessionState
48
- } from "../chunk-QNS7N4QX.js";
48
+ } from "../chunk-OGMCA67P.js";
49
49
  import {
50
50
  AnchorSessionClient,
51
51
  CHANNEL_REGISTRY,
@@ -79,7 +79,7 @@ import {
79
79
  serializeManifestForSlackCli,
80
80
  sessionFileExists,
81
81
  sessionTranscriptDir
82
- } from "../chunk-4WAUXFY7.js";
82
+ } from "../chunk-5SASCNYV.js";
83
83
  import "../chunk-OCMJ5E6J.js";
84
84
  import "../chunk-XWVM4KPK.js";
85
85
  import "../chunk-EL5MWGGH.js";
@@ -5474,7 +5474,7 @@ import { execFileSync, execSync } from "child_process";
5474
5474
  import { existsSync as existsSync11, realpathSync as realpathSync2 } from "fs";
5475
5475
  import chalk18 from "chalk";
5476
5476
  import ora16 from "ora";
5477
- var cliVersion = true ? "0.28.1077" : "dev";
5477
+ var cliVersion = true ? "0.28.1079" : "dev";
5478
5478
  async function fetchLatestVersion() {
5479
5479
  const host2 = getHost();
5480
5480
  if (!host2) return null;
@@ -6734,7 +6734,7 @@ function handleError(err) {
6734
6734
  }
6735
6735
 
6736
6736
  // src/bin/agt.ts
6737
- var cliVersion2 = true ? "0.28.1077" : "dev";
6737
+ var cliVersion2 = true ? "0.28.1079" : "dev";
6738
6738
  var program = new Command();
6739
6739
  program.name("agt").description("Augmented CLI \u2014 agent provisioning and management").version(cliVersion2).option("--json", "Emit machine-readable JSON output (suppress spinners and colors)").option("--skip-update-check", "Skip the automatic update check on startup");
6740
6740
  program.hook("preAction", async (thisCommand, actionCommand) => {
@@ -1170,6 +1170,34 @@ function formatEmptyChannelAllowlistLines() {
1170
1170
  ` the removal (ENG-9663).`
1171
1171
  ];
1172
1172
  }
1173
+ var EMAIL_MAIL_RULES_DEF = "email.mail_rules";
1174
+ var MAIL_RULE_DISPOSITION_TEXT = {
1175
+ egress: "forwards or redirects mail to another address",
1176
+ suppression: "hides mail from its owner (trash, delete, archive or mark as read)",
1177
+ opaque: "has an effect that can't be read from the request (including deleting a rule)"
1178
+ };
1179
+ function formatMailRuleHoldLines(hold) {
1180
+ const which = hold.heldDispositions.map((d) => ` - a rule that ${MAIL_RULE_DISPOSITION_TEXT[d] ?? d}`);
1181
+ if (hold.live) {
1182
+ return [
1183
+ ` The platform holds these mail-rule changes for an Approve/Deny card, and approving`,
1184
+ ` the card releases the change:`,
1185
+ ...which,
1186
+ ` When asked for one, attempt it: do not decline on this guardrail's basis. Tell the`,
1187
+ ` user it is waiting for approval, and do not say it was made until it is approved.`
1188
+ ];
1189
+ }
1190
+ return [` Not held by the platform yet: these mail-rule changes go through and are only recorded:`, ...which];
1191
+ }
1192
+ function effectiveMailRuleEnforcement(g) {
1193
+ if (g.definitionId !== EMAIL_MAIL_RULES_DEF)
1194
+ return g.enforcement;
1195
+ if (g.mailRuleHold === void 0)
1196
+ return g.enforcement;
1197
+ if (g.enforcement !== "enforce")
1198
+ return g.enforcement;
1199
+ return g.mailRuleHold.live ? "warn" : "log";
1200
+ }
1173
1201
  function renderGuardrailBullet(g) {
1174
1202
  const lines = [];
1175
1203
  const header = `- **${g.displayName}** (${g.category}, from ${g.source})`;
@@ -1177,7 +1205,7 @@ function renderGuardrailBullet(g) {
1177
1205
  if (g.description?.trim()) {
1178
1206
  lines.push(` ${g.description.trim()}`);
1179
1207
  }
1180
- lines.push(...g.definitionId === EMAIL_DOMAIN_RESTRICT_DEF ? formatEmailDomainConfigLines(g.config) : g.definitionId === CALENDAR_CONFIDENTIALITY_DEF ? formatCalendarConfidentialityLines(g.config) : (
1208
+ lines.push(...g.definitionId === EMAIL_DOMAIN_RESTRICT_DEF ? formatEmailDomainConfigLines(g.config) : g.definitionId === CALENDAR_CONFIDENTIALITY_DEF ? formatCalendarConfidentialityLines(g.config) : g.definitionId === EMAIL_MAIL_RULES_DEF && g.mailRuleHold ? formatMailRuleHoldLines(g.mailRuleHold) : (
1181
1209
  // ENG-9663: checked AFTER the two named formatters, so an email or
1182
1210
  // calendar guardrail can never be captured by the structural match.
1183
1211
  hasEmptyChannelAllowlist(g) ? formatEmptyChannelAllowlistLines() : formatConfigLines(g.config)
@@ -1197,16 +1225,18 @@ var REQUIRE_APPROVAL_HOW = {
1197
1225
  ` with the request_id and act only once it is approved; if it is denied or expires, do`,
1198
1226
  ` not act, and tell the user. Never just say you are waiting for, or cannot reach, your`,
1199
1227
  ` manager without filing the request. If \`request_approval\` fails, say so and leave the`,
1200
- ` action undone. For an email, pass \`detail.email\` = { to, from, subject } so your`,
1201
- ` manager sees who it goes to.`
1228
+ ` action undone.`
1202
1229
  ],
1203
1230
  warn: [
1204
1231
  ` When one of these actions is not clearly justified, ask rather than decline: call`,
1205
1232
  ` \`request_approval\` (it goes to your manager), end your turn, and act only once`,
1206
- ` \`check_approval\` says it is approved. For an email, pass \`detail.email\` =`,
1207
- ` { to, from, subject }.`
1233
+ ` \`check_approval\` says it is approved.`
1208
1234
  ]
1209
1235
  };
1236
+ var REQUIRE_APPROVAL_EMAIL_DETAIL = [
1237
+ ` For an email, pass \`detail.email\` = { to, from, subject } so your manager sees who it`,
1238
+ ` goes to.`
1239
+ ];
1210
1240
  var REQUIRE_APPROVAL_EMAIL_ACTION = "send_email";
1211
1241
  var EMAIL_REQUIRE_APPROVAL_DEF = "email.require_approval";
1212
1242
  function liveEmailHoldActions(guardrails) {
@@ -1223,7 +1253,8 @@ function requireApprovalEmailException(covered) {
1223
1253
  ` email approval hold puts every such send in front of a human, so for those do not call`,
1224
1254
  ` \`request_approval\` and do not decline on this guardrail's basis. Attempt the send and let`,
1225
1255
  ` that hold decide; asking first would make your manager approve the same email twice. Any`,
1226
- ` other way of sending email is not held: ask first with \`request_approval\`.`
1256
+ ` other way of sending email is not held: ask first with \`request_approval\`, and when you`,
1257
+ ` do, pass \`detail.email\` = { to, from, subject } so your manager sees who it goes to.`
1227
1258
  ];
1228
1259
  }
1229
1260
  function requireApprovalActions(config) {
@@ -1237,9 +1268,11 @@ function requireApprovalHowLines(g, level, emailHold) {
1237
1268
  const actions = requireApprovalActions(g.config);
1238
1269
  const namesEmail = actions === null || actions.includes(REQUIRE_APPROVAL_EMAIL_ACTION);
1239
1270
  const namesOther = actions === null || actions.some((a) => a !== REQUIRE_APPROVAL_EMAIL_ACTION);
1240
- const ask = namesOther || namesEmail && emailHold === null;
1271
+ const asksAboutEmail = namesEmail && emailHold === null;
1272
+ const ask = namesOther || asksAboutEmail;
1241
1273
  return [
1242
1274
  ...ask ? REQUIRE_APPROVAL_HOW[level] : [],
1275
+ ...asksAboutEmail ? REQUIRE_APPROVAL_EMAIL_DETAIL : [],
1243
1276
  ...namesEmail && emailHold !== null ? requireApprovalEmailException(emailHold) : []
1244
1277
  ];
1245
1278
  }
@@ -1306,9 +1339,12 @@ function buildGuardrailsSection(guardrails) {
1306
1339
  const active = guardrails.map((g) => {
1307
1340
  const enforcement = effectiveChannelAllowlistEnforcement({
1308
1341
  ...g,
1309
- enforcement: effectiveEmailEnforcement({
1342
+ enforcement: effectiveMailRuleEnforcement({
1310
1343
  ...g,
1311
- enforcement: effectiveCalendarEnforcement(g)
1344
+ enforcement: effectiveEmailEnforcement({
1345
+ ...g,
1346
+ enforcement: effectiveCalendarEnforcement(g)
1347
+ })
1312
1348
  })
1313
1349
  });
1314
1350
  return { ...g, enforcement };
@@ -7122,6 +7158,17 @@ var FLAG_REGISTRY = [
7122
7158
  // It widens who may DECIDE an approval, so it is a control, not a display toggle.
7123
7159
  sensitive: true
7124
7160
  },
7161
+ {
7162
+ key: "approval-unified-authority",
7163
+ description: "One authority check for every approval ingress (ENG-11207, ADR-0124 Phase 0b): canDecide() runs inside tryDispatchApprovalCore for console, Slack (channel, alerts, Socket Mode, which also carries Telegram) and Direct Chat taps alike. off = not computed. shadow = compute the verdict and log approval_authority_would_reject (ingress, verb, org, reason) for every tap it would refuse, then decide exactly as today. enforce = reserved for the per-(org, verb) allowlist slice; until that ships it behaves as shadow. Evaluated per-org. Ships dark.",
7164
+ flagType: "enum",
7165
+ allowedValues: ["off", "shadow", "enforce"],
7166
+ // Safe/default value is `off` (no computation, no extra reads on the tap path). A flag-DB read
7167
+ // error degrades to this, so an outage can never change who may decide.
7168
+ defaultValue: "off",
7169
+ // Its enforce value will refuse approvals, so mutating it is worth confirming.
7170
+ sensitive: true
7171
+ },
7125
7172
  {
7126
7173
  key: "slack-reply-binding",
7127
7174
  description: "Slack reply-target binding (ENG-7396 / WS2, cross-thread reply routing): the model names which inbound it answers (inbound_id) and the server resolves the destination from its own verified record. shadow = classify + count only, routing unchanged; warn = same routing plus a tool-result note so the model self-corrects; enforce = route a bound reply to the registry thread and REJECT a reply whose target matches no inbound this process delivered. The channel server can't evaluate flags, so the manager materializes the resolved value into the AGT_SLACK_REPLY_BINDING spawn env (the operator/canary override, ADR-0022). Ships shadow.",
@@ -13057,6 +13104,11 @@ var QUOTA_EXHAUSTED_ERROR_PATTERNS = [
13057
13104
  "usage limit",
13058
13105
  "daily limit exceeded"
13059
13106
  ];
13107
+ var PROVIDER_ACCESS_BLOCKED_ERROR_PATTERNS = [
13108
+ "api access blocked",
13109
+ "api access has been blocked",
13110
+ "api access is blocked"
13111
+ ];
13060
13112
  function isReadonlyToolDescriptor(t) {
13061
13113
  if (!t?.name)
13062
13114
  return false;
@@ -13149,6 +13201,10 @@ function formatRetryWindow(seconds) {
13149
13201
  return `about ${Math.round(hours * 10) / 10} hours`;
13150
13202
  return `about ${Math.round(hours / 24 * 10) / 10} days`;
13151
13203
  }
13204
+ function isProviderAccessBlockedError(message) {
13205
+ const m = message.toLowerCase();
13206
+ return PROVIDER_ACCESS_BLOCKED_ERROR_PATTERNS.some((p2) => m.includes(p2));
13207
+ }
13152
13208
  function classifyToolCallFailure(text) {
13153
13209
  if (isAccountResolutionError(text))
13154
13210
  return "account";
@@ -13156,6 +13212,8 @@ function classifyToolCallFailure(text) {
13156
13212
  return "quota";
13157
13213
  if (isScopeDeficitError(text))
13158
13214
  return "scope";
13215
+ if (isProviderAccessBlockedError(text))
13216
+ return "blocked";
13159
13217
  if (isUpstreamAuthError(text))
13160
13218
  return "auth";
13161
13219
  if (isSiteResolutionError(text))
@@ -13308,6 +13366,13 @@ async function probeComposioMcpToolCall(config, fetchImpl = fetch) {
13308
13366
  details: { ...baseDetails, reason: "upstream_auth_rejected" }
13309
13367
  };
13310
13368
  }
13369
+ if (kind === "blocked") {
13370
+ return {
13371
+ status: "degraded",
13372
+ message: `Live tool call '${toolName}' reached the provider, which refused API access for this connection's account or app. The credential itself was accepted, so reconnecting alone will not fix it: check that the connecting user still has a role on the account and that the account is not restricted with the provider, then reconnect: ${snippet}`,
13373
+ details: { ...baseDetails, reason: "provider_access_blocked" }
13374
+ };
13375
+ }
13311
13376
  if (kind === "site") {
13312
13377
  return {
13313
13378
  status: "down",
@@ -13315,6 +13380,13 @@ async function probeComposioMcpToolCall(config, fetchImpl = fetch) {
13315
13380
  details: { ...baseDetails, reason: "site_unresolved" }
13316
13381
  };
13317
13382
  }
13383
+ if (resolved.requestedTool && !resolved.fallback && toolName === resolved.requestedTool) {
13384
+ return {
13385
+ status: "degraded",
13386
+ message: `Live tool call '${toolName}' (this integration's connectivity test) failed with an error the probe does not recognise, so the connection cannot be confirmed working: ${snippet}`,
13387
+ details: { ...baseDetails, reason: "connectivity_test_failed", tool_error: snippet }
13388
+ };
13389
+ }
13318
13390
  return {
13319
13391
  status: "ok",
13320
13392
  message: `Live tool call '${toolName}' resolved the account (tool error: ${snippet})`,
@@ -16127,4 +16199,4 @@ export {
16127
16199
  peekCurrentSession,
16128
16200
  readDailySessionPin
16129
16201
  };
16130
- //# sourceMappingURL=chunk-4WAUXFY7.js.map
16202
+ //# sourceMappingURL=chunk-5SASCNYV.js.map