@integrity-labs/agt-cli 0.28.961 → 0.28.963

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.
Files changed (24) hide show
  1. package/dist/bin/agt.js +5 -5
  2. package/dist/{chunk-GSRUWWT6.js → chunk-4ZXFR64M.js} +5 -1
  3. package/dist/chunk-4ZXFR64M.js.map +1 -0
  4. package/dist/{chunk-INIVG34P.js → chunk-PE6Z3UMB.js} +4 -4
  5. package/dist/{chunk-SQGW4VAW.js → chunk-TI3V27FS.js} +2 -2
  6. package/dist/{claude-pair-runtime-W3NZZPKF.js → claude-pair-runtime-INNBV2E3.js} +2 -2
  7. package/dist/lib/manager-worker.js +14 -14
  8. package/dist/mcp/direct-chat-channel.js +4 -0
  9. package/dist/mcp/index.js +4 -0
  10. package/dist/mcp/origami.js +4 -0
  11. package/dist/mcp/slack-channel.js +4 -0
  12. package/dist/mcp/telegram-channel.js +4 -0
  13. package/dist/mcp/xero.js +158 -14
  14. package/dist/{persistent-session-OD7M7K5C.js → persistent-session-C7QW6EZJ.js} +3 -3
  15. package/dist/{responsiveness-probe-73TIJ6ZV.js → responsiveness-probe-OVDIYW5R.js} +3 -3
  16. package/dist/{session-auth-dead-FGWPJVFS.js → session-auth-dead-BW6SDESD.js} +2 -2
  17. package/package.json +1 -1
  18. package/dist/chunk-GSRUWWT6.js.map +0 -1
  19. /package/dist/{chunk-INIVG34P.js.map → chunk-PE6Z3UMB.js.map} +0 -0
  20. /package/dist/{chunk-SQGW4VAW.js.map → chunk-TI3V27FS.js.map} +0 -0
  21. /package/dist/{claude-pair-runtime-W3NZZPKF.js.map → claude-pair-runtime-INNBV2E3.js.map} +0 -0
  22. /package/dist/{persistent-session-OD7M7K5C.js.map → persistent-session-C7QW6EZJ.js.map} +0 -0
  23. /package/dist/{responsiveness-probe-73TIJ6ZV.js.map → responsiveness-probe-OVDIYW5R.js.map} +0 -0
  24. /package/dist/{session-auth-dead-FGWPJVFS.js.map → session-auth-dead-BW6SDESD.js.map} +0 -0
