@agent-native/core 0.137.2 → 0.137.4

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.
Files changed (176) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/agent-native-toolkit/SKILL.md +33 -0
  3. package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +53 -1
  4. package/corpus/templates/analytics/actions/gong-calls.ts +37 -17
  5. package/corpus/templates/analytics/app/lib/data-sources.ts +1 -1
  6. package/corpus/templates/analytics/server/lib/gong.ts +51 -2
  7. package/corpus/templates/assets/.agents/skills/agent-native-toolkit/SKILL.md +33 -0
  8. package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +53 -1
  9. package/corpus/templates/brain/.agents/skills/agent-native-toolkit/SKILL.md +33 -0
  10. package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +53 -1
  11. package/corpus/templates/brain/app/routes/settings.tsx +1 -1
  12. package/corpus/templates/brain/server/register-secrets.ts +1 -1
  13. package/corpus/templates/calendar/.agents/skills/agent-native-toolkit/SKILL.md +33 -0
  14. package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +53 -1
  15. package/corpus/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +33 -0
  16. package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +53 -1
  17. package/corpus/templates/chat/AGENTS.md +11 -0
  18. package/corpus/templates/chat/app/components/layout/Layout.tsx +1 -1
  19. package/corpus/templates/chat/app/root.tsx +1 -1
  20. package/corpus/templates/chat/app/routes/agent.tsx +29 -13
  21. package/corpus/templates/chat/vite.config.ts +42 -0
  22. package/corpus/templates/clips/.agents/skills/agent-native-toolkit/SKILL.md +33 -0
  23. package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +53 -1
  24. package/corpus/templates/clips/app/components/library/empty-state.tsx +1 -3
  25. package/corpus/templates/clips/app/components/library/library-grid.tsx +2 -6
  26. package/corpus/templates/clips/app/components/library/library-layout.tsx +2 -6
  27. package/corpus/templates/clips/app/components/recorder/pre-record-panel.tsx +1 -3
  28. package/corpus/templates/clips/app/routes/bug-report.tsx +1 -8
  29. package/corpus/templates/clips/app/routes/import.tsx +1 -3
  30. package/corpus/templates/clips/changelog/2026-08-04-recording-buttons-are-now-text-only-for-a-cleaner-clips-inte.md +6 -0
  31. package/corpus/templates/clips/changelog/2026-08-04-save-settings-now-matches-the-other-clips-settings-buttons.md +6 -0
  32. package/corpus/templates/clips/chrome-extension/src/styles.css +1 -0
  33. package/corpus/templates/content/.agents/skills/agent-native-toolkit/SKILL.md +33 -0
  34. package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +53 -1
  35. package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +33 -0
  36. package/corpus/templates/crm/app/routes/settings.tsx +2 -2
  37. package/corpus/templates/design/.agents/skills/agent-native-toolkit/SKILL.md +33 -0
  38. package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +53 -1
  39. package/corpus/templates/design/actions/import-figma-clipboard.ts +1 -1
  40. package/corpus/templates/dispatch/.agents/skills/agent-native-toolkit/SKILL.md +33 -0
  41. package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +53 -1
  42. package/corpus/templates/dispatch/changelog/2026-08-04-dispatch-keeps-connected-chats-out-of-local-history-by-defau.md +6 -0
  43. package/corpus/templates/factory/.agents/skills/agent-native-toolkit/SKILL.md +33 -0
  44. package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +53 -1
  45. package/corpus/templates/factory/README.md +1 -1
  46. package/corpus/templates/forms/.agents/skills/agent-native-toolkit/SKILL.md +33 -0
  47. package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +53 -1
  48. package/corpus/templates/macros/.agents/skills/agent-native-toolkit/SKILL.md +33 -0
  49. package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +53 -1
  50. package/corpus/templates/mail/.agents/skills/agent-native-toolkit/SKILL.md +33 -0
  51. package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +53 -1
  52. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +0 -2
  53. package/corpus/templates/mail/app/pages/SettingsPage.tsx +1 -1
  54. package/corpus/templates/plan/.agents/skills/agent-native-toolkit/SKILL.md +33 -0
  55. package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +53 -1
  56. package/corpus/templates/slides/.agents/skills/agent-native-toolkit/SKILL.md +33 -0
  57. package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +53 -1
  58. package/corpus/templates/slides/actions/generate-image-api.ts +15 -4
  59. package/corpus/templates/slides/actions/import-google-slides-reference.ts +83 -0
  60. package/corpus/templates/slides/actions/import-pptx.ts +134 -117
  61. package/corpus/templates/slides/app/components/editor/GoogleSlidesReferenceImport.tsx +387 -0
  62. package/corpus/templates/slides/app/components/editor/ImageGenPanel.tsx +78 -48
  63. package/corpus/templates/slides/app/components/editor/NewDeckReferenceStep.tsx +377 -187
  64. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +0 -1
  65. package/corpus/templates/slides/app/hooks/use-deck-design-system.ts +20 -1
  66. package/corpus/templates/slides/app/i18n/en-US.ts +15 -0
  67. package/corpus/templates/slides/app/lib/new-deck-reference-selection.ts +22 -0
  68. package/corpus/templates/slides/app/pages/DeckEditor.tsx +4 -1
  69. package/corpus/templates/slides/app/pages/Index.tsx +172 -85
  70. package/corpus/templates/slides/server/lib/assets-image-delegation.ts +4 -2
  71. package/corpus/templates/slides/shared/api.ts +14 -1
  72. package/corpus/templates/tasks/.agents/skills/agent-native-toolkit/SKILL.md +33 -0
  73. package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +53 -1
  74. package/dist/chat-threads/schema.d.ts +57 -0
  75. package/dist/chat-threads/schema.js +3 -0
  76. package/dist/chat-threads/store.d.ts +26 -0
  77. package/dist/chat-threads/store.js +84 -6
  78. package/dist/client/AgentPanel.js +11 -5
  79. package/dist/client/ConnectBuilderCard.js +1 -1
  80. package/dist/client/agent-page/AgentEmptyState.d.ts +2 -1
  81. package/dist/client/agent-page/AgentEmptyState.js +6 -2
  82. package/dist/client/agent-page/AgentJobsTab.d.ts +3 -1
  83. package/dist/client/agent-page/AgentJobsTab.js +55 -44
  84. package/dist/client/agent-page/AgentTabFrame.d.ts +2 -1
  85. package/dist/client/agent-page/AgentTabFrame.js +4 -2
  86. package/dist/client/agent-page/AgentTabsPage.js +12 -8
  87. package/dist/client/agent-page/AgentWorkspaceContent.d.ts +10 -0
  88. package/dist/client/agent-page/AgentWorkspaceContent.js +110 -0
  89. package/dist/client/agent-page/AutomationDetailsDialog.js +1 -1
  90. package/dist/client/chat/run-recovery.js +3 -3
  91. package/dist/client/error-format.js +1 -1
  92. package/dist/client/integrations/IntegrationsPanel.d.ts +1 -0
  93. package/dist/client/integrations/IntegrationsPanel.js +149 -5
  94. package/dist/client/onboarding/FirstRunOnboarding.js +130 -15
  95. package/dist/client/onboarding/index.d.ts +1 -1
  96. package/dist/client/onboarding/index.js +1 -1
  97. package/dist/client/onboarding/use-onboarding.js +12 -2
  98. package/dist/client/onboarding/use-preview-mode.d.ts +4 -0
  99. package/dist/client/onboarding/use-preview-mode.js +9 -0
  100. package/dist/client/resources/BuiltinCapabilityDetail.js +2 -2
  101. package/dist/client/resources/ResourceTree.d.ts +4 -1
  102. package/dist/client/resources/ResourceTree.js +13 -8
  103. package/dist/client/resources/ResourcesPanel.js +7 -3
  104. package/dist/client/resources/mcp-integration-catalog.js +4 -4
  105. package/dist/client/resources/use-mcp-servers.js +6 -6
  106. package/dist/client/settings/AgentsSection.js +15 -16
  107. package/dist/client/settings/AutomationsSection.js +1 -1
  108. package/dist/client/settings/DemoModeSection.js +1 -1
  109. package/dist/client/settings/SettingsPanel.d.ts +3 -1
  110. package/dist/client/settings/SettingsPanel.js +284 -88
  111. package/dist/client/settings/SettingsRow.js +1 -1
  112. package/dist/client/settings/SettingsSection.d.ts +6 -4
  113. package/dist/client/settings/SettingsSection.js +6 -6
  114. package/dist/client/settings/SettingsTabsPage.js +47 -25
  115. package/dist/client/settings/VoiceTranscriptionSection.d.ts +3 -1
  116. package/dist/client/settings/VoiceTranscriptionSection.js +20 -8
  117. package/dist/client/settings/agent-settings-search.d.ts +1 -1
  118. package/dist/client/settings/agent-settings-search.js +8 -8
  119. package/dist/client/transcription/BuilderTranscriptionCta.js +2 -2
  120. package/dist/client/use-chat-threads.d.ts +9 -0
  121. package/dist/client/use-chat-threads.js +22 -6
  122. package/dist/collab/routes.d.ts +1 -1
  123. package/dist/integrations/google-docs-poller.js +9 -1
  124. package/dist/integrations/webhook-handler.js +11 -1
  125. package/dist/jobs/scheduler.d.ts +4 -1
  126. package/dist/jobs/scheduler.js +34 -9
  127. package/dist/localization/default-messages.js +40 -40
  128. package/dist/mcp-client/oauth-routes.js +1 -1
  129. package/dist/notifications/routes.d.ts +1 -1
  130. package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
  131. package/dist/provider-api/actions/provider-api.d.ts +15 -15
  132. package/dist/resources/handlers.d.ts +1 -1
  133. package/dist/secrets/onboarding.js +1 -1
  134. package/dist/secrets/routes.d.ts +9 -9
  135. package/dist/server/agent-chat/browser-team-tools.d.ts +1 -0
  136. package/dist/server/agent-chat/browser-team-tools.js +1 -0
  137. package/dist/server/agent-chat-plugin.js +14 -1
  138. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  139. package/dist/server/agent-teams.d.ts +2 -0
  140. package/dist/server/agent-teams.js +2 -0
  141. package/dist/server/workspace-provider-oauth.js +1 -1
  142. package/dist/setup-connections/onboarding.js +2 -2
  143. package/dist/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +33 -0
  144. package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +53 -1
  145. package/dist/templates/chat/AGENTS.md +11 -0
  146. package/dist/templates/chat/app/components/layout/Layout.tsx +1 -1
  147. package/dist/templates/chat/app/root.tsx +1 -1
  148. package/dist/templates/chat/app/routes/agent.tsx +29 -13
  149. package/dist/templates/chat/vite.config.ts +42 -0
  150. package/dist/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +33 -0
  151. package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +53 -1
  152. package/dist/templates/default/AGENTS.md +11 -0
  153. package/dist/templates/default/vite.config.ts +42 -0
  154. package/dist/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +33 -0
  155. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +33 -0
  156. package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +53 -1
  157. package/dist/templates/workspace-core/AGENTS.md +11 -0
  158. package/dist/templates/workspace-root/AGENTS.md +14 -0
  159. package/dist/vite/client.js +56 -0
  160. package/package.json +2 -2
  161. package/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +33 -0
  162. package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +53 -1
  163. package/src/templates/chat/AGENTS.md +11 -0
  164. package/src/templates/chat/app/components/layout/Layout.tsx +1 -1
  165. package/src/templates/chat/app/root.tsx +1 -1
  166. package/src/templates/chat/app/routes/agent.tsx +29 -13
  167. package/src/templates/chat/vite.config.ts +42 -0
  168. package/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +33 -0
  169. package/src/templates/default/.agents/skills/frontend-design/SKILL.md +53 -1
  170. package/src/templates/default/AGENTS.md +11 -0
  171. package/src/templates/default/vite.config.ts +42 -0
  172. package/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +33 -0
  173. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +33 -0
  174. package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +53 -1
  175. package/src/templates/workspace-core/AGENTS.md +11 -0
  176. package/src/templates/workspace-root/AGENTS.md +14 -0
