@agent-native/core 0.154.4 → 0.155.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.
Files changed (207) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/account-health/SKILL.md +76 -0
  3. package/corpus/templates/analytics/.agents/skills/bigquery/SKILL.md +3 -0
  4. package/corpus/templates/analytics/.agents/skills/cross-source-analysis/SKILL.md +2 -1
  5. package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +6 -5
  6. package/corpus/templates/analytics/AGENTS.md +3 -0
  7. package/corpus/templates/analytics/actions/account-deep-dive.ts +3 -2
  8. package/corpus/templates/analytics/actions/bigquery.ts +1 -1
  9. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +4 -1
  10. package/corpus/templates/analytics/app/components/layout/NewDashboardDialog.tsx +1 -0
  11. package/corpus/templates/analytics/app/pages/adhoc/explorer/components/PropertyCombobox.tsx +12 -4
  12. package/corpus/templates/analytics/app/pages/adhoc/explorer/components/PropertyValueCombobox.tsx +5 -2
  13. package/corpus/templates/analytics/app/pages/adhoc/explorer/property-label.ts +32 -0
  14. package/corpus/templates/analytics/changelog/2026-08-13-account-health-readouts-verify-customer-scope-and-contract-metrics.md +7 -0
  15. package/corpus/templates/analytics/server/jobs/analytics-bigquery-backfill.ts +43 -17
  16. package/corpus/templates/analytics/server/lib/analytics-query-catalog.ts +17 -0
  17. package/corpus/templates/analytics/server/plugins/agent-chat.ts +4 -0
  18. package/corpus/templates/calendar/AGENTS.md +2 -0
  19. package/corpus/templates/calendar/DEVELOPING.md +4 -4
  20. package/corpus/templates/calendar/actions/get-settings.ts +4 -11
  21. package/corpus/templates/calendar/actions/update-availability.ts +15 -4
  22. package/corpus/templates/calendar/actions/update-settings.ts +15 -4
  23. package/corpus/templates/calendar/app/components/booking/DatePicker.tsx +9 -3
  24. package/corpus/templates/calendar/app/components/calendar/CreateEventDialog.tsx +21 -19
  25. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +9 -6
  26. package/corpus/templates/calendar/app/components/calendar/FindTimePanel.tsx +25 -3
  27. package/corpus/templates/calendar/app/components/calendar/InlineEventPickers.tsx +10 -3
  28. package/corpus/templates/calendar/app/components/calendar/MonthView.tsx +9 -9
  29. package/corpus/templates/calendar/app/components/calendar/WeekView.tsx +11 -3
  30. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +10 -4
  31. package/corpus/templates/calendar/app/i18n-data.ts +30 -0
  32. package/corpus/templates/calendar/app/lib/availability-schedule.ts +53 -0
  33. package/corpus/templates/calendar/app/lib/event-form-utils.ts +5 -0
  34. package/corpus/templates/calendar/app/pages/AvailabilitySettings.tsx +90 -28
  35. package/corpus/templates/calendar/app/pages/BookingLinksPage.tsx +135 -61
  36. package/corpus/templates/calendar/app/pages/BookingPage.tsx +2 -0
  37. package/corpus/templates/calendar/app/pages/CalendarView.tsx +30 -15
  38. package/corpus/templates/calendar/app/pages/Settings.tsx +60 -1
  39. package/corpus/templates/calendar/changelog/2026-08-13-find-a-time-now-closes-from-a-clear-header-action.md +6 -0
  40. package/corpus/templates/calendar/server/handlers/bookings.ts +2 -1
  41. package/corpus/templates/calendar/server/handlers/settings.ts +12 -16
  42. package/corpus/templates/calendar/shared/api.ts +1 -0
  43. package/corpus/templates/calendar/shared/availability-schedule.ts +64 -0
  44. package/corpus/templates/calendar/shared/calendar-week.ts +21 -0
  45. package/corpus/templates/calendar/shared/settings.ts +44 -0
  46. package/corpus/templates/clips/AGENTS.md +2 -0
  47. package/corpus/templates/clips/actions/add-comment.ts +5 -2
  48. package/corpus/templates/clips/actions/finalize-recording.ts +31 -1
  49. package/corpus/templates/clips/actions/get-recording-player-data.ts +9 -0
  50. package/corpus/templates/clips/actions/lib/ensure-seekable-video.ts +21 -1
  51. package/corpus/templates/clips/actions/reply-to-comment.ts +5 -2
  52. package/corpus/templates/clips/actions/update-comment.ts +9 -2
  53. package/corpus/templates/clips/app/components/library/search-bar.tsx +26 -13
  54. package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +135 -3
  55. package/corpus/templates/clips/app/components/player/comments-panel.tsx +5 -99
  56. package/corpus/templates/clips/app/components/player/playback-comment-overlay.tsx +7 -3
  57. package/corpus/templates/clips/app/components/player/video-player.tsx +84 -24
  58. package/corpus/templates/clips/app/components/workspace/notifications-list.tsx +11 -3
  59. package/corpus/templates/clips/app/i18n/en-US.ts +12 -0
  60. package/corpus/templates/clips/app/lib/public-meeting.ts +11 -3
  61. package/corpus/templates/clips/app/lib/search-focus.ts +15 -0
  62. package/corpus/templates/clips/app/root.tsx +2 -1
  63. package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +94 -26
  64. package/corpus/templates/clips/app/routes/_app.settings._index.tsx +24 -7
  65. package/corpus/templates/clips/app/routes/embed.$shareId.tsx +8 -4
  66. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +14 -7
  67. package/corpus/templates/clips/app/routes/share.$shareId.tsx +8 -4
  68. package/corpus/templates/clips/app/routes/share.meeting.$meetingId.tsx +72 -26
  69. package/corpus/templates/clips/changelog/2026-08-13-inline-markdown-comments.md +6 -0
  70. package/corpus/templates/clips/changelog/2026-08-13-private-meeting-agent-links.md +6 -0
  71. package/corpus/templates/clips/desktop/src/app.tsx +116 -19
  72. package/corpus/templates/clips/desktop/src/lib/recorder.ts +13 -29
  73. package/corpus/templates/clips/desktop/src/lib/recording-request.ts +39 -0
  74. package/corpus/templates/clips/desktop/src/lib/settings-navigation.ts +11 -0
  75. package/corpus/templates/clips/desktop/src/lib/whisper-model-picker.ts +7 -0
  76. package/corpus/templates/clips/desktop/src/styles.css +117 -0
  77. package/corpus/templates/clips/server/db/index.ts +10 -0
  78. package/corpus/templates/clips/server/db/schema.ts +1 -0
  79. package/corpus/templates/clips/server/lib/recordings.ts +3 -1
  80. package/corpus/templates/clips/server/lib/seekable-media-state.ts +90 -0
  81. package/corpus/templates/clips/server/plugins/db.ts +5 -0
  82. package/corpus/templates/clips/server/routes/api/public-meeting.get.ts +37 -4
  83. package/corpus/templates/clips/server/routes/api/public-recording.get.ts +16 -5
  84. package/corpus/templates/clips/shared/clips-ai-prefs.ts +3 -0
  85. package/corpus/templates/clips/shared/meeting-agent-access.ts +5 -0
  86. package/corpus/templates/content/.agents/skills/content/SKILL.md +2 -2
  87. package/corpus/templates/content/.agents/skills/document-editing/references/databases.md +20 -4
  88. package/corpus/templates/content/actions/_database-row-mutation.ts +1490 -0
  89. package/corpus/templates/content/actions/_database-utils.ts +44 -0
  90. package/corpus/templates/content/actions/_property-utils.ts +4 -1
  91. package/corpus/templates/content/actions/add-comment.ts +2 -1
  92. package/corpus/templates/content/actions/add-database-item.ts +62 -240
  93. package/corpus/templates/content/actions/configure-document-property.ts +165 -1
  94. package/corpus/templates/content/actions/delete-document-property.ts +18 -0
  95. package/corpus/templates/content/actions/set-document-property.ts +78 -1
  96. package/corpus/templates/content/actions/update-comment.ts +1 -1
  97. package/corpus/templates/content/actions/update-database-item.ts +62 -0
  98. package/corpus/templates/content/actions/upsert-database-item-by-key.ts +43 -796
  99. package/corpus/templates/content/app/components/editor/CommentsSidebar.tsx +24 -15
  100. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +10 -8
  101. package/corpus/templates/content/app/hooks/use-content-database.ts +33 -32
  102. package/corpus/templates/content/changelog/2026-08-10-database-row-actions-now-validate-exact-schemas-and-safe-ret.md +6 -0
  103. package/corpus/templates/content/parity/matrix.md +1 -1
  104. package/corpus/templates/content/parity/matrix.ts +2 -0
  105. package/corpus/templates/content/server/db/schema.ts +39 -3
  106. package/corpus/templates/content/server/plugins/db.ts +30 -0
  107. package/corpus/templates/content/shared/api.ts +75 -2
  108. package/corpus/templates/design/actions/generate-design.ts +10 -7
  109. package/corpus/templates/design/actions/present-design-variants.ts +35 -6
  110. package/corpus/templates/design/actions/run-design-audit.ts +33 -0
  111. package/corpus/templates/design/changelog/2026-08-13-the-design-audit-now-catches-a-screen-that-renders-behind-an.md +6 -0
  112. package/corpus/templates/design/shared/design-review.ts +1 -0
  113. package/corpus/templates/design/shared/html-integrity.ts +66 -0
  114. package/corpus/templates/dispatch/.env.example +5 -0
  115. package/corpus/templates/dispatch/AGENTS.md +24 -19
  116. package/corpus/templates/dispatch/app/i18n-data.ts +20 -0
  117. package/corpus/templates/dispatch/server/lib/identity-sso.ts +21 -90
  118. package/corpus/templates/dispatch/server/plugins/identity-sso.ts +3 -12
  119. package/corpus/templates/dispatch/shared/feature-flags.ts +4 -0
  120. package/corpus/templates/factory/AGENTS.md +5 -1
  121. package/corpus/templates/factory/README.md +23 -0
  122. package/corpus/templates/factory/actions/view-screen.ts +17 -0
  123. package/corpus/templates/factory/app/components/factory/FactoryAgentsView.tsx +239 -0
  124. package/corpus/templates/factory/app/components/factory/FactoryCanvas.tsx +2 -0
  125. package/corpus/templates/factory/app/components/factory/FactoryInspector.tsx +130 -7
  126. package/corpus/templates/factory/app/i18n/en-US.ts +20 -0
  127. package/corpus/templates/factory/app/routes/factory.tsx +41 -0
  128. package/corpus/templates/factory/package.json +1 -0
  129. package/corpus/templates/factory/server/factory-graph/contracts.ts +2 -0
  130. package/corpus/templates/factory/server/plugins/agent-chat.ts +9 -0
  131. package/corpus/templates/factory/server/plugins/dispatch-db.ts +1 -0
  132. package/corpus/templates/factory/server/plugins/setup-dispatch.ts +3 -0
  133. package/corpus/templates/mail/app/lib/native-mcp-exclusions.ts +3 -0
  134. package/corpus/templates/mail/vite.config.ts +7 -0
  135. package/corpus/templates/plan/actions/reply-to-plan-comment.ts +7 -2
  136. package/corpus/templates/plan/actions/resolve-plan-comment.ts +2 -2
  137. package/corpus/templates/plan/actions/update-visual-plan.ts +1 -1
  138. package/corpus/templates/plan/app/pages/PlansPage.tsx +29 -20
  139. package/corpus/templates/slides/actions/add-slide-comment.ts +1 -1
  140. package/corpus/templates/slides/actions/update-slide-comment.ts +1 -1
  141. package/corpus/templates/slides/app/components/comments/SlideCommentsPanel.tsx +9 -6
  142. package/dist/action.d.ts +22 -0
  143. package/dist/action.js +27 -0
  144. package/dist/agent/production-agent.js +5 -1
  145. package/dist/agent/thread-data-builder.js +17 -1
  146. package/dist/cli/skills-content/help.js +6 -4
  147. package/dist/cli/skills.js +17 -2
  148. package/dist/cli/workspacify.d.ts +5 -0
  149. package/dist/cli/workspacify.js +65 -8
  150. package/dist/client/AgentPanel.d.ts +5 -0
  151. package/dist/client/AgentPanel.js +20 -4
  152. package/dist/client/AssistantChat.d.ts +21 -0
  153. package/dist/client/AssistantChat.js +66 -68
  154. package/dist/client/active-run-state.d.ts +14 -1
  155. package/dist/client/active-run-state.js +0 -0
  156. package/dist/client/agent-chat-adapter.js +107 -5
  157. package/dist/client/analytics.js +9 -2
  158. package/dist/client/chat/tool-call-display.js +4 -4
  159. package/dist/client/chat-first/apps-rail.js +9 -4
  160. package/dist/client/chat-first/primary-nav.d.ts +2 -1
  161. package/dist/client/chat-first/primary-nav.js +3 -3
  162. package/dist/client/chat-first/types.d.ts +5 -1
  163. package/dist/client/markdown/InlineMarkdown.d.ts +23 -0
  164. package/dist/client/markdown/InlineMarkdown.js +65 -0
  165. package/dist/client/markdown/index.d.ts +1 -0
  166. package/dist/client/markdown/index.js +1 -0
  167. package/dist/client/review/ReviewThreadPanel.js +2 -1
  168. package/dist/client/run-stream-ownership.d.ts +39 -0
  169. package/dist/client/run-stream-ownership.js +65 -0
  170. package/dist/collab/routes.d.ts +1 -1
  171. package/dist/collab/struct-routes.d.ts +1 -1
  172. package/dist/feature-flags/index.d.ts +1 -1
  173. package/dist/feature-flags/index.js +1 -1
  174. package/dist/feature-flags/store.d.ts +10 -0
  175. package/dist/feature-flags/store.js +112 -1
  176. package/dist/guards/no-env-credentials.js +4 -0
  177. package/dist/index.browser.d.ts +1 -1
  178. package/dist/index.browser.js +1 -1
  179. package/dist/index.d.ts +2 -2
  180. package/dist/index.js +2 -2
  181. package/dist/integrations/adapters/slack.js +5 -1
  182. package/dist/localization/default-messages.d.ts +1 -0
  183. package/dist/localization/default-messages.js +1 -0
  184. package/dist/notifications/routes.d.ts +1 -1
  185. package/dist/observability/routes.d.ts +1 -1
  186. package/dist/progress/routes.d.ts +1 -1
  187. package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
  188. package/dist/provider-api/actions/provider-api.d.ts +15 -15
  189. package/dist/resources/agents.js +40 -5
  190. package/dist/resources/handlers.d.ts +1 -1
  191. package/dist/resources/metadata.d.ts +10 -0
  192. package/dist/resources/metadata.js +7 -3
  193. package/dist/review/actions/create-review-comment.js +1 -1
  194. package/dist/review/actions/reply-review-comment.js +1 -1
  195. package/dist/review/actions/resolve-review-thread.js +1 -1
  196. package/dist/server/action-routes.js +42 -8
  197. package/dist/server/agent-discovery.js +14 -3
  198. package/dist/server/core-routes-plugin.js +1 -1
  199. package/dist/server/identity-sso-migrations.d.ts +7 -0
  200. package/dist/server/identity-sso-migrations.js +36 -0
  201. package/dist/server/identity-sso-store.d.ts +3 -2
  202. package/dist/server/identity-sso-store.js +8 -3
  203. package/dist/server/realtime-token.d.ts +1 -1
  204. package/dist/server/release-migrations.js +4 -0
  205. package/dist/tracking/providers.js +13 -3
  206. package/dist/workspace-files/tool.js +1 -1
  207. package/package.json +3 -2