@@ -14,7 +14,7 @@ import {
14
14
  parseEnvFileEntries,
15
15
  parseEnvIntegrations,
16
16
  shellQuote
17
- } from "./chunk-SQGW4VAW.js";
17
+ } from "./chunk-TI3V27FS.js";
18
18
  import {
19
19
  BIND_FAILURE_QUARANTINE_THRESHOLD,
20
20
  INTEGRATIONS_SECTION_END,
@@ -74,7 +74,7 @@ import {
74
74
  sessionTranscriptDir,
75
75
  worseConnectivityOutcome,
76
76
  wrapScheduledTaskPrompt
77
- } from "./chunk-GSRUWWT6.js";
77
+ } from "./chunk-4ZXFR64M.js";
78
78
  import {
79
79
  classifyUnanswerablePane,
80
80
  summarizeUnanswerablePane
@@ -6967,7 +6967,7 @@ function exchangeFailureKind(err) {
6967
6967
  }
6968
6968
 
6969
6969
  // src/lib/api-client.ts
6970
- var agtCliVersion = true ? "0.28.961" : "dev";
6970
+ var agtCliVersion = true ? "0.28.963" : "dev";
6971
6971
  var lastConfigHash = null;
6972
6972
  function setConfigHash(hash) {
6973
6973
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -11666,4 +11666,4 @@ export {
11666
11666
  managerInstallSystemUnitCommand,
11667
11667
  managerUninstallSystemUnitCommand
11668
11668
  };
11669
- //# sourceMappingURL=chunk-INIVG34P.js.map
11669
+ //# sourceMappingURL=chunk-PE6Z3UMB.js.map
@@ -20,7 +20,7 @@ import {
20
20
  rotateDailySession,
21
21
  sessionFileExists,
22
22
  todayLocalIso
23
- } from "./chunk-GSRUWWT6.js";
23
+ } from "./chunk-4ZXFR64M.js";
24
24
  import {
25
25
  classifyUnanswerablePane,
26
26
  findUsageLimitResetHint,
@@ -5575,4 +5575,4 @@ export {
5575
5575
  stopAllSessionsAndWait,
5576
5576
  getProjectDir
5577
5577
  };
5578
- //# sourceMappingURL=chunk-SQGW4VAW.js.map
5578
+ //# sourceMappingURL=chunk-TI3V27FS.js.map
@@ -236,7 +236,7 @@ async function spawnPairSession(session) {
236
236
  return { ok: true };
237
237
  } catch {
238
238
  }
239
- const { resolveClaudeBinary } = await import("./persistent-session-OD7M7K5C.js");
239
+ const { resolveClaudeBinary } = await import("./persistent-session-C7QW6EZJ.js");
240
240
  const claudeBin = resolveClaudeBinary();
241
241
  const pairEnv = {
242
242
  ...process.env,
@@ -558,4 +558,4 @@ export {
558
558
  startClaudePair,
559
559
  submitClaudePairCode
560
560
  };
561
- //# sourceMappingURL=claude-pair-runtime-W3NZZPKF.js.map
561
+ //# sourceMappingURL=claude-pair-runtime-INNBV2E3.js.map
@@ -63,7 +63,7 @@ import {
63
63
  safeWriteJsonAtomic,
64
64
  setConfigHash,
65
65
  tripClass
66
- } from "../chunk-INIVG34P.js";
66
+ } from "../chunk-PE6Z3UMB.js";
67
67
  import {
68
68
  getProjectDir as getProjectDir2,
69
69
  getReadyTasks,
@@ -140,7 +140,7 @@ import {
140
140
  takeZombieDetection,
141
141
  toOpencodeModel,
142
142
  writeEgressAllowlist
143
- } from "../chunk-SQGW4VAW.js";
143
+ } from "../chunk-TI3V27FS.js";
144
144
  import {
145
145
  ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
146
146
  AnchorSessionClient,
@@ -236,7 +236,7 @@ import {
236
236
  subagentActivityAgeSeconds,
237
237
  sumTranscriptUsageInWindow,
238
238
  transcriptActivityAgeSeconds
239
- } from "../chunk-GSRUWWT6.js";
239
+ } from "../chunk-4ZXFR64M.js";
240
240
  import "../chunk-DHWNVVX4.js";
241
241
  import {
242
242
  reapOrphanChannelMcps
@@ -13262,7 +13262,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
13262
13262
  var dayRolloverInboundHold = /* @__PURE__ */ new Map();
13263
13263
  var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
13264
13264
  async function channelInboundActivityAgeSecondsFor(codeName) {
13265
- const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-73TIJ6ZV.js");
13265
+ const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-OVDIYW5R.js");
13266
13266
  const newest = newestPendingInboundActivityMtimeMs(dirname11(paneLogPath(codeName)));
13267
13267
  if (newest === null) return null;
13268
13268
  return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
@@ -13947,7 +13947,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
13947
13947
  var lastVersionCheckAt = 0;
13948
13948
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
13949
13949
  var lastResponsivenessProbeAt = 0;
13950
- var agtCliVersion = true ? "0.28.961" : "dev";
13950
+ var agtCliVersion = true ? "0.28.963" : "dev";
13951
13951
  function resolveBrewPath(execFileSync2) {
13952
13952
  try {
13953
13953
  const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -15549,7 +15549,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
15549
15549
  if (codeNames.length === 0) return;
15550
15550
  void (async () => {
15551
15551
  try {
15552
- const { collectDiagnostics } = await import("../persistent-session-OD7M7K5C.js");
15552
+ const { collectDiagnostics } = await import("../persistent-session-C7QW6EZJ.js");
15553
15553
  await api.post("/host/heartbeat", {
15554
15554
  host_id: hostId,
15555
15555
  agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
@@ -15691,7 +15691,7 @@ async function pollCycleInner() {
15691
15691
  }
15692
15692
  try {
15693
15693
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
15694
- const { collectDiagnostics } = await import("../persistent-session-OD7M7K5C.js");
15694
+ const { collectDiagnostics } = await import("../persistent-session-C7QW6EZJ.js");
15695
15695
  const diagCodeNames = [...agentState.persistentSessionAgents];
15696
15696
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor) : void 0;
15697
15697
  let tailscaleHostname;
@@ -15867,7 +15867,7 @@ async function pollCycleInner() {
15867
15867
  collectPanelessActivityProbes,
15868
15868
  getResponsivenessIntervalMs,
15869
15869
  occupancyQualificationClassifications
15870
- } = await import("../responsiveness-probe-73TIJ6ZV.js");
15870
+ } = await import("../responsiveness-probe-OVDIYW5R.js");
15871
15871
  const probeIntervalMs = getResponsivenessIntervalMs();
15872
15872
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
15873
15873
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -15984,7 +15984,7 @@ async function pollCycleInner() {
15984
15984
  collectResponsivenessProbes,
15985
15985
  livePendingInboundOldestAgeSeconds,
15986
15986
  parkPendingInbound
15987
- } = await import("../responsiveness-probe-73TIJ6ZV.js");
15987
+ } = await import("../responsiveness-probe-OVDIYW5R.js");
15988
15988
  const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
15989
15989
  const wedgeNow = /* @__PURE__ */ new Date();
15990
15990
  const liveAgents = agentState.persistentSessionAgents;
@@ -16140,7 +16140,7 @@ async function pollCycleInner() {
16140
16140
  }
16141
16141
  try {
16142
16142
  const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-JA437JIB.js");
16143
- const { probeSessionAuth } = await import("../session-auth-dead-FGWPJVFS.js");
16143
+ const { probeSessionAuth } = await import("../session-auth-dead-BW6SDESD.js");
16144
16144
  const observations = [];
16145
16145
  const pendingCacheCommits = [];
16146
16146
  const modelApiErrorReportingOn = hostFlagStore().getBoolean("model-api-error-reporting");
@@ -20416,7 +20416,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
20416
20416
  try {
20417
20417
  const freshId = rotateSessionForWedge(codeName);
20418
20418
  consecutiveWedgeCycles.delete(codeName);
20419
- const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-73TIJ6ZV.js");
20419
+ const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-OVDIYW5R.js");
20420
20420
  const { parked, deadLettered } = parkForRestart(codeName, /* @__PURE__ */ new Date());
20421
20421
  const parkNote = parked > 0 ? `, ${parked} inbound parked` : "";
20422
20422
  const deadNote = deadLettered > 0 ? `, ${deadLettered} undeliverable dead-lettered` : "";
@@ -20459,7 +20459,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
20459
20459
  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}`));
20460
20460
  void (async () => {
20461
20461
  try {
20462
- const { collectDiagnostics } = await import("../persistent-session-OD7M7K5C.js");
20462
+ const { collectDiagnostics } = await import("../persistent-session-C7QW6EZJ.js");
20463
20463
  await api.post("/host/heartbeat", {
20464
20464
  host_id: hostId,
20465
20465
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
@@ -20510,7 +20510,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
20510
20510
  }
20511
20511
  try {
20512
20512
  const hostId = await getHostId();
20513
- const { collectDiagnostics } = await import("../persistent-session-OD7M7K5C.js");
20513
+ const { collectDiagnostics } = await import("../persistent-session-C7QW6EZJ.js");
20514
20514
  await api.post("/host/heartbeat", {
20515
20515
  host_id: hostId,
20516
20516
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
@@ -21152,7 +21152,7 @@ async function processClaudePairSessions(agents) {
21152
21152
  killPairSession,
21153
21153
  pairTmuxSession,
21154
21154
  finalizeClaudePairOnboarding
21155
- } = await import("../claude-pair-runtime-W3NZZPKF.js");
21155
+ } = await import("../claude-pair-runtime-INNBV2E3.js");
21156
21156
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
21157
21157
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
21158
21158
  const killed = await killPairSession(pairTmuxSession(pairId));
@@ -34806,6 +34806,10 @@ var NOTICE_KIND_AUDIENCE = {
34806
34806
  // HITL tool-call approvals: "Do NOT call this tool again, do NOT claim the
34807
34807
  // action happened, and do NOT poll".
34808
34808
  integration_invoke_resolved: "agent",
34809
+ // ADR-0104: the batch finished. Addressed to the agent, which reports the
34810
+ // counts onward; the approver is told separately, on the surface they
34811
+ // approved from.
34812
+ integration_batch_resolved: "agent",
34809
34813
  integration_invoke_denied: "agent",
34810
34814
  // Support/recruit approvals — same shape, agent resumes the provisioning.
34811
34815
  recruit_resolved: "agent",
package/dist/mcp/index.js CHANGED
@@ -27407,6 +27407,10 @@ var NOTICE_KIND_AUDIENCE = {
27407
27407
  // HITL tool-call approvals: "Do NOT call this tool again, do NOT claim the
27408
27408
  // action happened, and do NOT poll".
27409
27409
  integration_invoke_resolved: "agent",
27410
+ // ADR-0104: the batch finished. Addressed to the agent, which reports the
27411
+ // counts onward; the approver is told separately, on the surface they
27412
+ // approved from.
27413
+ integration_batch_resolved: "agent",
27410
27414
  integration_invoke_denied: "agent",
27411
27415
  // Support/recruit approvals — same shape, agent resumes the provisioning.
27412
27416
  recruit_resolved: "agent",
@@ -41558,6 +41558,10 @@ var NOTICE_KIND_AUDIENCE = {
41558
41558
  // HITL tool-call approvals: "Do NOT call this tool again, do NOT claim the
41559
41559
  // action happened, and do NOT poll".
41560
41560
  integration_invoke_resolved: "agent",
41561
+ // ADR-0104: the batch finished. Addressed to the agent, which reports the
41562
+ // counts onward; the approver is told separately, on the surface they
41563
+ // approved from.
41564
+ integration_batch_resolved: "agent",
41561
41565
  integration_invoke_denied: "agent",
41562
41566
  // Support/recruit approvals — same shape, agent resumes the provisioning.
41563
41567
  recruit_resolved: "agent",
@@ -35784,6 +35784,10 @@ var NOTICE_KIND_AUDIENCE = {
35784
35784
  // HITL tool-call approvals: "Do NOT call this tool again, do NOT claim the
35785
35785
  // action happened, and do NOT poll".
35786
35786
  integration_invoke_resolved: "agent",
35787
+ // ADR-0104: the batch finished. Addressed to the agent, which reports the
35788
+ // counts onward; the approver is told separately, on the surface they
35789
+ // approved from.
35790
+ integration_batch_resolved: "agent",
35787
35791
  integration_invoke_denied: "agent",
35788
35792
  // Support/recruit approvals — same shape, agent resumes the provisioning.
35789
35793
  recruit_resolved: "agent",
@@ -35796,6 +35796,10 @@ var NOTICE_KIND_AUDIENCE = {
35796
35796
  // HITL tool-call approvals: "Do NOT call this tool again, do NOT claim the
35797
35797
  // action happened, and do NOT poll".
35798
35798
  integration_invoke_resolved: "agent",
35799
+ // ADR-0104: the batch finished. Addressed to the agent, which reports the
35800
+ // counts onward; the approver is told separately, on the surface they
35801
+ // approved from.
35802
+ integration_batch_resolved: "agent",
35799
35803
  integration_invoke_denied: "agent",
35800
35804
  // Support/recruit approvals — same shape, agent resumes the provisioning.
35801
35805
  recruit_resolved: "agent",
package/dist/mcp/xero.js CHANGED
@@ -114353,6 +114353,16 @@ function pickTenantId(tenants, desired) {
114353
114353
  return desired;
114354
114354
  }
114355
114355
 
114356
+ // src/helpers/tenant-context.ts
114357
+ import { AsyncLocalStorage } from "async_hooks";
114358
+ var store = new AsyncLocalStorage();
114359
+ function runWithTenant(tenantId, fn) {
114360
+ return store.run({ tenantId }, fn);
114361
+ }
114362
+ function currentCallTenant() {
114363
+ return store.getStore()?.tenantId;
114364
+ }
114365
+
114356
114366
  // src/clients/broker-credential-client.ts
114357
114367
  function makeError(status, message, needsReauth = false) {
114358
114368
  const err = new Error(message);
@@ -114437,7 +114447,11 @@ var BrokerCredentialClient = class {
114437
114447
  tenantId: res.data.tenant_id ?? null,
114438
114448
  expiresAt: res.data.expires_at ?? null,
114439
114449
  grantedScopes: res.data.granted_scopes ?? null,
114440
- effectiveScopes: res.data.effective_scopes ?? null
114450
+ effectiveScopes: res.data.effective_scopes ?? null,
114451
+ allowedTenants: Array.isArray(res.data.allowed_tenants) ? res.data.allowed_tenants.filter((t) => typeof t?.tenant_id === "string" && t.tenant_id.trim() !== "").map((t) => ({
114452
+ tenantId: t.tenant_id.trim(),
114453
+ tenantName: typeof t.tenant_name === "string" ? t.tenant_name : null
114454
+ })) : null
114441
114455
  };
114442
114456
  } catch (err) {
114443
114457
  if (err.status !== void 0) throw err;
@@ -114512,12 +114526,44 @@ if (!broker_mode && !bearer_token && (!client_id || !client_secret)) {
114512
114526
  throw Error("Environment Variables not set - please check your .env file");
114513
114527
  }
114514
114528
  var MCPXeroClient = class extends import_xero_node.XeroClient {
114515
- tenantId;
114516
- shortCode;
114529
+ pinnedTenantId = "";
114530
+ // CS-1739: one short code per organisation, since a call can now target any
114531
+ // allowed organisation and a deep link must point at the right one.
114532
+ shortCodes = /* @__PURE__ */ new Map();
114533
+ /** CS-1739: the organisations the platform allows for this login (broker mode). */
114534
+ /**
114535
+ * CS-1739: the operator's organisation list from the broker.
114536
+ * null = the platform sent none (older API, or a non-broker install), so
114537
+ * the single pinned tenant applies;
114538
+ * [] = an EXPLICIT empty list (nothing intersected), which must refuse
114539
+ * every call rather than fall back to the pin. CodeRabbit on #6188:
114540
+ * collapsing both to [] let a call run against the pinned tenant
114541
+ * despite the operator allowing nothing.
114542
+ */
114543
+ allowedTenants = null;
114517
114544
  constructor(config2) {
114518
114545
  super(config2);
114519
- this.tenantId = "";
114520
- this.shortCode = "";
114546
+ }
114547
+ /**
114548
+ * The tenant for the CURRENT tool call when one was chosen (CS-1739), else
114549
+ * the pinned tenant. Handlers keep reading `xeroClient.tenantId` unchanged.
114550
+ */
114551
+ get tenantId() {
114552
+ return currentCallTenant() ?? this.pinnedTenantId;
114553
+ }
114554
+ set tenantId(value) {
114555
+ this.pinnedTenantId = value;
114556
+ }
114557
+ /**
114558
+ * CS-1739: the organisations a tool call may target. The broker's list when
114559
+ * it sent one; otherwise the single pinned tenant (older API / non-broker).
114560
+ */
114561
+ async getAllowedTenants() {
114562
+ await this.authenticate();
114563
+ if (this.allowedTenants !== null) return this.allowedTenants;
114564
+ if (!this.pinnedTenantId) return [];
114565
+ const match = (this.tenants ?? []).find((t) => t?.tenantId === this.pinnedTenantId);
114566
+ return [{ tenantId: this.pinnedTenantId, tenantName: match?.tenantName ?? null }];
114521
114567
  }
114522
114568
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
114523
114569
  async updateTenants(fullOrgDetails) {
@@ -114537,10 +114583,11 @@ var MCPXeroClient = class extends import_xero_node.XeroClient {
114537
114583
  return organisation;
114538
114584
  }
114539
114585
  async getShortCode() {
114540
- if (!this.shortCode) {
114586
+ const key = this.tenantId;
114587
+ if (!this.shortCodes.has(key)) {
114541
114588
  try {
114542
114589
  const organisation = await this.getOrganisation();
114543
- this.shortCode = organisation.shortCode ?? "";
114590
+ this.shortCodes.set(key, organisation.shortCode ?? "");
114544
114591
  } catch (error2) {
114545
114592
  const err = ensureError(error2);
114546
114593
  throw new Error(
@@ -114548,7 +114595,7 @@ var MCPXeroClient = class extends import_xero_node.XeroClient {
114548
114595
  );
114549
114596
  }
114550
114597
  }
114551
- return this.shortCode;
114598
+ return this.shortCodes.get(key);
114552
114599
  }
114553
114600
  };
114554
114601
  var CustomConnectionsXeroClient = class extends MCPXeroClient {
@@ -114681,6 +114728,7 @@ var BrokerBearerTokenXeroClient = class extends MCPXeroClient {
114681
114728
  this.setTokenSet({
114682
114729
  access_token: cred.accessToken
114683
114730
  });
114731
+ this.allowedTenants = cred.allowedTenants ?? null;
114684
114732
  if (cred.tenantId) {
114685
114733
  this.tenantId = cred.tenantId;
114686
114734
  } else {
@@ -120844,6 +120892,100 @@ var UpdateTools = [
120844
120892
  update_repeating_invoice_tool_default
120845
120893
  ];
120846
120894
 
120895
+ // src/tools/list/list-organisations.tool.ts
120896
+ var ListOrganisationsTool = CreateXeroTool(
120897
+ "list-organisations",
120898
+ "Lists the Xero organisations this agent is allowed to use, with each organisation's tenant_id. Pass one of these tenant_id values to any Xero tool to target that organisation. Read-only.",
120899
+ {},
120900
+ async () => {
120901
+ try {
120902
+ const allowed = await xeroClient.getAllowedTenants();
120903
+ if (allowed.length === 0) {
120904
+ return {
120905
+ content: [{ type: "text", text: "No Xero organisation is selected for this agent. Ask an admin to choose one in the console." }],
120906
+ isError: true
120907
+ };
120908
+ }
120909
+ const lines = allowed.map(
120910
+ (t, i) => `${i + 1}. ${t.tenantName ?? "(name unknown)"} - tenant_id: ${t.tenantId}${i === 0 ? " (default)" : ""}`
120911
+ );
120912
+ return {
120913
+ content: [{ type: "text", text: `Xero organisations this agent may use:
120914
+ ${lines.join("\n")}` }]
120915
+ };
120916
+ } catch (error2) {
120917
+ return {
120918
+ content: [{ type: "text", text: `Could not list Xero organisations: ${ensureError(error2).message}` }],
120919
+ isError: true
120920
+ };
120921
+ }
120922
+ }
120923
+ );
120924
+ var list_organisations_tool_default = ListOrganisationsTool;
120925
+
120926
+ // src/helpers/resolve-call-tenant.ts
120927
+ function describe(allowed) {
120928
+ return allowed.map((t) => t.tenantName ? `${t.tenantName} (${t.tenantId})` : t.tenantId).join(", ");
120929
+ }
120930
+ function resolveCallTenant(allowed, requested) {
120931
+ const wanted = typeof requested === "string" ? requested.trim() : "";
120932
+ if (allowed !== null && allowed.length === 0) {
120933
+ return {
120934
+ ok: false,
120935
+ message: "This agent has no Xero organisations selected, so no Xero call can run. Ask an admin to choose the organisations for this integration."
120936
+ };
120937
+ }
120938
+ if (allowed === null) {
120939
+ if (wanted) {
120940
+ return {
120941
+ ok: false,
120942
+ message: `tenant_id ${wanted} cannot be used: this Xero connection has no organisation list to check it against.`
120943
+ };
120944
+ }
120945
+ return { ok: true, tenantId: void 0 };
120946
+ }
120947
+ if (wanted) {
120948
+ if (allowed.some((t) => t.tenantId === wanted)) return { ok: true, tenantId: wanted };
120949
+ return {
120950
+ ok: false,
120951
+ message: `tenant_id ${wanted} is not one of the Xero organisations this agent may use: ${describe(allowed)}.`
120952
+ };
120953
+ }
120954
+ if (allowed.length === 1) return { ok: true, tenantId: allowed[0].tenantId };
120955
+ return {
120956
+ ok: false,
120957
+ message: `This agent can use more than one Xero organisation, so pass tenant_id. Allowed: ${describe(allowed)}. Call list-organisations to see them.`
120958
+ };
120959
+ }
120960
+
120961
+ // src/tools/tenant-scope.ts
120962
+ var TENANT_ID_ARG_DESCRIPTION = "Optional. The Xero organisation id (tenant) to use. Needed only when this agent can use more than one Xero organisation; call list-organisations to see them. Defaults to the only allowed organisation.";
120963
+ function errorResult(text) {
120964
+ return { content: [{ type: "text", text }], isError: true };
120965
+ }
120966
+ function withTenantScope(tool) {
120967
+ const schema = tool.schema ?? {};
120968
+ if ("tenant_id" in schema) return tool;
120969
+ return {
120970
+ ...tool,
120971
+ schema: { ...schema, tenant_id: external_exports.string().optional().describe(TENANT_ID_ARG_DESCRIPTION) },
120972
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
120973
+ handler: (async (args, extra) => {
120974
+ const { tenant_id: requested, ...rest } = args ?? {};
120975
+ let allowed;
120976
+ try {
120977
+ allowed = await xeroClient.getAllowedTenants();
120978
+ } catch (error2) {
120979
+ return errorResult(`Could not resolve the Xero organisations for this agent: ${ensureError(error2).message}`);
120980
+ }
120981
+ const choice = resolveCallTenant(allowed, typeof requested === "string" ? requested : void 0);
120982
+ if (!choice.ok) return errorResult(choice.message);
120983
+ const call = () => tool.handler(rest, extra);
120984
+ return choice.tenantId === void 0 ? call() : runWithTenant(choice.tenantId, call);
120985
+ })
120986
+ };
120987
+ }
120988
+
120847
120989
  // src/tools/tool-factory.ts
120848
120990
  function writesGoViaBroker() {
120849
120991
  const raw = (process.env.XERO_WRITES_VIA_BROKER ?? "").trim().toLowerCase();
@@ -120877,15 +121019,17 @@ function ToolFactory(server, effectiveScopes = null) {
120877
121019
  "xero-mcp-server: agent policy excludes payroll scopes \u2014 payroll tools not registered (ENG-7824)."
120878
121020
  );
120879
121021
  }
120880
- GetTools.map((tool) => tool()).filter((tool) => allow(tool.name)).forEach((tool) => server.tool(tool.name, tool.description, tool.schema, tool.handler));
120881
- ListTools.map((tool) => tool()).filter((tool) => allow(tool.name)).forEach((tool) => server.tool(tool.name, tool.description, tool.schema, tool.handler));
120882
- AttachmentTools.map((tool) => tool()).forEach(
121022
+ const listOrganisations = list_organisations_tool_default();
121023
+ server.tool(listOrganisations.name, listOrganisations.description, listOrganisations.schema, listOrganisations.handler);
121024
+ GetTools.map((tool) => tool()).filter((tool) => allow(tool.name)).map(withTenantScope).forEach((tool) => server.tool(tool.name, tool.description, tool.schema, tool.handler));
121025
+ ListTools.map((tool) => tool()).filter((tool) => allow(tool.name)).map(withTenantScope).forEach((tool) => server.tool(tool.name, tool.description, tool.schema, tool.handler));
121026
+ AttachmentTools.map((tool) => tool()).map(withTenantScope).forEach(
120883
121027
  (tool) => server.tool(tool.name, tool.description, tool.schema, tool.handler)
120884
121028
  );
120885
121029
  if (readOnly) return;
120886
- DeleteTools.map((tool) => tool()).filter((tool) => allow(tool.name)).forEach((tool) => server.tool(tool.name, tool.description, tool.schema, tool.handler));
120887
- CreateTools.map((tool) => tool()).filter((tool) => allow(tool.name)).forEach((tool) => server.tool(tool.name, tool.description, tool.schema, tool.handler));
120888
- UpdateTools.map((tool) => tool()).filter((tool) => allow(tool.name)).forEach((tool) => server.tool(tool.name, tool.description, tool.schema, tool.handler));
121030
+ DeleteTools.map((tool) => tool()).filter((tool) => allow(tool.name)).map(withTenantScope).forEach((tool) => server.tool(tool.name, tool.description, tool.schema, tool.handler));
121031
+ CreateTools.map((tool) => tool()).filter((tool) => allow(tool.name)).map(withTenantScope).forEach((tool) => server.tool(tool.name, tool.description, tool.schema, tool.handler));
121032
+ UpdateTools.map((tool) => tool()).filter((tool) => allow(tool.name)).map(withTenantScope).forEach((tool) => server.tool(tool.name, tool.description, tool.schema, tool.handler));
120889
121033
  }
120890
121034
 
120891
121035
  // src/index.ts
@@ -62,8 +62,8 @@ import {
62
62
  writeDirectChatSessionState,
63
63
  writeEgressAllowlist,
64
64
  writePersistentClaudeWrapper
65
- } from "./chunk-SQGW4VAW.js";
66
- import "./chunk-GSRUWWT6.js";
65
+ } from "./chunk-TI3V27FS.js";
66
+ import "./chunk-4ZXFR64M.js";
67
67
  import "./chunk-DHWNVVX4.js";
68
68
  import "./chunk-XWVM4KPK.js";
69
69
  export {
@@ -131,4 +131,4 @@ export {
131
131
  writeEgressAllowlist,
132
132
  writePersistentClaudeWrapper
133
133
  };
134
- //# sourceMappingURL=persistent-session-OD7M7K5C.js.map
134
+ //# sourceMappingURL=persistent-session-C7QW6EZJ.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  paneLogPath
3
- } from "./chunk-SQGW4VAW.js";
4
- import "./chunk-GSRUWWT6.js";
3
+ } from "./chunk-TI3V27FS.js";
4
+ import "./chunk-4ZXFR64M.js";
5
5
  import "./chunk-DHWNVVX4.js";
6
6
  import "./chunk-XWVM4KPK.js";
7
7
 
@@ -800,4 +800,4 @@ export {
800
800
  readAndResetSlackReplyBindingClassifications,
801
801
  readAndResetSlackReplyTargetClassifications
802
802
  };
803
- //# sourceMappingURL=responsiveness-probe-73TIJ6ZV.js.map
803
+ //# sourceMappingURL=responsiveness-probe-OVDIYW5R.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  sessionTranscriptDir
3
- } from "./chunk-GSRUWWT6.js";
3
+ } from "./chunk-4ZXFR64M.js";
4
4
 
5
5
  // src/lib/session-auth-dead.ts
6
6
  import { closeSync, openSync, readSync, readdirSync, statSync } from "fs";
@@ -203,4 +203,4 @@ export {
203
203
  decideSessionAuthState,
204
204
  probeSessionAuth
205
205
  };
206
- //# sourceMappingURL=session-auth-dead-FGWPJVFS.js.map
206
+ //# sourceMappingURL=session-auth-dead-BW6SDESD.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@integrity-labs/agt-cli",
3
- "version": "0.28.961",
3
+ "version": "0.28.963",
4
4
  "description": "Augmented Team CLI — agent provisioning and management",
5
5
  "type": "module",
6
6
  "engines": {