@integrity-labs/agt-cli 0.28.778 → 0.28.779

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.
@@ -33341,6 +33341,459 @@ var ASSET_TYPES = {
33341
33341
  var DEFAULT_CHUNK_BUDGET_BYTES = 180 * 1024;
33342
33342
  var textEncoder = new TextEncoder();
33343
33343
 
33344
+ // ../core/dist/integrations/oauth-providers.js
33345
+ var OAUTH_PROVIDERS = {
33346
+ "google-workspace": {
33347
+ definitionId: "google-workspace",
33348
+ authorizeUrl: "https://accounts.google.com/o/oauth2/v2/auth",
33349
+ tokenUrl: "https://oauth2.googleapis.com/token",
33350
+ revokeUrl: "https://oauth2.googleapis.com/revoke",
33351
+ defaultScopes: [
33352
+ "https://www.googleapis.com/auth/gmail.modify",
33353
+ "https://www.googleapis.com/auth/calendar",
33354
+ "https://www.googleapis.com/auth/drive",
33355
+ "https://www.googleapis.com/auth/spreadsheets",
33356
+ "https://www.googleapis.com/auth/documents",
33357
+ "https://www.googleapis.com/auth/chat.messages",
33358
+ "https://www.googleapis.com/auth/chat.spaces.readonly"
33359
+ ],
33360
+ supportsRefresh: true,
33361
+ extraAuthorizeParams: {
33362
+ access_type: "offline",
33363
+ prompt: "consent"
33364
+ },
33365
+ clientAuthMethod: "body",
33366
+ userInfoUrl: "https://www.googleapis.com/oauth2/v2/userinfo"
33367
+ },
33368
+ "github": {
33369
+ definitionId: "github",
33370
+ authorizeUrl: "https://github.com/login/oauth/authorize",
33371
+ tokenUrl: "https://github.com/login/oauth/access_token",
33372
+ // ENG-6187: revoke the existing grant on reconnect so GitHub re-prompts and
33373
+ // the four scopes below are actually granted. Without this, a stale narrow
33374
+ // grant (e.g. an old read:user-only authorization) is silently re-issued and
33375
+ // the missing-scopes banner loops forever.
33376
+ grantRevokeUrl: "https://api.github.com/applications/{client_id}/grant",
33377
+ defaultScopes: ["repo", "read:org", "gist", "workflow"],
33378
+ supportsRefresh: true,
33379
+ extraAuthorizeParams: {},
33380
+ clientAuthMethod: "body",
33381
+ userInfoUrl: "https://api.github.com/user"
33382
+ },
33383
+ "granola": {
33384
+ // Granola MCP — remote streamable-HTTP at https://mcp.granola.ai/mcp.
33385
+ // The AS is at mcp-auth.granola.ai and exposes RFC 8414 metadata at
33386
+ // /.well-known/oauth-authorization-server. Auth is OAuth 2.0 with
33387
+ // mandatory PKCE (S256) and a public client (no client_secret) issued
33388
+ // via Dynamic Client Registration (RFC 7591). The bootstrap script
33389
+ // (`packages/api/scripts/dcr-register.ts`) registers a client once at
33390
+ // deploy time; OAUTH_GRANOLA_CLIENT_ID is set from its output.
33391
+ definitionId: "granola",
33392
+ authorizeUrl: "https://mcp-auth.granola.ai/oauth2/authorize",
33393
+ tokenUrl: "https://mcp-auth.granola.ai/oauth2/token",
33394
+ // Minimal scope set: `offline_access` earns the refresh_token so the
33395
+ // refresh cron can rotate the bearer without operator action; `openid`
33396
+ // is required for the OIDC code flow even when we don't request an
33397
+ // id_token. Profile/email are intentionally omitted — we have no
33398
+ // userInfoUrl wired up here, so requesting them would over-ask consent
33399
+ // for fields the callback can't read.
33400
+ defaultScopes: ["openid", "offline_access"],
33401
+ supportsRefresh: true,
33402
+ extraAuthorizeParams: {},
33403
+ clientAuthMethod: "body",
33404
+ pkce: "S256",
33405
+ publicClient: true,
33406
+ mcpUrl: "https://mcp.granola.ai/mcp",
33407
+ // Curated surface (matches the catalog seed's defined_scopes[].tools).
33408
+ toolAllowlist: ["search-meetings", "read-transcript", "read-summary", "list-folders"]
33409
+ },
33410
+ "brand-ninja": {
33411
+ // ENG-6820: Brand Ninja External-Content MCP, remote streamable-HTTP at
33412
+ // https://ext-api.app.brandninja.ai/v1/mcp. Same shape as Granola: the
33413
+ // server exposes RFC 8414 authorization-server metadata at
33414
+ // /.well-known/oauth-authorization-server (values below are taken verbatim
33415
+ // from that document, not inferred). Auth is OAuth 2.0 authorization-code
33416
+ // with mandatory PKCE (S256) and a public client (token_endpoint_auth_method
33417
+ // 'none') issued via Dynamic Client Registration (RFC 7591). The bootstrap
33418
+ // script (packages/api/scripts/dcr-register.ts) registers a client once at
33419
+ // deploy time against the registration_endpoint
33420
+ // (https://ext-api.app.brandninja.ai/v1/oauth/register); OAUTH_BRAND_NINJA_CLIENT_ID
33421
+ // is set from its output. The AS advertises the refresh_token grant, so the
33422
+ // shared oauth-refresh cron rotates the bearer without operator action.
33423
+ definitionId: "brand-ninja",
33424
+ authorizeUrl: "https://prod-brandninja.auth.ap-southeast-2.amazoncognito.com/oauth2/authorize",
33425
+ tokenUrl: "https://prod-brandninja.auth.ap-southeast-2.amazoncognito.com/oauth2/token",
33426
+ // The resource server (ext-api.app.brandninja.ai) advertises exactly two
33427
+ // scopes: external-api/content.write (the default content surface) and
33428
+ // external-api/admin (read-only credential metadata, granted per account
33429
+ // admin). Default install is least-privilege: content.write only; an
33430
+ // operator can widen to admin out of band. No openid/offline_access in the
33431
+ // advertised scope set, so Cognito issues the refresh_token for the code grant
33432
+ // regardless, so requesting only the resource scope keeps consent minimal.
33433
+ defaultScopes: ["external-api/content.write"],
33434
+ supportsRefresh: true,
33435
+ extraAuthorizeParams: {},
33436
+ clientAuthMethod: "body",
33437
+ pkce: "S256",
33438
+ publicClient: true,
33439
+ mcpUrl: "https://ext-api.app.brandninja.ai/v1/mcp",
33440
+ // Curated surface (matches the catalog seed's defined_scopes[].tools).
33441
+ toolAllowlist: [
33442
+ "submit_content_request",
33443
+ "get_content_status",
33444
+ "list_content_requests",
33445
+ "list_channels",
33446
+ "list_brands",
33447
+ "list_topics",
33448
+ "list_timeline_templates",
33449
+ "list_content_types",
33450
+ "list_source_skills",
33451
+ "list_output_skills",
33452
+ "list_conversion_skills",
33453
+ "list_credentials",
33454
+ "search_transcripts",
33455
+ "create_source_clips",
33456
+ "create_timeline_ranking",
33457
+ "create_topic",
33458
+ "create_timeline_template",
33459
+ "create_knowledge",
33460
+ "link_knowledge"
33461
+ ]
33462
+ },
33463
+ "kajabi": {
33464
+ // Kajabi MCP — remote streamable-HTTP at https://mcp.kajabi.com/mcp.
33465
+ // Same Granola/Brand-Ninja shape: OAuth 2.0 authorization-code with
33466
+ // mandatory PKCE (S256) and a public client (token_endpoint_auth_method
33467
+ // 'none') issued via Dynamic Client Registration (RFC 7591). Values below
33468
+ // are taken verbatim from Kajabi's RFC 8414 metadata at
33469
+ // https://mcp.kajabi.com/.well-known/oauth-authorization-server (a Rails
33470
+ // Doorkeeper AS), not inferred. NOTE the authorize host differs from the
33471
+ // token host: authorize is on app.kajabi.com (the login surface), while
33472
+ // token/register/revoke are on mcp.kajabi.com — do NOT "normalise" them to
33473
+ // one host. The bootstrap script (packages/api/scripts/dcr-register.ts)
33474
+ // registers a client once at deploy time against
33475
+ // https://mcp.kajabi.com/mcp/oauth/register; OAUTH_KAJABI_CLIENT_ID is set
33476
+ // from its output. Doorkeeper RESTRICTS a dynamic client to the scopes it
33477
+ // registered with, so register with at least the union of defaultScopes
33478
+ // below (--scope 'read write:contacts write:emails write:content
33479
+ // write:commerce'). Widening defaultScopes forces a client re-register
33480
+ // (new client_id) AND a per-connection re-consent: existing tokens keep
33481
+ // the old scope set and their refreshes fail under the new client_id, so
33482
+ // each connection flips to needs_reauth until the user re-runs Connect
33483
+ // (ENG-7483). The AS advertises the refresh_token grant (no
33484
+ // openid/offline_access scope needed), so the shared oauth-refresh cron
33485
+ // rotates the bearer without operator action.
33486
+ definitionId: "kajabi",
33487
+ authorizeUrl: "https://app.kajabi.com/mcp/oauth/authorize",
33488
+ tokenUrl: "https://mcp.kajabi.com/mcp/oauth/token",
33489
+ revokeUrl: "https://mcp.kajabi.com/mcp/oauth/revoke",
33490
+ // Coarse Doorkeeper scopes (NOT openid-style). Cross-domain reads (`read`)
33491
+ // plus the write surfaces this integration ships: contact tags/segments,
33492
+ // email broadcasts/sequences, and course updates (write:content gates
33493
+ // update_course, the course-thumbnail path, ENG-7483). write:commerce is
33494
+ // requested now (Brad's call on ENG-7483) so a later offer/pricing-write
33495
+ // enablement needs no extra re-consent round; the tool allowlist below
33496
+ // still exposes no commerce write, so the callable surface stays minimal.
33497
+ defaultScopes: ["read", "write:contacts", "write:emails", "write:content", "write:commerce"],
33498
+ supportsRefresh: true,
33499
+ extraAuthorizeParams: {},
33500
+ clientAuthMethod: "body",
33501
+ pkce: "S256",
33502
+ publicClient: true,
33503
+ mcpUrl: "https://mcp.kajabi.com/mcp",
33504
+ // Curated surface (matches the catalog seed's defined_scopes[].tools). Kajabi's
33505
+ // live MCP advertises ~111 tools; the agent only needs these 28.
33506
+ // CS-1427: `enable_toolset` is included so an agent can activate its own
33507
+ // products/commerce + analytics toolsets on the connection (Kajabi gates those
33508
+ // tool groups behind a runtime toolset that returns "not active" until enabled).
33509
+ // Low-risk: this proxy still caps every tools/call to the allowlist, so a broad
33510
+ // activation can't widen what's actually callable.
33511
+ // ENG-7483: `get_course`/`update_course` enable the course-thumbnail refresh
33512
+ // (update_course covers title/description/thumbnail per Kajabi's MCP docs).
33513
+ // Fail-safe on naming drift: an allowlisted tool the server doesn't advertise
33514
+ // is logged and skipped by the proxy, never a break.
33515
+ toolAllowlist: [
33516
+ "list_sites",
33517
+ "get_site_summary",
33518
+ "select_site",
33519
+ "search_contacts",
33520
+ "get_contact",
33521
+ "search_products",
33522
+ "get_product",
33523
+ "list_offers",
33524
+ "get_offer",
33525
+ "list_offer_purchases",
33526
+ "get_revenue_analytics",
33527
+ "get_contacts_analytics",
33528
+ "list_tags",
33529
+ "create_tag",
33530
+ "tag_contact",
33531
+ "untag_contact",
33532
+ "list_segments",
33533
+ "create_segment",
33534
+ "update_segment",
33535
+ "list_broadcasts",
33536
+ "get_broadcast",
33537
+ "create_broadcast",
33538
+ "list_sequences",
33539
+ "get_sequence",
33540
+ "create_sequence",
33541
+ "enable_toolset",
33542
+ "get_course",
33543
+ "update_course",
33544
+ // ENG-7629 follow-up: pages (Dee's landing-page edit) + themes (CS-1448
33545
+ // theme-builder broadcast content). Callable via the proxy union manifest
33546
+ // + per-call enable; matches the new kajabi:pages catalog scope.
33547
+ "list_landing_pages",
33548
+ "get_landing_page",
33549
+ "update_landing_page",
33550
+ "get_theme_content"
33551
+ ],
33552
+ // CS-1446: Kajabi gates several tool groups behind a runtime `enable_toolset`
33553
+ // and does not advertise their tools in `tools/list` until the group is
33554
+ // active. The harness freezes its callable-tool manifest from the
33555
+ // connect-time `tools/list`, so a group the agent activates later never
33556
+ // becomes callable (repro: enable_toolset('courses') → get_course/
33557
+ // update_course still "No such tool available"). Pre-activate the gated
33558
+ // groups whose tools we allowlist so they are advertised in that first
33559
+ // manifest. Names are Kajabi's toolset ids (courses per CS-1446;
33560
+ // products/commerce/analytics per CS-1427). Best-effort + idempotent: an
33561
+ // unknown/unscoped name is logged and skipped by the proxy, and the
33562
+ // toolAllowlist above still caps what is actually callable.
33563
+ //
33564
+ // ENG-8392: `contacts` + `emails` were missing, so thirteen allowlisted
33565
+ // tools were unreachable by construction — list_tags, create_tag,
33566
+ // tag_contact, untag_contact, list_segments, create_segment,
33567
+ // update_segment (contacts) and list_broadcasts, get_broadcast,
33568
+ // create_broadcast, list_sequences, get_sequence, create_sequence
33569
+ // (emails). A customer agent was blocked on exactly those.
33570
+ //
33571
+ // These two ids are Kajabi's OWN spelling, not ours: the server names the
33572
+ // toolset in its rejection, e.g. `list_tags` returns
33573
+ // "The 'contacts' toolset is not active. Call enable_toolset with
33574
+ // name: 'contacts' to activate it first."
33575
+ // and `list_sequences` returns the same with 'emails'. Sourced that way
33576
+ // deliberately — a wrong id here is logged and SKIPPED by the proxy, so a
33577
+ // guess would look applied and change nothing.
33578
+ //
33579
+ // Why this went unnoticed for four rounds: `get_contacts_analytics` lives
33580
+ // in the `analytics` group, which we already pre-enable. So the contacts
33581
+ // family read as partly alive (you could see a site's contact count and
33582
+ // growth curve) while every tag and segment call failed.
33583
+ preEnableToolsets: [
33584
+ "courses",
33585
+ "products",
33586
+ "commerce",
33587
+ "analytics",
33588
+ "pages",
33589
+ "themes",
33590
+ "contacts",
33591
+ "emails"
33592
+ ],
33593
+ // ENG-8512: `update_course.thumbnail` stores a RELATIVE path into Kajabi's
33594
+ // own storage — it is rendered as
33595
+ // https://kajabi-storefronts-production.kajabi-cdn.com/kajabi-storefronts-production/<value>
33596
+ // so an absolute http(s) URL is structurally not a valid value for it.
33597
+ // Kajabi accepts one anyway, returns 200, echoes it back, ingests nothing,
33598
+ // and the course shows a broken image. Reported from a live client site
33599
+ // (DTI) via CS-1548 after it produced a false "done" report and three
33600
+ // failed cards.
33601
+ //
33602
+ // Anchored at the start so only an ABSOLUTE URL is refused; every relative
33603
+ // path — the valid shape — passes untouched. This does not enable setting a
33604
+ // thumbnail from a URL (that needs an upload path, CS-1548 item 4). It stops
33605
+ // us reporting success for a write that did not happen.
33606
+ argRejects: [
33607
+ {
33608
+ tool: "update_course",
33609
+ field: "thumbnail",
33610
+ pattern: "^\\s*https?://",
33611
+ message: "thumbnail takes a relative path inside Kajabi storage, not an external URL. Kajabi accepts a URL here, returns 200 and never ingests it, so the image would silently stay broken. Upload the asset to Kajabi first and pass the storage path it returns."
33612
+ },
33613
+ // CS-1554: `search_contacts` accepts `tag_id`, does not apply it, and
33614
+ // returns the FULL unfiltered contact list with `filters_applied: null`.
33615
+ // Reported first-hand from a live client site (DTI) while auditing which
33616
+ // contacts carried an opt-in tag. Corroborating evidence: Kajabi's own
33617
+ // REST reference filters contacts with `filter[has_tag_id]`, not a bare
33618
+ // `tag_id` — so the argument is dropped as unrecognised and the response
33619
+ // says so, if you read `filters_applied`.
33620
+ //
33621
+ // Worse than the thumbnail case it sits next to. A broken image is
33622
+ // visible; an unfiltered list that reads as filtered produces a confident
33623
+ // wrong ANSWER, which a human then acts on. That is the same shape as the
33624
+ // incident in CS-1554 where the agent told the customer content did not
33625
+ // exist when it did.
33626
+ //
33627
+ // Any value at all is refused: the field is not partially supported, it
33628
+ // is inert. `[\s\S]` matches every stringified scalar including 0 and
33629
+ // false, which a `.`-style pattern anchored on truthiness would miss.
33630
+ //
33631
+ // NOT REPRODUCED BY ME — I have no Kajabi connection. This rests on the
33632
+ // CS-1554 first-hand report plus the REST reference. The file's own bar is
33633
+ // "provably wrong, never a guess", so a reviewer with a live Kajabi
33634
+ // connection should confirm before this merges. If `tag_id` DOES filter
33635
+ // for some tenant, drop this rule and keep the scalar fix.
33636
+ {
33637
+ tool: "search_contacts",
33638
+ field: "tag_id",
33639
+ pattern: "[\\s\\S]",
33640
+ message: "tag_id is accepted by Kajabi and never applied \u2014 the call returns the FULL contact list with filters_applied: null, which reads as a filtered result and is not one. There is no working tag filter on this tool today. Use list_tags plus the per-contact tag data to determine membership, and treat any tag audit built on search_contacts(tag_id) as unfiltered."
33641
+ }
33642
+ ]
33643
+ },
33644
+ "notion-cli": {
33645
+ // Notion's public OAuth app. Tokens are workspace-scoped and long-lived —
33646
+ // Notion does not issue refresh_tokens, so `supportsRefresh: false` and
33647
+ // the refresh cron skips this provider entirely. Scopes are not part of
33648
+ // Notion's authorize URL contract; consent is governed by what the user
33649
+ // grants in the OAuth screen, so `defaultScopes` stays empty.
33650
+ // `owner=user` forces the user-OAuth variant (vs internal integration).
33651
+ // Requires OAUTH_NOTION_CLI_CLIENT_ID and OAUTH_NOTION_CLI_CLIENT_SECRET.
33652
+ definitionId: "notion-cli",
33653
+ authorizeUrl: "https://api.notion.com/v1/oauth/authorize",
33654
+ tokenUrl: "https://api.notion.com/v1/oauth/token",
33655
+ defaultScopes: [],
33656
+ supportsRefresh: false,
33657
+ extraAuthorizeParams: {
33658
+ owner: "user"
33659
+ },
33660
+ clientAuthMethod: "basic"
33661
+ },
33662
+ "xero": {
33663
+ definitionId: "xero",
33664
+ authorizeUrl: "https://login.xero.com/identity/connect/authorize",
33665
+ tokenUrl: "https://identity.xero.com/connect/token",
33666
+ revokeUrl: "https://identity.xero.com/connect/revocation",
33667
+ defaultScopes: [
33668
+ "openid",
33669
+ "profile",
33670
+ "email",
33671
+ "offline_access",
33672
+ // Granular scopes (required for apps created after March 2, 2026 —
33673
+ // do NOT revert to the broad `accounting.transactions` /
33674
+ // `accounting.contacts` scopes, Xero rejects the manifest).
33675
+ // The variant *without* `.read` is the read+write granular scope.
33676
+ "accounting.settings.read",
33677
+ // contacts: write enables agent-driven supplier/customer creation
33678
+ // (required for bill creation since a bill must reference a contact).
33679
+ "accounting.contacts",
33680
+ // invoices: write enables bill creation (Type=ACCPAY invoices) and
33681
+ // updates to sales invoices alongside the existing read access.
33682
+ "accounting.invoices",
33683
+ // attachments: write enables agents to attach the source PDF to a
33684
+ // bill at creation time. Read-only would force a follow-up manual
33685
+ // upload in Xero; write closes the loop.
33686
+ "accounting.attachments",
33687
+ // accounting.transactions.read → granular read-only replacements
33688
+ // for the surfaces we don't yet need write access on.
33689
+ "accounting.payments.read",
33690
+ "accounting.banktransactions.read",
33691
+ // manualjournals: write (CS-1439) enables the xero-broker to post
33692
+ // manual journals (reclasses, accruals, corrections) on approval. The
33693
+ // variant without `.read` is the read+write granular scope. Note: an
33694
+ // existing Xero install must RECONNECT for its token to carry this — the
33695
+ // broker posts journals with the agent's own OAuth access_token.
33696
+ "accounting.manualjournals",
33697
+ // accounting.reports.read → granular read-only replacements
33698
+ "accounting.reports.balancesheet.read",
33699
+ "accounting.reports.profitandloss.read",
33700
+ "accounting.reports.trialbalance.read",
33701
+ "accounting.reports.budgetsummary.read",
33702
+ "accounting.reports.banksummary.read",
33703
+ "accounting.reports.executivesummary.read",
33704
+ "accounting.reports.aged.read"
33705
+ ],
33706
+ // Read-only variant (ENG-6170): the `.read` granular scope for every
33707
+ // surface, so a token granted under it cannot create bills/invoices or
33708
+ // mutate contacts/attachments. Used when an install is (re)connected with
33709
+ // `read_only: true` — e.g. to lock a production-books integration to reads
33710
+ // until per-vendor broker mediation (ENG-4922) gates its writes.
33711
+ readOnlyScopes: [
33712
+ "openid",
33713
+ "profile",
33714
+ "email",
33715
+ "offline_access",
33716
+ "accounting.settings.read",
33717
+ "accounting.contacts.read",
33718
+ "accounting.invoices.read",
33719
+ "accounting.attachments.read",
33720
+ "accounting.payments.read",
33721
+ "accounting.banktransactions.read",
33722
+ "accounting.manualjournals.read",
33723
+ "accounting.reports.balancesheet.read",
33724
+ "accounting.reports.profitandloss.read",
33725
+ "accounting.reports.trialbalance.read",
33726
+ "accounting.reports.budgetsummary.read",
33727
+ "accounting.reports.banksummary.read",
33728
+ "accounting.reports.executivesummary.read",
33729
+ "accounting.reports.aged.read"
33730
+ ],
33731
+ supportsRefresh: true,
33732
+ extraAuthorizeParams: {},
33733
+ clientAuthMethod: "basic",
33734
+ userInfoUrl: "https://api.xero.com/connections"
33735
+ },
33736
+ // LinkedIn Ads (Marketing API). Confidential client with a static secret and
33737
+ // refresh tokens (~60-day access token, ~1-year rotating refresh token), so it
33738
+ // mirrors the Xero shape: clientAuthMethod 'body', supportsRefresh true, no
33739
+ // PKCE. The shared authorize/callback/refresh machinery handles the rest.
33740
+ //
33741
+ // The single shared app is Augmented Team's own LinkedIn developer app
33742
+ // (client id/secret in OAUTH_LINKEDIN_ADS_CLIENT_ID / _SECRET) - every org
33743
+ // connects its own ad accounts against it; only the per-connection tokens
33744
+ // differ. Register `${API_PUBLIC_URL}/integrations/oauth/callback` as an
33745
+ // Authorized redirect URL on the LinkedIn app.
33746
+ //
33747
+ // NOTE (linkedin-verify): the grantable scope set depends on which LinkedIn
33748
+ // API products the app is approved for (Advertising API, Lead Sync API,
33749
+ // Community Management API). Keep this list to scopes the app actually holds -
33750
+ // requesting an ungranted scope makes LinkedIn reject the authorize request.
33751
+ "linkedin-ads": {
33752
+ definitionId: "linkedin-ads",
33753
+ authorizeUrl: "https://www.linkedin.com/oauth/v2/authorization",
33754
+ tokenUrl: "https://www.linkedin.com/oauth/v2/accessToken",
33755
+ // ENG-7897: this list is EXACTLY the Advertising API scope set, because
33756
+ // Advertising API is the only product added to the Brand Ninja app. Every
33757
+ // other scope we used to request here belonged to a product the app does
33758
+ // not hold, and LinkedIn rejects the ENTIRE authorize request with
33759
+ // `unauthorized_scope_error` if ANY single requested scope is ungranted -
33760
+ // so five unapproved scopes bricked the connect for every customer, on
33761
+ // every environment, rather than merely disabling five features.
33762
+ //
33763
+ // Scopes deliberately NOT requested, and the product each needs first:
33764
+ // openid / profile / email -> Sign In with LinkedIn (OpenID Connect)
33765
+ // r_organization_social -> Community Management API
33766
+ // r_marketing_leadgen_automation -> Lead Sync API
33767
+ //
33768
+ // Dropping the OIDC trio costs only the `Connected as <name>` label: the
33769
+ // userInfoUrl fetch in the callback is already best-effort and falls back
33770
+ // to a plain 'Connected'. Do NOT re-add any of these until the matching
33771
+ // product shows under "Added products" on the app - use the
33772
+ // OAUTH_LINKEDIN_ADS_SCOPES override below to widen without a deploy once
33773
+ // an approval lands, and only then promote it into this constant.
33774
+ defaultScopes: [
33775
+ // Advertising API: read + manage campaigns/creatives, and reporting.
33776
+ "r_ads",
33777
+ "rw_ads",
33778
+ "r_ads_reporting"
33779
+ ],
33780
+ // Read-only variant: reporting only, no campaign/creative mutation. Used
33781
+ // when an install is (re)connected with read_only: true. Same product
33782
+ // constraint as above - `r_organization_social` was removed with it.
33783
+ readOnlyScopes: [
33784
+ "r_ads",
33785
+ "r_ads_reporting"
33786
+ ],
33787
+ supportsRefresh: true,
33788
+ extraAuthorizeParams: {},
33789
+ clientAuthMethod: "body",
33790
+ userInfoUrl: "https://api.linkedin.com/v2/userinfo"
33791
+ }
33792
+ };
33793
+ OAUTH_PROVIDERS["xero-control-plane"] = {
33794
+ ...OAUTH_PROVIDERS["xero"]
33795
+ };
33796
+
33344
33797
  // ../core/dist/integrations/composio-account-probe.js
33345
33798
  var BODY_MAX_BYTES = 1024 * 1024;
33346
33799
 
@@ -49,8 +49,8 @@ import {
49
49
  writeDirectChatSessionState,
50
50
  writeEgressAllowlist,
51
51
  writePersistentClaudeWrapper
52
- } from "./chunk-NRMBKDER.js";
53
- import "./chunk-N6DU2RYO.js";
52
+ } from "./chunk-NTWABPKO.js";
53
+ import "./chunk-LLBJLKGL.js";
54
54
  import "./chunk-XWVM4KPK.js";