@@ -1,9 +1,10 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Button } from "@agent-native/toolkit/ui/button";
3
- import { IconBolt, IconCalendarEvent, IconClock, IconAlertTriangle, IconEye, IconLoader2, IconPencil, IconPlayerPause, IconPlayerPlay, IconTrash, } from "@tabler/icons-react";
3
+ import { IconBolt, IconCalendarEvent, IconClock, IconAlertTriangle, IconChevronDown, IconEye, IconLoader2, IconPencil, IconPlayerPause, IconPlayerPlay, IconTrash, } from "@tabler/icons-react";
4
4
  import { useState } from "react";
5
5
  import { AgentAskPopover } from "../AgentAskPopover.js";
6
6
  import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "../components/ui/dialog.js";
7
+ import { Popover, PopoverContent, PopoverTrigger, } from "../components/ui/popover.js";
7
8
  import { useFormatters, useT } from "../i18n.js";
8
9
  import { automationCreationContext } from "../settings/AutomationsSection.js";
9
10
  import { AgentEmptyState } from "./AgentEmptyState.js";
@@ -96,7 +97,7 @@ function detailsFields(entry, t, formatDateTime) {
96
97
  export function organizationAutomationCreationContext() {
97
98
  return "The user wants to create a new organization automation. Use manage-automations with action=define and scope=organization to create it. Ask clarifying questions if needed about whether it runs on a schedule or event, any conditions, and what actions to take.";
98
99
  }
99
- export function AgentJobsTab({ canManageOrg = false }) {
100
+ export function AgentJobsTab({ canManageOrg = false, hideHeader = false, }) {
100
101
  const t = useT();
101
102
  const formatters = useFormatters();
102
103
  const personalJobsQuery = useRecurringJobs("user");
@@ -181,51 +182,55 @@ export function AgentJobsTab({ canManageOrg = false }) {
181
182
  defaultValue: "Create an automation that does this: ",
182
183
  }), title: t("jobs.automationsCreateTitle", {
183
184
  defaultValue: "Create an automation",
184
- }) })) })) : (_jsx("div", { className: "divide-y divide-border/60 border-y border-border/60", children: entries.map((entry) => {
185
- const resource = entry.resource;
186
- const lastRun = formatDateTime(resource.lastRun);
187
- const lastCheck = formatDateTime(resource.lastCheck);
188
- const nextRun = formatDateTime(resource.nextRun);
189
- const triggerDescription = entry.kind === "automation" && entry.triggerType === "event"
190
- ? t("jobs.automationEventTrigger", {
191
- defaultValue: "On {{event}}",
192
- event: entry.resource.event ?? "event",
193
- })
194
- : resource.scheduleDescription ||
195
- resource.schedule ||
196
- t("jobs.scheduledTrigger", {
197
- defaultValue: "Scheduled",
198
- });
199
- const instructions = entry.kind === "automation"
200
- ? entry.resource.body
201
- : entry.resource.instructions;
202
- return (_jsx("article", { className: "py-4 first:pt-5 last:pb-5", children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("div", { className: "mt-0.5 text-muted-foreground", children: entry.triggerType === "event" ? (_jsx(IconBolt, { className: "size-4" })) : (_jsx(IconClock, { className: "size-4" })) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("h3", { className: "truncate text-sm font-medium", children: resource.name.replace(/-/g, " ") }), _jsx("span", { className: "rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground", children: entry.triggerType === "event"
203
- ? t("jobs.eventTrigger", {
204
- defaultValue: "Event-triggered",
205
- })
206
- : t("jobs.scheduledTrigger", {
207
- defaultValue: "Scheduled",
208
- }) }), _jsx("span", { className: resource.enabled
209
- ? "rounded-full bg-emerald-500/15 px-2 py-0.5 text-[10px] font-medium text-emerald-600 dark:text-emerald-400"
210
- : "rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground", children: resource.enabled
211
- ? t("jobs.enabled", { defaultValue: "Enabled" })
212
- : t("jobs.paused", { defaultValue: "Paused" }) }), resource.lastStatus ? (_jsx("span", { className: "rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground", children: resource.lastStatus })) : null] }), _jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: triggerDescription }), _jsx("p", { className: "mt-1 line-clamp-2 text-xs text-muted-foreground/80", children: instructions }), lastRun || nextRun || lastCheck ? (_jsxs("div", { className: "mt-2 flex flex-wrap gap-x-4 gap-y-1 text-[11px] text-muted-foreground", children: [nextRun ? (_jsxs("span", { children: [t("jobs.nextRun", { defaultValue: "Next run" }), ":", " ", nextRun] })) : null, _jsxs("span", { children: [t("jobs.lastRun", { defaultValue: "Last run" }), ":", " ", lastRun ??
213
- t("jobs.neverRan", { defaultValue: "Never" })] }), !lastRun && lastCheck ? (_jsxs("span", { children: [t("jobs.lastChecked", {
214
- defaultValue: "Last checked",
215
- }), ": ", lastCheck] })) : null] })) : null, resource.lastError ? (_jsxs("p", { className: "mt-2 flex items-start gap-1.5 text-[11px] text-destructive", children: [_jsx(IconAlertTriangle, { className: "mt-px size-3 shrink-0" }), _jsx("span", { className: "min-w-0 break-words", children: resource.lastError })] })) : null] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [_jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "cursor-pointer px-2 text-xs", onClick: () => setDetailsTarget(entry), children: [_jsx(IconEye, { className: "size-3.5" }), t("jobs.details", { defaultValue: "Details" })] }), resource.canUpdate ? (_jsxs(_Fragment, { children: [_jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "cursor-pointer px-2 text-xs", disabled: mutationPending || runAutomationMutation.isPending, onClick: () => setRunTarget(entry), children: [_jsx(IconPlayerPlay, { className: "size-3.5" }), t("jobs.runNow", { defaultValue: "Run now" })] }), entry.triggerType === "schedule" ? (_jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "cursor-pointer px-2 text-xs", disabled: mutationPending, onClick: () => setScheduleTarget(entry), children: [_jsx(IconPencil, { className: "size-3.5" }), t("jobs.edit", { defaultValue: "Edit" })] })) : null, _jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "cursor-pointer px-2 text-xs", disabled: mutationPending, onClick: () => mutateEntry(entry, "update", {
216
- enabled: !resource.enabled,
217
- }), children: [resource.enabled ? (_jsx(IconPlayerPause, { className: "size-3.5" })) : (_jsx(IconPlayerPlay, { className: "size-3.5" })), resource.enabled
218
- ? t("jobs.pause", { defaultValue: "Pause" })
219
- : t("jobs.resume", { defaultValue: "Resume" })] }), _jsx(Button, { type: "button", variant: "ghost", size: "icon", className: "size-8 cursor-pointer text-muted-foreground hover:text-destructive", "aria-label": t("jobs.delete", {
220
- defaultValue: "Delete",
221
- }), onClick: () => setDeleteTarget(entry), children: _jsx(IconTrash, { className: "size-3.5" }) })] })) : null] })] }) }, `${entry.kind}:${resource.id}`));
222
- }) }))] }));
185
+ }) })), variant: "card" })) : (_jsx("div", { className: "overflow-hidden rounded-xl border border-border/70 bg-card text-card-foreground", children: _jsx("div", { className: "divide-y divide-border/60 px-4", children: entries.map((entry) => {
186
+ const resource = entry.resource;
187
+ const lastRun = formatDateTime(resource.lastRun);
188
+ const lastCheck = formatDateTime(resource.lastCheck);
189
+ const nextRun = formatDateTime(resource.nextRun);
190
+ const triggerDescription = entry.kind === "automation" && entry.triggerType === "event"
191
+ ? t("jobs.automationEventTrigger", {
192
+ defaultValue: "On {{event}}",
193
+ event: entry.resource.event ?? "event",
194
+ })
195
+ : resource.scheduleDescription ||
196
+ resource.schedule ||
197
+ t("jobs.scheduledTrigger", {
198
+ defaultValue: "Scheduled",
199
+ });
200
+ const instructions = entry.kind === "automation"
201
+ ? entry.resource.body
202
+ : entry.resource.instructions;
203
+ return (_jsx("article", { className: "py-4 first:pt-5 last:pb-5", children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("div", { className: "mt-0.5 text-muted-foreground", children: entry.triggerType === "event" ? (_jsx(IconBolt, { className: "size-4" })) : (_jsx(IconClock, { className: "size-4" })) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("h3", { className: "truncate text-sm font-medium", children: resource.name.replace(/-/g, " ") }), _jsx("span", { className: "rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground", children: entry.triggerType === "event"
204
+ ? t("jobs.eventTrigger", {
205
+ defaultValue: "Event-triggered",
206
+ })
207
+ : t("jobs.scheduledTrigger", {
208
+ defaultValue: "Scheduled",
209
+ }) }), _jsx("span", { className: resource.enabled
210
+ ? "rounded-full bg-emerald-500/15 px-2 py-0.5 text-[10px] font-medium text-emerald-600 dark:text-emerald-400"
211
+ : "rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground", children: resource.enabled
212
+ ? t("jobs.enabled", { defaultValue: "Enabled" })
213
+ : t("jobs.paused", { defaultValue: "Paused" }) }), resource.lastStatus ? (_jsx("span", { className: "rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground", children: resource.lastStatus })) : null] }), _jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: triggerDescription }), _jsx("p", { className: "hidden", children: instructions }), lastRun || nextRun || lastCheck ? (_jsxs("div", { className: "hidden", children: [nextRun ? (_jsxs("span", { children: [t("jobs.nextRun", { defaultValue: "Next run" }), ":", " ", nextRun] })) : null, _jsxs("span", { children: [t("jobs.lastRun", { defaultValue: "Last run" }), ":", " ", lastRun ??
214
+ t("jobs.neverRan", { defaultValue: "Never" })] }), !lastRun && lastCheck ? (_jsxs("span", { children: [t("jobs.lastChecked", {
215
+ defaultValue: "Last checked",
216
+ }), ": ", lastCheck] })) : null] })) : null, resource.lastError ? (_jsxs("p", { className: "mt-2 flex items-start gap-1.5 text-[11px] text-destructive", children: [_jsx(IconAlertTriangle, { className: "mt-px size-3 shrink-0" }), _jsx("span", { className: "min-w-0 break-words", children: resource.lastError })] })) : null] }), _jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [resource.canUpdate ? (_jsx("button", { type: "button", role: "switch", "aria-checked": resource.enabled, "aria-label": resource.enabled
217
+ ? "Pause automation"
218
+ : "Resume automation", disabled: mutationPending, onClick: () => mutateEntry(entry, "update", {
219
+ enabled: !resource.enabled,
220
+ }), className: `relative h-5 w-9 rounded-full transition-colors disabled:opacity-50 ${resource.enabled ? "bg-primary" : "bg-muted"}`, children: _jsx("span", { className: `absolute top-0.5 size-4 rounded-full bg-background shadow-sm transition-transform ${resource.enabled ? "start-[18px]" : "start-0.5"}` }) })) : null, _jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs(Button, { type: "button", variant: "outline", size: "sm", className: "cursor-pointer gap-1 px-2.5 text-xs", children: ["Manage", _jsx(IconChevronDown, { className: "size-3.5" })] }) }), _jsxs(PopoverContent, { align: "end", className: "w-40 p-1", children: [_jsxs("button", { type: "button", onClick: () => setDetailsTarget(entry), className: "flex w-full items-center gap-2 rounded-md px-2.5 py-2 text-left text-xs hover:bg-accent", children: [_jsx(IconEye, { className: "size-3.5" }), " Details"] }), resource.canUpdate ? (_jsxs(_Fragment, { children: [_jsxs("button", { type: "button", disabled: runAutomationMutation.isPending, onClick: () => setRunTarget(entry), className: "flex w-full items-center gap-2 rounded-md px-2.5 py-2 text-left text-xs hover:bg-accent disabled:opacity-50", children: [_jsx(IconPlayerPlay, { className: "size-3.5" }), " Run now"] }), entry.triggerType === "schedule" ? (_jsxs("button", { type: "button", onClick: () => setScheduleTarget(entry), className: "flex w-full items-center gap-2 rounded-md px-2.5 py-2 text-left text-xs hover:bg-accent", children: [_jsx(IconPencil, { className: "size-3.5" }), " Edit"] })) : null, _jsxs("button", { type: "button", onClick: () => setDeleteTarget(entry), className: "flex w-full items-center gap-2 rounded-md px-2.5 py-2 text-left text-xs text-destructive hover:bg-destructive/10", children: [_jsx(IconTrash, { className: "size-3.5" }), " Delete"] })] })) : null] })] })] }), _jsxs("div", { className: "hidden", children: [_jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "cursor-pointer px-2 text-xs", onClick: () => setDetailsTarget(entry), children: [_jsx(IconEye, { className: "size-3.5" }), t("jobs.details", { defaultValue: "Details" })] }), resource.canUpdate ? (_jsxs(_Fragment, { children: [_jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "cursor-pointer px-2 text-xs", disabled: mutationPending || runAutomationMutation.isPending, onClick: () => setRunTarget(entry), children: [_jsx(IconPlayerPlay, { className: "size-3.5" }), t("jobs.runNow", { defaultValue: "Run now" })] }), entry.triggerType === "schedule" ? (_jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "cursor-pointer px-2 text-xs", disabled: mutationPending, onClick: () => setScheduleTarget(entry), children: [_jsx(IconPencil, { className: "size-3.5" }), t("jobs.edit", { defaultValue: "Edit" })] })) : null, _jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "cursor-pointer px-2 text-xs", disabled: mutationPending, onClick: () => mutateEntry(entry, "update", {
221
+ enabled: !resource.enabled,
222
+ }), children: [resource.enabled ? (_jsx(IconPlayerPause, { className: "size-3.5" })) : (_jsx(IconPlayerPlay, { className: "size-3.5" })), resource.enabled
223
+ ? t("jobs.pause", { defaultValue: "Pause" })
224
+ : t("jobs.resume", { defaultValue: "Resume" })] }), _jsx(Button, { type: "button", variant: "ghost", size: "icon", className: "size-8 cursor-pointer text-muted-foreground hover:text-destructive", "aria-label": t("jobs.delete", {
225
+ defaultValue: "Delete",
226
+ }), onClick: () => setDeleteTarget(entry), children: _jsx(IconTrash, { className: "size-3.5" }) })] })) : null] })] }) }, `${entry.kind}:${resource.id}`));
227
+ }) }) }))] }));
223
228
  const mutationError = personalJobsMutation.error ||
