diff --git a/.changeset/hide-only-you-session-share-url.md b/.changeset/hide-only-you-session-share-url.md
new file mode 100644
index 0000000000..2014d108c1
--- /dev/null
+++ b/.changeset/hide-only-you-session-share-url.md
@@ -0,0 +1,5 @@
+---
+'@truefoundry/trueforge-ui': patch
+---
+
+Hide the session share URL when access is Only you.
diff --git a/packages/trueforge-ui/src/atoms/ShareSessionDialog.tsx b/packages/trueforge-ui/src/atoms/ShareSessionDialog.tsx
index 155ceb0c97..855d7ba00d 100644
--- a/packages/trueforge-ui/src/atoms/ShareSessionDialog.tsx
+++ b/packages/trueforge-ui/src/atoms/ShareSessionDialog.tsx
@@ -129,34 +129,38 @@ export function ShareSessionDialog({ sessionId, trigger }: ShareSessionDialogPro
void changePermission(next);
}}
/>
-
-
-
-
- {
- track(AnalyticsEvents.Session.SHARE_LINK_COPIED, {
- session_id: sessionId,
- permission,
- });
- copySharedSessionLink();
- }}
- >
-
- {copied ? 'Copied' : 'Copy'}
-
-
+ {permission === 'tenant' ? (
+ <>
+
+
+
+
+ {
+ track(AnalyticsEvents.Session.SHARE_LINK_COPIED, {
+ session_id: sessionId,
+ permission,
+ });
+ copySharedSessionLink();
+ }}
+ >
+
+ {copied ? 'Copied' : 'Copy'}
+
+
+ >
+ ) : null}
);
}
diff --git a/packages/trueforge-ui/test/atoms/SessionsPage.test.tsx b/packages/trueforge-ui/test/atoms/SessionsPage.test.tsx
index 78de15a5a0..0adcba0700 100644
--- a/packages/trueforge-ui/test/atoms/SessionsPage.test.tsx
+++ b/packages/trueforge-ui/test/atoms/SessionsPage.test.tsx
@@ -273,12 +273,21 @@ describe('SessionsPage', () => {
it('copies the no-router shared-session query URL for the selected session', async () => {
window.history.replaceState(null, '', '/?view=sessions&sessionId=sess-1&agentId=agent-1&s_tw=30');
- renderPage();
+ renderPage({
+ getSession: vi.fn(async (): Promise => ({
+ id: 'sess-1',
+ title: 'Named session',
+ isMutable: false,
+ shared: true,
+ createdAt: namedRow.createdAt,
+ updatedAt: namedRow.updatedAt,
+ })),
+ });
fireEvent.click(await screen.findByRole('button', { name: 'Share' }));
expect(await screen.findByText('Change permissions')).toBeInTheDocument();
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
- fireEvent.click(screen.getByRole('button', { name: 'Copy' }));
+ fireEvent.click(await screen.findByRole('button', { name: 'Copy' }));
await waitFor(() => {
expect(clipboardWriteText).toHaveBeenCalledOnce();
diff --git a/packages/trueforge-ui/test/atoms/ShareChatButton.test.tsx b/packages/trueforge-ui/test/atoms/ShareChatButton.test.tsx
index 25c13308ab..97e00c6ddf 100644
--- a/packages/trueforge-ui/test/atoms/ShareChatButton.test.tsx
+++ b/packages/trueforge-ui/test/atoms/ShareChatButton.test.tsx
@@ -52,11 +52,22 @@ describe('ShareChatButton', () => {
it('opens the share popover and copies the routed shared-session URL', async () => {
activeThread.remoteId = 'session-1';
+ const server = createMockAgentUIServer({
+ getSession: vi.fn(async () => ({
+ id: 'session-1',
+ isMutable: true,
+ shared: true,
+ createdAt: '2026-01-01T00:00:00Z',
+ updatedAt: '2026-01-01T00:00:00Z',
+ })),
+ });
render(
-
-
-
+
+
+
+
+
,
);
@@ -64,7 +75,7 @@ describe('ShareChatButton', () => {
expect(await screen.findByText('Change permissions')).toBeInTheDocument();
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
- fireEvent.click(screen.getByRole('button', { name: 'Copy' }));
+ fireEvent.click(await screen.findByRole('button', { name: 'Copy' }));
await waitFor(() => {
expect(writeText).toHaveBeenCalledOnce();
});
diff --git a/packages/trueforge-ui/test/atoms/ShareSessionDialog.test.tsx b/packages/trueforge-ui/test/atoms/ShareSessionDialog.test.tsx
index bb19e21e2c..567d2ed623 100644
--- a/packages/trueforge-ui/test/atoms/ShareSessionDialog.test.tsx
+++ b/packages/trueforge-ui/test/atoms/ShareSessionDialog.test.tsx
@@ -85,11 +85,28 @@ async function openSharePopover() {
}
describe('ShareSessionDialog', () => {
- it('loads current sharing and copies the share URL', async () => {
+ it('hides the share URL while access is Only you', async () => {
renderDialog();
await openSharePopover();
expect(await screen.findByRole('button', { name: 'Session sharing' })).toHaveTextContent('Only you');
+ expect(screen.queryByLabelText('Share URL')).not.toBeInTheDocument();
+ expect(screen.queryByRole('button', { name: 'Copy' })).not.toBeInTheDocument();
+ });
+
+ it('loads tenant sharing and copies the share URL', async () => {
+ renderDialog({
+ getSession: vi.fn(async () => ({
+ id: 'session-1',
+ isMutable: true,
+ shared: true,
+ createdAt: '2026-01-01T00:00:00Z',
+ updatedAt: '2026-01-01T00:00:00Z',
+ })),
+ });
+ await openSharePopover();
+
+ expect(await screen.findByRole('button', { name: 'Session sharing' })).toHaveTextContent('Everyone within acme');
expect((screen.getByLabelText('Share URL') as HTMLInputElement).value).toContain('/sessions/share/session-1');
fireEvent.click(screen.getByRole('button', { name: 'Copy' }));
@@ -100,6 +117,29 @@ describe('ShareSessionDialog', () => {
expect(screen.getByRole('button', { name: 'Copied' })).toBeInTheDocument();
});
+ it('shows the share URL after switching to tenant access and hides it again for Only you', async () => {
+ const { updateSession } = renderDialog();
+ await openSharePopover();
+
+ expect(screen.queryByLabelText('Share URL')).not.toBeInTheDocument();
+
+ fireEvent.click(await screen.findByRole('button', { name: 'Session sharing' }));
+ fireEvent.click(await screen.findByRole('option', { name: 'Everyone within acme' }));
+
+ await waitFor(() => {
+ expect(updateSession).toHaveBeenCalledWith({ sessionId: 'session-1', shared: true });
+ });
+ expect(screen.getByLabelText('Share URL')).toBeInTheDocument();
+
+ fireEvent.click(screen.getByRole('button', { name: 'Session sharing' }));
+ fireEvent.click(await screen.findByRole('option', { name: 'Only you' }));
+
+ await waitFor(() => {
+ expect(updateSession).toHaveBeenCalledWith({ sessionId: 'session-1', shared: false });
+ });
+ expect(screen.queryByLabelText('Share URL')).not.toBeInTheDocument();
+ });
+
it('closes permission options on outside click without PATCHing', async () => {
const { updateSession } = renderDialog();
await openSharePopover();