@integrity-labs/agt-cli 0.27.118 → 0.27.120

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
@@ -28,7 +28,7 @@ import {
28
28
  success,
29
29
  table,
30
30
  warn
31
- } from "../chunk-WQV2432Z.js";
31
+ } from "../chunk-I2K6JKWP.js";
32
32
  import {
33
33
  CHANNEL_REGISTRY,
34
34
  DEPLOYMENT_TEMPLATES,
@@ -54,7 +54,7 @@ import {
54
54
  renderTemplate,
55
55
  resolveChannels,
56
56
  serializeManifestForSlackCli
57
- } from "../chunk-MTKM655R.js";
57
+ } from "../chunk-Z6JJRLHH.js";
58
58
 
59
59
  // src/bin/agt.ts
60
60
  import { join as join20 } from "path";
@@ -4934,7 +4934,7 @@ import { execFileSync, execSync } from "child_process";
4934
4934
  import { existsSync as existsSync10, realpathSync as realpathSync2 } from "fs";
4935
4935
  import chalk18 from "chalk";
4936
4936
  import ora16 from "ora";
4937
- var cliVersion = true ? "0.27.118" : "dev";
4937
+ var cliVersion = true ? "0.27.120" : "dev";
4938
4938
  async function fetchLatestVersion() {
4939
4939
  const host2 = getHost();
4940
4940
  if (!host2) return null;
@@ -5857,7 +5857,7 @@ function handleError(err) {
5857
5857
  }
5858
5858
 
5859
5859
  // src/bin/agt.ts
5860
- var cliVersion2 = true ? "0.27.118" : "dev";
5860
+ var cliVersion2 = true ? "0.27.120" : "dev";
5861
5861
  var program = new Command();
5862
5862
  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");
5863
5863
  program.hook("preAction", async (thisCommand, actionCommand) => {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  claudeModelAlias,
3
3
  isClaudeFastMode
4
- } from "./chunk-MTKM655R.js";
4
+ } from "./chunk-Z6JJRLHH.js";
5
5
  import {
6
6
  reapOrphanChannelMcps
7
7
  } from "./chunk-XWVM4KPK.js";
@@ -1584,4 +1584,4 @@ export {
1584
1584
  stopAllSessionsAndWait,
1585
1585
  getProjectDir
1586
1586
  };
1587
- //# sourceMappingURL=chunk-IUN5LBTQ.js.map
1587
+ //# sourceMappingURL=chunk-AZEYTJ4L.js.map
@@ -9,7 +9,7 @@ import {
9
9
  parseDeliveryTarget,
10
10
  registerFramework,
11
11
  wrapScheduledTaskPrompt
12
- } from "./chunk-MTKM655R.js";
12
+ } from "./chunk-Z6JJRLHH.js";
13
13
 
14
14
  // ../../packages/core/dist/integrations/registry.js
15
15
  var INTEGRATION_REGISTRY = [
@@ -7603,4 +7603,4 @@ export {
7603
7603
  managerInstallSystemUnitCommand,
7604
7604
  managerUninstallSystemUnitCommand
7605
7605
  };
7606
- //# sourceMappingURL=chunk-WQV2432Z.js.map
7606
+ //# sourceMappingURL=chunk-I2K6JKWP.js.map
@@ -1267,6 +1267,42 @@ var HOURLY_BY_REGION = {
1267
1267
  };
1268
1268
  var KNOWN_PRICING_REGIONS = Object.keys(HOURLY_BY_REGION);
1269
1269
 
1270
+ // ../../packages/core/dist/integrations/composio-linkage.js
1271
+ function assessAuthConfigLinkage(input) {
1272
+ const { accountAuthConfigId, serverAuthConfigIds, serverId } = input;
1273
+ const serverLabel = serverId ? ` (${serverId})` : "";
1274
+ if (serverAuthConfigIds == null || !accountAuthConfigId) {
1275
+ return {
1276
+ linked: null,
1277
+ message: "auth_config linkage not verified \u2014 " + (serverAuthConfigIds == null ? "couldn't read the wired MCP server's auth config binding" : "Composio returned no auth_config for the connected account"),
1278
+ details: {
1279
+ accountAuthConfigId: accountAuthConfigId ?? null,
1280
+ serverAuthConfigIds: serverAuthConfigIds ?? null,
1281
+ serverId: serverId ?? null
1282
+ }
1283
+ };
1284
+ }
1285
+ if (serverAuthConfigIds.length === 0) {
1286
+ return {
1287
+ linked: false,
1288
+ message: `The agent's wired MCP server${serverLabel} has no auth config bound, so it cannot resolve the connected account (bound to auth_config ${accountAuthConfigId}) \u2014 reconnect/rebind required.`,
1289
+ details: { accountAuthConfigId, serverAuthConfigIds, serverId: serverId ?? null }
1290
+ };
1291
+ }
1292
+ if (serverAuthConfigIds.includes(accountAuthConfigId)) {
1293
+ return {
1294
+ linked: true,
1295
+ message: `Connected account's auth_config (${accountAuthConfigId}) matches the wired MCP server binding.`,
1296
+ details: { accountAuthConfigId, serverAuthConfigIds, serverId: serverId ?? null }
1297
+ };
1298
+ }
1299
+ return {
1300
+ linked: false,
1301
+ message: `The connected account is bound to auth_config ${accountAuthConfigId}, but the agent's wired MCP server${serverLabel} resolves auth_config(s) [${serverAuthConfigIds.join(", ")}] \u2014 tool calls will fail with "No connected account found". Reconnect/rebind required.`,
1302
+ details: { accountAuthConfigId, serverAuthConfigIds, serverId: serverId ?? null }
1303
+ };
1304
+ }
1305
+
1270
1306
  // ../../packages/core/dist/integrations/composio-account-probe.js
1271
1307
  var PROBE_TIMEOUT_MS = 1e4;
1272
1308
  var COMPOSIO_API_BASE = "https://backend.composio.dev";
@@ -1350,12 +1386,214 @@ async function probeComposioAccount(params, fetchImpl = fetch) {
1350
1386
  details: { connectedAccountId, status: accountStatus, boundUserId, expectedUserId }
1351
1387
  };
1352
1388
  }