55
55
  export {
56
56
  EGRESS_BASELINE_DOMAINS,
@@ -104,4 +104,4 @@ export {
104
104
  writeEgressAllowlist,
105
105
  writePersistentClaudeWrapper
106
106
  };
107
- //# sourceMappingURL=persistent-session-CGIB77UQ.js.map
107
+ //# sourceMappingURL=persistent-session-GHIBAWHI.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  paneLogPath
3
- } from "./chunk-NRMBKDER.js";
4
- import "./chunk-N6DU2RYO.js";
3
+ } from "./chunk-NTWABPKO.js";
4
+ import "./chunk-LLBJLKGL.js";
5
5
  import "./chunk-XWVM4KPK.js";
6
6
 
7
7
  // src/lib/responsiveness-probe.ts
@@ -745,4 +745,4 @@ export {
745
745
  readAndResetSlackReplyBindingClassifications,
746
746
  readAndResetSlackReplyTargetClassifications
747
747
  };
748
- //# sourceMappingURL=responsiveness-probe-YINXZH3S.js.map
748
+ //# sourceMappingURL=responsiveness-probe-TT3LAALK.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  sessionTranscriptDir
3
- } from "./chunk-N6DU2RYO.js";
3
+ } from "./chunk-LLBJLKGL.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-OZBNHFPN.js.map
206
+ //# sourceMappingURL=session-auth-dead-OHPGSHYL.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@integrity-labs/agt-cli",
3
- "version": "0.28.778",
3
+ "version": "0.28.779",
4
4
  "description": "Augmented Team CLI — agent provisioning and management",
5
5
  "type": "module",
6
6
  "engines": {