Skip to content

feat(integration): post-OAuth accessible-resources picker + set-metadata CLI/SDK#142

Merged
khaliqgant merged 2 commits into
mainfrom
agent-relay/integration-accessible-resources
May 12, 2026
Merged

feat(integration): post-OAuth accessible-resources picker + set-metadata CLI/SDK#142
khaliqgant merged 2 commits into
mainfrom
agent-relay/integration-accessible-resources

Conversation

@khaliqgant
Copy link
Copy Markdown
Member

Draft until cloud#540 merges + deploys. The new SDK / CLI verbs call endpoints that don't exist on cloud main yet.

Summary

Cross-repo consumer of cloud's new GET .../accessible-resources and PUT .../metadata routes (see https://github.com/AgentWorkforce/cloud/pull/540). Together with that change this closes the loop on Jira/Confluence multi-tenant setup (cloud#535): operators no longer need to dive into the Nango dashboard to pick a cloudId after OAuth completes.

TS SDK (packages/sdk/typescript)

  • WorkspaceHandle.listAccessibleResources(provider) returns [{ id, url, name?, scopes?, avatarUrl? }] for Atlassian-family providers. Cloud's typed 400 for non-Atlassian providers surfaces as CloudApiError so callers can branch on the code.
  • WorkspaceHandle.setIntegrationMetadata(provider, metadata) PUTs the metadata namespace (full replacement, not merge); rejects non-object metadata locally before hitting Cloud.
  • Both accept WorkspaceIntegrationProvider | string so callers can target dynamically-discovered providers without an SDK release.

Python SDK (packages/sdk/python)

  • RelayFileClient and AsyncRelayFileClient gain list_accessible_resources(workspace_id, provider) and set_integration_metadata(workspace_id, provider, metadata).
  • Both clients also accept a cloud_base_url constructor arg because cloud's control plane is a different host from the relayfile data plane (https://agentrelay.com/cloud vs https://api.relayfile.dev).

Go CLI (cmd/relayfile-cli/main.go)

  • relayfile integration connect jira (and ... confluence) now calls accessible-resources after OAuth completes:
    • 0 sites: warn and fail (continuing would queue a sync that cannot succeed)
    • 1 site: auto-set { cloudId, baseUrl } and log "auto-selected"
    • >1 sites: numbered picker with default-to-1 on blank input, validates range, retries up to 3 times then errors out
  • Non-Atlassian providers skip the picker entirely so the existing connect flow is preserved.
  • New verb: relayfile integration set-metadata PROVIDER KEY=VALUE [KEY=VALUE...] [--workspace NAME] [--yes] — general-purpose, usable for any provider (Jira cloudId/baseUrl, linear team_id, custom API hosts, etc.). v1 is flat-keys-only; nested keys deferred.
  • Usage banner updated with both the new verb and a note that integration connect jira/confluence does post-OAuth site selection.

Test plan

  • npm test --workspace packages/sdk/typescript — 144/144 passing (6 new)
  • pytest packages/sdk/python — 52/52 passing (6 new)
  • go test ./cmd/relayfile-cli/ — passing (7 new tests: set-metadata happy path, KEY=VALUE validation, single-site auto-select, multi-site interactive pick, blank-input default, retry-then-error, non-Atlassian no-op)
  • go build ./... — clean
  • After cloud#540 deploys: smoke-test relayfile integration connect jira against a workspace with 2+ Atlassian sites, confirm prompt + selection + sync start

Judgment calls

  • Metadata route uses setMetadata (full replacement) rather than updateMetadata (merge) because the CLI confirmation prompt becomes truthful only with full replacement; callers wanting merge can read existing metadata first.
  • The picker constructs its own bufio.Reader rather than going through promptLine because promptLine creates a fresh bufio reader per call and drops bytes buffered past the first newline — that breaks the retry loop when stdin is a pre-loaded reader (tests / piped scripts).
  • Cloud-side validation rejects top-level _*, connection_*, auth_*, provider_config_key, connection_id keys to keep Nango plumbing safe, but allows these as nested keys under operator-supplied parents so legitimate domain metadata like { custom: { auth_url: "..." } } still works.

🤖 Generated with Claude Code

…ata CLI/SDK