@@ -1,13 +1,13 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { IconClock, IconPlus, IconPlugConnected, IconSearch, } from "@tabler/icons-react";
3
3
  import { defaultChatFirstCopy } from "./copy.js";
4
- export function ChatFirstPrimaryNavigation({ onNewChat, onOpenIntegrations, onOpenScheduled, onSearch, activeTab, stickyNewChat = false, copy = defaultChatFirstCopy, }) {
4
+ export function ChatFirstPrimaryNavigation({ onNewChat, onOpenIntegrations, onOpenScheduled, onSearch, activeTab, collapsed = false, stickyNewChat = false, copy = defaultChatFirstCopy, }) {
5
5
  const tabClassName = (tab) => `flex h-8 w-full items-center gap-2 rounded-md px-2 text-[13px] font-medium transition-[background-color,color] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ${activeTab === tab
6
6
  ? "bg-sidebar-accent text-sidebar-accent-foreground"
7
7
  : "text-sidebar-foreground/80 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground"}`;
8
- const renderTab = (tab, content, onSelect, className) => (_jsx("button", { type: "button", role: "tab", "aria-selected": activeTab === tab, className: [tabClassName(tab), className].filter(Boolean).join(" "), onClick: onSelect, children: content }));
8
+ const renderTab = (tab, content, onSelect, className) => (_jsx("button", { type: "button", role: "tab", "aria-selected": activeTab === tab, "aria-label": tab === "new-chat" ? copy("newChat") : undefined, title: tab === "new-chat" && collapsed ? copy("newChat") : undefined, className: [tabClassName(tab), className].filter(Boolean).join(" "), onClick: onSelect, children: content }));
9
9
  const newChatTab = onNewChat
10
- ? renderTab("new-chat", _jsxs(_Fragment, { children: [_jsx(IconPlus, { size: 15, className: "shrink-0", "aria-hidden": "true" }), _jsx("span", { children: copy("newChat") })] }), onNewChat, "code-agents-primary-new-chat")
10
+ ? renderTab("new-chat", _jsxs(_Fragment, { children: [_jsx(IconPlus, { size: 15, className: "shrink-0", "aria-hidden": "true" }), _jsx("span", { className: collapsed ? "sr-only" : undefined, children: copy("newChat") })] }), onNewChat, "code-agents-primary-new-chat")
11
11
  : null;
12
12
  const integrationsTab = renderTab("integrations", _jsxs(_Fragment, { children: [_jsx(IconPlugConnected, { size: 15, className: "shrink-0", "aria-hidden": "true" }), _jsx("span", { children: copy("integrations") })] }), onOpenIntegrations);
13
13
  const scheduledTab = renderTab("scheduled", _jsxs(_Fragment, { children: [_jsx(IconClock, { size: 15, className: "shrink-0", "aria-hidden": "true" }), _jsx("span", { children: copy("scheduled") })] }), onOpenScheduled);
@@ -8,6 +8,10 @@ export interface ChatFirstAppItem {
8
8
  color?: string;
9
9
  }
10
10
  export type ChatFirstCopy = (key: string, values?: Record<string, string>) => string;
11
+ export interface ChatFirstAppIconRenderOptions {
12
+ isActive: boolean;
13
+ isInactive: boolean;
14
+ }
11
15
  export interface ChatFirstEmbedTarget {
12
16
  url: string;
13
17
  title?: string;
@@ -51,7 +55,7 @@ export interface ChatFirstAppRailProps {
51
55
  onOpenAllApps?: () => void;
52
56
  onCreateApp?: () => void;
53
57
  createAppTrigger?: ReactNode;
54
- renderIcon: (app: ChatFirstAppItem) => ReactNode;
58
+ renderIcon: (app: ChatFirstAppItem, options?: ChatFirstAppIconRenderOptions) => ReactNode;
55
59
  copy?: ChatFirstCopy;
56
60
  }
57
61
  export interface ChatFirstBrowserPaneProps {
@@ -0,0 +1,23 @@
1
+ import type { ReactNode } from "react";
2
+ export interface InlineMarkdownProps {
3
+ content: string;
4
+ className?: string;
5
+ linkClassName?: string;
6
+ codeClassName?: string;
7
+ inline?: boolean;
8
+ protectedSpans?: readonly InlineMarkdownProtectedSpan[];
9
+ renderProtectedSpan?: (span: InlineMarkdownProtectedSpan, children: ReactNode) => ReactNode;
10
+ }
11
+ export interface InlineMarkdownProtectedSpan {
12
+ source: string;
13
+ label: string;
14
+ className?: string;
15
+ title?: string;
16
+ }
17
+ /**
18
+ * Render user-authored Markdown for compact text surfaces.
19
+ *
20
+ * This intentionally has no block-level Markdown elements: headings, lists,
21
+ * quotes, and raw HTML are either flattened to their text or omitted.
22
+ */
23
+ export declare function InlineMarkdown({ content, className, linkClassName, codeClassName, inline, protectedSpans, renderProtectedSpan, }: InlineMarkdownProps): import("react").JSX.Element;
@@ -0,0 +1,65 @@
1
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
+ import ReactMarkdown, { defaultUrlTransform, } from "react-markdown";
3
+ import remarkGfm from "remark-gfm";
4
+ import { cn } from "../utils.js";
5
+ const INLINE_MARKDOWN_ELEMENTS = [
6
+ "a",
7
+ "br",
8
+ "code",
9
+ "del",
10
+ "em",
11
+ "p",
12
+ "s",
13
+ "strong",
14
+ ];
15
+ /**
16
+ * Render user-authored Markdown for compact text surfaces.
17
+ *
18
+ * This intentionally has no block-level Markdown elements: headings, lists,
19
+ * quotes, and raw HTML are either flattened to their text or omitted.
20
+ */
21
+ export function InlineMarkdown({ content, className, linkClassName, codeClassName, inline = false, protectedSpans = [], renderProtectedSpan, }) {
22
+ const protectedSpanByHref = new Map(protectedSpans
23
+ .map((span, index) => [`${PROTECTED_SPAN_PREFIX}${index}`, span])
24
+ .filter(([, span]) => span.source.length > 0));
25
+ const renderedContent = protectInlineMarkdownSpans(content, protectedSpans);
26
+ const components = {
27
+ a: ({ children, href }) => {
28
+ const protectedSpan = href ? protectedSpanByHref.get(href) : undefined;
29
+ if (protectedSpan) {
30
+ return renderProtectedSpan ? (renderProtectedSpan(protectedSpan, children)) : (_jsx("span", { className: protectedSpan.className, title: protectedSpan.title, children: children }));
31
+ }
32
+ const safeHref = href
33
+ ? defaultUrlTransform(normalizeInlineMarkdownHref(href))
34
+ : "";
35
+ if (!safeHref)
36
+ return _jsx(_Fragment, { children: children });
37
+ return (_jsx("a", { href: safeHref, target: "_blank", rel: "noopener noreferrer", className: cn("text-primary underline-offset-2 hover:underline", linkClassName), children: children }));
38
+ },
39
+ code: ({ children, className: syntaxClassName }) => (_jsx("code", { className: cn("rounded bg-muted px-1 py-0.5 font-mono text-[0.9em]", syntaxClassName, codeClassName), children: children })),
40
+ p: ({ children }) => inline ? _jsx("span", { children: children }) : _jsx("p", { className: "m-0", children: children }),
41
+ };
42
+ const Root = inline ? "span" : "div";
43
+ return (_jsx(Root, { className: cn("whitespace-pre-wrap break-words", className), children: _jsx(ReactMarkdown, { allowedElements: INLINE_MARKDOWN_ELEMENTS, components: components, remarkPlugins: [remarkGfm], skipHtml: true, unwrapDisallowed: true, children: renderedContent }) }));
44
+ }
45
+ const PROTECTED_SPAN_PREFIX = "https://inline-markdown-protected.invalid/span/";
46
+ function protectInlineMarkdownSpans(content, spans) {
47
+ return [...spans]
48
+ .map((span, index) => ({ span, index }))
49
+ .filter(({ span }) => span.source.length > 0)
50
+ .sort((a, b) => b.span.source.length - a.span.source.length)
51
+ .reduce((markdown, { span, index }) => markdown
52
+ .split(span.source)
53
+ .join(`[${escapeProtectedSpanLabel(span.label)}](${PROTECTED_SPAN_PREFIX}${index})`), content);
54
+ }
55
+ function escapeProtectedSpanLabel(label) {
56
+ return label.replace(/[\\[\]]/g, "\\$&");
57
+ }
58
+ function normalizeInlineMarkdownHref(href) {
59
+ if (/^www\./i.test(href))
60
+ return `https://${href}`;
61
+ if (/^http:\/\/www\./i.test(href)) {
62
+ return `https://${href.slice("http://".length)}`;
63
+ }
64
+ return href;
65
+ }
@@ -0,0 +1 @@
1
+ export { InlineMarkdown, type InlineMarkdownProtectedSpan, type InlineMarkdownProps, } from "./InlineMarkdown.js";
@@ -0,0 +1 @@
1
+ export { InlineMarkdown, } from "./InlineMarkdown.js";
@@ -8,6 +8,7 @@ import { Spinner } from "@agent-native/toolkit/ui/spinner";
8
8
  import { IconCircleCheck, IconDots, IconMessageCircle, IconSend, IconTrash, IconX, } from "@tabler/icons-react";
9
9
  import { useMemo, useState } from "react";
10
10
  import { useFormatters } from "../i18n.js";
11
+ import { InlineMarkdown } from "../markdown/index.js";
11
12
  import { cn } from "../utils.js";
12
13
  import { ReviewCommentComposer } from "./ReviewCommentComposer.js";
13
14
  import { ReviewStatusBadge } from "./ReviewStatusBadge.js";
@@ -126,7 +127,7 @@ function CommentBubble({ comment, compact = false, resolvedLabel, reviewerLabel,
126
127
  const bodyIsResolutionNote = resolutionNote !== null &&
127
128
  resolutionNote === comment.body.trim() &&
128
129
  isResolutionNoteMetadata(comment.metadata);
129
- return (_jsxs("div", { className: "flex min-w-0 items-start gap-2.5", children: [_jsx(Avatar, { className: compact ? "size-5" : "size-7", children: _jsx(AvatarFallback, { className: "text-[10px] font-semibold text-muted-foreground", children: authorInitials(author) }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx("span", { className: "truncate text-sm font-medium", children: author }), _jsx("time", { className: "shrink-0 text-[11px] text-muted-foreground", dateTime: comment.createdAt, children: formatCommentDate(comment.createdAt, formatDate) }), comment.status === "resolved" ? (_jsx("span", { className: "hidden shrink-0 rounded-full bg-muted px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground @xs/review:inline-flex", children: resolvedLabel })) : null] }), !bodyIsResolutionNote ? (_jsx("p", { className: cn("mt-1 whitespace-pre-wrap break-words text-foreground", compact ? "text-xs leading-5" : "text-sm leading-5"), children: comment.body })) : null, resolutionNote ? (_jsxs("div", { className: "mt-1.5 flex min-w-0 items-start gap-1.5 rounded-md bg-muted/60 px-2 py-1.5 text-muted-foreground", "aria-label": resolvedLabel, children: [_jsx(IconCircleCheck, { className: "mt-0.5 size-3.5 shrink-0" }), _jsx("p", { className: "min-w-0 whitespace-pre-wrap break-words text-xs leading-4", children: resolutionNote })] })) : null] })] }));
130
+ return (_jsxs("div", { className: "flex min-w-0 items-start gap-2.5", children: [_jsx(Avatar, { className: compact ? "size-5" : "size-7", children: _jsx(AvatarFallback, { className: "text-[10px] font-semibold text-muted-foreground", children: authorInitials(author) }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx("span", { className: "truncate text-sm font-medium", children: author }), _jsx("time", { className: "shrink-0 text-[11px] text-muted-foreground", dateTime: comment.createdAt, children: formatCommentDate(comment.createdAt, formatDate) }), comment.status === "resolved" ? (_jsx("span", { className: "hidden shrink-0 rounded-full bg-muted px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground @xs/review:inline-flex", children: resolvedLabel })) : null] }), !bodyIsResolutionNote ? (_jsx(InlineMarkdown, { content: comment.body, className: cn("mt-1 text-foreground", compact ? "text-xs leading-5" : "text-sm leading-5") })) : null, resolutionNote ? (_jsxs("div", { className: "mt-1.5 flex min-w-0 items-start gap-1.5 rounded-md bg-muted/60 px-2 py-1.5 text-muted-foreground", "aria-label": resolvedLabel, children: [_jsx(IconCircleCheck, { className: "mt-0.5 size-3.5 shrink-0" }), _jsx(InlineMarkdown, { content: resolutionNote, className: "min-w-0 text-xs leading-4" })] })) : null] })] }));
130
131
  }