224
229
  personalAutomationsMutation.error ||
225
230
  organizationJobsMutation.error ||
226
231
  organizationAutomationsMutation.error ||
227
232
  runAutomationMutation.error;
228
- return (_jsxs(AgentTabFrame, { title: t("jobs.pageTitle", { defaultValue: "Automations" }), description: t("jobs.pageDescription", {
233
+ return (_jsxs(AgentTabFrame, { compact: hideHeader, title: t("jobs.pageTitle", { defaultValue: "Automations" }), description: t("jobs.pageDescription", {
229
234
  defaultValue: "Manage agent tasks that run on a schedule or in response to events.",
230
235
  }), actions: _jsx(AgentAskPopover, { context: automationCreationContext(), prompt: t("jobs.automationPrompt", {
231
236
  defaultValue: "Create an automation that does this: ",
@@ -233,7 +238,13 @@ export function AgentJobsTab({ canManageOrg = false }) {
233
238
  defaultValue: "Create an automation",
234
239
  }), label: t("jobs.newAutomation", {
235
240
  defaultValue: "New automation",
236
- }) }), children: [_jsxs("div", { className: "space-y-7", children: [renderSection({
241
+ }) }), children: [_jsxs("div", { className: "space-y-7", children: [hideHeader ? (_jsx("div", { className: "flex justify-end", children: _jsx(AgentAskPopover, { context: automationCreationContext(), prompt: t("jobs.automationPrompt", {
242
+ defaultValue: "Create an automation that does this: ",
243
+ }), title: t("jobs.automationsCreateTitle", {
244
+ defaultValue: "Create an automation",
245
+ }), label: t("jobs.newAutomation", {
246
+ defaultValue: "New automation",
247
+ }) }) })) : null, renderSection({
237
248
  title: t("jobs.personal", { defaultValue: "Personal" }),
238
249
  description: t("jobs.personalDescription", {
239
250
  defaultValue: "Scheduled and event-triggered automations that run for you.",
@@ -244,7 +255,7 @@ export function AgentJobsTab({ canManageOrg = false }) {
244
255
  personalJobsQuery.error,
245
256
  personalAutomationsQuery.error,
246
257
  ].filter(Boolean),
247
- }), _jsx("div", { className: "border-t border-border/70 pt-6", children: renderSection({
258
+ }), _jsx("div", { className: "pt-2", children: renderSection({
248
259
  title: t("jobs.organization", { defaultValue: "Organization" }),
249
260
  description: t("jobs.organizationDescription", {
250
261
  defaultValue: "Scheduled and event-triggered automations shared with this organization.",
@@ -7,8 +7,9 @@ interface AgentTabFrameProps {
7
7
  actions?: ReactNode;
8
8
  children: ReactNode;
9
9
  className?: string;
10
+ compact?: boolean;
10
11
  }
11
12
  /** Shared settings surface for Manage agent page tabs. */
12
- export declare function AgentTabFrame({ title, description, helpHref, helpLabel, actions, children, className, }: AgentTabFrameProps): import("react").JSX.Element;
13
+ export declare function AgentTabFrame({ title, description, helpHref, helpLabel, actions, children, className, compact, }: AgentTabFrameProps): import("react").JSX.Element;
13
14
  export {};
14
15
  //# sourceMappingURL=AgentTabFrame.d.ts.map
@@ -2,7 +2,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { IconHelpCircle } from "@tabler/icons-react";
3
3
  import { cn } from "../utils.js";
4
4
  /** Shared settings surface for Manage agent page tabs. */
5
- export function AgentTabFrame({ title, description, helpHref, helpLabel, actions, children, className, }) {
6
- return (_jsxs("div", { className: cn("mx-auto flex w-full max-w-5xl flex-col gap-6", className), children: [_jsxs("header", { className: "flex flex-wrap items-start justify-between gap-4 pb-5", children: [_jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("h2", { className: "text-xl font-semibold tracking-tight text-foreground", children: title }), helpHref && (_jsx("a", { href: helpHref, target: "_blank", rel: "noopener noreferrer", "aria-label": helpLabel ?? `Open ${title} documentation`, title: helpLabel ?? `Open ${title} documentation`, className: "inline-flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent/50 hover:text-foreground", children: _jsx(IconHelpCircle, { className: "size-4" }) }))] }), _jsx("p", { className: "max-w-2xl text-sm leading-relaxed text-muted-foreground", children: description })] }), actions] }), _jsx("div", { className: "min-w-0", children: children })] }));
5
+ export function AgentTabFrame({ title, description, helpHref, helpLabel, actions, children, className, compact = false, }) {
6
+ return (_jsxs("div", { className: cn(compact
7
+ ? "flex w-full flex-col gap-6"
8
+ : "mx-auto flex w-full max-w-5xl flex-col gap-6", className), children: [!compact && (_jsxs("header", { className: "flex flex-wrap items-start justify-between gap-4 pb-5", children: [_jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("h2", { className: "text-xl font-semibold tracking-tight text-foreground", children: title }), helpHref && (_jsx("a", { href: helpHref, target: "_blank", rel: "noopener noreferrer", "aria-label": helpLabel ?? `Open ${title} documentation`, title: helpLabel ?? `Open ${title} documentation`, className: "inline-flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent/50 hover:text-foreground", children: _jsx(IconHelpCircle, { className: "size-4" }) }))] }), _jsx("p", { className: "max-w-2xl text-sm leading-relaxed text-muted-foreground", children: description })] }), actions] })), _jsx("div", { className: "min-w-0", children: children })] }));
7
9
  }
8
10
  //# sourceMappingURL=AgentTabFrame.js.map
@@ -127,7 +127,7 @@ function ConnectionsTab({ canManageOrg = false }) {
127
127
  const canCreateOrgMcp = hasOrg && canManageOrg;
128
128
  const onCreateMcpServer = useCallback(async (args) => {
129
129
  if (args.scope === "org" && !canCreateOrgMcp) {
130
- throw new Error("Only organization admins can add organization MCP servers.");
130
+ throw new Error("Only organization admins can add organization agent integrations.");
131
131
  }
132
132
  return createServer.mutateAsync(args);
133
133
  }, [canCreateOrgMcp, createServer]);
@@ -156,15 +156,15 @@ function ConnectionsTab({ canManageOrg = false }) {
156
156
  const selected = selectedServer?.id === server.id && selectedServer.scope === server.scope;
157
157
  return (_jsxs("div", { className: cn("group/connection-row py-4 transition-colors first:pt-5 last:pb-5", selected && "bg-accent/20"), children: [_jsxs("div", { className: "flex items-start gap-3", children: [_jsxs("button", { type: "button", onClick: () => setSelectedServer(selected ? null : server), className: "min-w-0 flex-1 cursor-pointer text-start", children: [_jsx("div", { className: "flex flex-wrap items-center gap-2", children: _jsx("span", { className: "truncate text-sm font-medium text-foreground", children: server.name }) }), _jsx("code", { className: "mt-1 block truncate text-[11px] text-muted-foreground", children: server.url }), _jsxs("div", { className: "mt-2 flex items-center gap-2", children: [_jsx(ServerStatus, { server: server }), server.description && (_jsx("span", { className: "truncate text-[11px] text-muted-foreground/70", children: server.description }))] })] }), canDelete && (_jsx("button", { type: "button", onClick: () => void removeServer(server), disabled: deleteServer.isPending, className: cn("cursor-pointer rounded-md px-2 py-1 text-[11px] font-medium text-muted-foreground hover:bg-destructive/10 hover:text-destructive", deleteTarget === key && "bg-destructive/10 text-destructive"), children: deleteTarget === key ? "Confirm" : "Delete" }))] }), selected && (_jsx("div", { className: "mt-3 border-t border-border/70 pt-3", children: _jsx(McpServerDetail, { server: server }) }))] }, key));
158
158
  };
159
- return (_jsx(AgentTabFrame, { title: "Connections", description: "Tools and services this agent can reach, grouped by where they are configured.", actions: _jsx("button", { type: "button", onClick: () => {
159
+ return (_jsx(AgentTabFrame, { title: "Agent integrations", description: "Tools and services this agent can reach, grouped by where they are configured.", actions: _jsx("button", { type: "button", onClick: () => {
160
160
  setError(null);
161
161
  setDialogOpen(true);
162
- }, className: "cursor-pointer rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90", children: t("mcpIntegrations.connect") }), children: _jsxs("section", { className: "space-y-4", children: [error && (_jsx("p", { className: "rounded-md border border-destructive/20 bg-destructive/5 px-3 py-2 text-xs text-destructive", children: error })), serversQuery.isLoading ? (_jsx(TabLoading, {})) : serversQuery.isError ? (_jsx("p", { className: "rounded-md border border-destructive/20 bg-destructive/5 px-3 py-2 text-xs text-destructive", children: "Could not load MCP servers." })) : (_jsx("div", { className: "space-y-6", children: [
162
+ }, className: "cursor-pointer rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90", children: t("mcpIntegrations.connect") }), children: _jsxs("section", { className: "space-y-4", children: [error && (_jsx("p", { className: "rounded-md border border-destructive/20 bg-destructive/5 px-3 py-2 text-xs text-destructive", children: error })), serversQuery.isLoading ? (_jsx(TabLoading, {})) : serversQuery.isError ? (_jsx("p", { className: "rounded-md border border-destructive/20 bg-destructive/5 px-3 py-2 text-xs text-destructive", children: "Could not load agent integrations." })) : (_jsx("div", { className: "space-y-6", children: [
163
163
  { label: "Personal", servers: data?.user ?? [] },
164
164
  { label: "Organization", servers: data?.org ?? [] },
165
- ].map((section) => (_jsxs("section", { className: "space-y-2", children: [_jsx("h2", { className: "text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground/70", children: section.label }), section.servers.length > 0 ? (_jsx("div", { className: "divide-y divide-border/60 border-y border-border/60", children: section.servers.map(renderServer) })) : (_jsx(AgentEmptyState, { icon: IconPlugConnected, title: `No ${section.label.toLowerCase()} connections yet`, description: section.label === "Personal"
165
+ ].map((section) => (_jsxs("section", { className: "space-y-2", children: [_jsx("h2", { className: "text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground/70", children: section.label }), section.servers.length > 0 ? (_jsx("div", { className: "divide-y divide-border/60 border-y border-border/60", children: section.servers.map(renderServer) })) : (_jsx(AgentEmptyState, { icon: IconPlugConnected, title: `No ${section.label.toLowerCase()} agent integrations yet`, description: section.label === "Personal"
166
166
  ? "Connect a service to give the agent access to it."
167
- : "Organization connections shared with this workspace will appear here." }))] }, section.label))) })), _jsx(McpIntegrationDialog, { open: dialogOpen, onOpenChange: setDialogOpen, defaultScope: "user", canCreateOrgMcp: canCreateOrgMcp, hasOrg: hasOrg, onCreateMcpServer: onCreateMcpServer })] }) }));
167
+ : "Organization agent integrations shared with this workspace will appear here." }))] }, section.label))) })), _jsx(McpIntegrationDialog, { open: dialogOpen, onOpenChange: setDialogOpen, defaultScope: "user", canCreateOrgMcp: canCreateOrgMcp, hasOrg: hasOrg, onCreateMcpServer: onCreateMcpServer })] }) }));
168
168
  }
169
169
  export const AGENT_ACCESS_DOCS_HREF = {
170
170
  mcp: "https://agent-native.com/docs/mcp-protocol",
@@ -323,12 +323,16 @@ export function AgentTabsPage({ appName, extraTabs = [], extraTabFactories = [],
323
323
  },
324
324
  {
325
325
  id: "connections",
326
- label: "Connections",
326
+ label: "Agent integrations",
327
327
  icon: IconPlugConnected,
328
328
  group: "agent",
329
- keywords: "mcp servers tools integrations",
329
+ keywords: "agent integrations tools connections",
330
330
  searchEntries: [
331
- { id: "mcp-servers", label: "MCP servers", keywords: "tools" },
331
+ {
332
+ id: "mcp-servers",
333
+ label: "Agent integrations",
334
+ keywords: "tools integrations connections",
335
+ },
332
336
  ],
333
337
  content: _jsx(ConnectionsTab, { scope: scope, canManageOrg: canManageOrg }),
334
338
  },
@@ -0,0 +1,10 @@
1
+ import { type ReactNode } from "react";
2
+ export type AgentWorkspaceTab = "overview" | "resources" | "automations" | "agents" | "access";
3
+ export declare function AgentWorkspaceContent({ overview, className, activeTab, }: {
4
+ overview: ReactNode;
5
+ activeTab: AgentWorkspaceTab;
6
+ className?: string;
7
+ }): import("react").JSX.Element;
8
+ export declare function agentWorkspaceTabHash(tab: AgentWorkspaceTab): string;
9
+ export declare function isAgentWorkspaceTab(value: string): boolean;
10
+ //# sourceMappingURL=AgentWorkspaceContent.d.ts.map
@@ -0,0 +1,110 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { IconBook2, IconBolt, IconChecklist, IconFolder, IconHierarchy2, IconHistory, IconNotes, IconShieldLock, IconTopologyRing2, } from "@tabler/icons-react";
3
+ import { lazy, Suspense, useEffect, useState } from "react";
4
+ import { AgentsSection } from "../settings/AgentsSection.js";
5
+ import { cn } from "../utils.js";
6
+ import { AgentJobsTab } from "./AgentJobsTab.js";
7
+ const ResourcesPanel = lazy(() => import("../resources/ResourcesPanel.js").then((module) => ({
8
+ default: module.ResourcesPanel,
9
+ })));
10
+ const RESOURCE_TABS = [
11
+ { id: "files", label: "Files", icon: IconFolder },
12
+ { id: "instructions", label: "Instructions", icon: IconChecklist },
13
+ { id: "agents", label: "Agents", icon: IconHierarchy2 },
14
+ { id: "memory", label: "Memory", icon: IconNotes },
15
+ { id: "skills", label: "Skills", icon: IconBook2 },
16
+ { id: "learnings", label: "Learnings", icon: IconHistory },
17
+ { id: "remote-agents", label: "Remote agents", icon: IconTopologyRing2 },
18
+ ];
19
+ const HUB_TABS = [
20
+ { id: "overview", label: "Overview", icon: IconHierarchy2 },
21
+ { id: "resources", label: "Resources", icon: IconFolder },
22
+ { id: "automations", label: "Automations", icon: IconBolt },
23
+ { id: "agents", label: "Connected agents", icon: IconTopologyRing2 },
24
+ { id: "access", label: "Access", icon: IconShieldLock },
25
+ ];
26
+ const RESOURCE_IDS = new Set(RESOURCE_TABS.map((tab) => tab.id));
27
+ function normalizeHash(value) {
28
+ return decodeURIComponent(value.replace(/^#/, "")).toLowerCase();
29
+ }
30
+ function initialHubState() {
31
+ if (typeof window === "undefined") {
32
+ return { tab: "overview", resource: "files" };
33
+ }
34
+ const hash = normalizeHash(window.location.hash);
35
+ const parts = hash.split(":");
36
+ const scoped = parts[0] === "agent";
37
+ const requested = scoped ? parts[1] : hash;
38
+ const resource = scoped && RESOURCE_IDS.has(parts[2])
39
+ ? parts[2]
40
+ : "files";
41
+ if (requested === "resources" ||
42
+ (!scoped && RESOURCE_IDS.has(hash))) {
43
+ return {
44
+ tab: "resources",
45
+ resource: scoped ? resource : hash,
46
+ };
47
+ }
48
+ if (requested === "automations" || requested === "jobs") {
49
+ return { tab: "automations", resource };
50
+ }
51
+ if (requested === "agents" ||
52
+ requested === "a2a" ||
53
+ requested === "connected-agents" ||
54
+ requested === "remote-agents") {
55
+ return { tab: "agents", resource };
56
+ }
57
+ if (requested === "access")
58
+ return { tab: "access", resource };
59
+ return { tab: "overview", resource };
60
+ }
61
+ function ResourceContent({ resource }) {
62
+ const copy = RESOURCE_TABS.find((tab) => tab.id === resource);
63
+ return (_jsxs("div", { className: "space-y-5", children: [_jsx("div", { className: "flex items-center gap-1 overflow-x-auto", children: RESOURCE_TABS.map((tab) => {
64
+ const Icon = tab.icon;
65
+ const selected = tab.id === resource;
66
+ return (_jsxs("button", { type: "button", onClick: () => {
67
+ if (typeof window !== "undefined") {
68
+ window.history.pushState(null, "", `${window.location.pathname}${window.location.search}#agent:resources:${tab.id}`);
69
+ window.dispatchEvent(new Event("hashchange"));
70
+ }
71
+ }, className: cn("inline-flex shrink-0 items-center gap-1.5 rounded-md px-2.5 py-1.5 text-xs font-medium transition-colors", selected
72
+ ? "bg-accent text-foreground"
73
+ : "text-muted-foreground hover:bg-accent/50 hover:text-foreground"), children: [_jsx(Icon, { className: "size-3.5" }), tab.label] }, tab.id));
74
+ }) }), _jsxs("header", { className: "space-y-1", children: [_jsx("h2", { className: "text-lg font-semibold tracking-tight text-foreground", children: copy?.label ?? "Resources" }), _jsx("p", { className: "text-sm leading-5 text-muted-foreground", children: resource === "files"
75
+ ? "Add context the agent can use across conversations."
76
+ : "Manage the resources that shape how the agent works." })] }), _jsx(Suspense, { fallback: _jsx("div", { className: "h-48 animate-pulse rounded-xl border border-border bg-muted/20" }), children: _jsx(ResourcesPanel, { showMcpServers: false, resourceFilter: resource, resourceTreeVariant: "collection", scope: "personal" }, resource) })] }));
77
+ }
78
+ function AccessContent() {
79
+ return (_jsx("div", { children: _jsx("div", { className: "rounded-xl border border-border/70 bg-card text-card-foreground", children: _jsx("div", { className: "px-5 py-5 sm:px-6", children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("span", { className: "flex size-9 shrink-0 items-center justify-center rounded-lg border border-border bg-background text-muted-foreground", children: _jsx(IconShieldLock, { className: "size-4" }) }), _jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "text-sm font-medium text-foreground", children: "Agent access" }), _jsx("p", { className: "mt-1 text-sm leading-5 text-muted-foreground", children: "Use the agent card and MCP endpoints from connected clients." })] })] }) }) }) }));
80
+ }
81
+ export function AgentWorkspaceContent({ overview, className, activeTab, }) {
82
+ const [{ resource }, setState] = useState(initialHubState);
83
+ useEffect(() => {
84
+ const sync = () => setState(initialHubState());
85
+ window.addEventListener("hashchange", sync);
86
+ window.addEventListener("popstate", sync);
87
+ return () => {
88
+ window.removeEventListener("hashchange", sync);
89
+ window.removeEventListener("popstate", sync);
90
+ };
91
+ }, []);
92
+ const page = HUB_TABS.find((item) => item.id === activeTab);
93
+ const pageDescription = activeTab === "overview"
94
+ ? "Configure how your agent works, what it knows, and what it can do."
95
+ : activeTab === "resources"
96
+ ? "Add context the agent can use across conversations."
97
+ : activeTab === "automations"
98
+ ? "Schedule and manage agent tasks."
99
+ : activeTab === "agents"
100
+ ? "Connect agents to delegate work from chat."
101
+ : "Control how other apps and agents access this agent.";
102
+ return (_jsxs("div", { className: cn("w-full space-y-6", className), children: [_jsxs("header", { className: "space-y-1", children: [_jsx("h1", { className: "text-2xl font-semibold tracking-tight text-foreground", children: activeTab === "overview" ? "Agent" : page?.label }), _jsx("p", { className: "text-sm leading-5 text-muted-foreground", children: pageDescription })] }), activeTab === "overview" && overview, activeTab === "resources" && _jsx(ResourceContent, { resource: resource }), activeTab === "automations" && (_jsx(Suspense, { fallback: _jsx("div", { className: "h-48 animate-pulse rounded-xl border border-border bg-muted/20" }), children: _jsx(AgentJobsTab, { scope: "user", canManageOrg: true, hideHeader: true }) })), activeTab === "agents" && _jsx(AgentsSection, {}), activeTab === "access" && _jsx(AccessContent, {})] }));
103
+ }
104
+ export function agentWorkspaceTabHash(tab) {
105
+ return `agent:${tab}`;
106
+ }
107
+ export function isAgentWorkspaceTab(value) {
108
+ return value === "agent" || value.startsWith("agent:");
109
+ }
110
+ //# sourceMappingURL=AgentWorkspaceContent.js.map
@@ -24,7 +24,7 @@ export function AutomationDetailsDialog({ open, name, triggerSummary, fields, co
24
24
  onClose();
25
25
  }, children: _jsxs(DialogContent, { className: "max-h-[85vh] max-w-2xl overflow-y-auto", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: name.replace(/-/g, " ") }), _jsx(DialogDescription, { children: triggerSummary })] }), _jsxs("div", { className: "space-y-4", children: [lastError ? (_jsxs("div", { className: "flex items-start gap-2 rounded-md border border-destructive/30 bg-destructive/5 p-2.5", children: [_jsx(IconAlertTriangle, { className: "mt-0.5 size-4 shrink-0 text-destructive" }), _jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "text-xs font-medium text-destructive", children: t("jobs.blockedTitle", {
26
26
  defaultValue: "This automation is not running",
27
- }) }), _jsx("p", { className: "mt-0.5 break-words text-xs text-muted-foreground", children: lastError })] })] })) : null, _jsx("dl", { className: "grid grid-cols-2 gap-x-4 gap-y-2", children: fields.map((field) => (_jsxs("div", { className: "min-w-0", children: [_jsx("dt", { className: "text-[11px] uppercase tracking-wide text-muted-foreground/70", children: field.label }), _jsx("dd", { className: `mt-0.5 break-words text-sm ${field.mono ? "font-mono text-xs" : ""}`, children: field.value })] }, field.label))) }), condition ? (_jsxs("div", { children: [_jsx("p", { className: "text-xs font-medium text-foreground", children: t("jobs.condition", { defaultValue: "Condition" }) }), _jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: condition })] })) : null, _jsxs("div", { children: [_jsx("p", { className: "text-xs font-medium text-foreground", children: t("jobs.instructions", { defaultValue: "Instructions" }) }), _jsx("p", { className: "mt-1 max-h-56 overflow-y-auto whitespace-pre-wrap rounded-md bg-muted/50 p-2.5 text-sm text-muted-foreground", children: instructions })] }), mcpTools.length > 0 ? (_jsxs("div", { children: [_jsx("p", { className: "text-xs font-medium text-foreground", children: t("jobs.mcpTools", { defaultValue: "Connected MCP tools" }) }), _jsx("div", { className: "mt-1 flex flex-wrap gap-1.5", children: mcpTools.map((toolName) => (_jsx("code", { className: "rounded bg-muted px-1.5 py-0.5 text-[11px] text-muted-foreground", children: toolName }, toolName))) })] })) : null, _jsxs("div", { children: [_jsx("p", { className: "text-xs font-medium text-foreground", children: t("jobs.pastRuns", { defaultValue: "Past runs" }) }), runsQuery.isLoading ? (_jsxs("div", { className: "mt-2 flex items-center gap-2 text-xs text-muted-foreground", "aria-busy": "true", children: [_jsx(IconLoader2, { className: "size-3.5 animate-spin" }), t("jobs.loading", { defaultValue: "Loading…" })] })) : runsQuery.error ? (_jsx("p", { className: "mt-1 text-xs text-destructive", children: t("jobs.runsLoadError", {
27
+ }) }), _jsx("p", { className: "mt-0.5 break-words text-xs text-muted-foreground", children: lastError })] })] })) : null, _jsx("dl", { className: "grid grid-cols-2 gap-x-4 gap-y-2", children: fields.map((field) => (_jsxs("div", { className: "min-w-0", children: [_jsx("dt", { className: "text-[11px] uppercase tracking-wide text-muted-foreground/70", children: field.label }), _jsx("dd", { className: `mt-0.5 break-words text-sm ${field.mono ? "font-mono text-xs" : ""}`, children: field.value })] }, field.label))) }), condition ? (_jsxs("div", { children: [_jsx("p", { className: "text-xs font-medium text-foreground", children: t("jobs.condition", { defaultValue: "Condition" }) }), _jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: condition })] })) : null, _jsxs("div", { children: [_jsx("p", { className: "text-xs font-medium text-foreground", children: t("jobs.instructions", { defaultValue: "Instructions" }) }), _jsx("p", { className: "mt-1 max-h-56 overflow-y-auto whitespace-pre-wrap rounded-md bg-muted/50 p-2.5 text-sm text-muted-foreground", children: instructions })] }), mcpTools.length > 0 ? (_jsxs("div", { children: [_jsx("p", { className: "text-xs font-medium text-foreground", children: t("jobs.mcpTools", { defaultValue: "Connected agent tools" }) }), _jsx("div", { className: "mt-1 flex flex-wrap gap-1.5", children: mcpTools.map((toolName) => (_jsx("code", { className: "rounded bg-muted px-1.5 py-0.5 text-[11px] text-muted-foreground", children: toolName }, toolName))) })] })) : null, _jsxs("div", { children: [_jsx("p", { className: "text-xs font-medium text-foreground", children: t("jobs.pastRuns", { defaultValue: "Past runs" }) }), runsQuery.isLoading ? (_jsxs("div", { className: "mt-2 flex items-center gap-2 text-xs text-muted-foreground", "aria-busy": "true", children: [_jsx(IconLoader2, { className: "size-3.5 animate-spin" }), t("jobs.loading", { defaultValue: "Loading…" })] })) : runsQuery.error ? (_jsx("p", { className: "mt-1 text-xs text-destructive", children: t("jobs.runsLoadError", {
28
28
  defaultValue: "Could not load run history.",
29
29
  }) })) : runs.length === 0 ? (_jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: t("jobs.noRuns", {
30
30
  defaultValue: "This automation has not executed yet. Only real executions are recorded here.",
@@ -3,7 +3,7 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
3
3
  // LoopLimitContinueCard, BuilderConnectCta, BuilderSetupCard, ApiKeyConnect,
4
4
  // PlanModeCallout, and getLoopLimitMetadata / getRunErrorMetadata exports used
5
5
  // by AssistantChatInner.
6
- import { IconLoader2, IconCheck, IconCopy, IconX, IconChevronDown, IconExternalLink, IconGitFork, IconGauge, IconSettings, IconArrowRight, IconAlertTriangle, IconPlayerPlay, IconRefresh, IconPlus, IconClipboardList, } from "@tabler/icons-react";
6
+ import { IconLoader2, IconCheck, IconCopy, IconX, IconChevronDown, IconGitFork, IconGauge, IconSettings, IconArrowRight, IconAlertTriangle, IconPlayerPlay, IconRefresh, IconPlus, IconClipboardList, } from "@tabler/icons-react";
7
7
  import { useState, useEffect, useCallback, useRef } from "react";
8
8
  import { saveAgentEngineApiKey, } from "../agent-engine-key.js";
9
9
  import { agentNativePath } from "../api-path.js";
@@ -128,7 +128,7 @@ export function BuilderConnectCta({ variant = "primary", onConnected, }) {
128
128
  if (configured) {
129
129
  return (_jsxs("div", { className: containerClass, children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "text-xs font-medium text-foreground", children: "Builder.io" }), _jsx("p", { className: "text-[11px] text-muted-foreground mt-0.5", children: orgName ? `Connected — ${orgName}` : "Connected" })] }), _jsxs("span", { className: "ml-auto inline-flex items-center gap-1 shrink-0 rounded-md bg-emerald-500/10 px-2 py-0.5 text-[10px] font-medium text-emerald-500", children: [_jsx(IconCheck, { size: 10 }), "Connected"] })] }));
130
130
  }
131
- return (_jsxs("div", { className: containerClass, children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "text-xs font-medium text-foreground", children: "Connect Builder.io" }), _jsx("p", { className: "text-[11px] text-muted-foreground mt-0.5 max-w-[220px]", children: "Free credits for LLM, hosting, and more \u2014 no API key needed" }), error && _jsx("p", { className: "mt-1 text-[10px] text-destructive", children: error })] }), _jsx("button", { type: "button", onClick: () => start(), disabled: connecting, className: "ml-auto inline-flex items-center gap-1 shrink-0 rounded-md bg-foreground px-3 py-1.5 text-[11px] font-medium no-underline text-background hover:opacity-90 disabled:opacity-60 disabled:cursor-wait", "aria-busy": connecting, children: connecting ? (_jsxs(_Fragment, { children: [_jsx(IconLoader2, { size: 10, className: "animate-spin" }), "Waiting\u2026"] })) : (_jsxs(_Fragment, { children: ["Connect", _jsx(IconExternalLink, { size: 10 })] })) })] }));
131
+ return (_jsxs("div", { className: containerClass, children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "text-xs font-medium text-foreground", children: "Connect Builder.io" }), _jsx("p", { className: "text-[11px] text-muted-foreground mt-0.5 max-w-[220px]", children: "Free credits for LLM, hosting, and more \u2014 no API key needed" }), error && _jsx("p", { className: "mt-1 text-[10px] text-destructive", children: error })] }), _jsx("button", { type: "button", onClick: () => start(), disabled: connecting, className: "ml-auto inline-flex items-center gap-1 shrink-0 rounded-md bg-foreground px-3 py-1.5 text-[11px] font-medium no-underline text-background hover:opacity-90 disabled:opacity-60 disabled:cursor-wait", "aria-busy": connecting, children: connecting ? (_jsxs(_Fragment, { children: [_jsx(IconLoader2, { size: 10, className: "animate-spin" }), "Waiting\u2026"] })) : ("Connect") })] }));
132
132
  }