Cross-repo consumer of cloud's new GET .../accessible-resources and
PUT .../metadata routes. Together with the cloud-side change this
closes the loop on Jira/Confluence multi-tenant setup (cloud#535):
operators no longer need to dive into the Nango dashboard to pick a
cloudId after OAuth completes.

TS SDK (packages/sdk/typescript):
- WorkspaceHandle.listAccessibleResources(provider) returns
  [{ id, url, name?, scopes?, avatarUrl? }] for Atlassian-family
  providers; Cloud's typed 400 for non-Atlassian providers surfaces
  as CloudApiError so callers can branch on the code.
- WorkspaceHandle.setIntegrationMetadata(provider, metadata) PUTs the
  metadata namespace (full replacement); rejects non-object metadata
  locally before hitting Cloud so the failure mode is immediate.
- 6 new vitest cases covering happy path, junk-entry filtering,
  cloud error pass-through, and runtime guards.

Python SDK (packages/sdk/python):
- RelayFileClient and AsyncRelayFileClient gain list_accessible_resources
  and set_integration_metadata. Both clients also accept a
  cloud_base_url constructor arg because cloud's control plane is a
  different host from the relayfile data plane.
- 6 new respx-backed tests across sync + async paths.

Go CLI (cmd/relayfile-cli/main.go):
- `relayfile integration connect jira` (and `... confluence`) now
  calls accessible-resources after OAuth completes:
    * 0 sites: warn and fail (continuing would queue a sync that
      cannot succeed).
    * 1 site: auto-set { cloudId, baseUrl } and log "auto-selected".
    * >1 sites: numbered picker with default-to-1 on blank input,
      validates range, retries up to 3 times then errors out.
  Non-Atlassian providers skip the picker entirely so the existing
  connect flow is unchanged.
- New `relayfile integration set-metadata PROVIDER KEY=VALUE [...]`
  verb for general-purpose metadata writes (any provider, not just
  Jira). v1 accepts flat KEY=VALUE pairs only; nested keys are
  documented as a future enhancement.
- The picker uses a single bufio.Reader for the retry loop rather
  than promptLine, because promptLine creates a fresh bufio reader
  per call and drops bytes buffered past the first newline — that
  would break the retry path when stdin is a pre-loaded reader.
- Usage banner updated; 7 new Go tests covering set-metadata happy
  path, KEY=VALUE validation, single-site auto-select, multi-site
  interactive pick, blank-input default, retry-then-error, and the
  non-Atlassian no-op path.

Validation:
- npm test --workspace packages/sdk/typescript: 144 passing
- pytest packages/sdk/python: 52 passing
- go test ./cmd/relayfile-cli/: passing
- go build ./...: clean

Depends on cloud#540; this PR is draft until that lands and deploys.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 12, 2026

Review Change Stack

Warning

Rate limit exceeded

@khaliqgant has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 2 minutes and 32 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8c6ac336-0073-43c7-b575-f3c5131dc40c

📥 Commits

Reviewing files that changed from the base of the PR and between 6fd936e and 44e8150.

📒 Files selected for processing (7)
  • cmd/relayfile-cli/main.go
  • cmd/relayfile-cli/main_test.go
  • cmd/relayfile-cli/setup_e2e_test.go
  • packages/sdk/python/src/relayfile/client.py
  • packages/sdk/python/tests/test_client.py
  • packages/sdk/typescript/src/setup.test.ts
  • packages/sdk/typescript/src/setup.ts
📝 Walkthrough

Walkthrough

This PR introduces cloud-control-plane integration setup capabilities across the SDK and CLI. TypeScript and Python SDKs gain public methods to list accessible OAuth resources and update integration metadata. The CLI adds a set-metadata subcommand and extends the connect flow for Atlassian providers with an interactive site-picker after OAuth authentication completes.

Changes

Integration Metadata and Accessible Resources

Layer / File(s) Summary
TypeScript SDK: accessible resources and metadata APIs
packages/sdk/typescript/src/setup.ts, packages/sdk/typescript/src/setup.test.ts
WorkspaceHandle gains listAccessibleResources and setIntegrationMetadata methods targeting cloud control-plane endpoints, with provider normalization and response filtering. Tests verify request shapes, error handling, and payload validation.
Python SDK: sync client cloud support and setup APIs
packages/sdk/python/src/relayfile/client.py, packages/sdk/python/tests/test_client.py
RelayFileClient adds cloud_base_url parameter and request routing override, plus list_accessible_resources and set_integration_metadata public methods. Tests validate accessible-resource normalization, error surfacing, and metadata PUT forwarding.
Python SDK: async client cloud support and setup APIs
packages/sdk/python/src/relayfile/client.py, packages/sdk/python/tests/test_client.py
AsyncRelayFileClient mirrors sync changes with async/await versions of cloud setup methods and request routing. Tests cover async accessible-resources and metadata-setting flows.
CLI: set-metadata subcommand for integration metadata updates
cmd/relayfile-cli/main.go, cmd/relayfile-cli/main_test.go
New integration set-metadata command parses flat KEY=VALUE pairs, validates input, displays confirmation preview (unless --yes), and issues Cloud PUT request. Tests cover happy path, missing args, and malformed input validation.
CLI: Atlassian site picker flow for integration connect
cmd/relayfile-cli/main.go, cmd/relayfile-cli/main_test.go
Extends integration connect for jira and confluence with post-OAuth site selection: fetches accessible resources, auto-selects single site or prompts user with numbered selection (with retry bounds), then PUTs selected cloudId/baseUrl to metadata. Non-Atlassian providers skip picker. Tests verify all picker behaviors and error paths.

🎯 4 (Complex) | ⏱️ ~45 minutes


🐰 New metadata flows and site pickers bloom,
Cloud SDKs now grant operators elbow room,
Select your Jira site with a numbered choice,
Integration control now has a voice!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.91% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and accurately summarizes the main feature additions: a post-OAuth accessible-resources picker for Atlassian integrations and a set-metadata CLI/SDK capability.
Description check ✅ Passed The description comprehensively explains the changes across multiple components (TS SDK, Python SDK, Go CLI), their purpose in solving the Jira/Confluence multi-tenant setup problem, implementation details, test coverage, and design decisions.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent-relay/integration-accessible-resources

Comment @coderabbitai help to get the list of available commands and usage tips.

@khaliqgant khaliqgant marked this pull request as ready for review May 12, 2026 10:29
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

View 4 additional findings in Devin Review.

Open in Devin Review

Comment thread cmd/relayfile-cli/main.go
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Atlassian site picker missing from runSetup flow, causing Jira/Confluence setup to fail

The Atlassian site picker (runAtlassianSitePicker) is only wired into the runIntegrationConnect path (cmd/relayfile-cli/main.go:1464-1468) but is completely absent from the runSetup path. When an operator runs relayfile setup --provider jira, the code calls connectCloudIntegration (line 562) or ensureCloudIntegration (line 566) and then proceeds directly to waitForInitialSync (line 571) without ever invoking the site picker. The PR's own comments at cmd/relayfile-cli/main.go:1457-1462 state that "Cloud's Jira/Confluence sync bails with a clear error if metadata.cloudId is unset and the grant has >1 site." This means the guided relayfile setup --provider jira flow will complete OAuth but then hang or fail on the initial sync wait because no cloudId metadata was set for multi-site grants.

(Refers to lines 560-574)

Prompt for agents
The runSetup function in cmd/relayfile-cli/main.go (around lines 560-574) calls connectCloudIntegration or ensureCloudIntegration and then waitForInitialSync, but never invokes the Atlassian site picker for jira/confluence providers. The fix should mirror what runIntegrationConnect does at lines 1464-1468: after the connectCloudIntegration/ensureCloudIntegration call succeeds but before waitForInitialSync, check isAtlassianProvider(selectedProvider) and if true call runAtlassianSitePicker(tokenSet.APIURL, record.ID, joined.Token, selectedProvider, stdin, stdout). The stdin parameter is already available in runSetup's signature. This should be added in both the createdWorkspace and the else branch, or after the if/else block but before the waitForInitialSync call.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (3)
packages/sdk/typescript/src/setup.test.ts (2)

568-587: ⚡ Quick win

Assert the “no cloud call” guarantee explicitly in the local-validation test.

The test title says validation happens before Cloud, but it currently doesn’t verify fetch call count after invalid inputs.

Proposed patch
-    queueFetch(makeJoinResponse())
+    const fetchMock = queueFetch(makeJoinResponse())
@@
     await expect(
       // `@ts-expect-error` - exercising runtime guard
       handle.setIntegrationMetadata("jira", ["array"])
     ).rejects.toThrow(/metadata must be a plain object/)
+    expect(fetchMock).toHaveBeenCalledTimes(1)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/sdk/typescript/src/setup.test.ts` around lines 568 - 587, The test
currently checks runtime validation errors from handle.setIntegrationMetadata
but doesn't assert that no network call was made; after each invalid-call
expect(...).rejects, also assert the fetch/mock queue hasn't been consumed
(i.e., verify no Cloud fetch was attempted). Update the test around
RelayfileSetup/handle.setIntegrationMetadata and queueFetch(makeJoinResponse())
to check the fetch mock call count or remaining queue length after each
rejection (use the existing fetch-mocking utilities in the test suite to assert
zero additional fetches occurred).

424-525: ⚡ Quick win

Add one normalization-focused test for provider input casing/whitespace.

Given the new WorkspaceIntegrationProvider | string support, a dedicated test for " JiRa " (success) and "" (throws) would lock in the intended contract.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/sdk/typescript/src/setup.test.ts` around lines 424 - 525, Add a
normalization-focused unit test in the existing setup.test.ts suite that covers
the new WorkspaceIntegrationProvider | string support: create a test that uses
RelayfileSetup and joinWorkspace to call handle.listAccessibleResources with a
provider string containing mixed case and surrounding whitespace (e.g., "  JiRa 
") and assert it behaves like "jira" (returns the expected resources and issues
the same request URL/Authorization), and add another assertion or separate test
that calling listAccessibleResources with an empty string ("") rejects/throws
(matching the SDK’s error behavior). Reference the RelayfileSetup class and the
listAccessibleResources method when adding the test so it validates input
trimming/lowercasing and empty-string rejection.
packages/sdk/python/tests/test_client.py (1)

661-707: ⚡ Quick win

Add async negative-path parity tests for the new APIs.

Please mirror the sync negative cases in async (non-dict metadata and cloud 400 invalid_metadata / provider_has_no_accessible_resources) to lock in behavior parity.

As per coding guidelines, packages/sdk/python/**/*client*.py: “Maintain both sync and async client behavior when adding endpoints or retry/error handling.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/sdk/python/tests/test_client.py` around lines 661 - 707, Add async
negative-path tests mirroring the sync suite to ensure parity: in the
TestIntegrationSetupAsync class add a test that calls
AsyncRelayFileClient.set_integration_metadata with a non-dict metadata argument
and asserts the client raises the same exception as the sync version; also add
tests that mock the cloud endpoints (accessible-resources and
integrations/jira/metadata) to return 400 JSON errors like {"ok": False,
"error": {"code": "provider_has_no_accessible_resources"}} and {"ok": False,
"error": {"code": "invalid_metadata"}} and assert the async client
(AsyncRelayFileClient.list_accessible_resources and set_integration_metadata)
surface those error conditions exactly as the sync tests expect.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cmd/relayfile-cli/main_test.go`:
- Around line 2603-2615: The test HTTP handler currently silently returns 200 {}
for unexpected paths, letting waitForInitialSync and the connect flow miss or
call the wrong routes without failing; update the default branch of the switch
(the handler that matches strings.HasPrefix for
"/v1/workspaces/ws_123/syncs/jira" and "/v1/workspaces/ws_123/fs/tree") to fail
the test on any unexpected URL: return a non-2xx status (e.g.
http.StatusNotFound or http.StatusInternalServerError) and include the request
path in the response body (or panic) so the test fails loudly when
waitForInitialSync (the function under test) does not hit the real
"/v1/workspaces/<id>/sync/status" endpoint.

In `@cmd/relayfile-cli/main.go`:
- Around line 1454-1468: The Atlassian site picker is being invoked
unconditionally even when ensureCloudIntegration(...) did not perform a new
OAuth connect, which can overwrite existing metadata; change
ensureCloudIntegration to surface whether a new connection was created (e.g.,
return (bool, error) or set a returned/side-channel flag) and update the caller
in main.go to capture that "created" result from
ensureCloudIntegration(cloudCreds.APIURL, record.ID, joined.Token, provider,
requestedBackend, record.LocalDir, *timeout, !*noOpen, stdout) and only call
runAtlassianSitePicker(cloudCreds.APIURL, record.ID, joined.Token, provider,
stdin, stdout) when the created flag is true and isAtlassianProvider(provider)
is true; keep error handling identical for the updated ensureCloudIntegration
signature.
- Around line 2044-2055: The metadata parsing loop currently accepts keys like
"foo.bar" or "a[b]" but the CLI contract requires flat keys only; update the
loop that builds the metadata map (the for _, raw := range rest[1:] block that
sets key, value and metadata[key]=value) to validate the trimmed key and reject
any nested-looking keys (e.g., containing '.', '[' or ']') by returning an error
(use the existing fmt.Errorf pattern and include raw and key for context) so
only plain flat KEY names are accepted before adding to metadata.

In `@packages/sdk/python/src/relayfile/client.py`:
- Around line 880-885: The code silently returns the original input variable
metadata when the cloud response is malformed (payload missing or has non-dict
"metadata"); instead, change the behavior to fail fast by raising a clear
exception (e.g., ValueError or a module-specific InvalidResponseError) that
includes the offending payload for debugging. Replace the current pattern (if
isinstance(payload, dict): updated = payload.get("metadata"); if
isinstance(updated, dict): return updated; return metadata) with a strict
validation that raises when payload is not a dict or payload.get("metadata") is
missing/not a dict, and apply the same change to the other matching block in
client.py that uses the same payload/metadata pattern.

In `@packages/sdk/typescript/src/setup.ts`:
- Around line 838-850: The current validation accepts non-plain objects
(Date/Map) and the response check allows arrays; update the input and output
guards in the setIntegrationMetadata flow: for the input `metadata` (before
calling this._setup.requestJson) require typeof metadata === "object" &&
metadata !== null && !Array.isArray(metadata) && Object.getPrototypeOf(metadata)
=== Object.prototype (or equivalent "plain object" check) and reject otherwise;
after the request, ensure `response.metadata` is also a plain object (same
check: object, non-null, not Array, prototype === Object.prototype) before
returning it as Record<string, unknown>, and throw or surface an error if the
response shape is invalid. Use the same strict checks around the response from
this._setup.requestJson with operation "setIntegrationMetadata".

---

Nitpick comments:
In `@packages/sdk/python/tests/test_client.py`:
- Around line 661-707: Add async negative-path tests mirroring the sync suite to
ensure parity: in the TestIntegrationSetupAsync class add a test that calls
AsyncRelayFileClient.set_integration_metadata with a non-dict metadata argument
and asserts the client raises the same exception as the sync version; also add
tests that mock the cloud endpoints (accessible-resources and
integrations/jira/metadata) to return 400 JSON errors like {"ok": False,
"error": {"code": "provider_has_no_accessible_resources"}} and {"ok": False,
"error": {"code": "invalid_metadata"}} and assert the async client
(AsyncRelayFileClient.list_accessible_resources and set_integration_metadata)
surface those error conditions exactly as the sync tests expect.

In `@packages/sdk/typescript/src/setup.test.ts`:
- Around line 568-587: The test currently checks runtime validation errors from
handle.setIntegrationMetadata but doesn't assert that no network call was made;
after each invalid-call expect(...).rejects, also assert the fetch/mock queue
hasn't been consumed (i.e., verify no Cloud fetch was attempted). Update the
test around RelayfileSetup/handle.setIntegrationMetadata and
queueFetch(makeJoinResponse()) to check the fetch mock call count or remaining
queue length after each rejection (use the existing fetch-mocking utilities in
the test suite to assert zero additional fetches occurred).
- Around line 424-525: Add a normalization-focused unit test in the existing
setup.test.ts suite that covers the new WorkspaceIntegrationProvider | string
support: create a test that uses RelayfileSetup and joinWorkspace to call
handle.listAccessibleResources with a provider string containing mixed case and
surrounding whitespace (e.g., "  JiRa  ") and assert it behaves like "jira"
(returns the expected resources and issues the same request URL/Authorization),
and add another assertion or separate test that calling listAccessibleResources
with an empty string ("") rejects/throws (matching the SDK’s error behavior).
Reference the RelayfileSetup class and the listAccessibleResources method when
adding the test so it validates input trimming/lowercasing and empty-string
rejection.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c9260420-139e-408f-8052-95013ebfc451

📥 Commits

Reviewing files that changed from the base of the PR and between 8aabf6d and 6fd936e.

📒 Files selected for processing (6)
  • cmd/relayfile-cli/main.go
  • cmd/relayfile-cli/main_test.go
  • packages/sdk/python/src/relayfile/client.py
  • packages/sdk/python/tests/test_client.py
  • packages/sdk/typescript/src/setup.test.ts
  • packages/sdk/typescript/src/setup.ts

Comment thread cmd/relayfile-cli/main_test.go Outdated
Comment thread cmd/relayfile-cli/main.go Outdated
Comment thread cmd/relayfile-cli/main.go
Comment thread packages/sdk/python/src/relayfile/client.py Outdated
Comment thread packages/sdk/typescript/src/setup.ts Outdated
@khaliqgant khaliqgant merged commit ff33014 into main May 12, 2026
7 checks passed
@khaliqgant khaliqgant deleted the agent-relay/integration-accessible-resources branch May 12, 2026 10:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant