@integrity-labs/agt-cli 0.28.1114 → 0.28.1116

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-J3L66T65.js";
43
+ } from "../chunk-5LXKP254.js";
44
44
  import {
45
45
  getProjectDir,
46
46
  isSessionResumeDisabled,
47
47
  readDirectChatSessionState
48
- } from "../chunk-2XQPQOJX.js";
48
+ } from "../chunk-ZOHDIHUT.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-OBZB6MUE.js";
82
+ } from "../chunk-DC6EMGAO.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.1114" : "dev";
5477
+ var cliVersion = true ? "0.28.1116" : "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.1114" : "dev";
6737
+ var cliVersion2 = true ? "0.28.1116" : "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) => {
@@ -16,7 +16,7 @@ import {
16
16
  parseEnvFileEntries,
17
17
  parseEnvIntegrations,
18
18
  shellQuote
19
- } from "./chunk-2XQPQOJX.js";
19
+ } from "./chunk-ZOHDIHUT.js";
20
20
  import {
21
21
  BIND_FAILURE_QUARANTINE_THRESHOLD,
22
22
  INTEGRATIONS_SECTION_END,
@@ -79,7 +79,7 @@ import {
79
79
  sessionTranscriptDir,
80
80
  worseConnectivityOutcome,
81
81
  wrapScheduledTaskPrompt
82
- } from "./chunk-OBZB6MUE.js";
82
+ } from "./chunk-DC6EMGAO.js";
83
83
  import {
84
84
  classifyUnanswerablePane,
85
85
  isConsumerTermsDialogVisible,
@@ -7518,7 +7518,7 @@ function exchangeFailureKind(err) {
7518
7518
  }
7519
7519
 
7520
7520
  // src/lib/api-client.ts
7521
- var agtCliVersion = true ? "0.28.1114" : "dev";
7521
+ var agtCliVersion = true ? "0.28.1116" : "dev";
7522
7522
  var lastConfigHash = null;
7523
7523
  function setConfigHash(hash) {
7524
7524
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -12664,4 +12664,4 @@ export {
12664
12664
  managerInstallSystemUnitCommand,
12665
12665
  managerUninstallSystemUnitCommand
12666
12666
  };
12667
- //# sourceMappingURL=chunk-J3L66T65.js.map
12667
+ //# sourceMappingURL=chunk-5LXKP254.js.map
@@ -1811,7 +1811,7 @@ When you reply to a user via any channel (Slack, Telegram, direct chat, schedule
1811
1811
  - **Match the scope of the request.** A yes/no question gets a one-line answer; a "quick summary" gets a summary, not a dissertation. Cut any section, caveat, or restatement that doesn't directly answer what was asked.
1812
1812
  - **Never reference internal state.** Memory files, \`/tmp/\` paths, kanban task IDs, filesystem locations, "saved to \u2026" / "logged to \u2026" notes \u2014 these are invisible to the recipient and waste their attention. Only the deliverable content belongs in your reply.
1813
1813
  - **Put the full deliverable in the reply itself.** Don't tease ("I've prepared a detailed brief"), don't point "above" or "attached", and don't assume the recipient can see intermediate tool output. If they asked for a brief, the brief goes verbatim into your reply.
1814
- - **If the deliverable is a file** (PDF, CSV, screenshot, export, report), upload it with the channel's file-upload tool (e.g. \`slack_upload_file\`) rather than describing its path. The recipient cannot access your filesystem.
1814
+ - **If the deliverable is a file** (PDF, CSV, screenshot, export, report), upload it with the channel's file-upload tool rather than describing its path. The recipient cannot access your filesystem. On Slack that is \`slack_upload_file\`; in Direct Chat, \`direct_chat_attach_file\` the file, then send its \`upload_id\` in \`upload_ids\` on \`direct_chat_reply\`.
1815
1815
 
1816
1816
  ## Standards
1817
1817
 
@@ -11992,6 +11992,38 @@ var OAUTH_PROVIDERS = {
11992
11992
  extraAuthorizeParams: {},
11993
11993
  clientAuthMethod: "body",
11994
11994
  userInfoUrl: "https://api.linkedin.com/v2/userinfo"
11995
+ },
11996
+ // CS-2039: Google Business Profile, native OAuth + brokered REST (the
11997
+ // linkedin-ads shape). Confidential Google client with refresh tokens, the
11998
+ // same model as google-workspace; OAUTH_GOOGLE_BUSINESS_PROFILE_CLIENT_ID /
11999
+ // _SECRET may be the SAME Google OAuth client as google-workspace (the
12000
+ // redirect URI `/integrations/oauth/callback` is shared by every provider).
12001
+ //
12002
+ // `business.manage` is the ONLY Business Profile scope Google offers: there
12003
+ // is no read-only variant, so read-only is enforced by the broker exposing
12004
+ // read tools only (google-business-profile-shared.ts), not by consent.
12005
+ // That is also why `readOnlyScopes` is omitted rather than set equal.
12006
+ //
12007
+ // THE GATE THAT IS NOT CODE: every Business Profile API sits at a quota of
12008
+ // 0 requests/minute per Google Cloud project until Google approves that
12009
+ // project's "Application for Basic API Access". Until then every call 429s.
12010
+ // See docs/runbooks/google-business-profile-dogfood.md.
12011
+ //
12012
+ // No userInfoUrl: the userinfo endpoint needs `openid`/`email`, which are
12013
+ // deliberately not requested, so the callback's best-effort label falls
12014
+ // back to a plain "Connected".
12015
+ "google-business-profile": {
12016
+ definitionId: "google-business-profile",
12017
+ authorizeUrl: "https://accounts.google.com/o/oauth2/v2/auth",
12018
+ tokenUrl: "https://oauth2.googleapis.com/token",
12019
+ revokeUrl: "https://oauth2.googleapis.com/revoke",
12020
+ defaultScopes: ["https://www.googleapis.com/auth/business.manage"],
12021
+ supportsRefresh: true,
12022
+ extraAuthorizeParams: {
12023
+ access_type: "offline",
12024
+ prompt: "consent"
12025
+ },
12026
+ clientAuthMethod: "body"
11995
12027
  }
11996
12028
  };
11997
12029
  OAUTH_PROVIDERS["xero-control-plane"] = {
@@ -12067,6 +12099,9 @@ var HTTP_PROBE_PROVIDERS = /* @__PURE__ */ new Set([
12067
12099
  // over its toolkit source_type, so the probe is honest regardless of how the
12068
12100
  // toolkit row is classified.
12069
12101
  "buffer",
12102
+ // CS-2039: Google Business Profile is the same native OAuth + brokered-REST
12103
+ // shape as linkedin-ads below; routes to its accounts-list HTTP probe.
12104
+ "google-business-profile",
12070
12105
  // LinkedIn Ads is a native OAuth + brokered-REST integration (Xero's shape),
12071
12106
  // so its honest health signal is the same: a central read-only check that the
12072
12107
  // stored token still authenticates. Routes to the OIDC userinfo probe in
@@ -12474,6 +12509,57 @@ async function probeBearerJson(url, creds, fetchImpl, interpret, extraHeaders) {
12474
12509
  return networkOutcome(err, String(token ?? ""));
12475
12510
  }
12476
12511
  }
12512
+ function googleErrorReasons(text) {
12513
+ try {
12514
+ const details = JSON.parse(text)?.error?.details;
12515
+ if (!Array.isArray(details))
12516
+ return [];
12517
+ return details.map((d) => d && typeof d === "object" ? d.reason : void 0).filter((r) => typeof r === "string" && r.length > 0);
12518
+ } catch {
12519
+ return [];
12520
+ }
12521
+ }
12522
+ async function probeGoogleBusinessProfile(creds, fetchImpl) {
12523
+ if (!creds.access_token && !creds.api_key) {
12524
+ return {
12525
+ status: "unverified",
12526
+ evidence: "none",
12527
+ message: "Not probed from the host: the Business Profile token is held server-side and never sent here. Use Test connection to check it"
12528
+ };
12529
+ }
12530
+ const captured = { forbiddenReasons: null };
12531
+ const capturingFetch = async (input, init) => {
12532
+ const res = await fetchImpl(input, init);
12533
+ if (res.status === 403) {
12534
+ captured.forbiddenReasons = googleErrorReasons(await res.clone().text().catch(() => ""));
12535
+ }
12536
+ return res;
12537
+ };
12538
+ const outcome = await probeBearerJson("https://mybusinessaccountmanagement.googleapis.com/v1/accounts?pageSize=1", creds, capturingFetch, (body) => {
12539
+ const accounts = body?.accounts;
12540
+ const list = Array.isArray(accounts) ? accounts : [];
12541
+ if (!list.length)
12542
+ return { status: "ok", message: "Connected, but this Google account manages no Business Profile" };
12543
+ const name = typeof list[0]?.accountName === "string" ? list[0].accountName : "a Business Profile account";
12544
+ return { status: "ok", message: `Connected to ${name}` };
12545
+ });
12546
+ const reasons = captured.forbiddenReasons;
12547
+ if (outcome.cause === "auth_rejected" && reasons !== null && !reasons.includes("ACCESS_TOKEN_SCOPE_INSUFFICIENT")) {
12548
+ const shown = reasons.length ? ` (${reasons.join(", ")})` : "";
12549
+ return {
12550
+ ...outcome,
12551
+ cause: "semantic",
12552
+ message: `Google returned 403${shown} on the Business Profile accounts list. This is the platform Cloud project (a Business Profile API not enabled, or access not approved), not this connection: reconnecting will not fix it`
12553
+ };
12554
+ }
12555
+ if (outcome.cause === "rate_limited") {
12556
+ return {
12557
+ ...outcome,
12558
+ message: `${outcome.message ?? "Rate limited by Google"}. If this never clears, Google has not yet approved Business Profile API access for the platform Cloud project (quota is 0 until it does)`
12559
+ };
12560
+ }
12561
+ return outcome;
12562
+ }
12477
12563
  async function probeBuffer(creds, fetchImpl) {
12478
12564
  const key = creds.api_key ?? creds.access_token;
12479
12565
  if (!key)
@@ -12915,6 +13001,8 @@ async function probeHttpProvider(definitionId, credentials, fetchImpl = fetch, c
12915
13001
  return { status: "down", message: "No Xero organisations connected" };
12916
13002
  return { status: "ok", message: `Connected to ${conns[0]?.tenantName ?? "Xero"}` };
12917
13003
  });
13004
+ case "google-business-profile":
13005
+ return probeGoogleBusinessProfile(credentials, fetchImpl);
12918
13006
  case "linkedin-ads":
12919
13007
  return probeBearerJson("https://api.linkedin.com/v2/userinfo", credentials, fetchImpl, (body) => {
12920
13008
  const user = body;
@@ -16699,4 +16787,4 @@ export {
16699
16787
  peekCurrentSession,
16700
16788
  readDailySessionPin
16701
16789
  };
16702
- //# sourceMappingURL=chunk-OBZB6MUE.js.map
16790
+ //# sourceMappingURL=chunk-DC6EMGAO.js.map