@agent-native/core 0.151.1 → 0.152.0
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/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/analytics/actions/bigquery-query.ts +21 -0
- package/corpus/templates/analytics/app/components/ConnectionTestStatus.tsx +65 -0
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +3 -3
- package/corpus/templates/analytics/app/pages/DataSources.tsx +15 -37
- package/corpus/templates/analytics/app/root.tsx +0 -1
- package/corpus/templates/analytics/changelog/2026-08-11-analytics-custom-blocks-keep-loading-with-legacy-bigquery-action.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-11-analytics-routes-company-knowledge-and-slack-context-questio.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/analytics/public/manifest.json +0 -1
- package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +5 -0
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +5 -0
- package/corpus/templates/assets/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/assets/app/root.tsx +0 -1
- package/corpus/templates/assets/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/assets/public/manifest.json +0 -1
- package/corpus/templates/brain/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/brain/app/root.tsx +0 -1
- package/corpus/templates/brain/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/brain/public/manifest.json +0 -1
- package/corpus/templates/calendar/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/calendar/app/components/calendar/GoogleConnectBanner.tsx +0 -53
- package/corpus/templates/calendar/app/i18n-data.ts +0 -80
- package/corpus/templates/calendar/app/root.tsx +0 -1
- package/corpus/templates/calendar/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-11-google-calendar-connection-buttons-now-open-the-sign-in-flow.md +6 -0
- package/corpus/templates/calendar/public/manifest.json +0 -1
- package/corpus/templates/calendar/server/plugins/auth.ts +0 -10
- package/corpus/templates/chat/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/chat/app/root.tsx +0 -1
- package/corpus/templates/chat/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/chat/public/manifest.json +0 -1
- package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/clips/app/components/player/playback-comment-overlay.tsx +1 -1
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +6 -0
- package/corpus/templates/clips/app/components/sharing/share-ui.tsx +20 -3
- package/corpus/templates/clips/app/i18n/en-US.ts +4 -4
- package/corpus/templates/clips/app/root.tsx +0 -1
- package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +1 -3
- package/corpus/templates/clips/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-11-clips-desktop-settings-are-now-easier-to-scan-with-a-wider-t.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-11-google-calendar-connections-from-meetings-now-open-directly.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-11-recording-viewers-can-comment-and-react.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-11-system-audio-recording-now-lives-inside-the-microphone-menu-.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-11-timestamped-comments-stay-on-the-video-for-three-seconds-wh.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +773 -1001
- package/corpus/templates/clips/desktop/src/components/MediaDeviceRow.tsx +15 -27
- package/corpus/templates/clips/desktop/src/styles.css +364 -5
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +1 -1
- package/corpus/templates/clips/public/manifest.json +0 -1
- package/corpus/templates/content/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/content/AGENTS.md +3 -0
- package/corpus/templates/content/actions/resolve-content-landing.ts +120 -0
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +9 -0
- package/corpus/templates/content/app/i18n-data.ts +58 -0
- package/corpus/templates/content/app/lib/content-landing.ts +22 -0
- package/corpus/templates/content/app/root.tsx +0 -1
- package/corpus/templates/content/app/routes/_app._index.tsx +36 -26
- package/corpus/templates/content/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/content/changelog/2026-08-11-content-opens-your-last-page-on-return-and-gives-new-users-a.md +6 -0
- package/corpus/templates/content/docs/product/capabilities/content.workspace.session-restore.md +7 -1
- package/corpus/templates/content/parity/matrix.md +1 -0
- package/corpus/templates/content/parity/matrix.ts +22 -0
- package/corpus/templates/content/public/manifest.json +0 -1
- package/corpus/templates/content/shared/content-landing.ts +17 -0
- package/corpus/templates/crm/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/crm/app/root.tsx +0 -1
- package/corpus/templates/crm/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/crm/public/manifest.json +0 -1
- package/corpus/templates/design/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/design/app/i18n/en-US.ts +5 -0
- package/corpus/templates/design/app/root.tsx +0 -1
- package/corpus/templates/design/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/design/changelog/2026-08-11-design-sharing-now-identifies-viewers-who-can-add-review-com.md +6 -0
- package/corpus/templates/design/public/manifest.json +0 -1
- package/corpus/templates/dispatch/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/dispatch/AGENTS.md +9 -0
- package/corpus/templates/dispatch/actions/list-dispatch-usage-metrics.ts +5 -19
- package/corpus/templates/dispatch/actions/view-screen.ts +10 -3
- package/corpus/templates/dispatch/app/root.tsx +0 -1
- package/corpus/templates/dispatch/app/routes/settings.tsx +13 -1
- package/corpus/templates/dispatch/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-08-11-clicking-the-dispatch-logo-returns-to-the-overview-page.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-08-11-dispatch-no-longer-links-to-itself-from-the-app-switcher.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-08-11-dispatch-settings-now-link-directly-to-admin.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-08-11-dispatch-shows-usage-trends-recent-prompts-and-an-agent-revi.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-08-11-human-friendly-app-names.md +6 -0
- package/corpus/templates/dispatch/public/manifest.json +0 -1
- package/corpus/templates/dispatch/server/lib/identity-sso.ts +432 -158
- package/corpus/templates/dispatch/server/plugins/identity-sso.ts +204 -123
- package/corpus/templates/dispatch/server/plugins/setup-dispatch.ts +1 -0
- package/corpus/templates/factory/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/factory/app/root.tsx +0 -1
- package/corpus/templates/factory/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/factory/public/manifest.json +0 -1
- package/corpus/templates/forms/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/forms/app/root.tsx +0 -1
- package/corpus/templates/forms/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/forms/public/manifest.json +0 -1
- package/corpus/templates/macros/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/mail/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/mail/app/root.tsx +0 -1
- package/corpus/templates/mail/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/mail/changelog/2026-08-11-google-sign-in-now-opens-the-gmail-connection-flow-directly.md +6 -0
- package/corpus/templates/mail/public/manifest.json +0 -1
- package/corpus/templates/mail/server/plugins/auth.ts +0 -10
- package/corpus/templates/plan/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/plan/app/i18n/en-US.ts +2 -0
- package/corpus/templates/plan/app/pages/PlansPage.tsx +6 -0
- package/corpus/templates/plan/app/root.tsx +0 -1
- package/corpus/templates/plan/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/plan/changelog/2026-08-11-plan-sharing-now-identifies-viewers-who-can-add-comments.md +6 -0
- package/corpus/templates/plan/public/manifest.json +0 -1
- package/corpus/templates/slides/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +13 -0
- package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +6 -0
- package/corpus/templates/slides/app/i18n/en-US.ts +2 -0
- package/corpus/templates/slides/app/root.tsx +0 -1
- package/corpus/templates/slides/changelog/2026-08-10-asking-the-agent-for-several-slide-animations-at-once-now-ke.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-11-share-dialog-uses-commenter-terminology.md +6 -0
- package/corpus/templates/slides/public/manifest.json +0 -1
- package/corpus/templates/tasks/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/tasks/app/root.tsx +0 -1
- package/corpus/templates/tasks/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/tasks/public/manifest.json +0 -1
- package/dist/agent/production-agent.js +1 -22
- package/dist/agent/run-manager.d.ts +7 -0
- package/dist/agent/run-manager.js +46 -3
- package/dist/agent/tool-approval-migrations.d.ts +40 -0
- package/dist/agent/tool-approval-migrations.js +51 -0
- package/dist/agent/tool-approval-store.js +5 -20
- package/dist/cli/templates-meta.js +2 -2
- package/dist/client/AgentPanel.js +10 -1
- package/dist/client/AssistantChat.d.ts +3 -0
- package/dist/client/AssistantChat.js +148 -140
- package/dist/client/agent-page/AgentTabsPage.js +2 -2
- package/dist/client/chat/attachment-adapters.js +8 -2
- package/dist/client/chat/tool-call-display.d.ts +1 -0
- package/dist/client/chat/tool-call-display.js +3 -1
- package/dist/client/chat-first.js +11 -5
- package/dist/client/hooks/index.d.ts +1 -1
- package/dist/client/hooks/index.js +1 -1
- package/dist/client/org/OrgSwitcher.d.ts +3 -1
- package/dist/client/org/OrgSwitcher.js +22 -16
- package/dist/client/org/WorkspaceNotice.js +3 -1
- package/dist/client/resources/index.d.ts +1 -1
- package/dist/client/resources/index.js +1 -1
- package/dist/client/resources/use-mcp-servers.d.ts +1 -0
- package/dist/client/resources/use-mcp-servers.js +14 -0
- package/dist/client/settings/AccountSettingsCard.js +8 -4
- package/dist/client/settings/SettingsPanel.js +46 -13
- package/dist/client/settings/SettingsTabsPage.js +8 -3
- package/dist/client/sharing/ShareButton.d.ts +7 -1
- package/dist/client/sharing/ShareButton.js +14 -7
- package/dist/client/sharing/ShareDialog.js +5 -1
- package/dist/client/sharing/useShareButtonController.d.ts +4 -0
- package/dist/client/sharing/useShareButtonController.js +15 -0
- package/dist/client/sharing/useShareDialogController.d.ts +7 -0
- package/dist/client/sharing/useShareDialogController.js +14 -0
- package/dist/client/sse-event-processor.js +37 -0
- package/dist/client/use-session.d.ts +2 -0
- package/dist/client/use-session.js +69 -5
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/deploy/build.js +1 -1
- package/dist/file-upload/pre-upload-attachments.d.ts +3 -4
- package/dist/file-upload/pre-upload-attachments.js +65 -17
- package/dist/ingestion/index.d.ts +1 -0
- package/dist/ingestion/index.js +1 -0
- package/dist/ingestion/office.d.ts +3 -3
- package/dist/ingestion/office.js +24 -2
- package/dist/ingestion/spreadsheet.d.ts +41 -0
- package/dist/ingestion/spreadsheet.js +172 -0
- package/dist/integrations/adapters/slack.js +7 -3
- package/dist/localization/default-messages.d.ts +3 -0
- package/dist/localization/default-messages.js +3 -0
- package/dist/mcp/embed-app.js +20 -9
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/notifications/routes.d.ts +6 -6
- package/dist/oauth-tokens/migrations.d.ts +8 -0
- package/dist/oauth-tokens/migrations.js +36 -0
- package/dist/observability/routes.d.ts +5 -5
- package/dist/org/workspace-url.d.ts +8 -0
- package/dist/org/workspace-url.js +26 -2
- package/dist/progress/routes.d.ts +1 -1
- package/dist/secrets/routes.d.ts +3 -3
- package/dist/server/agent-chat-plugin.js +16 -8
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/auth.d.ts +0 -11
- package/dist/server/auth.js +37 -20
- package/dist/server/better-auth-migrations.js +23 -0
- package/dist/server/email-template.d.ts +5 -0
- package/dist/server/email-template.js +9 -0
- package/dist/server/embed-route.js +17 -5
- package/dist/server/identity-sso-store.d.ts +40 -66
- package/dist/server/identity-sso-store.js +187 -150
- package/dist/server/identity-sso.d.ts +17 -73
- package/dist/server/identity-sso.js +294 -297
- package/dist/server/onboarding-html.d.ts +0 -12
- package/dist/server/onboarding-html.js +46 -269
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/release-migrations.js +8 -0
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/shared/index.d.ts +1 -1
- package/dist/shared/index.js +1 -1
- package/dist/shared/workspace-app-id.d.ts +2 -0
- package/dist/shared/workspace-app-id.js +10 -0
- package/dist/sharing/actions/share-resource.d.ts +1 -0
- package/dist/sharing/actions/share-resource.js +20 -5
- package/dist/templates/chat/.agents/skills/sharing/SKILL.md +1 -1
- package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/dist/templates/chat/app/root.tsx +0 -1
- package/dist/templates/chat/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/dist/templates/chat/public/manifest.json +0 -1
- package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/dist/templates/default/app/root.tsx +0 -1
- package/dist/templates/default/public/manifest.json +0 -1
- package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +22 -11
- package/dist/templates/workspace-core/.agents/skills/sharing/SKILL.md +1 -1
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/docs/content/cross-app-sso.mdx +85 -27
- package/docs/content/template-mail.mdx +0 -6
- package/package.json +4 -3
- package/src/templates/chat/.agents/skills/sharing/SKILL.md +1 -1
- package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/src/templates/chat/app/root.tsx +0 -1
- package/src/templates/chat/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/src/templates/chat/public/manifest.json +0 -1
- package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/src/templates/default/app/root.tsx +0 -1
- package/src/templates/default/public/manifest.json +0 -1
- package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +22 -11
- package/src/templates/workspace-core/.agents/skills/sharing/SKILL.md +1 -1
- package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/calendar/changelog/2026-06-23-added-a-heads-up-explaining-google-s-app-not-verified-screen.md +0 -6
- package/corpus/templates/clips/app/components/meetings/google-oauth-identity-notice.tsx +0 -51
- package/corpus/templates/clips/changelog/2026-07-30-google-calendar-warning.md +0 -6
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Owns: image/document/text attachment adapters and attachment serialization helpers.
|
|
2
2
|
import { CHAT_DOCUMENT_ATTACHMENT_ACCEPT, IMAGE_ATTACHMENT_ACCEPT, } from "@agent-native/toolkit/composer/attachment-accept";
|
|
3
|
-
// Maximum
|
|
3
|
+
// Maximum document size (4 MB). Larger files would bloat the JSON POST
|
|
4
4
|
// body past Vercel's ~4.5 MB limit after base64 encoding (+33% overhead).
|
|
5
5
|
export const MAX_PDF_BYTES = 4 * 1024 * 1024;
|
|
6
6
|
// Anthropic / OpenAI vision inputs choke on multi-megabyte images, and
|
|
@@ -28,6 +28,12 @@ export function inferDocumentContentType(file) {
|
|
|
28
28
|
return file.type;
|
|
29
29
|
if (file.name.toLowerCase().endsWith(".pdf"))
|
|
30
30
|
return "application/pdf";
|
|
31
|
+
if (file.name.toLowerCase().endsWith(".xlsx")) {
|
|
32
|
+
return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
|
33
|
+
}
|
|
34
|
+
if (file.name.toLowerCase().endsWith(".xls")) {
|
|
35
|
+
return "application/vnd.ms-excel";
|
|
36
|
+
}
|
|
31
37
|
if (file.name.toLowerCase().endsWith(".svg"))
|
|
32
38
|
return "image/svg+xml";
|
|
33
39
|
return "application/octet-stream";
|
|
@@ -43,7 +49,7 @@ export function getFileDataURL(file) {
|
|
|
43
49
|
function formatOversizedDocumentError(name, size) {
|
|
44
50
|
const mb = (size / 1024 / 1024).toFixed(1);
|
|
45
51
|
const maxMb = (MAX_PDF_BYTES / 1024 / 1024).toFixed(0);
|
|
46
|
-
return `"${name}" is ${mb} MB
|
|
52
|
+
return `"${name}" is ${mb} MB - documents are capped at ${maxMb} MB to stay within message limits. Please reduce the file size or split it into smaller parts.`;
|
|
47
53
|
}
|
|
48
54
|
function loadImage(url) {
|
|
49
55
|
return new Promise((resolve, reject) => {
|
|
@@ -8,6 +8,7 @@ export declare const ChatRunningContext: React.Context<boolean>;
|
|
|
8
8
|
export declare const ChatRunningRunIdContext: React.Context<string | null>;
|
|
9
9
|
export declare const ChatRunningTurnIdContext: React.Context<string | null>;
|
|
10
10
|
export declare const ChatRunDurationContext: React.Context<number | null>;
|
|
11
|
+
export declare const SuppressInlineOpenAppContext: React.Context<boolean>;
|
|
11
12
|
export declare const ASSISTANT_VISIBLE_TOOL_CALL_LIMIT = 3;
|
|
12
13
|
/**
|
|
13
14
|
* Keeps the tool-call stack layout-transparent. Tool-entry motion is disabled
|
|
@@ -22,6 +22,7 @@ export const ChatRunningContext = React.createContext(false);
|
|
|
22
22
|
export const ChatRunningRunIdContext = React.createContext(null);
|
|
23
23
|
export const ChatRunningTurnIdContext = React.createContext(null);
|
|
24
24
|
export const ChatRunDurationContext = React.createContext(null);
|
|
25
|
+
export const SuppressInlineOpenAppContext = React.createContext(false);
|
|
25
26
|
export const ASSISTANT_VISIBLE_TOOL_CALL_LIMIT = 3;
|
|
26
27
|
/**
|
|
27
28
|
* Keeps the tool-call stack layout-transparent. Tool-entry motion is disabled
|
|
@@ -291,6 +292,7 @@ export function ToolCallDisplay({ toolName, toolCallId, argsText, args, result,
|
|
|
291
292
|
return wrapToolDisplay(_jsx(ToolCallDisplayGeneric, { toolName: toolName, toolCallId: toolCallId, argsText: argsText, args: args, result: result, mcpApp: mcpApp, chatUI: chatUI, isRunning: isRunning, outcome: outcome, isActiveTail: showActiveTail, structuredMeta: structuredMeta, approval: approval, repeatCount: repeatCount }));
|
|
292
293
|
}
|
|
293
294
|
function ToolCallDisplayGeneric({ toolName, toolCallId, argsText, args, result, mcpApp, chatUI, isRunning, outcome, isActiveTail, structuredMeta, approval, repeatCount, }) {
|
|
295
|
+
const suppressInlineOpenApp = React.useContext(SuppressInlineOpenAppContext);
|
|
294
296
|
const isRawCallAgent = toolName === "call-agent";
|
|
295
297
|
const isAgentCall = toolName.startsWith("agent:") || isRawCallAgent;
|
|
296
298
|
const [expanded, setExpanded] = useState(isAgentCall);
|
|
@@ -405,7 +407,7 @@ function ToolCallDisplayGeneric({ toolName, toolCallId, argsText, args, result,
|
|
|
405
407
|
? structuredMeta.agentDurationMs
|
|
406
408
|
: agentActivity?.durationMs }));
|
|
407
409
|
}
|
|
408
|
-
return (_jsxs("div", { className: "group/tool my-0.5 w-full overflow-hidden", children: [mcpApp && _jsx(McpAppRenderer, { app: mcpApp, className: "mb-1.5" }), _jsxs("button", { type: "button", onClick: () => canExpand && setExpanded(!isExpanded), "aria-expanded": canExpand ? isExpanded : undefined, className: cn("flex w-full items-center gap-1.5 rounded-md py-0.5 text-left text-[13px] text-muted-foreground transition-colors", canExpand && "hover:text-foreground", isRunning && "text-muted-foreground"), children: [_jsx("span", { className: "relative flex size-4 shrink-0 items-center justify-center", children: isRunning ? (_jsx(IconLoader2, { className: "size-3.5 animate-spin" })) : isAgentError ? (_jsx(IconCircleX, { className: "size-3.5 text-destructive" })) : isUnknownOutcome ? (_jsx(IconAlertTriangle, { className: "size-3.5 text-muted-foreground" })) : (_jsxs(_Fragment, { children: [_jsx(ToolIcon, { className: cn("size-3.5 transition-opacity", canExpand && "group-hover/tool:opacity-0") }), canExpand && (_jsx(IconChevronRight, { className: cn("absolute size-3.5 opacity-0 transition-[opacity,transform] group-hover/tool:opacity-100", isExpanded && "rotate-90") }))] })) }), _jsx("span", { className: cn("min-w-0 truncate font-normal", isActiveTail && "agent-running-shimmer"), children: displayName }), repeatCount && repeatCount > 1 && (_jsxs("span", { className: "shrink-0 rounded border border-border/60 px-1.5 py-0.5 text-[10px] leading-none text-muted-foreground", title: `Repeated ${repeatCount} times`, children: [repeatCount, "x"] }))] }), _jsx(AnimatedCollapse, { open: isExpanded && !isAgentCall && (hasArgs || result !== undefined), children: _jsxs("div", { className: "mt-1 space-y-2 pl-5", children: [inputPayload && (_jsx(SimpleCodeViewer, { text: inputPayload.text, lang: inputPayload.lang })), resultPayload && (_jsx(ToolOutputPopover, { open: outputOpen, onOpenChange: setOutputOpen, title: outputTitle, payload: resultPayload, children: _jsx("button", { type: "button", "aria-label": `View ${toolName} output`, className: "inline-flex size-6 items-center justify-center rounded-md text-muted-foreground/70 transition-colors hover:bg-accent hover:text-foreground", children: _jsx(IconCode, { className: "size-3.5" }) }) }))] }) }), isUnknownOutcome && (_jsx("p", { role: "status", className: "ps-5 text-xs text-muted-foreground", children: "Interrupted before this finished reporting \u2014 it may or may not have completed. Check before retrying." })), approval && (_jsx(ApprovalAffordance, { toolName: toolName, toolCallId: toolCallId, approval: approval }))] }));
|
|
410
|
+
return (_jsxs("div", { className: "group/tool my-0.5 w-full overflow-hidden", children: [mcpApp && !(suppressInlineOpenApp && toolName === "open_app") && (_jsx(McpAppRenderer, { app: mcpApp, className: "mb-1.5" })), _jsxs("button", { type: "button", onClick: () => canExpand && setExpanded(!isExpanded), "aria-expanded": canExpand ? isExpanded : undefined, className: cn("flex w-full items-center gap-1.5 rounded-md py-0.5 text-left text-[13px] text-muted-foreground transition-colors", canExpand && "hover:text-foreground", isRunning && "text-muted-foreground"), children: [_jsx("span", { className: "relative flex size-4 shrink-0 items-center justify-center", children: isRunning ? (_jsx(IconLoader2, { className: "size-3.5 animate-spin" })) : isAgentError ? (_jsx(IconCircleX, { className: "size-3.5 text-destructive" })) : isUnknownOutcome ? (_jsx(IconAlertTriangle, { className: "size-3.5 text-muted-foreground" })) : (_jsxs(_Fragment, { children: [_jsx(ToolIcon, { className: cn("size-3.5 transition-opacity", canExpand && "group-hover/tool:opacity-0") }), canExpand && (_jsx(IconChevronRight, { className: cn("absolute size-3.5 opacity-0 transition-[opacity,transform] group-hover/tool:opacity-100", isExpanded && "rotate-90") }))] })) }), _jsx("span", { className: cn("min-w-0 truncate font-normal", isActiveTail && "agent-running-shimmer"), children: displayName }), repeatCount && repeatCount > 1 && (_jsxs("span", { className: "shrink-0 rounded border border-border/60 px-1.5 py-0.5 text-[10px] leading-none text-muted-foreground", title: `Repeated ${repeatCount} times`, children: [repeatCount, "x"] }))] }), _jsx(AnimatedCollapse, { open: isExpanded && !isAgentCall && (hasArgs || result !== undefined), children: _jsxs("div", { className: "mt-1 space-y-2 pl-5", children: [inputPayload && (_jsx(SimpleCodeViewer, { text: inputPayload.text, lang: inputPayload.lang })), resultPayload && (_jsx(ToolOutputPopover, { open: outputOpen, onOpenChange: setOutputOpen, title: outputTitle, payload: resultPayload, children: _jsx("button", { type: "button", "aria-label": `View ${toolName} output`, className: "inline-flex size-6 items-center justify-center rounded-md text-muted-foreground/70 transition-colors hover:bg-accent hover:text-foreground", children: _jsx(IconCode, { className: "size-3.5" }) }) }))] }) }), isUnknownOutcome && (_jsx("p", { role: "status", className: "ps-5 text-xs text-muted-foreground", children: "Interrupted before this finished reporting \u2014 it may or may not have completed. Check before retrying." })), approval && (_jsx(ApprovalAffordance, { toolName: toolName, toolCallId: toolCallId, approval: approval }))] }));
|
|
409
411
|
}
|
|
410
412
|
function AgentCallCell({ agentName, activity, progress, responseText, isRunning, isError, durationMs, }) {
|
|
411
413
|
const t = useT();
|
|
@@ -312,14 +312,20 @@ export function orderChatFirstAppIds(appIds, layout) {
|
|
|
312
312
|
...preferredDefaults,
|
|
313
313
|
...appIds.filter((id) => !preferredDefaultSet.has(id)),
|
|
314
314
|
];
|
|
315
|
+
const manualOrderedIds = layout.orderedIds.filter((id) => available.has(id));
|
|
316
|
+
const hasManualOrder = manualOrderedIds.length > 0;
|
|
315
317
|
const ordered = [
|
|
316
|
-
...
|
|
318
|
+
...manualOrderedIds,
|
|
317
319
|
...fallbackOrder.filter((id) => !layout.orderedIds.includes(id)),
|
|
318
320
|
];
|
|
319
|
-
const
|
|
320
|
-
|
|
321
|
-
//
|
|
322
|
-
//
|
|
321
|
+
const pinnedIds = layout.pinnedIds.filter((id) => available.has(id));
|
|
322
|
+
const pinned = new Set(pinnedIds);
|
|
323
|
+
// A live `orderedIds` value is the single source of positional truth. Pinning
|
|
324
|
+
// changes presentation only; it must not rewrite the user's drag order or
|
|
325
|
+
// make an unpinned app jump to the fallback order.
|
|
326
|
+
if (!hasManualOrder) {
|
|
327
|
+
return [...pinnedIds, ...fallbackOrder.filter((id) => !pinned.has(id))];
|
|
328
|
+
}
|
|
323
329
|
return [
|
|
324
330
|
...ordered.filter((id) => pinned.has(id)),
|
|
325
331
|
...ordered.filter((id) => !pinned.has(id)),
|
|
@@ -4,7 +4,7 @@ export { useDbSync, useFileWatcher, useScreenRefreshKey, } from "../use-db-sync.
|
|
|
4
4
|
export { useChangeVersion, useChangeVersions, getChangeVersion, bumpChangeVersion, } from "../use-change-version.js";
|
|
5
5
|
export { useDemoModeStatus, type DemoModeStatus, } from "../use-demo-mode-status.js";
|
|
6
6
|
export { useReconciledState } from "../use-external-value.js";
|
|
7
|
-
export { useSession, type AuthSession } from "../use-session.js";
|
|
7
|
+
export { notifySessionInvalidated, useSession, type AuthSession, } from "../use-session.js";
|
|
8
8
|
export { ACTION_KEEPALIVE_BODY_BUDGET_BYTES, callAction, tryCallActionKeepalive, useActionQuery, useActionMutation, type ActionRegistry, type ClientActionCallOptions, type ClientActionMethod, type KeepaliveActionCallRejectionReason, type KeepaliveActionCallResult, } from "../use-action.js";
|
|
9
9
|
export { createAgentNativeQueryClient } from "../create-query-client.js";
|
|
10
10
|
export { AppProviders, type AppProvidersProps } from "../app-providers.js";
|
|
@@ -4,7 +4,7 @@ export { useDbSync, useFileWatcher, useScreenRefreshKey, } from "../use-db-sync.
|
|
|
4
4
|
export { useChangeVersion, useChangeVersions, getChangeVersion, bumpChangeVersion, } from "../use-change-version.js";
|
|
5
5
|
export { useDemoModeStatus, } from "../use-demo-mode-status.js";
|
|
6
6
|
export { useReconciledState } from "../use-external-value.js";
|
|
7
|
-
export { useSession } from "../use-session.js";
|
|
7
|
+
export { notifySessionInvalidated, useSession, } from "../use-session.js";
|
|
8
8
|
export { ACTION_KEEPALIVE_BODY_BUDGET_BYTES, callAction, tryCallActionKeepalive, useActionQuery, useActionMutation, } from "../use-action.js";
|
|
9
9
|
export { createAgentNativeQueryClient } from "../create-query-client.js";
|
|
10
10
|
export { AppProviders } from "../app-providers.js";
|
|
@@ -27,6 +27,8 @@ export interface OrgSwitcherProps {
|
|
|
27
27
|
* Pass `null` for apps that do not mount the Agent page.
|
|
28
28
|
*/
|
|
29
29
|
agentPath?: string | null;
|
|
30
|
+
/** Omit the link to the app that currently owns this switcher. */
|
|
31
|
+
currentAppId?: string;
|
|
30
32
|
}
|
|
31
33
|
/**
|
|
32
34
|
* Compact org switcher button. Shows the active org (or "Personal" when the
|
|
@@ -34,4 +36,4 @@ export interface OrgSwitcherProps {
|
|
|
34
36
|
* invitations, inline forms to create a new org / invite a teammate, and a
|
|
35
37
|
* sign-out item. Renders nothing in dev / no-auth mode.
|
|
36
38
|
*/
|
|
37
|
-
export declare function OrgSwitcher({ className, hideWhenSingle, reserveSpace, compact, settingsPath, profilePath, agentPath, }: OrgSwitcherProps): import("react").JSX.Element | null;
|
|
39
|
+
export declare function OrgSwitcher({ className, hideWhenSingle, reserveSpace, compact, settingsPath, profilePath, agentPath, currentAppId, }: OrgSwitcherProps): import("react").JSX.Element | null;
|
|
@@ -8,7 +8,7 @@ import { shouldOfferWorkspace } from "../../org/workspace-url.js";
|
|
|
8
8
|
import { agentNativePath } from "../api-path.js";
|
|
9
9
|
import { useT } from "../i18n.js";
|
|
10
10
|
import { useDemoModeStatus } from "../use-demo-mode-status.js";
|
|
11
|
-
import { useSession } from "../use-session.js";
|
|
11
|
+
import { notifySessionInvalidated, useSession } from "../use-session.js";
|
|
12
12
|
import { useOrg, useSwitchOrg, useCreateOrg, useInviteMember, useAcceptInvitation, useJoinByDomain, } from "./hooks.js";
|
|
13
13
|
import { ORG_SWITCHER_MAX_APP_LINKS, useOrgSwitcherAppLinks, visibleOrgAppLinks, } from "./workspace-app-links.js";
|
|
14
14
|
function personalLabelFromEmail(email) {
|
|
@@ -76,23 +76,28 @@ function AppMenuLink({ app, onNavigate, }) {
|
|
|
76
76
|
(app.isDispatch ? "Workspace hub" : `${app.name} workspace`);
|
|
77
77
|
return (_jsxs("a", { href: app.href, onClick: onNavigate, className: "flex items-center gap-2 rounded-sm px-2.5 py-2 text-xs outline-none hover:bg-accent focus:bg-accent", children: [_jsx("span", { className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-md bg-muted text-muted-foreground", children: _jsx(Icon, { className: "h-3.5 w-3.5" }) }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block truncate font-medium text-foreground", children: app.name }), _jsx("span", { className: "block truncate text-[11px] text-muted-foreground", title: description, children: description })] }), _jsx(IconArrowUpRight, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" })] }));
|
|
78
78
|
}
|
|
79
|
-
function AppsSubmenu({ apps, isLoading, dispatchHref, dispatchAllAppsHref, onNavigate, }) {
|
|
80
|
-
const
|
|
79
|
+
function AppsSubmenu({ apps, isLoading, dispatchHref, dispatchAllAppsHref, currentAppId, onNavigate, }) {
|
|
80
|
+
const appsForMenu = currentAppId
|
|
81
|
+
? apps.filter((app) => app.id !== currentAppId)
|
|
82
|
+
: apps;
|
|
83
|
+
const { links, overflowCount } = visibleOrgAppLinks(appsForMenu);
|
|
81
84
|
const visibleDispatchApp = links.find((app) => app.isDispatch);
|
|
82
|
-
const dispatchApp =
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
85
|
+
const dispatchApp = currentAppId === "dispatch"
|
|
86
|
+
? null
|
|
87
|
+
: (visibleDispatchApp ??
|
|
88
|
+
{
|
|
89
|
+
id: "dispatch",
|
|
90
|
+
name: "Dispatch",
|
|
91
|
+
href: dispatchHref,
|
|
92
|
+
isDispatch: true,
|
|
93
|
+
status: "ready",
|
|
94
|
+
});
|
|
90
95
|
const visibleNonDispatch = links
|
|
91
96
|
.filter((app) => !app.isDispatch)
|
|
92
|
-
.slice(0,
|
|
97
|
+
.slice(0, dispatchApp ? undefined : ORG_SWITCHER_MAX_APP_LINKS);
|
|
93
98
|
const shownCount = (dispatchApp ? 1 : 0) + visibleNonDispatch.length;
|
|
94
|
-
const remainingCount = Math.max(overflowCount,
|
|
95
|
-
return (_jsxs(PopoverPrimitive.Root, { children: [_jsx(PopoverPrimitive.Trigger, { asChild: true, children: _jsxs("button", { type: "button", className: `${ITEM_CLASS} cursor-pointer`, children: [_jsx(IconApps, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }), _jsx("span", { className: "flex-1 text-start", children: "Apps" }), _jsx("span", { className: "text-[11px] text-muted-foreground", children: isLoading ? (_jsx(IconLoader2, { className: "h-3 w-3 animate-spin" })) : (
|
|
99
|
+
const remainingCount = Math.max(overflowCount, appsForMenu.length - shownCount);
|
|
100
|
+
return (_jsxs(PopoverPrimitive.Root, { children: [_jsx(PopoverPrimitive.Trigger, { asChild: true, children: _jsxs("button", { type: "button", className: `${ITEM_CLASS} cursor-pointer`, children: [_jsx(IconApps, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }), _jsx("span", { className: "flex-1 text-start", children: "Apps" }), _jsx("span", { className: "text-[11px] text-muted-foreground", children: isLoading ? (_jsx(IconLoader2, { className: "h-3 w-3 animate-spin" })) : (appsForMenu.length) }), _jsx(IconChevronRight, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground rtl:-scale-x-100" })] }) }), _jsx(PopoverPrimitive.Portal, { children: _jsxs(PopoverPrimitive.Content, { side: "right", align: "start", sideOffset: 8, collisionPadding: 12, className: APP_SUBMENU_CONTENT_CLASS, children: [dispatchApp && (_jsx(AppMenuLink, { app: dispatchApp, onNavigate: onNavigate })), dispatchApp && visibleNonDispatch.length > 0 && (_jsx("div", { className: "my-1 h-px bg-border" })), visibleNonDispatch.map((app) => (_jsx(AppMenuLink, { app: app, onNavigate: onNavigate }, app.id))), remainingCount > 0 && (_jsxs(_Fragment, { children: [_jsx("div", { className: "my-1 h-px bg-border" }), _jsxs("a", { href: dispatchAllAppsHref, onClick: onNavigate, className: "flex items-center gap-2 rounded-sm px-2.5 py-1.5 text-xs text-foreground outline-none hover:bg-accent focus:bg-accent", children: [_jsx(IconApps, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }), _jsx("span", { className: "flex-1", children: `View ${remainingCount} more in Dispatch` }), _jsx(IconArrowUpRight, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" })] })] }))] }) })] }));
|
|
96
101
|
}
|
|
97
102
|
function ReservedOrgSwitcherSpace({ className }) {
|
|
98
103
|
return _jsx("div", { "aria-hidden": "true", className: `h-8 ${className ?? ""}` });
|
|
@@ -106,7 +111,7 @@ function OrgSwitcherLoadingPlaceholder({ className }) {
|
|
|
106
111
|
* invitations, inline forms to create a new org / invite a teammate, and a
|
|
107
112
|
* sign-out item. Renders nothing in dev / no-auth mode.
|
|
108
113
|
*/
|
|
109
|
-
export function OrgSwitcher({ className, hideWhenSingle, reserveSpace, compact, settingsPath = DEFAULT_ORGANIZATION_SETTINGS_PATH, profilePath = DEFAULT_PROFILE_PATH, agentPath = DEFAULT_AGENT_PATH, }) {
|
|
114
|
+
export function OrgSwitcher({ className, hideWhenSingle, reserveSpace, compact, settingsPath = DEFAULT_ORGANIZATION_SETTINGS_PATH, profilePath = DEFAULT_PROFILE_PATH, agentPath = DEFAULT_AGENT_PATH, currentAppId, }) {
|
|
110
115
|
const { data: org, isLoading } = useOrg();
|
|
111
116
|
const { session } = useSession();
|
|
112
117
|
const { enabled: demoModeEnabled } = useDemoModeStatus();
|
|
@@ -145,6 +150,7 @@ export function OrgSwitcher({ className, hideWhenSingle, reserveSpace, compact,
|
|
|
145
150
|
catch {
|
|
146
151
|
/* fall through to reload — server may already have cleared the cookie */
|
|
147
152
|
}
|
|
153
|
+
notifySessionInvalidated();
|
|
148
154
|
window.location.reload();
|
|
149
155
|
};
|
|
150
156
|
if (!org) {
|
|
@@ -216,7 +222,7 @@ export function OrgSwitcher({ className, hideWhenSingle, reserveSpace, compact,
|
|
|
216
222
|
setJoiningOrgId(null);
|
|
217
223
|
}
|
|
218
224
|
}, disabled: joinByDomain.isPending, className: "rounded px-1.5 py-0.5 text-[11px] font-medium text-primary hover:bg-primary/10 disabled:opacity-50 cursor-pointer", children: isJoining ? (_jsx(IconLoader2, { className: "h-3 w-3 animate-spin" })) : ("Join") })] }, match.orgId));
|
|
219
|
-
})] })), _jsx("div", { className: "my-1 h-px bg-border" }), _jsx(AppsSubmenu, { apps: appLinks.apps, isLoading: appLinks.isLoading, dispatchHref: appLinks.dispatchHref, dispatchAllAppsHref: appLinks.dispatchAllAppsHref, onNavigate: () => setOpen(false) }), profilePath && (_jsxs("button", { type: "button", onClick: () => {
|
|
225
|
+
})] })), _jsx("div", { className: "my-1 h-px bg-border" }), _jsx(AppsSubmenu, { apps: appLinks.apps, isLoading: appLinks.isLoading, dispatchHref: appLinks.dispatchHref, dispatchAllAppsHref: appLinks.dispatchAllAppsHref, currentAppId: currentAppId, onNavigate: () => setOpen(false) }), profilePath && (_jsxs("button", { type: "button", onClick: () => {
|
|
220
226
|
setOpen(false);
|
|
221
227
|
navigate(profilePath);
|
|
222
228
|
}, className: `${ITEM_CLASS} cursor-pointer`, children: [_jsx(IconUserCircle, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }), _jsx("span", { className: "flex-1 text-start", children: t("settings.profileMenuItem") })] })), agentPath && (_jsxs("button", { type: "button", onClick: () => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { IconExternalLink } from "@tabler/icons-react";
|
|
3
3
|
import { useState } from "react";
|
|
4
|
-
import { shouldOfferWorkspace } from "../../org/workspace-url.js";
|
|
4
|
+
import { isLocalDevelopmentOrigin, shouldOfferWorkspace, } from "../../org/workspace-url.js";
|
|
5
5
|
import { useOrg } from "./hooks.js";
|
|
6
6
|
const DISMISS_KEY_PREFIX = "agent-native:workspace-notice-dismissed:";
|
|
7
7
|
function dismissKey(workspaceUrl) {
|
|
@@ -38,6 +38,8 @@ export function WorkspaceNotice({ className }) {
|
|
|
38
38
|
const workspaceUrl = org?.workspaceUrl ?? null;
|
|
39
39
|
if (typeof window === "undefined")
|
|
40
40
|
return null;
|
|
41
|
+
if (isLocalDevelopmentOrigin(window.location.href))
|
|
42
|
+
return null;
|
|
41
43
|
if (!workspaceUrl || dismissedNow || readDismissed(workspaceUrl))
|
|
42
44
|
return null;
|
|
43
45
|
if (!shouldOfferWorkspace(window.location.href, workspaceUrl))
|
|
@@ -7,4 +7,4 @@ export * from "./use-builtin-capabilities.js";
|
|
|
7
7
|
export { DEFAULT_MCP_INTEGRATIONS, filterMcpIntegrations, findMcpIntegrationForText, getDefaultMcpIntegrations, isCustomMcpIntegrationEnabled, isMcpIntegrationCatalogAvailable, mergeDefaultMcpIntegrations, type DefaultMcpIntegration, } from "./mcp-integration-catalog.js";
|
|
8
8
|
export { McpIntegrationDialog, type McpIntegrationDialogProps, } from "./McpIntegrationDialog.js";
|
|
9
9
|
export { McpConnectionSuggestion, type McpConnectionSuggestionProps, type McpConnectionSuggestionVariant, } from "./McpConnectionSuggestion.js";
|
|
10
|
-
export { McpServersApiProvider, useMcpServersApi, useMcpServers, useCreateMcpServer, useDeleteMcpServer, useReconnectMcpServer, testMcpServerUrl, type CreateMcpServerArgs, type McpServer, type McpServerScope, type McpServersApi, type McpServersList, type ReconnectMcpServerArgs, type TestMcpUrlResult, } from "./use-mcp-servers.js";
|
|
10
|
+
export { McpServersApiProvider, useMcpServersApi, useMcpServers, useCreateMcpServer, useDeleteMcpServer, useReconnectMcpServer, testMcpServerUrl, formatMcpServersLoadError, type CreateMcpServerArgs, type McpServer, type McpServerScope, type McpServersApi, type McpServersList, type ReconnectMcpServerArgs, type TestMcpUrlResult, } from "./use-mcp-servers.js";
|
|
@@ -7,4 +7,4 @@ export * from "./use-builtin-capabilities.js";
|
|
|
7
7
|
export { DEFAULT_MCP_INTEGRATIONS, filterMcpIntegrations, findMcpIntegrationForText, getDefaultMcpIntegrations, isCustomMcpIntegrationEnabled, isMcpIntegrationCatalogAvailable, mergeDefaultMcpIntegrations, } from "./mcp-integration-catalog.js";
|
|
8
8
|
export { McpIntegrationDialog, } from "./McpIntegrationDialog.js";
|
|
9
9
|
export { McpConnectionSuggestion, } from "./McpConnectionSuggestion.js";
|
|
10
|
-
export { McpServersApiProvider, useMcpServersApi, useMcpServers, useCreateMcpServer, useDeleteMcpServer, useReconnectMcpServer, testMcpServerUrl, } from "./use-mcp-servers.js";
|
|
10
|
+
export { McpServersApiProvider, useMcpServersApi, useMcpServers, useCreateMcpServer, useDeleteMcpServer, useReconnectMcpServer, testMcpServerUrl, formatMcpServersLoadError, } from "./use-mcp-servers.js";
|
|
@@ -83,6 +83,7 @@ export interface TestMcpUrlResult {
|
|
|
83
83
|
}
|
|
84
84
|
export declare function getMcpUrlValidationError(rawUrl: string): string | null;
|
|
85
85
|
export declare function formatMcpServerError(error: unknown): string;
|
|
86
|
+
export declare function formatMcpServersLoadError(error: unknown): string;
|
|
86
87
|
export declare function testMcpServerUrl(url: string, headers?: Record<string, string>): Promise<TestMcpUrlResult>;
|
|
87
88
|
/**
|
|
88
89
|
* Virtual tree-node id used when a server is surfaced in the Workspace tree.
|
|
@@ -178,6 +178,20 @@ export function formatMcpServerError(error) {
|
|
|
178
178
|
}
|
|
179
179
|
return text.length > 240 ? `${text.slice(0, 237).trimEnd()}...` : text;
|
|
180
180
|
}
|
|
181
|
+
export function formatMcpServersLoadError(error) {
|
|
182
|
+
const raw = typeof error === "string"
|
|
183
|
+
? error
|
|
184
|
+
: error instanceof Error
|
|
185
|
+
? error.message
|
|
186
|
+
: String(error ?? "");
|
|
187
|
+
const text = raw.trim();
|
|
188
|
+
if (!text)
|
|
189
|
+
return "Could not load agent integrations.";
|
|
190
|
+
if (/401|unauthorized|signed-in workspace app|workspace app/i.test(text)) {
|
|
191
|
+
return "Sign in to a workspace app, then retry loading agent integrations.";
|
|
192
|
+
}
|
|
193
|
+
return text.length > 240 ? `${text.slice(0, 237).trimEnd()}...` : text;
|
|
194
|
+
}
|
|
181
195
|
export async function testMcpServerUrl(url, headers) {
|
|
182
196
|
const validationError = getMcpUrlValidationError(url);
|
|
183
197
|
if (validationError)
|
|
@@ -107,11 +107,17 @@ export function AccountSettingsForm({ compact = false, }) {
|
|
|
107
107
|
const [uploading, setUploading] = useState(false);
|
|
108
108
|
const [photoStatus, setPhotoStatus] = useState("idle");
|
|
109
109
|
const [name, setName] = useState("");
|
|
110
|
+
const nameEditedRef = useRef(false);
|
|
110
111
|
const displayName = profileQuery.data?.name ||
|
|
111
112
|
session?.name ||
|
|
112
113
|
email ||
|
|
113
114
|
t("settings.profileSignedOut");
|
|
114
115
|
useEffect(() => {
|
|
116
|
+
nameEditedRef.current = false;
|
|
117
|
+
}, [email]);
|
|
118
|
+
useEffect(() => {
|
|
119
|
+
if (nameEditedRef.current)
|
|
120
|
+
return;
|
|
115
121
|
const nextName = profileQuery.data?.name || session?.name;
|
|
116
122
|
if (nextName)
|
|
117
123
|
setName(nextName);
|
|
@@ -144,12 +150,10 @@ export function AccountSettingsForm({ compact = false, }) {
|
|
|
144
150
|
return (_jsxs(SettingsGroup, { id: "account", title: t("settings.profileTitle"), description: t("settings.profileDescription"), className: cn(compact && "[&>div:last-child>div>div]:py-3"), children: [_jsx(SettingsRow, { id: "profile", label: t("settings.profileTitle"), description: profileStatus, control: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Avatar, { name: displayName, src: avatarUrl, fallback: profileInitials(displayName), size: "default", className: "size-10 shrink-0 rounded-full border border-border bg-accent font-semibold text-muted-foreground" }), _jsx("input", { ref: fileInputRef, type: "file", accept: "image/*", className: "hidden", onChange: handleAvatarChange }), _jsx(ActionButton, { type: "button", intent: "neutral", emphasis: "outline", size: "compact", disabled: !email || uploading, leadingIcon: _jsx(IconCamera, { className: "size-3.5" }), onPress: () => fileInputRef.current?.click(), children: uploading
|
|
145
151
|
? t("settings.profileUploading")
|
|
146
152
|
: t("settings.profileChangePhoto") })] }) }), _jsx(SettingsRow, { id: "profile-name", label: t("settings.profileNameLabel"), description: updateProfile.isSuccess ? (_jsx("span", { className: "text-primary", children: t("settings.profileSaved") })) : updateProfile.error ? (_jsx("span", { className: "text-destructive", children: t("settings.profileSaveError") })) : (t("settings.profileNameDescription")), control: _jsxs("div", { className: "flex w-full items-center gap-2 sm:w-80", children: [_jsx(TextField, { id: "agent-native-profile-name", value: name, onChange: (value) => {
|
|
153
|
+
nameEditedRef.current = true;
|
|
147
154
|
updateProfile.reset();
|
|
148
155
|
setName(value);
|
|
149
|
-
}, placeholder: t("settings.profileNamePlaceholder"), disabled: !email ||
|
|
150
|
-
profileQuery.isLoading ||
|
|
151
|
-
updateProfile.isPending ||
|
|
152
|
-
!name.trim(), onPress: handleProfileSave, children: updateProfile.isPending
|
|
156
|
+
}, placeholder: t("settings.profileNamePlaceholder"), disabled: !email || updateProfile.isPending, "aria-label": t("settings.profileNameLabel"), className: "min-w-0 flex-1" }), _jsx(ActionButton, { type: "button", intent: "primary", emphasis: "solid", size: "compact", pending: updateProfile.isPending, disabled: !email || updateProfile.isPending || !name.trim(), onPress: handleProfileSave, children: updateProfile.isPending
|
|
153
157
|
? t("settings.profileSaving")
|
|
154
158
|
: t("settings.profileSave") })] }) }), _jsx(SettingsRow, { id: "timezone", label: t("settings.timezoneLabel", { defaultValue: "Timezone" }), description: t("settings.timezoneHint", {
|
|
155
159
|
defaultValue: "Used for timestamps and scheduled automations.",
|
|
@@ -8,7 +8,7 @@ import { PROVIDER_ENV_PLACEHOLDERS } from "../../agent/engine/provider-env-vars.
|
|
|
8
8
|
import { buildSettingsRoute } from "../../navigation/index.js";
|
|
9
9
|
import { saveAgentEngineProviderSettings, setAgentEngineProvider, } from "../agent-engine-key.js";
|
|
10
10
|
import { AgentWorkspaceContent } from "../agent-page/AgentWorkspaceContent.js";
|
|
11
|
-
import { getAgentProviderOption, providerIdForEngine, } from "../agent-provider-catalog.js";
|
|
11
|
+
import { AGENT_PROVIDER_CATALOG, getAgentProviderOption, providerIdForEngine, } from "../agent-provider-catalog.js";
|
|
12
12
|
import { agentNativePath } from "../api-path.js";
|
|
13
13
|
import { BuilderBMark } from "../builder-mark.js";
|
|
14
14
|
import { Popover, PopoverContent, PopoverTrigger, } from "../components/ui/popover.js";
|
|
@@ -208,8 +208,6 @@ function UseBuilderCard({ builderFlow, connectUrl, connected, orgName, envManage
|
|
|
208
208
|
? "Connect account"
|
|
209
209
|
: "Reconnect" })), credentialSource !== "env" ? _jsx(DisconnectBuilderButton, {}) : null] })) : null] }));
|
|
210
210
|
}
|
|
211
|
-
if (!connectUrl)
|
|
212
|
-
return null;
|
|
213
211
|
if (compact) {
|
|
214
212
|
return (_jsxs(Button, { type: "button", intent: "primary", emphasis: "solid", onClick: () => builderFlow.start({ trackingSource, trackingFlow }), disabled: builderFlow.connecting, className: "inline-flex shrink-0 items-center gap-1.5 rounded-md bg-primary px-3 py-1.5 text-sm font-medium text-primary-foreground hover:bg-primary/90 disabled:cursor-wait disabled:opacity-70", children: [builderFlow.connecting ? "Connecting…" : "Connect Builder.io", builderFlow.connecting ? (_jsx(IconLoader2, { size: 14, className: "animate-spin" })) : null] }));
|
|
215
213
|
}
|
|
@@ -278,6 +276,9 @@ function computeSourceBadge(args) {
|
|
|
278
276
|
if (settingsStatus?.source === "env") {
|
|
279
277
|
return `Connected via ${settingsStatus.envVar ?? args.envVar ?? "env"}`;
|
|
280
278
|
}
|
|
279
|
+
if (settingsStatus?.source === "app_secrets") {
|
|
280
|
+
return "Connected via saved key";
|
|
281
|
+
}
|
|
281
282
|
return "Connected via template (server-side)";
|
|
282
283
|
}
|
|
283
284
|
if (args.envConfigured)
|
|
@@ -373,7 +374,9 @@ function LLMSectionInner({ builderFlow, builderLoading, connectUrl, connected, o
|
|
|
373
374
|
setBaseUrlConfigured(Boolean(data?.openAiBaseUrlConfigured));
|
|
374
375
|
if (data?.configured &&
|
|
375
376
|
typeof data.engine === "string" &&
|
|
376
|
-
(data.source === "env" ||
|
|
377
|
+
(data.source === "env" ||
|
|
378
|
+
data.source === "settings" ||
|
|
379
|
+
data.source === "app_secrets")) {
|
|
377
380
|
setSettingsStatus({
|
|
378
381
|
engine: data.engine,
|
|
379
382
|
source: data.source,
|
|
@@ -407,15 +410,40 @@ function LLMSectionInner({ builderFlow, builderLoading, connectUrl, connected, o
|
|
|
407
410
|
.finally(() => setEnginesLoaded(true));
|
|
408
411
|
}, []);
|
|
409
412
|
const selectedEngineInfo = engines.find((e) => e.name === selectedEngine);
|
|
410
|
-
const
|
|
413
|
+
const selectedProvider = providerIdForEngine(selectedEngine) ?? "anthropic";
|
|
414
|
+
const selectedProviderOption = getAgentProviderOption(selectedProvider);
|
|
415
|
+
const envVar = selectedProviderOption.key;
|
|
411
416
|
const selectedEnginePackageInstalled = selectedEngineInfo?.packageInstalled !== false;
|
|
412
417
|
const envConfigured = envVar
|
|
413
418
|
? (envKeys.find((k) => k.key === envVar)?.configured ?? false)
|
|
414
419
|
: false;
|
|
415
|
-
const settingsConfigured = settingsStatus != null &&
|
|
420
|
+
const settingsConfigured = settingsStatus != null &&
|
|
421
|
+
(settingsStatus.engine === selectedEngine ||
|
|
422
|
+
(!!envVar && settingsStatus.envVar === envVar));
|
|
423
|
+
const configuredProviderIds = useMemo(() => {
|
|
424
|
+
const configured = new Set();
|
|
425
|
+
for (const option of AGENT_PROVIDER_CATALOG) {
|
|
426
|
+
if (option.key &&
|
|
427
|
+
envKeys.some((entry) => entry.key === option.key && entry.configured)) {
|
|
428
|
+
configured.add(option.id);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
if (settingsStatus) {
|
|
432
|
+
const statusProvider = providerIdForEngine(settingsStatus.engine);
|
|
433
|
+
if (statusProvider)
|
|
434
|
+
configured.add(statusProvider);
|
|
435
|
+
if (settingsStatus.envVar) {
|
|
436
|
+
const statusOption = AGENT_PROVIDER_CATALOG.find((option) => option.key === settingsStatus.envVar);
|
|
437
|
+
if (statusOption)
|
|
438
|
+
configured.add(statusOption.id);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
return configured;
|
|
442
|
+
}, [envKeys, settingsStatus]);
|
|
416
443
|
const builderConnected = connected || builderFlow.configured;
|
|
417
444
|
const anyKeyConfigured = builderConnected ||
|
|
418
|
-
(selectedEnginePackageInstalled &&
|
|
445
|
+
(selectedEnginePackageInstalled &&
|
|
446
|
+
(envConfigured || settingsConfigured || configuredProviderIds.size > 0));
|
|
419
447
|
const sourceBadge = computeSourceBadge({
|
|
420
448
|
settingsConfigured,
|
|
421
449
|
settingsStatus,
|
|
@@ -425,8 +453,6 @@ function LLMSectionInner({ builderFlow, builderLoading, connectUrl, connected, o
|
|
|
425
453
|
});
|
|
426
454
|
const manualSetupHint = "Select a provider.";
|
|
427
455
|
const engineChanged = selectedEngine !== currentEngine || selectedModel !== currentModel;
|
|
428
|
-
const selectedProvider = providerIdForEngine(selectedEngine) ?? "anthropic";
|
|
429
|
-
const selectedProviderOption = getAgentProviderOption(selectedProvider);
|
|
430
456
|
const isEndpointProvider = selectedProviderOption.supportsEndpoint === true;
|
|
431
457
|
const endpointChanged = isEndpointProvider && (!!baseUrl.trim() || clearBaseUrl);
|
|
432
458
|
const providerSettingsChanged = !!apiKey.trim() || endpointChanged;
|
|
@@ -553,7 +579,7 @@ function LLMSectionInner({ builderFlow, builderLoading, connectUrl, connected, o
|
|
|
553
579
|
? "Manage"
|
|
554
580
|
: t("agentPanel.addOwnKeys", {
|
|
555
581
|
defaultValue: "Custom keys",
|
|
556
|
-
}), children: _jsxs("div", { className: "space-y-2 mb-1", children: [_jsx(AgentProviderPicker, { value: selectedProvider, layout: isPage ? "page" : "compact", onChange: (provider) => {
|
|
582
|
+
}), children: _jsxs("div", { className: "space-y-2 mb-1", children: [_jsx(AgentProviderPicker, { value: selectedProvider, configuredProviders: configuredProviderIds, layout: isPage ? "page" : "compact", onChange: (provider) => {
|
|
557
583
|
const option = getAgentProviderOption(provider);
|
|
558
584
|
setSelectedEngine(option.engine);
|
|
559
585
|
setSelectedModel(option.defaultModel);
|
|
@@ -578,7 +604,10 @@ function LLMSectionInner({ builderFlow, builderLoading, connectUrl, connected, o
|
|
|
578
604
|
setClearBaseUrl(checked);
|
|
579
605
|
if (checked)
|
|
580
606
|
setBaseUrl("");
|
|
581
|
-
}, "aria-label": "Clear saved endpoint override", className: "shrink-0" }), "Clear saved endpoint override"] })), endpointChanged && (_jsx(Button, { type: "button", intent: "neutral", emphasis: "solid", onClick: handleSave, disabled: saving, className: "rounded bg-accent px-2.5 py-1 text-[10px] font-medium text-foreground hover:bg-accent/80 disabled:opacity-40", children: saving ? (_jsx(IconLoader2, { size: 10, className: "animate-spin" })) : saved ? (_jsx(IconCheck, { size: 10 })) : ("Save endpoint") }))] }))] })), envVar && envConfigured ? (_jsxs("div", { className: cn("flex items-center gap-1.5 text-primary", isPage ? "text-xs" : "text-[10px]"), children: [_jsx(IconCheck, { size: isPage ? 14 : 10 }),
|
|
607
|
+
}, "aria-label": "Clear saved endpoint override", className: "shrink-0" }), "Clear saved endpoint override"] })), endpointChanged && (_jsx(Button, { type: "button", intent: "neutral", emphasis: "solid", onClick: handleSave, disabled: saving, className: "rounded bg-accent px-2.5 py-1 text-[10px] font-medium text-foreground hover:bg-accent/80 disabled:opacity-40", children: saving ? (_jsx(IconLoader2, { size: 10, className: "animate-spin" })) : saved ? (_jsx(IconCheck, { size: 10 })) : ("Save endpoint") }))] }))] })), envVar && (envConfigured || settingsConfigured) ? (_jsxs("div", { className: cn("flex items-center gap-1.5 text-primary", isPage ? "text-xs" : "text-[10px]"), children: [_jsx(IconCheck, { size: isPage ? 14 : 10 }), settingsStatus?.source === "app_secrets" &&
|
|
608
|
+
settingsConfigured
|
|
609
|
+
? "Saved key configured"
|
|
610
|
+
: `${envVar} configured`] })) : envVar ? (_jsxs("div", { className: "flex gap-1.5", children: [_jsx("input", { type: "password", value: apiKey, onChange: (e) => setApiKey(e.target.value), onKeyDown: (e) => {
|
|
582
611
|
if (e.key === "Enter")
|
|
583
612
|
handleSave();
|
|
584
613
|
}, placeholder: PROVIDER_ENV_PLACEHOLDERS[envVar] ?? "...", className: cn(textInputClass(isPage), "flex-1"), style: isPage ? CONTROL_STYLE_PAGE : undefined }), _jsx(Button, { intent: "primary", emphasis: "solid", onClick: handleSave, disabled: !providerSettingsChanged || saving, className: pillButtonClass(isPage, "solid"), children: saving ? (_jsx(IconLoader2, { size: isPage ? 14 : 10, className: "animate-spin" })) : saved ? (_jsx(IconCheck, { size: isPage ? 14 : 10 })) : ("Save") })] })) : null, _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Button, { intent: "neutral", emphasis: "outline", onClick: handleTest, disabled: testing, className: pillButtonClass(isPage, "outline"), children: testing ? (_jsxs("span", { className: "flex items-center gap-1", children: [_jsx(IconLoader2, { size: isPage ? 14 : 10, className: "animate-spin" }), "Testing\u2026"] })) : ("Test") }), PROVIDER_DOCS[selectedEngine] ? (_jsxs("a", { href: PROVIDER_DOCS[selectedEngine], target: "_blank", rel: "noopener noreferrer", className: cn(pillButtonClass(isPage, "outline"), "no-underline"), children: ["Get an API key", _jsx(IconExternalLink, { size: isPage ? 14 : 10 })] })) : null, engineChanged && (_jsx(Button, { intent: "primary", emphasis: "solid", onClick: handleApply, className: pillButtonClass(isPage, "solid"), children: "Apply" })), settingsStatus != null && (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { intent: "danger", emphasis: "outline", onClick: handleDisconnect, className: cn(pillButtonClass(isPage, "outline"), "ms-auto text-muted-foreground hover:bg-destructive/10 hover:text-destructive hover:border-destructive/40"), children: "Disconnect" }) }), _jsx(TooltipContent, { children: "Clear the saved engine \u2014 the app will fall back to the default until you re-apply." })] }))] }), testResult && testResult.ok && (_jsxs("p", { className: cn("flex items-center gap-1 text-primary", isPage ? "text-xs" : "text-[10px]"), children: [_jsx(IconCheck, { size: isPage ? 14 : 10 }), "Test passed \u2014 ", testResult.latencyMs, "ms"] })), testResult && testResult.ok === false && (_jsxs("p", { className: cn("text-destructive", isPage ? "text-xs" : "text-[10px]"), children: ["Test failed: ", testResult.error] })), disconnectError && (_jsxs("p", { className: cn("text-destructive", isPage ? "text-xs" : "text-[10px]"), children: ["Disconnect failed: ", disconnectError] })), applyError && (_jsxs("p", { className: cn("text-destructive", isPage ? "text-xs" : "text-[10px]"), children: ["Apply failed: ", applyError] })), applyNote && (_jsx("p", { className: cn("text-muted-foreground", isPage ? "text-xs" : "text-[10px]"), children: "Changes take effect on next conversation" }))] }) })] })] })) }));
|
|
@@ -667,6 +696,8 @@ function AppModelDefaultsSectionInner({ grouped = false, open, onToggle, }) {
|
|
|
667
696
|
};
|
|
668
697
|
}, []);
|
|
669
698
|
useEffect(() => load(), [load]);
|
|
699
|
+
if (!loading && !settings)
|
|
700
|
+
return null;
|
|
670
701
|
const selectedEngineInfo = settings?.engines.find((engine) => engine.name === selectedEngine) ?? null;
|
|
671
702
|
const engineOptions = (settings?.engines ?? [])
|
|
672
703
|
.filter((engine) => engine.name === selectedEngine || engine.name !== "ai-sdk:anthropic")
|
|
@@ -793,7 +824,7 @@ function AppModelDefaultsSectionInner({ grouped = false, open, onToggle, }) {
|
|
|
793
824
|
}, onEnter: () => {
|
|
794
825
|
if (hasPendingChange)
|
|
795
826
|
void save();
|
|
796
|
-
} }), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx(Button, { type: "button", intent: "primary", emphasis: "solid", onClick: () => void save(), disabled: !hasPendingChange || saving, className: pillButtonClass(isPage, "solid"), children: saving ? (_jsx(IconLoader2, { size: isPage ? 14 : 10, className: "animate-spin" })) : saved ? (_jsx(IconCheck, { size: isPage ? 14 : 10 })) : ("Save") }), _jsx(Button, { type: "button", intent: "neutral", emphasis: "outline", onClick: reset, disabled: !settings.canUpdate || !hasAppDefault || saving, className: pillButtonClass(isPage, "outline"), children: "Reset" })] })] }), !settings.canUpdate && (_jsx("p", { className: cn("mt-2 text-muted-foreground", noteTextClass(isPage)), children: "Only organization owners and admins can change app model defaults." })), selectedEngineInfo?.packageInstalled === false ? (_jsx("p", { className: cn("mt-2 text-muted-foreground", noteTextClass(isPage)), children: "This app does not include the optional runtime packages for this provider." })) : selectedEngineInfo && !selectedEngineInfo.configured ? (_jsx("p", { className: cn("mt-2 text-muted-foreground", noteTextClass(isPage)), children: "Credentials for this provider were not detected; runtime will fall back if the model cannot be used." })) : null, error && (_jsx("p", { className: cn("mt-2 text-destructive", noteTextClass(isPage)), children: error }))] }) }))) :
|
|
827
|
+
} }), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx(Button, { type: "button", intent: "primary", emphasis: "solid", onClick: () => void save(), disabled: !hasPendingChange || saving, className: pillButtonClass(isPage, "solid"), children: saving ? (_jsx(IconLoader2, { size: isPage ? 14 : 10, className: "animate-spin" })) : saved ? (_jsx(IconCheck, { size: isPage ? 14 : 10 })) : ("Save") }), _jsx(Button, { type: "button", intent: "neutral", emphasis: "outline", onClick: reset, disabled: !settings.canUpdate || !hasAppDefault || saving, className: pillButtonClass(isPage, "outline"), children: "Reset" })] })] }), !settings.canUpdate && (_jsx("p", { className: cn("mt-2 text-muted-foreground", noteTextClass(isPage)), children: "Only organization owners and admins can change app model defaults." })), selectedEngineInfo?.packageInstalled === false ? (_jsx("p", { className: cn("mt-2 text-muted-foreground", noteTextClass(isPage)), children: "This app does not include the optional runtime packages for this provider." })) : selectedEngineInfo && !selectedEngineInfo.configured ? (_jsx("p", { className: cn("mt-2 text-muted-foreground", noteTextClass(isPage)), children: "Credentials for this provider were not detected; runtime will fall back if the model cannot be used." })) : null, error && (_jsx("p", { className: cn("mt-2 text-destructive", noteTextClass(isPage)), children: error }))] }) }))) : null }));
|
|
797
828
|
}
|
|
798
829
|
// ─── Email Section ──────────────────────────────────────────────────────────
|
|
799
830
|
function EmailSectionInner({ open, onToggle, }) {
|
|
@@ -920,6 +951,8 @@ function AgentLimitsSectionInner({ grouped = false, open, onToggle, }) {
|
|
|
920
951
|
window.addEventListener("agent-loop-settings:changed", handler);
|
|
921
952
|
return () => window.removeEventListener("agent-loop-settings:changed", handler);
|
|
922
953
|
}, []);
|
|
954
|
+
if (!loading && !settings)
|
|
955
|
+
return null;
|
|
923
956
|
const numericValue = Number(value);
|
|
924
957
|
const hasPendingChange = !!settings &&
|
|
925
958
|
settings.canUpdate &&
|
|
@@ -1004,7 +1037,7 @@ function AgentLimitsSectionInner({ grouped = false, open, onToggle, }) {
|
|
|
1004
1037
|
void save();
|
|
1005
1038
|
}, className: cn(textInputClass(isPage), "min-w-0 flex-1 disabled:opacity-60"), style: isPage ? CONTROL_STYLE_PAGE : undefined }), _jsx(Button, { type: "button", intent: "primary", emphasis: "solid", onClick: save, disabled: !hasPendingChange || saving, className: pillButtonClass(isPage, "solid"), children: saving ? (_jsx(IconLoader2, { size: isPage ? 14 : 10, className: "animate-spin" })) : saved ? (_jsx(IconCheck, { size: isPage ? 14 : 10 })) : ("Save") }), _jsx(Button, { type: "button", intent: "neutral", emphasis: "outline", onClick: reset, disabled: !settings.canUpdate ||
|
|
1006
1039
|
saving ||
|
|
1007
|
-
settings.maxIterations === settings.defaultMaxIterations, className: pillButtonClass(isPage, "outline"), children: "Reset" })] }), !settings.canUpdate && (_jsx("p", { className: cn("mt-2 text-muted-foreground", noteTextClass(isPage)), children: "Only organization owners and admins can change this limit." })), error && (_jsx("p", { className: cn("mt-2 text-destructive", noteTextClass(isPage)), children: error }))] }) }))) :
|
|
1040
|
+
settings.maxIterations === settings.defaultMaxIterations, className: pillButtonClass(isPage, "outline"), children: "Reset" })] }), !settings.canUpdate && (_jsx("p", { className: cn("mt-2 text-muted-foreground", noteTextClass(isPage)), children: "Only organization owners and admins can change this limit." })), error && (_jsx("p", { className: cn("mt-2 text-destructive", noteTextClass(isPage)), children: error }))] }) }))) : null }));
|
|
1008
1041
|
}
|
|
1009
1042
|
export function areExtensionSettingsEnabled(options = {}) {
|
|
1010
1043
|
return options.extensionTools === true;
|
|
@@ -29,9 +29,6 @@ function normalizeTabId(value) {
|
|
|
29
29
|
if (normalized === "workspace" || normalized === "workspace-settings") {
|
|
30
30
|
return "workspace";
|
|
31
31
|
}
|
|
32
|
-
if (normalized === "connections") {
|
|
33
|
-
return "integrations";
|
|
34
|
-
}
|
|
35
32
|
return normalized;
|
|
36
33
|
}
|
|
37
34
|
function resolveTabId(tabs, value) {
|
|
@@ -40,6 +37,14 @@ function resolveTabId(tabs, value) {
|
|
|
40
37
|
return null;
|
|
41
38
|
if (tabs.some((tab) => tab.id === normalized))
|
|
42
39
|
return normalized;
|
|
40
|
+
const alternateTabId = normalized === "connections"
|
|
41
|
+
? "integrations"
|
|
42
|
+
: normalized === "integrations"
|
|
43
|
+
? "connections"
|
|
44
|
+
: null;
|
|
45
|
+
if (alternateTabId && tabs.some((tab) => tab.id === alternateTabId)) {
|
|
46
|
+
return alternateTabId;
|
|
47
|
+
}
|
|
43
48
|
const nestedTab = tabs
|
|
44
49
|
.filter((tab) => normalized.startsWith(`${tab.id}:`) ||
|
|
45
50
|
tab.id.startsWith(`${normalized}:`))
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
|
-
import { type ShareButtonVisibility } from "./useShareButtonController.js";
|
|
2
|
+
import { type ShareButtonRole, type ShareButtonVisibility } from "./useShareButtonController.js";
|
|
3
3
|
export interface ShareButtonProps {
|
|
4
4
|
resourceType: string;
|
|
5
5
|
resourceId: string;
|
|
@@ -61,6 +61,11 @@ export interface ShareButtonProps {
|
|
|
61
61
|
label?: string;
|
|
62
62
|
description?: string;
|
|
63
63
|
}>>;
|
|
64
|
+
/** Optional template-specific labels and descriptions for share roles. */
|
|
65
|
+
roleCopy?: Partial<Record<Role, {
|
|
66
|
+
label?: string;
|
|
67
|
+
description?: string;
|
|
68
|
+
}>>;
|
|
64
69
|
/** Optional label for the explicit per-person access list. */
|
|
65
70
|
peopleAccessLabel?: ReactNode;
|
|
66
71
|
/** Optional label for the coarse visibility control. */
|
|
@@ -95,6 +100,7 @@ export interface ShareButtonProps {
|
|
|
95
100
|
popoverClassName?: string;
|
|
96
101
|
}
|
|
97
102
|
type Visibility = ShareButtonVisibility;
|
|
103
|
+
type Role = ShareButtonRole;
|
|
98
104
|
/**
|
|
99
105
|
* Framework share control. Renders a shadcn-outline-styled trigger that
|
|
100
106
|
* opens a Google-Docs-style popover anchored beneath it. Uses Tailwind
|