1389
+ const accountAuthConfigId = data.auth_config_id ?? data.auth_config?.id;
1390
+ if (params.serverId) {
1391
+ const serverAuthConfigIds = await fetchServerAuthConfigIds(fetchImpl, base, params.serverId, apiKey);
1392
+ const linkage = assessAuthConfigLinkage({
1393
+ accountAuthConfigId,
1394
+ serverAuthConfigIds,
1395
+ serverId: params.serverId
1396
+ });
1397
+ if (linkage.linked === false) {
1398
+ return {
1399
+ status: "down",
1400
+ message: linkage.message,
1401
+ details: { connectedAccountId, status: accountStatus, boundUserId, ...linkage.details }
1402
+ };
1403
+ }
1404
+ }
1353
1405
  return {
1354
1406
  status: "ok",
1355
1407
  message: `Connected (account ${connectedAccountId}, status=ACTIVE)`,
1356
- details: { connectedAccountId, status: accountStatus, boundUserId }
1408
+ details: {
1409
+ connectedAccountId,
1410
+ status: accountStatus,
1411
+ boundUserId,
1412
+ ...accountAuthConfigId ? { authConfigId: accountAuthConfigId } : {}
1413
+ }
1357
1414
  };
1358
1415
  }
1416
+ async function fetchServerAuthConfigIds(fetchImpl, base, serverId, apiKey) {
1417
+ let res;
1418
+ try {
1419
+ res = await timedFetch(fetchImpl, `${base}/api/v3/mcp/${encodeURIComponent(serverId)}`, { headers: { "x-api-key": apiKey } });
1420
+ } catch {
1421
+ return null;
1422
+ }
1423
+ if (!res.ok)
1424
+ return null;
1425
+ try {
1426
+ const data = await res.json();
1427
+ return data.auth_config_ids ?? data.auth_configs?.map((c) => c.id).filter((id) => typeof id === "string" && id.length > 0) ?? [];
1428
+ } catch {
1429
+ return null;
1430
+ }
1431
+ }
1432
+
1433
+ // ../../packages/core/dist/integrations/composio-tool-call-probe.js
1434
+ var MCP_ACCEPT = "application/json, text/event-stream";
1435
+ var DEFAULT_TIMEOUT_MS = 1e4;
1436
+ var READONLY_VERB_TOKENS = [
1437
+ "LIST",
1438
+ "GET",
1439
+ "FIND",
1440
+ "SEARCH",
1441
+ "FETCH",
1442
+ "COUNT",
1443
+ "RETRIEVE",
1444
+ "READ"
1445
+ ];
1446
+ var ACCOUNT_RESOLUTION_ERROR_PATTERNS = [
1447
+ "no connected account",
1448
+ "connected account not found",
1449
+ "no account found",
1450
+ "could not be resolved",
1451
+ "auth config",
1452
+ "no connection found"
1453
+ ];
1454
+ function pickSafeReadonlyTool(tools) {
1455
+ for (const t of tools) {
1456
+ if (!t?.name)
1457
+ continue;
1458
+ const upper = t.name.toUpperCase();
1459
+ const hasReadVerb = READONLY_VERB_TOKENS.some((v) => upper.includes(v));
1460
+ if (!hasReadVerb)
1461
+ continue;
1462
+ const required = t.inputSchema?.required ?? [];
1463
+ if (Array.isArray(required) && required.length > 0)
1464
+ continue;
1465
+ return t.name;
1466
+ }
1467
+ return null;
1468
+ }
1469
+ function isAccountResolutionError(message) {
1470
+ const m = message.toLowerCase();
1471
+ return ACCOUNT_RESOLUTION_ERROR_PATTERNS.some((p) => m.includes(p));
1472
+ }
1473
+ async function parseRpc(res, expectedId) {
1474
+ const ct = res.headers.get("content-type") ?? "";
1475
+ if (ct.includes("text/event-stream")) {
1476
+ const text = await res.text();
1477
+ let dataLines = [];
1478
+ for (const rawLine of text.split(/\r?\n/)) {
1479
+ if (rawLine.startsWith("data:")) {
1480
+ dataLines.push(rawLine.slice(5).trimStart());
1481
+ continue;
1482
+ }
1483
+ if (rawLine === "" && dataLines.length > 0) {
1484
+ try {
1485
+ const msg2 = JSON.parse(dataLines.join("\n"));
1486
+ if (("result" in msg2 || "error" in msg2) && msg2["id"] === expectedId)
1487
+ return msg2;
1488
+ } catch {
1489
+ }
1490
+ dataLines = [];
1491
+ }
1492
+ }
1493
+ return null;
1494
+ }
1495
+ const msg = await res.json().catch(() => null);
1496
+ if (msg && ("result" in msg || "error" in msg) && msg["id"] === expectedId)
1497
+ return msg;
1498
+ return null;
1499
+ }
1500
+ async function probeComposioMcpToolCall(config, fetchImpl = fetch) {
1501
+ const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
1502
+ const baseHeaders = {
1503
+ ...config.headers ?? {},
1504
+ "Content-Type": "application/json",
1505
+ Accept: MCP_ACCEPT
1506
+ };
1507
+ try {
1508
+ const initRes = await fetchImpl(config.url, {
1509
+ method: "POST",
1510
+ headers: baseHeaders,
1511
+ body: JSON.stringify({
1512
+ jsonrpc: "2.0",
1513
+ id: 1,
1514
+ method: "initialize",
1515
+ params: {
1516
+ protocolVersion: "2025-03-26",
1517
+ capabilities: {},
1518
+ clientInfo: { name: "augmented-toolcall-probe", version: "1.0.0" }
1519
+ }
1520
+ }),
1521
+ signal: AbortSignal.timeout(timeoutMs)
1522
+ });
1523
+ if (!initRes.ok) {
1524
+ return initRes.status >= 500 ? { status: "transient_error", message: `MCP initialize returned ${initRes.status}` } : null;
1525
+ }
1526
+ const sessionId = initRes.headers.get("mcp-session-id");
1527
+ await parseRpc(initRes, 1);
1528
+ const sessionHeaders = { ...baseHeaders, ...sessionId ? { "Mcp-Session-Id": sessionId } : {} };
1529
+ const initializedRes = await fetchImpl(config.url, {
1530
+ method: "POST",
1531
+ headers: sessionHeaders,
1532
+ body: JSON.stringify({ jsonrpc: "2.0", method: "notifications/initialized" }),
1533
+ signal: AbortSignal.timeout(5e3)
1534
+ });
1535
+ await initializedRes.text().catch(() => "");
1536
+ const listRes = await fetchImpl(config.url, {
1537
+ method: "POST",
1538
+ headers: sessionHeaders,
1539
+ body: JSON.stringify({ jsonrpc: "2.0", id: 2, method: "tools/list" }),
1540
+ signal: AbortSignal.timeout(timeoutMs)
1541
+ });
1542
+ if (!listRes.ok) {
1543
+ return listRes.status >= 500 ? { status: "transient_error", message: `MCP tools/list returned ${listRes.status}` } : null;
1544
+ }
1545
+ const listRpc = await parseRpc(listRes, 2);
1546
+ const tools = listRpc?.["result"]?.tools ?? [];
1547
+ const toolName = pickSafeReadonlyTool(tools);
1548
+ if (!toolName)
1549
+ return null;
1550
+ const callRes = await fetchImpl(config.url, {
1551
+ method: "POST",
1552
+ headers: sessionHeaders,
1553
+ body: JSON.stringify({
1554
+ jsonrpc: "2.0",
1555
+ id: 3,
1556
+ method: "tools/call",
1557
+ params: { name: toolName, arguments: {} }
1558
+ }),
1559
+ signal: AbortSignal.timeout(timeoutMs)
1560
+ });
1561
+ if (!callRes.ok) {
1562
+ return callRes.status >= 500 ? { status: "transient_error", message: `MCP tools/call returned ${callRes.status}` } : null;
1563
+ }
1564
+ const callRpc = await parseRpc(callRes, 3);
1565
+ if (callRpc && "error" in callRpc) {
1566
+ const errMsg = callRpc["error"]?.message ?? "";
1567
+ if (isAccountResolutionError(errMsg)) {
1568
+ return {
1569
+ status: "down",
1570
+ message: `Live tool call '${toolName}' failed to resolve the connected account: ${errMsg}`,
1571
+ details: { tool: toolName }
1572
+ };
1573
+ }
1574
+ return { status: "ok", message: `Live tool call '${toolName}' resolved the account (tool error: ${errMsg})`, details: { tool: toolName } };
1575
+ }
1576
+ const result = callRpc?.["result"];
1577
+ if (result?.isError) {
1578
+ const text = (result.content ?? []).map((c) => c.text ?? "").join(" ");
1579
+ if (isAccountResolutionError(text)) {
1580
+ return {
1581
+ status: "down",
1582
+ message: `Live tool call '${toolName}' failed to resolve the connected account: ${text}`,
1583
+ details: { tool: toolName }
1584
+ };
1585
+ }
1586
+ return { status: "ok", message: `Live tool call '${toolName}' resolved the account (tool error)`, details: { tool: toolName } };
1587
+ }
1588
+ return { status: "ok", message: `Live tool call '${toolName}' resolved the connected account`, details: { tool: toolName } };
1589
+ } catch (err) {
1590
+ const isAbort = err?.name === "TimeoutError" || err?.name === "AbortError";
1591
+ return {
1592
+ status: "transient_error",
1593
+ message: isAbort ? `MCP tool-call probe timed out after ${timeoutMs / 1e3}s` : `MCP tool-call probe failed: ${err.message}`
1594
+ };
1595
+ }
1596
+ }
1359
1597
 
1360
1598
  // ../../packages/core/dist/integrations/context-validator.js
1361
1599
  import Ajv2020 from "ajv/dist/2020.js";
@@ -1596,6 +1834,31 @@ var OAUTH_PROVIDERS = {
1596
1834
  "accounting.reports.executivesummary.read",
1597
1835
  "accounting.reports.aged.read"
1598
1836
  ],
1837
+ // Read-only variant (ENG-6170): the `.read` granular scope for every
1838
+ // surface, so a token granted under it cannot create bills/invoices or
1839
+ // mutate contacts/attachments. Used when an install is (re)connected with
1840
+ // `read_only: true` — e.g. to lock a production-books integration to reads
1841
+ // until per-vendor broker mediation (ENG-4922) gates its writes.
1842
+ readOnlyScopes: [
1843
+ "openid",
1844
+ "profile",
1845
+ "email",
1846
+ "offline_access",
1847
+ "accounting.settings.read",
1848
+ "accounting.contacts.read",
1849
+ "accounting.invoices.read",
1850
+ "accounting.attachments.read",
1851
+ "accounting.payments.read",
1852
+ "accounting.banktransactions.read",
1853
+ "accounting.manualjournals.read",
1854
+ "accounting.reports.balancesheet.read",
1855
+ "accounting.reports.profitandloss.read",
1856
+ "accounting.reports.trialbalance.read",
1857
+ "accounting.reports.budgetsummary.read",
1858
+ "accounting.reports.banksummary.read",
1859
+ "accounting.reports.executivesummary.read",
1860
+ "accounting.reports.aged.read"
1861
+ ],
1599
1862
  supportsRefresh: true,
1600
1863
  extraAuthorizeParams: {},
1601
1864
  clientAuthMethod: "basic",
@@ -4388,6 +4651,7 @@ export {
4388
4651
  worseConnectivityOutcome,
4389
4652
  resolveConnectivityProbe,
4390
4653
  probeComposioAccount,
4654
+ probeComposioMcpToolCall,
4391
4655
  probeHttpProvider,
4392
4656
  detectDrift,
4393
4657
  SUPPRESS_SENTINEL,
@@ -4399,4 +4663,4 @@ export {
4399
4663
  attributeTranscriptUsageByRun,
4400
4664
  KANBAN_CHECK_COMMAND
4401
4665
  };
4402
- //# sourceMappingURL=chunk-MTKM655R.js.map
4666
+ //# sourceMappingURL=chunk-Z6JJRLHH.js.map