131
132
  function capabilityAllowsThread(capability, thread) {
132
133
  return typeof capability === "function" ? capability(thread) : capability;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Exactly one SSE reader may fold a given run into UI state.
3
+ *
4
+ * Two readers attach to the same run routinely: the chat adapter's own stream,
5
+ * and AssistantChat's reconnect reader for runs with no live adapter stream
6
+ * (page reload, tab restore). When both are attached they build two independent
7
+ * accumulators from the same events, and the UI renders both — duplicate tool
8
+ * cards (one spinning, one static) and the same assistant text streaming twice.
9
+ *
10
+ * The previous guard read a React ref (`isRuntimeRunningRef`) at attach time and
11
+ * re-checked it from a 1s poll. That is a race, not a lock: the ref lags a
12
+ * render behind, the poll is skipped while the tab is hidden, and the refs were
13
+ * per-component-instance while MultiTabAssistantChat mounts several instances
14
+ * against one run. Ownership therefore lives here — module scope, one registry
15
+ * per browser tab, claimed and checked synchronously.
16
+ *
17
+ * Claims are advisory in one direction only: a reader that does not hold the
18
+ * claim must not mutate UI state. It may still drain its socket to completion.
19
+ */
20
+ /** Mint a token identifying one reader. Not shared between readers. */
21
+ export declare function createRunStreamToken(label?: string): symbol;
22
+ /**
23
+ * Take ownership of a run's UI fold. Returns false when another live reader
24
+ * already holds it — the caller must not attach, or must attach read-only.
25
+ * Re-claiming with the same token is a no-op success so retry loops are safe.
26
+ */
27
+ export declare function claimRunStream(threadId: string, runId: string, token: symbol): boolean;
28
+ /**
29
+ * Take ownership even if another reader holds it, and return whether the claim
30
+ * changed hands. The adapter's own stream outranks the reconnect fallback: when
31
+ * the user sends a message the adapter legitimately becomes the owner, and the
32
+ * displaced reader learns it lost via `ownsRunStream`.
33
+ */
34
+ export declare function preemptRunStream(threadId: string, runId: string, token: symbol): boolean;
35
+ export declare function ownsRunStream(threadId: string, runId: string, token: symbol): boolean;
36
+ /** Release only if still held by this token, so a late unmount cannot free a successor's claim. */
37
+ export declare function releaseRunStream(threadId: string, runId: string, token: symbol): void;
38
+ /** Test seam. */
39
+ export declare function __resetRunStreamOwnership(): void;
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Exactly one SSE reader may fold a given run into UI state.
3
+ *
4
+ * Two readers attach to the same run routinely: the chat adapter's own stream,
5
+ * and AssistantChat's reconnect reader for runs with no live adapter stream
6
+ * (page reload, tab restore). When both are attached they build two independent
7
+ * accumulators from the same events, and the UI renders both — duplicate tool
8
+ * cards (one spinning, one static) and the same assistant text streaming twice.
9
+ *
10
+ * The previous guard read a React ref (`isRuntimeRunningRef`) at attach time and
11
+ * re-checked it from a 1s poll. That is a race, not a lock: the ref lags a
12
+ * render behind, the poll is skipped while the tab is hidden, and the refs were
13
+ * per-component-instance while MultiTabAssistantChat mounts several instances
14
+ * against one run. Ownership therefore lives here — module scope, one registry
15
+ * per browser tab, claimed and checked synchronously.
16
+ *
17
+ * Claims are advisory in one direction only: a reader that does not hold the
18
+ * claim must not mutate UI state. It may still drain its socket to completion.
19
+ */
20
+ const owners = new Map();
21
+ function runKey(threadId, runId) {
22
+ return `${threadId} ${runId}`;
23
+ }
24
+ /** Mint a token identifying one reader. Not shared between readers. */
25
+ export function createRunStreamToken(label) {
26
+ return Symbol(label ?? "run-stream-reader");
27
+ }
28
+ /**
29
+ * Take ownership of a run's UI fold. Returns false when another live reader
30
+ * already holds it — the caller must not attach, or must attach read-only.
31
+ * Re-claiming with the same token is a no-op success so retry loops are safe.
32
+ */
33
+ export function claimRunStream(threadId, runId, token) {
34
+ const key = runKey(threadId, runId);
35
+ const current = owners.get(key);
36
+ if (current && current !== token)
37
+ return false;
38
+ owners.set(key, token);
39
+ return true;
40
+ }
41
+ /**
42
+ * Take ownership even if another reader holds it, and return whether the claim
43
+ * changed hands. The adapter's own stream outranks the reconnect fallback: when
44
+ * the user sends a message the adapter legitimately becomes the owner, and the
45
+ * displaced reader learns it lost via `ownsRunStream`.
46
+ */
47
+ export function preemptRunStream(threadId, runId, token) {
48
+ const key = runKey(threadId, runId);
49
+ const current = owners.get(key);
50
+ owners.set(key, token);
51
+ return current !== token;
52
+ }
53
+ export function ownsRunStream(threadId, runId, token) {
54
+ return owners.get(runKey(threadId, runId)) === token;
55
+ }
56
+ /** Release only if still held by this token, so a late unmount cannot free a successor's claim. */
57
+ export function releaseRunStream(threadId, runId, token) {
58
+ const key = runKey(threadId, runId);
59
+ if (owners.get(key) === token)
60
+ owners.delete(key);
61
+ }
62
+ /** Test seam. */
63
+ export function __resetRunStreamOwnership() {
64
+ owners.clear();
65
+ }
@@ -26,8 +26,8 @@ export declare const getCollabState: import("h3").EventHandlerWithFetch<import("
26
26
  * Body: { update: string (base64), requestSource?: string }
27
27
  */
28
28
  export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
29
- ok?: undefined;
30
29
  error: string;
30
+ ok?: undefined;
31
31
  } | {
32
32
  error?: undefined;
33
33
  ok: boolean;
@@ -13,8 +13,8 @@
13
13
  * Body: { json: any, fieldName?: string, type?: "map"|"array", requestSource?: string }
14
14
  */
15
15
  export declare const postCollabJson: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
16
- ok?: undefined;
17
16
  error: string;
17
+ ok?: undefined;
18
18
  } | {
19
19
  error?: undefined;
20
20
  ok: boolean;
@@ -1,4 +1,4 @@
1
1
  export { defineFeatureFlag, defineFeatureFlags, getFeatureFlagDefinition, listFeatureFlags, registerFeatureFlags, type FeatureFlagDefinition, } from "./registry.js";
2
- export { defaultFeatureFlagRules, evaluateFeatureFlag, evaluateFeatureFlagRules, isFeatureFlagEnabled, getFeatureFlagRules, normalizeFeatureFlagRules, type FeatureFlagMode, type FeatureFlagRules, type FeatureFlagScope, } from "./store.js";
2
+ export { defaultFeatureFlagRules, evaluateFeatureFlag, evaluateFeatureFlagRules, hasActiveFeatureFlagRollout, isFeatureFlagEnabled, getFeatureFlagRules, normalizeFeatureFlagRules, type FeatureFlagMode, type FeatureFlagRules, type FeatureFlagScope, } from "./store.js";
3
3
  export { createFeatureFlagsPlugin } from "./plugin.js";
4
4
  export { createFeatureFlagA2AActionRouteAuth } from "./a2a-action-route.js";
@@ -1,4 +1,4 @@
1
1
  export { defineFeatureFlag, defineFeatureFlags, getFeatureFlagDefinition, listFeatureFlags, registerFeatureFlags, } from "./registry.js";
2
- export { defaultFeatureFlagRules, evaluateFeatureFlag, evaluateFeatureFlagRules, isFeatureFlagEnabled, getFeatureFlagRules, normalizeFeatureFlagRules, } from "./store.js";
2
+ export { defaultFeatureFlagRules, evaluateFeatureFlag, evaluateFeatureFlagRules, hasActiveFeatureFlagRollout, isFeatureFlagEnabled, getFeatureFlagRules, normalizeFeatureFlagRules, } from "./store.js";
3
3
  export { createFeatureFlagsPlugin } from "./plugin.js";
4
4
  export { createFeatureFlagA2AActionRouteAuth } from "./a2a-action-route.js";
@@ -19,6 +19,16 @@ export declare const FEATURE_FLAG_SETTINGS_PREFIX = "feature-flag:";
19
19
  export declare function defaultFeatureFlagRules(): FeatureFlagRules;
20
20
  export declare function normalizeFeatureFlagRules(value: unknown): FeatureFlagRules;
21
21
  export declare function getFeatureFlagRules(key: string, scope: Pick<FeatureFlagScope, "orgId">): Promise<FeatureFlagRules>;
22
+ /**
23
+ * Anonymous discovery hint for a rollout that may be scoped to an org.
24
+ *
25
+ * This deliberately answers only whether some active rollout exists. It does
26
+ * not reveal the target email or organization, and callers must still run
27
+ * `evaluateFeatureFlag` with the authenticated scope before granting access.
28
+ * Without this separate hint, an org-only rollout is invisible to Desktop
29
+ * before the user has authenticated and the org can be resolved.
30
+ */
31
+ export declare function hasActiveFeatureFlagRollout(key: string): Promise<boolean>;
22
32
  /**
23
33
  * Atomically derive one flag's scoped rules. An org's first override starts
24
34
  * from the global fallback, then becomes independently CAS-protected.
@@ -1,10 +1,73 @@
1
+ import { getDbExec, isPostgres } from "../db/client.js";
1
2
  import { getOrgSetting, mutateOrgSetting } from "../settings/org-settings.js";
2
3
  import { getSetting, mutateSetting } from "../settings/store.js";
3
4
  import { getFeatureFlagDefinition, } from "./registry.js";
4
5
  export const FEATURE_FLAG_SETTINGS_PREFIX = "feature-flag:";
6
+ const FEATURE_FLAG_ROLLOUT_INDEX_PREFIX = "feature-flag-rollout-index:";
5
7
  function settingKey(key) {
6
8
  return `${FEATURE_FLAG_SETTINGS_PREFIX}${key}`;
7
9
  }
10
+ function rolloutIndexKey(key) {
11
+ return `${FEATURE_FLAG_ROLLOUT_INDEX_PREFIX}${key}`;
12
+ }
13
+ function parseStoredRules(value) {
14
+ if (typeof value === "string")
15
+ return normalizeFeatureFlagRules(JSON.parse(value));
16
+ return normalizeFeatureFlagRules(value);
17
+ }
18
+ function hasActiveRollout(rules) {
19
+ return (rules.mode === "on" ||
20
+ (rules.mode === "rules" &&
21
+ (rules.emails.length > 0 ||
22
+ rules.orgIds.length > 0 ||
23
+ rules.percentage > 0)));
24
+ }
25
+ function normalizeFeatureFlagRolloutIndex(value) {
26
+ if (!value || typeof value !== "object")
27
+ return null;
28
+ const raw = value;
29
+ const orgIds = Array.isArray(raw.orgIds)
30
+ ? [
31
+ ...new Set(raw.orgIds.filter((item) => typeof item === "string")),
32
+ ]
33
+ .map((orgId) => orgId.trim())
34
+ .filter(Boolean)
35
+ .sort()
36
+ : [];
37
+ return {
38
+ version: 1,
39
+ global: raw.global === true,
40
+ orgIds,
41
+ };
42
+ }
43
+ function activeFeatureFlagRolloutIndex(index) {
44
+ return index.global || index.orgIds.length > 0;
45
+ }
46
+ async function syncFeatureFlagRolloutIndex(key, scope, rules) {
47
+ const indexKey = rolloutIndexKey(key);
48
+ await mutateSetting(indexKey, async (current) => {
49
+ const next = normalizeFeatureFlagRolloutIndex(current) ?? {
50
+ version: 1,
51
+ global: false,
52
+ orgIds: [],
53
+ };
54
+ if (scope.orgId?.trim()) {
55
+ const orgId = scope.orgId.trim();
56
+ const active = hasActiveRollout(rules);
57
+ const orgIds = active
58
+ ? [...new Set([...next.orgIds, orgId])].sort()
59
+ : next.orgIds.filter((value) => value !== orgId);
60
+ return {
61
+ ...next,
62
+ orgIds,
63
+ };
64
+ }
65
+ return {
66
+ ...next,
67
+ global: hasActiveRollout(rules),
68
+ };
69
+ });
70
+ }
8
71
  export function defaultFeatureFlagRules() {
9
72
  return {
10
73
  version: 1,
@@ -66,6 +129,52 @@ export async function getFeatureFlagRules(key, scope) {
66
129
  ]);
67
130
  return normalizeFeatureFlagRules(orgStored ?? globalStored);
68
131
  }
132
+ /**
133
+ * Anonymous discovery hint for a rollout that may be scoped to an org.
134
+ *
135
+ * This deliberately answers only whether some active rollout exists. It does
136
+ * not reveal the target email or organization, and callers must still run
137
+ * `evaluateFeatureFlag` with the authenticated scope before granting access.
138
+ * Without this separate hint, an org-only rollout is invisible to Desktop
139
+ * before the user has authenticated and the org can be resolved.
140
+ */
141
+ export async function hasActiveFeatureFlagRollout(key) {
142
+ if (!getFeatureFlagDefinition(key))
143
+ return false;
144
+ const indexKey = rolloutIndexKey(key);
145
+ const storedIndex = normalizeFeatureFlagRolloutIndex(await getSetting(indexKey));
146
+ if (storedIndex)
147
+ return activeFeatureFlagRolloutIndex(storedIndex);
148
+ const globalStored = await getSetting(settingKey(key));
149
+ const globalActive = hasActiveRollout(parseStoredRules(globalStored));
150
+ if (globalActive) {
151
+ await mutateSetting(indexKey, async () => ({
152
+ version: 1,
153
+ global: true,
154
+ orgIds: [],
155
+ }));
156
+ return true;
157
+ }
158
+ const table = isPostgres() ? "public.settings" : "settings";
159
+ const { rows } = await getDbExec().execute({
160
+ sql: `SELECT key, value FROM ${table} WHERE key LIKE ?`,
161
+ args: [`o:%:${settingKey(key)}`],
162
+ });
163
+ const orgIds = rows
164
+ .filter((row) => hasActiveRollout(parseStoredRules(row.value)))
165
+ .map((row) => {
166
+ const match = /^o:([^:]+):/.exec(row.key ?? "");
167
+ return match?.[1] ?? null;
168
+ })
169
+ .filter((orgId) => Boolean(orgId))
170
+ .sort();
171
+ await mutateSetting(indexKey, async () => ({
172
+ version: 1,
173
+ global: false,
174
+ orgIds,
175
+ }));
176
+ return orgIds.length > 0;
177
+ }
69
178
  /**
70
179
  * Atomically derive one flag's scoped rules. An org's first override starts
71
180
  * from the global fallback, then becomes independently CAS-protected.
@@ -85,7 +194,9 @@ export async function mutateFeatureFlagRules(key, scope, updater) {
85
194
  const persisted = scope.orgId?.trim()
86
195
  ? await mutateOrgSetting(scope.orgId, settingKey(key), mutate)
87
196
  : await mutateSetting(settingKey(key), mutate);
88
- return normalizeFeatureFlagRules(persisted);
197
+ const normalized = normalizeFeatureFlagRules(persisted);
198
+ await syncFeatureFlagRolloutIndex(key, scope, normalized);
199
+ return normalized;
89
200
  }
90
201
  function rolloutBucket(input) {
91
202
  // FNV-1a is deliberately tiny, deterministic, and independent of runtime.
@@ -55,6 +55,10 @@ const ALLOWLIST_EXACT = new Set([
55
55
  "AWS_LAMBDA_FUNCTION_NAME",
56
56
  "BETTER_AUTH_SECRET",
57
57
  "BETTER_AUTH_URL",
58
+ // Public deployment identity/configuration. These select the app origin and
59
+ // explicitly registered SSO clients; they are not user credentials.
60
+ "APP_URL",
61
+ "IDENTITY_SSO_APP_REGISTRY_JSON",
58
62
  "NOTION_CLIENT_ID",
59
63
  "NOTION_CLIENT_SECRET",
60
64
  "NOTION_STATE_SECRET",
@@ -2,7 +2,7 @@ export * from "./config.js";
2
2
  export { addContextToAgentChat, appendAgentChatContextToMessage, clearAgentChatContext, formatAgentChatContextItemsForPrompt, listAgentChatContext, refreshAgentChatContext, removeAgentChatContextItem, sendToAgentChat, sendToAgentChatAndConfirm, setAgentChatContextItem, setContextToAgentChat, isEmbedMcpChatBridgeActive, useAgentChatContext, useAgentChatGenerating, useDevMode, useSendToAgentChat, AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES, getMcpAppHostContext, openMcpAppHostLink, requestMcpAppDisplayMode, sendMcpAppHostMessage, updateMcpAppModelContext, useMcpAppHostContext, CodeRequiredDialog, AgentNativeI18nProvider, LanguagePicker, getLocaleInitScript, localeDirection, normalizeLocaleCode, normalizeLocalePreference, normalizeLocalizationPreference, resolveLocaleFromCandidates, resolveLocaleFromPreference, useFormatters, useLocale, useT, DEFAULT_LOCALE, LOCALE_HYDRATION_GLOBAL, LOCALE_METADATA, LOCALE_STORAGE_KEY, SUPPORTED_LOCALES, useDbSync, useFileWatcher, useSession, cn, ApiKeySettings, type AgentChatContextItem, type AgentChatContextMessage, type AgentChatContextMutationOptions, type AgentChatContextRemoveOptions, type AgentChatContextSetOptions, type AgentChatContextState, type AgentChatMessage, type AgentNativeMcpAppHostMessageType, type McpAppDisplayMode, type McpAppHostChatMessage, type McpAppHostCapabilities, type McpAppHostContext, type McpAppHostContextSnapshot, type McpAppModelContextContentPart, type McpAppModelContextUpdate, type CodeRequiredDialogProps, type AuthSession, type UseAgentChatContextResult, type AgentNativeI18nCatalog, type AgentNativeI18nProviderProps, type LocaleCode, type LocaleHydrationPayload, type LocaleMessages, type LocaleMetadata, type LocalePreference, type LocalizationPreference, } from "./client/index.js";
3
3
  export { agentChat } from "./shared/index.js";
4
4
  export { parseArgs, camelCaseArgs } from "./scripts/parse-args.js";
5
- export { defineAction, AgentActionStopError, isAgentActionStopError, type ActionHttpConfig, type AgentActionStopOptions, MCP_APP_EXTENSION_ID, MCP_APP_MIME_TYPE, MCP_APP_RESOURCE_URI_META_KEY, type ActionMcpAppConfig, type ActionMcpAppCsp, type ActionMcpAppCspBuilder, type ActionMcpAppHtmlBuilder, type ActionMcpAppPermissions, type ActionMcpAppResourceConfig, type ActionMcpAppResourceMeta, } from "./action.js";
5
+ export { defineAction, ActionContractError, isActionContractError, type ActionContractErrorOptions, AgentActionStopError, isAgentActionStopError, type ActionHttpConfig, type AgentActionStopOptions, MCP_APP_EXTENSION_ID, MCP_APP_MIME_TYPE, MCP_APP_RESOURCE_URI_META_KEY, type ActionMcpAppConfig, type ActionMcpAppCsp, type ActionMcpAppCspBuilder, type ActionMcpAppHtmlBuilder, type ActionMcpAppPermissions, type ActionMcpAppResourceConfig, type ActionMcpAppResourceMeta, } from "./action.js";
6
6
  export { normalizeUserProfileName, USER_PROFILE_SETTING_KEY, type UserProfile, } from "./user-profile/index.js";
7
7
  export { ACTION_CHAT_UI_DATA_CHART_RENDERER, ACTION_CHAT_UI_DATA_INSIGHTS_RENDERER, ACTION_CHAT_UI_DATA_TABLE_RENDERER, ACTION_CHAT_UI_DATA_WIDGET_RENDERER, ACTION_CHAT_UI_INLINE_EXTENSION_RENDERER, ACTION_CHAT_UI_WORKSPACE_FILE_RENDERER, type ActionChatUIConfig, } from "./action-ui.js";
8
8
  export { DATA_CHART_WIDGET, DATA_INSIGHTS_WIDGET, DATA_TABLE_WIDGET, createDataChartWidgetResult, createDataInsightsWidgetResult, createDataTableWidgetResult, dataChartWidgetResultSchema, dataChartWidgetSchema, dataInsightsWidgetResultSchema, dataTableWidgetResultSchema, dataTableWidgetSchema, dataWidgetResultSchema, isDataChartWidget, isDataTableWidget, isDataWidgetResult, normalizeDataWidgetKind, normalizeDataWidgetResult, type DataChartSeriesDefinition, type DataChartWidget, type DataChartWidgetResult, type DataChartWidgetResultInput, type DataInsightsWidgetResult, type DataInsightsWidgetResultInput, type DataTableColumn, type DataTableWidget, type DataTableWidgetResult, type DataTableWidgetResultInput, type DataWidgetDisplay, type DataWidgetKind, type DataWidgetResult, type DataWidgetResultMetadata, } from "./data-widgets/index.js";
@@ -9,7 +9,7 @@ export { agentChat } from "./shared/index.js";
9
9
  // Pure utilities (no Node.js deps — safe for browser and SSR)
10
10
  export { parseArgs, camelCaseArgs } from "./scripts/parse-args.js";
11
11
  // defineAction — used by template actions, no Node.js deps
12
- export { defineAction, AgentActionStopError, isAgentActionStopError, MCP_APP_EXTENSION_ID, MCP_APP_MIME_TYPE, MCP_APP_RESOURCE_URI_META_KEY, } from "./action.js";
12
+ export { defineAction, ActionContractError, isActionContractError, AgentActionStopError, isAgentActionStopError, MCP_APP_EXTENSION_ID, MCP_APP_MIME_TYPE, MCP_APP_RESOURCE_URI_META_KEY, } from "./action.js";
13
13
  export { normalizeUserProfileName, USER_PROFILE_SETTING_KEY, } from "./user-profile/index.js";
14
14
  export { ACTION_CHAT_UI_DATA_CHART_RENDERER, ACTION_CHAT_UI_DATA_INSIGHTS_RENDERER, ACTION_CHAT_UI_DATA_TABLE_RENDERER, ACTION_CHAT_UI_DATA_WIDGET_RENDERER, ACTION_CHAT_UI_INLINE_EXTENSION_RENDERER, ACTION_CHAT_UI_WORKSPACE_FILE_RENDERER, } from "./action-ui.js";
15
15
  export { DATA_CHART_WIDGET, DATA_INSIGHTS_WIDGET, DATA_TABLE_WIDGET, createDataChartWidgetResult, createDataInsightsWidgetResult, createDataTableWidgetResult, dataChartWidgetResultSchema, dataChartWidgetSchema, dataInsightsWidgetResultSchema, dataTableWidgetResultSchema, dataTableWidgetSchema, dataWidgetResultSchema, isDataChartWidget, isDataTableWidget, isDataWidgetResult, normalizeDataWidgetKind, normalizeDataWidgetResult, } from "./data-widgets/index.js";
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export * from "./config.js";
2
2
  export { createProductionAgentHandler, type ActionEntry, type ScriptEntry, type ProductionAgentOptions, type ActionTool, type ScriptTool, type AgentMessage, type AgentChatRequest, type AgentChatEvent, type AgentChatAttachment, DEFAULT_MODEL, TripWire, type Processor, type ProcessorState, type ProcessorAbort, } from "./agent/index.js";
3
- export { defineAction, AgentActionStopError, isAgentActionStopError, type ActionDefinition, type ActionHttpConfig, type AgentActionStopOptions, type PublicAgentActionConfig, type ActionDeepLink, type ActionLinkBuilder, MCP_APP_EXTENSION_ID, MCP_APP_MIME_TYPE, MCP_APP_RESOURCE_URI_META_KEY, type ActionMcpAppConfig, type ActionMcpAppCsp, type ActionMcpAppCspBuilder, type ActionMcpAppHtmlBuilder, type ActionMcpAppPermissions, type ActionMcpAppResourceConfig, type ActionMcpAppResourceMeta, } from "./action.js";
3
+ export { defineAction, ActionContractError, isActionContractError, type ActionContractErrorOptions, AgentActionStopError, isAgentActionStopError, type ActionDefinition, type ActionHttpConfig, type AgentActionStopOptions, type PublicAgentActionConfig, type ActionDeepLink, type ActionLinkBuilder, MCP_APP_EXTENSION_ID, MCP_APP_MIME_TYPE, MCP_APP_RESOURCE_URI_META_KEY, type ActionMcpAppConfig, type ActionMcpAppCsp, type ActionMcpAppCspBuilder, type ActionMcpAppHtmlBuilder, type ActionMcpAppPermissions, type ActionMcpAppResourceConfig, type ActionMcpAppResourceMeta, } from "./action.js";
4
4
  export * from "./user-profile/index.js";
5
5
  export { embedApp, MCP_APP_REQUEST_ORIGIN_CSP_SOURCE, type EmbedAppOptions, } from "./mcp/embed-app.js";
6
6
  export { embedRoute, type EmbedRouteContext, type EmbedRouteOptions, type EmbedRoutePathBuilder, type EmbedRouteResult, } from "./mcp/embed-route.js";
@@ -11,7 +11,7 @@ export { createAgentChatPlugin, defaultAgentChatPlugin, type AgentChatPluginOpti
11
11
  export { createAgentNativeEmbeddedPlugin, mountAgentNativeEmbedded, type AgentNativeEmbeddedPluginOptions, } from "./server/embedded.js";
12
12
  export { BUILT_IN_INTEGRATION_CATALOG, INTEGRATION_CATEGORIES, getIntegrationCatalogEntry, listBuiltInChannelIntegrations, listIntegrationCatalog, type AutomationCapabilities, type BuiltInChannelId, type ChannelCapabilities, type IntegrationAvailability, type IntegrationCatalogEntry, type IntegrationCategory, type IntegrationCredentialRequirement, type IntegrationIconKey, type IntegrationSupportMaturity, } from "./integrations/catalog.js";
13
13
  export { AutomationConnectorError, createAutomationCallbackHandler, createAutomationRuntime, createInvokeAutomationWorkflowAction, type AutomationCallbackAuthentication, type AutomationCallbackInput, type AutomationCallbackResult, type AutomationInboundDefinition, type AutomationInvocation, type AutomationInvocationResult, type AutomationInvocationStatus, type AutomationOutboundDefinition, type AutomationResponseMode, type AutomationRetryPolicy, type AutomationRuntime, type AutomationRuntimeOptions, type AutomationWorkflowCapabilities, type AutomationWorkflowDefinition, type JsonSchema, } from "./automation/index.js";
14
- export { createFeatureFlagsPlugin, defineFeatureFlag, defineFeatureFlags, evaluateFeatureFlag, getFeatureFlagDefinition, getFeatureFlagRules, isFeatureFlagEnabled, listFeatureFlags, registerFeatureFlags, type FeatureFlagDefinition, type FeatureFlagMode, type FeatureFlagRules, type FeatureFlagScope, } from "./feature-flags/index.js";
14
+ export { createFeatureFlagsPlugin, defineFeatureFlag, defineFeatureFlags, evaluateFeatureFlag, getFeatureFlagDefinition, getFeatureFlagRules, hasActiveFeatureFlagRollout, isFeatureFlagEnabled, listFeatureFlags, registerFeatureFlags, type FeatureFlagDefinition, type FeatureFlagMode, type FeatureFlagRules, type FeatureFlagScope, } from "./feature-flags/index.js";
15
15
  export { createServer, createSSEHandler, defineNitroPlugin, autoMountAuth, getSession, type CreateServerOptions, type SSEHandlerOptions, type AuthSession, type AuthOptions, } from "./server/index.js";
16
16
  export { agentChat, type AgentChatCallOptions, type AgentChatResponse, } from "./shared/index.js";
17
17
  export { EMBED_MODE_QUERY_PARAM, EMBED_SESSION_COOKIE, EMBED_START_PATH, EMBED_TOKEN_QUERY_PARAM, } from "./shared/embed-auth.js";
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ export * from "./config.js";
5
5
  export { createProductionAgentHandler, DEFAULT_MODEL,
6
6
  // In-loop processors (observers/guardrails for runAgentLoop)
7
7
  TripWire, } from "./agent/index.js";
8
- export { defineAction, AgentActionStopError, isAgentActionStopError, MCP_APP_EXTENSION_ID, MCP_APP_MIME_TYPE, MCP_APP_RESOURCE_URI_META_KEY, } from "./action.js";
8
+ export { defineAction, ActionContractError, isActionContractError, AgentActionStopError, isAgentActionStopError, MCP_APP_EXTENSION_ID, MCP_APP_MIME_TYPE, MCP_APP_RESOURCE_URI_META_KEY, } from "./action.js";
9
9
  export * from "./user-profile/index.js";
10
10
  export { embedApp, MCP_APP_REQUEST_ORIGIN_CSP_SOURCE, } from "./mcp/embed-app.js";
11
11
  export { embedRoute, } from "./mcp/embed-route.js";
@@ -16,7 +16,7 @@ export { createAgentChatPlugin, defaultAgentChatPlugin, } from "./server/agent-c
16
16
  export { createAgentNativeEmbeddedPlugin, mountAgentNativeEmbedded, } from "./server/embedded.js";
17
17
  export { BUILT_IN_INTEGRATION_CATALOG, INTEGRATION_CATEGORIES, getIntegrationCatalogEntry, listBuiltInChannelIntegrations, listIntegrationCatalog, } from "./integrations/catalog.js";
18
18
  export { AutomationConnectorError, createAutomationCallbackHandler, createAutomationRuntime, createInvokeAutomationWorkflowAction, } from "./automation/index.js";
19
- export { createFeatureFlagsPlugin, defineFeatureFlag, defineFeatureFlags, evaluateFeatureFlag, getFeatureFlagDefinition, getFeatureFlagRules, isFeatureFlagEnabled, listFeatureFlags, registerFeatureFlags, } from "./feature-flags/index.js";
19
+ export { createFeatureFlagsPlugin, defineFeatureFlag, defineFeatureFlags, evaluateFeatureFlag, getFeatureFlagDefinition, getFeatureFlagRules, hasActiveFeatureFlagRollout, isFeatureFlagEnabled, listFeatureFlags, registerFeatureFlags, } from "./feature-flags/index.js";
20
20
  // Server
21
21
  export { createServer, createSSEHandler, defineNitroPlugin, autoMountAuth, getSession, } from "./server/index.js";
22
22
  // Client
@@ -858,7 +858,11 @@ function markdownToSlackMrkdwn(text) {
858
858
  // pathological "**" sequence that exhibits super-linear backtracking.
859
859
  // Newlines are allowed because `[^*]` excludes only the asterisk
860
860
  // itself, so multi-line bold spans still match.
861
- .replace(/\*\*([^*]{1,5000})\*\*/g, "*$1*"));
861
+ .replace(/\*\*([^*]{1,5000})\*\*/g, "*$1*")
862
+ // Agent output sometimes uses Markdown-style bare Slack user IDs.
863
+ // Leave native `<@...>` mentions untouched while converting the bare
864
+ // user/member forms Slack expects in mrkdwn.
865
+ .replace(/(?<![<\w])@([UW][A-Z0-9]+)(?![A-Z0-9])/g, "<@$1>"));
862
866
  }