133
133
  // ─── ApiKeyConnect ────────────────────────────────────────────────────────────
134
134
  const API_KEY_PROVIDERS = [
@@ -277,7 +277,7 @@ export function RunErrorRecoveryCard({ info, onContinue, onRetry, onFork, onDism
277
277
  onDismiss();
278
278
  }
279
279
  }, [builderReconnectResolved, onDismiss]);
280
- return (_jsxs("div", { className: "rounded-lg border border-amber-500/25 bg-amber-500/[0.06] p-3 text-sm", children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx("span", { className: "mt-0.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-md bg-amber-500/10 text-amber-700 dark:text-amber-300", children: _jsx(IconAlertTriangle, { size: 14 }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "font-medium text-foreground", children: runErrorHeadline(info) }), _jsx("p", { className: "mt-1 text-xs leading-relaxed text-muted-foreground", children: info.message }), shouldShowBuilderReconnect && !builderReconnectResolved && (_jsx("p", { className: "mt-2 text-xs leading-relaxed text-muted-foreground", children: "The current Builder.io or model-provider credential was rejected. Reconnect Builder.io, then retry this message." })), isConnectionRecoveryError && (_jsx("p", { className: "mt-2 text-xs leading-relaxed text-muted-foreground", children: "If retry lands on the same error, start a new chat session and continue from what already changed." })), (info.runId || info.errorCode || info.details) && (_jsxs("button", { type: "button", onClick: () => setDetailsOpen((v) => !v), className: "mt-2 inline-flex items-center gap-1 text-[11px] font-medium text-muted-foreground hover:text-foreground", children: [_jsx(IconChevronDown, { size: 12, className: cn("transition-transform", detailsOpen && "rotate-180") }), "Details"] })), detailsOpen && (_jsxs("div", { className: "mt-2 rounded-md border border-border/60 bg-background/70 p-2 font-mono text-[11px] leading-relaxed text-muted-foreground", children: [info.runId && _jsxs("div", { children: ["run: ", info.runId] }), info.errorCode && _jsxs("div", { children: ["code: ", info.errorCode] }), info.details && (_jsx("pre", { className: "mt-2 max-h-28 overflow-auto whitespace-pre-wrap break-words font-mono", children: info.details }))] }))] }), _jsx("button", { type: "button", onClick: onDismiss, "aria-label": "Dismiss", className: "flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-background/80 hover:text-foreground", children: _jsx(IconX, { size: 14 }) })] }), _jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-2", children: [shouldShowBuilderReconnect && !builderReconnectResolved && (_jsxs("button", { type: "button", onClick: () => builderReconnect.start(), disabled: builderReconnect.connecting, className: "inline-flex h-8 items-center gap-1.5 rounded-md bg-foreground px-3 text-xs font-medium text-background hover:opacity-90 disabled:cursor-wait disabled:opacity-70", children: [builderReconnect.connecting ? (_jsx(IconLoader2, { size: 13, className: "animate-spin" })) : (_jsx(IconExternalLink, { size: 13 })), builderReconnect.connecting
280
+ return (_jsxs("div", { className: "rounded-lg border border-amber-500/25 bg-amber-500/[0.06] p-3 text-sm", children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx("span", { className: "mt-0.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-md bg-amber-500/10 text-amber-700 dark:text-amber-300", children: _jsx(IconAlertTriangle, { size: 14 }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "font-medium text-foreground", children: runErrorHeadline(info) }), _jsx("p", { className: "mt-1 text-xs leading-relaxed text-muted-foreground", children: info.message }), shouldShowBuilderReconnect && !builderReconnectResolved && (_jsx("p", { className: "mt-2 text-xs leading-relaxed text-muted-foreground", children: "The current Builder.io or model-provider credential was rejected. Reconnect Builder.io, then retry this message." })), isConnectionRecoveryError && (_jsx("p", { className: "mt-2 text-xs leading-relaxed text-muted-foreground", children: "If retry lands on the same error, start a new chat session and continue from what already changed." })), (info.runId || info.errorCode || info.details) && (_jsxs("button", { type: "button", onClick: () => setDetailsOpen((v) => !v), className: "mt-2 inline-flex items-center gap-1 text-[11px] font-medium text-muted-foreground hover:text-foreground", children: [_jsx(IconChevronDown, { size: 12, className: cn("transition-transform", detailsOpen && "rotate-180") }), "Details"] })), detailsOpen && (_jsxs("div", { className: "mt-2 rounded-md border border-border/60 bg-background/70 p-2 font-mono text-[11px] leading-relaxed text-muted-foreground", children: [info.runId && _jsxs("div", { children: ["run: ", info.runId] }), info.errorCode && _jsxs("div", { children: ["code: ", info.errorCode] }), info.details && (_jsx("pre", { className: "mt-2 max-h-28 overflow-auto whitespace-pre-wrap break-words font-mono", children: info.details }))] }))] }), _jsx("button", { type: "button", onClick: onDismiss, "aria-label": "Dismiss", className: "flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-background/80 hover:text-foreground", children: _jsx(IconX, { size: 14 }) })] }), _jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-2", children: [shouldShowBuilderReconnect && !builderReconnectResolved && (_jsxs("button", { type: "button", onClick: () => builderReconnect.start(), disabled: builderReconnect.connecting, className: "inline-flex h-8 items-center gap-1.5 rounded-md bg-foreground px-3 text-xs font-medium text-background hover:opacity-90 disabled:cursor-wait disabled:opacity-70", children: [builderReconnect.connecting ? (_jsx(IconLoader2, { size: 13, className: "animate-spin" })) : null, builderReconnect.connecting
281
281
  ? "Connecting Builder.io"