863
867
  /**
864
868
  * Optionally set Slack's native Agent status indicator (the small "is
@@ -315,6 +315,7 @@ declare const messages: {
315
315
  openApp: string;
316
316
  notDispatchOrWorkspaceApp: string;
317
317
  agentsDescription: string;
318
+ simpleAgentsDescription: string;
318
319
  mcpAccessUpdated: string;
319
320
  selectAppForMcp: string;
320
321
  mcpUrlCopied: string;
@@ -321,6 +321,7 @@ const messages = {
321
321
  openApp: "Open app",
322
322
  notDispatchOrWorkspaceApp: " a Dispatch tab or a workspace app in this workspace.",
323
323
  agentsDescription: "Dispatch can delegate to the built-in app suite over A2A by default. Add extra agents here only if you want to route work to apps outside that built-in set.",
324
+ simpleAgentsDescription: "Create reusable agents in minutes, or import a setup you already made in Claude or another agent tool.",
324
325
  mcpAccessUpdated: "Agent integration access updated",
325
326
  selectAppForMcp: "Select at least one app, or expose all apps.",
326
327
  mcpUrlCopied: "Agent integration URL copied",
@@ -28,6 +28,6 @@ export declare function createNotificationsHandler(): import("h3").EventHandlerW
28
28
  } | {
29
29
  count?: undefined;
30
30
  updated?: undefined;
31
- error?: undefined;
32
31
  ok: boolean;
32
+ error?: undefined;
33
33
  }>>;
@@ -62,6 +62,6 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
62
62
  summary?: undefined;
63
63
  spans?: undefined;
64
64
  id?: undefined;
65
- error?: undefined;
66
65
  ok: boolean;
66
+ error?: undefined;
67
67
  }>>;
@@ -15,6 +15,6 @@ export declare function createProgressHandler(): import("h3").EventHandlerWithFe
15
15
  error: string;
16
16
  ok?: undefined;
17
17
  } | {
18
- error?: undefined;
19
18
  ok: boolean;
19
+ error?: undefined;
20
20
  }>>;