282
282
  : "Reconnect Builder.io"] })), canRecover && (_jsxs(_Fragment, { children: [_jsxs("button", { type: "button", onClick: onContinue, className: "inline-flex h-8 items-center gap-1.5 rounded-md bg-foreground px-3 text-xs font-medium text-background hover:opacity-90", children: [_jsx(IconPlayerPlay, { size: 13 }), "Continue"] }), _jsxs("button", { type: "button", onClick: onRetry, className: "inline-flex h-8 items-center gap-1.5 rounded-md border border-border bg-background px-3 text-xs font-medium text-foreground hover:bg-accent", children: [_jsx(IconRefresh, { size: 13 }), isQueryError ? "Diagnose and retry" : "Retry"] })] })), canRecover && isConnectionRecoveryError && (_jsxs("button", { type: "button", onClick: startNewChat, className: "inline-flex h-8 items-center gap-1.5 rounded-md border border-border bg-background px-3 text-xs font-medium text-foreground hover:bg-accent", children: [_jsx(IconPlus, { size: 13 }), "New chat"] })), canRecover && onFork && !isConnectionRecoveryError && (_jsxs("button", { type: "button", onClick: handleFork, disabled: forking, title: "Fork this conversation into a separate chat thread.", "aria-label": "Fork this conversation into a separate chat thread", className: "inline-flex h-8 items-center gap-1.5 rounded-md border border-border bg-background px-3 text-xs font-medium text-foreground hover:bg-accent disabled:cursor-wait disabled:opacity-70", children: [forking ? (_jsx(IconLoader2, { size: 13, className: "animate-spin" })) : (_jsx(IconGitFork, { size: 13 })), forking ? "Forking..." : "Fork chat"] })), _jsxs("button", { type: "button", onClick: copyDetails, className: "ml-auto inline-flex h-8 items-center gap-1.5 rounded-md px-2.5 text-xs font-medium text-muted-foreground hover:bg-background/80 hover:text-foreground", children: [copyState === "copied" ? (_jsx(IconCheck, { size: 13 })) : copyState === "failed" ? (_jsx(IconX, { size: 13 })) : (_jsx(IconCopy, { size: 13 })), _jsx("span", { "aria-live": "polite", children: copyState === "copied"
283
283
  ? "Copied"
@@ -115,7 +115,7 @@ export function normalizeChatError(errorMessage, errorCode) {
115
115
  }
116
116
  if (isProviderAuthenticationError(text, errorCode)) {
117
117
  return {
118
- message: "The model provider rejected the saved API key. Update the key in API Keys & Connections, then retry.",
118
+ message: "The model provider rejected the saved API key. Update the key in Settings Integrations → API keys, then retry.",
119
119
  details: text,
120
120
  };
121
121
  }
@@ -1,3 +1,4 @@
1
1
  import React from "react";
2
+ export declare function LegacyIntegrationsPanel(): React.JSX.Element;
2
3
  export declare function IntegrationsPanel(): React.JSX.Element;
3
4
  //# sourceMappingURL=IntegrationsPanel.d.ts.map